@invisi-labs/sdk 1.1.0 → 1.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/ethers.cjs CHANGED
@@ -74,6 +74,28 @@ var EthersChainReader = class {
74
74
  async getChainId() {
75
75
  return (await this.client.getNetwork()).chainId;
76
76
  }
77
+ async isValidRegistrationSignature(owner, digest, signature) {
78
+ try {
79
+ const result = await this.client.call({
80
+ to: getAddress(owner),
81
+ data: new import_ethers.Interface(erc1271Abi).encodeFunctionData("isValidSignature", [
82
+ digest,
83
+ signature
84
+ ])
85
+ });
86
+ return result.length >= 66 && result.slice(0, 66).toLowerCase() === "0x1626ba7e" + "00".repeat(28);
87
+ } catch (error) {
88
+ if ((0, import_ethers.isError)(error, "CALL_EXCEPTION")) return false;
89
+ throw error;
90
+ }
91
+ }
92
+ async getProtocolAddressRegistry(address) {
93
+ return getAddress(
94
+ await new import_ethers.Contract(getAddress(address), import_contracts.invisiProtocolAbi, this.client).getFunction(
95
+ "addressRegistry"
96
+ )()
97
+ );
98
+ }
77
99
  async getProtocolVersion(address) {
78
100
  return BigInt(
79
101
  await new import_ethers.Contract(getAddress(address), import_contracts.invisiProtocolAbi, this.client).getFunction(
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/integrations/ethers.ts"],"sourcesContent":["import {\n Contract,\n zeroPadValue,\n Interface,\n TypedDataEncoder,\n verifyTypedData,\n getAddress as ethersAddress,\n getBytes,\n keccak256,\n isError,\n type Provider,\n type Signer,\n} from \"ethers\";\nimport type { Address, Hex } from \"@invisi-labs/protocol/contracts\";\nconst getAddress = (value: string): Address => ethersAddress(value) as Address;\nimport {\n invisiProtocolAbi,\n invisiAddressRegistryAbi,\n invisiFactoryAbi,\n} from \"@invisi-labs/protocol/contracts\";\nimport { ReceivingAddress, type ReceivingKeyLookup } from \"@invisi-labs/core/address\";\nimport type {\n ChainReader,\n FactoryReader,\n RegistryReader,\n RegistryContext,\n TransactionContext,\n DeploymentContext,\n CanonicalBlock,\n CanonicalReceipt,\n} from \"@invisi-labs/protocol\";\nimport type { FundingSigner, FundingTypedData, FundingAuthorizationVerifier } from \"../session\";\n\nconst erc1271Abi = [\n \"function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)\",\n];\nfunction fundingTypes(data: FundingTypedData) {\n const types = Object.fromEntries(\n Object.entries(data.types).map(([name, fields]) => [name, [...fields]])\n );\n check(\n TypedDataEncoder.from(types).primaryType === data.primaryType,\n \"funding typed-data primary type mismatch\"\n );\n return types;\n}\n\nfunction check(value: unknown, message: string): asserts value {\n if (!value) {\n throw new Error(message);\n }\n}\n\nasync function chain(client: Provider, expected: bigint): Promise<void> {\n check((await client.getNetwork()).chainId === expected, \"EVM client chain mismatch\");\n}\n\nfunction number(value: unknown): bigint {\n check(typeof value === \"bigint\" && value >= 0n, \"invalid chain integer\");\n return value;\n}\n\nfunction boolean(value: unknown): boolean {\n check(typeof value === \"boolean\", \"invalid chain boolean\");\n return value;\n}\n\nfunction word(value: unknown): Hex {\n check(typeof value === \"string\" && /^0x[0-9a-fA-F]{64}$/.test(value), \"invalid chain word\");\n return value.toLowerCase() as Hex;\n}\n\nfunction ownerWord(value: Hex): Hex {\n // Public owners use canonical EVM addresses; registry slots remain bytes32.\n const identity = ReceivingAddress.fromIdentity(value).walletIdentity;\n return zeroPadValue(identity, 32) as Hex;\n}\n\n/** Reads exact block numbers; higher layers additionally enforce post-read snapshot barriers. */\nexport class EthersChainReader implements ChainReader, RegistryReader, FactoryReader {\n constructor(readonly client: Provider) {}\n\n async getChainId() {\n return (await this.client.getNetwork()).chainId;\n }\n\n async getProtocolVersion(address: Address): Promise<bigint> {\n return BigInt(\n await new Contract(getAddress(address), invisiProtocolAbi, this.client).getFunction(\n \"VERSION\"\n )()\n );\n }\n\n async getCode(address: Address): Promise<Hex> {\n return (await this.client.getCode(getAddress(address))) as Hex;\n }\n\n async getFactoryInstanceAddress(factory: Address, salt: Hex): Promise<Address> {\n return getAddress(\n await new Contract(factory, invisiFactoryAbi, this.client).getFunction(\n \"getInstanceAddress\"\n )(salt)\n );\n }\n async isFactoryInstance(factory: Address, instance: Address): Promise<boolean> {\n return boolean(\n await new Contract(factory, invisiFactoryAbi, this.client).getFunction(\"isInstance\")(\n instance\n )\n );\n }\n async getInstanceFactory(instance: Address): Promise<Address> {\n return getAddress(\n await new Contract(instance, invisiProtocolAbi, this.client).getFunction(\"factory\")()\n );\n }\n async getLatestBlockNumber() {\n return BigInt(await this.client.getBlockNumber());\n }\n\n async getBlock(blockNumber: bigint): Promise<CanonicalBlock> {\n const block = await this.client.getBlock(blockNumber);\n check(\n block && BigInt(block.number) === blockNumber && block.hash && block.parentHash,\n \"invalid canonical block\"\n );\n return {\n number: BigInt(block.number),\n hash: word(block.hash),\n parentHash: word(block.parentHash),\n timestamp: number(BigInt(block.timestamp)),\n };\n }\n\n private async read(\n context: { chainId: bigint },\n address: Address,\n abi: ConstructorParameters<typeof Interface>[0],\n functionName: string,\n args: readonly unknown[],\n block?: CanonicalBlock\n ): Promise<unknown> {\n await chain(this.client, context.chainId);\n if (block) {\n check(\n (await this.getBlock(block.number)).hash === block.hash,\n \"canonical read block mismatch\"\n );\n }\n return new Contract(getAddress(address), abi, this.client).getFunction(functionName)(\n ...args,\n ...(block ? [{ blockTag: block.number }] : [])\n );\n }\n\n async getFundingNonce(context: DeploymentContext, payer: Address, block: CanonicalBlock) {\n return number(\n await this.read(\n context,\n context.protocolAddress,\n invisiProtocolAbi,\n \"nonces\",\n [getAddress(payer)],\n block\n )\n );\n }\n\n async getRegistryNonce(context: RegistryContext, walletIdentity: Hex, block: CanonicalBlock) {\n return number(\n await this.read(\n context,\n context.registryAddress,\n invisiAddressRegistryAbi,\n \"nonceOf\",\n [ownerWord(walletIdentity)],\n block\n )\n );\n }\n\n async isKnownRoot(\n context: DeploymentContext,\n treeId: bigint,\n root: Hex,\n block: CanonicalBlock\n ) {\n return boolean(\n await this.read(\n context,\n context.protocolAddress,\n invisiProtocolAbi,\n \"rootHistory\",\n [number(treeId), word(root)],\n block\n )\n );\n }\n\n async isSpent(context: DeploymentContext, nullifiers: readonly Hex[], block: CanonicalBlock) {\n const copied = nullifiers.map(word);\n const result: boolean[] = [];\n for (let offset = 0; offset < copied.length; offset += 32) {\n result.push(\n ...(await Promise.all(\n copied\n .slice(offset, offset + 32)\n .map((nf) =>\n this.read(\n context,\n context.protocolAddress,\n invisiProtocolAbi,\n \"isNullifierSpent\",\n [nf],\n block\n ).then(boolean)\n )\n ))\n );\n }\n return result;\n }\n\n async getTransaction(hash: Hex) {\n try {\n const tx = await this.client.getTransaction(word(hash));\n if (!tx?.to) {\n return null;\n }\n return {\n transactionHash: word(tx.hash),\n to: getAddress(tx.to),\n from: getAddress(tx.from),\n nonce: number(BigInt(tx.nonce)),\n data: tx.data as Hex,\n value: number(tx.value),\n };\n } catch (error) {\n if (error instanceof Error && error.name === \"TransactionNotFoundError\") {\n return null;\n }\n throw error;\n }\n }\n\n async getReceipt(hash: Hex): Promise<CanonicalReceipt | null> {\n try {\n const receipt = await this.client.getTransactionReceipt(word(hash));\n if (!receipt) return null;\n const block = await this.getBlock(BigInt(receipt.blockNumber));\n check(block.hash === receipt.blockHash, \"receipt block is no longer canonical\");\n return {\n block,\n transactionHash: word(receipt.hash),\n status: receipt.status === 1 ? \"success\" : \"reverted\",\n logs: receipt.logs.map((log) => {\n check(\n !log.removed && log.transactionHash === receipt.hash && log.index !== null,\n \"invalid receipt log\"\n );\n return {\n address: getAddress(log.address),\n data: log.data as Hex,\n topics: [...log.topics] as Hex[],\n transactionHash: word(log.transactionHash),\n logIndex: log.index,\n };\n }),\n };\n } catch (error) {\n if (error instanceof Error && error.name === \"TransactionReceiptNotFoundError\") {\n return null;\n }\n throw error;\n }\n }\n}\n\n/** Resolves only the explicitly selected registry. Validates canonical public key encodings. */\nexport class EthersAddressResolver {\n readonly #context: Readonly<RegistryContext>;\n\n constructor(\n readonly client: Provider,\n context: RegistryContext,\n readonly expectedRuntimeCodeHash?: Hex\n ) {\n this.#context = Object.freeze({\n ...context,\n registryAddress: getAddress(context.registryAddress),\n });\n check(BigInt(context.registryAddress) !== 0n, \"invalid registry address\");\n }\n\n readonly lookup: ReceivingKeyLookup = async (walletIdentity) => {\n await chain(this.client, this.#context.chainId);\n if (this.expectedRuntimeCodeHash) {\n const code = await this.client.getCode(this.#context.registryAddress);\n check(\n code !== \"0x\" && keccak256(code) === this.expectedRuntimeCodeHash,\n \"registry runtime profile mismatch\"\n );\n }\n const block = await this.client.getBlock(\"latest\");\n check(block && block.hash, \"invalid registry block\");\n const contract = new Contract(\n this.#context.registryAddress,\n invisiAddressRegistryAbi,\n this.client\n );\n const registered = await contract.getFunction(\"isRegistered\")(ownerWord(walletIdentity), {\n blockTag: block.number,\n });\n if (!registered) return null;\n const [keys] = await contract.getFunction(\"receivingKeysOf\")(ownerWord(walletIdentity), {\n blockTag: block.number,\n });\n check(\n (await this.client.getBlock(block.number))?.hash === block.hash,\n \"canonical registry read changed\"\n );\n return ReceivingAddress.from({\n walletIdentity,\n viewingPublicKey: getBytes(keys.viewingPublicKey),\n clueKey: getBytes(keys.clueKey),\n }).getReceivingKeys();\n };\n}\n\nexport class EthersFundingSigner implements FundingSigner {\n readonly address: Address;\n constructor(\n readonly signer: Signer,\n readonly chainId: bigint,\n address: Address\n ) {\n this.address = getAddress(address);\n }\n static async create(signer: Signer, chainId: bigint): Promise<EthersFundingSigner> {\n return new EthersFundingSigner(signer, chainId, getAddress(await signer.getAddress()));\n }\n async signTypedData(data: FundingTypedData): Promise<Hex> {\n const copied = structuredClone(data);\n check(\n BigInt(copied.domain.chainId as bigint) === this.chainId,\n \"funding typed-data chain mismatch\"\n );\n check(\n getAddress(await this.signer.getAddress()) === this.address,\n \"funding signer address mismatch\"\n );\n if (this.signer.provider) await chain(this.signer.provider, this.chainId);\n return (await this.signer.signTypedData(\n copied.domain,\n fundingTypes(copied),\n copied.message\n )) as Hex;\n }\n}\n\nexport class EthersFundingVerifier implements FundingAuthorizationVerifier {\n constructor(\n readonly client: Provider,\n readonly chainId: bigint\n ) {}\n async verifyTypedData(\n data: FundingTypedData & { address: Address; signature: Hex }\n ): Promise<boolean> {\n const copied = structuredClone(data);\n check(\n BigInt(copied.domain.chainId as bigint) === this.chainId,\n \"funding typed-data chain mismatch\"\n );\n await chain(this.client, this.chainId);\n const address = getAddress(copied.address);\n if ((await this.client.getCode(address)) === \"0x\") {\n try {\n return (\n getAddress(\n verifyTypedData(\n copied.domain,\n fundingTypes(copied),\n copied.message,\n copied.signature\n )\n ) === address\n );\n } catch {\n return false;\n }\n }\n try {\n return (\n (await new Contract(address, erc1271Abi, this.client).getFunction(\n \"isValidSignature\"\n )(\n TypedDataEncoder.hash(copied.domain, fundingTypes(copied), copied.message),\n copied.signature\n )) === \"0x1626ba7e\"\n );\n } catch (error) {\n if (isError(error, \"CALL_EXCEPTION\")) return false;\n throw error;\n }\n }\n}\n"],"mappings":"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","names":["ethersAddress"]}
1
+ {"version":3,"sources":["../src/integrations/ethers.ts"],"sourcesContent":["import {\n Contract,\n zeroPadValue,\n Interface,\n TypedDataEncoder,\n verifyTypedData,\n getAddress as ethersAddress,\n getBytes,\n keccak256,\n isError,\n type Provider,\n type Signer,\n} from \"ethers\";\nimport type { Address, Hex } from \"@invisi-labs/protocol/contracts\";\nconst getAddress = (value: string): Address => ethersAddress(value) as Address;\nimport {\n invisiProtocolAbi,\n invisiAddressRegistryAbi,\n invisiFactoryAbi,\n} from \"@invisi-labs/protocol/contracts\";\nimport { ReceivingAddress, type ReceivingKeyLookup } from \"@invisi-labs/core/address\";\nimport type {\n ChainReader,\n FactoryReader,\n RegistryReader,\n RegistryContext,\n TransactionContext,\n DeploymentContext,\n CanonicalBlock,\n CanonicalReceipt,\n} from \"@invisi-labs/protocol\";\nimport type { FundingSigner, FundingTypedData, FundingAuthorizationVerifier } from \"../session\";\n\nconst erc1271Abi = [\n \"function isValidSignature(bytes32 hash, bytes signature) view returns (bytes4)\",\n];\nfunction fundingTypes(data: FundingTypedData) {\n const types = Object.fromEntries(\n Object.entries(data.types).map(([name, fields]) => [name, [...fields]])\n );\n check(\n TypedDataEncoder.from(types).primaryType === data.primaryType,\n \"funding typed-data primary type mismatch\"\n );\n return types;\n}\n\nfunction check(value: unknown, message: string): asserts value {\n if (!value) {\n throw new Error(message);\n }\n}\n\nasync function chain(client: Provider, expected: bigint): Promise<void> {\n check((await client.getNetwork()).chainId === expected, \"EVM client chain mismatch\");\n}\n\nfunction number(value: unknown): bigint {\n check(typeof value === \"bigint\" && value >= 0n, \"invalid chain integer\");\n return value;\n}\n\nfunction boolean(value: unknown): boolean {\n check(typeof value === \"boolean\", \"invalid chain boolean\");\n return value;\n}\n\nfunction word(value: unknown): Hex {\n check(typeof value === \"string\" && /^0x[0-9a-fA-F]{64}$/.test(value), \"invalid chain word\");\n return value.toLowerCase() as Hex;\n}\n\nfunction ownerWord(value: Hex): Hex {\n // Public owners use canonical EVM addresses; registry slots remain bytes32.\n const identity = ReceivingAddress.fromIdentity(value).walletIdentity;\n return zeroPadValue(identity, 32) as Hex;\n}\n\n/** Reads exact block numbers; higher layers additionally enforce post-read snapshot barriers. */\nexport class EthersChainReader implements ChainReader, RegistryReader, FactoryReader {\n constructor(readonly client: Provider) {}\n\n async getChainId() {\n return (await this.client.getNetwork()).chainId;\n }\n\n async isValidRegistrationSignature(\n owner: Address,\n digest: Hex,\n signature: Hex\n ): Promise<boolean> {\n try {\n const result = await this.client.call({\n to: getAddress(owner),\n data: new Interface(erc1271Abi).encodeFunctionData(\"isValidSignature\", [\n digest,\n signature,\n ]),\n });\n // SignatureChecker compares the complete first return word, including padding.\n return (\n result.length >= 66 &&\n result.slice(0, 66).toLowerCase() === \"0x1626ba7e\" + \"00\".repeat(28)\n );\n } catch (error) {\n if (isError(error, \"CALL_EXCEPTION\")) return false;\n throw error;\n }\n }\n\n async getProtocolAddressRegistry(address: Address): Promise<Address> {\n return getAddress(\n await new Contract(getAddress(address), invisiProtocolAbi, this.client).getFunction(\n \"addressRegistry\"\n )()\n );\n }\n\n async getProtocolVersion(address: Address): Promise<bigint> {\n return BigInt(\n await new Contract(getAddress(address), invisiProtocolAbi, this.client).getFunction(\n \"VERSION\"\n )()\n );\n }\n\n async getCode(address: Address): Promise<Hex> {\n return (await this.client.getCode(getAddress(address))) as Hex;\n }\n\n async getFactoryInstanceAddress(factory: Address, salt: Hex): Promise<Address> {\n return getAddress(\n await new Contract(factory, invisiFactoryAbi, this.client).getFunction(\n \"getInstanceAddress\"\n )(salt)\n );\n }\n async isFactoryInstance(factory: Address, instance: Address): Promise<boolean> {\n return boolean(\n await new Contract(factory, invisiFactoryAbi, this.client).getFunction(\"isInstance\")(\n instance\n )\n );\n }\n async getInstanceFactory(instance: Address): Promise<Address> {\n return getAddress(\n await new Contract(instance, invisiProtocolAbi, this.client).getFunction(\"factory\")()\n );\n }\n async getLatestBlockNumber() {\n return BigInt(await this.client.getBlockNumber());\n }\n\n async getBlock(blockNumber: bigint): Promise<CanonicalBlock> {\n const block = await this.client.getBlock(blockNumber);\n check(\n block && BigInt(block.number) === blockNumber && block.hash && block.parentHash,\n \"invalid canonical block\"\n );\n return {\n number: BigInt(block.number),\n hash: word(block.hash),\n parentHash: word(block.parentHash),\n timestamp: number(BigInt(block.timestamp)),\n };\n }\n\n private async read(\n context: { chainId: bigint },\n address: Address,\n abi: ConstructorParameters<typeof Interface>[0],\n functionName: string,\n args: readonly unknown[],\n block?: CanonicalBlock\n ): Promise<unknown> {\n await chain(this.client, context.chainId);\n if (block) {\n check(\n (await this.getBlock(block.number)).hash === block.hash,\n \"canonical read block mismatch\"\n );\n }\n return new Contract(getAddress(address), abi, this.client).getFunction(functionName)(\n ...args,\n ...(block ? [{ blockTag: block.number }] : [])\n );\n }\n\n async getFundingNonce(context: DeploymentContext, payer: Address, block: CanonicalBlock) {\n return number(\n await this.read(\n context,\n context.protocolAddress,\n invisiProtocolAbi,\n \"nonces\",\n [getAddress(payer)],\n block\n )\n );\n }\n\n async getRegistryNonce(context: RegistryContext, walletIdentity: Hex, block: CanonicalBlock) {\n return number(\n await this.read(\n context,\n context.registryAddress,\n invisiAddressRegistryAbi,\n \"nonceOf\",\n [ownerWord(walletIdentity)],\n block\n )\n );\n }\n\n async isKnownRoot(\n context: DeploymentContext,\n treeId: bigint,\n root: Hex,\n block: CanonicalBlock\n ) {\n return boolean(\n await this.read(\n context,\n context.protocolAddress,\n invisiProtocolAbi,\n \"rootHistory\",\n [number(treeId), word(root)],\n block\n )\n );\n }\n\n async isSpent(context: DeploymentContext, nullifiers: readonly Hex[], block: CanonicalBlock) {\n const copied = nullifiers.map(word);\n const result: boolean[] = [];\n for (let offset = 0; offset < copied.length; offset += 32) {\n result.push(\n ...(await Promise.all(\n copied\n .slice(offset, offset + 32)\n .map((nf) =>\n this.read(\n context,\n context.protocolAddress,\n invisiProtocolAbi,\n \"isNullifierSpent\",\n [nf],\n block\n ).then(boolean)\n )\n ))\n );\n }\n return result;\n }\n\n async getTransaction(hash: Hex) {\n try {\n const tx = await this.client.getTransaction(word(hash));\n if (!tx?.to) {\n return null;\n }\n return {\n transactionHash: word(tx.hash),\n to: getAddress(tx.to),\n from: getAddress(tx.from),\n nonce: number(BigInt(tx.nonce)),\n data: tx.data as Hex,\n value: number(tx.value),\n };\n } catch (error) {\n if (error instanceof Error && error.name === \"TransactionNotFoundError\") {\n return null;\n }\n throw error;\n }\n }\n\n async getReceipt(hash: Hex): Promise<CanonicalReceipt | null> {\n try {\n const receipt = await this.client.getTransactionReceipt(word(hash));\n if (!receipt) return null;\n const block = await this.getBlock(BigInt(receipt.blockNumber));\n check(block.hash === receipt.blockHash, \"receipt block is no longer canonical\");\n return {\n block,\n transactionHash: word(receipt.hash),\n status: receipt.status === 1 ? \"success\" : \"reverted\",\n logs: receipt.logs.map((log) => {\n check(\n !log.removed && log.transactionHash === receipt.hash && log.index !== null,\n \"invalid receipt log\"\n );\n return {\n address: getAddress(log.address),\n data: log.data as Hex,\n topics: [...log.topics] as Hex[],\n transactionHash: word(log.transactionHash),\n logIndex: log.index,\n };\n }),\n };\n } catch (error) {\n if (error instanceof Error && error.name === \"TransactionReceiptNotFoundError\") {\n return null;\n }\n throw error;\n }\n }\n}\n\n/** Resolves only the explicitly selected registry. Validates canonical public key encodings. */\nexport class EthersAddressResolver {\n readonly #context: Readonly<RegistryContext>;\n\n constructor(\n readonly client: Provider,\n context: RegistryContext,\n readonly expectedRuntimeCodeHash?: Hex\n ) {\n this.#context = Object.freeze({\n ...context,\n registryAddress: getAddress(context.registryAddress),\n });\n check(BigInt(context.registryAddress) !== 0n, \"invalid registry address\");\n }\n\n readonly lookup: ReceivingKeyLookup = async (walletIdentity) => {\n await chain(this.client, this.#context.chainId);\n if (this.expectedRuntimeCodeHash) {\n const code = await this.client.getCode(this.#context.registryAddress);\n check(\n code !== \"0x\" && keccak256(code) === this.expectedRuntimeCodeHash,\n \"registry runtime profile mismatch\"\n );\n }\n const block = await this.client.getBlock(\"latest\");\n check(block && block.hash, \"invalid registry block\");\n const contract = new Contract(\n this.#context.registryAddress,\n invisiAddressRegistryAbi,\n this.client\n );\n const registered = await contract.getFunction(\"isRegistered\")(ownerWord(walletIdentity), {\n blockTag: block.number,\n });\n if (!registered) return null;\n const [keys] = await contract.getFunction(\"receivingKeysOf\")(ownerWord(walletIdentity), {\n blockTag: block.number,\n });\n check(\n (await this.client.getBlock(block.number))?.hash === block.hash,\n \"canonical registry read changed\"\n );\n return ReceivingAddress.from({\n walletIdentity,\n viewingPublicKey: getBytes(keys.viewingPublicKey),\n clueKey: getBytes(keys.clueKey),\n }).getReceivingKeys();\n };\n}\n\nexport class EthersFundingSigner implements FundingSigner {\n readonly address: Address;\n constructor(\n readonly signer: Signer,\n readonly chainId: bigint,\n address: Address\n ) {\n this.address = getAddress(address);\n }\n static async create(signer: Signer, chainId: bigint): Promise<EthersFundingSigner> {\n return new EthersFundingSigner(signer, chainId, getAddress(await signer.getAddress()));\n }\n async signTypedData(data: FundingTypedData): Promise<Hex> {\n const copied = structuredClone(data);\n check(\n BigInt(copied.domain.chainId as bigint) === this.chainId,\n \"funding typed-data chain mismatch\"\n );\n check(\n getAddress(await this.signer.getAddress()) === this.address,\n \"funding signer address mismatch\"\n );\n if (this.signer.provider) await chain(this.signer.provider, this.chainId);\n return (await this.signer.signTypedData(\n copied.domain,\n fundingTypes(copied),\n copied.message\n )) as Hex;\n }\n}\n\nexport class EthersFundingVerifier implements FundingAuthorizationVerifier {\n constructor(\n readonly client: Provider,\n readonly chainId: bigint\n ) {}\n async verifyTypedData(\n data: FundingTypedData & { address: Address; signature: Hex }\n ): Promise<boolean> {\n const copied = structuredClone(data);\n check(\n BigInt(copied.domain.chainId as bigint) === this.chainId,\n \"funding typed-data chain mismatch\"\n );\n await chain(this.client, this.chainId);\n const address = getAddress(copied.address);\n if ((await this.client.getCode(address)) === \"0x\") {\n try {\n return (\n getAddress(\n verifyTypedData(\n copied.domain,\n fundingTypes(copied),\n copied.message,\n copied.signature\n )\n ) === address\n );\n } catch {\n return false;\n }\n }\n try {\n return (\n (await new Contract(address, erc1271Abi, this.client).getFunction(\n \"isValidSignature\"\n )(\n TypedDataEncoder.hash(copied.domain, fundingTypes(copied), copied.message),\n copied.signature\n )) === \"0x1626ba7e\"\n );\n } catch (error) {\n if (isError(error, \"CALL_EXCEPTION\")) return false;\n throw error;\n }\n }\n}\n"],"mappings":"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","names":["ethersAddress"]}
package/dist/ethers.d.cts CHANGED
@@ -2,7 +2,7 @@ import { Provider, Signer } from 'ethers';
2
2
  import { Hex, Address } from '@invisi-labs/protocol/contracts';
3
3
  import { ReceivingKeyLookup } from '@invisi-labs/core/address';
4
4
  import { RegistryContext, ChainReader, RegistryReader, FactoryReader, CanonicalBlock, DeploymentContext, CanonicalReceipt } from '@invisi-labs/protocol';
5
- import { F as FundingSigner, j as FundingTypedData, h as FundingAuthorizationVerifier } from './gas-estimation-Byi278aa.cjs';
5
+ import { F as FundingSigner, j as FundingTypedData, h as FundingAuthorizationVerifier } from './gas-estimation-BV8WdwNF.cjs';
6
6
  import '@invisi-labs/core';
7
7
  import './state-DHl6j33x.cjs';
8
8
  import '@invisi-labs/prover';
@@ -12,6 +12,8 @@ declare class EthersChainReader implements ChainReader, RegistryReader, FactoryR
12
12
  readonly client: Provider;
13
13
  constructor(client: Provider);
14
14
  getChainId(): Promise<bigint>;
15
+ isValidRegistrationSignature(owner: Address, digest: Hex, signature: Hex): Promise<boolean>;
16
+ getProtocolAddressRegistry(address: Address): Promise<Address>;
15
17
  getProtocolVersion(address: Address): Promise<bigint>;
16
18
  getCode(address: Address): Promise<Hex>;
17
19
  getFactoryInstanceAddress(factory: Address, salt: Hex): Promise<Address>;
package/dist/ethers.d.ts CHANGED
@@ -2,7 +2,7 @@ import { Provider, Signer } from 'ethers';
2
2
  import { Hex, Address } from '@invisi-labs/protocol/contracts';
3
3
  import { ReceivingKeyLookup } from '@invisi-labs/core/address';
4
4
  import { RegistryContext, ChainReader, RegistryReader, FactoryReader, CanonicalBlock, DeploymentContext, CanonicalReceipt } from '@invisi-labs/protocol';
5
- import { F as FundingSigner, j as FundingTypedData, h as FundingAuthorizationVerifier } from './gas-estimation-CUZXjsO7.js';
5
+ import { F as FundingSigner, j as FundingTypedData, h as FundingAuthorizationVerifier } from './gas-estimation-v9OjKMsL.js';
6
6
  import '@invisi-labs/core';
7
7
  import './state-DHl6j33x.js';
8
8
  import '@invisi-labs/prover';
@@ -12,6 +12,8 @@ declare class EthersChainReader implements ChainReader, RegistryReader, FactoryR
12
12
  readonly client: Provider;
13
13
  constructor(client: Provider);
14
14
  getChainId(): Promise<bigint>;
15
+ isValidRegistrationSignature(owner: Address, digest: Hex, signature: Hex): Promise<boolean>;
16
+ getProtocolAddressRegistry(address: Address): Promise<Address>;
15
17
  getProtocolVersion(address: Address): Promise<bigint>;
16
18
  getCode(address: Address): Promise<Hex>;
17
19
  getFactoryInstanceAddress(factory: Address, salt: Hex): Promise<Address>;
package/dist/ethers.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  EthersChainReader,
4
4
  EthersFundingSigner,
5
5
  EthersFundingVerifier
6
- } from "./chunk-NAEEEZMH.js";
6
+ } from "./chunk-4HMM7ZKY.js";
7
7
  export {
8
8
  EthersAddressResolver,
9
9
  EthersChainReader,
@@ -37,6 +37,7 @@ interface FundingSource {
37
37
  permit?: NonNullable<FundingInput["permit"]>;
38
38
  }
39
39
  interface PaymentOutput {
40
+ memo?: string | Uint8Array;
40
41
  to: string;
41
42
  amount: bigint;
42
43
  }
@@ -75,6 +76,7 @@ interface PreparedOutput {
75
76
  change: boolean;
76
77
  }
77
78
  interface CreateCreditPreparation {
79
+ memo?: string | Uint8Array;
78
80
  tokenAddress: Address;
79
81
  spender: string;
80
82
  amount: bigint;
@@ -87,10 +89,12 @@ interface DrawCreditPreparation {
87
89
  credits: readonly {
88
90
  credit: Hex;
89
91
  amount: bigint;
92
+ memo?: string | Uint8Array;
90
93
  }[];
91
94
  deadline?: bigint;
92
95
  }
93
96
  interface TopUpCreditPreparation {
97
+ memo?: string | Uint8Array;
94
98
  tokenAddress: Address;
95
99
  credit: Hex;
96
100
  additionalAmount: bigint;
@@ -37,6 +37,7 @@ interface FundingSource {
37
37
  permit?: NonNullable<FundingInput["permit"]>;
38
38
  }
39
39
  interface PaymentOutput {
40
+ memo?: string | Uint8Array;
40
41
  to: string;
41
42
  amount: bigint;
42
43
  }
@@ -75,6 +76,7 @@ interface PreparedOutput {
75
76
  change: boolean;
76
77
  }
77
78
  interface CreateCreditPreparation {
79
+ memo?: string | Uint8Array;
78
80
  tokenAddress: Address;
79
81
  spender: string;
80
82
  amount: bigint;
@@ -87,10 +89,12 @@ interface DrawCreditPreparation {
87
89
  credits: readonly {
88
90
  credit: Hex;
89
91
  amount: bigint;
92
+ memo?: string | Uint8Array;
90
93
  }[];
91
94
  deadline?: bigint;
92
95
  }
93
96
  interface TopUpCreditPreparation {
97
+ memo?: string | Uint8Array;
94
98
  tokenAddress: Address;
95
99
  credit: Hex;
96
100
  additionalAmount: bigint;
package/dist/index.cjs CHANGED
@@ -26,6 +26,7 @@ __export(src_exports, {
26
26
  DisclosureVerifier: () => DisclosureVerifier,
27
27
  EncryptedWalletCodec: () => EncryptedWalletCodec,
28
28
  Invisi: () => Invisi,
29
+ MAX_MEMO_BYTES: () => import_core15.MAX_MEMO_BYTES,
29
30
  MissingCapabilityError: () => import_core15.MissingCapabilityError,
30
31
  NullifierCapability: () => import_core15.NullifierCapability,
31
32
  Operation: () => Operation,
@@ -38,7 +39,9 @@ __export(src_exports, {
38
39
  Wallet: () => import_core15.Wallet,
39
40
  WalletAuthorization: () => import_core15.WalletAuthorization,
40
41
  WalletSession: () => WalletSession,
42
+ decodeMemoText: () => import_core15.decodeMemoText,
41
43
  defineGasBenchmarks: () => defineGasBenchmarks,
44
+ encodeMemo: () => import_core15.encodeMemo,
42
45
  walletBalance: () => walletBalance
43
46
  });
44
47
  module.exports = __toCommonJS(src_exports);
@@ -1633,6 +1636,7 @@ var Preparation = class {
1633
1636
  const recipient = await import_core4.ReceivingAddress.parse(payment.to).resolve(
1634
1637
  this.runtime.options.addressResolver
1635
1638
  );
1639
+ const memo = (0, import_core4.encodeMemo)(payment.memo);
1636
1640
  const nonce = (0, import_core4.generateNonce)();
1637
1641
  const identity = await (0, import_core4.computeNoteIdentity)(BigInt(recipient.walletIdentity), nonce);
1638
1642
  const keys = recipient.getReceivingKeys();
@@ -1642,6 +1646,7 @@ var Preparation = class {
1642
1646
  tokenAddress: BigInt(context.tokenAddress),
1643
1647
  walletIdentity: recipient.walletIdentity,
1644
1648
  amount: payment.amount,
1649
+ ...memo.length === 0 ? {} : { memo },
1645
1650
  nonce
1646
1651
  };
1647
1652
  const commitment = await (0, import_core4.computeNoteCommitment)(
@@ -1901,6 +1906,7 @@ var CreditPreparation = class {
1901
1906
  ownerPayout: BigInt(ownerPayout),
1902
1907
  spenderPayout: BigInt(spenderPayout),
1903
1908
  amount: options.amount,
1909
+ ...options.memo === void 0 ? {} : { memo: options.memo },
1904
1910
  expiry,
1905
1911
  nonce: (0, import_core6.generateNonce)(),
1906
1912
  creditSharedKey: (0, import_core6.generateCreditSharedKey)()
@@ -1992,7 +1998,16 @@ var CreditPreparation = class {
1992
1998
  }
1993
1999
  const amount = positiveAmount(old.note.amount + options.additionalAmount, 126);
1994
2000
  const output = await this.seal(
1995
- { ...old, note: { ...old.note, amount, expiry, nonce: (0, import_core6.generateNonce)() } },
2001
+ {
2002
+ ...old,
2003
+ note: {
2004
+ ...old.note,
2005
+ amount,
2006
+ expiry,
2007
+ nonce: (0, import_core6.generateNonce)(),
2008
+ ...options.memo === void 0 ? {} : { memo: options.memo }
2009
+ }
2010
+ },
1996
2011
  frame
1997
2012
  );
1998
2013
  return this.creation(
@@ -2058,6 +2073,7 @@ var CreditPreparation = class {
2058
2073
  note: {
2059
2074
  ...n,
2060
2075
  amount: remaining,
2076
+ ...options.credits[i].memo === void 0 ? {} : { memo: options.credits[i].memo },
2061
2077
  nonce: await (0, import_core6.deriveRemainderNonce)(...args)
2062
2078
  }
2063
2079
  },
@@ -2434,6 +2450,28 @@ var EthersChainReader = class {
2434
2450
  async getChainId() {
2435
2451
  return (await this.client.getNetwork()).chainId;
2436
2452
  }
2453
+ async isValidRegistrationSignature(owner, digest, signature) {
2454
+ try {
2455
+ const result = await this.client.call({
2456
+ to: getAddress5(owner),
2457
+ data: new import_ethers7.Interface(erc1271Abi).encodeFunctionData("isValidSignature", [
2458
+ digest,
2459
+ signature
2460
+ ])
2461
+ });
2462
+ return result.length >= 66 && result.slice(0, 66).toLowerCase() === "0x1626ba7e" + "00".repeat(28);
2463
+ } catch (error) {
2464
+ if ((0, import_ethers7.isError)(error, "CALL_EXCEPTION")) return false;
2465
+ throw error;
2466
+ }
2467
+ }
2468
+ async getProtocolAddressRegistry(address2) {
2469
+ return getAddress5(
2470
+ await new import_ethers7.Contract(getAddress5(address2), import_contracts.invisiProtocolAbi, this.client).getFunction(
2471
+ "addressRegistry"
2472
+ )()
2473
+ );
2474
+ }
2437
2475
  async getProtocolVersion(address2) {
2438
2476
  return BigInt(
2439
2477
  await new import_ethers7.Contract(getAddress5(address2), import_contracts.invisiProtocolAbi, this.client).getFunction(
@@ -2972,25 +3010,27 @@ function extractDeliveryCandidates(logs, context, confirmedThrough) {
2972
3010
  const tokens = array(a.tokens);
2973
3011
  const cs = array(a.commitments), tree = integer(a.treeId), start = index(a.startLeafIndex), packed = a.packedDeliveries;
2974
3012
  check4(
2975
- typeof packed === "string" && /^0x(?:[0-9a-fA-F]{2})*$/.test(packed) && packed.length === 2 + 452 * cs.length,
3013
+ typeof packed === "string" && /^0x(?:[0-9a-fA-F]{2})*$/.test(packed),
2976
3014
  "invalid packed deliveries"
2977
3015
  );
2978
3016
  check4(tokens.length === cs.length, "batch token count mismatch");
3017
+ check4(start + cs.length <= 65536, "batch exceeds tree capacity");
3018
+ let offset = 2;
2979
3019
  cs.forEach((c, i) => {
2980
- const segment = packed.slice(2 + 452 * i, 2 + 452 * (i + 1));
2981
- add(
2982
- log,
2983
- tree,
2984
- start + i,
2985
- c,
2986
- "funds",
2987
- {
2988
- ciphertext: `0x${segment.slice(0, 316)}`,
2989
- clue: `0x${segment.slice(316)}`
2990
- },
2991
- tokens[i]
3020
+ check4(offset + 4 <= packed.length, "truncated delivery length prefix");
3021
+ const length = Number.parseInt(packed.slice(offset, offset + 4), 16);
3022
+ offset += 4;
3023
+ check4(
3024
+ length >= 160 && length <= 416 && offset + length * 2 + 136 <= packed.length,
3025
+ "invalid packed delivery length"
2992
3026
  );
3027
+ const ciphertext = `0x${packed.slice(offset, offset + length * 2)}`;
3028
+ offset += length * 2;
3029
+ const clue = `0x${packed.slice(offset, offset + 136)}`;
3030
+ offset += 136;
3031
+ add(log, tree, start + i, c, "funds", { ciphertext, clue }, tokens[i]);
2993
3032
  });
3033
+ check4(offset === packed.length, "trailing packed delivery bytes");
2994
3034
  } else if (log.eventName === "CreditCreated") creation(log, a, a);
2995
3035
  else if (log.eventName === "CreditToppedUp")
2996
3036
  creation(log, a, object(object(a.params).creation));
@@ -4401,6 +4441,10 @@ var InventoryProcessor = class {
4401
4441
  if (!remainder) {
4402
4442
  continue;
4403
4443
  }
4444
+ const child = foundByKey.get(
4445
+ params.remainderCommitments[index2] + ":" + previous.role
4446
+ );
4447
+ const memo = child?.state.note.memo;
4404
4448
  const record = {
4405
4449
  commitment: params.remainderCommitments[index2],
4406
4450
  treeId: BigInt(args.outputTreeId),
@@ -4409,7 +4453,13 @@ var InventoryProcessor = class {
4409
4453
  blockHash: event.blockHash,
4410
4454
  transactionHash: event.transactionHash,
4411
4455
  role: previous.role,
4412
- state: { ...clone(previous.state), note: remainder },
4456
+ state: {
4457
+ ...clone(previous.state),
4458
+ note: {
4459
+ ...remainder,
4460
+ ...memo === void 0 ? {} : { memo: (0, import_core11.encodeMemo)(memo) }
4461
+ }
4462
+ },
4413
4463
  receivingKeySource: { kind: "draw", commitment: previous.commitment },
4414
4464
  spent: "unknown"
4415
4465
  };
@@ -5110,6 +5160,7 @@ var EncryptedWalletCodec = class _EncryptedWalletCodec {
5110
5160
  DisclosureVerifier,
5111
5161
  EncryptedWalletCodec,
5112
5162
  Invisi,
5163
+ MAX_MEMO_BYTES,
5113
5164
  MissingCapabilityError,
5114
5165
  NullifierCapability,
5115
5166
  Operation,
@@ -5122,7 +5173,9 @@ var EncryptedWalletCodec = class _EncryptedWalletCodec {
5122
5173
  Wallet,
5123
5174
  WalletAuthorization,
5124
5175
  WalletSession,
5176
+ decodeMemoText,
5125
5177
  defineGasBenchmarks,
5178
+ encodeMemo,
5126
5179
  walletBalance
5127
5180
  });
5128
5181
  //# sourceMappingURL=index.cjs.map