@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,91 @@
|
|
|
1
|
+
import { noopLogger } from '../interfaces/logger.js';
|
|
2
|
+
import { VerificationError } from '../types/index.js';
|
|
3
|
+
import { verifyAtomicSwap } from './atomic-swap.js';
|
|
4
|
+
import { verifyThorchain } from './thorchain.js';
|
|
5
|
+
import { verifyChainflip } from './chainflip.js';
|
|
6
|
+
import { verifyNearIntents } from './near-intents.js';
|
|
7
|
+
import { check } from './shared.js';
|
|
8
|
+
export { parseThorchainMemo, requireMemoBindsDestination } from './memo.js';
|
|
9
|
+
export { verifyAtomicSwap, verifyThorchain, verifyChainflip, verifyNearIntents };
|
|
10
|
+
export { fetchThorchainVaults, verifyThorchainQuote } from './thorchain.js';
|
|
11
|
+
export { verifyChainflipChannel } from './chainflip.js';
|
|
12
|
+
export { CHAINFLIP_VERIFICATION_NETWORKS, chainflipEndpointsForNetwork, } from './chainflip-networks.js';
|
|
13
|
+
export { THORCHAIN_VERIFICATION_NETWORKS, thorchainEndpointsForNetwork, } from './thorchain-networks.js';
|
|
14
|
+
export { fetchNearIntentStatus, requireIntentBinds, requireIntentDeadlineMargin, verifyNearIntentOnChain, } from './near-intents.js';
|
|
15
|
+
export { fetchConsensusRate } from './rate-oracle.js';
|
|
16
|
+
export { VERIFY_FETCH_TIMEOUT_MS, VERIFY_MAX_ATTEMPTS, VERIFY_RETRY_DELAY_MS } from './constants.js';
|
|
17
|
+
/**
|
|
18
|
+
* Verify a deposit address against the authoritative infrastructure for its
|
|
19
|
+
* provider. Common client-side checks (address presence, output amount,
|
|
20
|
+
* destination match) run for every provider.
|
|
21
|
+
*
|
|
22
|
+
* @throws {VerificationError} `E_PROVIDER_UNKNOWN` for an unrecognised
|
|
23
|
+
* provider; `E_UNEXPECTED_TIMELOCK` when `timelock_blocks` is set for a
|
|
24
|
+
* non-atomicswap provider.
|
|
25
|
+
*/
|
|
26
|
+
export async function verifyDepositAddress(params) {
|
|
27
|
+
const { depositAddress, verification, destAddress, refundAddress, toToken, amount, fromChain, toChain, fromToken, network = 'mainnet', protocol, expectedAmountOut, expectedDestAddress, fetchFn = globalThis.fetch, resume, logger = noopLogger, signal, } = params;
|
|
28
|
+
const verifyParams = {
|
|
29
|
+
destAddress,
|
|
30
|
+
refundAddress,
|
|
31
|
+
toToken,
|
|
32
|
+
amount,
|
|
33
|
+
fromChain,
|
|
34
|
+
toChain,
|
|
35
|
+
fromToken,
|
|
36
|
+
};
|
|
37
|
+
// AV-A.13 scope: timelock_blocks is only meaningful for atomicswap. If
|
|
38
|
+
// any other provider carries one, it's a client-side bug or a server
|
|
39
|
+
// confusion attempt — reject loudly.
|
|
40
|
+
if (verification.provider !== 'atomicswap' && protocol?.timelock_blocks !== undefined) {
|
|
41
|
+
throw new VerificationError('E_UNEXPECTED_TIMELOCK', `timelock_blocks is set for non-atomicswap provider ${verification.provider}`);
|
|
42
|
+
}
|
|
43
|
+
let providerResult;
|
|
44
|
+
switch (verification.provider) {
|
|
45
|
+
case 'thorchain':
|
|
46
|
+
providerResult = await verifyThorchain(depositAddress, verification, verifyParams, fetchFn, network, resume, signal);
|
|
47
|
+
break;
|
|
48
|
+
case 'chainflip':
|
|
49
|
+
providerResult = await verifyChainflip(depositAddress, verification, verifyParams, fetchFn, network, signal);
|
|
50
|
+
break;
|
|
51
|
+
case 'near_intents':
|
|
52
|
+
providerResult = await verifyNearIntents(verification, fetchFn, signal);
|
|
53
|
+
break;
|
|
54
|
+
case 'atomicswap':
|
|
55
|
+
providerResult = verifyAtomicSwap(verification, verifyParams, protocol);
|
|
56
|
+
break;
|
|
57
|
+
default: {
|
|
58
|
+
const unknown = verification;
|
|
59
|
+
throw new VerificationError('E_PROVIDER_UNKNOWN', `unknown provider: ${String(unknown.provider)}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const clientChecks = [];
|
|
63
|
+
clientChecks.push(check('Deposit address', !!depositAddress && depositAddress.length > 5, depositAddress ? `${depositAddress.slice(0, 12)}...` : 'Missing'));
|
|
64
|
+
if (expectedAmountOut) {
|
|
65
|
+
const amt = parseFloat(expectedAmountOut);
|
|
66
|
+
clientChecks.push(check('Output amount', amt > 0, `${expectedAmountOut} ${toToken}`));
|
|
67
|
+
}
|
|
68
|
+
if (expectedDestAddress) {
|
|
69
|
+
const match = expectedDestAddress === destAddress;
|
|
70
|
+
const truncDest = expectedDestAddress.length > 20
|
|
71
|
+
? `${expectedDestAddress.slice(0, 6)}...${expectedDestAddress.slice(-6)}`
|
|
72
|
+
: expectedDestAddress;
|
|
73
|
+
clientChecks.push(check('Destination address', match, match ? truncDest : `MISMATCH: ${truncDest}`));
|
|
74
|
+
}
|
|
75
|
+
const allChecks = [...providerResult.checks, ...clientChecks];
|
|
76
|
+
const verified = allChecks.every((c) => c.passed);
|
|
77
|
+
const failed = allChecks.filter((c) => !c.passed).map((c) => c.name);
|
|
78
|
+
if (verified) {
|
|
79
|
+
logger.info({ provider: providerResult.provider, checks: allChecks.length }, 'Verification passed');
|
|
80
|
+
}
|
|
81
|
+
else {
|
|
82
|
+
logger.warn({ provider: providerResult.provider, failed }, 'Verification failed');
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
verified,
|
|
86
|
+
provider: providerResult.provider,
|
|
87
|
+
checks: allChecks,
|
|
88
|
+
timestamp: Date.now(),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/verification/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export interface ParsedThorchainMemo {
|
|
2
|
+
readonly asset: string;
|
|
3
|
+
readonly destAddress: string;
|
|
4
|
+
readonly minOut?: bigint;
|
|
5
|
+
readonly streamingInterval?: number;
|
|
6
|
+
readonly streamingQuantity?: number;
|
|
7
|
+
readonly affiliate?: string;
|
|
8
|
+
readonly affiliateFeeBps?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parse a THORChain memo string. Accepts `SWAP:`, `=:`, and `s:` prefixes
|
|
12
|
+
* followed by asset, destination, optional min-out (either a plain integer
|
|
13
|
+
* or the streaming form `LIMIT/INTERVAL/QUANTITY`), optional affiliate,
|
|
14
|
+
* optional affiliate fee in bps.
|
|
15
|
+
*
|
|
16
|
+
* @throws {VerificationError} `E_MEMO_MALFORMED` when the memo does not
|
|
17
|
+
* match the canonical ABI.
|
|
18
|
+
*/
|
|
19
|
+
export declare function parseThorchainMemo(memo: string): ParsedThorchainMemo;
|
|
20
|
+
/**
|
|
21
|
+
* Assert the parsed memo's destination field equals the expected address.
|
|
22
|
+
*
|
|
23
|
+
* @throws {VerificationError} `E_MEMO_DEST_MISMATCH` on mismatch.
|
|
24
|
+
* @throws {VerificationError} `E_MEMO_MALFORMED` if the memo fails to parse.
|
|
25
|
+
*/
|
|
26
|
+
export declare function requireMemoBindsDestination(memo: string, expectedDestAddress: string): void;
|
|
27
|
+
//# sourceMappingURL=memo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memo.d.ts","sourceRoot":"","sources":["../../src/verification/memo.ts"],"names":[],"mappings":"AAiBA,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAepE;AAED;;;;;GAKG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAQ3F"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THORChain memo parsing and strict binding.
|
|
3
|
+
*
|
|
4
|
+
* Old code used `memo.includes(destAddress)` which matches any memo where the
|
|
5
|
+
* destination address is a substring. An attacker-controlled memo of the form
|
|
6
|
+
* `SWAP:ETH.ETH:0xATTACKER:0:affid_<USER_ADDR>:10` would pass that check.
|
|
7
|
+
*
|
|
8
|
+
* The strict parser matches the THORChain memo ABI and compares the
|
|
9
|
+
* destination field only.
|
|
10
|
+
*
|
|
11
|
+
* @security Closes AV-A.14 variant / AV-K.6.
|
|
12
|
+
*/
|
|
13
|
+
import { VerificationError } from '../types/index.js';
|
|
14
|
+
const THORCHAIN_MEMO_RE = /^(?:SWAP|=|s):([A-Z0-9./-]+):([A-Za-z0-9_./]+)(?::(\d+)(?:\/(\d+)\/(\d+))?)?(?::([A-Za-z0-9]+))?(?::(\d+))?$/;
|
|
15
|
+
/**
|
|
16
|
+
* Parse a THORChain memo string. Accepts `SWAP:`, `=:`, and `s:` prefixes
|
|
17
|
+
* followed by asset, destination, optional min-out (either a plain integer
|
|
18
|
+
* or the streaming form `LIMIT/INTERVAL/QUANTITY`), optional affiliate,
|
|
19
|
+
* optional affiliate fee in bps.
|
|
20
|
+
*
|
|
21
|
+
* @throws {VerificationError} `E_MEMO_MALFORMED` when the memo does not
|
|
22
|
+
* match the canonical ABI.
|
|
23
|
+
*/
|
|
24
|
+
export function parseThorchainMemo(memo) {
|
|
25
|
+
const match = memo.trim().match(THORCHAIN_MEMO_RE);
|
|
26
|
+
if (!match) {
|
|
27
|
+
throw new VerificationError('E_MEMO_MALFORMED', `memo does not parse: ${memo}`);
|
|
28
|
+
}
|
|
29
|
+
const [, asset = '', destAddress = '', minOut, streamingInterval, streamingQuantity, affiliate, feeBps] = match;
|
|
30
|
+
return {
|
|
31
|
+
asset,
|
|
32
|
+
destAddress,
|
|
33
|
+
minOut: minOut !== undefined ? BigInt(minOut) : undefined,
|
|
34
|
+
streamingInterval: streamingInterval !== undefined ? Number(streamingInterval) : undefined,
|
|
35
|
+
streamingQuantity: streamingQuantity !== undefined ? Number(streamingQuantity) : undefined,
|
|
36
|
+
affiliate,
|
|
37
|
+
affiliateFeeBps: feeBps !== undefined ? Number(feeBps) : undefined,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Assert the parsed memo's destination field equals the expected address.
|
|
42
|
+
*
|
|
43
|
+
* @throws {VerificationError} `E_MEMO_DEST_MISMATCH` on mismatch.
|
|
44
|
+
* @throws {VerificationError} `E_MEMO_MALFORMED` if the memo fails to parse.
|
|
45
|
+
*/
|
|
46
|
+
export function requireMemoBindsDestination(memo, expectedDestAddress) {
|
|
47
|
+
const parsed = parseThorchainMemo(memo);
|
|
48
|
+
if (parsed.destAddress !== expectedDestAddress) {
|
|
49
|
+
throw new VerificationError('E_MEMO_DEST_MISMATCH', `memo destination ${parsed.destAddress} differs from expected ${expectedDestAddress}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=memo.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memo.js","sourceRoot":"","sources":["../../src/verification/memo.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD,MAAM,iBAAiB,GACrB,8GAA8G,CAAC;AAYjH;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAY;IAC7C,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,iBAAiB,CAAC,kBAAkB,EAAE,wBAAwB,IAAI,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,MAAM,CAAC,EAAE,KAAK,GAAG,EAAE,EAAE,WAAW,GAAG,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC;IAChH,OAAO;QACL,KAAK;QACL,WAAW;QACX,MAAM,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;QACzD,iBAAiB,EAAE,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS;QAC1F,iBAAiB,EAAE,iBAAiB,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAAS;QAC1F,SAAS;QACT,eAAe,EAAE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS;KACnE,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,2BAA2B,CAAC,IAAY,EAAE,mBAA2B;IACnF,MAAM,MAAM,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,MAAM,CAAC,WAAW,KAAK,mBAAmB,EAAE,CAAC;QAC/C,MAAM,IAAI,iBAAiB,CACzB,sBAAsB,EACtB,oBAAoB,MAAM,CAAC,WAAW,0BAA0B,mBAAmB,EAAE,CACtF,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type { NearIntentsVerification, VerificationResult } from '../types/index.js';
|
|
2
|
+
import { type NearIntentStatusResponse } from '../wire/near-intents.zod.js';
|
|
3
|
+
/**
|
|
4
|
+
* Verify a NEAR-Intents deposit address against the 1Click status endpoint.
|
|
5
|
+
* Uses an explicit status enum switch (no `!== 'NOT_FOUND'` substring).
|
|
6
|
+
*/
|
|
7
|
+
export declare function verifyNearIntents(v: NearIntentsVerification, fetchFn: typeof globalThis.fetch, externalSignal?: AbortSignal): Promise<VerificationResult>;
|
|
8
|
+
export interface FetchNearIntentStatusInput {
|
|
9
|
+
readonly statusUrl: string;
|
|
10
|
+
readonly fetchFn: typeof globalThis.fetch;
|
|
11
|
+
readonly timeoutMs?: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Fetch 1Click `/v0/status` and return a flattened intent view. Performs an
|
|
15
|
+
* exhaustive enum switch over the 7 real status values.
|
|
16
|
+
*
|
|
17
|
+
* Mapping of HTTP / status to error codes:
|
|
18
|
+
* - HTTP 404 → `E_NEAR_INTENT_NOT_REGISTERED` (deposit address unknown to 1Click)
|
|
19
|
+
* - HTTP non-2xx (non-404) → `E_NEAR_INTENT_FAILED` (network / server error)
|
|
20
|
+
* - status === 'FAILED' → `E_NEAR_INTENT_FAILED`
|
|
21
|
+
* - status in {PENDING_DEPOSIT, KNOWN_DEPOSIT_TX, INCOMPLETE_DEPOSIT,
|
|
22
|
+
* PROCESSING, SUCCESS, REFUNDED} → returns the flattened response.
|
|
23
|
+
*
|
|
24
|
+
* 1Click does not surface an "EXPIRED" status. Past-deadline detection is
|
|
25
|
+
* performed via `requireIntentDeadlineMargin` against `quote.deadline`.
|
|
26
|
+
*
|
|
27
|
+
* @throws {VerificationError} `E_NEAR_INTENT_NOT_REGISTERED` on HTTP 404.
|
|
28
|
+
* @throws {VerificationError} `E_NEAR_INTENT_FAILED` on HTTP error or
|
|
29
|
+
* `status === 'FAILED'`.
|
|
30
|
+
*/
|
|
31
|
+
export declare function fetchNearIntentStatus(input: FetchNearIntentStatusInput): Promise<NearIntentStatusResponse>;
|
|
32
|
+
export interface RequireIntentBindsInput {
|
|
33
|
+
readonly destinationAddress: string;
|
|
34
|
+
/**
|
|
35
|
+
* Optional 1Click destination-asset ID (e.g.
|
|
36
|
+
* `nep141:eth-0xa0b8…omft.near`). Pass it to assert the intent really
|
|
37
|
+
* targets the destination chain you expect — 1Click's `/v0/status`
|
|
38
|
+
* exposes the chain only inside this asset ID, not as a separate field.
|
|
39
|
+
*/
|
|
40
|
+
readonly destinationAssetId?: string;
|
|
41
|
+
readonly refundAddress?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Assert the returned intent binds the caller's expected destination address,
|
|
45
|
+
* destination asset, and (optional) refund address.
|
|
46
|
+
*
|
|
47
|
+
* @throws {VerificationError} `E_NEAR_INTENT_MISBINDING` on any mismatch.
|
|
48
|
+
*/
|
|
49
|
+
export declare function requireIntentBinds(intent: NearIntentStatusResponse, expected: RequireIntentBindsInput): void;
|
|
50
|
+
/**
|
|
51
|
+
* Enforce the quote deadline has at least the safety margin (90 min) before
|
|
52
|
+
* it expires relative to `Date.now()`. The deadline lives at
|
|
53
|
+
* `quoteResponse.quote.deadline` in the raw 1Click response and is surfaced
|
|
54
|
+
* as `intent.deadline` after flattening.
|
|
55
|
+
*
|
|
56
|
+
* Returns silently if `intent.deadline` is null (1Click's dry-run quotes
|
|
57
|
+
* omit the deadline; we cannot enforce expiry against an absent value).
|
|
58
|
+
*
|
|
59
|
+
* @throws {VerificationError} `E_NEAR_INTENT_EXPIRING` when the deadline is
|
|
60
|
+
* sooner than the safety margin.
|
|
61
|
+
*/
|
|
62
|
+
export declare function requireIntentDeadlineMargin(intent: NearIntentStatusResponse): void;
|
|
63
|
+
export interface VerifyNearIntentOnChainInput {
|
|
64
|
+
readonly intentHash: string;
|
|
65
|
+
readonly expected: {
|
|
66
|
+
readonly destinationAddress: string;
|
|
67
|
+
readonly expectedOutputAmount: string;
|
|
68
|
+
};
|
|
69
|
+
readonly nearRpcUrl: string;
|
|
70
|
+
readonly fetchFn: typeof globalThis.fetch;
|
|
71
|
+
readonly timeoutMs?: number;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* **Direct-blockchain near-intents only — NOT for 1Click swaps.**
|
|
75
|
+
*
|
|
76
|
+
* Queries the NEAR contract `intents.near` via JSON-RPC `get_intent` and
|
|
77
|
+
* cross-checks that an intent hash binds the expected destination + amount.
|
|
78
|
+
* This is the verification path for swaps that go through the solver-relay
|
|
79
|
+
* directly. 1Click swaps do not surface usable on-chain intent hashes
|
|
80
|
+
* suitable for this query — for 1Click, use `fetchNearIntentStatus` +
|
|
81
|
+
* `requireIntentBinds` against the `/v0/status` URL instead.
|
|
82
|
+
*
|
|
83
|
+
* Kept available for a future direct-blockchain near_intents provider
|
|
84
|
+
* (`packages/miradex-client/src/...` / `daemons/near/`).
|
|
85
|
+
*
|
|
86
|
+
* @throws {VerificationError} `E_NEAR_INTENT_FAILED` on RPC error.
|
|
87
|
+
* @throws {VerificationError} `E_NEAR_INTENT_CHAIN_DEST` on destination mismatch.
|
|
88
|
+
* @throws {VerificationError} `E_NEAR_INTENT_CHAIN_AMOUNT` on amount mismatch.
|
|
89
|
+
*/
|
|
90
|
+
export declare function verifyNearIntentOnChain(input: VerifyNearIntentOnChainInput): Promise<void>;
|
|
91
|
+
//# sourceMappingURL=near-intents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"near-intents.d.ts","sourceRoot":"","sources":["../../src/verification/near-intents.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAqB,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAGxG,OAAO,EAIL,KAAK,wBAAwB,EAC9B,MAAM,6BAA6B,CAAC;AAkBrC;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,CAAC,EAAE,uBAAuB,EAC1B,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,EAChC,cAAc,CAAC,EAAE,WAAW,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CA2C7B;AAED,MAAM,WAAW,0BAA0B;IACzC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,qBAAqB,CACzC,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,wBAAwB,CAAC,CAoDnC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC;;;;;OAKG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IACrC,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;CACjC;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,wBAAwB,EAChC,QAAQ,EAAE,uBAAuB,GAChC,IAAI,CAyBN;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,wBAAwB,GAC/B,IAAI,CAWN;AAED,MAAM,WAAW,4BAA4B;IAC3C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,QAAQ,EAAE;QAAE,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,oBAAoB,EAAE,MAAM,CAAA;KAAE,CAAC;IAClG,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,4BAA4B,GAClC,OAAO,CAAC,IAAI,CAAC,CA4Cf"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { check, errMsg, failOf, resultOf } from './shared.js';
|
|
2
|
+
import { VerificationError } from '../types/index.js';
|
|
3
|
+
import { NearIntentRawStatusSchema, NearIntentOnChainSchema, NearRpcResponseSchema, } from '../wire/near-intents.zod.js';
|
|
4
|
+
import { VERIFY_FETCH_TIMEOUT_MS } from './constants.js';
|
|
5
|
+
// Mirrors the canonical 1Click status enum (7 values). INCOMPLETE_DEPOSIT
|
|
6
|
+
// means "deposit observed but below bridge minimum"; from a verification
|
|
7
|
+
// standpoint the intent is registered and the address is real, so it counts
|
|
8
|
+
// as active. Source: 1Click OpenAPI v0.1.10 + live captures.
|
|
9
|
+
const ACTIVE_STATUSES = [
|
|
10
|
+
'PENDING_DEPOSIT',
|
|
11
|
+
'KNOWN_DEPOSIT_TX',
|
|
12
|
+
'INCOMPLETE_DEPOSIT',
|
|
13
|
+
'PROCESSING',
|
|
14
|
+
'SUCCESS',
|
|
15
|
+
'REFUNDED',
|
|
16
|
+
];
|
|
17
|
+
const INTENT_DEADLINE_MARGIN_MS = 90 * 60 * 1000;
|
|
18
|
+
/**
|
|
19
|
+
* Verify a NEAR-Intents deposit address against the 1Click status endpoint.
|
|
20
|
+
* Uses an explicit status enum switch (no `!== 'NOT_FOUND'` substring).
|
|
21
|
+
*/
|
|
22
|
+
export async function verifyNearIntents(v, fetchFn, externalSignal) {
|
|
23
|
+
const checks = [];
|
|
24
|
+
// Server schema permits a null status_url (e.g. when the engine declines to
|
|
25
|
+
// emit a public-clickable URL). Without one we cannot run the live check —
|
|
26
|
+
// surface that explicitly rather than calling fetch() on null.
|
|
27
|
+
if (!v.status_url) {
|
|
28
|
+
return failOf('near_intents', [
|
|
29
|
+
check('NEAR reachable', false, 'No public status URL available'),
|
|
30
|
+
]);
|
|
31
|
+
}
|
|
32
|
+
try {
|
|
33
|
+
const res = await fetchFn(v.status_url, {
|
|
34
|
+
signal: externalSignal !== undefined
|
|
35
|
+
? AbortSignal.any([AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS), externalSignal])
|
|
36
|
+
: AbortSignal.timeout(VERIFY_FETCH_TIMEOUT_MS),
|
|
37
|
+
});
|
|
38
|
+
if (!res.ok) {
|
|
39
|
+
return failOf('near_intents', [check('NEAR reachable', false, `HTTP ${res.status}`)]);
|
|
40
|
+
}
|
|
41
|
+
const rawNear = await res.json();
|
|
42
|
+
if (typeof rawNear !== 'object' || rawNear === null) {
|
|
43
|
+
return failOf('near_intents', [check('NEAR response', false, 'Expected object')]);
|
|
44
|
+
}
|
|
45
|
+
const data = rawNear;
|
|
46
|
+
checks.push(check('NEAR reachable', true, 'Status endpoint responded'));
|
|
47
|
+
const status = data.status;
|
|
48
|
+
const registered = typeof status === 'string' && ACTIVE_STATUSES.includes(status);
|
|
49
|
+
checks.push(check('Intent registered', registered, registered ? `Status: ${status}` : `Status: ${status ?? 'unknown'}`));
|
|
50
|
+
}
|
|
51
|
+
catch (err) {
|
|
52
|
+
checks.push(check('NEAR verification', false, errMsg(err)));
|
|
53
|
+
}
|
|
54
|
+
return resultOf('near_intents', checks);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Fetch 1Click `/v0/status` and return a flattened intent view. Performs an
|
|
58
|
+
* exhaustive enum switch over the 7 real status values.
|
|
59
|
+
*
|
|
60
|
+
* Mapping of HTTP / status to error codes:
|
|
61
|
+
* - HTTP 404 → `E_NEAR_INTENT_NOT_REGISTERED` (deposit address unknown to 1Click)
|
|
62
|
+
* - HTTP non-2xx (non-404) → `E_NEAR_INTENT_FAILED` (network / server error)
|
|
63
|
+
* - status === 'FAILED' → `E_NEAR_INTENT_FAILED`
|
|
64
|
+
* - status in {PENDING_DEPOSIT, KNOWN_DEPOSIT_TX, INCOMPLETE_DEPOSIT,
|
|
65
|
+
* PROCESSING, SUCCESS, REFUNDED} → returns the flattened response.
|
|
66
|
+
*
|
|
67
|
+
* 1Click does not surface an "EXPIRED" status. Past-deadline detection is
|
|
68
|
+
* performed via `requireIntentDeadlineMargin` against `quote.deadline`.
|
|
69
|
+
*
|
|
70
|
+
* @throws {VerificationError} `E_NEAR_INTENT_NOT_REGISTERED` on HTTP 404.
|
|
71
|
+
* @throws {VerificationError} `E_NEAR_INTENT_FAILED` on HTTP error or
|
|
72
|
+
* `status === 'FAILED'`.
|
|
73
|
+
*/
|
|
74
|
+
export async function fetchNearIntentStatus(input) {
|
|
75
|
+
const timeoutMs = input.timeoutMs ?? VERIFY_FETCH_TIMEOUT_MS;
|
|
76
|
+
const res = await input.fetchFn(input.statusUrl, { signal: AbortSignal.timeout(timeoutMs) });
|
|
77
|
+
if (res.status === 404) {
|
|
78
|
+
throw new VerificationError('E_NEAR_INTENT_NOT_REGISTERED', 'deposit address unknown to 1Click (HTTP 404)');
|
|
79
|
+
}
|
|
80
|
+
if (!res.ok) {
|
|
81
|
+
throw new VerificationError('E_NEAR_INTENT_FAILED', `HTTP ${String(res.status)}`);
|
|
82
|
+
}
|
|
83
|
+
const raw = await res.json();
|
|
84
|
+
const parsed = NearIntentRawStatusSchema.parse(raw);
|
|
85
|
+
if (parsed.status === 'FAILED') {
|
|
86
|
+
throw new VerificationError('E_NEAR_INTENT_FAILED', `intent failed on 1Click${parsed.swapDetails.refundReason ? ` (${parsed.swapDetails.refundReason})` : ''}`);
|
|
87
|
+
}
|
|
88
|
+
// Flatten the nested response. The user-visible binding fields live under
|
|
89
|
+
// `quoteResponse.quoteRequest` (recipient, refundTo, originAsset, …) and
|
|
90
|
+
// `quoteResponse.quote` (depositAddress, depositMemo, deadline, amounts).
|
|
91
|
+
const qr = parsed.quoteResponse;
|
|
92
|
+
const request = qr?.quoteRequest ?? {};
|
|
93
|
+
const quote = qr?.quote;
|
|
94
|
+
const recipient = typeof request.recipient === 'string' ? request.recipient : null;
|
|
95
|
+
const refundTo = typeof request.refundTo === 'string' ? request.refundTo : null;
|
|
96
|
+
const destinationAsset = typeof request.destinationAsset === 'string' ? request.destinationAsset : null;
|
|
97
|
+
return {
|
|
98
|
+
status: parsed.status,
|
|
99
|
+
correlationId: parsed.correlationId,
|
|
100
|
+
updatedAt: parsed.updatedAt,
|
|
101
|
+
depositAddress: quote?.depositAddress ?? null,
|
|
102
|
+
depositMemo: quote?.depositMemo ?? null,
|
|
103
|
+
destinationAddress: recipient,
|
|
104
|
+
destinationAssetId: destinationAsset,
|
|
105
|
+
refundAddress: refundTo,
|
|
106
|
+
deadline: quote?.deadline ?? null,
|
|
107
|
+
expectedOutputAmount: quote?.amountOut ?? null,
|
|
108
|
+
actualOutputAmount: parsed.swapDetails.amountOut ?? null,
|
|
109
|
+
intentHash: parsed.swapDetails.intentHashes[0] ?? null,
|
|
110
|
+
originTxHashes: parsed.swapDetails.originChainTxHashes.map((t) => t.hash),
|
|
111
|
+
destinationTxHashes: parsed.swapDetails.destinationChainTxHashes.map((t) => t.hash),
|
|
112
|
+
refundReason: parsed.swapDetails.refundReason ?? null,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Assert the returned intent binds the caller's expected destination address,
|
|
117
|
+
* destination asset, and (optional) refund address.
|
|
118
|
+
*
|
|
119
|
+
* @throws {VerificationError} `E_NEAR_INTENT_MISBINDING` on any mismatch.
|
|
120
|
+
*/
|
|
121
|
+
export function requireIntentBinds(intent, expected) {
|
|
122
|
+
if (intent.destinationAddress !== expected.destinationAddress) {
|
|
123
|
+
throw new VerificationError('E_NEAR_INTENT_MISBINDING', `intent destination ${String(intent.destinationAddress)} != expected ${expected.destinationAddress}`);
|
|
124
|
+
}
|
|
125
|
+
if (expected.destinationAssetId !== undefined &&
|
|
126
|
+
intent.destinationAssetId !== expected.destinationAssetId) {
|
|
127
|
+
throw new VerificationError('E_NEAR_INTENT_MISBINDING', `intent destinationAsset ${String(intent.destinationAssetId)} != expected ${expected.destinationAssetId}`);
|
|
128
|
+
}
|
|
129
|
+
if (expected.refundAddress !== undefined &&
|
|
130
|
+
intent.refundAddress !== expected.refundAddress) {
|
|
131
|
+
throw new VerificationError('E_NEAR_INTENT_MISBINDING', `intent refund ${String(intent.refundAddress)} != expected ${expected.refundAddress}`);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Enforce the quote deadline has at least the safety margin (90 min) before
|
|
136
|
+
* it expires relative to `Date.now()`. The deadline lives at
|
|
137
|
+
* `quoteResponse.quote.deadline` in the raw 1Click response and is surfaced
|
|
138
|
+
* as `intent.deadline` after flattening.
|
|
139
|
+
*
|
|
140
|
+
* Returns silently if `intent.deadline` is null (1Click's dry-run quotes
|
|
141
|
+
* omit the deadline; we cannot enforce expiry against an absent value).
|
|
142
|
+
*
|
|
143
|
+
* @throws {VerificationError} `E_NEAR_INTENT_EXPIRING` when the deadline is
|
|
144
|
+
* sooner than the safety margin.
|
|
145
|
+
*/
|
|
146
|
+
export function requireIntentDeadlineMargin(intent) {
|
|
147
|
+
if (intent.deadline === null)
|
|
148
|
+
return;
|
|
149
|
+
const deadlineMs = new Date(intent.deadline).getTime();
|
|
150
|
+
if (Number.isNaN(deadlineMs))
|
|
151
|
+
return;
|
|
152
|
+
const remaining = deadlineMs - Date.now();
|
|
153
|
+
if (remaining < INTENT_DEADLINE_MARGIN_MS) {
|
|
154
|
+
throw new VerificationError('E_NEAR_INTENT_EXPIRING', `intent deadline in ${(remaining / 60_000).toFixed(1)} minutes, below safety margin`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* **Direct-blockchain near-intents only — NOT for 1Click swaps.**
|
|
159
|
+
*
|
|
160
|
+
* Queries the NEAR contract `intents.near` via JSON-RPC `get_intent` and
|
|
161
|
+
* cross-checks that an intent hash binds the expected destination + amount.
|
|
162
|
+
* This is the verification path for swaps that go through the solver-relay
|
|
163
|
+
* directly. 1Click swaps do not surface usable on-chain intent hashes
|
|
164
|
+
* suitable for this query — for 1Click, use `fetchNearIntentStatus` +
|
|
165
|
+
* `requireIntentBinds` against the `/v0/status` URL instead.
|
|
166
|
+
*
|
|
167
|
+
* Kept available for a future direct-blockchain near_intents provider
|
|
168
|
+
* (`packages/miradex-client/src/...` / `daemons/near/`).
|
|
169
|
+
*
|
|
170
|
+
* @throws {VerificationError} `E_NEAR_INTENT_FAILED` on RPC error.
|
|
171
|
+
* @throws {VerificationError} `E_NEAR_INTENT_CHAIN_DEST` on destination mismatch.
|
|
172
|
+
* @throws {VerificationError} `E_NEAR_INTENT_CHAIN_AMOUNT` on amount mismatch.
|
|
173
|
+
*/
|
|
174
|
+
export async function verifyNearIntentOnChain(input) {
|
|
175
|
+
const timeoutMs = input.timeoutMs ?? VERIFY_FETCH_TIMEOUT_MS;
|
|
176
|
+
const body = {
|
|
177
|
+
jsonrpc: '2.0',
|
|
178
|
+
id: 1,
|
|
179
|
+
method: 'query',
|
|
180
|
+
params: {
|
|
181
|
+
request_type: 'call_function',
|
|
182
|
+
finality: 'final',
|
|
183
|
+
account_id: 'intents.near',
|
|
184
|
+
method_name: 'get_intent',
|
|
185
|
+
args_base64: Buffer.from(JSON.stringify({ hash: input.intentHash })).toString('base64'),
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
const res = await input.fetchFn(input.nearRpcUrl, {
|
|
189
|
+
method: 'POST',
|
|
190
|
+
body: JSON.stringify(body),
|
|
191
|
+
headers: { 'content-type': 'application/json' },
|
|
192
|
+
signal: AbortSignal.timeout(timeoutMs),
|
|
193
|
+
});
|
|
194
|
+
if (!res.ok) {
|
|
195
|
+
throw new VerificationError('E_NEAR_INTENT_FAILED', `NEAR RPC HTTP ${String(res.status)}`);
|
|
196
|
+
}
|
|
197
|
+
const raw = await res.json();
|
|
198
|
+
const envelope = NearRpcResponseSchema.parse(raw);
|
|
199
|
+
const result = envelope.result;
|
|
200
|
+
if (!result || !Array.isArray(result.result)) {
|
|
201
|
+
throw new VerificationError('E_NEAR_INTENT_CHAIN_AMOUNT', 'NEAR RPC returned no function result');
|
|
202
|
+
}
|
|
203
|
+
const bytes = new Uint8Array(result.result);
|
|
204
|
+
const decoded = new TextDecoder().decode(bytes);
|
|
205
|
+
const parsed = NearIntentOnChainSchema.parse(JSON.parse(decoded));
|
|
206
|
+
if (parsed.destinationAddress !== input.expected.destinationAddress) {
|
|
207
|
+
throw new VerificationError('E_NEAR_INTENT_CHAIN_DEST', `on-chain destination ${parsed.destinationAddress} != expected`);
|
|
208
|
+
}
|
|
209
|
+
if (BigInt(parsed.expectedOutputAmount) !== BigInt(input.expected.expectedOutputAmount)) {
|
|
210
|
+
throw new VerificationError('E_NEAR_INTENT_CHAIN_AMOUNT', `on-chain amount ${parsed.expectedOutputAmount} != expected ${input.expected.expectedOutputAmount}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=near-intents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"near-intents.js","sourceRoot":"","sources":["../../src/verification/near-intents.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External rate oracles for cross-checking engine quotes.
|
|
3
|
+
*
|
|
4
|
+
* The client queries two independent oracles (e.g., CoinGecko + CryptoCompare)
|
|
5
|
+
* and demands they agree within a band before allowing a swap to proceed.
|
|
6
|
+
* Any wider disagreement surfaces as `E_ORACLE_SPREAD`; too few responses as
|
|
7
|
+
* `E_ORACLE_QUORUM`.
|
|
8
|
+
*
|
|
9
|
+
* @security Closes AV-D.4 / AV-H.12 — protects against sidecar + proxy
|
|
10
|
+
* collusion on rate quotes.
|
|
11
|
+
*/
|
|
12
|
+
import type { Logger } from '../interfaces/logger.js';
|
|
13
|
+
export interface RateOracleConfig {
|
|
14
|
+
readonly oracleUrls: ReadonlyArray<string>;
|
|
15
|
+
readonly fetchFn: typeof globalThis.fetch;
|
|
16
|
+
readonly timeoutMs?: number;
|
|
17
|
+
readonly quorum: number;
|
|
18
|
+
readonly logger?: Logger;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Query every configured oracle in parallel, extract a numeric rate from each
|
|
22
|
+
* response, and return the median if at least `quorum` oracles agree within
|
|
23
|
+
* a 2 % band.
|
|
24
|
+
*
|
|
25
|
+
* @param input Oracle URLs, fetch function, timeout, quorum, logger.
|
|
26
|
+
* @param extractRate Per-oracle adapter that pulls the rate out of the body.
|
|
27
|
+
* @returns The median rate across all agreeing oracles.
|
|
28
|
+
* @throws {VerificationError} `E_ORACLE_QUORUM` when fewer than `quorum`
|
|
29
|
+
* oracles respond; `E_ORACLE_SPREAD` when the rates span more than 2 %.
|
|
30
|
+
*/
|
|
31
|
+
export declare function fetchConsensusRate(input: RateOracleConfig, extractRate: (url: string, body: unknown) => number): Promise<number>;
|
|
32
|
+
//# sourceMappingURL=rate-oracle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-oracle.d.ts","sourceRoot":"","sources":["../../src/verification/rate-oracle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAKtD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAC3C,QAAQ,CAAC,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC1C,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAID;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,gBAAgB,EACvB,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,MAAM,GAClD,OAAO,CAAC,MAAM,CAAC,CAoCjB"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { noopLogger } from '../interfaces/logger.js';
|
|
2
|
+
import { VerificationError } from '../types/index.js';
|
|
3
|
+
import { VERIFY_FETCH_TIMEOUT_MS } from './constants.js';
|
|
4
|
+
const DEFAULT_SPREAD_CAP = 0.02; // 2 %
|
|
5
|
+
/**
|
|
6
|
+
* Query every configured oracle in parallel, extract a numeric rate from each
|
|
7
|
+
* response, and return the median if at least `quorum` oracles agree within
|
|
8
|
+
* a 2 % band.
|
|
9
|
+
*
|
|
10
|
+
* @param input Oracle URLs, fetch function, timeout, quorum, logger.
|
|
11
|
+
* @param extractRate Per-oracle adapter that pulls the rate out of the body.
|
|
12
|
+
* @returns The median rate across all agreeing oracles.
|
|
13
|
+
* @throws {VerificationError} `E_ORACLE_QUORUM` when fewer than `quorum`
|
|
14
|
+
* oracles respond; `E_ORACLE_SPREAD` when the rates span more than 2 %.
|
|
15
|
+
*/
|
|
16
|
+
export async function fetchConsensusRate(input, extractRate) {
|
|
17
|
+
const timeoutMs = input.timeoutMs ?? VERIFY_FETCH_TIMEOUT_MS;
|
|
18
|
+
const log = input.logger ?? noopLogger;
|
|
19
|
+
const attempts = input.oracleUrls.map(async (url) => {
|
|
20
|
+
const res = await input.fetchFn(url, { signal: AbortSignal.timeout(timeoutMs) });
|
|
21
|
+
if (!res.ok)
|
|
22
|
+
throw new Error(`HTTP ${String(res.status)}`);
|
|
23
|
+
const body = await res.json();
|
|
24
|
+
return extractRate(url, body);
|
|
25
|
+
});
|
|
26
|
+
const settled = await Promise.allSettled(attempts);
|
|
27
|
+
const rates = settled
|
|
28
|
+
.filter((s) => s.status === 'fulfilled')
|
|
29
|
+
.map((s) => s.value)
|
|
30
|
+
.filter((r) => Number.isFinite(r) && r > 0);
|
|
31
|
+
if (rates.length < input.quorum) {
|
|
32
|
+
throw new VerificationError('E_ORACLE_QUORUM', `only ${String(rates.length)} of ${String(input.oracleUrls.length)} oracles responded`);
|
|
33
|
+
}
|
|
34
|
+
const sorted = [...rates].sort((a, b) => a - b);
|
|
35
|
+
const median = sorted[Math.floor(sorted.length / 2)] ?? 0;
|
|
36
|
+
const spread = (Math.max(...rates) - Math.min(...rates)) / median;
|
|
37
|
+
if (spread > DEFAULT_SPREAD_CAP) {
|
|
38
|
+
throw new VerificationError('E_ORACLE_SPREAD', `oracles disagree by ${(spread * 100).toFixed(2)}% (cap ${(DEFAULT_SPREAD_CAP * 100).toFixed(2)}%)`);
|
|
39
|
+
}
|
|
40
|
+
log.debug({ median, spread, samples: rates.length }, 'Oracle consensus reached');
|
|
41
|
+
return median;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=rate-oracle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-oracle.js","sourceRoot":"","sources":["../../src/verification/rate-oracle.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAUzD,MAAM,kBAAkB,GAAG,IAAI,CAAC,CAAC,MAAM;AAEvC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAuB,EACvB,WAAmD;IAEnD,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,uBAAuB,CAAC;IAC7D,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC;IAEvC,MAAM,QAAQ,GAAG,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QAClD,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QACjF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAC3D,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC;QAC9B,OAAO,WAAW,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IACnD,MAAM,KAAK,GAAG,OAAO;SAClB,MAAM,CAAC,CAAC,CAAC,EAAuC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC;SAC5E,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAE9C,IAAI,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,IAAI,iBAAiB,CACzB,iBAAiB,EACjB,QAAQ,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC,oBAAoB,CACvF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC1D,MAAM,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC;IAClE,IAAI,MAAM,GAAG,kBAAkB,EAAE,CAAC;QAChC,MAAM,IAAI,iBAAiB,CACzB,iBAAiB,EACjB,uBAAuB,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,kBAAkB,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CACpG,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,0BAA0B,CAAC,CAAC;IACjF,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { VerificationCheck, VerificationResult } from '../types/index.js';
|
|
2
|
+
export interface VerifyParams {
|
|
3
|
+
readonly destAddress: string;
|
|
4
|
+
readonly refundAddress: string;
|
|
5
|
+
readonly toToken: string;
|
|
6
|
+
readonly amount: string;
|
|
7
|
+
readonly fromChain?: string;
|
|
8
|
+
readonly toChain?: string;
|
|
9
|
+
readonly fromToken?: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ProtocolContext {
|
|
12
|
+
readonly psbt?: string;
|
|
13
|
+
readonly lock_address?: string;
|
|
14
|
+
readonly timelock_blocks?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function check(name: string, passed: boolean, detail: string): VerificationCheck;
|
|
17
|
+
export declare function resultOf(provider: string, checks: readonly VerificationCheck[]): VerificationResult;
|
|
18
|
+
export declare function failOf(provider: string, checks: readonly VerificationCheck[]): VerificationResult;
|
|
19
|
+
export declare function errMsg(err: unknown): string;
|
|
20
|
+
//# sourceMappingURL=shared.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shared.d.ts","sourceRoot":"","sources":["../../src/verification/shared.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC;CACnC;AAED,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAEtF;AAED,wBAAgB,QAAQ,CACtB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,iBAAiB,EAAE,GACnC,kBAAkB,CAOpB;AAED,wBAAgB,MAAM,CACpB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,SAAS,iBAAiB,EAAE,GACnC,kBAAkB,CAEpB;AAED,wBAAgB,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAM3C"}
|