@miradexio/client 0.1.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/LICENSE +21 -0
- package/README.md +405 -0
- package/dist/address/base58.d.ts +9 -0
- package/dist/address/base58.d.ts.map +1 -0
- package/dist/address/base58.js +33 -0
- package/dist/address/base58.js.map +1 -0
- package/dist/address/bech32.d.ts +13 -0
- package/dist/address/bech32.d.ts.map +1 -0
- package/dist/address/bech32.js +41 -0
- package/dist/address/bech32.js.map +1 -0
- package/dist/address/evm.d.ts +5 -0
- package/dist/address/evm.d.ts.map +1 -0
- package/dist/address/evm.js +27 -0
- package/dist/address/evm.js.map +1 -0
- package/dist/address/index.d.ts +15 -0
- package/dist/address/index.d.ts.map +1 -0
- package/dist/address/index.js +134 -0
- package/dist/address/index.js.map +1 -0
- package/dist/address/monero.d.ts +15 -0
- package/dist/address/monero.d.ts.map +1 -0
- package/dist/address/monero.js +30 -0
- package/dist/address/monero.js.map +1 -0
- package/dist/address/polkadot.d.ts +10 -0
- package/dist/address/polkadot.d.ts.map +1 -0
- package/dist/address/polkadot.js +36 -0
- package/dist/address/polkadot.js.map +1 -0
- package/dist/address/solana.d.ts +5 -0
- package/dist/address/solana.d.ts.map +1 -0
- package/dist/address/solana.js +17 -0
- package/dist/address/solana.js.map +1 -0
- package/dist/address/ton.d.ts +11 -0
- package/dist/address/ton.d.ts.map +1 -0
- package/dist/address/ton.js +28 -0
- package/dist/address/ton.js.map +1 -0
- package/dist/api/index.d.ts +80 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +213 -0
- package/dist/api/index.js.map +1 -0
- package/dist/atomic-swap/drive.d.ts +22 -0
- package/dist/atomic-swap/drive.d.ts.map +1 -0
- package/dist/atomic-swap/drive.js +713 -0
- package/dist/atomic-swap/drive.js.map +1 -0
- package/dist/atomic-swap/extract.d.ts +46 -0
- package/dist/atomic-swap/extract.d.ts.map +1 -0
- package/dist/atomic-swap/extract.js +55 -0
- package/dist/atomic-swap/extract.js.map +1 -0
- package/dist/atomic-swap/index.d.ts +15 -0
- package/dist/atomic-swap/index.d.ts.map +1 -0
- package/dist/atomic-swap/index.js +13 -0
- package/dist/atomic-swap/index.js.map +1 -0
- package/dist/atomic-swap/monero-sweep/errors.d.ts +2 -0
- package/dist/atomic-swap/monero-sweep/errors.d.ts.map +1 -0
- package/dist/atomic-swap/monero-sweep/errors.js +43 -0
- package/dist/atomic-swap/monero-sweep/errors.js.map +1 -0
- package/dist/atomic-swap/monero-sweep/index.d.ts +33 -0
- package/dist/atomic-swap/monero-sweep/index.d.ts.map +1 -0
- package/dist/atomic-swap/monero-sweep/index.js +415 -0
- package/dist/atomic-swap/monero-sweep/index.js.map +1 -0
- package/dist/atomic-swap/monero-sweep/ring-select.d.ts +12 -0
- package/dist/atomic-swap/monero-sweep/ring-select.d.ts.map +1 -0
- package/dist/atomic-swap/monero-sweep/ring-select.js +61 -0
- package/dist/atomic-swap/monero-sweep/ring-select.js.map +1 -0
- package/dist/atomic-swap/presign.d.ts +101 -0
- package/dist/atomic-swap/presign.d.ts.map +1 -0
- package/dist/atomic-swap/presign.js +460 -0
- package/dist/atomic-swap/presign.js.map +1 -0
- package/dist/atomic-swap/refund.d.ts +72 -0
- package/dist/atomic-swap/refund.d.ts.map +1 -0
- package/dist/atomic-swap/refund.js +224 -0
- package/dist/atomic-swap/refund.js.map +1 -0
- package/dist/atomic-swap/run.d.ts +27 -0
- package/dist/atomic-swap/run.d.ts.map +1 -0
- package/dist/atomic-swap/run.js +282 -0
- package/dist/atomic-swap/run.js.map +1 -0
- package/dist/atomic-swap/snapshot.d.ts +111 -0
- package/dist/atomic-swap/snapshot.d.ts.map +1 -0
- package/dist/atomic-swap/snapshot.js +69 -0
- package/dist/atomic-swap/snapshot.js.map +1 -0
- package/dist/atomic-swap/submit-encsig.d.ts +10 -0
- package/dist/atomic-swap/submit-encsig.d.ts.map +1 -0
- package/dist/atomic-swap/submit-encsig.js +56 -0
- package/dist/atomic-swap/submit-encsig.js.map +1 -0
- package/dist/atomic-swap/types.d.ts +168 -0
- package/dist/atomic-swap/types.d.ts.map +1 -0
- package/dist/atomic-swap/types.js +5 -0
- package/dist/atomic-swap/types.js.map +1 -0
- package/dist/blockchain/quorum-provider.d.ts +25 -0
- package/dist/blockchain/quorum-provider.d.ts.map +1 -0
- package/dist/blockchain/quorum-provider.js +144 -0
- package/dist/blockchain/quorum-provider.js.map +1 -0
- package/dist/cooperative-redeem.d.ts +23 -0
- package/dist/cooperative-redeem.d.ts.map +1 -0
- package/dist/cooperative-redeem.js +40 -0
- package/dist/cooperative-redeem.js.map +1 -0
- package/dist/engine/blockchain-querier.d.ts +34 -0
- package/dist/engine/blockchain-querier.d.ts.map +1 -0
- package/dist/engine/blockchain-querier.js +2 -0
- package/dist/engine/blockchain-querier.js.map +1 -0
- package/dist/engine/engine-state.d.ts +20 -0
- package/dist/engine/engine-state.d.ts.map +1 -0
- package/dist/engine/engine-state.js +9 -0
- package/dist/engine/engine-state.js.map +1 -0
- package/dist/engine/flow-context.d.ts +494 -0
- package/dist/engine/flow-context.d.ts.map +1 -0
- package/dist/engine/flow-context.js +147 -0
- package/dist/engine/flow-context.js.map +1 -0
- package/dist/engine/flows/atomic-flow-state.d.ts +124 -0
- package/dist/engine/flows/atomic-flow-state.d.ts.map +1 -0
- package/dist/engine/flows/atomic-flow-state.js +2 -0
- package/dist/engine/flows/atomic-flow-state.js.map +1 -0
- package/dist/engine/flows/atomic-flow.d.ts +88 -0
- package/dist/engine/flows/atomic-flow.d.ts.map +1 -0
- package/dist/engine/flows/atomic-flow.js +1192 -0
- package/dist/engine/flows/atomic-flow.js.map +1 -0
- package/dist/engine/flows/history-flow-state.d.ts +19 -0
- package/dist/engine/flows/history-flow-state.d.ts.map +1 -0
- package/dist/engine/flows/history-flow-state.js +2 -0
- package/dist/engine/flows/history-flow-state.js.map +1 -0
- package/dist/engine/flows/providers-flow-state.d.ts +14 -0
- package/dist/engine/flows/providers-flow-state.d.ts.map +1 -0
- package/dist/engine/flows/providers-flow-state.js +2 -0
- package/dist/engine/flows/providers-flow-state.js.map +1 -0
- package/dist/engine/flows/quote-flow-state.d.ts +20 -0
- package/dist/engine/flows/quote-flow-state.d.ts.map +1 -0
- package/dist/engine/flows/quote-flow-state.js +2 -0
- package/dist/engine/flows/quote-flow-state.js.map +1 -0
- package/dist/engine/flows/swap-flow-state.d.ts +155 -0
- package/dist/engine/flows/swap-flow-state.d.ts.map +1 -0
- package/dist/engine/flows/swap-flow-state.js +2 -0
- package/dist/engine/flows/swap-flow-state.js.map +1 -0
- package/dist/engine/flows/swap-flow.d.ts +81 -0
- package/dist/engine/flows/swap-flow.d.ts.map +1 -0
- package/dist/engine/flows/swap-flow.js +720 -0
- package/dist/engine/flows/swap-flow.js.map +1 -0
- package/dist/engine/flows/tokens-flow-state.d.ts +16 -0
- package/dist/engine/flows/tokens-flow-state.d.ts.map +1 -0
- package/dist/engine/flows/tokens-flow-state.js +2 -0
- package/dist/engine/flows/tokens-flow-state.js.map +1 -0
- package/dist/engine/miradex-engine.d.ts +152 -0
- package/dist/engine/miradex-engine.d.ts.map +1 -0
- package/dist/engine/miradex-engine.js +278 -0
- package/dist/engine/miradex-engine.js.map +1 -0
- package/dist/engine/pipeline.d.ts +27 -0
- package/dist/engine/pipeline.d.ts.map +1 -0
- package/dist/engine/pipeline.js +166 -0
- package/dist/engine/pipeline.js.map +1 -0
- package/dist/engine/platform.d.ts +220 -0
- package/dist/engine/platform.d.ts.map +1 -0
- package/dist/engine/platform.js +2 -0
- package/dist/engine/platform.js.map +1 -0
- package/dist/index.d.ts +85 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/blockchain.d.ts +33 -0
- package/dist/interfaces/blockchain.d.ts.map +1 -0
- package/dist/interfaces/blockchain.js +2 -0
- package/dist/interfaces/blockchain.js.map +1 -0
- package/dist/interfaces/logger.d.ts +14 -0
- package/dist/interfaces/logger.d.ts.map +1 -0
- package/dist/interfaces/logger.js +7 -0
- package/dist/interfaces/logger.js.map +1 -0
- package/dist/lib/bitcoin/deposit-watcher.d.ts +66 -0
- package/dist/lib/bitcoin/deposit-watcher.d.ts.map +1 -0
- package/dist/lib/bitcoin/deposit-watcher.js +218 -0
- package/dist/lib/bitcoin/deposit-watcher.js.map +1 -0
- package/dist/lib/bitcoin/script-hash.d.ts +8 -0
- package/dist/lib/bitcoin/script-hash.d.ts.map +1 -0
- package/dist/lib/bitcoin/script-hash.js +29 -0
- package/dist/lib/bitcoin/script-hash.js.map +1 -0
- package/dist/lib/bitcoin/sweep.d.ts +56 -0
- package/dist/lib/bitcoin/sweep.d.ts.map +1 -0
- package/dist/lib/bitcoin/sweep.js +185 -0
- package/dist/lib/bitcoin/sweep.js.map +1 -0
- package/dist/lib/bitcoin/tx-verify.d.ts +43 -0
- package/dist/lib/bitcoin/tx-verify.d.ts.map +1 -0
- package/dist/lib/bitcoin/tx-verify.js +202 -0
- package/dist/lib/bitcoin/tx-verify.js.map +1 -0
- package/dist/lib/bitcoin/wallet.d.ts +71 -0
- package/dist/lib/bitcoin/wallet.d.ts.map +1 -0
- package/dist/lib/bitcoin/wallet.js +141 -0
- package/dist/lib/bitcoin/wallet.js.map +1 -0
- package/dist/lib/crypto/bytes.d.ts +21 -0
- package/dist/lib/crypto/bytes.d.ts.map +1 -0
- package/dist/lib/crypto/bytes.js +39 -0
- package/dist/lib/crypto/bytes.js.map +1 -0
- package/dist/lib/crypto/errors.d.ts +12 -0
- package/dist/lib/crypto/errors.d.ts.map +1 -0
- package/dist/lib/crypto/errors.js +16 -0
- package/dist/lib/crypto/errors.js.map +1 -0
- package/dist/lib/crypto/keygen.d.ts +19 -0
- package/dist/lib/crypto/keygen.d.ts.map +1 -0
- package/dist/lib/crypto/keygen.js +24 -0
- package/dist/lib/crypto/keygen.js.map +1 -0
- package/dist/lib/crypto/libp2p-identity.d.ts +25 -0
- package/dist/lib/crypto/libp2p-identity.d.ts.map +1 -0
- package/dist/lib/crypto/libp2p-identity.js +80 -0
- package/dist/lib/crypto/libp2p-identity.js.map +1 -0
- package/dist/lib/crypto/mnemonic.d.ts +28 -0
- package/dist/lib/crypto/mnemonic.d.ts.map +1 -0
- package/dist/lib/crypto/mnemonic.js +97 -0
- package/dist/lib/crypto/mnemonic.js.map +1 -0
- package/dist/lib/crypto/platform.d.ts +10 -0
- package/dist/lib/crypto/platform.d.ts.map +1 -0
- package/dist/lib/crypto/platform.js +38 -0
- package/dist/lib/crypto/platform.js.map +1 -0
- package/dist/lib/crypto/scalars.d.ts +33 -0
- package/dist/lib/crypto/scalars.d.ts.map +1 -0
- package/dist/lib/crypto/scalars.js +81 -0
- package/dist/lib/crypto/scalars.js.map +1 -0
- package/dist/lib/crypto/types.d.ts +24 -0
- package/dist/lib/crypto/types.d.ts.map +1 -0
- package/dist/lib/crypto/types.js +2 -0
- package/dist/lib/crypto/types.js.map +1 -0
- package/dist/lib/crypto/wasm.d.ts +51 -0
- package/dist/lib/crypto/wasm.d.ts.map +1 -0
- package/dist/lib/crypto/wasm.js +192 -0
- package/dist/lib/crypto/wasm.js.map +1 -0
- package/dist/lib/default-config.d.ts +140 -0
- package/dist/lib/default-config.d.ts.map +1 -0
- package/dist/lib/default-config.js +239 -0
- package/dist/lib/default-config.js.map +1 -0
- package/dist/lib/delay.d.ts +6 -0
- package/dist/lib/delay.d.ts.map +1 -0
- package/dist/lib/delay.js +20 -0
- package/dist/lib/delay.js.map +1 -0
- package/dist/lib/errors.d.ts +90 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +129 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/format.d.ts +7 -0
- package/dist/lib/format.d.ts.map +1 -0
- package/dist/lib/format.js +43 -0
- package/dist/lib/format.js.map +1 -0
- package/dist/lib/keystore.d.ts +85 -0
- package/dist/lib/keystore.d.ts.map +1 -0
- package/dist/lib/keystore.js +105 -0
- package/dist/lib/keystore.js.map +1 -0
- package/dist/lib/monero/output-scanner.d.ts +53 -0
- package/dist/lib/monero/output-scanner.d.ts.map +1 -0
- package/dist/lib/monero/output-scanner.js +180 -0
- package/dist/lib/monero/output-scanner.js.map +1 -0
- package/dist/lib/monero/rpc.d.ts +131 -0
- package/dist/lib/monero/rpc.d.ts.map +1 -0
- package/dist/lib/monero/rpc.js +267 -0
- package/dist/lib/monero/rpc.js.map +1 -0
- package/dist/lib/monero/verify-lock.d.ts +50 -0
- package/dist/lib/monero/verify-lock.d.ts.map +1 -0
- package/dist/lib/monero/verify-lock.js +161 -0
- package/dist/lib/monero/verify-lock.js.map +1 -0
- package/dist/lib/monero/verify-sweep.d.ts +59 -0
- package/dist/lib/monero/verify-sweep.d.ts.map +1 -0
- package/dist/lib/monero/verify-sweep.js +82 -0
- package/dist/lib/monero/verify-sweep.js.map +1 -0
- package/dist/lib/monero/wasm.d.ts +19 -0
- package/dist/lib/monero/wasm.d.ts.map +1 -0
- package/dist/lib/monero/wasm.js +24 -0
- package/dist/lib/monero/wasm.js.map +1 -0
- package/dist/lib/pow-solver.d.ts +4 -0
- package/dist/lib/pow-solver.d.ts.map +1 -0
- package/dist/lib/pow-solver.js +37 -0
- package/dist/lib/pow-solver.js.map +1 -0
- package/dist/lib/retry.d.ts +86 -0
- package/dist/lib/retry.d.ts.map +1 -0
- package/dist/lib/retry.js +104 -0
- package/dist/lib/retry.js.map +1 -0
- package/dist/portable.d.ts +23 -0
- package/dist/portable.d.ts.map +1 -0
- package/dist/portable.js +13 -0
- package/dist/portable.js.map +1 -0
- package/dist/quote-binding.d.ts +31 -0
- package/dist/quote-binding.d.ts.map +1 -0
- package/dist/quote-binding.js +40 -0
- package/dist/quote-binding.js.map +1 -0
- package/dist/swap-executor.d.ts +51 -0
- package/dist/swap-executor.d.ts.map +1 -0
- package/dist/swap-executor.js +138 -0
- package/dist/swap-executor.js.map +1 -0
- package/dist/types/api.d.ts +34 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +18 -0
- package/dist/types/api.js.map +1 -0
- package/dist/types/errors.d.ts +94 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +93 -0
- package/dist/types/errors.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +10 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/keys.d.ts +33 -0
- package/dist/types/keys.d.ts.map +1 -0
- package/dist/types/keys.js +2 -0
- package/dist/types/keys.js.map +1 -0
- package/dist/types/protocol.d.ts +93 -0
- package/dist/types/protocol.d.ts.map +1 -0
- package/dist/types/protocol.js +18 -0
- package/dist/types/protocol.js.map +1 -0
- package/dist/types/status.d.ts +3 -0
- package/dist/types/status.d.ts.map +1 -0
- package/dist/types/status.js +23 -0
- package/dist/types/status.js.map +1 -0
- package/dist/types/verification.d.ts +49 -0
- package/dist/types/verification.d.ts.map +1 -0
- package/dist/types/verification.js +34 -0
- package/dist/types/verification.js.map +1 -0
- package/dist/verification/atomic-swap.d.ts +9 -0
- package/dist/verification/atomic-swap.d.ts.map +1 -0
- package/dist/verification/atomic-swap.js +22 -0
- package/dist/verification/atomic-swap.js.map +1 -0
- package/dist/verification/chainflip-networks.d.ts +46 -0
- package/dist/verification/chainflip-networks.d.ts.map +1 -0
- package/dist/verification/chainflip-networks.js +24 -0
- package/dist/verification/chainflip-networks.js.map +1 -0
- package/dist/verification/chainflip.d.ts +61 -0
- package/dist/verification/chainflip.d.ts.map +1 -0
- package/dist/verification/chainflip.js +377 -0
- package/dist/verification/chainflip.js.map +1 -0
- package/dist/verification/constants.d.ts +52 -0
- package/dist/verification/constants.d.ts.map +1 -0
- package/dist/verification/constants.js +54 -0
- package/dist/verification/constants.js.map +1 -0
- package/dist/verification/index.d.ts +71 -0
- package/dist/verification/index.d.ts.map +1 -0
- package/dist/verification/index.js +91 -0
- package/dist/verification/index.js.map +1 -0
- package/dist/verification/memo.d.ts +27 -0
- package/dist/verification/memo.d.ts.map +1 -0
- package/dist/verification/memo.js +52 -0
- package/dist/verification/memo.js.map +1 -0
- package/dist/verification/near-intents.d.ts +91 -0
- package/dist/verification/near-intents.d.ts.map +1 -0
- package/dist/verification/near-intents.js +213 -0
- package/dist/verification/near-intents.js.map +1 -0
- package/dist/verification/rate-oracle.d.ts +32 -0
- package/dist/verification/rate-oracle.d.ts.map +1 -0
- package/dist/verification/rate-oracle.js +43 -0
- package/dist/verification/rate-oracle.js.map +1 -0
- package/dist/verification/shared.d.ts +20 -0
- package/dist/verification/shared.d.ts.map +1 -0
- package/dist/verification/shared.js +25 -0
- package/dist/verification/shared.js.map +1 -0
- package/dist/verification/thorchain-networks.d.ts +35 -0
- package/dist/verification/thorchain-networks.d.ts.map +1 -0
- package/dist/verification/thorchain-networks.js +35 -0
- package/dist/verification/thorchain-networks.js.map +1 -0
- package/dist/verification/thorchain.d.ts +55 -0
- package/dist/verification/thorchain.d.ts.map +1 -0
- package/dist/verification/thorchain.js +232 -0
- package/dist/verification/thorchain.js.map +1 -0
- package/dist/wasm-pins.d.ts +4 -0
- package/dist/wasm-pins.d.ts.map +1 -0
- package/dist/wasm-pins.js +6 -0
- package/dist/wasm-pins.js.map +1 -0
- package/dist/wire/chainflip.zod.d.ts +144 -0
- package/dist/wire/chainflip.zod.d.ts.map +1 -0
- package/dist/wire/chainflip.zod.js +33 -0
- package/dist/wire/chainflip.zod.js.map +1 -0
- package/dist/wire/near-intents.zod.d.ts +376 -0
- package/dist/wire/near-intents.zod.d.ts.map +1 -0
- package/dist/wire/near-intents.zod.js +101 -0
- package/dist/wire/near-intents.zod.js.map +1 -0
- package/dist/wire/server/action.zod.d.ts +1119 -0
- package/dist/wire/server/action.zod.d.ts.map +1 -0
- package/dist/wire/server/action.zod.js +173 -0
- package/dist/wire/server/action.zod.js.map +1 -0
- package/dist/wire/server/common.zod.d.ts +62 -0
- package/dist/wire/server/common.zod.d.ts.map +1 -0
- package/dist/wire/server/common.zod.js +43 -0
- package/dist/wire/server/common.zod.js.map +1 -0
- package/dist/wire/server/index.d.ts +8 -0
- package/dist/wire/server/index.d.ts.map +1 -0
- package/dist/wire/server/index.js +8 -0
- package/dist/wire/server/index.js.map +1 -0
- package/dist/wire/server/pow.zod.d.ts +45 -0
- package/dist/wire/server/pow.zod.d.ts.map +1 -0
- package/dist/wire/server/pow.zod.js +18 -0
- package/dist/wire/server/pow.zod.js.map +1 -0
- package/dist/wire/server/quotes.zod.d.ts +694 -0
- package/dist/wire/server/quotes.zod.d.ts.map +1 -0
- package/dist/wire/server/quotes.zod.js +103 -0
- package/dist/wire/server/quotes.zod.js.map +1 -0
- package/dist/wire/server/swap.zod.d.ts +1981 -0
- package/dist/wire/server/swap.zod.d.ts.map +1 -0
- package/dist/wire/server/swap.zod.js +270 -0
- package/dist/wire/server/swap.zod.js.map +1 -0
- package/dist/wire/server/tokens.zod.d.ts +93 -0
- package/dist/wire/server/tokens.zod.d.ts.map +1 -0
- package/dist/wire/server/tokens.zod.js +28 -0
- package/dist/wire/server/tokens.zod.js.map +1 -0
- package/dist/wire/server/verify.zod.d.ts +30 -0
- package/dist/wire/server/verify.zod.d.ts.map +1 -0
- package/dist/wire/server/verify.zod.js +12 -0
- package/dist/wire/server/verify.zod.js.map +1 -0
- package/dist/wire/thorchain.zod.d.ts +224 -0
- package/dist/wire/thorchain.zod.d.ts.map +1 -0
- package/dist/wire/thorchain.zod.js +51 -0
- package/dist/wire/thorchain.zod.js.map +1 -0
- package/package.json +128 -0
- package/wasm/miradex-rust/README.md +74 -0
- package/wasm/miradex-rust/miradex_rust.d.ts +149 -0
- package/wasm/miradex-rust/miradex_rust.js +943 -0
- package/wasm/miradex-rust/miradex_rust_bg.wasm +0 -0
- package/wasm/miradex-rust/miradex_rust_bg.wasm.d.ts +31 -0
- package/wasm/miradex-rust/package.json +24 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-lock.d.ts","sourceRoot":"","sources":["../../../src/lib/monero/verify-lock.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAWzD,MAAM,WAAW,mBAAmB;IAClC,qCAAqC;IACrC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,gDAAgD;IAChD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,+BAA+B;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED,MAAM,WAAW,mBAAmB;IAClC,6CAA6C;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,6DAA6D;IAC7D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,yEAAyE;IACzE,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,oCAAoC;IACpC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,oDAAoD;IACpD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,iFAAiF;IACjF,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1C,0DAA0D;IAC1D,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAChC,sDAAsD;IACtD,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc;IACd,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAID;;;;;;GAMG;AACH,wBAAsB,eAAe,CACnC,MAAM,EAAE,mBAAmB,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CA8K9B"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-side verification that XMR is locked at the shared address.
|
|
3
|
+
*
|
|
4
|
+
* Fetches the lock transaction from a public Monero node and scans its
|
|
5
|
+
* outputs using the shared view key. This ensures the client doesn't
|
|
6
|
+
* submit encsig (releasing BTC) unless the XMR is actually locked.
|
|
7
|
+
*
|
|
8
|
+
* Uses @noble/ed25519 + @noble/hashes — both already in dependencies.
|
|
9
|
+
* No WASM, no heavy dependencies, no sidecar required.
|
|
10
|
+
*/
|
|
11
|
+
import { Point } from '@noble/ed25519';
|
|
12
|
+
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
13
|
+
import { noopLogger } from '../../interfaces/logger.js';
|
|
14
|
+
import { extractTxPubKey, hexToScalar, deriveScalar, decryptAmount, } from './output-scanner.js';
|
|
15
|
+
import { fetchTransaction, fetchTransactionQuorum, STAGENET_NODES } from './rpc.js';
|
|
16
|
+
const FAIL = { verified: false, amount: 0n, confirmations: 0 };
|
|
17
|
+
/**
|
|
18
|
+
* Verify that XMR is locked at the shared address by scanning the lock
|
|
19
|
+
* transaction from a public Monero node.
|
|
20
|
+
*
|
|
21
|
+
* Call this BEFORE submitting encsig. If this returns verified: false,
|
|
22
|
+
* DO NOT submit the encrypted signature.
|
|
23
|
+
*/
|
|
24
|
+
export async function verifyXmrLocked(params) {
|
|
25
|
+
const { lockTxHash, viewKeyHex, spendPubHex, expectedAmount, minConfirmations = 10, txKeyHex, logger: log = noopLogger, } = params;
|
|
26
|
+
const quorumNodes = params.monerodNodes;
|
|
27
|
+
const nodes = quorumNodes ?? (params.monerodUrl ? [params.monerodUrl] : [...STAGENET_NODES]);
|
|
28
|
+
const quorum = params.monerodQuorum ?? 2;
|
|
29
|
+
const timeoutMs = params.monerodTimeoutMs ?? 15_000;
|
|
30
|
+
log.info({ lockTxHash, nodes, quorum, viewKeyLen: viewKeyHex.length, spendPubLen: spendPubHex.length }, 'Verifying XMR lock');
|
|
31
|
+
let txJson;
|
|
32
|
+
let confirmations;
|
|
33
|
+
try {
|
|
34
|
+
const fetched = quorumNodes && quorumNodes.length >= quorum
|
|
35
|
+
? await fetchTransactionQuorum({ nodes, quorum, timeoutMs, logger: log }, lockTxHash)
|
|
36
|
+
: await fetchTransaction({ nodes, logger: log }, lockTxHash);
|
|
37
|
+
txJson = fetched.txJson;
|
|
38
|
+
confirmations = fetched.confirmations;
|
|
39
|
+
log.info({ confirmations, inPool: fetched.inPool, blockHeight: fetched.blockHeight }, 'Transaction found on chain');
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
const reason = `Could not fetch tx: ${err instanceof Error ? err.message : String(err)}`;
|
|
43
|
+
log.warn({ lockTxHash, reason }, 'Monerod fetch failed; marking retryable');
|
|
44
|
+
// Transient network / node failure — the caller should retry after a
|
|
45
|
+
// backoff rather than treat this as a hard verification failure.
|
|
46
|
+
return { ...FAIL, reason, retryable: true };
|
|
47
|
+
}
|
|
48
|
+
if (confirmations < minConfirmations) {
|
|
49
|
+
return {
|
|
50
|
+
verified: false,
|
|
51
|
+
amount: 0n,
|
|
52
|
+
confirmations,
|
|
53
|
+
reason: `Only ${String(confirmations)} confirmations (need ${String(minConfirmations)})`,
|
|
54
|
+
retryable: true,
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
// AV-A.5: a non-zero tx-level unlock_time keeps the output spend-locked past
|
|
58
|
+
// the cancel window. There is no legitimate reason for a swap-lock tx to use
|
|
59
|
+
// it, so treat any non-zero value as a griefing attempt.
|
|
60
|
+
if (txJson.unlock_time !== undefined && txJson.unlock_time !== 0) {
|
|
61
|
+
return {
|
|
62
|
+
verified: false,
|
|
63
|
+
amount: 0n,
|
|
64
|
+
confirmations,
|
|
65
|
+
reason: `unlock_time is ${String(txJson.unlock_time)} (expected 0)`,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
const txPubKeyR = extractTxPubKey(txJson.extra);
|
|
69
|
+
if (!txPubKeyR) {
|
|
70
|
+
return {
|
|
71
|
+
verified: false,
|
|
72
|
+
amount: 0n,
|
|
73
|
+
confirmations,
|
|
74
|
+
reason: 'Could not extract tx public key from extra',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const txPubKeyHex = bytesToHex(txPubKeyR);
|
|
78
|
+
log.info({ txPubKeyR: txPubKeyHex }, 'Extracted tx public key R');
|
|
79
|
+
let d8Bytes;
|
|
80
|
+
try {
|
|
81
|
+
if (txKeyHex) {
|
|
82
|
+
log.debug({ txKeyLen: txKeyHex.length }, 'Using tx_key path for verification');
|
|
83
|
+
const txKey = hexToScalar(txKeyHex);
|
|
84
|
+
const expectedR = Point.BASE.multiply(txKey);
|
|
85
|
+
const expectedRHex = bytesToHex(expectedR.toBytes());
|
|
86
|
+
if (expectedRHex !== bytesToHex(txPubKeyR)) {
|
|
87
|
+
return {
|
|
88
|
+
verified: false,
|
|
89
|
+
amount: 0n,
|
|
90
|
+
confirmations,
|
|
91
|
+
reason: 'tx_key does not match tx public key — Alice may have provided a fake tx_key',
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
log.info({}, 'tx_key verified: R = r*G');
|
|
95
|
+
const viewKeyScalar = hexToScalar(viewKeyHex);
|
|
96
|
+
const viewPub = Point.BASE.multiply(viewKeyScalar);
|
|
97
|
+
const sharedSecret = viewPub.multiply(txKey);
|
|
98
|
+
d8Bytes = sharedSecret.clearCofactor().toBytes();
|
|
99
|
+
}
|
|
100
|
+
else {
|
|
101
|
+
const viewKey = hexToScalar(viewKeyHex);
|
|
102
|
+
const rPoint = Point.fromHex(txPubKeyHex);
|
|
103
|
+
const sharedSecret = rPoint.multiply(viewKey);
|
|
104
|
+
d8Bytes = sharedSecret.clearCofactor().toBytes();
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
const reason = `Cryptographic error: ${err instanceof Error ? err.message : String(err)}`;
|
|
109
|
+
return { verified: false, amount: 0n, confirmations, reason };
|
|
110
|
+
}
|
|
111
|
+
let spendPub;
|
|
112
|
+
try {
|
|
113
|
+
spendPub = Point.fromHex(spendPubHex);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
const reason = `Invalid spend public key: ${err instanceof Error ? err.message : String(err)}`;
|
|
117
|
+
return { verified: false, amount: 0n, confirmations, reason };
|
|
118
|
+
}
|
|
119
|
+
for (let i = 0; i < txJson.vout.length; i++) {
|
|
120
|
+
const output = txJson.vout[i];
|
|
121
|
+
if (!output)
|
|
122
|
+
continue;
|
|
123
|
+
// AV-A.5: skip per-output unlock_time != 0 so a mixed lock tx can still
|
|
124
|
+
// match if its honest output is the target.
|
|
125
|
+
if (output.unlock_time !== undefined && output.unlock_time !== 0)
|
|
126
|
+
continue;
|
|
127
|
+
const outputKeyHex = output.target.tagged_key?.key ?? output.target.key;
|
|
128
|
+
if (!outputKeyHex)
|
|
129
|
+
continue;
|
|
130
|
+
const derivationScalar = deriveScalar(d8Bytes, i);
|
|
131
|
+
const expectedKey = Point.BASE.multiply(derivationScalar).add(spendPub);
|
|
132
|
+
const expectedKeyHex = bytesToHex(expectedKey.toBytes());
|
|
133
|
+
if (expectedKeyHex === outputKeyHex) {
|
|
134
|
+
log.info({ outputIndex: i }, 'Found matching output');
|
|
135
|
+
const ecdhInfo = txJson.rct_signatures.ecdhInfo[i];
|
|
136
|
+
const amount = decryptAmount(d8Bytes, i, ecdhInfo);
|
|
137
|
+
log.info({
|
|
138
|
+
amount: amount.toString(),
|
|
139
|
+
expectedAmount: expectedAmount.toString(),
|
|
140
|
+
amountXmr: (Number(amount) / 1e12).toFixed(12),
|
|
141
|
+
}, 'Decrypted amount');
|
|
142
|
+
if (amount < expectedAmount) {
|
|
143
|
+
return {
|
|
144
|
+
verified: false,
|
|
145
|
+
amount,
|
|
146
|
+
confirmations,
|
|
147
|
+
reason: `Locked amount ${amount.toString()} is less than expected ${expectedAmount.toString()}`,
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return { verified: true, amount, confirmations };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
log.error({ outputCount: txJson.vout.length }, 'No output matched the lock address');
|
|
154
|
+
return {
|
|
155
|
+
verified: false,
|
|
156
|
+
amount: 0n,
|
|
157
|
+
confirmations,
|
|
158
|
+
reason: 'No output matched the lock address',
|
|
159
|
+
};
|
|
160
|
+
}
|
|
161
|
+
//# sourceMappingURL=verify-lock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-lock.js","sourceRoot":"","sources":["../../../src/lib/monero/verify-lock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEpD,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EACL,eAAe,EACf,WAAW,EACX,YAAY,EACZ,aAAa,GACd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AA6CpF,MAAM,IAAI,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,EAAW,CAAC;AAExE;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,MAA2B;IAE3B,MAAM,EACJ,UAAU,EACV,UAAU,EACV,WAAW,EACX,cAAc,EACd,gBAAgB,GAAG,EAAE,EACrB,QAAQ,EACR,MAAM,EAAE,GAAG,GAAG,UAAU,GACzB,GAAG,MAAM,CAAC;IAEX,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC;IACxC,MAAM,KAAK,GAAG,WAAW,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CAAC;IAC7F,MAAM,MAAM,GAAG,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,MAAM,CAAC,gBAAgB,IAAI,MAAM,CAAC;IACpD,GAAG,CAAC,IAAI,CACN,EAAE,UAAU,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,WAAW,EAAE,WAAW,CAAC,MAAM,EAAE,EAC7F,oBAAoB,CACrB,CAAC;IAEF,IAAI,MAAoB,CAAC;IACzB,IAAI,aAAqB,CAAC;IAE1B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,WAAW,IAAI,WAAW,CAAC,MAAM,IAAI,MAAM;YACzD,CAAC,CAAC,MAAM,sBAAsB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC;YACrF,CAAC,CAAC,MAAM,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;QAC/D,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QACxB,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;QACtC,GAAG,CAAC,IAAI,CACN,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,EAC3E,4BAA4B,CAC7B,CAAC;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,uBAAuB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QACzF,GAAG,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,yCAAyC,CAAC,CAAC;QAC5E,qEAAqE;QACrE,iEAAiE;QACjE,OAAO,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;IAC9C,CAAC;IAED,IAAI,aAAa,GAAG,gBAAgB,EAAE,CAAC;QACrC,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,EAAE;YACV,aAAa;YACb,MAAM,EAAE,QAAQ,MAAM,CAAC,aAAa,CAAC,wBAAwB,MAAM,CAAC,gBAAgB,CAAC,GAAG;YACxF,SAAS,EAAE,IAAI;SAChB,CAAC;IACJ,CAAC;IAED,6EAA6E;IAC7E,6EAA6E;IAC7E,yDAAyD;IACzD,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,KAAK,CAAC,EAAE,CAAC;QACjE,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,EAAE;YACV,aAAa;YACb,MAAM,EAAE,kBAAkB,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe;SACpE,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,eAAe,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChD,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,OAAO;YACL,QAAQ,EAAE,KAAK;YACf,MAAM,EAAE,EAAE;YACV,aAAa;YACb,MAAM,EAAE,4CAA4C;SACrD,CAAC;IACJ,CAAC;IAED,MAAM,WAAW,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;IAC1C,GAAG,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,2BAA2B,CAAC,CAAC;IAElE,IAAI,OAAmB,CAAC;IAExB,IAAI,CAAC;QACH,IAAI,QAAQ,EAAE,CAAC;YACb,GAAG,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,EAAE,oCAAoC,CAAC,CAAC;YAC/E,MAAM,KAAK,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YAEpC,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7C,MAAM,YAAY,GAAG,UAAU,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;YAErD,IAAI,YAAY,KAAK,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3C,OAAO;oBACL,QAAQ,EAAE,KAAK;oBACf,MAAM,EAAE,EAAE;oBACV,aAAa;oBACb,MAAM,EAAE,6EAA6E;iBACtF,CAAC;YACJ,CAAC;YAED,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,0BAA0B,CAAC,CAAC;YAEzC,MAAM,aAAa,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;YAC9C,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC7C,OAAO,GAAG,YAAY,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC;QACnD,CAAC;aAAM,CAAC;YACN,MAAM,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;YACxC,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;YAC1C,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC9C,OAAO,GAAG,YAAY,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,CAAC;QACnD,CAAC;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1F,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAChE,CAAC;IAED,IAAI,QAAoC,CAAC;IACzC,IAAI,CAAC;QACH,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,6BAA6B,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/F,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,aAAa,EAAE,MAAM,EAAE,CAAC;IAChE,CAAC;IAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,MAAM;YAAE,SAAS;QAEtB,wEAAwE;QACxE,4CAA4C;QAC5C,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,IAAI,MAAM,CAAC,WAAW,KAAK,CAAC;YAAE,SAAS;QAE3E,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QACxE,IAAI,CAAC,YAAY;YAAE,SAAS;QAE5B,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QAClD,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxE,MAAM,cAAc,GAAG,UAAU,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAEzD,IAAI,cAAc,KAAK,YAAY,EAAE,CAAC;YACpC,GAAG,CAAC,IAAI,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,EAAE,uBAAuB,CAAC,CAAC;YAEtD,MAAM,QAAQ,GAAG,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YAEnD,GAAG,CAAC,IAAI,CACN;gBACE,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;gBACzB,cAAc,EAAE,cAAc,CAAC,QAAQ,EAAE;gBACzC,SAAS,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;aAC/C,EACD,kBAAkB,CACnB,CAAC;YAEF,IAAI,MAAM,GAAG,cAAc,EAAE,CAAC;gBAC5B,OAAO;oBACL,QAAQ,EAAE,KAAK;oBACf,MAAM;oBACN,aAAa;oBACb,MAAM,EAAE,iBAAiB,MAAM,CAAC,QAAQ,EAAE,0BAA0B,cAAc,CAAC,QAAQ,EAAE,EAAE;iBAChG,CAAC;YACJ,CAAC;YAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;QACnD,CAAC;IACH,CAAC;IAED,GAAG,CAAC,KAAK,CACP,EAAE,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,EACnC,oCAAoC,CACrC,CAAC;IAEF,OAAO;QACL,QAAQ,EAAE,KAAK;QACf,MAAM,EAAE,EAAE;QACV,aAAa;QACb,MAAM,EAAE,oCAAoC;KAC7C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify a sweep transaction's construction data before signing.
|
|
3
|
+
*
|
|
4
|
+
* Checks that:
|
|
5
|
+
* 1. The destination address matches the expected receive address
|
|
6
|
+
* 2. The amount is positive
|
|
7
|
+
* 3. The fee is reasonable (not zero, not more than 10% of amount)
|
|
8
|
+
* 4. The inputs exist and have valid ring sizes
|
|
9
|
+
*
|
|
10
|
+
* This runs in TypeScript (not WASM) so business rules like fee caps
|
|
11
|
+
* can be updated without recompiling Rust.
|
|
12
|
+
*/
|
|
13
|
+
import type { Logger } from '../../interfaces/logger.js';
|
|
14
|
+
export interface SweepConstructionData {
|
|
15
|
+
readonly inputs: readonly SweepInputData[];
|
|
16
|
+
readonly destination: {
|
|
17
|
+
readonly address: string;
|
|
18
|
+
readonly amount: string | number;
|
|
19
|
+
};
|
|
20
|
+
readonly fee: string | number;
|
|
21
|
+
readonly tx_extra: string;
|
|
22
|
+
readonly rct_type: number;
|
|
23
|
+
}
|
|
24
|
+
interface SweepInputData {
|
|
25
|
+
readonly ring_members: readonly {
|
|
26
|
+
readonly public_key: string;
|
|
27
|
+
readonly commitment: string;
|
|
28
|
+
}[];
|
|
29
|
+
readonly real_output_index: number;
|
|
30
|
+
readonly real_output?: {
|
|
31
|
+
readonly one_time_public_key: string;
|
|
32
|
+
readonly tx_public_key: string;
|
|
33
|
+
readonly output_index: number;
|
|
34
|
+
readonly global_output_index: number;
|
|
35
|
+
readonly amount: number;
|
|
36
|
+
readonly rct_mask: string;
|
|
37
|
+
readonly additional_tx_keys: readonly string[];
|
|
38
|
+
readonly subaddr_major: number;
|
|
39
|
+
readonly subaddr_minor: number;
|
|
40
|
+
};
|
|
41
|
+
readonly key_offsets: readonly number[];
|
|
42
|
+
}
|
|
43
|
+
export interface SweepVerificationResult {
|
|
44
|
+
readonly valid: boolean;
|
|
45
|
+
readonly amount: string;
|
|
46
|
+
readonly fee: string;
|
|
47
|
+
readonly reason?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Verify sweep construction data before signing.
|
|
51
|
+
*
|
|
52
|
+
* @param constructionData - Full construction data from server
|
|
53
|
+
* @param expectedAddress - The client's XMR receive address
|
|
54
|
+
* @param logger - Optional structured logger
|
|
55
|
+
* @returns Verification result with amount, fee, and reason if invalid
|
|
56
|
+
*/
|
|
57
|
+
export declare function verifySweepTx(constructionData: SweepConstructionData, expectedAddress: string, logger?: Logger): SweepVerificationResult;
|
|
58
|
+
export {};
|
|
59
|
+
//# sourceMappingURL=verify-sweep.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-sweep.d.ts","sourceRoot":"","sources":["../../../src/lib/monero/verify-sweep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAMzD,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,MAAM,EAAE,SAAS,cAAc,EAAE,CAAC;IAC3C,QAAQ,CAAC,WAAW,EAAE;QAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAC;IACrF,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,UAAU,cAAc;IACtB,QAAQ,CAAC,YAAY,EAAE,SAAS;QAAE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC/F,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,WAAW,CAAC,EAAE;QACrB,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;QACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;QAC9B,QAAQ,CAAC,mBAAmB,EAAE,MAAM,CAAC;QACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;QAC/C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;KAChC,CAAC;IACF,QAAQ,CAAC,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;CACzC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC3B,gBAAgB,EAAE,qBAAqB,EACvC,eAAe,EAAE,MAAM,EACvB,MAAM,GAAE,MAAmB,GAC1B,uBAAuB,CAqEzB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Verify a sweep transaction's construction data before signing.
|
|
3
|
+
*
|
|
4
|
+
* Checks that:
|
|
5
|
+
* 1. The destination address matches the expected receive address
|
|
6
|
+
* 2. The amount is positive
|
|
7
|
+
* 3. The fee is reasonable (not zero, not more than 10% of amount)
|
|
8
|
+
* 4. The inputs exist and have valid ring sizes
|
|
9
|
+
*
|
|
10
|
+
* This runs in TypeScript (not WASM) so business rules like fee caps
|
|
11
|
+
* can be updated without recompiling Rust.
|
|
12
|
+
*/
|
|
13
|
+
import { noopLogger } from '../../interfaces/logger.js';
|
|
14
|
+
const CLSAG_RING_SIZE = 16;
|
|
15
|
+
const PRE_CLSAG_RING_SIZE = 11;
|
|
16
|
+
/**
|
|
17
|
+
* Verify sweep construction data before signing.
|
|
18
|
+
*
|
|
19
|
+
* @param constructionData - Full construction data from server
|
|
20
|
+
* @param expectedAddress - The client's XMR receive address
|
|
21
|
+
* @param logger - Optional structured logger
|
|
22
|
+
* @returns Verification result with amount, fee, and reason if invalid
|
|
23
|
+
*/
|
|
24
|
+
export function verifySweepTx(constructionData, expectedAddress, logger = noopLogger) {
|
|
25
|
+
const amount = String(constructionData.destination.amount);
|
|
26
|
+
const fee = String(constructionData.fee);
|
|
27
|
+
// 1. Destination address must match exactly
|
|
28
|
+
if (constructionData.destination.address !== expectedAddress) {
|
|
29
|
+
const reason = `Destination mismatch: expected ${expectedAddress}, got ${constructionData.destination.address}`;
|
|
30
|
+
logger.error({ expectedAddress, got: constructionData.destination.address }, reason);
|
|
31
|
+
return { valid: false, amount, fee, reason };
|
|
32
|
+
}
|
|
33
|
+
// 2. Amount must be positive
|
|
34
|
+
const amountNum = BigInt(amount);
|
|
35
|
+
if (amountNum <= 0n) {
|
|
36
|
+
const reason = `Sweep amount must be positive, got ${amount}`;
|
|
37
|
+
logger.error({ amount }, reason);
|
|
38
|
+
return { valid: false, amount, fee, reason };
|
|
39
|
+
}
|
|
40
|
+
// 3. Fee must be positive and not exceed 10% of amount
|
|
41
|
+
const feeNum = BigInt(fee);
|
|
42
|
+
if (feeNum <= 0n) {
|
|
43
|
+
const reason = `Fee must be positive, got ${fee}`;
|
|
44
|
+
logger.error({ fee }, reason);
|
|
45
|
+
return { valid: false, amount, fee, reason };
|
|
46
|
+
}
|
|
47
|
+
const maxFee = amountNum / 10n;
|
|
48
|
+
if (feeNum > maxFee) {
|
|
49
|
+
const reason = `Fee ${fee} exceeds 10% of amount ${amount}`;
|
|
50
|
+
logger.warn({ fee, amount, maxFee: maxFee.toString() }, reason);
|
|
51
|
+
return { valid: false, amount, fee, reason };
|
|
52
|
+
}
|
|
53
|
+
// 4. Must have at least one input
|
|
54
|
+
if (constructionData.inputs.length === 0) {
|
|
55
|
+
const reason = 'No inputs in construction data';
|
|
56
|
+
logger.error({}, reason);
|
|
57
|
+
return { valid: false, amount, fee, reason };
|
|
58
|
+
}
|
|
59
|
+
// 5. Ring size must match RCT type (CLSAG+BP+ or CLSAG+BP)
|
|
60
|
+
const expectedRingSize = constructionData.rct_type === 6 ? CLSAG_RING_SIZE : PRE_CLSAG_RING_SIZE;
|
|
61
|
+
for (let i = 0; i < constructionData.inputs.length; i++) {
|
|
62
|
+
const input = constructionData.inputs[i];
|
|
63
|
+
if (!input) {
|
|
64
|
+
const reason = `Input ${i} is undefined`;
|
|
65
|
+
logger.error({ inputIndex: i }, reason);
|
|
66
|
+
return { valid: false, amount, fee, reason };
|
|
67
|
+
}
|
|
68
|
+
if (input.ring_members.length !== expectedRingSize) {
|
|
69
|
+
const reason = `Input ${i} has ${input.ring_members.length} ring members, expected ${expectedRingSize}`;
|
|
70
|
+
logger.error({ inputIndex: i, ringSize: input.ring_members.length }, reason);
|
|
71
|
+
return { valid: false, amount, fee, reason };
|
|
72
|
+
}
|
|
73
|
+
if (input.real_output_index >= input.ring_members.length) {
|
|
74
|
+
const reason = `Input ${i} real_output_index ${input.real_output_index} out of range`;
|
|
75
|
+
logger.error({ inputIndex: i, realIndex: input.real_output_index }, reason);
|
|
76
|
+
return { valid: false, amount, fee, reason };
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
logger.info({ amount, fee, inputs: constructionData.inputs.length }, 'Sweep tx verified');
|
|
80
|
+
return { valid: true, amount, fee };
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=verify-sweep.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-sweep.js","sourceRoot":"","sources":["../../../src/lib/monero/verify-sweep.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Import directly from '@miradex/client' (or '../crypto/wasm.js').
|
|
3
|
+
* This file re-exports the unified surface for backwards compatibility.
|
|
4
|
+
* Scheduled for removal in 0.4.0.
|
|
5
|
+
*/
|
|
6
|
+
import { WasmError } from '../crypto/errors.js';
|
|
7
|
+
export { ensureWasm as ensureMoneroSweep, deriveKeyImages, selectDecoys, signSweepTx, computeCommitmentMask, verifyCommitment, decryptAmount as wasmDecryptAmount, isMoneroSweepAvailable, initMoneroSweep, } from '../crypto/wasm.js';
|
|
8
|
+
/**
|
|
9
|
+
* Legacy error class retained for downstream `new MoneroSweepError(...)` and
|
|
10
|
+
* `err.name === 'MoneroSweepError'` patterns. Thrown errors from the new
|
|
11
|
+
* unified loader are plain `WasmError` instances; this subclass is for
|
|
12
|
+
* direct construction by consumers.
|
|
13
|
+
*/
|
|
14
|
+
export declare class MoneroSweepError extends WasmError {
|
|
15
|
+
constructor(message: string, code?: string, cause?: unknown);
|
|
16
|
+
}
|
|
17
|
+
export type { WasmModule as MoneroSweepWasmModule } from '../crypto/types.js';
|
|
18
|
+
export type { EnsureWasmOptions as EnsureMoneroSweepOptions } from '../crypto/wasm.js';
|
|
19
|
+
//# sourceMappingURL=wasm.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm.d.ts","sourceRoot":"","sources":["../../../src/lib/monero/wasm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EACL,UAAU,IAAI,iBAAiB,EAC/B,eAAe,EACf,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,IAAI,iBAAiB,EAClC,sBAAsB,EACtB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,qBAAa,gBAAiB,SAAQ,SAAS;gBACjC,OAAO,EAAE,MAAM,EAAE,IAAI,SAAmB,EAAE,KAAK,CAAC,EAAE,OAAO;CAQtE;AAED,YAAY,EAAE,UAAU,IAAI,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAC9E,YAAY,EAAE,iBAAiB,IAAI,wBAAwB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Import directly from '@miradex/client' (or '../crypto/wasm.js').
|
|
3
|
+
* This file re-exports the unified surface for backwards compatibility.
|
|
4
|
+
* Scheduled for removal in 0.4.0.
|
|
5
|
+
*/
|
|
6
|
+
import { WasmError } from '../crypto/errors.js';
|
|
7
|
+
export { ensureWasm as ensureMoneroSweep, deriveKeyImages, selectDecoys, signSweepTx, computeCommitmentMask, verifyCommitment, decryptAmount as wasmDecryptAmount, isMoneroSweepAvailable, initMoneroSweep, } from '../crypto/wasm.js';
|
|
8
|
+
/**
|
|
9
|
+
* Legacy error class retained for downstream `new MoneroSweepError(...)` and
|
|
10
|
+
* `err.name === 'MoneroSweepError'` patterns. Thrown errors from the new
|
|
11
|
+
* unified loader are plain `WasmError` instances; this subclass is for
|
|
12
|
+
* direct construction by consumers.
|
|
13
|
+
*/
|
|
14
|
+
export class MoneroSweepError extends WasmError {
|
|
15
|
+
constructor(message, code = 'E_MONERO_SWEEP', cause) {
|
|
16
|
+
super(code, message, cause);
|
|
17
|
+
Object.defineProperty(this, 'name', {
|
|
18
|
+
value: 'MoneroSweepError',
|
|
19
|
+
writable: false,
|
|
20
|
+
configurable: true,
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=wasm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wasm.js","sourceRoot":"","sources":["../../../src/lib/monero/wasm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAEhD,OAAO,EACL,UAAU,IAAI,iBAAiB,EAC/B,eAAe,EACf,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,gBAAgB,EAChB,aAAa,IAAI,iBAAiB,EAClC,sBAAsB,EACtB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAE3B;;;;;GAKG;AACH,MAAM,OAAO,gBAAiB,SAAQ,SAAS;IAC7C,YAAY,OAAe,EAAE,IAAI,GAAG,gBAAgB,EAAE,KAAe;QACnE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE;YAClC,KAAK,EAAE,kBAAkB;YACzB,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { PowChallenge, PowPayload } from '../types/index.js';
|
|
2
|
+
export declare function solveChallenge(challenge: PowChallenge, onProgress?: (current: number, total: number) => void): Promise<PowPayload>;
|
|
3
|
+
export declare function encodePowHeader(payload: PowPayload): string;
|
|
4
|
+
//# sourceMappingURL=pow-solver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pow-solver.d.ts","sourceRoot":"","sources":["../../src/lib/pow-solver.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAIlE,wBAAsB,cAAc,CAClC,SAAS,EAAE,YAAY,EACvB,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACpD,OAAO,CAAC,UAAU,CAAC,CA0BrB;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,UAAU,GAAG,MAAM,CAE3D"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Proof-of-work solver for swap creation.
|
|
3
|
+
*
|
|
4
|
+
* The server issues a SHA-256 hash-preimage challenge: given a salt and a
|
|
5
|
+
* target hash, find a number n in [0, maxnumber] such that
|
|
6
|
+
* SHA-256(salt + String(n)) === challenge. The solution is sent as a
|
|
7
|
+
* Base64-encoded JSON header on the swap creation request.
|
|
8
|
+
*/
|
|
9
|
+
import { sha256 } from '@noble/hashes/sha2.js';
|
|
10
|
+
import { bytesToHex } from '@noble/hashes/utils.js';
|
|
11
|
+
const BATCH_SIZE = 10_000;
|
|
12
|
+
export async function solveChallenge(challenge, onProgress) {
|
|
13
|
+
const { salt, challenge: target, maxnumber } = challenge;
|
|
14
|
+
for (let start = 0; start <= maxnumber; start += BATCH_SIZE) {
|
|
15
|
+
const end = Math.min(start + BATCH_SIZE, maxnumber + 1);
|
|
16
|
+
for (let n = start; n < end; n++) {
|
|
17
|
+
const hash = bytesToHex(sha256(new TextEncoder().encode(salt + String(n))));
|
|
18
|
+
if (hash === target) {
|
|
19
|
+
return {
|
|
20
|
+
algorithm: challenge.algorithm,
|
|
21
|
+
challenge: target,
|
|
22
|
+
number: n,
|
|
23
|
+
salt,
|
|
24
|
+
signature: challenge.signature,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
onProgress?.(end, maxnumber);
|
|
29
|
+
// Yield to the event loop between batches so the TUI stays responsive
|
|
30
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
31
|
+
}
|
|
32
|
+
throw new Error('PoW solution not found within search space');
|
|
33
|
+
}
|
|
34
|
+
export function encodePowHeader(payload) {
|
|
35
|
+
return btoa(JSON.stringify(payload));
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=pow-solver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pow-solver.js","sourceRoot":"","sources":["../../src/lib/pow-solver.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIpD,MAAM,UAAU,GAAG,MAAM,CAAC;AAE1B,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,SAAuB,EACvB,UAAqD;IAErD,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;IAEzD,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,IAAI,SAAS,EAAE,KAAK,IAAI,UAAU,EAAE,CAAC;QAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,UAAU,EAAE,SAAS,GAAG,CAAC,CAAC,CAAC;QAExD,KAAK,IAAI,CAAC,GAAG,KAAK,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC5E,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;gBACpB,OAAO;oBACL,SAAS,EAAE,SAAS,CAAC,SAAS;oBAC9B,SAAS,EAAE,MAAM;oBACjB,MAAM,EAAE,CAAC;oBACT,IAAI;oBACJ,SAAS,EAAE,SAAS,CAAC,SAAS;iBAC/B,CAAC;YACJ,CAAC;QACH,CAAC;QAED,UAAU,EAAE,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;QAE7B,sEAAsE;QACtE,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,OAAmB;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AACvC,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cross-platform retry helper.
|
|
3
|
+
*
|
|
4
|
+
* Wraps an async operation and retries it according to the {@link ErrorCategory}
|
|
5
|
+
* derived from each thrown value. Network and server errors retry indefinitely
|
|
6
|
+
* with exponential backoff capped at {@link RetryOptions.maxBackoffMs}; bounded
|
|
7
|
+
* categories retry at most {@link RetryOptions.maxBoundedRetries} times before
|
|
8
|
+
* surfacing the error; fatal categories propagate immediately.
|
|
9
|
+
*
|
|
10
|
+
* Cancellation is honoured via an optional {@link AbortSignal}. The signal is
|
|
11
|
+
* checked before every attempt and during every backoff sleep — a caller that
|
|
12
|
+
* aborts mid-retry sees a {@link SwapCancelledError} within ms, never the
|
|
13
|
+
* original failure that triggered the retry.
|
|
14
|
+
*
|
|
15
|
+
* Cross-platform: only `setTimeout` / `clearTimeout` and `AbortSignal` are
|
|
16
|
+
* used. Works in Node 20+ and modern browsers without polyfills.
|
|
17
|
+
*/
|
|
18
|
+
import type { Logger } from '../interfaces/logger.js';
|
|
19
|
+
import { type ErrorCategory } from './errors.js';
|
|
20
|
+
export interface RetryOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Cap on retries for `client-bounded` and `unknown` categories.
|
|
23
|
+
* After this many failures the original error is rethrown.
|
|
24
|
+
* Default: 3.
|
|
25
|
+
*/
|
|
26
|
+
readonly maxBoundedRetries?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Initial backoff in ms. Each subsequent attempt doubles the wait
|
|
29
|
+
* (capped at {@link maxBackoffMs}).
|
|
30
|
+
* Default: 500.
|
|
31
|
+
*/
|
|
32
|
+
readonly baseMs?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Upper bound for the per-retry backoff sleep, in ms. Network / server /
|
|
35
|
+
* rate-limit errors retry indefinitely; this caps how long each successive
|
|
36
|
+
* sleep can grow to before plateauing.
|
|
37
|
+
* Default: 60000 (one minute).
|
|
38
|
+
*/
|
|
39
|
+
readonly maxBackoffMs?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Optional cancellation signal. When aborted, the in-flight wait or the
|
|
42
|
+
* next attempt rejects with {@link SwapCancelledError}.
|
|
43
|
+
*/
|
|
44
|
+
readonly signal?: AbortSignal;
|
|
45
|
+
/** Optional structured logger. Defaults to a no-op. */
|
|
46
|
+
readonly logger?: Logger;
|
|
47
|
+
/**
|
|
48
|
+
* Diagnostic label appended to log lines. Use the call site / endpoint
|
|
49
|
+
* (e.g. `"GET /api/v1/swap/SWP-…"`).
|
|
50
|
+
* Default: `"op"`.
|
|
51
|
+
*/
|
|
52
|
+
readonly label?: string;
|
|
53
|
+
/**
|
|
54
|
+
* Optional override for the classifier. Useful when a caller wants to
|
|
55
|
+
* promote a known transient string to `network`, or treat a 404 as
|
|
56
|
+
* `client-fatal` instead of `client-bounded`.
|
|
57
|
+
*/
|
|
58
|
+
readonly classify?: (err: unknown) => ErrorCategory;
|
|
59
|
+
/**
|
|
60
|
+
* Hook called once per retry, after classification, before backoff. Lets
|
|
61
|
+
* callers integrate with metrics / UI without re-implementing the loop.
|
|
62
|
+
*/
|
|
63
|
+
readonly onRetry?: (info: RetryInfo) => void;
|
|
64
|
+
}
|
|
65
|
+
export interface RetryInfo {
|
|
66
|
+
readonly category: ErrorCategory;
|
|
67
|
+
readonly attempt: number;
|
|
68
|
+
readonly backoffMs: number;
|
|
69
|
+
readonly error: unknown;
|
|
70
|
+
readonly isUnbounded: boolean;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Run `fn` with retries until it succeeds, the signal aborts, or the policy
|
|
74
|
+
* rejects further attempts. Returns the resolved value of the first
|
|
75
|
+
* successful call.
|
|
76
|
+
*
|
|
77
|
+
* @example
|
|
78
|
+
* await withRetry(
|
|
79
|
+
* () => api.executeAction(swapId, { type: 'submit_encsig', tx_redeem_encsig }),
|
|
80
|
+
* { logger, label: 'submit_encsig', signal: engineSignal },
|
|
81
|
+
* );
|
|
82
|
+
*/
|
|
83
|
+
export declare function withRetry<T>(fn: (attempt: number) => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
84
|
+
/** Public for tests / callers that want the same backoff schedule. */
|
|
85
|
+
export declare function computeBackoffMs(retryNumber: number, baseMs: number, maxMs: number): number;
|
|
86
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/lib/retry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,aAAa,CAAC;AAErB,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;;OAKG;IACH,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B;;;OAGG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC;IAC9B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,aAAa,CAAC;IACpD;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE,SAAS,KAAK,IAAI,CAAC;CAC9C;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;CAC/B;AAQD;;;;;;;;;;GAUG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EACnC,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CA2EZ;AAED,sEAAsE;AACtE,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAI3F"}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { noopLogger } from '../interfaces/logger.js';
|
|
2
|
+
import { SwapCancelledError, classifyError, errorMessage, } from './errors.js';
|
|
3
|
+
const DEFAULT_MAX_BOUNDED = 3;
|
|
4
|
+
const DEFAULT_BASE_MS = 500;
|
|
5
|
+
const DEFAULT_MAX_BACKOFF_MS = 60_000;
|
|
6
|
+
/** Cap the exponent so `2 ** n` cannot overflow `Number` after a long retry chain. */
|
|
7
|
+
const MAX_EXPONENT = 30;
|
|
8
|
+
/**
|
|
9
|
+
* Run `fn` with retries until it succeeds, the signal aborts, or the policy
|
|
10
|
+
* rejects further attempts. Returns the resolved value of the first
|
|
11
|
+
* successful call.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* await withRetry(
|
|
15
|
+
* () => api.executeAction(swapId, { type: 'submit_encsig', tx_redeem_encsig }),
|
|
16
|
+
* { logger, label: 'submit_encsig', signal: engineSignal },
|
|
17
|
+
* );
|
|
18
|
+
*/
|
|
19
|
+
export async function withRetry(fn, options = {}) {
|
|
20
|
+
const maxBounded = options.maxBoundedRetries ?? DEFAULT_MAX_BOUNDED;
|
|
21
|
+
const baseMs = options.baseMs ?? DEFAULT_BASE_MS;
|
|
22
|
+
const maxBackoffMs = options.maxBackoffMs ?? DEFAULT_MAX_BACKOFF_MS;
|
|
23
|
+
const log = options.logger ?? noopLogger;
|
|
24
|
+
const label = options.label ?? 'op';
|
|
25
|
+
const classify = options.classify ?? classifyError;
|
|
26
|
+
let unboundedRetries = 0;
|
|
27
|
+
let boundedRetries = 0;
|
|
28
|
+
let attempt = 0;
|
|
29
|
+
while (true) {
|
|
30
|
+
if (options.signal?.aborted)
|
|
31
|
+
throw new SwapCancelledError();
|
|
32
|
+
try {
|
|
33
|
+
return await fn(attempt);
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
attempt++;
|
|
37
|
+
const category = classify(err);
|
|
38
|
+
if (category === 'cancelled' ||
|
|
39
|
+
category === 'protocol' ||
|
|
40
|
+
category === 'verification' ||
|
|
41
|
+
category === 'client-fatal') {
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
const isUnbounded = category === 'network' || category === 'server';
|
|
45
|
+
if (isUnbounded) {
|
|
46
|
+
unboundedRetries++;
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// 'rate-limit' | 'client-bounded' | 'unknown'
|
|
50
|
+
boundedRetries++;
|
|
51
|
+
if (boundedRetries > maxBounded) {
|
|
52
|
+
log.warn({
|
|
53
|
+
label,
|
|
54
|
+
attempts: boundedRetries,
|
|
55
|
+
category,
|
|
56
|
+
error: errorMessage(err),
|
|
57
|
+
}, `${label}: bounded retry exhausted, surfacing error`);
|
|
58
|
+
throw err;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const totalRetries = unboundedRetries + boundedRetries;
|
|
62
|
+
const backoffMs = computeBackoffMs(totalRetries, baseMs, maxBackoffMs);
|
|
63
|
+
log.warn({
|
|
64
|
+
label,
|
|
65
|
+
attempt: totalRetries,
|
|
66
|
+
category,
|
|
67
|
+
backoffMs,
|
|
68
|
+
error: errorMessage(err),
|
|
69
|
+
}, `${label}: retrying after ${String(backoffMs)}ms`);
|
|
70
|
+
options.onRetry?.({
|
|
71
|
+
category,
|
|
72
|
+
attempt: totalRetries,
|
|
73
|
+
backoffMs,
|
|
74
|
+
error: err,
|
|
75
|
+
isUnbounded,
|
|
76
|
+
});
|
|
77
|
+
await sleepWithSignal(backoffMs, options.signal);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Public for tests / callers that want the same backoff schedule. */
|
|
82
|
+
export function computeBackoffMs(retryNumber, baseMs, maxMs) {
|
|
83
|
+
if (retryNumber <= 0)
|
|
84
|
+
return 0;
|
|
85
|
+
const exp = baseMs * 2 ** Math.min(retryNumber - 1, MAX_EXPONENT);
|
|
86
|
+
return Math.min(exp, maxMs);
|
|
87
|
+
}
|
|
88
|
+
async function sleepWithSignal(ms, signal) {
|
|
89
|
+
if (ms <= 0)
|
|
90
|
+
return;
|
|
91
|
+
if (signal?.aborted)
|
|
92
|
+
throw new SwapCancelledError();
|
|
93
|
+
return new Promise((resolve, reject) => {
|
|
94
|
+
const timer = setTimeout(resolve, ms);
|
|
95
|
+
if (signal === undefined)
|
|
96
|
+
return;
|
|
97
|
+
const onAbort = () => {
|
|
98
|
+
clearTimeout(timer);
|
|
99
|
+
reject(new SwapCancelledError());
|
|
100
|
+
};
|
|
101
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/lib/retry.ts"],"names":[],"mappings":"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"}
|