@zama-fhe/sdk 3.8.0-beta.13 → 3.8.0-beta.14

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.
Files changed (81) hide show
  1. package/dist/cjs/base-signer.cjs +1 -1
  2. package/dist/cjs/ethers/index.cjs +1 -1
  3. package/dist/cjs/index.cjs +1 -1
  4. package/dist/cjs/index.cjs.map +1 -1
  5. package/dist/cjs/query/index.cjs +1 -1
  6. package/dist/cjs/relayer.cjs +1 -1
  7. package/dist/cjs/relayer.cjs.map +1 -1
  8. package/dist/cjs/telemetry.cjs +1 -1
  9. package/dist/cjs/telemetry.cjs.map +1 -1
  10. package/dist/cjs/token.cjs +1 -1
  11. package/dist/cjs/token.cjs.map +1 -1
  12. package/dist/cjs/vaults/index.cjs +1 -1
  13. package/dist/cjs/vaults/index.cjs.map +1 -1
  14. package/dist/cjs/viem/index.cjs +1 -1
  15. package/dist/cjs/wrapped-token.cjs +1 -1
  16. package/dist/cjs/wrapped-token.cjs.map +1 -1
  17. package/dist/cjs/wrappers-registry.cjs +1 -1
  18. package/dist/cjs/wrappers-registry.cjs.map +1 -1
  19. package/dist/esm/base-signer-3sG3Xkts.js +2 -0
  20. package/dist/esm/{base-signer-6YPpqhw9.js.map → base-signer-3sG3Xkts.js.map} +1 -1
  21. package/dist/esm/{base-signer-DKHbbrIT.d.ts → base-signer-8USxGaww.d.ts} +2 -2
  22. package/dist/esm/cleartext/index.d.ts +2 -2
  23. package/dist/esm/cleartext/index.js +1 -1
  24. package/dist/esm/{cleartext-C--gPqhI.d.ts → cleartext-DrM4cW3t.d.ts} +2 -2
  25. package/dist/esm/{cleartext-RqXnz7I6.js → cleartext-nCn9kYJS.js} +2 -2
  26. package/dist/esm/{cleartext-RqXnz7I6.js.map → cleartext-nCn9kYJS.js.map} +1 -1
  27. package/dist/esm/{encrypt-worker-client-BlQ06ILZ.d.ts → encrypt-worker-client-COTXc_1W.d.ts} +2 -2
  28. package/dist/esm/{encryption-ieCO6J5r.js → encryption-CmS92gcG.js} +2 -2
  29. package/dist/esm/{encryption-ieCO6J5r.js.map → encryption-CmS92gcG.js.map} +1 -1
  30. package/dist/esm/ethers/index.d.ts +3 -3
  31. package/dist/esm/ethers/index.js +1 -1
  32. package/dist/esm/ethers/index.js.map +1 -1
  33. package/dist/esm/{fatal-batch-CI1pes1q.js → fatal-batch-DiOf61zk.js} +2 -2
  34. package/dist/esm/{fatal-batch-CI1pes1q.js.map → fatal-batch-DiOf61zk.js.map} +1 -1
  35. package/dist/esm/{fhevm-relayer-DF4uuzDF.js → fhevm-relayer-6tb2mmPB.js} +2 -2
  36. package/dist/esm/{fhevm-relayer-DF4uuzDF.js.map → fhevm-relayer-6tb2mmPB.js.map} +1 -1
  37. package/dist/esm/{index-CnxoTnTi.d.ts → index-DT35Rcla.d.ts} +3 -3
  38. package/dist/esm/{index-B-bk_RhJ.d.ts → index-DdilY3Dd.d.ts} +4952 -1416
  39. package/dist/esm/{index-DrTWm3Aw.d.ts → index-saxxnsEo.d.ts} +6 -6
  40. package/dist/esm/index.d.ts +8 -8
  41. package/dist/esm/index.js +1 -1
  42. package/dist/esm/index.js.map +1 -1
  43. package/dist/esm/internal/index.d.ts +3 -3
  44. package/dist/esm/internal/index.js +1 -1
  45. package/dist/esm/node/index.d.ts +3 -3
  46. package/dist/esm/node/index.js +1 -1
  47. package/dist/esm/query/index.d.ts +4 -4
  48. package/dist/esm/query/index.js +1 -1
  49. package/dist/esm/{relayer-ov8b_HOu.js → relayer-BSx1sH7X.js} +2 -2
  50. package/dist/esm/{relayer-ov8b_HOu.js.map → relayer-BSx1sH7X.js.map} +1 -1
  51. package/dist/esm/{signing-CneT-WIV.js → signing-B9kttd7Z.js} +2 -2
  52. package/dist/esm/{signing-CneT-WIV.js.map → signing-B9kttd7Z.js.map} +1 -1
  53. package/dist/esm/{telemetry-D9Mf59ts.js → telemetry-B04S28Sb.js} +2 -2
  54. package/dist/esm/telemetry-B04S28Sb.js.map +1 -0
  55. package/dist/esm/token-BW1UzTUP.js +2 -0
  56. package/dist/esm/token-BW1UzTUP.js.map +1 -0
  57. package/dist/esm/{types-BF5HtmsQ.d.ts → types-Bj--dFQv.d.ts} +2 -2
  58. package/dist/esm/{types-CKtpO41S.d.ts → types-D006gRq-.d.ts} +3 -3
  59. package/dist/esm/{types-BR69mm5U.d.ts → types-DGUt8ary.d.ts} +2 -2
  60. package/dist/esm/{validation-ChQwNxaY.js → validation-DSFC9ibc.js} +2 -2
  61. package/dist/esm/{validation-ChQwNxaY.js.map → validation-DSFC9ibc.js.map} +1 -1
  62. package/dist/esm/vaults/index.d.ts +2076 -19
  63. package/dist/esm/vaults/index.js +1 -1
  64. package/dist/esm/vaults/index.js.map +1 -1
  65. package/dist/esm/viem/index.d.ts +3 -3
  66. package/dist/esm/viem/index.js +1 -1
  67. package/dist/esm/web/index.d.ts +2 -2
  68. package/dist/esm/web/index.js +1 -1
  69. package/dist/esm/wrapped-token-k3JWYR9E.js +2 -0
  70. package/dist/esm/wrapped-token-k3JWYR9E.js.map +1 -0
  71. package/dist/esm/wrappers-registry-D7ZE7Bff.js +2 -0
  72. package/dist/esm/wrappers-registry-D7ZE7Bff.js.map +1 -0
  73. package/package.json +1 -1
  74. package/dist/esm/base-signer-6YPpqhw9.js +0 -2
  75. package/dist/esm/telemetry-D9Mf59ts.js.map +0 -1
  76. package/dist/esm/token-DlsiZmg5.js +0 -2
  77. package/dist/esm/token-DlsiZmg5.js.map +0 -1
  78. package/dist/esm/wrapped-token-C8eKid8W.js +0 -2
  79. package/dist/esm/wrapped-token-C8eKid8W.js.map +0 -1
  80. package/dist/esm/wrappers-registry-DnYVQ02R.js +0 -2
  81. package/dist/esm/wrappers-registry-DnYVQ02R.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["eventTopic","topicToAddress","wordToBytes32","#vault","#fromToken","#toToken","isEncryptedValueZero","DecryptionFailedError","withOperation","#requireSigner","requireAlignedWalletAccount","#assertJoinableBalance","EncryptionFailedError","#submitTransaction","TransactionRevertedError","requireChainAlignment","#resolveTarget","SignerNotConfiguredError","#inputToken","#fromTokenInstance","Token","assertConfidentialBalance","submitSdkTransaction","#expectedVaultAddress","#vaultAddress","#resolveVaultAddress","#cAsset","WrappedToken","#cShare","#ensureOperator","ConfigurationError","SignerNotConfiguredError","#registry","ConfigurationError","isConfidentialTokenValidContract","withOperation","#caller","#legs","#requireAssetListed","#assertBalance","#encryptLegs","EncryptionFailedError","#submitTransaction","confidentialTransferAndCallContract","#result","SignerNotConfiguredError","requireAlignedWalletAccount","#leg","VaultBatcherPausedError","assertConfidentialBalance","Token","BalanceCheckUnavailableError","UnlistedConfidentialTokenError","submitSdkTransaction","VaultGroupJoinUnconfirmedError","filterQueryOptions","filterQueryOptions","filterQueryOptions"],"sources":["../../../src/utils/memoize-address-read.ts","../../../src/vaults/abi/vault-batcher.abi.ts","../../../src/vaults/contracts/vault-batcher.ts","../../../src/vaults/abi/vault-router.abi.ts","../../../src/vaults/contracts/vault-router.ts","../../../src/vaults/events.ts","../../../src/vaults/types.ts","../../../src/vaults/vault-batcher.ts","../../../src/vaults/vault.ts","../../../src/vaults/vault-group.ts","../../../src/vaults/query/query-keys.ts","../../../src/vaults/query/invalidation.ts","../../../src/vaults/query/group-deposit.ts","../../../src/vaults/query/group-redeem.ts","../../../src/vaults/query/current-batch-id.ts","../../../src/vaults/query/batch-state.ts","../../../src/vaults/query/time-until-dispatchable.ts","../../../src/vaults/query/deposit.ts","../../../src/vaults/query/redeem.ts","../../../src/vaults/query/join.ts","../../../src/vaults/query/claim.ts","../../../src/vaults/query/quit.ts","../../../src/vaults/query/recover.ts","../../../src/vaults/query/dispatch-batch.ts"],"sourcesContent":["import type { Address } from \"viem\";\n\n/**\n * Caches the read for good and shares one in-flight call: only for addresses\n * a contract fixes at deploy time.\n *\n * @internal\n */\nexport function memoizeAddressRead(read: () => Promise<Address>): () => Promise<Address> {\n let cached: Address | undefined;\n let pending: Promise<Address> | null = null;\n return () => {\n if (cached !== undefined) {\n return Promise.resolve(cached);\n }\n if (!pending) {\n pending = read()\n .then((value) => {\n cached = value;\n pending = null;\n return value;\n })\n .catch((error) => {\n pending = null;\n throw error;\n });\n }\n return pending;\n };\n}\n","/**\n * ABI for the deposit and redeem vault batchers, which share one interface.\n * Owner-only writes and the relayer-driven `dispatchBatchCallback` are omitted;\n * every custom error is kept so reverts decode to a name.\n */\nexport const vaultBatcherAbi = [\n {\n type: \"function\",\n name: \"batchCallbackDeadline\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchCreatedAt\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchDispatchedAt\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchMaxSlippageBps\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint16\", internalType: \"uint16\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchMinBatchAge\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchState\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint8\", internalType: \"enum BatcherConfidential.BatchState\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"callbackDeadline\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"claim\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"account\", type: \"address\", internalType: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"currentBatchId\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"deposits\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"account\", type: \"address\", internalType: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"dispatchBatch\",\n inputs: [],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"exchangeRate\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint64\", internalType: \"uint64\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"exchangeRateDecimals\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\", internalType: \"uint8\" }],\n stateMutability: \"pure\",\n },\n {\n type: \"function\",\n name: \"fromToken\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract IERC7984ERC20Wrapper\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"join\",\n inputs: [\n { name: \"beneficiary\", type: \"address\", internalType: \"address\" },\n { name: \"encryptedAmount\", type: \"bytes32\", internalType: \"externalEuint64\" },\n { name: \"inputProof\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [{ name: \"joined\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"maxSlippageBps\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint16\", internalType: \"uint16\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"minBatchAge\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"paused\",\n inputs: [],\n outputs: [{ name: \"\", type: \"bool\", internalType: \"bool\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"quit\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"recover\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"account\", type: \"address\", internalType: \"address\" },\n ],\n outputs: [{ name: \"refunded\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"toToken\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract IERC7984ERC20Wrapper\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"totalDeposits\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"unwrapRequestId\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"bytes32\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"vault\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract IERC4626\" }],\n stateMutability: \"view\",\n },\n {\n type: \"event\",\n name: \"BatchCanceled\",\n inputs: [{ name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" }],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"BatchDispatched\",\n inputs: [{ name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" }],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"BatchFinalized\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" },\n { name: \"exchangeRate\", type: \"uint64\", indexed: false, internalType: \"uint64\" },\n ],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"Claimed\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" },\n { name: \"account\", type: \"address\", indexed: true, internalType: \"address\" },\n { name: \"amount\", type: \"bytes32\", indexed: false, internalType: \"euint64\" },\n ],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"Joined\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" },\n { name: \"account\", type: \"address\", indexed: true, internalType: \"address\" },\n { name: \"amount\", type: \"bytes32\", indexed: false, internalType: \"euint64\" },\n ],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"Quit\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" },\n { name: \"account\", type: \"address\", indexed: true, internalType: \"address\" },\n { name: \"amount\", type: \"bytes32\", indexed: false, internalType: \"euint64\" },\n ],\n anonymous: false,\n },\n {\n type: \"error\",\n name: \"BatchNonexistent\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n },\n {\n type: \"error\",\n name: \"BatchTooYoung\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"elapsed\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"required\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n {\n type: \"error\",\n name: \"BatchUnexpectedState\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"current\", type: \"uint8\", internalType: \"enum BatcherConfidential.BatchState\" },\n { name: \"expectedStates\", type: \"bytes32\", internalType: \"bytes32\" },\n ],\n },\n { type: \"error\", name: \"DuplicateUnderlyingTokens\", inputs: [] },\n { type: \"error\", name: \"EnforcedPause\", inputs: [] },\n { type: \"error\", name: \"ExpectedPause\", inputs: [] },\n {\n type: \"error\",\n name: \"IntermediateStepToTokenBalanceChanged\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n },\n { type: \"error\", name: \"InvalidBeneficiary\", inputs: [] },\n { type: \"error\", name: \"InvalidCallbackDeadline\", inputs: [] },\n {\n type: \"error\",\n name: \"InvalidExchangeRate\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"totalDeposits\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"exchangeRate\", type: \"uint64\", internalType: \"uint64\" },\n ],\n },\n { type: \"error\", name: \"InvalidKMSSignatures\", inputs: [] },\n { type: \"error\", name: \"InvalidMaxSlippageBps\", inputs: [] },\n { type: \"error\", name: \"InvalidMinBatchAge\", inputs: [] },\n { type: \"error\", name: \"InvalidTokenRate\", inputs: [] },\n {\n type: \"error\",\n name: \"InvalidWrapperToken\",\n inputs: [{ name: \"token\", type: \"address\", internalType: \"address\" }],\n },\n {\n type: \"error\",\n name: \"OwnableInvalidOwner\",\n inputs: [{ name: \"owner\", type: \"address\", internalType: \"address\" }],\n },\n {\n type: \"error\",\n name: \"OwnableUnauthorizedAccount\",\n inputs: [{ name: \"account\", type: \"address\", internalType: \"address\" }],\n },\n { type: \"error\", name: \"ReentrancyGuardReentrantCall\", inputs: [] },\n {\n type: \"error\",\n name: \"RouteAssetMismatch\",\n inputs: [\n { name: \"actualAsset\", type: \"address\", internalType: \"address\" },\n { name: \"expectedAsset\", type: \"address\", internalType: \"address\" },\n ],\n },\n {\n type: \"error\",\n name: \"RouteShareMismatch\",\n inputs: [\n { name: \"actualShare\", type: \"address\", internalType: \"address\" },\n { name: \"expectedShare\", type: \"address\", internalType: \"address\" },\n ],\n },\n {\n type: \"error\",\n name: \"SafeCastOverflowedUintDowncast\",\n inputs: [\n { name: \"bits\", type: \"uint8\", internalType: \"uint8\" },\n { name: \"value\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n {\n type: \"error\",\n name: \"SafeERC20FailedOperation\",\n inputs: [{ name: \"token\", type: \"address\", internalType: \"address\" }],\n },\n {\n type: \"error\",\n name: \"SenderNotAllowedToUseHandle\",\n inputs: [\n { name: \"handle\", type: \"bytes32\", internalType: \"bytes32\" },\n { name: \"sender\", type: \"address\", internalType: \"address\" },\n ],\n },\n {\n type: \"error\",\n name: \"SlippageExceeded\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"actual\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"minimum\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { type: \"error\", name: \"Unauthorized\", inputs: [] },\n { type: \"error\", name: \"ZamaProtocolUnsupported\", inputs: [] },\n {\n type: \"error\",\n name: \"ZeroDeposits\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"account\", type: \"address\", internalType: \"address\" },\n ],\n },\n] as const;\n","import type { Address, Hex } from \"viem\";\nimport type { EncryptedValue } from \"../../relayer/types\";\nimport { vaultBatcherAbi } from \"../abi/vault-batcher.abi\";\n\n/** Returns the contract config to join the currently open batch with an encrypted amount. */\nexport function joinContract(\n batcher: Address,\n beneficiary: Address,\n encryptedAmount: EncryptedValue,\n inputProof: Hex,\n) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"join\",\n args: [beneficiary, encryptedAmount, inputProof],\n } as const;\n}\n\n/** Returns the contract config to claim a finalized batch's output on behalf of `account`. Permissionless. */\nexport function claimContract(batcher: Address, batchId: bigint, account: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"claim\",\n args: [batchId, account],\n } as const;\n}\n\n/** Returns the contract config to withdraw the caller's own deposit from a pending or canceled batch. */\nexport function quitContract(batcher: Address, batchId: bigint) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"quit\", args: [batchId] } as const;\n}\n\n/** Returns the contract config to refund `account`'s deposit in a canceled batch. Permissionless — the refund goes to `account`, not the caller. */\nexport function recoverContract(batcher: Address, batchId: bigint, account: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"recover\",\n args: [batchId, account],\n } as const;\n}\n\n/** Returns the contract config to close the current batch and kick off decryption. Permissionless. */\nexport function dispatchBatchContract(batcher: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"dispatchBatch\",\n args: [],\n } as const;\n}\n\n/** Returns the contract config to read the id of the currently open batch. */\nexport function currentBatchIdContract(batcher: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"currentBatchId\",\n args: [],\n } as const;\n}\n\n/** Returns the contract config to read a batch's lifecycle state (the contract's `BatchState` enum). */\nexport function batchStateContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchState\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read a batch's encrypted aggregate deposit amount. */\nexport function totalDepositsContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"totalDeposits\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read one account's encrypted deposit within a batch. */\nexport function depositsContract(batcher: Address, batchId: bigint, account: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"deposits\",\n args: [batchId, account],\n } as const;\n}\n\n/** Returns the contract config to read the underlying ERC-4626 vault address. */\nexport function vaultContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"vault\", args: [] } as const;\n}\n\n/** Returns the contract config to read the confidential token this batcher accepts as input. */\nexport function fromTokenContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"fromToken\", args: [] } as const;\n}\n\n/** Returns the contract config to read the confidential token this batcher pays out. */\nexport function toTokenContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"toToken\", args: [] } as const;\n}\n\n/** Returns the contract config to read the batcher's current minimum-batch-age policy. */\nexport function minBatchAgeContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"minBatchAge\", args: [] } as const;\n}\n\n/** Returns the contract config to read the minimum age pinned to one batch when it opened. */\nexport function batchMinBatchAgeContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchMinBatchAge\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read the batcher's current callback-deadline policy. */\nexport function callbackDeadlineContract(batcher: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"callbackDeadline\",\n args: [],\n } as const;\n}\n\n/** Returns the contract config to read the callback deadline pinned to one batch when it opened. */\nexport function batchCallbackDeadlineContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchCallbackDeadline\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read the Unix timestamp a batch was opened at. */\nexport function batchCreatedAtContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchCreatedAt\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read the Unix timestamp a batch was dispatched at, or 0 if not yet dispatched. */\nexport function batchDispatchedAtContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchDispatchedAt\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read a finalized batch's exchange rate, or 0 while unfinalized. */\nexport function exchangeRateContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"exchangeRate\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read the number of decimals the exchange rate is scaled by. */\nexport function exchangeRateDecimalsContract(batcher: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"exchangeRateDecimals\",\n args: [],\n } as const;\n}\n\n/** Returns the contract config to read whether the batcher is paused (blocking joins and dispatch). */\nexport function pausedContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"paused\", args: [] } as const;\n}\n","/**\n * ABI for the vault batcher router, which fans one submission out across\n * several batchers. Transcribed by hand from `IVaultBatcherConfidentialRouter`\n * in zama-ai/confidential-defi at tag `oz-audit-20261016` (commit `d7cd0c8e`),\n * so `abi:check` does not cover it: compare against that ref when the router\n * changes. `onConfidentialTransferReceived` is omitted because a token calls\n * it, not the SDK; the router's custom errors are kept so its reverts decode\n * to a name.\n */\nexport const vaultRouterAbi = [\n {\n type: \"function\",\n name: \"join\",\n inputs: [\n {\n name: \"legs\",\n type: \"tuple[]\",\n internalType: \"struct IVaultBatcherConfidentialRouter.Allocation[]\",\n components: [\n { name: \"batcher\", type: \"address\", internalType: \"address\" },\n { name: \"token\", type: \"address\", internalType: \"address\" },\n { name: \"amount\", type: \"bytes32\", internalType: \"externalEuint64\" },\n ],\n },\n { name: \"inputProof\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"tokenWrapperRegistry\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract ITokenWrapperRegistry\" }],\n stateMutability: \"view\",\n },\n { type: \"error\", name: \"InvalidTokenWrapperRegistry\", inputs: [] },\n { type: \"error\", name: \"MissingInputProof\", inputs: [] },\n { type: \"error\", name: \"ReentrancyGuardReentrantCall\", inputs: [] },\n { type: \"error\", name: \"ZamaProtocolUnsupported\", inputs: [] },\n {\n type: \"error\",\n name: \"UnlistedConfidentialToken\",\n inputs: [{ name: \"token\", type: \"address\", internalType: \"address\" }],\n },\n] as const;\n","import { encodeAbiParameters, getAbiItem, type Address, type Hex } from \"viem\";\nimport type { EncryptedValue } from \"../../relayer/types\";\nimport { vaultRouterAbi } from \"../abi/vault-router.abi\";\n\n/** One vault's share of a fan-out, its amount encrypted against the router. */\nexport interface EncryptedAllocationLeg {\n readonly batcher: Address;\n /** The confidential token this leg spends. */\n readonly token: Address;\n readonly amount: EncryptedValue;\n}\n\n/** Returns the contract config to pull every leg from the caller and join each named batcher. */\nexport function routerJoinContract(\n router: Address,\n legs: readonly EncryptedAllocationLeg[],\n inputProof: Hex,\n) {\n return {\n address: router,\n abi: vaultRouterAbi,\n functionName: \"join\",\n args: [legs, inputProof],\n } as const;\n}\n\n// The push path decodes its `data` into the same pair `join` takes, so reading\n// the parameters off the ABI keeps the encoding from drifting from the call.\nconst ALLOCATION_PARAMETERS = getAbiItem({ abi: vaultRouterAbi, name: \"join\" }).inputs;\n\n/** The payload that lets one confidential transfer of the shared asset fund every leg. */\nexport function encodeAllocationData(\n legs: readonly EncryptedAllocationLeg[],\n inputProof: Hex,\n): Hex {\n return encodeAbiParameters(ALLOCATION_PARAMETERS, [legs.map((leg) => ({ ...leg })), inputProof]);\n}\n\n/** Returns the contract config to read the registry the router gates its push path on. */\nexport function tokenWrapperRegistryContract(router: Address) {\n return {\n address: router,\n abi: vaultRouterAbi,\n functionName: \"tokenWrapperRegistry\",\n args: [],\n } as const;\n}\n","import { getAddress, type Address } from \"viem\";\nimport { eventTopic, topicToAddress, wordToBytes32 } from \"../events/log-decoding\";\nimport type { EncryptedValue } from \"../relayer/types\";\nimport type { RawLog } from \"../types/transaction\";\n\n/**\n * Vault batcher event topic0 constants (keccak256 of the canonical Solidity\n * signature). Pass to `getLogs({ topics: [Object.values(VaultTopics)] })`.\n */\nexport const VaultTopics = {\n /** `Joined(uint256 indexed batchId, address indexed account, euint64 amount)` */\n Joined: eventTopic(\"Joined(uint256,address,bytes32)\"),\n} as const;\n\n/** A decoded `Joined` event. */\nexport interface JoinedEvent {\n /** The batch the join landed in. */\n batchId: bigint;\n /** The account credited — the beneficiary a join named, which may not be the caller. */\n account: Address;\n /** The encrypted amount credited, which can be zero when the pull transferred nothing. */\n confidentialAmount: EncryptedValue;\n}\n\n/**\n * Joined(uint256 indexed batchId, address indexed account, euint64 amount)\n * Indexed: batchId (topics[1]), account (topics[2])\n * Data: amount (bytes32)\n */\nexport function decodeJoined(log: RawLog): JoinedEvent | null {\n const [topic, batchId, account] = log.topics;\n if (topic !== VaultTopics.Joined || batchId === undefined || account === undefined) {\n return null;\n }\n\n return {\n batchId: BigInt(batchId),\n account: topicToAddress(account),\n confidentialAmount: wordToBytes32(log.data, 0),\n };\n}\n\nfunction matchJoined(\n log: RawLog,\n batcher: Address,\n account: Address | undefined,\n): JoinedEvent | null {\n if (log.address !== undefined && getAddress(log.address) !== batcher) {\n return null;\n }\n const event = decodeJoined(log);\n if (!event || (account !== undefined && event.account !== account)) {\n return null;\n }\n return event;\n}\n\n/**\n * Filters on `batcher`, and on `account` when given, rather than taking the\n * first match: one transaction can join several batchers and credit several\n * beneficiaries, so an unfiltered search can return someone else's batch id.\n * Logs carrying no emitter address are kept, since some adapters omit it.\n */\nexport function findJoined(\n logs: readonly RawLog[],\n batcher: Address,\n account?: Address,\n): JoinedEvent | null {\n return takeJoined([...logs], batcher, account);\n}\n\n/**\n * {@link findJoined} for a receipt with several `Joined` logs to the same\n * account: removes the match from `logs`, so walking the legs in order pairs\n * each with its own log even when the adapter omits emitter addresses.\n */\nexport function takeJoined(\n logs: RawLog[],\n batcher: Address,\n account?: Address,\n): JoinedEvent | null {\n const normalizedAccount = account ? getAddress(account) : undefined;\n for (const [index, log] of logs.entries()) {\n const event = matchJoined(log, batcher, normalizedAccount);\n if (event) {\n logs.splice(index, 1);\n return event;\n }\n }\n return null;\n}\n","import type { Address } from \"viem\";\nimport type { EncryptedValue } from \"../relayer/types\";\nimport type { TelemetryOperation } from \"../telemetry\";\nimport type { TransactionResult } from \"../types\";\n\n/**\n * A batch's lifecycle state. The numbers mirror the batcher contract's own\n * enum, so they are part of the on-chain contract, not an arbitrary encoding.\n */\nexport const BatchState = {\n /** Open: accepts joins and quits. Always the batcher's `currentBatchId`. */\n Pending: 0,\n /** Closed; the aggregate amount is being decrypted. No user action is possible. */\n Dispatched: 1,\n /** Settled with an exchange rate — the only state in which `claim` succeeds. */\n Finalized: 2,\n /** The route failed or the callback deadline passed; `quit` refunds the original deposit. */\n Canceled: 3,\n} as const;\n\n/** Union of all {@link BatchState} values. */\nexport type BatchState = (typeof BatchState)[keyof typeof BatchState];\n\n/** Addresses that make up one confidential vault. */\nexport interface VaultAddresses {\n /**\n * The ERC-4626 vault contract that holds the underlying asset and issues\n * shares. Optional — both batchers report it on chain. Passing it does not\n * skip that read: it is verified against what the batchers report.\n */\n vault?: Address;\n /** The batcher users join to deposit the confidential underlying asset into the vault. */\n depositBatcher: Address;\n /** The batcher users join to redeem confidential shares back into the underlying asset. */\n redeemBatcher: Address;\n}\n\n/** Options for {@link VaultBatcher.join}. */\nexport interface JoinOptions {\n /**\n * Skip the confidential-balance pre-flight before joining — for accounts\n * whose balance the connected signer cannot decrypt, such as smart wallets.\n */\n skipBalanceCheck?: boolean;\n /** @internal */\n readonly operation?: TelemetryOperation;\n}\n\n/** Options for {@link Vault.deposit} and {@link Vault.redeem}. */\nexport interface VaultJoinOptions extends JoinOptions {\n /**\n * Account credited in the batch. Defaults to the connected wallet address.\n *\n * Set this to join on behalf of another account — but note that the\n * beneficiary, not the caller, then owns the position: only they can\n * {@link VaultBatcher.quit} it, and {@link VaultBatcher.claim} pays out to\n * them.\n */\n beneficiary?: Address;\n /**\n * Unix timestamp until which the batcher's operator grant on the joined\n * token is valid. Only used when a grant isn't already active. Defaults to\n * `Token.setOperator`'s own default (now + 1 hour).\n */\n operatorUntil?: number;\n}\n\n/** What the batcher reported for a successful join. */\nexport interface JoinResult extends TransactionResult {\n /** The batch the join landed in. */\n batchId: bigint;\n /** The account credited — the beneficiary, which may not be the caller. */\n beneficiary: Address;\n /**\n * The encrypted amount actually credited, which is **not** always the amount\n * requested: an ERC-7984 transfer moves zero rather than reverting when the\n * balance is short. Decrypt it to confirm the join landed in full.\n */\n confidentialJoinedAmount: EncryptedValue;\n}\n","import { getAddress, type Address } from \"viem\";\nimport {\n DecryptionFailedError,\n EncryptionFailedError,\n SignerNotConfiguredError,\n TransactionRevertedError,\n} from \"../errors\";\nimport type { TransactionOperation } from \"../events/sdk-events\";\nimport type { EncryptedValue } from \"../relayer/types\";\nimport { type TelemetryOperation, withOperation } from \"../telemetry\";\nimport { Token } from \"../token\";\nimport type { GenericSigner, TransactionResult, WriteContractConfig } from \"../types\";\nimport { requireAlignedWalletAccount, requireChainAlignment } from \"../utils/alignment\";\nimport { assertConfidentialBalance } from \"../utils/assert-balance\";\nimport { assertBigint } from \"../utils/assertions\";\nimport { isEncryptedValueZero } from \"../utils/handles\";\nimport { memoizeAddressRead } from \"../utils/memoize-address-read\";\nimport { submitTransaction as submitSdkTransaction } from \"../utils/submit-transaction\";\nimport type { ZamaSDK } from \"../zama-sdk\";\nimport {\n batchCallbackDeadlineContract,\n batchCreatedAtContract,\n batchDispatchedAtContract,\n batchMinBatchAgeContract,\n batchStateContract,\n callbackDeadlineContract,\n claimContract,\n currentBatchIdContract,\n depositsContract,\n dispatchBatchContract,\n exchangeRateContract,\n exchangeRateDecimalsContract,\n fromTokenContract,\n joinContract,\n minBatchAgeContract,\n pausedContract,\n quitContract,\n recoverContract,\n toTokenContract,\n totalDepositsContract,\n vaultContract,\n} from \"./contracts\";\nimport { findJoined } from \"./events\";\nimport { BatchState, type JoinOptions, type JoinResult } from \"./types\";\n\n/**\n * One on-chain batcher contract: it pools participants' encrypted amounts,\n * dispatches only the decrypted aggregate through the underlying ERC-4626\n * vault, and lets each participant claim their share. A vault has one batcher\n * per direction, so construct one instance for deposits and one for redeems.\n *\n * The lifecycle is `join` → `dispatchBatch` → `claim`, but finalization\n * between the last two is driven by the relayer, not by the caller: a batch\n * is claimable only once it reaches {@link BatchState.Finalized}, which can be\n * well after dispatch.\n */\nexport class VaultBatcher {\n /** The SDK instance this batcher reads and writes through. */\n readonly sdk: ZamaSDK;\n /** Checksummed address of the batcher contract. */\n readonly address: Address;\n\n readonly #vault: () => Promise<Address>;\n readonly #fromToken: () => Promise<Address>;\n readonly #toToken: () => Promise<Address>;\n\n // One instance, so repeated joins reuse the token's decrypted-balance cache.\n #fromTokenInstance: Promise<Token> | null = null;\n\n constructor(sdk: ZamaSDK, address: Address) {\n this.sdk = sdk;\n this.address = getAddress(address);\n this.#vault = memoizeAddressRead(() => sdk.provider.readContract(vaultContract(this.address)));\n this.#fromToken = memoizeAddressRead(() =>\n sdk.provider.readContract(fromTokenContract(this.address)),\n );\n this.#toToken = memoizeAddressRead(() =>\n sdk.provider.readContract(toTokenContract(this.address)),\n );\n }\n\n // READS\n\n /**\n * The underlying ERC-4626 vault. Share price (`convertToShares`,\n * `convertToAssets`, `totalAssets`) is read from it directly, not from the\n * batcher. Resolved once and cached.\n */\n async vault(): Promise<Address> {\n return this.#vault();\n }\n\n /**\n * The confidential token this batcher accepts as input (e.g. shares for a\n * redeem batcher). Resolved once and cached.\n */\n async fromToken(): Promise<Address> {\n return this.#fromToken();\n }\n\n /**\n * The confidential token this batcher pays out (e.g. shares for a\n * deposit batcher). Resolved once and cached.\n */\n async toToken(): Promise<Address> {\n return this.#toToken();\n }\n\n /** The id of the currently open (not-yet-dispatched) batch. */\n async currentBatchId(): Promise<bigint> {\n return this.sdk.provider.readContract(currentBatchIdContract(this.address));\n }\n\n /**\n * A batch's lifecycle state. See {@link BatchState} for which operation each\n * state allows.\n *\n * @throws Reverts on chain with `BatchNonexistent` for an id above\n * {@link currentBatchId} — batch ids start at 1.\n */\n async batchState(batchId: bigint): Promise<BatchState> {\n // The ABI types this uint8 enum as a plain `number`.\n const state = await this.sdk.provider.readContract(batchStateContract(this.address, batchId));\n return state as BatchState;\n }\n\n /** Whether the batcher is paused. While paused, `join` and `dispatchBatch` revert; `quit` and `claim` still work. */\n async paused(): Promise<boolean> {\n return this.sdk.provider.readContract(pausedContract(this.address));\n }\n\n /**\n * The policy for batches opened from now on. Dispatch of an existing batch\n * is gated on {@link batchMinBatchAge} instead.\n */\n async minBatchAge(): Promise<bigint> {\n return this.sdk.provider.readContract(minBatchAgeContract(this.address));\n }\n\n /** The minimum age in seconds pinned to `batchId` when it opened — the value dispatch enforces. */\n async batchMinBatchAge(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(batchMinBatchAgeContract(this.address, batchId));\n }\n\n /**\n * How long a dispatched batch may wait for its decryption callback before it\n * is canceled — seconds, not a timestamp, despite the name. Applies to\n * batches opened from now on; for an existing batch use\n * {@link batchCallbackDeadline}.\n */\n async callbackDeadline(): Promise<bigint> {\n return this.sdk.provider.readContract(callbackDeadlineContract(this.address));\n }\n\n /**\n * The callback deadline pinned to `batchId` when it opened. Add it to\n * {@link batchDispatchedAt} for the timestamp that batch must finalize by.\n */\n async batchCallbackDeadline(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(batchCallbackDeadlineContract(this.address, batchId));\n }\n\n /** The Unix timestamp (seconds) at which a batch was opened. */\n async batchCreatedAt(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(batchCreatedAtContract(this.address, batchId));\n }\n\n /** The Unix timestamp (seconds) at which a batch was dispatched, or `0` if it hasn't been yet. */\n async batchDispatchedAt(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(batchDispatchedAtContract(this.address, batchId));\n }\n\n /**\n * A finalized batch's exchange rate, scaled by\n * {@link exchangeRateDecimals}; `0` until the batch finalizes. A claim pays\n * out `deposit * exchangeRate / 10 ** exchangeRateDecimals`, rounded down.\n */\n async exchangeRate(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(exchangeRateContract(this.address, batchId));\n }\n\n /** The number of decimals {@link exchangeRate} is scaled by. */\n async exchangeRateDecimals(): Promise<number> {\n return this.sdk.provider.readContract(exchangeRateDecimalsContract(this.address));\n }\n\n /**\n * Seconds until `batchId` becomes eligible for dispatch, `0` once it already\n * is — the earliest possible moment, not a promise anyone will dispatch\n * then. `null` once the batch has left {@link BatchState.Pending} and can\n * never be dispatched again.\n *\n * Measured against the chain's block timestamp and the batch's own pinned\n * minimum age, so neither local clock drift nor a mid-flight policy change\n * desyncs the countdown.\n */\n async timeUntilDispatchable(batchId: bigint): Promise<bigint | null> {\n const [state, createdAt, minAge, now] = await Promise.all([\n this.batchState(batchId),\n this.batchCreatedAt(batchId),\n this.batchMinBatchAge(batchId),\n this.sdk.provider.getBlockTimestamp(),\n ]);\n if (state !== BatchState.Pending) {\n return null;\n }\n const eligibleAt = createdAt + minAge;\n return eligibleAt > now ? eligibleAt - now : 0n;\n }\n\n /** The encrypted aggregate amount joined into a batch, without decrypting it. */\n async confidentialTotalDeposits(batchId: bigint): Promise<EncryptedValue> {\n return this.sdk.provider.readContract(totalDepositsContract(this.address, batchId));\n }\n\n /** The encrypted amount `account` joined into a batch, without decrypting it. */\n async confidentialDepositOf(batchId: bigint, account: Address): Promise<EncryptedValue> {\n return this.sdk.provider.readContract(\n depositsContract(this.address, batchId, getAddress(account)),\n );\n }\n\n /**\n * Decrypt and return the plaintext amount `account` joined into a batch.\n * Acquires FHE credentials via a wallet signature if none are cached.\n */\n async depositOf(batchId: bigint, account: Address): Promise<bigint> {\n const normalizedAccount = getAddress(account);\n const encryptedValue = await this.confidentialDepositOf(batchId, normalizedAccount);\n if (isEncryptedValueZero(encryptedValue)) {\n return 0n;\n }\n const result = await this.sdk.decryption.decryptValues(\n [{ encryptedValue, contractAddress: this.address }],\n { operation: \"vault-deposit-of\" },\n );\n const value = result[encryptedValue];\n if (value === undefined) {\n throw new DecryptionFailedError(`Decryption returned no value for ${encryptedValue}`);\n }\n assertBigint(value, \"depositOf: result[encryptedValue]\");\n return value;\n }\n\n // WRITES\n\n /**\n * Join the currently open batch with a plaintext amount, encrypted via FHE\n * automatically. Once someone calls {@link dispatchBatch} and the relayer\n * finalizes it, call {@link claim} to receive the output.\n *\n * @param amount - The plaintext amount to contribute; encrypted before submission.\n * @param beneficiary - Recipient of the batch's eventual output. Defaults to the connected wallet account.\n *\n * @remarks\n * The batcher must already hold an ERC-7984 operator grant from the caller,\n * or it cannot pull the amount. A join with too little balance still\n * succeeds on chain and credits nothing, so the amount is checked against\n * the caller's confidential balance first; `confidentialJoinedAmount` is the\n * authoritative record of what actually landed.\n *\n * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n */\n async join(amount: bigint, beneficiary?: Address, options?: JoinOptions): Promise<JoinResult> {\n const { operation } = withOperation(options, \"vault-join\");\n this.#requireSigner(\"join\");\n const account = await requireAlignedWalletAccount(\"join\", this.sdk.signer, this.sdk.provider);\n const userAddress = getAddress(account.address);\n const resolvedBeneficiary = beneficiary ? getAddress(beneficiary) : userAddress;\n\n if (!options?.skipBalanceCheck) {\n await this.#assertJoinableBalance(amount, operation);\n }\n\n const { encryptedValues, inputProof } = await this.sdk.encrypt(\n { values: [{ value: amount, type: \"euint64\" }], contractAddress: this.address, userAddress },\n { operation },\n );\n\n const encryptedAmount = encryptedValues[0];\n if (!encryptedAmount) {\n throw new EncryptionFailedError(\"Encryption returned no encrypted values\");\n }\n\n const result = await this.#submitTransaction(\n \"vault:join\",\n joinContract(this.address, resolvedBeneficiary, encryptedAmount, inputProof),\n );\n\n const joined = findJoined(result.receipt.logs, this.address, resolvedBeneficiary);\n if (!joined) {\n throw new TransactionRevertedError(\n `No Joined event for ${resolvedBeneficiary} from batcher ${this.address} found in the join receipt`,\n );\n }\n return {\n ...result,\n batchId: joined.batchId,\n beneficiary: joined.account,\n confidentialJoinedAmount: joined.confidentialAmount,\n };\n }\n\n /**\n * Withdraw the caller's own deposit from a batch, returning it to their\n * confidential balance on `fromToken`.\n *\n * Legal in two states: {@link BatchState.Pending} (undo a join before\n * dispatch) and {@link BatchState.Canceled} (take the deposit back after a\n * batch failed to finalize).\n *\n * Refunds the caller only. To refund someone else's deposit in a canceled\n * batch, use {@link recover}.\n */\n async quit(batchId: bigint): Promise<TransactionResult> {\n this.#requireSigner(\"quit\");\n await requireChainAlignment(\"quit\", this.sdk.signer, this.sdk.provider);\n return this.#submitTransaction(\"vault:quit\", quitContract(this.address, batchId));\n }\n\n /**\n * Refund `account`'s deposit in a canceled batch on their behalf.\n * Permissionless — anyone can call this, and the refund always goes to\n * `account`, never to the caller.\n *\n * Only legal once the batch reaches {@link BatchState.Canceled}; before that,\n * a participant undoes their own join with {@link quit}.\n *\n * @param account - The depositor to refund. Defaults to the connected wallet account.\n */\n async recover(batchId: bigint, account?: Address): Promise<TransactionResult> {\n const target = await this.#resolveTarget(\"recover\", account);\n return this.#submitTransaction(\"vault:recover\", recoverContract(this.address, batchId, target));\n }\n\n /**\n * Claim a finalized batch's output for `account`. Permissionless — anyone\n * can call this on another account's behalf, and the output always goes to\n * `account`, never to the caller. The amount is not returned; read it as a\n * balance on the batcher's {@link toToken}.\n *\n * Only legal once the batch reaches {@link BatchState.Finalized}; on a\n * canceled batch use {@link quit} or {@link recover} instead.\n *\n * @param account - The account to claim for. Defaults to the connected wallet account.\n */\n async claim(batchId: bigint, account?: Address): Promise<TransactionResult> {\n const target = await this.#resolveTarget(\"claim\", account);\n return this.#submitTransaction(\"vault:claim\", claimContract(this.address, batchId, target));\n }\n\n /**\n * Close the current batch once it has reached its pinned minimum age and\n * kick off decryption of its aggregate amount. Permissionless — any\n * account with a configured signer can call this, not just participants.\n * Reverts while the batcher is {@link paused}.\n */\n async dispatchBatch(): Promise<TransactionResult> {\n this.#requireSigner(\"dispatchBatch\");\n await requireChainAlignment(\"dispatchBatch\", this.sdk.signer, this.sdk.provider);\n return this.#submitTransaction(\"vault:dispatchBatch\", dispatchBatchContract(this.address));\n }\n\n // INTERNAL\n\n #requireSigner(operation: string): GenericSigner {\n if (!this.sdk.signer) {\n throw new SignerNotConfiguredError(operation);\n }\n return this.sdk.signer;\n }\n\n async #inputToken(): Promise<Token> {\n this.#fromTokenInstance ??= this.fromToken()\n .then((address) => new Token(this.sdk, address))\n .catch((error: unknown) => {\n this.#fromTokenInstance = null;\n throw error;\n });\n return this.#fromTokenInstance;\n }\n\n async #assertJoinableBalance(\n amount: bigint,\n telemetryOperation: TelemetryOperation,\n ): Promise<void> {\n const token = await this.#inputToken();\n return assertConfidentialBalance({\n operation: \"join\",\n tokenAddress: token.address,\n amount,\n signer: this.sdk.signer,\n provider: this.sdk.provider,\n readBalance: (owner) => token.decryptBalance(owner, telemetryOperation),\n });\n }\n\n /**\n * Chain alignment is verified even when `account` is someone else's: the\n * connected signer still submits the transaction.\n */\n async #resolveTarget(operation: string, account: Address | undefined): Promise<Address> {\n this.#requireSigner(operation);\n if (account) {\n await requireChainAlignment(operation, this.sdk.signer, this.sdk.provider);\n return getAddress(account);\n }\n const aligned = await requireAlignedWalletAccount(\n operation,\n this.sdk.signer,\n this.sdk.provider,\n );\n return getAddress(aligned.address);\n }\n\n async #submitTransaction(\n operation: TransactionOperation,\n config: WriteContractConfig,\n ): Promise<TransactionResult> {\n return submitSdkTransaction({\n operation,\n signer: this.#requireSigner(operation),\n provider: this.sdk.provider,\n config,\n emit: (input) => this.sdk.emitEvent(input, this.address),\n logger: this.sdk.logger,\n });\n }\n}\n\n/**\n * Create a {@link VaultBatcher} bound to `sdk` for the batcher contract at `address`.\n *\n * @example\n * ```ts\n * import { createVaultBatcher } from \"@zama-fhe/sdk/vaults\";\n *\n * const depositBatcher = createVaultBatcher(sdk, \"0xDepositBatcher\");\n * const { batchId } = await depositBatcher.join(1_000_000n);\n * ```\n */\nexport function createVaultBatcher(sdk: ZamaSDK, address: Address): VaultBatcher {\n return new VaultBatcher(sdk, address);\n}\n","import { getAddress, type Address } from \"viem\";\nimport { ConfigurationError, SignerNotConfiguredError } from \"../errors\";\nimport { WrappedToken } from \"../token\";\nimport type { ZamaSDK } from \"../zama-sdk\";\nimport type { JoinResult, VaultAddresses, VaultJoinOptions } from \"./types\";\nimport { VaultBatcher } from \"./vault-batcher\";\n\n/**\n * A confidential ERC-4626 vault: one deposit batcher and one redeem batcher\n * behind ERC-4626-style `deposit` and `redeem` methods.\n *\n * Claiming, quitting and batch state live on the two batchers directly —\n * `vault.depositBatcher.claim(batchId)`.\n */\nexport class Vault {\n /** The SDK instance this vault reads and writes through. */\n readonly sdk: ZamaSDK;\n /** Joined by deposits of the underlying asset. */\n readonly depositBatcher: VaultBatcher;\n /** Joined by share redemptions. */\n readonly redeemBatcher: VaultBatcher;\n\n // The promise is cached, not just the resolved value, so concurrent callers\n // share one lookup and end up with the same instance.\n #vaultAddress: Promise<Address> | null = null;\n #cAsset: Promise<WrappedToken> | null = null;\n #cShare: Promise<WrappedToken> | null = null;\n\n readonly #expectedVaultAddress: Address | undefined;\n\n constructor(sdk: ZamaSDK, addresses: VaultAddresses) {\n this.sdk = sdk;\n this.#expectedVaultAddress = addresses.vault ? getAddress(addresses.vault) : undefined;\n this.depositBatcher = new VaultBatcher(sdk, addresses.depositBatcher);\n this.redeemBatcher = new VaultBatcher(sdk, addresses.redeemBatcher);\n }\n\n /**\n * The underlying ERC-4626 vault contract, read from both batchers rather\n * than trusted from configuration. Resolved once and cached.\n *\n * @throws if the batchers report different vaults, or either disagrees with\n * an `addresses.vault` passed to the constructor — a mismatched pair would\n * settle deposits and redemptions against different vaults.\n * {@link ConfigurationError}\n */\n async vaultAddress(): Promise<Address> {\n this.#vaultAddress ??= this.#resolveVaultAddress().catch((error: unknown) => {\n this.#vaultAddress = null;\n throw error;\n });\n return this.#vaultAddress;\n }\n\n /**\n * The confidential wrapper of the vault's underlying asset — the token\n * deposits are paid in. Resolved once and cached.\n */\n async cAsset(): Promise<WrappedToken> {\n this.#cAsset ??= this.depositBatcher\n .fromToken()\n .then((address) => new WrappedToken(this.sdk, address))\n .catch((error: unknown) => {\n this.#cAsset = null;\n throw error;\n });\n return this.#cAsset;\n }\n\n /**\n * The confidential share token this vault issues. Resolved once and cached.\n *\n * Read from the redeem batcher, which is the contract that actually pulls\n * these shares and so decides which token a redemption must grant on.\n */\n async cShare(): Promise<WrappedToken> {\n this.#cShare ??= this.redeemBatcher\n .fromToken()\n .then((address) => new WrappedToken(this.sdk, address))\n .catch((error: unknown) => {\n this.#cShare = null;\n throw error;\n });\n return this.#cShare;\n }\n\n /**\n * Deposit a plaintext amount of the underlying confidential asset,\n * joining the current deposit batch. Grants the deposit batcher an\n * ERC-7984 operator approval on the deposit token first, unless one is\n * already active.\n *\n * @param amount - The plaintext amount to deposit.\n * @throws before any approval is granted, if the batchers do not agree on\n * the vault. {@link ConfigurationError}\n */\n async deposit(amount: bigint, options?: VaultJoinOptions): Promise<JoinResult> {\n const [, token] = await Promise.all([this.vaultAddress(), this.cAsset()]);\n await this.#ensureOperator(\n \"deposit\",\n token,\n this.depositBatcher.address,\n options?.operatorUntil,\n );\n return this.depositBatcher.join(amount, options?.beneficiary, {\n skipBalanceCheck: options?.skipBalanceCheck,\n operation: \"vault-deposit\",\n });\n }\n\n /**\n * Join the current redeem batch, which the vault later settles into the\n * underlying asset at the batch's exchange rate. Grants the redeem batcher\n * an ERC-7984 operator approval on the share token first, unless one is\n * already active.\n *\n * @param amount - The plaintext amount of shares — ERC-4626 `redeem`, not\n * `withdraw`, so this is denominated in shares, never in assets.\n * @throws before any approval is granted, if the batchers do not agree on\n * the vault. {@link ConfigurationError}\n */\n async redeem(amount: bigint, options?: VaultJoinOptions): Promise<JoinResult> {\n const [, token] = await Promise.all([this.vaultAddress(), this.cShare()]);\n await this.#ensureOperator(\"redeem\", token, this.redeemBatcher.address, options?.operatorUntil);\n return this.redeemBatcher.join(amount, options?.beneficiary, {\n skipBalanceCheck: options?.skipBalanceCheck,\n operation: \"vault-redeem\",\n });\n }\n\n async #resolveVaultAddress(): Promise<Address> {\n const [depositVault, redeemVault] = await Promise.all([\n this.depositBatcher.vault(),\n this.redeemBatcher.vault(),\n ]);\n if (getAddress(depositVault) !== getAddress(redeemVault)) {\n throw new ConfigurationError(\n `Vault batchers point at different ERC-4626 vaults: deposit batcher ${this.depositBatcher.address} reports ${depositVault}, redeem batcher ${this.redeemBatcher.address} reports ${redeemVault}`,\n );\n }\n const onChain = getAddress(depositVault);\n if (this.#expectedVaultAddress !== undefined && this.#expectedVaultAddress !== onChain) {\n throw new ConfigurationError(\n `Configured vault address ${this.#expectedVaultAddress} does not match the ${onChain} both batchers report`,\n );\n }\n return onChain;\n }\n\n /**\n * The batcher pulls with `confidentialTransferFrom`, which ERC-7984 rejects\n * unless the batcher is already an operator of the caller.\n */\n async #ensureOperator(\n operation: string,\n token: WrappedToken,\n operator: Address,\n until: number | undefined,\n ): Promise<void> {\n if (!this.sdk.signer) {\n throw new SignerNotConfiguredError(operation);\n }\n const account = this.sdk.signer.requireWalletAccount(operation);\n const alreadyApproved = await token.isOperator(account.address, operator);\n if (!alreadyApproved) {\n await token.setOperator(operator, until);\n }\n }\n}\n\n/**\n * Create a {@link Vault} bound to `sdk` for the deposit/redeem batchers at `addresses`.\n *\n * @example\n * ```ts\n * import { createVault } from \"@zama-fhe/sdk/vaults\";\n *\n * const vault = createVault(sdk, {\n * depositBatcher: \"0xDepositBatcher\",\n * redeemBatcher: \"0xRedeemBatcher\",\n * });\n * const { batchId } = await vault.deposit(1_000_000n);\n * // …once the batch is dispatched and reaches BatchState.Finalized:\n * await vault.depositBatcher.claim(batchId);\n * ```\n */\nexport function createVault(sdk: ZamaSDK, addresses: VaultAddresses): Vault {\n return new Vault(sdk, addresses);\n}\n","import { getAddress, type Address, type Hex } from \"viem\";\nimport {\n confidentialTransferAndCallContract,\n isConfidentialTokenValidContract,\n} from \"../contracts\";\nimport {\n BalanceCheckUnavailableError,\n ConfigurationError,\n EncryptionFailedError,\n SignerNotConfiguredError,\n UnlistedConfidentialTokenError,\n VaultBatcherPausedError,\n VaultGroupJoinUnconfirmedError,\n} from \"../errors\";\nimport type { EncryptedValue } from \"../relayer/types\";\nimport { withOperation, type TelemetryOperation } from \"../telemetry\";\nimport { Token, type WrappedToken } from \"../token\";\nimport type { GenericSigner, TransactionResult, WriteContractConfig } from \"../types\";\nimport { requireAlignedWalletAccount } from \"../utils/alignment\";\nimport { assertConfidentialBalance } from \"../utils/assert-balance\";\nimport { memoizeAddressRead } from \"../utils/memoize-address-read\";\nimport { submitTransaction as submitSdkTransaction } from \"../utils/submit-transaction\";\nimport type { ZamaSDK } from \"../zama-sdk\";\nimport {\n encodeAllocationData,\n routerJoinContract,\n tokenWrapperRegistryContract,\n type EncryptedAllocationLeg,\n} from \"./contracts\";\nimport { takeJoined } from \"./events\";\nimport type { JoinOptions, VaultAddresses } from \"./types\";\nimport { Vault } from \"./vault\";\nimport type { VaultBatcher } from \"./vault-batcher\";\n\ntype Direction = \"deposit\" | \"redeem\";\n\n/** The most vaults a group may name: the router's per-transaction leg limit on the pull path, so a group is always exitable. */\nexport const MAX_GROUP_VAULTS = 10;\n\n/** One vault of a group. */\nexport interface VaultMemberConfig extends VaultAddresses {\n /** What callers pass to `deposit` and `redeem` to pick this vault. */\n readonly id: string;\n}\n\n/** What {@link createVaultGroup} takes. */\nexport interface VaultGroupConfig {\n /** Names the group in error messages. */\n readonly id: string;\n /** The confidential wrapper of the asset every member takes deposits in. */\n readonly cAsset: Address;\n /** The router that fans a submission out across the members. */\n readonly router: Address;\n /** The members, in the order their legs are submitted. At least two: a single vault is a {@link Vault}. */\n readonly vaults: readonly VaultMemberConfig[];\n}\n\n/** A member of a {@link VaultGroup}. */\nexport interface VaultGroupMember {\n /** What callers pass to `deposit` and `redeem` to pick this vault. */\n readonly id: string;\n /** The vault, whose batchers are where claims and quits happen. */\n readonly vault: Vault;\n}\n\n/** Options for {@link VaultGroup.redeem}; a deposit takes plain {@link JoinOptions}. */\nexport interface VaultGroupRedeemOptions extends JoinOptions {\n /**\n * Unix timestamp until which the router's operator grant on each share\n * token is valid, for a grant this redemption has to make. Defaults to\n * now + 1 hour.\n */\n operatorUntil?: number;\n}\n\n/** What one leg's batcher reported. */\nexport interface VaultGroupJoin {\n /** The member this leg joined, by id. */\n vaultId: string;\n /** The batcher this leg joined, where its claim and quit happen. */\n batcher: Address;\n /** The token this leg spent: `cAsset` for a deposit, the member's share token for a redemption. */\n token: Address;\n /** The batch the leg landed in; what that batcher's `claim` and `quit` take. */\n batchId: bigint;\n /**\n * The encrypted amount credited. Zero for every leg but the chosen one, and\n * zero for that one too if `skipBalanceCheck` let a short balance through,\n * since an ERC-7984 transfer moves nothing rather than reverting.\n */\n confidentialJoinedAmount: EncryptedValue;\n}\n\n/** The transaction that joined every member, plus what each member's batcher reported. */\nexport interface VaultGroupJoinResult extends TransactionResult {\n /** The member the caller chose; every other leg is a decoy. */\n vaultId: string;\n /** One entry per leg, in group order, decoys included. */\n joins: readonly VaultGroupJoin[];\n}\n\ninterface GroupLeg {\n readonly member: VaultGroupMember;\n readonly batcher: VaultBatcher;\n /** What this leg spends. */\n readonly token: WrappedToken;\n readonly vault: Address;\n readonly amount: bigint;\n}\n\nconst SIDES = {\n deposit: {\n batcher: (vault: Vault) => vault.depositBatcher,\n token: (vault: Vault) => vault.cAsset(),\n // The batcher's asset side: what a deposit batcher pulls, what a redeem batcher pays out.\n asset: (vault: Vault) => vault.depositBatcher.fromToken(),\n },\n redeem: {\n batcher: (vault: Vault) => vault.redeemBatcher,\n token: (vault: Vault) => vault.cShare(),\n asset: (vault: Vault) => vault.redeemBatcher.toToken(),\n },\n} as const;\n\n// Deduped: every deposit leg spends the same `cAsset`.\nfunction uniqueTokens(legs: readonly GroupLeg[]): WrappedToken[] {\n return [...new Map(legs.map((leg) => [leg.token.address, leg.token])).values()];\n}\n\nfunction duplicate<T>(values: readonly T[]): T | undefined {\n const seen = new Set<T>();\n for (const value of values) {\n if (seen.has(value)) {\n return value;\n }\n seen.add(value);\n }\n return undefined;\n}\n\n/**\n * Vaults that take deposits in the same confidential asset, joined as one\n * through the router: a deposit into one member joins *every* member's batch,\n * the chosen vault with the amount and the rest with an encrypted zero.\n */\nexport class VaultGroup {\n /** The SDK the group reads and writes through. */\n readonly sdk: ZamaSDK;\n /** The configured group id, used in error messages. */\n readonly id: string;\n /** The shared asset wrapper, checksummed. */\n readonly cAsset: Address;\n /** The router every submission goes through, checksummed. */\n readonly router: Address;\n /** The members in leg order. */\n readonly members: readonly VaultGroupMember[];\n\n readonly #registry: () => Promise<Address>;\n\n constructor(sdk: ZamaSDK, config: VaultGroupConfig) {\n if (config.vaults.length < 2) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" names ${config.vaults.length} vault(s); a group needs at least two, and a single vault is a Vault`,\n );\n }\n if (config.vaults.length > MAX_GROUP_VAULTS) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" names ${config.vaults.length} vaults, above the ${MAX_GROUP_VAULTS} a submission can carry`,\n );\n }\n const members = config.vaults.map((member) => ({\n id: member.id,\n vault: new Vault(sdk, member),\n }));\n const duplicateId = duplicate(members.map((member) => member.id));\n if (duplicateId !== undefined) {\n throw new ConfigurationError(`Vault group \"${config.id}\" names \"${duplicateId}\" twice`);\n }\n const duplicateVault = duplicate(\n config.vaults.flatMap((member) => (member.vault ? [getAddress(member.vault)] : [])),\n );\n if (duplicateVault !== undefined) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" gives ${duplicateVault} as the vault of more than one member`,\n );\n }\n // A batcher serves one vault in one direction, so the same address anywhere twice is a mistake.\n const duplicateBatcher = duplicate(\n members.flatMap(({ vault }) => [vault.depositBatcher.address, vault.redeemBatcher.address]),\n );\n if (duplicateBatcher !== undefined) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" names batcher ${duplicateBatcher} more than once`,\n );\n }\n\n this.sdk = sdk;\n this.id = config.id;\n this.cAsset = getAddress(config.cAsset);\n this.router = getAddress(config.router);\n this.members = members;\n // The router declares its registry `immutable`, so one read holds for the group's lifetime.\n this.#registry = memoizeAddressRead(async () =>\n getAddress(await sdk.provider.readContract(tokenWrapperRegistryContract(this.router))),\n );\n }\n\n /** Whether the router's registry lists `cAsset`, which a deposit requires. Not cached: a listing can be revoked. */\n async isAssetListed(): Promise<boolean> {\n return this.sdk.provider.readContract(\n isConfidentialTokenValidContract(await this.#registry(), this.cAsset),\n );\n }\n\n /**\n * One member by id.\n *\n * @throws if no member has id `vaultId`. {@link ConfigurationError}\n */\n member(vaultId: string): VaultGroupMember {\n const member = this.members.find((candidate) => candidate.id === vaultId);\n if (!member) {\n throw new ConfigurationError(`Vault group \"${this.id}\" has no vault \"${vaultId}\"`);\n }\n return member;\n }\n\n /**\n * Deposit the confidential asset into one member of the group, joining every\n * member's current deposit batch in one transaction.\n *\n * @param vaultId - The member to deposit into.\n * @param amount - The plaintext amount; encrypted before submission.\n *\n * @remarks\n * There is no `beneficiary`: the router credits the account the legs came\n * from, so a group deposit cannot be made on someone else's behalf.\n *\n * @throws if no member has id `vaultId`, a member's batchers disagree with its config or are not paired with `cAsset`, or two members' batchers report the same vault. {@link ConfigurationError}\n * @throws if a member's deposit batcher is paused. {@link VaultBatcherPausedError}\n * @throws if the router's registry does not list `cAsset`. {@link UnlistedConfidentialTokenError}\n * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n * @throws if a `Joined` event in the mined receipt could not be matched to every leg. {@link VaultGroupJoinUnconfirmedError}\n */\n async deposit(\n vaultId: string,\n amount: bigint,\n options?: JoinOptions,\n ): Promise<VaultGroupJoinResult> {\n const { operation } = withOperation(options, \"vault-group-deposit\");\n const { member, signer, holder } = await this.#caller(\"deposit\", vaultId);\n // Read alongside the legs, so an unlisted asset fails before the balance check can prompt the wallet.\n const [legs] = await Promise.all([\n this.#legs(\"deposit\", member, amount),\n this.#requireAssetListed(),\n ]);\n await this.#assertBalance(\"deposit\", member, amount, legs, signer, options);\n\n // One encryption per verifying contract: the asset checks the transfer's proof, the router the allocation's.\n const [transfer, allocation] = await Promise.all([\n this.sdk.encrypt(\n {\n values: [{ value: amount, type: \"euint64\" }],\n contractAddress: this.cAsset,\n userAddress: holder,\n },\n { operation },\n ),\n this.#encryptLegs(holder, legs, operation),\n ]);\n const [encryptedAmount] = transfer.encryptedValues;\n if (!encryptedAmount) {\n throw new EncryptionFailedError(\"Encryption returned no encrypted values\");\n }\n const transaction = await this.#submitTransaction(\n signer,\n confidentialTransferAndCallContract(\n this.cAsset,\n this.router,\n encryptedAmount,\n transfer.inputProof,\n encodeAllocationData(allocation.legs, allocation.inputProof),\n ),\n );\n return this.#result(vaultId, holder, legs, transaction);\n }\n\n /**\n * Redeem shares of one member of the group by joining every member's\n * current redeem batch in one transaction, each leg with its own share token.\n *\n * @param vaultId - The member to redeem from.\n * @param amount - The plaintext amount of shares: ERC-4626 `redeem`, not\n * `withdraw`, so this is denominated in shares, never in assets.\n *\n * @remarks\n * The router pulls every leg's share token, so before the join this grants\n * it an operator approval on each member's share token that lacks one. Each\n * grant is its own wallet prompt, so a first redemption from a group of N\n * vaults can ask the user to sign up to N + 1 times. The balance check\n * decrypts every member's share balance, not only the chosen one's.\n *\n * @throws if no member has id `vaultId`, a member's batchers disagree with its config or are not paired with `cAsset`, or two members' batchers report the same vault. {@link ConfigurationError}\n * @throws if a member's redeem batcher is paused. {@link VaultBatcherPausedError}\n * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n * @throws if a `Joined` event in the mined receipt could not be matched to every leg. {@link VaultGroupJoinUnconfirmedError}\n */\n async redeem(\n vaultId: string,\n amount: bigint,\n options?: VaultGroupRedeemOptions,\n ): Promise<VaultGroupJoinResult> {\n const { operation } = withOperation(options, \"vault-group-redeem\");\n const { member, signer, holder } = await this.#caller(\"redeem\", vaultId);\n // A router address with no registry to read fails here, before anything is granted to it.\n const [legs] = await Promise.all([this.#legs(\"redeem\", member, amount), this.#registry()]);\n await this.#assertBalance(\"redeem\", member, amount, legs, signer, options);\n\n // Encrypted before the grants, which cost the user a signature each; a proof does not expire.\n const allocation = await this.#encryptLegs(holder, legs, operation);\n const grants = await Promise.all(\n uniqueTokens(legs).map(async (token) => ({\n token,\n granted: await token.isOperator(holder, this.router),\n })),\n );\n for (const { token } of grants.filter((grant) => !grant.granted)) {\n await token.setOperator(this.router, options?.operatorUntil);\n }\n const transaction = await this.#submitTransaction(\n signer,\n routerJoinContract(this.router, allocation.legs, allocation.inputProof),\n );\n return this.#result(vaultId, holder, legs, transaction);\n }\n\n // INTERNAL\n\n async #caller(\n direction: Direction,\n vaultId: string,\n ): Promise<{ member: VaultGroupMember; signer: GenericSigner; holder: Address }> {\n const member = this.member(vaultId);\n const signer = this.sdk.signer;\n if (!signer) {\n throw new SignerNotConfiguredError(direction);\n }\n const account = await requireAlignedWalletAccount(direction, signer, this.sdk.provider);\n return { member, signer, holder: getAddress(account.address) };\n }\n\n // Every member gets a leg, zero-amount ones included: trimming them would reveal which vault was chosen.\n async #legs(\n direction: Direction,\n member: VaultGroupMember,\n amount: bigint,\n ): Promise<readonly GroupLeg[]> {\n const legs = await Promise.all(\n this.members.map((candidate) =>\n this.#leg(direction, candidate, candidate === member ? amount : 0n),\n ),\n );\n // The constructor's check only sees configured addresses; the batchers' reports can still name one vault twice.\n const duplicateVault = duplicate(legs.map((leg) => leg.vault));\n if (duplicateVault !== undefined) {\n throw new ConfigurationError(\n `Vault group \"${this.id}\" has two members whose batchers report the same vault ${duplicateVault}`,\n );\n }\n return legs;\n }\n\n // One paused batcher reverts the whole submission, so every leg's is read, not just the chosen one's.\n async #leg(direction: Direction, member: VaultGroupMember, amount: bigint): Promise<GroupLeg> {\n const side = SIDES[direction];\n const batcher = side.batcher(member.vault);\n const [vault, token, asset, paused] = await Promise.all([\n member.vault.vaultAddress(),\n side.token(member.vault),\n side.asset(member.vault),\n batcher.paused(),\n ]);\n if (getAddress(asset) !== this.cAsset) {\n throw new ConfigurationError(\n `Batcher ${batcher.address} of vault \"${member.id}\" is paired with ${asset}, but group \"${this.id}\" is configured with ${this.cAsset}`,\n );\n }\n if (paused) {\n throw new VaultBatcherPausedError(\n `Batcher ${batcher.address} of vault \"${member.id}\" in group \"${this.id}\" is paused, so no member can be joined until it resumes`,\n { batcher: batcher.address, vaultId: member.id },\n );\n }\n return { member, batcher, token, vault, amount };\n }\n\n // A short balance joins every batch with nothing and still costs the transaction.\n async #assertBalance(\n direction: Direction,\n member: VaultGroupMember,\n amount: bigint,\n legs: readonly GroupLeg[],\n signer: GenericSigner,\n options: JoinOptions | undefined,\n ): Promise<void> {\n if (options?.skipBalanceCheck) {\n return;\n }\n const token = await SIDES[direction].token(member.vault);\n // Every leg's token is decrypted, not just the chosen one's: a lone decrypt would tell the relayer which vault was picked.\n const tokens = uniqueTokens(legs);\n await assertConfidentialBalance({\n operation: direction,\n tokenAddress: token.address,\n amount,\n signer,\n provider: this.sdk.provider,\n readBalance: async (owner) => {\n const { results, errors } = await Token.batchBalancesOf(tokens, owner);\n const balance = results.get(token.address);\n if (balance === undefined) {\n throw (\n errors.get(token.address) ??\n new BalanceCheckUnavailableError(`Balance validation failed (token: ${token.address})`)\n );\n }\n return balance;\n },\n });\n }\n\n // Bound to the router rather than the batchers or the tokens: the router is the contract that verifies the proof.\n async #encryptLegs(\n holder: Address,\n legs: readonly GroupLeg[],\n operation: TelemetryOperation,\n ): Promise<{ legs: readonly EncryptedAllocationLeg[]; inputProof: Hex }> {\n const { encryptedValues, inputProof } = await this.sdk.encrypt(\n {\n values: legs.map((leg) => ({ value: leg.amount, type: \"euint64\" as const })),\n contractAddress: this.router,\n userAddress: holder,\n },\n { operation },\n );\n if (encryptedValues.length !== legs.length) {\n throw new EncryptionFailedError(\n `Encryption returned ${encryptedValues.length} values for ${legs.length} legs`,\n );\n }\n return {\n legs: legs.map((leg, index) => ({\n batcher: leg.batcher.address,\n token: leg.token.address,\n amount: encryptedValues[index] as EncryptedValue,\n })),\n inputProof,\n };\n }\n\n // The router rejects a push of an unlisted token with a revert that costs the caller a transaction.\n async #requireAssetListed(): Promise<void> {\n if (!(await this.isAssetListed())) {\n throw new UnlistedConfidentialTokenError(\n `The vault router's registry does not list ${this.cAsset}, so it would reject a transfer of it`,\n { token: this.cAsset, registry: await this.#registry() },\n );\n }\n }\n\n #submitTransaction(\n signer: GenericSigner,\n config: WriteContractConfig,\n ): Promise<TransactionResult> {\n return submitSdkTransaction({\n operation: \"vault:routerJoin\",\n signer,\n provider: this.sdk.provider,\n config,\n emit: (input) => this.sdk.emitEvent(input, this.router),\n logger: this.sdk.logger,\n });\n }\n\n #result(\n vaultId: string,\n holder: Address,\n legs: readonly GroupLeg[],\n transaction: TransactionResult,\n ): VaultGroupJoinResult {\n // Each log is consumed once: the router joins the legs in order, so the\n // Nth match is the Nth leg's even when the adapter omits log addresses.\n const logs = [...transaction.receipt.logs];\n const joins: VaultGroupJoin[] = [];\n const unconfirmed: string[] = [];\n for (const leg of legs) {\n const joined = takeJoined(logs, leg.batcher.address, holder);\n if (!joined) {\n unconfirmed.push(leg.member.id);\n continue;\n }\n joins.push({\n vaultId: leg.member.id,\n batcher: leg.batcher.address,\n token: leg.token.address,\n batchId: joined.batchId,\n confidentialJoinedAmount: joined.confidentialAmount,\n });\n }\n if (unconfirmed.length > 0) {\n throw new VaultGroupJoinUnconfirmedError(\n `Transaction ${transaction.txHash} was mined, but its receipt has no Joined event for ${holder} from the batcher of vault(s) ${unconfirmed.map((id) => `\"${id}\"`).join(\", \")} in group \"${this.id}\"`,\n { txHash: transaction.txHash, receipt: transaction.receipt, joins, unconfirmed },\n );\n }\n return { ...transaction, vaultId, joins };\n }\n}\n\n/**\n * Create a {@link VaultGroup} bound to `sdk`.\n *\n * @example\n * ```ts\n * import { createVaultGroup } from \"@zama-fhe/sdk/vaults\";\n *\n * const group = createVaultGroup(sdk, {\n * id: \"stable\",\n * cAsset: \"0xConfidentialAsset\",\n * router: \"0xRouter\",\n * vaults: [\n * { id: \"alpha\", depositBatcher: \"0xAlphaDeposit\", redeemBatcher: \"0xAlphaRedeem\" },\n * { id: \"beta\", depositBatcher: \"0xBetaDeposit\", redeemBatcher: \"0xBetaRedeem\" },\n * ],\n * });\n * const { joins } = await group.deposit(\"alpha\", 1_000_000n);\n * ```\n */\nexport function createVaultGroup(sdk: ZamaSDK, config: VaultGroupConfig): VaultGroup {\n return new VaultGroup(sdk, config);\n}\n","import { getAddress, type Address } from \"viem\";\n\n/**\n * Query keys for the vaults module.\n *\n * A `batcher(...)` key is a prefix of every `batch(...)` key for that batcher,\n * so invalidating it clears all of them at once.\n */\nexport const vaultQueryKeys = {\n currentBatchId: {\n batcher: (batcherAddress: Address) =>\n [\"zama.vault.currentBatchId\", { batcherAddress: getAddress(batcherAddress) }] as const,\n },\n batchState: {\n batcher: (batcherAddress: Address) =>\n [\"zama.vault.batchState\", { batcherAddress: getAddress(batcherAddress) }] as const,\n batch: (batcherAddress: Address, batchId: bigint | undefined) =>\n [\"zama.vault.batchState\", { batcherAddress: getAddress(batcherAddress), batchId }] as const,\n },\n timeUntilDispatchable: {\n batcher: (batcherAddress: Address) =>\n [\"zama.vault.timeUntilDispatchable\", { batcherAddress: getAddress(batcherAddress) }] as const,\n batch: (batcherAddress: Address, batchId: bigint | undefined) =>\n [\n \"zama.vault.timeUntilDispatchable\",\n { batcherAddress: getAddress(batcherAddress), batchId },\n ] as const,\n },\n};\n","import type { Address } from \"viem\";\nimport { invalidateBalanceQueries, type QueryClientLike } from \"../../query/invalidation\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Invalidates every cached batch read for a batcher. */\nexport function invalidateBatchQueries(\n queryClient: QueryClientLike,\n batcherAddress: Address,\n): void {\n void queryClient.invalidateQueries({\n queryKey: vaultQueryKeys.currentBatchId.batcher(batcherAddress),\n });\n void queryClient.invalidateQueries({\n queryKey: vaultQueryKeys.batchState.batcher(batcherAddress),\n });\n void queryClient.invalidateQueries({\n queryKey: vaultQueryKeys.timeUntilDispatchable.batcher(batcherAddress),\n });\n}\n\n/** Invalidates the caches affected by a join: the input token's balance, and the batcher's batch reads. */\nexport function invalidateAfterJoin(\n queryClient: QueryClientLike,\n params: { batcherAddress: Address; fromToken: Address },\n): void {\n invalidateBalanceQueries(queryClient, params.fromToken);\n invalidateBatchQueries(queryClient, params.batcherAddress);\n}\n\n/** Invalidates the caches affected by a quit or recover: the input token's balance and the batcher's batch reads. */\nexport function invalidateAfterQuit(\n queryClient: QueryClientLike,\n params: { batcherAddress: Address; fromToken: Address },\n): void {\n invalidateBalanceQueries(queryClient, params.fromToken);\n invalidateBatchQueries(queryClient, params.batcherAddress);\n}\n\n/** Invalidates the caches affected by a claim: the output token's balance. */\nexport function invalidateAfterClaim(\n queryClient: QueryClientLike,\n params: { toToken: Address },\n): void {\n invalidateBalanceQueries(queryClient, params.toToken);\n}\n\n/** Invalidates the caches affected by a dispatch: a new batch opens and the old one leaves `Pending`. */\nexport function invalidateAfterDispatchBatch(\n queryClient: QueryClientLike,\n batcherAddress: Address,\n): void {\n invalidateBatchQueries(queryClient, batcherAddress);\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { JoinOptions } from \"../types\";\nimport type { VaultGroup, VaultGroupJoinResult } from \"../vault-group\";\n\n/** Variables for {@link groupDepositMutationOptions}. */\nexport interface GroupDepositParams extends JoinOptions {\n /** The member of the group to deposit into. */\n vaultId: string;\n /** Plaintext amount to deposit. */\n amount: bigint;\n}\n\n/** Builds mutation options for {@link VaultGroup.deposit | depositing} into a group. */\nexport function groupDepositMutationOptions(\n group: VaultGroup,\n): MutationFactoryOptions<\n readonly [\"zama.vaultGroup.deposit\", { cAsset: Address; batchers: readonly Address[] }],\n GroupDepositParams,\n VaultGroupJoinResult\n> {\n return {\n // Keyed on the batchers, not the group's id, which two groups may share.\n mutationKey: [\n \"zama.vaultGroup.deposit\",\n {\n cAsset: group.cAsset,\n batchers: group.members.map(({ vault }) => vault.depositBatcher.address),\n },\n ] as const,\n mutationFn: async ({ vaultId, amount, ...rest }) => group.deposit(vaultId, amount, rest),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { VaultGroup, VaultGroupRedeemOptions, VaultGroupJoinResult } from \"../vault-group\";\n\n/** Variables for {@link groupRedeemMutationOptions}. */\nexport interface GroupRedeemParams extends VaultGroupRedeemOptions {\n /** The member of the group to redeem from. */\n vaultId: string;\n /** Plaintext amount of shares to redeem. */\n amount: bigint;\n}\n\n/** Builds mutation options for {@link VaultGroup.redeem | redeeming shares} from a group. */\nexport function groupRedeemMutationOptions(\n group: VaultGroup,\n): MutationFactoryOptions<\n readonly [\"zama.vaultGroup.redeem\", { cAsset: Address; batchers: readonly Address[] }],\n GroupRedeemParams,\n VaultGroupJoinResult\n> {\n return {\n // Keyed on the batchers, not the group's id, which two groups may share.\n mutationKey: [\n \"zama.vaultGroup.redeem\",\n {\n cAsset: group.cAsset,\n batchers: group.members.map(({ vault }) => vault.redeemBatcher.address),\n },\n ] as const,\n mutationFn: async ({ vaultId, amount, ...rest }) => group.redeem(vaultId, amount, rest),\n };\n}\n","import type { QueryFactoryOptions } from \"../../query/factory-types\";\nimport { filterQueryOptions } from \"../../query/utils\";\nimport type { VaultBatcher } from \"../vault-batcher\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Configuration for {@link currentBatchIdQueryOptions}. */\nexport interface CurrentBatchIdQueryConfig {\n /** Additional TanStack Query options merged into the generated query (e.g. `staleTime`, `enabled`). */\n query?: Record<string, unknown>;\n}\n\n/** Query options for a batcher's currently open batch id. */\nexport function currentBatchIdQueryOptions(\n batcher: VaultBatcher,\n config: CurrentBatchIdQueryConfig = {},\n): QueryFactoryOptions<\n bigint,\n Error,\n bigint,\n ReturnType<typeof vaultQueryKeys.currentBatchId.batcher>\n> {\n const queryOpts = config.query ?? {};\n\n return {\n ...filterQueryOptions(queryOpts),\n queryKey: vaultQueryKeys.currentBatchId.batcher(batcher.address),\n queryFn: async () => batcher.currentBatchId(),\n enabled: queryOpts.enabled !== false,\n };\n}\n","import { assertNonNullable } from \"../../utils/assertions\";\nimport type { QueryFactoryOptions } from \"../../query/factory-types\";\nimport { filterQueryOptions } from \"../../query/utils\";\nimport type { BatchState } from \"../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Configuration for {@link batchStateQueryOptions}. */\nexport interface BatchStateQueryConfig {\n /** Batch to read the state of; the query stays disabled until provided. */\n batchId?: bigint;\n /** Additional TanStack Query options merged into the generated query (e.g. `staleTime`, `enabled`). */\n query?: Record<string, unknown>;\n}\n\n/** Query options for a batch's lifecycle state — see {@link BatchState}. */\nexport function batchStateQueryOptions(\n batcher: VaultBatcher,\n config: BatchStateQueryConfig = {},\n): QueryFactoryOptions<\n BatchState,\n Error,\n BatchState,\n ReturnType<typeof vaultQueryKeys.batchState.batch>\n> {\n const queryOpts = config.query ?? {};\n\n return {\n ...filterQueryOptions(queryOpts),\n queryKey: vaultQueryKeys.batchState.batch(batcher.address, config.batchId),\n queryFn: async (context) => {\n const [, { batchId }] = context.queryKey;\n assertNonNullable(batchId, \"batchStateQueryOptions: batchId\");\n return batcher.batchState(batchId);\n },\n enabled: config.batchId !== undefined && queryOpts.enabled !== false,\n };\n}\n","import type { QueryFactoryOptions } from \"../../query/factory-types\";\nimport { filterQueryOptions } from \"../../query/utils\";\nimport { assertNonNullable } from \"../../utils/assertions\";\nimport type { VaultBatcher } from \"../vault-batcher\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Configuration for {@link timeUntilDispatchableQueryOptions}. */\nexport interface TimeUntilDispatchableQueryConfig {\n /** Batch to check; the query stays disabled until provided. */\n batchId?: bigint;\n /** Additional TanStack Query options merged into the generated query (e.g. `staleTime`, `enabled`). */\n query?: Record<string, unknown>;\n}\n\n/**\n * Query options for the seconds remaining until a batch can be dispatched, or\n * `null` once the batch has left `Pending` and can no longer be dispatched —\n * see {@link VaultBatcher.timeUntilDispatchable}.\n */\nexport function timeUntilDispatchableQueryOptions(\n batcher: VaultBatcher,\n config: TimeUntilDispatchableQueryConfig = {},\n): QueryFactoryOptions<\n bigint | null,\n Error,\n bigint | null,\n ReturnType<typeof vaultQueryKeys.timeUntilDispatchable.batch>\n> {\n const queryOpts = config.query ?? {};\n\n return {\n ...filterQueryOptions(queryOpts),\n queryKey: vaultQueryKeys.timeUntilDispatchable.batch(batcher.address, config.batchId),\n queryFn: async (context) => {\n const [, { batchId }] = context.queryKey;\n assertNonNullable(batchId, \"timeUntilDispatchableQueryOptions: batchId\");\n return batcher.timeUntilDispatchable(batchId);\n },\n enabled: config.batchId !== undefined && queryOpts.enabled !== false,\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { Vault } from \"../vault\";\nimport type { JoinResult, VaultJoinOptions } from \"../types\";\n\n/** Variables for {@link depositMutationOptions}. */\nexport interface DepositParams extends VaultJoinOptions {\n /** Plaintext amount to deposit. */\n amount: bigint;\n}\n\n/** Builds TanStack Query mutation options for {@link Vault.deposit | depositing} into a vault. */\nexport function depositMutationOptions(\n vault: Vault,\n): MutationFactoryOptions<readonly [\"zama.vault.deposit\", Address], DepositParams, JoinResult> {\n return {\n mutationKey: [\"zama.vault.deposit\", vault.depositBatcher.address] as const,\n mutationFn: async ({ amount, ...rest }) => vault.deposit(amount, rest),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { Vault } from \"../vault\";\nimport type { JoinResult, VaultJoinOptions } from \"../types\";\n\n/** Variables for {@link redeemMutationOptions}. */\nexport interface RedeemParams extends VaultJoinOptions {\n /** Plaintext amount of shares to redeem. */\n amount: bigint;\n}\n\n/** Builds TanStack Query mutation options for {@link Vault.redeem | redeeming shares}. */\nexport function redeemMutationOptions(\n vault: Vault,\n): MutationFactoryOptions<readonly [\"zama.vault.redeem\", Address], RedeemParams, JoinResult> {\n return {\n mutationKey: [\"zama.vault.redeem\", vault.redeemBatcher.address] as const,\n mutationFn: async ({ amount, ...rest }) => vault.redeem(amount, rest),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { JoinOptions, JoinResult } from \"../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link joinMutationOptions}. */\nexport interface JoinParams extends JoinOptions {\n /** Plaintext amount to contribute to the batch. */\n amount: bigint;\n /** Recipient of the batch's eventual output. Defaults to the connected wallet account. */\n beneficiary?: Address;\n}\n\n/**\n * Builds TanStack Query mutation options for {@link VaultBatcher.join | joining} a batch directly.\n * Low-level — most apps should use `depositMutationOptions` / `redeemMutationOptions` instead.\n */\nexport function joinMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<readonly [\"zama.vault.join\", Address], JoinParams, JoinResult> {\n return {\n mutationKey: [\"zama.vault.join\", batcher.address] as const,\n mutationFn: async ({ amount, beneficiary, ...options }) =>\n batcher.join(amount, beneficiary, options),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link claimMutationOptions}. */\nexport interface ClaimParams {\n /** The finalized batch to claim from. */\n batchId: bigint;\n /** The account to claim for. Defaults to the connected wallet account. */\n account?: Address;\n}\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.claim | claiming} a finalized batch. */\nexport function claimMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<readonly [\"zama.vault.claim\", Address], ClaimParams, TransactionResult> {\n return {\n mutationKey: [\"zama.vault.claim\", batcher.address] as const,\n mutationFn: async ({ batchId, account }) => batcher.claim(batchId, account),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link quitMutationOptions}. */\nexport interface QuitParams {\n /** The pending or canceled batch to withdraw the caller's own deposit from. */\n batchId: bigint;\n}\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.quit | withdrawing a deposit} from a pending or canceled batch. */\nexport function quitMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<readonly [\"zama.vault.quit\", Address], QuitParams, TransactionResult> {\n return {\n mutationKey: [\"zama.vault.quit\", batcher.address] as const,\n mutationFn: async ({ batchId }) => batcher.quit(batchId),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link recoverMutationOptions}. */\nexport interface RecoverParams {\n /** The canceled batch holding the deposit. */\n batchId: bigint;\n /** The depositor to refund. Defaults to the connected wallet account. */\n account?: Address;\n}\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.recover | refunding a deposit} in a canceled batch on the depositor's behalf. */\nexport function recoverMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<\n readonly [\"zama.vault.recover\", Address],\n RecoverParams,\n TransactionResult\n> {\n return {\n mutationKey: [\"zama.vault.recover\", batcher.address] as const,\n mutationFn: async ({ batchId, account }) => batcher.recover(batchId, account),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.dispatchBatch | dispatching} the current batch. Permissionless — takes no variables. */\nexport function dispatchBatchMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<readonly [\"zama.vault.dispatchBatch\", Address], void, TransactionResult> {\n return {\n mutationKey: [\"zama.vault.dispatchBatch\", batcher.address] as const,\n mutationFn: async () => batcher.dispatchBatch(),\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["eventTopic","topicToAddress","wordToBytes32","#vault","#fromToken","#toToken","isEncryptedValueZero","DecryptionFailedError","withOperation","#requireSigner","requireAlignedWalletAccount","#assertJoinableBalance","EncryptionFailedError","#submitTransaction","TransactionRevertedError","requireChainAlignment","#resolveTarget","VaultBatchNotDispatchedError","unwrapAmountContract","SignerNotConfiguredError","#inputToken","#fromTokenInstance","Token","assertConfidentialBalance","submitSdkTransaction","#expectedVaultAddress","#vaultAddress","#resolveVaultAddress","#cAsset","WrappedToken","#cShare","#ensureOperator","ConfigurationError","SignerNotConfiguredError","ConfigurationError","#config","#shares","#registry","ConfigurationError","#router","isConfidentialTokenValidContract","Token","#prepare","#requireSigner","#send","SignerNotConfiguredError","withOperation","#delivery","#account","#configuredLegs","#verifiedLegs","#requireAssetListed","#assertBalance","#legWrites","#routerWrite","requireAlignedWalletAccount","WrappedToken","#share","#assertNotPaused","#amountFor","VaultBatcherPausedError","#verifiedLeg","assertConfidentialBalance","BalanceCheckUnavailableError","#encrypt","EncryptionFailedError","confidentialTransferAndCallContract","UnlistedConfidentialTokenError","submitSdkTransaction","VaultGroupJoinUnconfirmedError","filterQueryOptions","filterQueryOptions","filterQueryOptions","filterQueryOptions"],"sources":["../../../src/utils/memoize-address-read.ts","../../../src/vaults/abi/vault-batcher.abi.ts","../../../src/vaults/contracts/vault-batcher.ts","../../../src/vaults/abi/vault-router.abi.ts","../../../src/vaults/contracts/vault-router.ts","../../../src/vaults/events.ts","../../../src/vaults/types.ts","../../../src/vaults/vault-batcher.ts","../../../src/vaults/vault.ts","../../../src/vaults/vault-group-standalone.ts","../../../src/vaults/vault-group.ts","../../../src/vaults/query/query-keys.ts","../../../src/vaults/query/invalidation.ts","../../../src/vaults/query/group-deposit.ts","../../../src/vaults/query/group-redeem.ts","../../../src/vaults/query/current-batch-id.ts","../../../src/vaults/query/batch-state.ts","../../../src/vaults/query/time-until-dispatchable.ts","../../../src/vaults/query/time-until-callback-deadline.ts","../../../src/vaults/query/deposit.ts","../../../src/vaults/query/redeem.ts","../../../src/vaults/query/join.ts","../../../src/vaults/query/claim.ts","../../../src/vaults/query/quit.ts","../../../src/vaults/query/recover.ts","../../../src/vaults/query/dispatch-batch.ts","../../../src/vaults/query/finalize.ts"],"sourcesContent":["import type { Address } from \"viem\";\n\n/**\n * Caches the read for good and shares one in-flight call: only for addresses\n * a contract fixes at deploy time.\n *\n * @internal\n */\nexport function memoizeAddressRead(read: () => Promise<Address>): () => Promise<Address> {\n let cached: Address | undefined;\n let pending: Promise<Address> | null = null;\n return () => {\n if (cached !== undefined) {\n return Promise.resolve(cached);\n }\n if (!pending) {\n pending = read()\n .then((value) => {\n cached = value;\n pending = null;\n return value;\n })\n .catch((error) => {\n pending = null;\n throw error;\n });\n }\n return pending;\n };\n}\n","/**\n * ABI for the deposit and redeem vault batchers, which share one interface.\n * Owner-only writes are omitted; every custom error is kept so reverts decode\n * to a name.\n */\nexport const vaultBatcherAbi = [\n {\n type: \"function\",\n name: \"batchCallbackDeadline\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchCreatedAt\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchDispatchedAt\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchMaxSlippageBps\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint16\", internalType: \"uint16\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchMinBatchAge\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"batchState\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint8\", internalType: \"enum BatcherConfidential.BatchState\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"callbackDeadline\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"claim\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"account\", type: \"address\", internalType: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"currentBatchId\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"deposits\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"account\", type: \"address\", internalType: \"address\" },\n ],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"dispatchBatch\",\n inputs: [],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"dispatchBatchCallback\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"unwrapAmountCleartext\", type: \"uint64\", internalType: \"uint64\" },\n { name: \"decryptionProof\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"exchangeRate\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"uint64\", internalType: \"uint64\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"exchangeRateDecimals\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint8\", internalType: \"uint8\" }],\n stateMutability: \"pure\",\n },\n {\n type: \"function\",\n name: \"fromToken\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract IERC7984ERC20Wrapper\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"join\",\n inputs: [\n { name: \"beneficiary\", type: \"address\", internalType: \"address\" },\n { name: \"encryptedAmount\", type: \"bytes32\", internalType: \"externalEuint64\" },\n { name: \"inputProof\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [{ name: \"joined\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"maxSlippageBps\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint16\", internalType: \"uint16\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"minBatchAge\",\n inputs: [],\n outputs: [{ name: \"\", type: \"uint256\", internalType: \"uint256\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"paused\",\n inputs: [],\n outputs: [{ name: \"\", type: \"bool\", internalType: \"bool\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"quit\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"recover\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"account\", type: \"address\", internalType: \"address\" },\n ],\n outputs: [{ name: \"refunded\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"toToken\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract IERC7984ERC20Wrapper\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"totalDeposits\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"euint64\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"unwrapRequestId\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n outputs: [{ name: \"\", type: \"bytes32\", internalType: \"bytes32\" }],\n stateMutability: \"view\",\n },\n {\n type: \"function\",\n name: \"vault\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract IERC4626\" }],\n stateMutability: \"view\",\n },\n {\n type: \"event\",\n name: \"BatchCanceled\",\n inputs: [{ name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" }],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"BatchDispatched\",\n inputs: [{ name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" }],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"BatchFinalized\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" },\n { name: \"exchangeRate\", type: \"uint64\", indexed: false, internalType: \"uint64\" },\n ],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"Claimed\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" },\n { name: \"account\", type: \"address\", indexed: true, internalType: \"address\" },\n { name: \"amount\", type: \"bytes32\", indexed: false, internalType: \"euint64\" },\n ],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"Joined\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" },\n { name: \"account\", type: \"address\", indexed: true, internalType: \"address\" },\n { name: \"amount\", type: \"bytes32\", indexed: false, internalType: \"euint64\" },\n ],\n anonymous: false,\n },\n {\n type: \"event\",\n name: \"Quit\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", indexed: true, internalType: \"uint256\" },\n { name: \"account\", type: \"address\", indexed: true, internalType: \"address\" },\n { name: \"amount\", type: \"bytes32\", indexed: false, internalType: \"euint64\" },\n ],\n anonymous: false,\n },\n {\n type: \"error\",\n name: \"BatchNonexistent\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n },\n {\n type: \"error\",\n name: \"BatchTooYoung\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"elapsed\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"required\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n {\n type: \"error\",\n name: \"BatchUnexpectedState\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"current\", type: \"uint8\", internalType: \"enum BatcherConfidential.BatchState\" },\n { name: \"expectedStates\", type: \"bytes32\", internalType: \"bytes32\" },\n ],\n },\n { type: \"error\", name: \"DuplicateUnderlyingTokens\", inputs: [] },\n { type: \"error\", name: \"EnforcedPause\", inputs: [] },\n { type: \"error\", name: \"ExpectedPause\", inputs: [] },\n {\n type: \"error\",\n name: \"IntermediateStepToTokenBalanceChanged\",\n inputs: [{ name: \"batchId\", type: \"uint256\", internalType: \"uint256\" }],\n },\n { type: \"error\", name: \"InvalidBeneficiary\", inputs: [] },\n { type: \"error\", name: \"InvalidCallbackDeadline\", inputs: [] },\n {\n type: \"error\",\n name: \"InvalidExchangeRate\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"totalDeposits\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"exchangeRate\", type: \"uint64\", internalType: \"uint64\" },\n ],\n },\n { type: \"error\", name: \"InvalidKMSSignatures\", inputs: [] },\n { type: \"error\", name: \"InvalidMaxSlippageBps\", inputs: [] },\n { type: \"error\", name: \"InvalidMinBatchAge\", inputs: [] },\n { type: \"error\", name: \"InvalidTokenRate\", inputs: [] },\n {\n type: \"error\",\n name: \"InvalidWrapperToken\",\n inputs: [{ name: \"token\", type: \"address\", internalType: \"address\" }],\n },\n {\n type: \"error\",\n name: \"OwnableInvalidOwner\",\n inputs: [{ name: \"owner\", type: \"address\", internalType: \"address\" }],\n },\n {\n type: \"error\",\n name: \"OwnableUnauthorizedAccount\",\n inputs: [{ name: \"account\", type: \"address\", internalType: \"address\" }],\n },\n { type: \"error\", name: \"ReentrancyGuardReentrantCall\", inputs: [] },\n {\n type: \"error\",\n name: \"RouteAssetMismatch\",\n inputs: [\n { name: \"actualAsset\", type: \"address\", internalType: \"address\" },\n { name: \"expectedAsset\", type: \"address\", internalType: \"address\" },\n ],\n },\n {\n type: \"error\",\n name: \"RouteShareMismatch\",\n inputs: [\n { name: \"actualShare\", type: \"address\", internalType: \"address\" },\n { name: \"expectedShare\", type: \"address\", internalType: \"address\" },\n ],\n },\n {\n type: \"error\",\n name: \"SafeCastOverflowedUintDowncast\",\n inputs: [\n { name: \"bits\", type: \"uint8\", internalType: \"uint8\" },\n { name: \"value\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n {\n type: \"error\",\n name: \"SafeERC20FailedOperation\",\n inputs: [{ name: \"token\", type: \"address\", internalType: \"address\" }],\n },\n {\n type: \"error\",\n name: \"SenderNotAllowedToUseHandle\",\n inputs: [\n { name: \"handle\", type: \"bytes32\", internalType: \"bytes32\" },\n { name: \"sender\", type: \"address\", internalType: \"address\" },\n ],\n },\n {\n type: \"error\",\n name: \"SlippageExceeded\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"actual\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"minimum\", type: \"uint256\", internalType: \"uint256\" },\n ],\n },\n { type: \"error\", name: \"Unauthorized\", inputs: [] },\n { type: \"error\", name: \"ZamaProtocolUnsupported\", inputs: [] },\n {\n type: \"error\",\n name: \"ZeroDeposits\",\n inputs: [\n { name: \"batchId\", type: \"uint256\", internalType: \"uint256\" },\n { name: \"account\", type: \"address\", internalType: \"address\" },\n ],\n },\n] as const;\n","import type { Address, Hex } from \"viem\";\nimport type { EncryptedValue } from \"../../relayer/types\";\nimport { vaultBatcherAbi } from \"../abi/vault-batcher.abi\";\n\n/** Returns the contract config to join the currently open batch with an encrypted amount. */\nexport function joinContract(\n batcher: Address,\n beneficiary: Address,\n encryptedAmount: EncryptedValue,\n inputProof: Hex,\n) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"join\",\n args: [beneficiary, encryptedAmount, inputProof],\n } as const;\n}\n\n/** Returns the contract config to claim a finalized batch's output on behalf of `account`. Permissionless. */\nexport function claimContract(batcher: Address, batchId: bigint, account: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"claim\",\n args: [batchId, account],\n } as const;\n}\n\n/** Returns the contract config to withdraw the caller's own deposit from a pending or canceled batch. */\nexport function quitContract(batcher: Address, batchId: bigint) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"quit\", args: [batchId] } as const;\n}\n\n/** Returns the contract config to refund `account`'s deposit in a canceled batch. Permissionless — the refund goes to `account`, not the caller. */\nexport function recoverContract(batcher: Address, batchId: bigint, account: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"recover\",\n args: [batchId, account],\n } as const;\n}\n\n/** Returns the contract config to close the current batch and kick off decryption. Permissionless. */\nexport function dispatchBatchContract(batcher: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"dispatchBatch\",\n args: [],\n } as const;\n}\n\n/** Returns the contract config to read the id of the currently open batch. */\nexport function currentBatchIdContract(batcher: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"currentBatchId\",\n args: [],\n } as const;\n}\n\n/** Returns the contract config to read a batch's lifecycle state (the contract's `BatchState` enum). */\nexport function batchStateContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchState\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read a batch's encrypted aggregate deposit amount. */\nexport function totalDepositsContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"totalDeposits\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read one account's encrypted deposit within a batch. */\nexport function depositsContract(batcher: Address, batchId: bigint, account: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"deposits\",\n args: [batchId, account],\n } as const;\n}\n\n/** Returns the contract config to read the underlying ERC-4626 vault address. */\nexport function vaultContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"vault\", args: [] } as const;\n}\n\n/** Returns the contract config to read the confidential token this batcher accepts as input. */\nexport function fromTokenContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"fromToken\", args: [] } as const;\n}\n\n/** Returns the contract config to read the confidential token this batcher pays out. */\nexport function toTokenContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"toToken\", args: [] } as const;\n}\n\n/** Returns the contract config to read the batcher's current minimum-batch-age policy. */\nexport function minBatchAgeContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"minBatchAge\", args: [] } as const;\n}\n\n/** Returns the contract config to read the minimum age pinned to one batch when it opened. */\nexport function batchMinBatchAgeContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchMinBatchAge\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read the batcher's current callback-deadline policy. */\nexport function callbackDeadlineContract(batcher: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"callbackDeadline\",\n args: [],\n } as const;\n}\n\n/** Returns the contract config to read the callback deadline pinned to one batch when it opened. */\nexport function batchCallbackDeadlineContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchCallbackDeadline\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read the Unix timestamp a batch was opened at. */\nexport function batchCreatedAtContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchCreatedAt\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read the Unix timestamp a batch was dispatched at, or 0 if not yet dispatched. */\nexport function batchDispatchedAtContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"batchDispatchedAt\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read a finalized batch's exchange rate, or 0 while unfinalized. */\nexport function exchangeRateContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"exchangeRate\",\n args: [batchId],\n } as const;\n}\n\n/** Returns the contract config to read the number of decimals the exchange rate is scaled by. */\nexport function exchangeRateDecimalsContract(batcher: Address) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"exchangeRateDecimals\",\n args: [],\n } as const;\n}\n\n/** Returns the contract config to read whether the batcher is paused (blocking joins and dispatch). */\nexport function pausedContract(batcher: Address) {\n return { address: batcher, abi: vaultBatcherAbi, functionName: \"paused\", args: [] } as const;\n}\n\n/** Returns the contract config to read the unwrap request a dispatched batch is waiting on. */\nexport function unwrapRequestIdContract(batcher: Address, batchId: bigint) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"unwrapRequestId\",\n args: [batchId],\n } as const;\n}\n\n/**\n * Returns the contract config to settle a dispatched batch with the public decryption of its\n * aggregate amount, or to cancel it once its callback deadline has passed. Permissionless.\n */\nexport function dispatchBatchCallbackContract(\n batcher: Address,\n batchId: bigint,\n unwrapAmountCleartext: bigint,\n decryptionProof: Hex,\n) {\n return {\n address: batcher,\n abi: vaultBatcherAbi,\n functionName: \"dispatchBatchCallback\",\n args: [batchId, unwrapAmountCleartext, decryptionProof],\n } as const;\n}\n","/**\n * ABI for the vault batcher router, which fans one submission out across\n * several batchers. Transcribed by hand from `IVaultBatcherConfidentialRouter`\n * in zama-ai/confidential-defi at tag `oz-audit-20261016` (commit `d7cd0c8e`),\n * so `abi:check` does not cover it: compare against that ref when the router\n * changes. `onConfidentialTransferReceived` is omitted because a token calls\n * it, not the SDK; the router's custom errors are kept so its reverts decode\n * to a name.\n */\nexport const vaultRouterAbi = [\n {\n type: \"function\",\n name: \"join\",\n inputs: [\n {\n name: \"legs\",\n type: \"tuple[]\",\n internalType: \"struct IVaultBatcherConfidentialRouter.Allocation[]\",\n components: [\n { name: \"batcher\", type: \"address\", internalType: \"address\" },\n { name: \"token\", type: \"address\", internalType: \"address\" },\n { name: \"amount\", type: \"bytes32\", internalType: \"externalEuint64\" },\n ],\n },\n { name: \"inputProof\", type: \"bytes\", internalType: \"bytes\" },\n ],\n outputs: [],\n stateMutability: \"nonpayable\",\n },\n {\n type: \"function\",\n name: \"tokenWrapperRegistry\",\n inputs: [],\n outputs: [{ name: \"\", type: \"address\", internalType: \"contract ITokenWrapperRegistry\" }],\n stateMutability: \"view\",\n },\n { type: \"error\", name: \"InvalidTokenWrapperRegistry\", inputs: [] },\n { type: \"error\", name: \"MissingInputProof\", inputs: [] },\n { type: \"error\", name: \"ReentrancyGuardReentrantCall\", inputs: [] },\n { type: \"error\", name: \"ZamaProtocolUnsupported\", inputs: [] },\n {\n type: \"error\",\n name: \"UnlistedConfidentialToken\",\n inputs: [{ name: \"token\", type: \"address\", internalType: \"address\" }],\n },\n] as const;\n","import { encodeAbiParameters, getAbiItem, type Address, type Hex } from \"viem\";\nimport type { EncryptedValue } from \"../../relayer/types\";\nimport { vaultRouterAbi } from \"../abi/vault-router.abi\";\n\n/** One vault's share of a fan-out, its amount encrypted against the router. */\nexport interface EncryptedAllocationLeg {\n /** The batcher this leg joins. */\n readonly batcher: Address;\n /** The confidential token this leg spends. */\n readonly token: Address;\n /** The leg's amount, encrypted with the router as the verifying contract. */\n readonly amount: EncryptedValue;\n}\n\n/** Returns the contract config to pull every leg from the caller and join each named batcher. */\nexport function routerJoinContract(\n router: Address,\n legs: readonly EncryptedAllocationLeg[],\n inputProof: Hex,\n) {\n return {\n address: router,\n abi: vaultRouterAbi,\n functionName: \"join\",\n args: [legs, inputProof],\n } as const;\n}\n\n// The push path decodes its `data` into the same pair `join` takes, so reading\n// the parameters off the ABI keeps the encoding from drifting from the call.\nconst ALLOCATION_PARAMETERS = getAbiItem({ abi: vaultRouterAbi, name: \"join\" }).inputs;\n\n/** The payload that lets one confidential transfer of the shared asset fund every leg. */\nexport function encodeAllocationData(\n legs: readonly EncryptedAllocationLeg[],\n inputProof: Hex,\n): Hex {\n return encodeAbiParameters(ALLOCATION_PARAMETERS, [legs.map((leg) => ({ ...leg })), inputProof]);\n}\n\n/** Returns the contract config to read the registry the router gates its push path on. */\nexport function tokenWrapperRegistryContract(router: Address) {\n return {\n address: router,\n abi: vaultRouterAbi,\n functionName: \"tokenWrapperRegistry\",\n args: [],\n } as const;\n}\n","import { getAddress, type Address } from \"viem\";\nimport { eventTopic, topicToAddress, wordToBytes32 } from \"../events/log-decoding\";\nimport type { EncryptedValue } from \"../relayer/types\";\nimport type { RawLog } from \"../types/transaction\";\n\n/**\n * Vault batcher event topic0 constants (keccak256 of the canonical Solidity\n * signature). Pass to `getLogs({ topics: [Object.values(VaultTopics)] })`.\n */\nexport const VaultTopics = {\n /** `Joined(uint256 indexed batchId, address indexed account, euint64 amount)` */\n Joined: eventTopic(\"Joined(uint256,address,bytes32)\"),\n} as const;\n\n/** A decoded `Joined` event. */\nexport interface JoinedEvent {\n /** The batch the join landed in. */\n batchId: bigint;\n /** The account credited — the beneficiary a join named, which may not be the caller. */\n account: Address;\n /** The encrypted amount credited, which can be zero when the pull transferred nothing. */\n confidentialAmount: EncryptedValue;\n}\n\n/**\n * Joined(uint256 indexed batchId, address indexed account, euint64 amount)\n * Indexed: batchId (topics[1]), account (topics[2])\n * Data: amount (bytes32)\n */\nexport function decodeJoined(log: RawLog): JoinedEvent | null {\n const [topic, batchId, account] = log.topics;\n if (topic !== VaultTopics.Joined || batchId === undefined || account === undefined) {\n return null;\n }\n\n return {\n batchId: BigInt(batchId),\n account: topicToAddress(account),\n confidentialAmount: wordToBytes32(log.data, 0),\n };\n}\n\nfunction matchJoined(\n log: RawLog,\n batcher: Address,\n account: Address | undefined,\n): JoinedEvent | null {\n if (log.address !== undefined && getAddress(log.address) !== batcher) {\n return null;\n }\n const event = decodeJoined(log);\n if (!event || (account !== undefined && event.account !== account)) {\n return null;\n }\n return event;\n}\n\n/**\n * Filters on `batcher`, and on `account` when given, rather than taking the\n * first match: one transaction can join several batchers and credit several\n * beneficiaries, so an unfiltered search can return someone else's batch id.\n * Logs carrying no emitter address are kept, since some adapters omit it.\n */\nexport function findJoined(\n logs: readonly RawLog[],\n batcher: Address,\n account?: Address,\n): JoinedEvent | null {\n return takeJoined([...logs], batcher, account);\n}\n\n/**\n * {@link findJoined} for a receipt with several `Joined` logs to the same\n * account: removes the match from `logs`, so walking the legs in order pairs\n * each with its own log even when the adapter omits emitter addresses.\n */\nexport function takeJoined(\n logs: RawLog[],\n batcher: Address,\n account?: Address,\n): JoinedEvent | null {\n const normalizedAccount = account ? getAddress(account) : undefined;\n for (const [index, log] of logs.entries()) {\n const event = matchJoined(log, batcher, normalizedAccount);\n if (event) {\n logs.splice(index, 1);\n return event;\n }\n }\n return null;\n}\n","import type { Address } from \"viem\";\nimport type { EncryptedValue } from \"../relayer/types\";\nimport type { TelemetryOperation } from \"../telemetry\";\nimport type { TransactionResult } from \"../types\";\n\n/**\n * A batch's lifecycle state. The numbers mirror the batcher contract's own\n * enum, so they are part of the on-chain contract, not an arbitrary encoding.\n */\nexport const BatchState = {\n /** Open: accepts joins and quits. Always the batcher's `currentBatchId`. */\n Pending: 0,\n /** Closed; the aggregate amount is being decrypted. Only `finalize` applies, which a keeper normally sends. */\n Dispatched: 1,\n /** Settled with an exchange rate — the only state in which `claim` succeeds. */\n Finalized: 2,\n /** The route failed or the callback deadline passed; `quit` refunds the original deposit. */\n Canceled: 3,\n} as const;\n\n/** Union of all {@link BatchState} values. */\nexport type BatchState = (typeof BatchState)[keyof typeof BatchState];\n\n/** Addresses that make up one confidential vault. */\nexport interface VaultAddresses {\n /**\n * The ERC-4626 vault contract that holds the underlying asset and issues\n * shares. Optional — both batchers report it on chain. Passing it does not\n * skip that read: it is verified against what the batchers report.\n */\n vault?: Address;\n /** The batcher users join to deposit the confidential underlying asset into the vault. */\n depositBatcher: Address;\n /** The batcher users join to redeem confidential shares back into the underlying asset. */\n redeemBatcher: Address;\n}\n\n/** Options for {@link VaultBatcher.join}. */\nexport interface JoinOptions {\n /**\n * Skip the confidential-balance pre-flight before joining — for accounts\n * whose balance the connected signer cannot decrypt, such as smart wallets.\n */\n skipBalanceCheck?: boolean;\n /** @internal */\n readonly operation?: TelemetryOperation;\n}\n\n/** Options for {@link Vault.deposit} and {@link Vault.redeem}. */\nexport interface VaultJoinOptions extends JoinOptions {\n /**\n * Account credited in the batch. Defaults to the connected wallet address.\n *\n * Set this to join on behalf of another account — but note that the\n * beneficiary, not the caller, then owns the position: only they can\n * {@link VaultBatcher.quit} it, and {@link VaultBatcher.claim} pays out to\n * them.\n */\n beneficiary?: Address;\n /**\n * Unix timestamp until which the batcher's operator grant on the joined\n * token is valid. Only used when a grant isn't already active. Defaults to\n * `Token.setOperator`'s own default (now + 1 hour).\n */\n operatorUntil?: number;\n}\n\n/** What the batcher reported for a successful join. */\nexport interface JoinResult extends TransactionResult {\n /** The batch the join landed in. */\n batchId: bigint;\n /** The account credited — the beneficiary, which may not be the caller. */\n beneficiary: Address;\n /**\n * The encrypted amount actually credited, which is **not** always the amount\n * requested: an ERC-7984 transfer moves zero rather than reverting when the\n * balance is short. Decrypt it to confirm the join landed in full.\n */\n confidentialJoinedAmount: EncryptedValue;\n}\n","import { getAddress, type Address, type Hex } from \"viem\";\nimport { unwrapAmountContract } from \"../contracts\";\nimport {\n DecryptionFailedError,\n EncryptionFailedError,\n SignerNotConfiguredError,\n TransactionRevertedError,\n VaultBatchNotDispatchedError,\n} from \"../errors\";\nimport type { TransactionOperation } from \"../events/sdk-events\";\nimport type { EncryptedValue } from \"../relayer/types\";\nimport { type TelemetryOperation, withOperation } from \"../telemetry\";\nimport { Token } from \"../token\";\nimport type { GenericSigner, TransactionResult, WriteContractConfig } from \"../types\";\nimport { requireAlignedWalletAccount, requireChainAlignment } from \"../utils/alignment\";\nimport { assertConfidentialBalance } from \"../utils/assert-balance\";\nimport { assertBigint } from \"../utils/assertions\";\nimport { isEncryptedValueZero } from \"../utils/handles\";\nimport { memoizeAddressRead } from \"../utils/memoize-address-read\";\nimport { submitTransaction as submitSdkTransaction } from \"../utils/submit-transaction\";\nimport type { ZamaSDK } from \"../zama-sdk\";\nimport {\n batchCallbackDeadlineContract,\n batchCreatedAtContract,\n batchDispatchedAtContract,\n batchMinBatchAgeContract,\n batchStateContract,\n callbackDeadlineContract,\n claimContract,\n currentBatchIdContract,\n depositsContract,\n dispatchBatchCallbackContract,\n dispatchBatchContract,\n exchangeRateContract,\n exchangeRateDecimalsContract,\n fromTokenContract,\n joinContract,\n minBatchAgeContract,\n pausedContract,\n quitContract,\n recoverContract,\n toTokenContract,\n totalDepositsContract,\n unwrapRequestIdContract,\n vaultContract,\n} from \"./contracts\";\nimport { findJoined } from \"./events\";\nimport { BatchState, type JoinOptions, type JoinResult } from \"./types\";\n\n/** A settlement built but not sent: what {@link VaultBatcher.prepareFinalize} returns. */\nexport interface PreparedFinalize {\n /** The batch the call settles. */\n readonly batchId: bigint;\n /** The publicly decrypted amount the batch's unwrap released. */\n readonly unwrapAmountCleartext: bigint;\n /** The relayer's proof of that decryption, which the batcher verifies. */\n readonly decryptionProof: Hex;\n /** The `dispatchBatchCallback` call, ready for the host's own signer. */\n readonly call: WriteContractConfig;\n}\n\n/**\n * One on-chain batcher contract: it pools participants' encrypted amounts,\n * dispatches only the decrypted aggregate through the underlying ERC-4626\n * vault, and lets each participant claim their share. A vault has one batcher\n * per direction, so construct one instance for deposits and one for redeems.\n *\n * The lifecycle is `join` → `dispatchBatch` → `claim`. Finalization between\n * the last two is normally driven by a keeper, an off-chain service that\n * sends each dispatched batch's callback, so a batch is claimable only once it\n * reaches {@link BatchState.Finalized}, which can be well after dispatch;\n * {@link finalize} settles a batch the keeper has not.\n */\nexport class VaultBatcher {\n /** The SDK instance this batcher reads and writes through. */\n readonly sdk: ZamaSDK;\n /** Checksummed address of the batcher contract. */\n readonly address: Address;\n\n readonly #vault: () => Promise<Address>;\n readonly #fromToken: () => Promise<Address>;\n readonly #toToken: () => Promise<Address>;\n\n // One instance, so repeated joins reuse the token's decrypted-balance cache.\n #fromTokenInstance: Promise<Token> | null = null;\n\n constructor(sdk: ZamaSDK, address: Address) {\n this.sdk = sdk;\n this.address = getAddress(address);\n this.#vault = memoizeAddressRead(() => sdk.provider.readContract(vaultContract(this.address)));\n this.#fromToken = memoizeAddressRead(() =>\n sdk.provider.readContract(fromTokenContract(this.address)),\n );\n this.#toToken = memoizeAddressRead(() =>\n sdk.provider.readContract(toTokenContract(this.address)),\n );\n }\n\n // READS\n\n /**\n * The underlying ERC-4626 vault. Share price (`convertToShares`,\n * `convertToAssets`, `totalAssets`) is read from it directly, not from the\n * batcher. Resolved once and cached.\n */\n async vault(): Promise<Address> {\n return this.#vault();\n }\n\n /**\n * The confidential token this batcher accepts as input (e.g. shares for a\n * redeem batcher). Resolved once and cached.\n */\n async fromToken(): Promise<Address> {\n return this.#fromToken();\n }\n\n /**\n * The confidential token this batcher pays out (e.g. shares for a\n * deposit batcher). Resolved once and cached.\n */\n async toToken(): Promise<Address> {\n return this.#toToken();\n }\n\n /** The id of the currently open (not-yet-dispatched) batch. */\n async currentBatchId(): Promise<bigint> {\n return this.sdk.provider.readContract(currentBatchIdContract(this.address));\n }\n\n /**\n * A batch's lifecycle state. See {@link BatchState} for which operation each\n * state allows.\n *\n * @throws Reverts on chain with `BatchNonexistent` for an id above\n * {@link currentBatchId} — batch ids start at 1.\n */\n async batchState(batchId: bigint): Promise<BatchState> {\n // The ABI types this uint8 enum as a plain `number`.\n const state = await this.sdk.provider.readContract(batchStateContract(this.address, batchId));\n return state as BatchState;\n }\n\n /** Whether the batcher is paused. While paused, `join` and `dispatchBatch` revert; `quit` and `claim` still work. */\n async paused(): Promise<boolean> {\n return this.sdk.provider.readContract(pausedContract(this.address));\n }\n\n /**\n * The policy for batches opened from now on. Dispatch of an existing batch\n * is gated on {@link batchMinBatchAge} instead.\n */\n async minBatchAge(): Promise<bigint> {\n return this.sdk.provider.readContract(minBatchAgeContract(this.address));\n }\n\n /** The minimum age in seconds pinned to `batchId` when it opened — the value dispatch enforces. */\n async batchMinBatchAge(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(batchMinBatchAgeContract(this.address, batchId));\n }\n\n /**\n * How long a dispatched batch may wait for its decryption callback before it\n * is canceled — seconds, not a timestamp, despite the name. Applies to\n * batches opened from now on; for an existing batch use\n * {@link batchCallbackDeadline}.\n */\n async callbackDeadline(): Promise<bigint> {\n return this.sdk.provider.readContract(callbackDeadlineContract(this.address));\n }\n\n /**\n * The callback deadline pinned to `batchId` when it opened. Add it to\n * {@link batchDispatchedAt} for the timestamp that batch must finalize by.\n */\n async batchCallbackDeadline(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(batchCallbackDeadlineContract(this.address, batchId));\n }\n\n /** The Unix timestamp (seconds) at which a batch was opened. */\n async batchCreatedAt(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(batchCreatedAtContract(this.address, batchId));\n }\n\n /** The Unix timestamp (seconds) at which a batch was dispatched, or `0` if it hasn't been yet. */\n async batchDispatchedAt(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(batchDispatchedAtContract(this.address, batchId));\n }\n\n /**\n * A finalized batch's exchange rate, scaled by\n * {@link exchangeRateDecimals}; `0` until the batch finalizes. A claim pays\n * out `deposit * exchangeRate / 10 ** exchangeRateDecimals`, rounded down.\n */\n async exchangeRate(batchId: bigint): Promise<bigint> {\n return this.sdk.provider.readContract(exchangeRateContract(this.address, batchId));\n }\n\n /** The number of decimals {@link exchangeRate} is scaled by. */\n async exchangeRateDecimals(): Promise<number> {\n return this.sdk.provider.readContract(exchangeRateDecimalsContract(this.address));\n }\n\n /**\n * Seconds until `batchId` becomes eligible for dispatch, `0` once it already\n * is — the earliest possible moment, not a promise anyone will dispatch\n * then. `null` once the batch has left {@link BatchState.Pending} and can\n * never be dispatched again.\n *\n * Measured against the chain's block timestamp and the batch's own pinned\n * minimum age, so neither local clock drift nor a mid-flight policy change\n * desyncs the countdown.\n */\n async timeUntilDispatchable(batchId: bigint): Promise<bigint | null> {\n const [state, createdAt, minAge, now] = await Promise.all([\n this.batchState(batchId),\n this.batchCreatedAt(batchId),\n this.batchMinBatchAge(batchId),\n this.sdk.provider.getBlockTimestamp(),\n ]);\n if (state !== BatchState.Pending) {\n return null;\n }\n const eligibleAt = createdAt + minAge;\n return eligibleAt > now ? eligibleAt - now : 0n;\n }\n\n /**\n * Seconds until a dispatched batch reaches its callback deadline, `0` once\n * it has. From then on {@link finalize} cancels the batch instead of\n * settling it. `null` outside {@link BatchState.Dispatched}, where there is\n * nothing to finalize.\n *\n * Measured against the chain's block timestamp and the batch's own pinned\n * deadline, like {@link timeUntilDispatchable}.\n */\n async timeUntilCallbackDeadline(batchId: bigint): Promise<bigint | null> {\n const [state, dispatchedAt, deadline, now] = await Promise.all([\n this.batchState(batchId),\n this.batchDispatchedAt(batchId),\n this.batchCallbackDeadline(batchId),\n this.sdk.provider.getBlockTimestamp(),\n ]);\n if (state !== BatchState.Dispatched) {\n return null;\n }\n const cancelsAt = dispatchedAt + deadline;\n return cancelsAt > now ? cancelsAt - now : 0n;\n }\n\n /** The encrypted aggregate amount joined into a batch, without decrypting it. */\n async confidentialTotalDeposits(batchId: bigint): Promise<EncryptedValue> {\n return this.sdk.provider.readContract(totalDepositsContract(this.address, batchId));\n }\n\n /** The encrypted amount `account` joined into a batch, without decrypting it. */\n async confidentialDepositOf(batchId: bigint, account: Address): Promise<EncryptedValue> {\n return this.sdk.provider.readContract(\n depositsContract(this.address, batchId, getAddress(account)),\n );\n }\n\n /**\n * The unwrap request on `fromToken` that a dispatched batch settles against\n * once its amount is publicly decrypted. Zero until the batch is dispatched.\n */\n async unwrapRequestId(batchId: bigint): Promise<EncryptedValue> {\n return this.sdk.provider.readContract(unwrapRequestIdContract(this.address, batchId));\n }\n\n /**\n * Decrypt and return the plaintext amount `account` joined into a batch.\n * Acquires FHE credentials via a wallet signature if none are cached.\n */\n async depositOf(batchId: bigint, account: Address): Promise<bigint> {\n const normalizedAccount = getAddress(account);\n const encryptedValue = await this.confidentialDepositOf(batchId, normalizedAccount);\n if (isEncryptedValueZero(encryptedValue)) {\n return 0n;\n }\n const result = await this.sdk.decryption.decryptValues(\n [{ encryptedValue, contractAddress: this.address }],\n { operation: \"vault-deposit-of\" },\n );\n const value = result[encryptedValue];\n if (value === undefined) {\n throw new DecryptionFailedError(`Decryption returned no value for ${encryptedValue}`);\n }\n assertBigint(value, \"depositOf: result[encryptedValue]\");\n return value;\n }\n\n // WRITES\n\n /**\n * Join the currently open batch with a plaintext amount, encrypted via FHE\n * automatically. Once someone calls {@link dispatchBatch} and the batch\n * is finalized, call {@link claim} to receive the output.\n *\n * @param amount - The plaintext amount to contribute; encrypted before submission.\n * @param beneficiary - Recipient of the batch's eventual output. Defaults to the connected wallet account.\n *\n * @remarks\n * The batcher must already hold an ERC-7984 operator grant from the caller,\n * or it cannot pull the amount. A join with too little balance still\n * succeeds on chain and credits nothing, so the amount is checked against\n * the caller's confidential balance first; `confidentialJoinedAmount` is the\n * authoritative record of what actually landed.\n *\n * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n */\n async join(amount: bigint, beneficiary?: Address, options?: JoinOptions): Promise<JoinResult> {\n const { operation } = withOperation(options, \"vault-join\");\n this.#requireSigner(\"join\");\n const account = await requireAlignedWalletAccount(\"join\", this.sdk.signer, this.sdk.provider);\n const userAddress = getAddress(account.address);\n const resolvedBeneficiary = beneficiary ? getAddress(beneficiary) : userAddress;\n\n if (!options?.skipBalanceCheck) {\n await this.#assertJoinableBalance(amount, operation);\n }\n\n const { encryptedValues, inputProof } = await this.sdk.encrypt(\n { values: [{ value: amount, type: \"euint64\" }], contractAddress: this.address, userAddress },\n { operation },\n );\n\n const encryptedAmount = encryptedValues[0];\n if (!encryptedAmount) {\n throw new EncryptionFailedError(\"Encryption returned no encrypted values\");\n }\n\n const result = await this.#submitTransaction(\n \"vault:join\",\n joinContract(this.address, resolvedBeneficiary, encryptedAmount, inputProof),\n );\n\n const joined = findJoined(result.receipt.logs, this.address, resolvedBeneficiary);\n if (!joined) {\n throw new TransactionRevertedError(\n `No Joined event for ${resolvedBeneficiary} from batcher ${this.address} found in the join receipt`,\n );\n }\n return {\n ...result,\n batchId: joined.batchId,\n beneficiary: joined.account,\n confidentialJoinedAmount: joined.confidentialAmount,\n };\n }\n\n /**\n * Withdraw the caller's own deposit from a batch, returning it to their\n * confidential balance on `fromToken`.\n *\n * Legal in two states: {@link BatchState.Pending} (undo a join before\n * dispatch) and {@link BatchState.Canceled} (take the deposit back after a\n * batch failed to finalize).\n *\n * Refunds the caller only. To refund someone else's deposit in a canceled\n * batch, use {@link recover}.\n */\n async quit(batchId: bigint): Promise<TransactionResult> {\n this.#requireSigner(\"quit\");\n await requireChainAlignment(\"quit\", this.sdk.signer, this.sdk.provider);\n return this.#submitTransaction(\"vault:quit\", quitContract(this.address, batchId));\n }\n\n /**\n * Refund `account`'s deposit in a canceled batch on their behalf.\n * Permissionless — anyone can call this, and the refund always goes to\n * `account`, never to the caller.\n *\n * Only legal once the batch reaches {@link BatchState.Canceled}; before that,\n * a participant undoes their own join with {@link quit}.\n *\n * @param account - The depositor to refund. Defaults to the connected wallet account.\n */\n async recover(batchId: bigint, account?: Address): Promise<TransactionResult> {\n const target = await this.#resolveTarget(\"recover\", account);\n return this.#submitTransaction(\"vault:recover\", recoverContract(this.address, batchId, target));\n }\n\n /**\n * Claim a finalized batch's output for `account`. Permissionless — anyone\n * can call this on another account's behalf, and the output always goes to\n * `account`, never to the caller. The amount is not returned; read it as a\n * balance on the batcher's {@link toToken}.\n *\n * Only legal once the batch reaches {@link BatchState.Finalized}; on a\n * canceled batch use {@link quit} or {@link recover} instead.\n *\n * @param account - The account to claim for. Defaults to the connected wallet account.\n */\n async claim(batchId: bigint, account?: Address): Promise<TransactionResult> {\n const target = await this.#resolveTarget(\"claim\", account);\n return this.#submitTransaction(\"vault:claim\", claimContract(this.address, batchId, target));\n }\n\n /**\n * Close the current batch once it has reached its pinned minimum age and\n * kick off decryption of its aggregate amount. Permissionless — any\n * account with a configured signer can call this, not just participants.\n * Reverts while the batcher is {@link paused}.\n */\n async dispatchBatch(): Promise<TransactionResult> {\n this.#requireSigner(\"dispatchBatch\");\n await requireChainAlignment(\"dispatchBatch\", this.sdk.signer, this.sdk.provider);\n return this.#submitTransaction(\"vault:dispatchBatch\", dispatchBatchContract(this.address));\n }\n\n /**\n * Settle a dispatched batch yourself: publicly decrypt the aggregate amount\n * its unwrap request released and hand the cleartext and proof to the\n * batcher, which executes the route. Permissionless, like\n * {@link dispatchBatch}. A keeper normally does this, so reach for it\n * when a batch has sat in {@link BatchState.Dispatched} longer than\n * expected. Past the batch's callback deadline the same call cancels the\n * batch instead of settling it; {@link timeUntilCallbackDeadline} says\n * which one a call now does.\n *\n * @throws if no signer is configured. {@link SignerNotConfiguredError}\n * @throws if the batch is not {@link BatchState.Dispatched}, for example because a keeper already finalized it. {@link VaultBatchNotDispatchedError}\n * @throws if the public decryption returns no cleartext for the amount. {@link DecryptionFailedError}\n */\n async finalize(batchId: bigint): Promise<TransactionResult> {\n this.#requireSigner(\"finalize\");\n await requireChainAlignment(\"finalize\", this.sdk.signer, this.sdk.provider);\n const { call } = await this.prepareFinalize(batchId);\n return this.#submitTransaction(\"vault:finalize\", call);\n }\n\n /**\n * Build the settlement {@link finalize} sends without sending it: the\n * `dispatchBatchCallback` call with the publicly decrypted amount and its\n * proof, for a host that signs and sends through its own pipeline. Needs no\n * signer.\n *\n * @throws if the batch is not {@link BatchState.Dispatched}, for example because a keeper already finalized it. {@link VaultBatchNotDispatchedError}\n * @throws if the public decryption returns no cleartext for the amount. {@link DecryptionFailedError}\n */\n async prepareFinalize(batchId: bigint): Promise<PreparedFinalize> {\n const [state, unwrapRequestId, wrapper] = await Promise.all([\n this.batchState(batchId),\n this.unwrapRequestId(batchId),\n this.fromToken(),\n ]);\n // Checked before the decryption: outside `Dispatched` the request id is unset or already\n // consumed, so the relayer round trip would end in an opaque error or a reverting call.\n if (state !== BatchState.Dispatched) {\n const name = Object.entries(BatchState).find(([, value]) => value === state)?.[0] ?? state;\n throw new VaultBatchNotDispatchedError(\n `Batch ${batchId} of batcher ${this.address} is ${name}, but only a Dispatched batch can be finalized`,\n { batcher: this.address, batchId, state },\n );\n }\n const encryptedAmount = await this.sdk.provider.readContract(\n unwrapAmountContract(wrapper, unwrapRequestId),\n );\n const { clearValues, decryptionProof } = await this.sdk.decryption.decryptPublicValues(\n [encryptedAmount],\n { operation: \"vault-finalize\" },\n );\n const cleartext = clearValues[encryptedAmount];\n if (cleartext === undefined) {\n throw new DecryptionFailedError(`Public decryption returned no value for ${encryptedAmount}`);\n }\n assertBigint(cleartext, \"finalize: clearValues[encryptedAmount]\");\n return {\n batchId,\n unwrapAmountCleartext: cleartext,\n decryptionProof,\n call: dispatchBatchCallbackContract(this.address, batchId, cleartext, decryptionProof),\n };\n }\n\n // INTERNAL\n\n #requireSigner(operation: string): GenericSigner {\n if (!this.sdk.signer) {\n throw new SignerNotConfiguredError(operation);\n }\n return this.sdk.signer;\n }\n\n async #inputToken(): Promise<Token> {\n this.#fromTokenInstance ??= this.fromToken()\n .then((address) => new Token(this.sdk, address))\n .catch((error: unknown) => {\n this.#fromTokenInstance = null;\n throw error;\n });\n return this.#fromTokenInstance;\n }\n\n async #assertJoinableBalance(\n amount: bigint,\n telemetryOperation: TelemetryOperation,\n ): Promise<void> {\n const token = await this.#inputToken();\n return assertConfidentialBalance({\n operation: \"join\",\n tokenAddress: token.address,\n amount,\n signer: this.sdk.signer,\n provider: this.sdk.provider,\n readBalance: (owner) => token.decryptBalance(owner, telemetryOperation),\n });\n }\n\n /**\n * Chain alignment is verified even when `account` is someone else's: the\n * connected signer still submits the transaction.\n */\n async #resolveTarget(operation: string, account: Address | undefined): Promise<Address> {\n this.#requireSigner(operation);\n if (account) {\n await requireChainAlignment(operation, this.sdk.signer, this.sdk.provider);\n return getAddress(account);\n }\n const aligned = await requireAlignedWalletAccount(\n operation,\n this.sdk.signer,\n this.sdk.provider,\n );\n return getAddress(aligned.address);\n }\n\n async #submitTransaction(\n operation: TransactionOperation,\n config: WriteContractConfig,\n ): Promise<TransactionResult> {\n return submitSdkTransaction({\n operation,\n signer: this.#requireSigner(operation),\n provider: this.sdk.provider,\n config,\n emit: (input) => this.sdk.emitEvent(input, this.address),\n logger: this.sdk.logger,\n });\n }\n}\n\n/**\n * Create a {@link VaultBatcher} bound to `sdk` for the batcher contract at `address`.\n *\n * @example\n * ```ts\n * import { createVaultBatcher } from \"@zama-fhe/sdk/vaults\";\n *\n * const depositBatcher = createVaultBatcher(sdk, \"0xDepositBatcher\");\n * const { batchId } = await depositBatcher.join(1_000_000n);\n * ```\n */\nexport function createVaultBatcher(sdk: ZamaSDK, address: Address): VaultBatcher {\n return new VaultBatcher(sdk, address);\n}\n","import { getAddress, type Address } from \"viem\";\nimport { ConfigurationError, SignerNotConfiguredError } from \"../errors\";\nimport { WrappedToken } from \"../token\";\nimport type { ZamaSDK } from \"../zama-sdk\";\nimport type { JoinResult, VaultAddresses, VaultJoinOptions } from \"./types\";\nimport { VaultBatcher } from \"./vault-batcher\";\n\n/**\n * A confidential ERC-4626 vault: one deposit batcher and one redeem batcher\n * behind ERC-4626-style `deposit` and `redeem` methods.\n *\n * Claiming, quitting and batch state live on the two batchers directly —\n * `vault.depositBatcher.claim(batchId)`.\n */\nexport class Vault {\n /** The SDK instance this vault reads and writes through. */\n readonly sdk: ZamaSDK;\n /** Joined by deposits of the underlying asset. */\n readonly depositBatcher: VaultBatcher;\n /** Joined by share redemptions. */\n readonly redeemBatcher: VaultBatcher;\n\n // The promise is cached, not just the resolved value, so concurrent callers\n // share one lookup and end up with the same instance.\n #vaultAddress: Promise<Address> | null = null;\n #cAsset: Promise<WrappedToken> | null = null;\n #cShare: Promise<WrappedToken> | null = null;\n\n readonly #expectedVaultAddress: Address | undefined;\n\n constructor(sdk: ZamaSDK, addresses: VaultAddresses) {\n this.sdk = sdk;\n this.#expectedVaultAddress = addresses.vault ? getAddress(addresses.vault) : undefined;\n this.depositBatcher = new VaultBatcher(sdk, addresses.depositBatcher);\n this.redeemBatcher = new VaultBatcher(sdk, addresses.redeemBatcher);\n }\n\n /**\n * The underlying ERC-4626 vault contract, read from both batchers rather\n * than trusted from configuration. Resolved once and cached.\n *\n * @throws if the batchers report different vaults, or either disagrees with\n * an `addresses.vault` passed to the constructor — a mismatched pair would\n * settle deposits and redemptions against different vaults.\n * {@link ConfigurationError}\n */\n async vaultAddress(): Promise<Address> {\n this.#vaultAddress ??= this.#resolveVaultAddress().catch((error: unknown) => {\n this.#vaultAddress = null;\n throw error;\n });\n return this.#vaultAddress;\n }\n\n /**\n * The confidential wrapper of the vault's underlying asset — the token\n * deposits are paid in. Resolved once and cached.\n */\n async cAsset(): Promise<WrappedToken> {\n this.#cAsset ??= this.depositBatcher\n .fromToken()\n .then((address) => new WrappedToken(this.sdk, address))\n .catch((error: unknown) => {\n this.#cAsset = null;\n throw error;\n });\n return this.#cAsset;\n }\n\n /**\n * The confidential share token this vault issues. Resolved once and cached.\n *\n * Read from the redeem batcher, which is the contract that actually pulls\n * these shares and so decides which token a redemption must grant on.\n */\n async cShare(): Promise<WrappedToken> {\n this.#cShare ??= this.redeemBatcher\n .fromToken()\n .then((address) => new WrappedToken(this.sdk, address))\n .catch((error: unknown) => {\n this.#cShare = null;\n throw error;\n });\n return this.#cShare;\n }\n\n /**\n * Deposit a plaintext amount of the underlying confidential asset,\n * joining the current deposit batch. Grants the deposit batcher an\n * ERC-7984 operator approval on the deposit token first, unless one is\n * already active.\n *\n * @param amount - The plaintext amount to deposit.\n * @throws before any approval is granted, if the batchers do not agree on\n * the vault. {@link ConfigurationError}\n */\n async deposit(amount: bigint, options?: VaultJoinOptions): Promise<JoinResult> {\n const [, token] = await Promise.all([this.vaultAddress(), this.cAsset()]);\n await this.#ensureOperator(\n \"deposit\",\n token,\n this.depositBatcher.address,\n options?.operatorUntil,\n );\n return this.depositBatcher.join(amount, options?.beneficiary, {\n skipBalanceCheck: options?.skipBalanceCheck,\n operation: \"vault-deposit\",\n });\n }\n\n /**\n * Join the current redeem batch, which the vault later settles into the\n * underlying asset at the batch's exchange rate. Grants the redeem batcher\n * an ERC-7984 operator approval on the share token first, unless one is\n * already active.\n *\n * @param amount - The plaintext amount of shares — ERC-4626 `redeem`, not\n * `withdraw`, so this is denominated in shares, never in assets.\n * @throws before any approval is granted, if the batchers do not agree on\n * the vault. {@link ConfigurationError}\n */\n async redeem(amount: bigint, options?: VaultJoinOptions): Promise<JoinResult> {\n const [, token] = await Promise.all([this.vaultAddress(), this.cShare()]);\n await this.#ensureOperator(\"redeem\", token, this.redeemBatcher.address, options?.operatorUntil);\n return this.redeemBatcher.join(amount, options?.beneficiary, {\n skipBalanceCheck: options?.skipBalanceCheck,\n operation: \"vault-redeem\",\n });\n }\n\n async #resolveVaultAddress(): Promise<Address> {\n const [depositVault, redeemVault] = await Promise.all([\n this.depositBatcher.vault(),\n this.redeemBatcher.vault(),\n ]);\n if (getAddress(depositVault) !== getAddress(redeemVault)) {\n throw new ConfigurationError(\n `Vault batchers point at different ERC-4626 vaults: deposit batcher ${this.depositBatcher.address} reports ${depositVault}, redeem batcher ${this.redeemBatcher.address} reports ${redeemVault}`,\n );\n }\n const onChain = getAddress(depositVault);\n if (this.#expectedVaultAddress !== undefined && this.#expectedVaultAddress !== onChain) {\n throw new ConfigurationError(\n `Configured vault address ${this.#expectedVaultAddress} does not match the ${onChain} both batchers report`,\n );\n }\n return onChain;\n }\n\n /**\n * The batcher pulls with `confidentialTransferFrom`, which ERC-7984 rejects\n * unless the batcher is already an operator of the caller.\n */\n async #ensureOperator(\n operation: string,\n token: WrappedToken,\n operator: Address,\n until: number | undefined,\n ): Promise<void> {\n if (!this.sdk.signer) {\n throw new SignerNotConfiguredError(operation);\n }\n const account = this.sdk.signer.requireWalletAccount(operation);\n const alreadyApproved = await token.isOperator(account.address, operator);\n if (!alreadyApproved) {\n await token.setOperator(operator, until);\n }\n }\n}\n\n/**\n * Create a {@link Vault} bound to `sdk` for the deposit/redeem batchers at `addresses`.\n *\n * @example\n * ```ts\n * import { createVault } from \"@zama-fhe/sdk/vaults\";\n *\n * const vault = createVault(sdk, {\n * depositBatcher: \"0xDepositBatcher\",\n * redeemBatcher: \"0xRedeemBatcher\",\n * });\n * const { batchId } = await vault.deposit(1_000_000n);\n * // …once the batch is dispatched and reaches BatchState.Finalized:\n * await vault.depositBatcher.claim(batchId);\n * ```\n */\nexport function createVault(sdk: ZamaSDK, addresses: VaultAddresses): Vault {\n return new Vault(sdk, addresses);\n}\n","import { getAddress } from \"viem\";\nimport { ConfigurationError } from \"../errors\";\nimport type { RawLog } from \"../types/transaction\";\nimport { takeJoined } from \"./events\";\nimport type {\n DecodedVaultGroupJoins,\n JoinDelivery,\n PreparedVaultGroupJoin,\n VaultGroupConfig,\n VaultGroupJoin,\n VaultGroupOperator,\n} from \"./vault-group-types\";\n\n// Group functions that need no SDK instance, for a host that has only the config or saved legs.\n\n/**\n * The operator grants a redemption of `config` with `delivery` relies on,\n * from the config alone: the router on every member's `cShare` for\n * `\"router\"`, none for `\"legs\"` or a group of one. The same answer as\n * {@link VaultGroup.redeemOperators}, for the parts of a host's transaction\n * pipeline that run with the config in hand but no SDK instance in scope,\n * such as the guard that decides whether a grant transaction is needed.\n *\n * @throws if `delivery` is `\"router\"` and a member gives no `cShare`, or the config names no router. {@link ConfigurationError}\n */\nexport function vaultGroupRedeemOperators(\n config: VaultGroupConfig,\n delivery: JoinDelivery = \"router\",\n): readonly VaultGroupOperator[] {\n if (config.vaults.length === 1 || delivery === \"legs\") {\n return [];\n }\n if (config.router === undefined) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" names no router, which a router submission needs`,\n );\n }\n const router = getAddress(config.router);\n return config.vaults.map((member) => {\n if (member.cShare === undefined) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" gives no cShare for \"${member.id}\", which redeemOperators needs; pass it, or use prepareRedeem`,\n );\n }\n return { vaultId: member.id, token: getAddress(member.cShare), spender: router };\n });\n}\n\n/**\n * Pair each leg of a submission with its `Joined` log in `logs`: what\n * {@link PreparedVaultGroupJoin.decodeJoins} does, from plain data, so a host\n * that saved the legs and the account can decode after a reload. A leg with\n * no log is reported in `unconfirmed` rather than thrown, so the host decides\n * what a partial match means for its delivery; for a partly sent `\"legs\"`\n * delivery, those are the legs still to send.\n *\n * @param prepared - The submission's `legs` and `account`.\n * @param logs - Every mined receipt's logs. For a `\"legs\"` delivery, pass the\n * receipts in leg order: when the adapter omits log addresses, legs pair\n * with logs by position.\n */\nexport function decodeVaultGroupJoins(\n prepared: Pick<PreparedVaultGroupJoin, \"legs\" | \"account\">,\n logs: readonly RawLog[],\n): DecodedVaultGroupJoins {\n // Each log is consumed once, so the Nth match is the Nth leg's even when\n // the adapter omits log addresses.\n const remaining = [...logs];\n const joins: VaultGroupJoin[] = [];\n const unconfirmed: string[] = [];\n for (const leg of prepared.legs) {\n const joined = takeJoined(remaining, leg.batcher, prepared.account);\n if (!joined) {\n unconfirmed.push(leg.vaultId);\n continue;\n }\n joins.push({\n vaultId: leg.vaultId,\n batcher: leg.batcher,\n token: leg.token,\n batchId: joined.batchId,\n confidentialJoinedAmount: joined.confidentialAmount,\n });\n }\n return { joins, unconfirmed };\n}\n","import { getAddress, type Address, type Hex } from \"viem\";\nimport {\n confidentialTransferAndCallContract,\n isConfidentialTokenValidContract,\n} from \"../contracts\";\nimport {\n BalanceCheckUnavailableError,\n ConfigurationError,\n EncryptionFailedError,\n SignerNotConfiguredError,\n UnlistedConfidentialTokenError,\n VaultBatcherPausedError,\n VaultGroupJoinUnconfirmedError,\n} from \"../errors\";\nimport type { EncryptedValue } from \"../relayer/types\";\nimport { withOperation, type TelemetryOperation } from \"../telemetry\";\nimport { Token, WrappedToken } from \"../token\";\nimport type { GenericSigner } from \"../types\";\nimport { requireAlignedWalletAccount } from \"../utils/alignment\";\nimport { assertConfidentialBalance } from \"../utils/assert-balance\";\nimport { memoizeAddressRead } from \"../utils/memoize-address-read\";\nimport { submitTransaction as submitSdkTransaction } from \"../utils/submit-transaction\";\nimport type { ZamaSDK } from \"../zama-sdk\";\nimport {\n encodeAllocationData,\n routerJoinContract,\n tokenWrapperRegistryContract,\n type EncryptedAllocationLeg,\n} from \"./contracts\";\nimport { Vault } from \"./vault\";\nimport type { JoinOptions } from \"./types\";\nimport type { VaultBatcher } from \"./vault-batcher\";\nimport { decodeVaultGroupJoins, vaultGroupRedeemOperators } from \"./vault-group-standalone\";\nimport type {\n Direction,\n JoinDelivery,\n PreparedVaultGroupJoin,\n PreparedVaultGroupWrite,\n PrepareVaultGroupJoinOptions,\n VaultGroupConfig,\n VaultGroupJoinResult,\n VaultGroupLeg,\n VaultGroupMember,\n VaultGroupOperator,\n VaultGroupRedeemOptions,\n} from \"./vault-group-types\";\n\n/** The most vaults a group may name: the router's per-transaction leg limit on the pull path, so a group is always exitable. */\nexport const MAX_GROUP_VAULTS = 10;\n\n/** How long a grant `redeem` makes lasts when the caller gives no `operatorUntil`. */\nconst OPERATOR_WINDOW_SECONDS = 3600;\n\ninterface GroupLeg {\n readonly member: VaultGroupMember;\n readonly batcher: VaultBatcher;\n /** What this leg spends. */\n readonly token: WrappedToken;\n readonly amount: bigint;\n}\n\nconst SIDES = {\n deposit: {\n batcher: (vault: Vault) => vault.depositBatcher,\n // The batcher's asset side: what a deposit batcher pulls, what a redeem batcher pays out.\n asset: (vault: Vault) => vault.depositBatcher.fromToken(),\n },\n redeem: {\n batcher: (vault: Vault) => vault.redeemBatcher,\n asset: (vault: Vault) => vault.redeemBatcher.toToken(),\n },\n} as const;\n\nconst TELEMETRY = {\n deposit: \"vault-group-deposit\",\n redeem: \"vault-group-redeem\",\n} as const satisfies Record<Direction, TelemetryOperation>;\n\n// Deduped: every deposit leg spends the same `cAsset`.\nfunction uniqueTokens(legs: readonly GroupLeg[]): WrappedToken[] {\n return [...new Map(legs.map((leg) => [leg.token.address, leg.token])).values()];\n}\n\nfunction duplicate<T>(values: readonly T[]): T | undefined {\n const seen = new Set<T>();\n for (const value of values) {\n if (seen.has(value)) {\n return value;\n }\n seen.add(value);\n }\n return undefined;\n}\n\nfunction toLeg(leg: GroupLeg): VaultGroupLeg {\n return {\n vaultId: leg.member.id,\n batcher: leg.batcher.address,\n token: leg.token.address,\n amount: leg.amount,\n };\n}\n\n/**\n * Vaults that take deposits in the same confidential asset, joined together: a\n * deposit into one member joins *every* member's batch, the chosen vault with\n * the amount and the rest with an encrypted zero.\n *\n * `deposit` and `redeem` sign and send one transaction through the SDK's\n * signer: through the router, or straight to the batcher for a group of one.\n * `prepareDeposit` and `prepareRedeem` stop short of sending, for a host with\n * its own transaction pipeline, and can also prepare one transfer per member.\n */\nexport class VaultGroup {\n /** The SDK the group reads and writes through. */\n readonly sdk: ZamaSDK;\n /** The configured group id, used in error messages. */\n readonly id: string;\n /** The shared asset wrapper, checksummed. */\n readonly cAsset: Address;\n /** The router a `\"router\"` submission goes through, checksummed; `undefined` when the config names none. */\n readonly router: Address | undefined;\n /** The members in leg order. */\n readonly members: readonly VaultGroupMember[];\n\n readonly #config: VaultGroupConfig;\n readonly #shares: ReadonlyMap<string, Address>;\n readonly #registry: () => Promise<Address>;\n\n constructor(sdk: ZamaSDK, config: VaultGroupConfig) {\n if (config.vaults.length === 0) {\n throw new ConfigurationError(`Vault group \"${config.id}\" names no vault`);\n }\n if (config.vaults.length > MAX_GROUP_VAULTS) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" names ${config.vaults.length} vaults, above the ${MAX_GROUP_VAULTS} a submission can carry`,\n );\n }\n const members = config.vaults.map((member) => ({\n id: member.id,\n vault: new Vault(sdk, member),\n }));\n const duplicateId = duplicate(members.map((member) => member.id));\n if (duplicateId !== undefined) {\n throw new ConfigurationError(`Vault group \"${config.id}\" names \"${duplicateId}\" twice`);\n }\n const duplicateVault = duplicate(\n config.vaults.flatMap((member) => (member.vault ? [getAddress(member.vault)] : [])),\n );\n if (duplicateVault !== undefined) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" gives ${duplicateVault} as the vault of more than one member`,\n );\n }\n // A batcher serves one vault in one direction, so the same address anywhere twice is a mistake.\n const duplicateBatcher = duplicate(\n members.flatMap(({ vault }) => [vault.depositBatcher.address, vault.redeemBatcher.address]),\n );\n if (duplicateBatcher !== undefined) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" names batcher ${duplicateBatcher} more than once`,\n );\n }\n const duplicateShare = duplicate(\n config.vaults.flatMap((member) => (member.cShare ? [getAddress(member.cShare)] : [])),\n );\n if (duplicateShare !== undefined) {\n throw new ConfigurationError(\n `Vault group \"${config.id}\" gives ${duplicateShare} as the share token of more than one member`,\n );\n }\n\n this.sdk = sdk;\n this.#config = config;\n this.id = config.id;\n this.cAsset = getAddress(config.cAsset);\n this.router = config.router ? getAddress(config.router) : undefined;\n this.members = members;\n this.#shares = new Map(\n config.vaults.flatMap((member) =>\n member.cShare ? [[member.id, getAddress(member.cShare)] as const] : [],\n ),\n );\n // The router declares its registry `immutable`, so one read holds for the group's lifetime.\n this.#registry = memoizeAddressRead(async () =>\n getAddress(await sdk.provider.readContract(tokenWrapperRegistryContract(this.#router()))),\n );\n }\n\n /** Whether the router's registry lists `cAsset`, which a router deposit requires. Not cached: a listing can be revoked. */\n async isAssetListed(): Promise<boolean> {\n return this.sdk.provider.readContract(\n isConfidentialTokenValidContract(await this.#registry(), this.cAsset),\n );\n }\n\n /**\n * One member by id.\n *\n * @throws if no member has id `vaultId`. {@link ConfigurationError}\n */\n member(vaultId: string): VaultGroupMember {\n const member = this.members.find((candidate) => candidate.id === vaultId);\n if (!member) {\n throw new ConfigurationError(`Vault group \"${this.id}\" has no vault \"${vaultId}\"`);\n }\n return member;\n }\n\n /**\n * The operator grants a redemption with `delivery` relies on, from the\n * config alone: the router on every member's share token for `\"router\"`,\n * none for `\"legs\"` or a group of one. Lets a host check the grants before\n * it prepares anything.\n *\n * @throws if `delivery` is `\"router\"` and a member's config gives no `cShare`, or the config names no router. {@link ConfigurationError}\n */\n redeemOperators(delivery: JoinDelivery = \"router\"): readonly VaultGroupOperator[] {\n return vaultGroupRedeemOperators(this.#config, delivery);\n }\n\n /**\n * The grants in a prepared redemption's `requiredOperators` that its\n * account does not hold: the ones the host makes before sending the\n * writes, and the ones `redeem` makes itself. `isOperator` answers for the\n * current block, so make each grant with an `until` that outlasts the time\n * the writes take to land.\n */\n async missingOperators(\n prepared: Pick<PreparedVaultGroupJoin, \"account\" | \"requiredOperators\">,\n ): Promise<readonly VaultGroupOperator[]> {\n const granted = await Promise.all(\n prepared.requiredOperators.map((operator) =>\n new Token(this.sdk, operator.token).isOperator(prepared.account, operator.spender),\n ),\n );\n return prepared.requiredOperators.filter((_operator, index) => !granted[index]);\n }\n\n /**\n * Build a deposit without sending it: every verification `deposit` does,\n * the encryptions, and the writes, for a host that signs and sends through\n * its own pipeline.\n *\n * @param vaultId - The member to deposit into.\n * @param amount - The plaintext amount; encrypted before submission.\n * @param options - The account, delivery, and which checks to skip.\n *\n * @throws if no member has id `vaultId`, a `\"router\"` delivery has no router, or the balance check would run for an `account` that is not the signer's. {@link ConfigurationError}\n * @throws unless `skipPreflight`, if a member's batchers disagree with its config or are not paired with `cAsset`, or two members' batchers report the same vault. {@link ConfigurationError}\n * @throws if a member's deposit batcher is paused. {@link VaultBatcherPausedError}\n * @throws unless `skipPreflight`, if a router deposit's `cAsset` is not listed in the router's registry. {@link UnlistedConfidentialTokenError}\n * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n */\n async prepareDeposit(\n vaultId: string,\n amount: bigint,\n options?: PrepareVaultGroupJoinOptions,\n ): Promise<PreparedVaultGroupJoin> {\n return this.#prepare(\"deposit\", vaultId, amount, options);\n }\n\n /**\n * Build a redemption without sending it. The writes rely on the grants in\n * `requiredOperators`; the host makes the ones {@link missingOperators}\n * returns first.\n *\n * @param vaultId - The member to redeem from.\n * @param amount - The plaintext amount of shares: ERC-4626 `redeem`, not\n * `withdraw`, so this is denominated in shares, never in assets.\n * @param options - The account, delivery, and which checks to skip.\n *\n * @throws if no member has id `vaultId`, a `\"router\"` delivery has no router, or the balance check would run for an `account` that is not the signer's. {@link ConfigurationError}\n * @throws unless `skipPreflight`, if a member's batchers disagree with its config or are not paired with `cAsset`, or two members' batchers report the same vault. {@link ConfigurationError}\n * @throws if a member's redeem batcher is paused. {@link VaultBatcherPausedError}\n * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n */\n async prepareRedeem(\n vaultId: string,\n amount: bigint,\n options?: PrepareVaultGroupJoinOptions,\n ): Promise<PreparedVaultGroupJoin> {\n return this.#prepare(\"redeem\", vaultId, amount, options);\n }\n\n /**\n * Deposit the confidential asset into one member of the group, joining every\n * member's current deposit batch in one transaction.\n *\n * @param vaultId - The member to deposit into.\n * @param amount - The plaintext amount; encrypted before submission.\n *\n * @remarks\n * There is no `beneficiary`: the router credits the account the legs came\n * from, so a group deposit cannot be made on someone else's behalf.\n *\n * @throws if no signer is configured. {@link SignerNotConfiguredError}\n * @throws if no member has id `vaultId`, a member's batchers disagree with its config or are not paired with `cAsset`, two members' batchers report the same vault, or a group of more than one member names no router. {@link ConfigurationError}\n * @throws if a member's deposit batcher is paused. {@link VaultBatcherPausedError}\n * @throws if the router's registry does not list `cAsset`. {@link UnlistedConfidentialTokenError}\n * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n * @throws if a `Joined` event in the mined receipt could not be matched to every leg. {@link VaultGroupJoinUnconfirmedError}\n */\n async deposit(\n vaultId: string,\n amount: bigint,\n options?: JoinOptions,\n ): Promise<VaultGroupJoinResult> {\n const signer = this.#requireSigner(\"deposit\");\n const prepared = await this.prepareDeposit(vaultId, amount, {\n skipBalanceCheck: options?.skipBalanceCheck,\n operation: options?.operation,\n });\n return this.#send(signer, prepared);\n }\n\n /**\n * Redeem shares of one member of the group by joining every member's\n * current redeem batch in one transaction, each leg with its own share token.\n *\n * @param vaultId - The member to redeem from.\n * @param amount - The plaintext amount of shares: ERC-4626 `redeem`, not\n * `withdraw`, so this is denominated in shares, never in assets.\n *\n * @remarks\n * In a group of more than one, the router pulls every leg's share token, so\n * before the join this grants it an operator approval on each member's share\n * token that lacks one. Each grant is its own wallet prompt, so a first\n * redemption from a group of N vaults can ask the user to sign up to N + 1\n * times. The balance check decrypts every member's share balance, not only\n * the chosen one's.\n *\n * @throws if no signer is configured. {@link SignerNotConfiguredError}\n * @throws if no member has id `vaultId`, a member's batchers disagree with its config or are not paired with `cAsset`, two members' batchers report the same vault, or a group of more than one member names no router. {@link ConfigurationError}\n * @throws if a member's redeem batcher is paused. {@link VaultBatcherPausedError}\n * @throws if the balance is less than `amount`. {@link InsufficientConfidentialBalanceError}\n * @throws if balance validation requires decryption that is not possible. {@link BalanceCheckUnavailableError}\n * @throws if a `Joined` event in the mined receipt could not be matched to every leg. {@link VaultGroupJoinUnconfirmedError}\n */\n async redeem(\n vaultId: string,\n amount: bigint,\n options?: VaultGroupRedeemOptions,\n ): Promise<VaultGroupJoinResult> {\n const signer = this.#requireSigner(\"redeem\");\n const prepared = await this.prepareRedeem(vaultId, amount, {\n skipBalanceCheck: options?.skipBalanceCheck,\n operation: options?.operation,\n });\n // Encrypted before the grants, which cost the user a signature each; a proof does not expire.\n const missing = await this.missingOperators(prepared);\n if (missing.length > 0) {\n // The token compares the deadline against the block's time, not the local clock.\n const until =\n options?.operatorUntil ??\n Number(await this.sdk.provider.getBlockTimestamp()) + OPERATOR_WINDOW_SECONDS;\n for (const operator of missing) {\n await new Token(this.sdk, operator.token).setOperator(operator.spender, until);\n }\n }\n return this.#send(signer, prepared);\n }\n\n // INTERNAL\n\n #requireSigner(direction: Direction): GenericSigner {\n const signer = this.sdk.signer;\n if (!signer) {\n throw new SignerNotConfiguredError(direction);\n }\n return signer;\n }\n\n #router(): Address {\n if (this.router === undefined) {\n throw new ConfigurationError(\n `Vault group \"${this.id}\" names no router, which a router submission needs`,\n );\n }\n return this.router;\n }\n\n // A group of one has nothing to hide a leg among, so it joins its batcher directly.\n #delivery(requested: JoinDelivery | undefined): JoinDelivery {\n return this.members.length === 1 ? \"legs\" : (requested ?? \"router\");\n }\n\n async #prepare(\n direction: Direction,\n vaultId: string,\n amount: bigint,\n options: PrepareVaultGroupJoinOptions | undefined,\n ): Promise<PreparedVaultGroupJoin> {\n const { operation } = withOperation(options, TELEMETRY[direction]);\n const member = this.member(vaultId);\n const delivery = this.#delivery(options?.delivery);\n const router = delivery === \"router\" ? this.#router() : undefined;\n const account = await this.#account(direction, options);\n\n // Read alongside the legs, so an unlisted asset, or a router with no registry to read, fails\n // before the balance check can prompt the wallet.\n const [legs] = await Promise.all([\n options?.skipPreflight\n ? this.#configuredLegs(direction, member, amount)\n : this.#verifiedLegs(direction, member, amount),\n router === undefined || options?.skipPreflight\n ? undefined\n : direction === \"deposit\"\n ? this.#requireAssetListed()\n : this.#registry(),\n ]);\n if (!options?.skipBalanceCheck) {\n await this.#assertBalance(direction, member, amount, legs, account);\n }\n\n const writes =\n router === undefined\n ? await this.#legWrites(direction, legs, account, operation)\n : await this.#routerWrite(direction, router, member, legs, account, operation);\n\n const publicLegs = legs.map(toLeg);\n return {\n direction,\n vaultId,\n account,\n delivery,\n legs: publicLegs,\n writes,\n requiredOperators:\n direction === \"redeem\" && router !== undefined\n ? legs.map((leg) => ({\n vaultId: leg.member.id,\n token: leg.token.address,\n spender: router,\n }))\n : [],\n decodeJoins: (logs) => decodeVaultGroupJoins({ legs: publicLegs, account }, logs),\n };\n }\n\n async #account(\n direction: Direction,\n options: PrepareVaultGroupJoinOptions | undefined,\n ): Promise<Address> {\n const requested = options?.account === undefined ? undefined : getAddress(options.account);\n if (requested !== undefined && options?.skipBalanceCheck) {\n return requested;\n }\n // The balance check decrypts as the signer, so it can only vouch for the signer's account.\n if (requested !== undefined && this.sdk.signer === undefined) {\n throw new ConfigurationError(\n `The balance check for ${requested} decrypts as the signer, and none is configured; pass skipBalanceCheck to prepare without one`,\n );\n }\n const wallet = getAddress(\n (await requireAlignedWalletAccount(direction, this.sdk.signer, this.sdk.provider)).address,\n );\n if (requested !== undefined && requested !== wallet) {\n throw new ConfigurationError(\n `The balance check for ${requested} decrypts as the signer's account ${wallet}; pass skipBalanceCheck to prepare for another account`,\n );\n }\n return wallet;\n }\n\n // Every member gets a leg, zero-amount ones included: trimming them would reveal which vault was chosen.\n #amountFor(member: VaultGroupMember, chosen: VaultGroupMember, amount: bigint): bigint {\n return member === chosen ? amount : 0n;\n }\n\n // What the config says each leg joins and spends. Only `paused()` and a missing share token are read.\n async #configuredLegs(\n direction: Direction,\n chosen: VaultGroupMember,\n amount: bigint,\n ): Promise<readonly GroupLeg[]> {\n return Promise.all(\n this.members.map(async (member) => {\n const batcher = SIDES[direction].batcher(member.vault);\n const [token, paused] = await Promise.all([\n direction === \"deposit\" ? new WrappedToken(this.sdk, this.cAsset) : this.#share(member),\n batcher.paused(),\n ]);\n this.#assertNotPaused(member, batcher, paused);\n return { member, batcher, token, amount: this.#amountFor(member, chosen, amount) };\n }),\n );\n }\n\n // One paused batcher reverts the whole submission, so every leg's is checked, not just the chosen one's.\n #assertNotPaused(member: VaultGroupMember, batcher: VaultBatcher, paused: boolean): void {\n if (paused) {\n throw new VaultBatcherPausedError(\n `Batcher ${batcher.address} of vault \"${member.id}\" in group \"${this.id}\" is paused, so no member can be joined until it resumes`,\n { batcher: batcher.address, vaultId: member.id },\n );\n }\n }\n\n async #share(member: VaultGroupMember): Promise<WrappedToken> {\n const configured = this.#shares.get(member.id);\n return configured === undefined\n ? member.vault.cShare()\n : new WrappedToken(this.sdk, configured);\n }\n\n async #verifiedLegs(\n direction: Direction,\n chosen: VaultGroupMember,\n amount: bigint,\n ): Promise<readonly GroupLeg[]> {\n const legs = await Promise.all(\n this.members.map((member) =>\n this.#verifiedLeg(direction, member, this.#amountFor(member, chosen, amount)),\n ),\n );\n // The constructor's check only sees configured addresses; the batchers' reports can still name one vault twice.\n const duplicateVault = duplicate(legs.map((leg) => leg.vault));\n if (duplicateVault !== undefined) {\n throw new ConfigurationError(\n `Vault group \"${this.id}\" has two members whose batchers report the same vault ${duplicateVault}`,\n );\n }\n return legs;\n }\n\n async #verifiedLeg(\n direction: Direction,\n member: VaultGroupMember,\n amount: bigint,\n ): Promise<GroupLeg & { readonly vault: Address }> {\n const side = SIDES[direction];\n const batcher = side.batcher(member.vault);\n const [vault, share, asset, paused] = await Promise.all([\n member.vault.vaultAddress(),\n member.vault.cShare(),\n side.asset(member.vault),\n batcher.paused(),\n ]);\n if (getAddress(asset) !== this.cAsset) {\n throw new ConfigurationError(\n `Batcher ${batcher.address} of vault \"${member.id}\" is paired with ${asset}, but group \"${this.id}\" is configured with ${this.cAsset}`,\n );\n }\n const configuredShare = this.#shares.get(member.id);\n if (configuredShare !== undefined && configuredShare !== share.address) {\n throw new ConfigurationError(\n `Vault \"${member.id}\" of group \"${this.id}\" is configured with share token ${configuredShare}, but its redeem batcher pulls ${share.address}`,\n );\n }\n this.#assertNotPaused(member, batcher, paused);\n return {\n member,\n batcher,\n token: direction === \"deposit\" ? new WrappedToken(this.sdk, this.cAsset) : share,\n vault,\n amount,\n };\n }\n\n // A short balance joins every batch with nothing and still costs the transaction.\n async #assertBalance(\n direction: Direction,\n member: VaultGroupMember,\n amount: bigint,\n legs: readonly GroupLeg[],\n account: Address,\n ): Promise<void> {\n const token = legs.find((leg) => leg.member === member)?.token;\n if (token === undefined) {\n throw new ConfigurationError(`Vault group \"${this.id}\" built no leg for \"${member.id}\"`);\n }\n await assertConfidentialBalance({\n operation: direction,\n tokenAddress: token.address,\n amount,\n account,\n signer: this.sdk.signer,\n provider: this.sdk.provider,\n // Every leg's token is decrypted, not just the chosen one's: a lone decrypt would tell the relayer which vault was picked.\n readBalance: async (owner) => {\n const { results, errors } = await Token.batchBalancesOf(uniqueTokens(legs), owner);\n const balance = results.get(token.address);\n if (balance === undefined) {\n throw (\n errors.get(token.address) ??\n new BalanceCheckUnavailableError(`Balance validation failed (token: ${token.address})`)\n );\n }\n return balance;\n },\n });\n }\n\n async #encrypt(\n contractAddress: Address,\n account: Address,\n values: readonly bigint[],\n operation: TelemetryOperation,\n ): Promise<{ readonly encryptedValues: readonly EncryptedValue[]; readonly inputProof: Hex }> {\n const { encryptedValues, inputProof } = await this.sdk.encrypt(\n {\n values: values.map((value) => ({ value, type: \"euint64\" as const })),\n contractAddress,\n userAddress: account,\n },\n { operation },\n );\n if (encryptedValues.length !== values.length) {\n throw new EncryptionFailedError(\n `Encryption returned ${encryptedValues.length} values for ${values.length} legs`,\n );\n }\n return { encryptedValues, inputProof };\n }\n\n // One transfer per leg, each verified by the token it spends: one proof covers a deposit's\n // legs, which all spend `cAsset`; a redemption's legs each spend their own share token.\n async #legWrites(\n direction: Direction,\n legs: readonly GroupLeg[],\n account: Address,\n operation: TelemetryOperation,\n ): Promise<readonly PreparedVaultGroupWrite[]> {\n const write = (leg: GroupLeg, encryptedAmount: EncryptedValue, inputProof: Hex) => ({\n leg: toLeg(leg),\n call: confidentialTransferAndCallContract(\n leg.token.address,\n leg.batcher.address,\n encryptedAmount,\n inputProof,\n \"0x\",\n ),\n });\n if (direction === \"deposit\") {\n const { encryptedValues, inputProof } = await this.#encrypt(\n this.cAsset,\n account,\n legs.map((leg) => leg.amount),\n operation,\n );\n return legs.map((leg, index) =>\n write(leg, encryptedValues[index] as EncryptedValue, inputProof),\n );\n }\n return Promise.all(\n legs.map(async (leg) => {\n const { encryptedValues, inputProof } = await this.#encrypt(\n leg.token.address,\n account,\n [leg.amount],\n operation,\n );\n return write(leg, encryptedValues[0] as EncryptedValue, inputProof);\n }),\n );\n }\n\n // Bound to the router rather than the batchers or the tokens: the router is the contract that verifies the proof.\n async #routerWrite(\n direction: Direction,\n router: Address,\n chosen: VaultGroupMember,\n legs: readonly GroupLeg[],\n account: Address,\n operation: TelemetryOperation,\n ): Promise<readonly PreparedVaultGroupWrite[]> {\n const chosenLeg = legs.find((leg) => leg.member === chosen);\n if (chosenLeg === undefined) {\n throw new ConfigurationError(`Vault group \"${this.id}\" built no leg for \"${chosen.id}\"`);\n }\n const allocation = async (): Promise<{ legs: EncryptedAllocationLeg[]; inputProof: Hex }> => {\n const { encryptedValues, inputProof } = await this.#encrypt(\n router,\n account,\n legs.map((leg) => leg.amount),\n operation,\n );\n return {\n legs: legs.map((leg, index) => ({\n batcher: leg.batcher.address,\n token: leg.token.address,\n amount: encryptedValues[index] as EncryptedValue,\n })),\n inputProof,\n };\n };\n if (direction === \"redeem\") {\n const { legs: encryptedLegs, inputProof } = await allocation();\n return [\n { leg: toLeg(chosenLeg), call: routerJoinContract(router, encryptedLegs, inputProof) },\n ];\n }\n // One encryption per verifying contract: the asset checks the transfer's proof, the router the allocation's.\n const total = legs.reduce((sum, leg) => sum + leg.amount, 0n);\n const [transfer, encryptedAllocation] = await Promise.all([\n this.#encrypt(this.cAsset, account, [total], operation),\n allocation(),\n ]);\n return [\n {\n leg: toLeg(chosenLeg),\n call: confidentialTransferAndCallContract(\n this.cAsset,\n router,\n transfer.encryptedValues[0] as EncryptedValue,\n transfer.inputProof,\n encodeAllocationData(encryptedAllocation.legs, encryptedAllocation.inputProof),\n ),\n },\n ];\n }\n\n // The router rejects a push of an unlisted token with a revert that costs the caller a transaction.\n async #requireAssetListed(): Promise<void> {\n if (!(await this.isAssetListed())) {\n throw new UnlistedConfidentialTokenError(\n `The vault router's registry does not list ${this.cAsset}, so it would reject a transfer of it`,\n { token: this.cAsset, registry: await this.#registry() },\n );\n }\n }\n\n // A router delivery, or a group of one's lone leg: one write either way. Several legs are only\n // private as an atomic bundle, which a host sends itself.\n async #send(\n signer: GenericSigner,\n prepared: PreparedVaultGroupJoin,\n ): Promise<VaultGroupJoinResult> {\n const [write, ...extra] = prepared.writes;\n if (write === undefined || extra.length > 0) {\n throw new ConfigurationError(\n `Vault group \"${this.id}\" prepared ${prepared.writes.length} writes for one submission`,\n );\n }\n const transaction = await submitSdkTransaction({\n operation: prepared.delivery === \"router\" ? \"vault:routerJoin\" : \"vault:join\",\n signer,\n provider: this.sdk.provider,\n config: write.call,\n emit: (input) =>\n this.sdk.emitEvent(\n input,\n prepared.delivery === \"router\" ? this.#router() : write.leg.batcher,\n ),\n logger: this.sdk.logger,\n });\n const { joins, unconfirmed } = prepared.decodeJoins(transaction.receipt.logs);\n if (unconfirmed.length > 0) {\n throw new VaultGroupJoinUnconfirmedError(\n `Transaction ${transaction.txHash} was mined, but its receipt has no Joined event for ${prepared.account} from the batcher of vault(s) ${unconfirmed.map((id) => `\"${id}\"`).join(\", \")} in group \"${this.id}\"`,\n { txHash: transaction.txHash, receipt: transaction.receipt, joins, unconfirmed },\n );\n }\n return { ...transaction, vaultId: prepared.vaultId, joins };\n }\n}\n\n/**\n * Create a {@link VaultGroup} bound to `sdk`.\n *\n * @example\n * ```ts\n * import { createVaultGroup } from \"@zama-fhe/sdk/vaults\";\n *\n * const group = createVaultGroup(sdk, {\n * id: \"stable\",\n * cAsset: \"0xConfidentialAsset\",\n * router: \"0xRouter\",\n * vaults: [\n * { id: \"alpha\", depositBatcher: \"0xAlphaDeposit\", redeemBatcher: \"0xAlphaRedeem\" },\n * { id: \"beta\", depositBatcher: \"0xBetaDeposit\", redeemBatcher: \"0xBetaRedeem\" },\n * ],\n * });\n * const { joins } = await group.deposit(\"alpha\", 1_000_000n);\n * ```\n */\nexport function createVaultGroup(sdk: ZamaSDK, config: VaultGroupConfig): VaultGroup {\n return new VaultGroup(sdk, config);\n}\n","import { getAddress, type Address } from \"viem\";\n\n/**\n * Query keys for the vaults module.\n *\n * A `batcher(...)` key is a prefix of every `batch(...)` key for that batcher,\n * so invalidating it clears all of them at once.\n */\nexport const vaultQueryKeys = {\n currentBatchId: {\n batcher: (batcherAddress: Address) =>\n [\"zama.vault.currentBatchId\", { batcherAddress: getAddress(batcherAddress) }] as const,\n },\n batchState: {\n batcher: (batcherAddress: Address) =>\n [\"zama.vault.batchState\", { batcherAddress: getAddress(batcherAddress) }] as const,\n batch: (batcherAddress: Address, batchId: bigint | undefined) =>\n [\"zama.vault.batchState\", { batcherAddress: getAddress(batcherAddress), batchId }] as const,\n },\n timeUntilDispatchable: {\n batcher: (batcherAddress: Address) =>\n [\"zama.vault.timeUntilDispatchable\", { batcherAddress: getAddress(batcherAddress) }] as const,\n batch: (batcherAddress: Address, batchId: bigint | undefined) =>\n [\n \"zama.vault.timeUntilDispatchable\",\n { batcherAddress: getAddress(batcherAddress), batchId },\n ] as const,\n },\n timeUntilCallbackDeadline: {\n batcher: (batcherAddress: Address) =>\n [\n \"zama.vault.timeUntilCallbackDeadline\",\n { batcherAddress: getAddress(batcherAddress) },\n ] as const,\n batch: (batcherAddress: Address, batchId: bigint | undefined) =>\n [\n \"zama.vault.timeUntilCallbackDeadline\",\n { batcherAddress: getAddress(batcherAddress), batchId },\n ] as const,\n },\n};\n","import type { Address } from \"viem\";\nimport { invalidateBalanceQueries, type QueryClientLike } from \"../../query/invalidation\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Invalidates every cached batch read for a batcher. */\nexport function invalidateBatchQueries(\n queryClient: QueryClientLike,\n batcherAddress: Address,\n): void {\n void queryClient.invalidateQueries({\n queryKey: vaultQueryKeys.currentBatchId.batcher(batcherAddress),\n });\n void queryClient.invalidateQueries({\n queryKey: vaultQueryKeys.batchState.batcher(batcherAddress),\n });\n void queryClient.invalidateQueries({\n queryKey: vaultQueryKeys.timeUntilDispatchable.batcher(batcherAddress),\n });\n void queryClient.invalidateQueries({\n queryKey: vaultQueryKeys.timeUntilCallbackDeadline.batcher(batcherAddress),\n });\n}\n\n/** Invalidates the caches affected by a join: the input token's balance, and the batcher's batch reads. */\nexport function invalidateAfterJoin(\n queryClient: QueryClientLike,\n params: { batcherAddress: Address; fromToken: Address },\n): void {\n invalidateBalanceQueries(queryClient, params.fromToken);\n invalidateBatchQueries(queryClient, params.batcherAddress);\n}\n\n/**\n * Invalidates the caches affected by a group submission: each leg's token\n * balance and its batcher's batch reads. Takes a prepared submission's\n * `legs` or a result's `joins`, so a host that sends the writes itself\n * invalidates what the group hooks do.\n */\nexport function invalidateAfterGroupJoin(\n queryClient: QueryClientLike,\n legs: readonly { readonly batcher: Address; readonly token: Address }[],\n): void {\n for (const { batcher, token } of legs) {\n invalidateAfterJoin(queryClient, { batcherAddress: batcher, fromToken: token });\n }\n}\n\n/** Invalidates the caches affected by a quit or recover: the input token's balance and the batcher's batch reads. */\nexport function invalidateAfterQuit(\n queryClient: QueryClientLike,\n params: { batcherAddress: Address; fromToken: Address },\n): void {\n invalidateBalanceQueries(queryClient, params.fromToken);\n invalidateBatchQueries(queryClient, params.batcherAddress);\n}\n\n/** Invalidates the caches affected by a claim: the output token's balance. */\nexport function invalidateAfterClaim(\n queryClient: QueryClientLike,\n params: { toToken: Address },\n): void {\n invalidateBalanceQueries(queryClient, params.toToken);\n}\n\n/** Invalidates the caches affected by a dispatch: a new batch opens and the old one leaves `Pending`. */\nexport function invalidateAfterDispatchBatch(\n queryClient: QueryClientLike,\n batcherAddress: Address,\n): void {\n invalidateBatchQueries(queryClient, batcherAddress);\n}\n\n/** Invalidates the caches affected by a finalize: the batch leaves `Dispatched` and gains an exchange rate. */\nexport function invalidateAfterFinalize(\n queryClient: QueryClientLike,\n batcherAddress: Address,\n): void {\n invalidateBatchQueries(queryClient, batcherAddress);\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { JoinOptions } from \"../types\";\nimport type { VaultGroup } from \"../vault-group\";\nimport type { VaultGroupJoinResult } from \"../vault-group-types\";\n\n/** Variables for {@link groupDepositMutationOptions}. */\nexport interface GroupDepositParams extends JoinOptions {\n /** The member of the group to deposit into. */\n vaultId: string;\n /** Plaintext amount to deposit. */\n amount: bigint;\n}\n\n/** Builds mutation options for {@link VaultGroup.deposit | depositing} into a group. */\nexport function groupDepositMutationOptions(\n group: VaultGroup,\n): MutationFactoryOptions<\n readonly [\"zama.vaultGroup.deposit\", { cAsset: Address; batchers: readonly Address[] }],\n GroupDepositParams,\n VaultGroupJoinResult\n> {\n return {\n // Keyed on the batchers, not the group's id, which two groups may share.\n mutationKey: [\n \"zama.vaultGroup.deposit\",\n {\n cAsset: group.cAsset,\n batchers: group.members.map(({ vault }) => vault.depositBatcher.address),\n },\n ] as const,\n mutationFn: async ({ vaultId, amount, ...rest }) => group.deposit(vaultId, amount, rest),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { VaultGroup } from \"../vault-group\";\nimport type { VaultGroupRedeemOptions, VaultGroupJoinResult } from \"../vault-group-types\";\n\n/** Variables for {@link groupRedeemMutationOptions}. */\nexport interface GroupRedeemParams extends VaultGroupRedeemOptions {\n /** The member of the group to redeem from. */\n vaultId: string;\n /** Plaintext amount of shares to redeem. */\n amount: bigint;\n}\n\n/** Builds mutation options for {@link VaultGroup.redeem | redeeming shares} from a group. */\nexport function groupRedeemMutationOptions(\n group: VaultGroup,\n): MutationFactoryOptions<\n readonly [\"zama.vaultGroup.redeem\", { cAsset: Address; batchers: readonly Address[] }],\n GroupRedeemParams,\n VaultGroupJoinResult\n> {\n return {\n // Keyed on the batchers, not the group's id, which two groups may share.\n mutationKey: [\n \"zama.vaultGroup.redeem\",\n {\n cAsset: group.cAsset,\n batchers: group.members.map(({ vault }) => vault.redeemBatcher.address),\n },\n ] as const,\n mutationFn: async ({ vaultId, amount, ...rest }) => group.redeem(vaultId, amount, rest),\n };\n}\n","import type { QueryFactoryOptions } from \"../../query/factory-types\";\nimport { filterQueryOptions } from \"../../query/utils\";\nimport type { VaultBatcher } from \"../vault-batcher\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Configuration for {@link currentBatchIdQueryOptions}. */\nexport interface CurrentBatchIdQueryConfig {\n /** Additional TanStack Query options merged into the generated query (e.g. `staleTime`, `enabled`). */\n query?: Record<string, unknown>;\n}\n\n/** Query options for a batcher's currently open batch id. */\nexport function currentBatchIdQueryOptions(\n batcher: VaultBatcher,\n config: CurrentBatchIdQueryConfig = {},\n): QueryFactoryOptions<\n bigint,\n Error,\n bigint,\n ReturnType<typeof vaultQueryKeys.currentBatchId.batcher>\n> {\n const queryOpts = config.query ?? {};\n\n return {\n ...filterQueryOptions(queryOpts),\n queryKey: vaultQueryKeys.currentBatchId.batcher(batcher.address),\n queryFn: async () => batcher.currentBatchId(),\n enabled: queryOpts.enabled !== false,\n };\n}\n","import { assertNonNullable } from \"../../utils/assertions\";\nimport type { QueryFactoryOptions } from \"../../query/factory-types\";\nimport { filterQueryOptions } from \"../../query/utils\";\nimport type { BatchState } from \"../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Configuration for {@link batchStateQueryOptions}. */\nexport interface BatchStateQueryConfig {\n /** Batch to read the state of; the query stays disabled until provided. */\n batchId?: bigint;\n /** Additional TanStack Query options merged into the generated query (e.g. `staleTime`, `enabled`). */\n query?: Record<string, unknown>;\n}\n\n/** Query options for a batch's lifecycle state — see {@link BatchState}. */\nexport function batchStateQueryOptions(\n batcher: VaultBatcher,\n config: BatchStateQueryConfig = {},\n): QueryFactoryOptions<\n BatchState,\n Error,\n BatchState,\n ReturnType<typeof vaultQueryKeys.batchState.batch>\n> {\n const queryOpts = config.query ?? {};\n\n return {\n ...filterQueryOptions(queryOpts),\n queryKey: vaultQueryKeys.batchState.batch(batcher.address, config.batchId),\n queryFn: async (context) => {\n const [, { batchId }] = context.queryKey;\n assertNonNullable(batchId, \"batchStateQueryOptions: batchId\");\n return batcher.batchState(batchId);\n },\n enabled: config.batchId !== undefined && queryOpts.enabled !== false,\n };\n}\n","import type { QueryFactoryOptions } from \"../../query/factory-types\";\nimport { filterQueryOptions } from \"../../query/utils\";\nimport { assertNonNullable } from \"../../utils/assertions\";\nimport type { VaultBatcher } from \"../vault-batcher\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Configuration for {@link timeUntilDispatchableQueryOptions}. */\nexport interface TimeUntilDispatchableQueryConfig {\n /** Batch to check; the query stays disabled until provided. */\n batchId?: bigint;\n /** Additional TanStack Query options merged into the generated query (e.g. `staleTime`, `enabled`). */\n query?: Record<string, unknown>;\n}\n\n/**\n * Query options for the seconds remaining until a batch can be dispatched, or\n * `null` once the batch has left `Pending` and can no longer be dispatched —\n * see {@link VaultBatcher.timeUntilDispatchable}.\n */\nexport function timeUntilDispatchableQueryOptions(\n batcher: VaultBatcher,\n config: TimeUntilDispatchableQueryConfig = {},\n): QueryFactoryOptions<\n bigint | null,\n Error,\n bigint | null,\n ReturnType<typeof vaultQueryKeys.timeUntilDispatchable.batch>\n> {\n const queryOpts = config.query ?? {};\n\n return {\n ...filterQueryOptions(queryOpts),\n queryKey: vaultQueryKeys.timeUntilDispatchable.batch(batcher.address, config.batchId),\n queryFn: async (context) => {\n const [, { batchId }] = context.queryKey;\n assertNonNullable(batchId, \"timeUntilDispatchableQueryOptions: batchId\");\n return batcher.timeUntilDispatchable(batchId);\n },\n enabled: config.batchId !== undefined && queryOpts.enabled !== false,\n };\n}\n","import type { QueryFactoryOptions } from \"../../query/factory-types\";\nimport { filterQueryOptions } from \"../../query/utils\";\nimport { assertNonNullable } from \"../../utils/assertions\";\nimport type { VaultBatcher } from \"../vault-batcher\";\nimport { vaultQueryKeys } from \"./query-keys\";\n\n/** Configuration for {@link timeUntilCallbackDeadlineQueryOptions}. */\nexport interface TimeUntilCallbackDeadlineQueryConfig {\n /** Batch to check; the query stays disabled until provided. */\n batchId?: bigint;\n /** Additional TanStack Query options merged into the generated query (e.g. `staleTime`, `enabled`). */\n query?: Record<string, unknown>;\n}\n\n/**\n * Query options for the seconds remaining until a dispatched batch reaches\n * its callback deadline, or `null` outside `Dispatched` — see\n * {@link VaultBatcher.timeUntilCallbackDeadline}.\n */\nexport function timeUntilCallbackDeadlineQueryOptions(\n batcher: VaultBatcher,\n config: TimeUntilCallbackDeadlineQueryConfig = {},\n): QueryFactoryOptions<\n bigint | null,\n Error,\n bigint | null,\n ReturnType<typeof vaultQueryKeys.timeUntilCallbackDeadline.batch>\n> {\n const queryOpts = config.query ?? {};\n\n return {\n ...filterQueryOptions(queryOpts),\n queryKey: vaultQueryKeys.timeUntilCallbackDeadline.batch(batcher.address, config.batchId),\n queryFn: async (context) => {\n const [, { batchId }] = context.queryKey;\n assertNonNullable(batchId, \"timeUntilCallbackDeadlineQueryOptions: batchId\");\n return batcher.timeUntilCallbackDeadline(batchId);\n },\n enabled: config.batchId !== undefined && queryOpts.enabled !== false,\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { Vault } from \"../vault\";\nimport type { JoinResult, VaultJoinOptions } from \"../types\";\n\n/** Variables for {@link depositMutationOptions}. */\nexport interface DepositParams extends VaultJoinOptions {\n /** Plaintext amount to deposit. */\n amount: bigint;\n}\n\n/** Builds TanStack Query mutation options for {@link Vault.deposit | depositing} into a vault. */\nexport function depositMutationOptions(\n vault: Vault,\n): MutationFactoryOptions<readonly [\"zama.vault.deposit\", Address], DepositParams, JoinResult> {\n return {\n mutationKey: [\"zama.vault.deposit\", vault.depositBatcher.address] as const,\n mutationFn: async ({ amount, ...rest }) => vault.deposit(amount, rest),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { Vault } from \"../vault\";\nimport type { JoinResult, VaultJoinOptions } from \"../types\";\n\n/** Variables for {@link redeemMutationOptions}. */\nexport interface RedeemParams extends VaultJoinOptions {\n /** Plaintext amount of shares to redeem. */\n amount: bigint;\n}\n\n/** Builds TanStack Query mutation options for {@link Vault.redeem | redeeming shares}. */\nexport function redeemMutationOptions(\n vault: Vault,\n): MutationFactoryOptions<readonly [\"zama.vault.redeem\", Address], RedeemParams, JoinResult> {\n return {\n mutationKey: [\"zama.vault.redeem\", vault.redeemBatcher.address] as const,\n mutationFn: async ({ amount, ...rest }) => vault.redeem(amount, rest),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { JoinOptions, JoinResult } from \"../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link joinMutationOptions}. */\nexport interface JoinParams extends JoinOptions {\n /** Plaintext amount to contribute to the batch. */\n amount: bigint;\n /** Recipient of the batch's eventual output. Defaults to the connected wallet account. */\n beneficiary?: Address;\n}\n\n/**\n * Builds TanStack Query mutation options for {@link VaultBatcher.join | joining} a batch directly.\n * Low-level — most apps should use `depositMutationOptions` / `redeemMutationOptions` instead.\n */\nexport function joinMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<readonly [\"zama.vault.join\", Address], JoinParams, JoinResult> {\n return {\n mutationKey: [\"zama.vault.join\", batcher.address] as const,\n mutationFn: async ({ amount, beneficiary, ...options }) =>\n batcher.join(amount, beneficiary, options),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link claimMutationOptions}. */\nexport interface ClaimParams {\n /** The finalized batch to claim from. */\n batchId: bigint;\n /** The account to claim for. Defaults to the connected wallet account. */\n account?: Address;\n}\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.claim | claiming} a finalized batch. */\nexport function claimMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<readonly [\"zama.vault.claim\", Address], ClaimParams, TransactionResult> {\n return {\n mutationKey: [\"zama.vault.claim\", batcher.address] as const,\n mutationFn: async ({ batchId, account }) => batcher.claim(batchId, account),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link quitMutationOptions}. */\nexport interface QuitParams {\n /** The pending or canceled batch to withdraw the caller's own deposit from. */\n batchId: bigint;\n}\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.quit | withdrawing a deposit} from a pending or canceled batch. */\nexport function quitMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<readonly [\"zama.vault.quit\", Address], QuitParams, TransactionResult> {\n return {\n mutationKey: [\"zama.vault.quit\", batcher.address] as const,\n mutationFn: async ({ batchId }) => batcher.quit(batchId),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link recoverMutationOptions}. */\nexport interface RecoverParams {\n /** The canceled batch holding the deposit. */\n batchId: bigint;\n /** The depositor to refund. Defaults to the connected wallet account. */\n account?: Address;\n}\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.recover | refunding a deposit} in a canceled batch on the depositor's behalf. */\nexport function recoverMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<\n readonly [\"zama.vault.recover\", Address],\n RecoverParams,\n TransactionResult\n> {\n return {\n mutationKey: [\"zama.vault.recover\", batcher.address] as const,\n mutationFn: async ({ batchId, account }) => batcher.recover(batchId, account),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.dispatchBatch | dispatching} the current batch. Permissionless — takes no variables. */\nexport function dispatchBatchMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<readonly [\"zama.vault.dispatchBatch\", Address], void, TransactionResult> {\n return {\n mutationKey: [\"zama.vault.dispatchBatch\", batcher.address] as const,\n mutationFn: async () => batcher.dispatchBatch(),\n };\n}\n","import type { Address } from \"viem\";\nimport type { MutationFactoryOptions } from \"../../query/factory-types\";\nimport type { TransactionResult } from \"../../types\";\nimport type { VaultBatcher } from \"../vault-batcher\";\n\n/** Variables for {@link finalizeMutationOptions}. */\nexport interface FinalizeParams {\n /** The dispatched batch to settle. */\n batchId: bigint;\n}\n\n/** Builds TanStack Query mutation options for {@link VaultBatcher.finalize | finalizing} a dispatched batch. Permissionless. */\nexport function finalizeMutationOptions(\n batcher: VaultBatcher,\n): MutationFactoryOptions<\n readonly [\"zama.vault.finalize\", Address],\n FinalizeParams,\n TransactionResult\n> {\n return {\n mutationKey: [\"zama.vault.finalize\", batcher.address] as const,\n mutationFn: async ({ batchId }: FinalizeParams) => batcher.finalize(batchId),\n };\n}\n"],"mappings":"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"}