@unionlabs/payments 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Abi/package.json +6 -0
- package/Attestor/package.json +6 -0
- package/Constants/package.json +6 -0
- package/Domain/package.json +6 -0
- package/Error/package.json +6 -0
- package/EvmPublicClient/package.json +6 -0
- package/EvmWalletClient/package.json +6 -0
- package/Payment/package.json +6 -0
- package/PaymentError/package.json +6 -0
- package/Prover/package.json +6 -0
- package/PublicClient/package.json +6 -0
- package/README.md +1 -0
- package/Schema/package.json +6 -0
- package/Utils/package.json +6 -0
- package/WalletClient/package.json +6 -0
- package/attestation/package.json +6 -0
- package/cli/commands/balance/package.json +6 -0
- package/cli/commands/deposit/package.json +6 -0
- package/cli/commands/export-verifier/package.json +6 -0
- package/cli/commands/generate/package.json +6 -0
- package/cli/commands/history/package.json +6 -0
- package/cli/commands/prove/package.json +6 -0
- package/cli/commands/redeem/package.json +6 -0
- package/cli/commands/update-client/package.json +6 -0
- package/cli/config/package.json +6 -0
- package/cli/package.json +6 -0
- package/cli/utils/package.json +6 -0
- package/constants/ibc-core-registry/package.json +6 -0
- package/constants/services/package.json +6 -0
- package/constants/z-asset-registry/package.json +6 -0
- package/dist/cjs/Abi.js +270 -0
- package/dist/cjs/Abi.js.map +1 -0
- package/dist/cjs/Attestor.js +76 -0
- package/dist/cjs/Attestor.js.map +1 -0
- package/dist/cjs/Constants.js +8 -0
- package/dist/cjs/Constants.js.map +1 -0
- package/dist/cjs/Domain.js +24 -0
- package/dist/cjs/Domain.js.map +1 -0
- package/dist/cjs/Error.js +100 -0
- package/dist/cjs/Error.js.map +1 -0
- package/dist/cjs/EvmPublicClient.js +301 -0
- package/dist/cjs/EvmPublicClient.js.map +1 -0
- package/dist/cjs/EvmWalletClient.js +670 -0
- package/dist/cjs/EvmWalletClient.js.map +1 -0
- package/dist/cjs/Payment.js +333 -0
- package/dist/cjs/Payment.js.map +1 -0
- package/dist/cjs/PaymentError.js +32 -0
- package/dist/cjs/PaymentError.js.map +1 -0
- package/dist/cjs/Prover.js +153 -0
- package/dist/cjs/Prover.js.map +1 -0
- package/dist/cjs/PublicClient.js +39 -0
- package/dist/cjs/PublicClient.js.map +1 -0
- package/dist/cjs/Schema.js +38 -0
- package/dist/cjs/Schema.js.map +1 -0
- package/dist/cjs/Utils.js +33 -0
- package/dist/cjs/Utils.js.map +1 -0
- package/dist/cjs/WalletClient.js +39 -0
- package/dist/cjs/WalletClient.js.map +1 -0
- package/dist/cjs/attestation.js +49 -0
- package/dist/cjs/attestation.js.map +1 -0
- package/dist/cjs/cli/commands/balance.js +60 -0
- package/dist/cjs/cli/commands/balance.js.map +1 -0
- package/dist/cjs/cli/commands/deposit.js +58 -0
- package/dist/cjs/cli/commands/deposit.js.map +1 -0
- package/dist/cjs/cli/commands/export-verifier.js +27 -0
- package/dist/cjs/cli/commands/export-verifier.js.map +1 -0
- package/dist/cjs/cli/commands/generate.js +41 -0
- package/dist/cjs/cli/commands/generate.js.map +1 -0
- package/dist/cjs/cli/commands/history.js +59 -0
- package/dist/cjs/cli/commands/history.js.map +1 -0
- package/dist/cjs/cli/commands/prove.js +82 -0
- package/dist/cjs/cli/commands/prove.js.map +1 -0
- package/dist/cjs/cli/commands/redeem.js +152 -0
- package/dist/cjs/cli/commands/redeem.js.map +1 -0
- package/dist/cjs/cli/commands/update-client.js +62 -0
- package/dist/cjs/cli/commands/update-client.js.map +1 -0
- package/dist/cjs/cli/config.js +32 -0
- package/dist/cjs/cli/config.js.map +1 -0
- package/dist/cjs/cli/utils.js +108 -0
- package/dist/cjs/cli/utils.js.map +1 -0
- package/dist/cjs/cli.js +24 -0
- package/dist/cjs/cli.js.map +1 -0
- package/dist/cjs/constants/ibc-core-registry.js +30 -0
- package/dist/cjs/constants/ibc-core-registry.js.map +1 -0
- package/dist/cjs/constants/services.js +9 -0
- package/dist/cjs/constants/services.js.map +1 -0
- package/dist/cjs/constants/z-asset-registry.js +32 -0
- package/dist/cjs/constants/z-asset-registry.js.map +1 -0
- package/dist/cjs/gen/prover_pb.js +81 -0
- package/dist/cjs/gen/prover_pb.js.map +1 -0
- package/dist/cjs/index.js +32 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/internal/evm.js +191 -0
- package/dist/cjs/internal/evm.js.map +1 -0
- package/dist/cjs/internal/evmWalletClient.js +6 -0
- package/dist/cjs/internal/evmWalletClient.js.map +1 -0
- package/dist/cjs/internal/publicClient.js +49 -0
- package/dist/cjs/internal/publicClient.js.map +1 -0
- package/dist/cjs/internal/walletClient.js +43 -0
- package/dist/cjs/internal/walletClient.js.map +1 -0
- package/dist/cjs/legacy/client.js +1222 -0
- package/dist/cjs/legacy/client.js.map +1 -0
- package/dist/cjs/legacy/prover.js +112 -0
- package/dist/cjs/legacy/prover.js.map +1 -0
- package/dist/cjs/poseidon2.js +226 -0
- package/dist/cjs/poseidon2.js.map +1 -0
- package/dist/cjs/promises/Attestor.js +23 -0
- package/dist/cjs/promises/Attestor.js.map +1 -0
- package/dist/cjs/promises/EvmPublicClient.js +34 -0
- package/dist/cjs/promises/EvmPublicClient.js.map +1 -0
- package/dist/cjs/promises/EvmWalletClient.js +51 -0
- package/dist/cjs/promises/EvmWalletClient.js.map +1 -0
- package/dist/cjs/promises/Payment.js +22 -0
- package/dist/cjs/promises/Payment.js.map +1 -0
- package/dist/cjs/promises/Prover.js +26 -0
- package/dist/cjs/promises/Prover.js.map +1 -0
- package/dist/cjs/promises/PublicClient.js +53 -0
- package/dist/cjs/promises/PublicClient.js.map +1 -0
- package/dist/cjs/promises/WalletClient.js +44 -0
- package/dist/cjs/promises/WalletClient.js.map +1 -0
- package/dist/cjs/promises/index.js +22 -0
- package/dist/cjs/promises/index.js.map +1 -0
- package/dist/cjs/rpc.js +867 -0
- package/dist/cjs/rpc.js.map +1 -0
- package/dist/cjs/types.js +6 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/dts/Abi.d.ts +220 -0
- package/dist/dts/Abi.d.ts.map +1 -0
- package/dist/dts/Attestor.d.ts +42 -0
- package/dist/dts/Attestor.d.ts.map +1 -0
- package/dist/dts/Constants.d.ts +3 -0
- package/dist/dts/Constants.d.ts.map +1 -0
- package/dist/dts/Domain.d.ts +141 -0
- package/dist/dts/Domain.d.ts.map +1 -0
- package/dist/dts/Error.d.ts +102 -0
- package/dist/dts/Error.d.ts.map +1 -0
- package/dist/dts/EvmPublicClient.d.ts +61 -0
- package/dist/dts/EvmPublicClient.d.ts.map +1 -0
- package/dist/dts/EvmWalletClient.d.ts +67 -0
- package/dist/dts/EvmWalletClient.d.ts.map +1 -0
- package/dist/dts/Payment.d.ts +128 -0
- package/dist/dts/Payment.d.ts.map +1 -0
- package/dist/dts/PaymentError.d.ts +21 -0
- package/dist/dts/PaymentError.d.ts.map +1 -0
- package/dist/dts/Prover.d.ts +87 -0
- package/dist/dts/Prover.d.ts.map +1 -0
- package/dist/dts/PublicClient.d.ts +146 -0
- package/dist/dts/PublicClient.d.ts.map +1 -0
- package/dist/dts/Schema.d.ts +16 -0
- package/dist/dts/Schema.d.ts.map +1 -0
- package/dist/dts/Utils.d.ts +11 -0
- package/dist/dts/Utils.d.ts.map +1 -0
- package/dist/dts/WalletClient.d.ts +123 -0
- package/dist/dts/WalletClient.d.ts.map +1 -0
- package/dist/dts/attestation.d.ts +13 -0
- package/dist/dts/attestation.d.ts.map +1 -0
- package/dist/dts/cli/commands/balance.d.ts +3 -0
- package/dist/dts/cli/commands/balance.d.ts.map +1 -0
- package/dist/dts/cli/commands/deposit.d.ts +3 -0
- package/dist/dts/cli/commands/deposit.d.ts.map +1 -0
- package/dist/dts/cli/commands/export-verifier.d.ts +3 -0
- package/dist/dts/cli/commands/export-verifier.d.ts.map +1 -0
- package/dist/dts/cli/commands/generate.d.ts +3 -0
- package/dist/dts/cli/commands/generate.d.ts.map +1 -0
- package/dist/dts/cli/commands/history.d.ts +3 -0
- package/dist/dts/cli/commands/history.d.ts.map +1 -0
- package/dist/dts/cli/commands/prove.d.ts +3 -0
- package/dist/dts/cli/commands/prove.d.ts.map +1 -0
- package/dist/dts/cli/commands/redeem.d.ts +3 -0
- package/dist/dts/cli/commands/redeem.d.ts.map +1 -0
- package/dist/dts/cli/commands/update-client.d.ts +3 -0
- package/dist/dts/cli/commands/update-client.d.ts.map +1 -0
- package/dist/dts/cli/config.d.ts +14 -0
- package/dist/dts/cli/config.d.ts.map +1 -0
- package/dist/dts/cli/utils.d.ts +11 -0
- package/dist/dts/cli/utils.d.ts.map +1 -0
- package/dist/dts/cli.d.ts +3 -0
- package/dist/dts/cli.d.ts.map +1 -0
- package/dist/dts/constants/ibc-core-registry.d.ts +11 -0
- package/dist/dts/constants/ibc-core-registry.d.ts.map +1 -0
- package/dist/dts/constants/services.d.ts +3 -0
- package/dist/dts/constants/services.d.ts.map +1 -0
- package/dist/dts/constants/z-asset-registry.d.ts +13 -0
- package/dist/dts/constants/z-asset-registry.d.ts.map +1 -0
- package/dist/dts/gen/prover_pb.d.ts +300 -0
- package/dist/dts/gen/prover_pb.d.ts.map +1 -0
- package/dist/dts/index.d.ts +21 -0
- package/dist/dts/index.d.ts.map +1 -0
- package/dist/dts/internal/evm.d.ts +250 -0
- package/dist/dts/internal/evm.d.ts.map +1 -0
- package/dist/dts/internal/evmWalletClient.d.ts +2 -0
- package/dist/dts/internal/evmWalletClient.d.ts.map +1 -0
- package/dist/dts/internal/publicClient.d.ts +2 -0
- package/dist/dts/internal/publicClient.d.ts.map +1 -0
- package/dist/dts/internal/walletClient.d.ts +2 -0
- package/dist/dts/internal/walletClient.d.ts.map +1 -0
- package/dist/dts/legacy/client.d.ts +313 -0
- package/dist/dts/legacy/client.d.ts.map +1 -0
- package/dist/dts/legacy/prover.d.ts +30 -0
- package/dist/dts/legacy/prover.d.ts.map +1 -0
- package/dist/dts/poseidon2.d.ts +18 -0
- package/dist/dts/poseidon2.d.ts.map +1 -0
- package/dist/dts/promises/Attestor.d.ts +17 -0
- package/dist/dts/promises/Attestor.d.ts.map +1 -0
- package/dist/dts/promises/EvmPublicClient.d.ts +3709 -0
- package/dist/dts/promises/EvmPublicClient.d.ts.map +1 -0
- package/dist/dts/promises/EvmWalletClient.d.ts +4502 -0
- package/dist/dts/promises/EvmWalletClient.d.ts.map +1 -0
- package/dist/dts/promises/Payment.d.ts +33 -0
- package/dist/dts/promises/Payment.d.ts.map +1 -0
- package/dist/dts/promises/Prover.d.ts +14 -0
- package/dist/dts/promises/Prover.d.ts.map +1 -0
- package/dist/dts/promises/PublicClient.d.ts +23 -0
- package/dist/dts/promises/PublicClient.d.ts.map +1 -0
- package/dist/dts/promises/WalletClient.d.ts +57 -0
- package/dist/dts/promises/WalletClient.d.ts.map +1 -0
- package/dist/dts/promises/index.d.ts +8 -0
- package/dist/dts/promises/index.d.ts.map +1 -0
- package/dist/dts/rpc.d.ts +148 -0
- package/dist/dts/rpc.d.ts.map +1 -0
- package/dist/dts/types.d.ts +263 -0
- package/dist/dts/types.d.ts.map +1 -0
- package/dist/esm/Abi.js +264 -0
- package/dist/esm/Abi.js.map +1 -0
- package/dist/esm/Attestor.js +68 -0
- package/dist/esm/Attestor.js.map +1 -0
- package/dist/esm/Constants.js +2 -0
- package/dist/esm/Constants.js.map +1 -0
- package/dist/esm/Domain.js +17 -0
- package/dist/esm/Domain.js.map +1 -0
- package/dist/esm/Error.js +89 -0
- package/dist/esm/Error.js.map +1 -0
- package/dist/esm/EvmPublicClient.js +292 -0
- package/dist/esm/EvmPublicClient.js.map +1 -0
- package/dist/esm/EvmWalletClient.js +659 -0
- package/dist/esm/EvmWalletClient.js.map +1 -0
- package/dist/esm/Payment.js +323 -0
- package/dist/esm/Payment.js.map +1 -0
- package/dist/esm/PaymentError.js +24 -0
- package/dist/esm/PaymentError.js.map +1 -0
- package/dist/esm/Prover.js +142 -0
- package/dist/esm/Prover.js.map +1 -0
- package/dist/esm/PublicClient.js +30 -0
- package/dist/esm/PublicClient.js.map +1 -0
- package/dist/esm/Schema.js +31 -0
- package/dist/esm/Schema.js.map +1 -0
- package/dist/esm/Utils.js +27 -0
- package/dist/esm/Utils.js.map +1 -0
- package/dist/esm/WalletClient.js +30 -0
- package/dist/esm/WalletClient.js.map +1 -0
- package/dist/esm/attestation.js +42 -0
- package/dist/esm/attestation.js.map +1 -0
- package/dist/esm/cli/commands/balance.js +54 -0
- package/dist/esm/cli/commands/balance.js.map +1 -0
- package/dist/esm/cli/commands/deposit.js +52 -0
- package/dist/esm/cli/commands/deposit.js.map +1 -0
- package/dist/esm/cli/commands/export-verifier.js +21 -0
- package/dist/esm/cli/commands/export-verifier.js.map +1 -0
- package/dist/esm/cli/commands/generate.js +35 -0
- package/dist/esm/cli/commands/generate.js.map +1 -0
- package/dist/esm/cli/commands/history.js +53 -0
- package/dist/esm/cli/commands/history.js.map +1 -0
- package/dist/esm/cli/commands/prove.js +76 -0
- package/dist/esm/cli/commands/prove.js.map +1 -0
- package/dist/esm/cli/commands/redeem.js +146 -0
- package/dist/esm/cli/commands/redeem.js.map +1 -0
- package/dist/esm/cli/commands/update-client.js +56 -0
- package/dist/esm/cli/commands/update-client.js.map +1 -0
- package/dist/esm/cli/config.js +26 -0
- package/dist/esm/cli/config.js.map +1 -0
- package/dist/esm/cli/utils.js +94 -0
- package/dist/esm/cli/utils.js.map +1 -0
- package/dist/esm/cli.js +22 -0
- package/dist/esm/cli.js.map +1 -0
- package/dist/esm/constants/ibc-core-registry.js +21 -0
- package/dist/esm/constants/ibc-core-registry.js.map +1 -0
- package/dist/esm/constants/services.js +3 -0
- package/dist/esm/constants/services.js.map +1 -0
- package/dist/esm/constants/z-asset-registry.js +23 -0
- package/dist/esm/constants/z-asset-registry.js.map +1 -0
- package/dist/esm/gen/prover_pb.js +74 -0
- package/dist/esm/gen/prover_pb.js.map +1 -0
- package/dist/esm/index.js +22 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/internal/evm.js +169 -0
- package/dist/esm/internal/evm.js.map +1 -0
- package/dist/esm/internal/evmWalletClient.js +2 -0
- package/dist/esm/internal/evmWalletClient.js.map +1 -0
- package/dist/esm/internal/publicClient.js +41 -0
- package/dist/esm/internal/publicClient.js.map +1 -0
- package/dist/esm/internal/walletClient.js +35 -0
- package/dist/esm/internal/walletClient.js.map +1 -0
- package/dist/esm/legacy/client.js +1212 -0
- package/dist/esm/legacy/client.js.map +1 -0
- package/dist/esm/legacy/prover.js +105 -0
- package/dist/esm/legacy/prover.js.map +1 -0
- package/dist/esm/package.json +4 -0
- package/dist/esm/poseidon2.js +218 -0
- package/dist/esm/poseidon2.js.map +1 -0
- package/dist/esm/promises/Attestor.js +14 -0
- package/dist/esm/promises/Attestor.js.map +1 -0
- package/dist/esm/promises/EvmPublicClient.js +26 -0
- package/dist/esm/promises/EvmPublicClient.js.map +1 -0
- package/dist/esm/promises/EvmWalletClient.js +43 -0
- package/dist/esm/promises/EvmWalletClient.js.map +1 -0
- package/dist/esm/promises/Payment.js +13 -0
- package/dist/esm/promises/Payment.js.map +1 -0
- package/dist/esm/promises/Prover.js +17 -0
- package/dist/esm/promises/Prover.js.map +1 -0
- package/dist/esm/promises/PublicClient.js +45 -0
- package/dist/esm/promises/PublicClient.js.map +1 -0
- package/dist/esm/promises/WalletClient.js +36 -0
- package/dist/esm/promises/WalletClient.js.map +1 -0
- package/dist/esm/promises/index.js +8 -0
- package/dist/esm/promises/index.js.map +1 -0
- package/dist/esm/rpc.js +850 -0
- package/dist/esm/rpc.js.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/gen/prover_pb/package.json +6 -0
- package/index/package.json +6 -0
- package/legacy/client/package.json +6 -0
- package/legacy/prover/package.json +6 -0
- package/package.json +397 -44
- package/poseidon2/package.json +6 -0
- package/promises/Attestor/package.json +6 -0
- package/promises/EvmPublicClient/package.json +6 -0
- package/promises/EvmWalletClient/package.json +6 -0
- package/promises/Payment/package.json +6 -0
- package/promises/Prover/package.json +6 -0
- package/promises/PublicClient/package.json +6 -0
- package/promises/WalletClient/package.json +6 -0
- package/promises/index/package.json +6 -0
- package/promises/package.json +6 -0
- package/rpc/package.json +6 -0
- package/src/Abi.ts +195 -0
- package/src/Attestor.ts +113 -0
- package/src/Constants.ts +4 -0
- package/src/Domain.ts +52 -0
- package/src/Error.ts +163 -0
- package/src/EvmPublicClient.ts +549 -0
- package/src/EvmWalletClient.ts +1034 -0
- package/src/Payment.ts +523 -0
- package/src/PaymentError.ts +39 -0
- package/src/Prover.ts +240 -0
- package/src/PublicClient.ts +196 -0
- package/src/Schema.ts +36 -0
- package/src/Utils.ts +43 -0
- package/src/WalletClient.ts +172 -0
- package/src/attestation.ts +69 -0
- package/src/cli/commands/balance.ts +88 -0
- package/src/cli/commands/deposit.ts +104 -0
- package/src/cli/commands/export-verifier.ts +28 -0
- package/src/cli/commands/generate.ts +86 -0
- package/src/cli/commands/history.ts +91 -0
- package/src/cli/commands/prove.ts +133 -0
- package/src/cli/commands/redeem.ts +277 -0
- package/src/cli/commands/update-client.ts +96 -0
- package/src/cli/config.ts +55 -0
- package/src/cli/utils.ts +136 -0
- package/src/cli.ts +31 -0
- package/src/constants/ibc-core-registry.ts +44 -0
- package/src/constants/services.ts +4 -0
- package/src/constants/z-asset-registry.ts +47 -0
- package/src/gen/prover_pb.ts +375 -0
- package/src/index.ts +23 -0
- package/src/internal/evm.ts +361 -0
- package/src/internal/evmWalletClient.ts +0 -0
- package/src/internal/publicClient.ts +57 -0
- package/src/internal/walletClient.ts +50 -0
- package/src/legacy/client.ts +1652 -0
- package/src/legacy/prover.ts +135 -0
- package/src/poseidon2.ts +246 -0
- package/src/promises/Attestor.ts +25 -0
- package/src/promises/EvmPublicClient.ts +39 -0
- package/src/promises/EvmWalletClient.ts +63 -0
- package/src/promises/Payment.ts +86 -0
- package/src/promises/Prover.ts +26 -0
- package/src/promises/PublicClient.ts +47 -0
- package/src/promises/WalletClient.ts +38 -0
- package/src/promises/index.ts +7 -0
- package/src/rpc.ts +994 -0
- package/src/types.ts +281 -0
- package/types/package.json +6 -0
- package/dist/LICENSE +0 -1
- package/dist/chunk-37PNLRA6.js +0 -2418
- package/dist/cli.cjs +0 -3031
- package/dist/cli.js +0 -675
- package/dist/index.cjs +0 -2451
- package/dist/index.js +0 -1
- package/dist/package.json +0 -18
- package/dist/payments.d.ts +0 -835
- /package/{dist → src}/tsdoc-metadata.json +0 -0
package/src/rpc.ts
ADDED
|
@@ -0,0 +1,994 @@
|
|
|
1
|
+
import {
|
|
2
|
+
type Address,
|
|
3
|
+
type Block,
|
|
4
|
+
bytesToHex,
|
|
5
|
+
createPublicClient,
|
|
6
|
+
encodeAbiParameters,
|
|
7
|
+
encodePacked,
|
|
8
|
+
type GetProofReturnType,
|
|
9
|
+
type Hash,
|
|
10
|
+
type Hex,
|
|
11
|
+
hexToBigInt,
|
|
12
|
+
hexToBytes,
|
|
13
|
+
http,
|
|
14
|
+
keccak256,
|
|
15
|
+
type PublicClient,
|
|
16
|
+
padHex,
|
|
17
|
+
sha256,
|
|
18
|
+
toHex,
|
|
19
|
+
toRlp,
|
|
20
|
+
type WalletClient,
|
|
21
|
+
} from "viem";
|
|
22
|
+
import { sign } from "viem/accounts";
|
|
23
|
+
import type {
|
|
24
|
+
ConsensusState,
|
|
25
|
+
CounterpartyInfo,
|
|
26
|
+
DepositToZAssetResult,
|
|
27
|
+
LightClientData,
|
|
28
|
+
MptProofData,
|
|
29
|
+
ProofJSON,
|
|
30
|
+
RedeemParams,
|
|
31
|
+
RedemptionHistoryEntry,
|
|
32
|
+
UpdateLightClientResult,
|
|
33
|
+
} from "./types.js";
|
|
34
|
+
|
|
35
|
+
const ERC20_ABI = [
|
|
36
|
+
{
|
|
37
|
+
inputs: [{ name: "account", type: "address" }],
|
|
38
|
+
name: "balanceOf",
|
|
39
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
40
|
+
stateMutability: "view",
|
|
41
|
+
type: "function",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
inputs: [],
|
|
45
|
+
name: "decimals",
|
|
46
|
+
outputs: [{ name: "", type: "uint8" }],
|
|
47
|
+
stateMutability: "view",
|
|
48
|
+
type: "function",
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
inputs: [],
|
|
52
|
+
name: "symbol",
|
|
53
|
+
outputs: [{ name: "", type: "string" }],
|
|
54
|
+
stateMutability: "view",
|
|
55
|
+
type: "function",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
inputs: [
|
|
59
|
+
{ name: "spender", type: "address" },
|
|
60
|
+
{ name: "amount", type: "uint256" },
|
|
61
|
+
],
|
|
62
|
+
name: "approve",
|
|
63
|
+
outputs: [{ name: "", type: "bool" }],
|
|
64
|
+
stateMutability: "nonpayable",
|
|
65
|
+
type: "function",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
inputs: [
|
|
69
|
+
{ name: "to", type: "address" },
|
|
70
|
+
{ name: "amount", type: "uint256" },
|
|
71
|
+
],
|
|
72
|
+
name: "transfer",
|
|
73
|
+
outputs: [{ name: "", type: "bool" }],
|
|
74
|
+
stateMutability: "nonpayable",
|
|
75
|
+
type: "function",
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
inputs: [
|
|
79
|
+
{ name: "from", type: "address" },
|
|
80
|
+
{ name: "to", type: "address" },
|
|
81
|
+
{ name: "amount", type: "uint256" },
|
|
82
|
+
],
|
|
83
|
+
name: "transferFrom",
|
|
84
|
+
outputs: [{ name: "", type: "bool" }],
|
|
85
|
+
stateMutability: "nonpayable",
|
|
86
|
+
type: "function",
|
|
87
|
+
},
|
|
88
|
+
] as const;
|
|
89
|
+
|
|
90
|
+
export const IBC_STORE_ABI = [
|
|
91
|
+
{
|
|
92
|
+
inputs: [{ name: "clientId", type: "uint32" }],
|
|
93
|
+
name: "getClient",
|
|
94
|
+
outputs: [{ name: "", type: "address" }],
|
|
95
|
+
stateMutability: "view",
|
|
96
|
+
type: "function",
|
|
97
|
+
},
|
|
98
|
+
] as const;
|
|
99
|
+
|
|
100
|
+
const LIGHT_CLIENT_ABI = [
|
|
101
|
+
{
|
|
102
|
+
inputs: [{ name: "clientId", type: "uint32" }],
|
|
103
|
+
name: "getLatestHeight",
|
|
104
|
+
outputs: [{ name: "", type: "uint64" }],
|
|
105
|
+
stateMutability: "view",
|
|
106
|
+
type: "function",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
inputs: [
|
|
110
|
+
{ name: "clientId", type: "uint32" },
|
|
111
|
+
{ name: "height", type: "uint64" },
|
|
112
|
+
],
|
|
113
|
+
name: "getConsensusState",
|
|
114
|
+
outputs: [{ name: "", type: "bytes" }],
|
|
115
|
+
stateMutability: "view",
|
|
116
|
+
type: "function",
|
|
117
|
+
},
|
|
118
|
+
] as const;
|
|
119
|
+
|
|
120
|
+
const ZASSET_ABI = [
|
|
121
|
+
{
|
|
122
|
+
inputs: [{ name: "nullifier", type: "uint256" }],
|
|
123
|
+
name: "nullifierBalance",
|
|
124
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
125
|
+
stateMutability: "view",
|
|
126
|
+
type: "function",
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
inputs: [{ name: "clientId", type: "uint32" }],
|
|
130
|
+
name: "counterparty",
|
|
131
|
+
outputs: [
|
|
132
|
+
{
|
|
133
|
+
components: [
|
|
134
|
+
{ name: "tokenAddressKey", type: "bytes32" },
|
|
135
|
+
{ name: "balanceSlot", type: "bytes32" },
|
|
136
|
+
],
|
|
137
|
+
type: "tuple",
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
stateMutability: "view",
|
|
141
|
+
type: "function",
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
inputs: [],
|
|
145
|
+
name: "ibcHandler",
|
|
146
|
+
outputs: [{ name: "", type: "address" }],
|
|
147
|
+
stateMutability: "view",
|
|
148
|
+
type: "function",
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
inputs: [{ name: "clientId", type: "uint32" }],
|
|
152
|
+
name: "stateRootIndex",
|
|
153
|
+
outputs: [{ name: "", type: "uint256" }],
|
|
154
|
+
stateMutability: "view",
|
|
155
|
+
type: "function",
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
inputs: [],
|
|
159
|
+
name: "underlying",
|
|
160
|
+
outputs: [{ name: "", type: "address" }],
|
|
161
|
+
stateMutability: "view",
|
|
162
|
+
type: "function",
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
inputs: [{ name: "amount", type: "uint256" }],
|
|
166
|
+
name: "deposit",
|
|
167
|
+
outputs: [],
|
|
168
|
+
stateMutability: "nonpayable",
|
|
169
|
+
type: "function",
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
inputs: [
|
|
173
|
+
{ name: "to", type: "address" },
|
|
174
|
+
{ name: "amount", type: "uint256" },
|
|
175
|
+
],
|
|
176
|
+
name: "transfer",
|
|
177
|
+
outputs: [{ name: "", type: "bool" }],
|
|
178
|
+
stateMutability: "nonpayable",
|
|
179
|
+
type: "function",
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
inputs: [
|
|
183
|
+
{ name: "proof", type: "uint256[8]" },
|
|
184
|
+
{ name: "commitments", type: "uint256[2]" },
|
|
185
|
+
{ name: "commitmentPok", type: "uint256[2]" },
|
|
186
|
+
{
|
|
187
|
+
name: "lightClients",
|
|
188
|
+
type: "tuple[]",
|
|
189
|
+
components: [
|
|
190
|
+
{ name: "clientId", type: "uint32" },
|
|
191
|
+
{ name: "height", type: "uint64" },
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
{ name: "nullifier", type: "uint256" },
|
|
195
|
+
{ name: "value", type: "uint256" },
|
|
196
|
+
{ name: "beneficiary", type: "address" },
|
|
197
|
+
{ name: "attestedMessage", type: "bytes32" },
|
|
198
|
+
{ name: "signature", type: "bytes" },
|
|
199
|
+
],
|
|
200
|
+
name: "redeem",
|
|
201
|
+
outputs: [],
|
|
202
|
+
stateMutability: "nonpayable",
|
|
203
|
+
type: "function",
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
anonymous: false,
|
|
207
|
+
inputs: [
|
|
208
|
+
{ indexed: true, name: "from", type: "address" },
|
|
209
|
+
{ indexed: true, name: "to", type: "address" },
|
|
210
|
+
{ indexed: false, name: "value", type: "uint256" },
|
|
211
|
+
],
|
|
212
|
+
name: "Transfer",
|
|
213
|
+
type: "event",
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
anonymous: false,
|
|
217
|
+
inputs: [
|
|
218
|
+
{ indexed: true, name: "nullifier", type: "uint256" },
|
|
219
|
+
{ indexed: true, name: "redeemAmount", type: "uint256" },
|
|
220
|
+
{ indexed: true, name: "beneficiary", type: "address" },
|
|
221
|
+
],
|
|
222
|
+
name: "Redeemed",
|
|
223
|
+
type: "event",
|
|
224
|
+
},
|
|
225
|
+
] as const;
|
|
226
|
+
|
|
227
|
+
const IBC_HANDLER_ABI = [
|
|
228
|
+
{
|
|
229
|
+
inputs: [
|
|
230
|
+
{
|
|
231
|
+
components: [
|
|
232
|
+
{ name: "clientId", type: "uint32" },
|
|
233
|
+
{ name: "clientMessage", type: "bytes" },
|
|
234
|
+
{ name: "relayer", type: "address" },
|
|
235
|
+
],
|
|
236
|
+
name: "msg_",
|
|
237
|
+
type: "tuple",
|
|
238
|
+
},
|
|
239
|
+
],
|
|
240
|
+
name: "updateClient",
|
|
241
|
+
outputs: [],
|
|
242
|
+
stateMutability: "nonpayable",
|
|
243
|
+
type: "function",
|
|
244
|
+
},
|
|
245
|
+
] as const;
|
|
246
|
+
|
|
247
|
+
// @ts-expect-error
|
|
248
|
+
const MULTICALL3_ADDRESS =
|
|
249
|
+
"0xcA11bde05977b3631167028862bE2a173976CA11" as Address;
|
|
250
|
+
|
|
251
|
+
// @ts-expect-error
|
|
252
|
+
const MULTICALL3_ABI = [
|
|
253
|
+
{
|
|
254
|
+
inputs: [
|
|
255
|
+
{
|
|
256
|
+
name: "calls",
|
|
257
|
+
type: "tuple[]",
|
|
258
|
+
components: [
|
|
259
|
+
{ name: "target", type: "address" },
|
|
260
|
+
{ name: "allowFailure", type: "bool" },
|
|
261
|
+
{ name: "callData", type: "bytes" },
|
|
262
|
+
],
|
|
263
|
+
},
|
|
264
|
+
],
|
|
265
|
+
name: "aggregate3",
|
|
266
|
+
outputs: [
|
|
267
|
+
{
|
|
268
|
+
name: "returnData",
|
|
269
|
+
type: "tuple[]",
|
|
270
|
+
components: [
|
|
271
|
+
{ name: "success", type: "bool" },
|
|
272
|
+
{ name: "returnData", type: "bytes" },
|
|
273
|
+
],
|
|
274
|
+
},
|
|
275
|
+
],
|
|
276
|
+
stateMutability: "payable",
|
|
277
|
+
type: "function",
|
|
278
|
+
},
|
|
279
|
+
] as const;
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* @public
|
|
283
|
+
*/
|
|
284
|
+
export class RpcClient {
|
|
285
|
+
private client: PublicClient;
|
|
286
|
+
|
|
287
|
+
constructor(rpcUrl: string) {
|
|
288
|
+
this.client = createPublicClient({
|
|
289
|
+
transport: http(rpcUrl),
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
getClient(): PublicClient {
|
|
294
|
+
return this.client;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
async getChainId(): Promise<bigint> {
|
|
298
|
+
return BigInt(await this.client.getChainId());
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
async getLatestBlockNumber(): Promise<bigint> {
|
|
302
|
+
return this.client.getBlockNumber();
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async getBalance(
|
|
306
|
+
tokenAddress: Address,
|
|
307
|
+
accountAddress: Address,
|
|
308
|
+
blockNumber?: bigint,
|
|
309
|
+
): Promise<bigint> {
|
|
310
|
+
return this.client.readContract({
|
|
311
|
+
address: tokenAddress,
|
|
312
|
+
abi: ERC20_ABI,
|
|
313
|
+
functionName: "balanceOf",
|
|
314
|
+
args: [accountAddress],
|
|
315
|
+
blockNumber,
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
async getDecimals(tokenAddress: Address): Promise<number> {
|
|
320
|
+
return this.client.readContract({
|
|
321
|
+
address: tokenAddress,
|
|
322
|
+
abi: ERC20_ABI,
|
|
323
|
+
functionName: "decimals",
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
async getSymbol(tokenAddress: Address): Promise<string> {
|
|
328
|
+
return this.client.readContract({
|
|
329
|
+
address: tokenAddress,
|
|
330
|
+
abi: ERC20_ABI,
|
|
331
|
+
functionName: "symbol",
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
async getLightClientAddress(
|
|
336
|
+
ibcStoreAddress: Address,
|
|
337
|
+
clientId: number,
|
|
338
|
+
): Promise<Address> {
|
|
339
|
+
return this.client.readContract({
|
|
340
|
+
address: ibcStoreAddress,
|
|
341
|
+
abi: IBC_STORE_ABI,
|
|
342
|
+
functionName: "getClient",
|
|
343
|
+
args: [clientId],
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
async getLatestHeight(
|
|
348
|
+
lightClientAddress: Address,
|
|
349
|
+
clientId: number,
|
|
350
|
+
): Promise<bigint> {
|
|
351
|
+
return this.client.readContract({
|
|
352
|
+
address: lightClientAddress,
|
|
353
|
+
abi: LIGHT_CLIENT_ABI,
|
|
354
|
+
functionName: "getLatestHeight",
|
|
355
|
+
args: [clientId],
|
|
356
|
+
});
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Get consensus state, extracting the state root at the given byte index
|
|
361
|
+
*/
|
|
362
|
+
async getConsensusState(
|
|
363
|
+
lightClientAddress: Address,
|
|
364
|
+
clientId: number,
|
|
365
|
+
height: bigint,
|
|
366
|
+
stateRootIndex: bigint,
|
|
367
|
+
): Promise<ConsensusState> {
|
|
368
|
+
const consensusBytes = await this.client.readContract({
|
|
369
|
+
address: lightClientAddress,
|
|
370
|
+
abi: LIGHT_CLIENT_ABI,
|
|
371
|
+
functionName: "getConsensusState",
|
|
372
|
+
args: [clientId, height],
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
const bytes: Uint8Array = hexToBytes(consensusBytes);
|
|
376
|
+
const idx = Number(stateRootIndex);
|
|
377
|
+
const stateRoot = bytesToHex(bytes.slice(idx, idx + 32)) as Hash;
|
|
378
|
+
|
|
379
|
+
return { stateRoot };
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
async getNullifierBalance(
|
|
383
|
+
zassetAddress: Address,
|
|
384
|
+
nullifier: bigint,
|
|
385
|
+
): Promise<bigint> {
|
|
386
|
+
return this.client.readContract({
|
|
387
|
+
address: zassetAddress,
|
|
388
|
+
abi: ZASSET_ABI,
|
|
389
|
+
functionName: "nullifierBalance",
|
|
390
|
+
args: [nullifier],
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async getCounterparty(
|
|
395
|
+
zassetAddress: Address,
|
|
396
|
+
clientId: number,
|
|
397
|
+
): Promise<CounterpartyInfo> {
|
|
398
|
+
const result = await this.client.readContract({
|
|
399
|
+
address: zassetAddress,
|
|
400
|
+
abi: ZASSET_ABI,
|
|
401
|
+
functionName: "counterparty",
|
|
402
|
+
args: [clientId],
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
return {
|
|
406
|
+
tokenAddressKey: result.tokenAddressKey as Hash,
|
|
407
|
+
balanceSlot: result.balanceSlot as Hash,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
async getIbcHandlerAddress(zassetAddress: Address): Promise<Address> {
|
|
412
|
+
return this.client.readContract({
|
|
413
|
+
address: zassetAddress,
|
|
414
|
+
abi: ZASSET_ABI,
|
|
415
|
+
functionName: "ibcHandler",
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
async getStateRootIndex(
|
|
420
|
+
zassetAddress: Address,
|
|
421
|
+
clientId: number,
|
|
422
|
+
): Promise<bigint> {
|
|
423
|
+
return this.client.readContract({
|
|
424
|
+
address: zassetAddress,
|
|
425
|
+
abi: ZASSET_ABI,
|
|
426
|
+
functionName: "stateRootIndex",
|
|
427
|
+
args: [clientId],
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
async getProof(
|
|
432
|
+
address: Address,
|
|
433
|
+
storageKeys: Hex[],
|
|
434
|
+
blockNumber: bigint,
|
|
435
|
+
): Promise<GetProofReturnType> {
|
|
436
|
+
return this.client.getProof({
|
|
437
|
+
address,
|
|
438
|
+
storageKeys,
|
|
439
|
+
blockNumber,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
async getBlock(blockNumber: bigint) {
|
|
444
|
+
return this.client.getBlock({ blockNumber });
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
/**
|
|
448
|
+
* Get redemption history for a nullifier by querying Redeemed events
|
|
449
|
+
*/
|
|
450
|
+
async getRedemptionHistory(
|
|
451
|
+
zassetAddress: Address,
|
|
452
|
+
nullifier: bigint,
|
|
453
|
+
fromBlock?: bigint,
|
|
454
|
+
toBlock?: bigint,
|
|
455
|
+
): Promise<RedemptionHistoryEntry[]> {
|
|
456
|
+
const logs = await this.client.getLogs({
|
|
457
|
+
address: zassetAddress,
|
|
458
|
+
event: {
|
|
459
|
+
type: "event",
|
|
460
|
+
name: "Redeemed",
|
|
461
|
+
inputs: [
|
|
462
|
+
{ indexed: true, name: "nullifier", type: "uint256" },
|
|
463
|
+
{ indexed: true, name: "redeemAmount", type: "uint256" },
|
|
464
|
+
{ indexed: true, name: "beneficiary", type: "address" },
|
|
465
|
+
],
|
|
466
|
+
},
|
|
467
|
+
args: {
|
|
468
|
+
nullifier,
|
|
469
|
+
},
|
|
470
|
+
fromBlock: fromBlock ?? "earliest",
|
|
471
|
+
toBlock: toBlock ?? "latest",
|
|
472
|
+
});
|
|
473
|
+
|
|
474
|
+
return logs.map((log) => ({
|
|
475
|
+
txHash: log.transactionHash as Hash,
|
|
476
|
+
blockNumber: log.blockNumber,
|
|
477
|
+
redeemAmount: log.args.redeemAmount as bigint,
|
|
478
|
+
beneficiary: log.args.beneficiary as Address,
|
|
479
|
+
}));
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
/**
|
|
484
|
+
* Compute the storage slot for an ERC20 balance mapping: keccak256(abi.encode(address, slot))
|
|
485
|
+
* @public
|
|
486
|
+
*/
|
|
487
|
+
export function computeStorageSlot(address: Address, mappingSlot: bigint): Hex {
|
|
488
|
+
const paddedAddress = padHex(address, { size: 32 });
|
|
489
|
+
const paddedSlot = padHex(toHex(mappingSlot), { size: 32 });
|
|
490
|
+
return keccak256(
|
|
491
|
+
encodePacked(["bytes32", "bytes32"], [paddedAddress, paddedSlot]),
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
/**
|
|
496
|
+
* @public
|
|
497
|
+
*/
|
|
498
|
+
export async function fetchLightClients(
|
|
499
|
+
dstClient: RpcClient,
|
|
500
|
+
zassetAddress: Address,
|
|
501
|
+
clientIds: number[],
|
|
502
|
+
): Promise<LightClientData[]> {
|
|
503
|
+
const ibcHandlerAddress = await dstClient.getIbcHandlerAddress(zassetAddress);
|
|
504
|
+
const results: LightClientData[] = [];
|
|
505
|
+
|
|
506
|
+
for (const clientId of clientIds) {
|
|
507
|
+
try {
|
|
508
|
+
const lightClientAddress = await dstClient.getLightClientAddress(
|
|
509
|
+
ibcHandlerAddress,
|
|
510
|
+
clientId,
|
|
511
|
+
);
|
|
512
|
+
const height = await dstClient.getLatestHeight(
|
|
513
|
+
lightClientAddress,
|
|
514
|
+
clientId,
|
|
515
|
+
);
|
|
516
|
+
const stateRootIndex = await dstClient.getStateRootIndex(
|
|
517
|
+
zassetAddress,
|
|
518
|
+
clientId,
|
|
519
|
+
);
|
|
520
|
+
const { stateRoot } = await dstClient.getConsensusState(
|
|
521
|
+
lightClientAddress,
|
|
522
|
+
clientId,
|
|
523
|
+
height,
|
|
524
|
+
stateRootIndex,
|
|
525
|
+
);
|
|
526
|
+
|
|
527
|
+
results.push({ clientId, height, stateRoot });
|
|
528
|
+
} catch {}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
return results;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
/**
|
|
535
|
+
* @public
|
|
536
|
+
*/
|
|
537
|
+
export async function fetchMptProof(
|
|
538
|
+
srcClient: RpcClient,
|
|
539
|
+
tokenAddress: Address,
|
|
540
|
+
storageSlot: Hex,
|
|
541
|
+
blockNumber: bigint,
|
|
542
|
+
): Promise<MptProofData> {
|
|
543
|
+
const proof = await srcClient.getProof(
|
|
544
|
+
tokenAddress,
|
|
545
|
+
[storageSlot],
|
|
546
|
+
blockNumber,
|
|
547
|
+
);
|
|
548
|
+
|
|
549
|
+
let storageProof: Hex[] = [];
|
|
550
|
+
let storageValue: Hex = "0x0";
|
|
551
|
+
|
|
552
|
+
if (proof.storageProof.length > 0 && proof.storageProof[0]) {
|
|
553
|
+
storageProof = proof.storageProof[0].proof as Hex[];
|
|
554
|
+
storageValue = toHex(proof.storageProof[0].value);
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
return {
|
|
558
|
+
accountProof: proof.accountProof as Hex[],
|
|
559
|
+
storageProof,
|
|
560
|
+
storageValue,
|
|
561
|
+
storageRoot: proof.storageHash,
|
|
562
|
+
};
|
|
563
|
+
}
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Deterministically shuffle light clients using the secret as seed.
|
|
567
|
+
* Same secret always produces the same ordering for privacy.
|
|
568
|
+
* @public
|
|
569
|
+
*/
|
|
570
|
+
export function deterministicShuffleClients(
|
|
571
|
+
clients: LightClientData[],
|
|
572
|
+
secret: Hex,
|
|
573
|
+
): LightClientData[] {
|
|
574
|
+
if (clients.length <= 1) {
|
|
575
|
+
return [...clients];
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// Seed = SHA256(secret || clientHeights as big-endian uint64s)
|
|
579
|
+
const secretBytes = hexToBytes(secret);
|
|
580
|
+
const heightsBytes = new Uint8Array(clients.length * 8);
|
|
581
|
+
for (let i = 0; i < clients.length; i++) {
|
|
582
|
+
const view = new DataView(heightsBytes.buffer, i * 8, 8);
|
|
583
|
+
view.setBigUint64(0, clients[i]!.height, false);
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
const combined = new Uint8Array(secretBytes.length + heightsBytes.length);
|
|
587
|
+
combined.set(secretBytes, 0);
|
|
588
|
+
combined.set(heightsBytes, secretBytes.length);
|
|
589
|
+
const seedHex = sha256(combined);
|
|
590
|
+
const seed = hexToBytes(seedHex);
|
|
591
|
+
|
|
592
|
+
// Fisher-Yates shuffle with deterministic PRNG
|
|
593
|
+
const shuffled = [...clients];
|
|
594
|
+
let seedIndex = 0;
|
|
595
|
+
for (let i = shuffled.length - 1; i > 0; i--) {
|
|
596
|
+
const randomByte = seed[seedIndex % seed.length]!;
|
|
597
|
+
seedIndex++;
|
|
598
|
+
const j = randomByte % (i + 1);
|
|
599
|
+
[shuffled[i], shuffled[j]] = [shuffled[j]!, shuffled[i]!];
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
return shuffled;
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Sign an attested message with raw ECDSA (no EIP-191 prefix).
|
|
607
|
+
* Matches Go CLI's crypto.Sign behavior for SignatureCheckerLib verification.
|
|
608
|
+
* @public
|
|
609
|
+
*/
|
|
610
|
+
export async function signAttestedMessage(
|
|
611
|
+
message: Hex,
|
|
612
|
+
privateKey: Hex,
|
|
613
|
+
): Promise<Hex> {
|
|
614
|
+
const messageBytes = hexToBytes(message);
|
|
615
|
+
if (messageBytes.length !== 32) {
|
|
616
|
+
throw new Error(
|
|
617
|
+
`Invalid message length: expected 32 bytes, got ${messageBytes.length}`,
|
|
618
|
+
);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
const signature = await sign({
|
|
622
|
+
hash: message,
|
|
623
|
+
privateKey,
|
|
624
|
+
to: "hex",
|
|
625
|
+
});
|
|
626
|
+
|
|
627
|
+
return signature;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* @public
|
|
632
|
+
*/
|
|
633
|
+
export function parseProofJson(proofJsonBytes: Uint8Array): ProofJSON {
|
|
634
|
+
const jsonStr = new TextDecoder().decode(proofJsonBytes);
|
|
635
|
+
const raw = JSON.parse(jsonStr);
|
|
636
|
+
const commitments = raw.commitments ?? ["0x0", "0x0"];
|
|
637
|
+
|
|
638
|
+
return {
|
|
639
|
+
proof: raw.proof as ProofJSON["proof"],
|
|
640
|
+
commitments: commitments as ProofJSON["commitments"],
|
|
641
|
+
commitmentPok: raw.commitmentPok as ProofJSON["commitmentPok"],
|
|
642
|
+
publicInputs: raw.publicInputs ?? [],
|
|
643
|
+
};
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
/**
|
|
647
|
+
* Client-side metadata for redeem (NOT from prover)
|
|
648
|
+
* @public
|
|
649
|
+
*/
|
|
650
|
+
export interface RedeemMetadata {
|
|
651
|
+
lightClients: LightClientData[];
|
|
652
|
+
nullifier: bigint;
|
|
653
|
+
value: bigint;
|
|
654
|
+
beneficiary: Address;
|
|
655
|
+
attestedMessage: Hex;
|
|
656
|
+
signature: Hex;
|
|
657
|
+
}
|
|
658
|
+
|
|
659
|
+
/**
|
|
660
|
+
* @public
|
|
661
|
+
*/
|
|
662
|
+
export function proofJsonToRedeemParams(
|
|
663
|
+
proofJson: ProofJSON,
|
|
664
|
+
metadata: RedeemMetadata,
|
|
665
|
+
): RedeemParams {
|
|
666
|
+
const parseBigInt = (s: string): bigint => {
|
|
667
|
+
if (s.startsWith("0x")) {
|
|
668
|
+
return hexToBigInt(s as Hex);
|
|
669
|
+
}
|
|
670
|
+
return BigInt(s);
|
|
671
|
+
};
|
|
672
|
+
|
|
673
|
+
return {
|
|
674
|
+
proof: proofJson.proof.map(parseBigInt) as RedeemParams["proof"],
|
|
675
|
+
commitments: proofJson.commitments.map(
|
|
676
|
+
parseBigInt,
|
|
677
|
+
) as RedeemParams["commitments"],
|
|
678
|
+
commitmentPok: proofJson.commitmentPok.map(
|
|
679
|
+
parseBigInt,
|
|
680
|
+
) as RedeemParams["commitmentPok"],
|
|
681
|
+
lightClients: metadata.lightClients.map((lc) => ({
|
|
682
|
+
clientId: lc.clientId,
|
|
683
|
+
height: lc.height,
|
|
684
|
+
})),
|
|
685
|
+
nullifier: metadata.nullifier,
|
|
686
|
+
value: metadata.value,
|
|
687
|
+
beneficiary: metadata.beneficiary,
|
|
688
|
+
attestedMessage: metadata.attestedMessage,
|
|
689
|
+
signature: metadata.signature,
|
|
690
|
+
};
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
/**
|
|
694
|
+
* @public
|
|
695
|
+
*/
|
|
696
|
+
export async function submitRedeem(
|
|
697
|
+
zassetAddress: Address,
|
|
698
|
+
params: RedeemParams,
|
|
699
|
+
walletClient: WalletClient,
|
|
700
|
+
): Promise<Hash> {
|
|
701
|
+
if (!walletClient.account) {
|
|
702
|
+
throw new Error("WalletClient must have an account");
|
|
703
|
+
}
|
|
704
|
+
if (!walletClient.chain) {
|
|
705
|
+
throw new Error("WalletClient must have a chain configured");
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
const hash = await walletClient
|
|
709
|
+
.writeContractSync({
|
|
710
|
+
address: zassetAddress,
|
|
711
|
+
abi: ZASSET_ABI,
|
|
712
|
+
functionName: "redeem",
|
|
713
|
+
args: [
|
|
714
|
+
params.proof,
|
|
715
|
+
params.commitments,
|
|
716
|
+
params.commitmentPok,
|
|
717
|
+
params.lightClients,
|
|
718
|
+
params.nullifier,
|
|
719
|
+
params.value,
|
|
720
|
+
params.beneficiary,
|
|
721
|
+
params.attestedMessage,
|
|
722
|
+
params.signature,
|
|
723
|
+
],
|
|
724
|
+
chain: walletClient.chain,
|
|
725
|
+
account: walletClient.account,
|
|
726
|
+
})
|
|
727
|
+
.then((x) => x.transactionHash);
|
|
728
|
+
|
|
729
|
+
return hash;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
* RLP encode an EVM block header for the loopback light client.
|
|
734
|
+
* The header fields must be in the exact order expected by the EVM.
|
|
735
|
+
* Verifies the encoding by checking that keccak256(rlp) == block.hash
|
|
736
|
+
*/
|
|
737
|
+
function rlpEncodeBlockHeader(block: Block): Hex {
|
|
738
|
+
// Helper to convert bigint/number to minimal RLP hex encoding
|
|
739
|
+
// RLP requires no leading zeros, and 0 is encoded as empty string (0x80)
|
|
740
|
+
const toRlpHex = (value: bigint | number | null | undefined): Hex => {
|
|
741
|
+
if (value === undefined || value === null || value === 0n || value === 0) {
|
|
742
|
+
return "0x" as Hex;
|
|
743
|
+
}
|
|
744
|
+
let hex =
|
|
745
|
+
typeof value === "bigint" ? value.toString(16) : value.toString(16);
|
|
746
|
+
// Ensure even length for proper byte encoding
|
|
747
|
+
if (hex.length % 2 !== 0) {
|
|
748
|
+
hex = "0" + hex;
|
|
749
|
+
}
|
|
750
|
+
return `0x${hex}` as Hex;
|
|
751
|
+
};
|
|
752
|
+
|
|
753
|
+
// Build header fields in order (pre-merge + post-merge fields)
|
|
754
|
+
const headerFields: (Hex | Hex[])[] = [
|
|
755
|
+
block.parentHash,
|
|
756
|
+
block.sha3Uncles,
|
|
757
|
+
block.miner,
|
|
758
|
+
block.stateRoot,
|
|
759
|
+
block.transactionsRoot,
|
|
760
|
+
block.receiptsRoot,
|
|
761
|
+
block.logsBloom ?? (("0x" + "00".repeat(256)) as Hex),
|
|
762
|
+
toRlpHex(block.difficulty),
|
|
763
|
+
toRlpHex(block.number),
|
|
764
|
+
toRlpHex(block.gasLimit),
|
|
765
|
+
toRlpHex(block.gasUsed),
|
|
766
|
+
toRlpHex(block.timestamp),
|
|
767
|
+
block.extraData,
|
|
768
|
+
block.mixHash ??
|
|
769
|
+
("0x0000000000000000000000000000000000000000000000000000000000000000" as Hex),
|
|
770
|
+
block.nonce ?? ("0x0000000000000000" as Hex),
|
|
771
|
+
];
|
|
772
|
+
|
|
773
|
+
// Post-merge fields (EIP-1559, EIP-4895, EIP-4844, EIP-4788, EIP-7685)
|
|
774
|
+
if (block.baseFeePerGas !== undefined && block.baseFeePerGas !== null) {
|
|
775
|
+
headerFields.push(toRlpHex(block.baseFeePerGas));
|
|
776
|
+
}
|
|
777
|
+
if (block.withdrawalsRoot) {
|
|
778
|
+
headerFields.push(block.withdrawalsRoot);
|
|
779
|
+
}
|
|
780
|
+
if (block.blobGasUsed !== undefined && block.blobGasUsed !== null) {
|
|
781
|
+
headerFields.push(toRlpHex(block.blobGasUsed));
|
|
782
|
+
}
|
|
783
|
+
if (block.excessBlobGas !== undefined && block.excessBlobGas !== null) {
|
|
784
|
+
headerFields.push(toRlpHex(block.excessBlobGas));
|
|
785
|
+
}
|
|
786
|
+
if (block.parentBeaconBlockRoot) {
|
|
787
|
+
headerFields.push(block.parentBeaconBlockRoot);
|
|
788
|
+
}
|
|
789
|
+
// EIP-7685 requestsHash (Pectra upgrade) - not yet in viem types
|
|
790
|
+
const blockAny = block as Record<string, unknown>;
|
|
791
|
+
if (blockAny.requestsHash) {
|
|
792
|
+
headerFields.push(blockAny.requestsHash as Hex);
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
const rlpEncoded = toRlp(headerFields);
|
|
796
|
+
|
|
797
|
+
// Verify the encoding produces the correct block hash
|
|
798
|
+
const computedHash = keccak256(rlpEncoded);
|
|
799
|
+
if (computedHash !== block.hash) {
|
|
800
|
+
throw new Error(
|
|
801
|
+
`RLP encoding mismatch: computed hash ${computedHash} does not match block hash ${block.hash}. ` +
|
|
802
|
+
`Block number: ${block.number}, fields count: ${headerFields.length}`,
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
return rlpEncoded;
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
/**
|
|
810
|
+
* Update a loopback light client to a specific block height.
|
|
811
|
+
* The loopback client operates on the same chain, so only one RPC URL is needed.
|
|
812
|
+
*
|
|
813
|
+
* @param rpcUrl - RPC URL for the chain (same chain for fetching block and submitting tx)
|
|
814
|
+
* @param ibcHandlerAddress - Address of the IBCHandler contract
|
|
815
|
+
* @param clientId - The light client ID to update
|
|
816
|
+
* @param height - Block height to update to (bigint or 'latest')
|
|
817
|
+
* @param walletClient - viem WalletClient with account and chain configured
|
|
818
|
+
* @returns Transaction hash, block number, state root, and chain ID
|
|
819
|
+
* @public
|
|
820
|
+
*/
|
|
821
|
+
export async function updateLoopbackClient(
|
|
822
|
+
rpcUrl: string,
|
|
823
|
+
ibcHandlerAddress: Address,
|
|
824
|
+
clientId: number,
|
|
825
|
+
height: bigint | "latest",
|
|
826
|
+
walletClient: WalletClient,
|
|
827
|
+
): Promise<UpdateLightClientResult> {
|
|
828
|
+
if (!walletClient.account) {
|
|
829
|
+
throw new Error("WalletClient must have an account");
|
|
830
|
+
}
|
|
831
|
+
if (!walletClient.chain) {
|
|
832
|
+
throw new Error("WalletClient must have a chain configured");
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
// Create public client
|
|
836
|
+
const publicClient = createPublicClient({
|
|
837
|
+
transport: http(rpcUrl),
|
|
838
|
+
});
|
|
839
|
+
|
|
840
|
+
// Get chain ID from RPC
|
|
841
|
+
const chainId = await publicClient.getChainId();
|
|
842
|
+
|
|
843
|
+
// Get the block number
|
|
844
|
+
const blockNumber =
|
|
845
|
+
height === "latest" ? await publicClient.getBlockNumber() : height;
|
|
846
|
+
|
|
847
|
+
// Get the block for metadata
|
|
848
|
+
const block = await publicClient.getBlock({ blockNumber });
|
|
849
|
+
|
|
850
|
+
if (!block.number) {
|
|
851
|
+
throw new Error("Block number is null");
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
// RLP encode the block header and verify the hash matches
|
|
855
|
+
const rlpEncodedHeader = rlpEncodeBlockHeader(block);
|
|
856
|
+
|
|
857
|
+
// Encode the Header struct: (uint64 height, bytes encodedHeader)
|
|
858
|
+
const clientMessage = encodeAbiParameters(
|
|
859
|
+
[
|
|
860
|
+
{ type: "uint64", name: "height" },
|
|
861
|
+
{ type: "bytes", name: "encodedHeader" },
|
|
862
|
+
],
|
|
863
|
+
[block.number, rlpEncodedHeader],
|
|
864
|
+
);
|
|
865
|
+
|
|
866
|
+
// Wait for the next block so the fetched block's hash is verifiable on-chain
|
|
867
|
+
let currentBlock = await publicClient.getBlockNumber();
|
|
868
|
+
while (currentBlock <= blockNumber) {
|
|
869
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
870
|
+
currentBlock = await publicClient.getBlockNumber();
|
|
871
|
+
}
|
|
872
|
+
|
|
873
|
+
// Submit the transaction
|
|
874
|
+
const txHash = await walletClient
|
|
875
|
+
.writeContractSync({
|
|
876
|
+
address: ibcHandlerAddress,
|
|
877
|
+
abi: IBC_HANDLER_ABI,
|
|
878
|
+
functionName: "updateClient",
|
|
879
|
+
args: [
|
|
880
|
+
{
|
|
881
|
+
clientId,
|
|
882
|
+
clientMessage,
|
|
883
|
+
relayer: walletClient.account.address,
|
|
884
|
+
},
|
|
885
|
+
],
|
|
886
|
+
chain: walletClient.chain,
|
|
887
|
+
account: walletClient.account,
|
|
888
|
+
})
|
|
889
|
+
.then((x) => x.transactionHash);
|
|
890
|
+
|
|
891
|
+
return {
|
|
892
|
+
txHash,
|
|
893
|
+
blockNumber: block.number,
|
|
894
|
+
stateRoot: block.stateRoot,
|
|
895
|
+
chainId: BigInt(chainId),
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
/**
|
|
900
|
+
* Deposit underlying tokens to ZAsset and transfer to a deposit address.
|
|
901
|
+
* Executes 3 transactions: approve → deposit → transfer.
|
|
902
|
+
*
|
|
903
|
+
* @param rpcUrl - RPC URL for the chain
|
|
904
|
+
* @param zAssetAddress - Address of the ZAsset contract
|
|
905
|
+
* @param depositAddress - Address to receive the ZAsset tokens (derived from secret)
|
|
906
|
+
* @param amount - Amount to deposit (in underlying token's smallest unit)
|
|
907
|
+
* @param walletClient - viem WalletClient with account and chain configured
|
|
908
|
+
* @returns Transaction hash of the final transfer, underlying token address, and chain ID
|
|
909
|
+
* @public
|
|
910
|
+
*/
|
|
911
|
+
export async function depositToZAsset(
|
|
912
|
+
rpcUrl: string,
|
|
913
|
+
zAssetAddress: Address,
|
|
914
|
+
depositAddress: Address,
|
|
915
|
+
amount: bigint,
|
|
916
|
+
walletClient: WalletClient,
|
|
917
|
+
): Promise<DepositToZAssetResult> {
|
|
918
|
+
if (!walletClient.account) {
|
|
919
|
+
throw new Error("WalletClient must have an account");
|
|
920
|
+
}
|
|
921
|
+
if (!walletClient.chain) {
|
|
922
|
+
throw new Error("WalletClient must have a chain configured");
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
const publicClient = createPublicClient({
|
|
926
|
+
transport: http(rpcUrl),
|
|
927
|
+
});
|
|
928
|
+
|
|
929
|
+
const chainId = await publicClient.getChainId();
|
|
930
|
+
|
|
931
|
+
// Get underlying token address
|
|
932
|
+
const underlyingToken = (await publicClient.readContract({
|
|
933
|
+
address: zAssetAddress,
|
|
934
|
+
abi: ZASSET_ABI,
|
|
935
|
+
functionName: "underlying",
|
|
936
|
+
})) as Address;
|
|
937
|
+
|
|
938
|
+
if (underlyingToken === "0x0000000000000000000000000000000000000000") {
|
|
939
|
+
throw new Error(
|
|
940
|
+
"ZAsset is not a wrapped token (underlying is zero address)",
|
|
941
|
+
);
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
// 1. Approve ZAsset to spend underlying tokens
|
|
945
|
+
const approveReceipt = await walletClient.writeContractSync({
|
|
946
|
+
address: underlyingToken,
|
|
947
|
+
abi: ERC20_ABI,
|
|
948
|
+
functionName: "approve",
|
|
949
|
+
args: [zAssetAddress, amount],
|
|
950
|
+
chain: walletClient.chain,
|
|
951
|
+
account: walletClient.account,
|
|
952
|
+
});
|
|
953
|
+
if (approveReceipt.status === "reverted") {
|
|
954
|
+
throw new Error(
|
|
955
|
+
`Approve transaction reverted: ${approveReceipt.transactionHash}`,
|
|
956
|
+
);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
// 2. Deposit underlying to get ZAsset
|
|
960
|
+
const depositReceipt = await walletClient.writeContractSync({
|
|
961
|
+
address: zAssetAddress,
|
|
962
|
+
abi: ZASSET_ABI,
|
|
963
|
+
functionName: "deposit",
|
|
964
|
+
args: [amount],
|
|
965
|
+
chain: walletClient.chain,
|
|
966
|
+
account: walletClient.account,
|
|
967
|
+
});
|
|
968
|
+
if (depositReceipt.status === "reverted") {
|
|
969
|
+
throw new Error(
|
|
970
|
+
`Deposit transaction reverted: ${depositReceipt.transactionHash}`,
|
|
971
|
+
);
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// 3. Transfer ZAsset to deposit address
|
|
975
|
+
const transferReceipt = await walletClient.writeContractSync({
|
|
976
|
+
address: zAssetAddress,
|
|
977
|
+
abi: ZASSET_ABI,
|
|
978
|
+
functionName: "transfer",
|
|
979
|
+
args: [depositAddress, amount],
|
|
980
|
+
chain: walletClient.chain,
|
|
981
|
+
account: walletClient.account,
|
|
982
|
+
});
|
|
983
|
+
if (transferReceipt.status === "reverted") {
|
|
984
|
+
throw new Error(
|
|
985
|
+
`Transfer transaction reverted: ${transferReceipt.transactionHash}`,
|
|
986
|
+
);
|
|
987
|
+
}
|
|
988
|
+
|
|
989
|
+
return {
|
|
990
|
+
txHash: transferReceipt.transactionHash,
|
|
991
|
+
underlyingToken,
|
|
992
|
+
chainId: BigInt(chainId),
|
|
993
|
+
};
|
|
994
|
+
}
|