Files
core/test/helpers/utils.ts
2022-04-08 18:01:24 -04:00

1118 lines
30 KiB
TypeScript

import '@nomiclabs/hardhat-ethers';
import { BigNumberish, Bytes, logger, utils, BigNumber, Contract, Signer } from 'ethers';
import {
eventsLib,
helper,
lensHub,
LENS_HUB_NFT_NAME,
lensPeriphery,
LENS_PERIPHERY_NAME,
testWallet,
user,
} from '../__setup.spec';
import { expect } from 'chai';
import { HARDHAT_CHAINID, MAX_UINT256 } from './constants';
import { BytesLike, hexlify, keccak256, RLP, toUtf8Bytes } from 'ethers/lib/utils';
import { LensHub__factory } from '../../typechain-types';
import { TransactionReceipt, TransactionResponse } from '@ethersproject/providers';
import hre, { ethers } from 'hardhat';
import { readFileSync } from 'fs';
import { join } from 'path';
import {
CollectWithSigDataStruct,
CommentDataStruct,
CommentWithSigDataStruct,
CreateProfileDataStruct,
FollowWithSigDataStruct,
MirrorDataStruct,
MirrorWithSigDataStruct,
PostDataStruct,
PostWithSigDataStruct,
} from '../../typechain-types/LensHub';
export enum ProtocolState {
Unpaused,
PublishingPaused,
Paused,
}
export function matchEvent(
receipt: TransactionReceipt,
name: string,
expectedArgs?: any[],
eventContract: Contract = eventsLib,
emitterAddress?: string
) {
const events = receipt.logs;
if (events != undefined) {
// match name from list of events in eventContract, when found, compute the sigHash
let sigHash: string | undefined;
for (let contractEvent of Object.keys(eventContract.interface.events)) {
if (contractEvent.startsWith(name) && contractEvent.charAt(name.length) == '(') {
sigHash = keccak256(toUtf8Bytes(contractEvent));
break;
}
}
// Throw if the sigHash was not found
if (!sigHash) {
logger.throwError(
`Event "${name}" not found in provided contract (default: Events libary). \nAre you sure you're using the right contract?`
);
}
// Find the given event in the emitted logs
let invalidParamsButExists = false;
for (let emittedEvent of events) {
// If we find one with the correct sighash, check if it is the one we're looking for
if (emittedEvent.topics[0] == sigHash) {
// If an emitter address is passed, validate that this is indeed the correct emitter, if not, continue
if (emitterAddress) {
if (emittedEvent.address != emitterAddress) continue;
}
const event = eventContract.interface.parseLog(emittedEvent);
// If there are expected arguments, validate them, otherwise, return here
if (expectedArgs) {
if (expectedArgs.length != event.args.length) {
logger.throwError(
`Event "${name}" emitted with correct signature, but expected args are of invalid length`
);
}
invalidParamsButExists = false;
// Iterate through arguments and check them, if there is a mismatch, continue with the loop
for (let i = 0; i < expectedArgs.length; i++) {
// Parse empty arrays as empty bytes
if (expectedArgs[i].constructor == Array && expectedArgs[i].length == 0) {
expectedArgs[i] = '0x';
}
// Break out of the expected args loop if there is a mismatch, this will continue the emitted event loop
if (BigNumber.isBigNumber(event.args[i])) {
if (!event.args[i].eq(BigNumber.from(expectedArgs[i]))) {
invalidParamsButExists = true;
break;
}
} else if (event.args[i].constructor == Array) {
let params = event.args[i];
let expected = expectedArgs[i];
if (expected != '0x' && params.length != expected.length) {
invalidParamsButExists = true;
break;
}
for (let j = 0; j < params.length; j++) {
if (BigNumber.isBigNumber(params[j])) {
if (!params[j].eq(BigNumber.from(expected[j]))) {
invalidParamsButExists = true;
break;
}
} else if (params[j] != expected[j]) {
invalidParamsButExists = true;
break;
}
}
if (invalidParamsButExists) break;
} else if (event.args[i] != expectedArgs[i]) {
invalidParamsButExists = true;
break;
}
}
// Return if the for loop did not cause a break, so a match has been found, otherwise proceed with the event loop
if (!invalidParamsButExists) {
return;
}
} else {
return;
}
}
}
// Throw if the event args were not expected or the event was not found in the logs
if (invalidParamsButExists) {
logger.throwError(`Event "${name}" found in logs but with unexpected args`);
} else {
logger.throwError(
`Event "${name}" not found emitted by "${emitterAddress}" in given transaction log`
);
}
} else {
logger.throwError('No events were emitted');
}
}
export function computeContractAddress(deployerAddress: string, nonce: number): string {
const hexNonce = hexlify(nonce);
return '0x' + keccak256(RLP.encode([deployerAddress, hexNonce])).substr(26);
}
export function getChainId(): number {
return hre.network.config.chainId || HARDHAT_CHAINID;
}
export function getAbbreviation(handle: string) {
let slice = handle.substr(0, 4);
if (slice.charAt(3) == ' ') {
slice = slice.substr(0, 3);
}
return slice;
}
export async function waitForTx(
tx: Promise<TransactionResponse> | TransactionResponse,
skipCheck = false
): Promise<TransactionReceipt> {
if (!skipCheck) await expect(tx).to.not.be.reverted;
return await (await tx).wait();
}
export async function getBlockNumber(): Promise<number> {
return (await helper.getBlockNumber()).toNumber();
}
export async function resetFork(): Promise<void> {
await hre.network.provider.request({
method: 'hardhat_reset',
params: [
{
forking: {
jsonRpcUrl: `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_KEY}`,
blockNumber: 12012081,
},
},
],
});
console.log('\t> Fork reset');
await hre.network.provider.request({
method: 'evm_setNextBlockTimestamp',
params: [1614290545], // Original block timestamp + 1
});
console.log('\t> Timestamp reset to 1614290545');
}
export async function getTimestamp(): Promise<any> {
const blockNumber = await hre.ethers.provider.send('eth_blockNumber', []);
const block = await hre.ethers.provider.send('eth_getBlockByNumber', [blockNumber, false]);
return block.timestamp;
}
export async function setNextBlockTimestamp(timestamp: number): Promise<void> {
await hre.ethers.provider.send('evm_setNextBlockTimestamp', [timestamp]);
}
export async function mine(blocks: number): Promise<void> {
for (let i = 0; i < blocks; i++) {
await hre.ethers.provider.send('evm_mine', []);
}
}
let snapshotId: string = '0x1';
export async function takeSnapshot() {
snapshotId = await hre.ethers.provider.send('evm_snapshot', []);
}
export async function revertToSnapshot() {
await hre.ethers.provider.send('evm_revert', [snapshotId]);
}
export async function cancelWithPermitForAll(nft: string = lensHub.address) {
const nftContract = LensHub__factory.connect(nft, testWallet);
const name = await nftContract.name();
const nonce = (await nftContract.sigNonces(testWallet.address)).toNumber();
const { v, r, s } = await getPermitForAllParts(
nft,
name,
testWallet.address,
testWallet.address,
false,
nonce,
MAX_UINT256
);
await nftContract.permitForAll(testWallet.address, testWallet.address, false, {
v,
r,
s,
deadline: MAX_UINT256,
});
}
export async function getPermitParts(
nft: string,
name: string,
spender: string,
tokenId: BigNumberish,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildPermitParams(nft, name, spender, tokenId, nonce, deadline);
return await getSig(msgParams);
}
export async function getPermitForAllParts(
nft: string,
name: string,
owner: string,
operator: string,
approved: boolean,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildPermitForAllParams(nft, name, owner, operator, approved, nonce, deadline);
return await getSig(msgParams);
}
export async function getBurnWithSigparts(
nft: string,
name: string,
tokenId: BigNumberish,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildBurnWithSigParams(nft, name, tokenId, nonce, deadline);
return await getSig(msgParams);
}
export async function getDelegateBySigParts(
nft: string,
name: string,
delegator: string,
delegatee: string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildDelegateBySigParams(nft, name, delegator, delegatee, nonce, deadline);
return await getSig(msgParams);
}
const buildDelegateBySigParams = (
nft: string,
name: string,
delegator: string,
delegatee: string,
nonce: number,
deadline: string
) => ({
types: {
DelegateBySig: [
{ name: 'delegator', type: 'address' },
{ name: 'delegatee', type: 'address' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: {
name: name,
version: '1',
chainId: getChainId(),
verifyingContract: nft,
},
value: {
delegator: delegator,
delegatee: delegatee,
nonce: nonce,
deadline: deadline,
},
});
export async function getSetFollowModuleWithSigParts(
profileId: BigNumberish,
followModule: string,
followModuleInitData: Bytes | string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildSetFollowModuleWithSigParams(
profileId,
followModule,
followModuleInitData,
nonce,
deadline
);
return await getSig(msgParams);
}
export async function getSetDispatcherWithSigParts(
profileId: BigNumberish,
dispatcher: string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildSetDispatcherWithSigParams(profileId, dispatcher, nonce, deadline);
return await getSig(msgParams);
}
export async function getSetProfileImageURIWithSigParts(
profileId: BigNumberish,
imageURI: string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildSetProfileImageURIWithSigParams(profileId, imageURI, nonce, deadline);
return await getSig(msgParams);
}
export async function getSetDefaultProfileWithSigParts(
wallet: string,
profileId: BigNumberish,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildSetDefaultProfileWithSigParams(profileId, wallet, nonce, deadline);
return await getSig(msgParams);
}
export async function getSetFollowNFTURIWithSigParts(
profileId: BigNumberish,
followNFTURI: string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildSetFollowNFTURIWithSigParams(profileId, followNFTURI, nonce, deadline);
return await getSig(msgParams);
}
export async function getPostWithSigParts(
profileId: BigNumberish,
contentURI: string,
collectModule: string,
collectModuleInitData: Bytes | string,
referenceModule: string,
referenceModuleInitData: Bytes | string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildPostWithSigParams(
profileId,
contentURI,
collectModule,
collectModuleInitData,
referenceModule,
referenceModuleInitData,
nonce,
deadline
);
return await getSig(msgParams);
}
export async function getCommentWithSigParts(
profileId: BigNumberish,
contentURI: string,
profileIdPointed: BigNumberish,
pubIdPointed: string,
referenceModuleData: Bytes | string,
collectModule: string,
collectModuleInitData: Bytes | string,
referenceModule: string,
referenceModuleInitData: Bytes | string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildCommentWithSigParams(
profileId,
contentURI,
profileIdPointed,
pubIdPointed,
referenceModuleData,
collectModule,
collectModuleInitData,
referenceModule,
referenceModuleInitData,
nonce,
deadline
);
return await getSig(msgParams);
}
export async function getMirrorWithSigParts(
profileId: BigNumberish,
profileIdPointed: BigNumberish,
pubIdPointed: string,
referenceModuleData: Bytes | string,
referenceModule: string,
referenceModuleInitData: Bytes | string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildMirrorWithSigParams(
profileId,
profileIdPointed,
pubIdPointed,
referenceModuleData,
referenceModule,
referenceModuleInitData,
nonce,
deadline
);
return await getSig(msgParams);
}
export async function getFollowWithSigParts(
profileIds: string[] | number[],
datas: Bytes[] | string[],
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildFollowWithSigParams(profileIds, datas, nonce, deadline);
return await getSig(msgParams);
}
export async function getToggleFollowWithSigParts(
profileIds: string[] | number[],
enables: boolean[],
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildToggleFollowWithSigParams(profileIds, enables, nonce, deadline);
return await getSig(msgParams);
}
export async function getSetProfileMetadataURIWithSigParts(
profileId: string | number,
metadata: string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildSetProfileMetadataURIWithSigParams(profileId, metadata, nonce, deadline);
return await getSig(msgParams);
}
export async function getCollectWithSigParts(
profileId: BigNumberish,
pubId: string,
data: Bytes | string,
nonce: number,
deadline: string
): Promise<{ v: number; r: string; s: string }> {
const msgParams = buildCollectWithSigParams(profileId, pubId, data, nonce, deadline);
return await getSig(msgParams);
}
export function expectEqualArrays(actual: BigNumberish[], expected: BigNumberish[]) {
if (actual.length != expected.length) {
logger.throwError(
`${actual} length ${actual.length} does not match ${expected} length ${expect.length}`
);
}
let areEquals = true;
for (let i = 0; areEquals && i < actual.length; i++) {
areEquals = BigNumber.from(actual[i]).eq(BigNumber.from(expected[i]));
}
if (!areEquals) {
logger.throwError(`${actual} does not match ${expected}`);
}
}
export interface CreateProfileReturningTokenIdStruct {
sender?: Signer;
vars: CreateProfileDataStruct;
}
export async function createProfileReturningTokenId({
sender = user,
vars,
}: CreateProfileReturningTokenIdStruct): Promise<BigNumber> {
const tokenId = await lensHub.connect(sender).callStatic.createProfile(vars);
await expect(lensHub.connect(sender).createProfile(vars)).to.not.be.reverted;
return tokenId;
}
export interface FollowDataStruct {
profileIds: BigNumberish[];
datas: BytesLike[];
}
export interface FollowReturningTokenIdsStruct {
sender?: Signer;
vars: FollowDataStruct | FollowWithSigDataStruct;
}
export async function followReturningTokenIds({
sender = user,
vars,
}: FollowReturningTokenIdsStruct): Promise<BigNumber[]> {
let tokenIds;
if ('sig' in vars) {
tokenIds = await lensHub.connect(sender).callStatic.followWithSig(vars);
await expect(lensHub.connect(sender).followWithSig(vars)).to.not.be.reverted;
} else {
tokenIds = await lensHub.connect(sender).callStatic.follow(vars.profileIds, vars.datas);
await expect(lensHub.connect(sender).follow(vars.profileIds, vars.datas)).to.not.be.reverted;
}
return tokenIds;
}
export interface CollectDataStruct {
profileId: BigNumberish;
pubId: BigNumberish;
data: BytesLike;
}
export interface CollectReturningTokenIdsStruct {
sender?: Signer;
vars: CollectDataStruct | CollectWithSigDataStruct;
}
export async function collectReturningTokenIds({
sender = user,
vars,
}: CollectReturningTokenIdsStruct): Promise<BigNumber> {
let tokenId;
if ('sig' in vars) {
tokenId = await lensHub.connect(sender).callStatic.collectWithSig(vars);
await expect(lensHub.connect(sender).collectWithSig(vars)).to.not.be.reverted;
} else {
tokenId = await lensHub
.connect(sender)
.callStatic.collect(vars.profileId, vars.pubId, vars.data);
await expect(lensHub.connect(sender).collect(vars.profileId, vars.pubId, vars.data)).to.not.be
.reverted;
}
return tokenId;
}
export interface CommentReturningTokenIdStruct {
sender?: Signer;
vars: CommentDataStruct | CommentWithSigDataStruct;
}
export async function commentReturningTokenId({
sender = user,
vars,
}: CommentReturningTokenIdStruct): Promise<BigNumber> {
let tokenId;
if ('sig' in vars) {
tokenId = await lensHub.connect(sender).callStatic.commentWithSig(vars);
await expect(lensHub.connect(sender).commentWithSig(vars)).to.not.be.reverted;
} else {
tokenId = await lensHub.connect(sender).callStatic.comment(vars);
await expect(lensHub.connect(sender).comment(vars)).to.not.be.reverted;
}
return tokenId;
}
export interface MirrorReturningTokenIdStruct {
sender?: Signer;
vars: MirrorDataStruct | MirrorWithSigDataStruct;
}
export async function mirrorReturningTokenId({
sender = user,
vars,
}: MirrorReturningTokenIdStruct): Promise<BigNumber> {
let tokenId;
if ('sig' in vars) {
tokenId = await lensHub.connect(sender).callStatic.mirrorWithSig(vars);
await expect(lensHub.connect(sender).mirrorWithSig(vars)).to.not.be.reverted;
} else {
tokenId = await lensHub.connect(sender).callStatic.mirror(vars);
await expect(lensHub.connect(sender).mirror(vars)).to.not.be.reverted;
}
return tokenId;
}
export interface PostReturningTokenIdStruct {
sender?: Signer;
vars: PostDataStruct | PostWithSigDataStruct;
}
export async function postReturningTokenId({
sender = user,
vars,
}: PostReturningTokenIdStruct): Promise<BigNumber> {
let tokenId;
if ('sig' in vars) {
tokenId = await lensHub.connect(sender).callStatic.postWithSig(vars);
await expect(lensHub.connect(sender).postWithSig(vars)).to.not.be.reverted;
} else {
tokenId = await lensHub.connect(sender).callStatic.post(vars);
await expect(lensHub.connect(sender).post(vars)).to.not.be.reverted;
}
return tokenId;
}
export interface TokenUriMetadataAttribute {
trait_type: string;
value: string;
}
export interface ProfileTokenUriMetadata {
name: string;
description: string;
image: string;
attributes: TokenUriMetadataAttribute[];
}
export async function getMetadataFromBase64TokenUri(
tokenUri: string
): Promise<ProfileTokenUriMetadata> {
const splittedTokenUri = tokenUri.split('data:application/json;base64,');
if (splittedTokenUri.length != 2) {
logger.throwError('Wrong or unrecognized token URI format');
} else {
const jsonMetadataBase64String = splittedTokenUri[1];
const jsonMetadataBytes = ethers.utils.base64.decode(jsonMetadataBase64String);
const jsonMetadataString = ethers.utils.toUtf8String(jsonMetadataBytes);
return JSON.parse(jsonMetadataString);
}
}
export async function getDecodedSvgImage(tokenUriMetadata: ProfileTokenUriMetadata) {
const splittedImage = tokenUriMetadata.image.split('data:image/svg+xml;base64,');
if (splittedImage.length != 2) {
logger.throwError('Wrong or unrecognized token URI format');
} else {
return ethers.utils.toUtf8String(ethers.utils.base64.decode(splittedImage[1]));
}
}
export function loadTestResourceAsUtf8String(relativePathToResouceDir: string) {
return readFileSync(join('test', 'resources', relativePathToResouceDir), 'utf8');
}
// Modified from AaveTokenV2 repo
const buildPermitParams = (
nft: string,
name: string,
spender: string,
tokenId: BigNumberish,
nonce: number,
deadline: string
) => ({
types: {
Permit: [
{ name: 'spender', type: 'address' },
{ name: 'tokenId', type: 'uint256' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: {
name: name,
version: '1',
chainId: getChainId(),
verifyingContract: nft,
},
value: {
spender: spender,
tokenId: tokenId,
nonce: nonce,
deadline: deadline,
},
});
const buildPermitForAllParams = (
nft: string,
name: string,
owner: string,
operator: string,
approved: boolean,
nonce: number,
deadline: string
) => ({
types: {
PermitForAll: [
{ name: 'owner', type: 'address' },
{ name: 'operator', type: 'address' },
{ name: 'approved', type: 'bool' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: {
name: name,
version: '1',
chainId: getChainId(),
verifyingContract: nft,
},
value: {
owner: owner,
operator: operator,
approved: approved,
nonce: nonce,
deadline: deadline,
},
});
const buildBurnWithSigParams = (
nft: string,
name: string,
tokenId: BigNumberish,
nonce: number,
deadline: string
) => ({
types: {
BurnWithSig: [
{ name: 'tokenId', type: 'uint256' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: {
name: name,
version: '1',
chainId: getChainId(),
verifyingContract: nft,
},
value: {
tokenId: tokenId,
nonce: nonce,
deadline: deadline,
},
});
const buildSetFollowModuleWithSigParams = (
profileId: BigNumberish,
followModule: string,
followModuleInitData: Bytes | string,
nonce: number,
deadline: string
) => ({
types: {
SetFollowModuleWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'followModule', type: 'address' },
{ name: 'followModuleInitData', type: 'bytes' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileId: profileId,
followModule: followModule,
followModuleInitData: followModuleInitData,
nonce: nonce,
deadline: deadline,
},
});
const buildSetDispatcherWithSigParams = (
profileId: BigNumberish,
dispatcher: string,
nonce: number,
deadline: string
) => ({
types: {
SetDispatcherWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'dispatcher', type: 'address' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileId: profileId,
dispatcher: dispatcher,
nonce: nonce,
deadline: deadline,
},
});
const buildSetProfileImageURIWithSigParams = (
profileId: BigNumberish,
imageURI: string,
nonce: number,
deadline: string
) => ({
types: {
SetProfileImageURIWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'imageURI', type: 'string' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileId: profileId,
imageURI: imageURI,
nonce: nonce,
deadline: deadline,
},
});
const buildSetDefaultProfileWithSigParams = (
profileId: BigNumberish,
wallet: string,
nonce: number,
deadline: string
) => ({
types: {
SetDefaultProfileWithSig: [
{ name: 'wallet', type: 'address' },
{ name: 'profileId', type: 'uint256' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
wallet: wallet,
profileId: profileId,
nonce: nonce,
deadline: deadline,
},
});
const buildSetFollowNFTURIWithSigParams = (
profileId: BigNumberish,
followNFTURI: string,
nonce: number,
deadline: string
) => ({
types: {
SetFollowNFTURIWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'followNFTURI', type: 'string' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileId: profileId,
followNFTURI: followNFTURI,
nonce: nonce,
deadline: deadline,
},
});
const buildPostWithSigParams = (
profileId: BigNumberish,
contentURI: string,
collectModule: string,
collectModuleInitData: Bytes | string,
referenceModule: string,
referenceModuleInitData: Bytes | string,
nonce: number,
deadline: string
) => ({
types: {
PostWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'contentURI', type: 'string' },
{ name: 'collectModule', type: 'address' },
{ name: 'collectModuleInitData', type: 'bytes' },
{ name: 'referenceModule', type: 'address' },
{ name: 'referenceModuleInitData', type: 'bytes' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileId: profileId,
contentURI: contentURI,
collectModule: collectModule,
collectModuleInitData: collectModuleInitData,
referenceModule: referenceModule,
referenceModuleInitData: referenceModuleInitData,
nonce: nonce,
deadline: deadline,
},
});
const buildCommentWithSigParams = (
profileId: BigNumberish,
contentURI: string,
profileIdPointed: BigNumberish,
pubIdPointed: string,
referenceModuleData: Bytes | string,
collectModule: string,
collectModuleInitData: Bytes | string,
referenceModule: string,
referenceModuleInitData: Bytes | string,
nonce: number,
deadline: string
) => ({
types: {
CommentWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'contentURI', type: 'string' },
{ name: 'profileIdPointed', type: 'uint256' },
{ name: 'pubIdPointed', type: 'uint256' },
{ name: 'referenceModuleData', type: 'bytes' },
{ name: 'collectModule', type: 'address' },
{ name: 'collectModuleInitData', type: 'bytes' },
{ name: 'referenceModule', type: 'address' },
{ name: 'referenceModuleInitData', type: 'bytes' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileId: profileId,
contentURI: contentURI,
profileIdPointed: profileIdPointed,
pubIdPointed: pubIdPointed,
referenceModuleData: referenceModuleData,
collectModule: collectModule,
collectModuleInitData: collectModuleInitData,
referenceModule: referenceModule,
referenceModuleInitData: referenceModuleInitData,
nonce: nonce,
deadline: deadline,
},
});
const buildMirrorWithSigParams = (
profileId: BigNumberish,
profileIdPointed: BigNumberish,
pubIdPointed: string,
referenceModuleData: Bytes | string,
referenceModule: string,
referenceModuleInitData: Bytes | string,
nonce: number,
deadline: string
) => ({
types: {
MirrorWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'profileIdPointed', type: 'uint256' },
{ name: 'pubIdPointed', type: 'uint256' },
{ name: 'referenceModuleData', type: 'bytes' },
{ name: 'referenceModule', type: 'address' },
{ name: 'referenceModuleInitData', type: 'bytes' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileId: profileId,
profileIdPointed: profileIdPointed,
pubIdPointed: pubIdPointed,
referenceModuleData: referenceModuleData,
referenceModule: referenceModule,
referenceModuleInitData: referenceModuleInitData,
nonce: nonce,
deadline: deadline,
},
});
const buildFollowWithSigParams = (
profileIds: string[] | number[],
datas: Bytes[] | string[],
nonce: number,
deadline: string
) => ({
types: {
FollowWithSig: [
{ name: 'profileIds', type: 'uint256[]' },
{ name: 'datas', type: 'bytes[]' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileIds: profileIds,
datas: datas,
nonce: nonce,
deadline: deadline,
},
});
const buildToggleFollowWithSigParams = (
profileIds: string[] | number[],
enables: boolean[],
nonce: number,
deadline: string
) => ({
types: {
ToggleFollowWithSig: [
{ name: 'profileIds', type: 'uint256[]' },
{ name: 'enables', type: 'bool[]' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: {
name: LENS_PERIPHERY_NAME,
version: '1',
chainId: getChainId(),
verifyingContract: lensPeriphery.address,
},
value: {
profileIds: profileIds,
enables: enables,
nonce: nonce,
deadline: deadline,
},
});
const buildSetProfileMetadataURIWithSigParams = (
profileId: string | number,
metadata: string,
nonce: number,
deadline: string
) => ({
types: {
SetProfileMetadataURIWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'metadata', type: 'string' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: {
name: LENS_PERIPHERY_NAME,
version: '1',
chainId: getChainId(),
verifyingContract: lensPeriphery.address,
},
value: {
profileId: profileId,
metadata: metadata,
nonce: nonce,
deadline: deadline,
},
});
const buildCollectWithSigParams = (
profileId: BigNumberish,
pubId: string,
data: Bytes | string,
nonce: number,
deadline: string
) => ({
types: {
CollectWithSig: [
{ name: 'profileId', type: 'uint256' },
{ name: 'pubId', type: 'uint256' },
{ name: 'data', type: 'bytes' },
{ name: 'nonce', type: 'uint256' },
{ name: 'deadline', type: 'uint256' },
],
},
domain: domain(),
value: {
profileId: profileId,
pubId: pubId,
data: data,
nonce: nonce,
deadline: deadline,
},
});
async function getSig(msgParams: {
domain: any;
types: any;
value: any;
}): Promise<{ v: number; r: string; s: string }> {
const sig = await testWallet._signTypedData(msgParams.domain, msgParams.types, msgParams.value);
return utils.splitSignature(sig);
}
function domain(): { name: string; version: string; chainId: number; verifyingContract: string } {
return {
name: LENS_HUB_NFT_NAME,
version: '1',
chainId: getChainId(),
verifyingContract: lensHub.address,
};
}