@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,134 @@
|
|
|
1
|
+
import { validateBase58Check, validateXrpAddress } from './base58.js';
|
|
2
|
+
import { validateBech32 } from './bech32.js';
|
|
3
|
+
import { validateEvmAddress } from './evm.js';
|
|
4
|
+
import { validateSolanaAddress } from './solana.js';
|
|
5
|
+
import { validateMoneroAddress } from './monero.js';
|
|
6
|
+
import { validateTonAddress } from './ton.js';
|
|
7
|
+
import { validatePolkadotAddress } from './polkadot.js';
|
|
8
|
+
const CHAIN_VALIDATORS = {
|
|
9
|
+
// BTC: bech32 or base58check — mainnet and testnet
|
|
10
|
+
bitcoin: (addr) => {
|
|
11
|
+
if (addr.startsWith('bc1'))
|
|
12
|
+
return validateBech32(addr, 'bc');
|
|
13
|
+
if (addr.startsWith('tb1'))
|
|
14
|
+
return validateBech32(addr, 'tb');
|
|
15
|
+
// Mainnet: 1..=0x00, 3..=0x05 | Testnet: m/n=0x6f, 2=0xc4
|
|
16
|
+
return validateBase58Check(addr, [0x00, 0x05, 0x6f, 0xc4]);
|
|
17
|
+
},
|
|
18
|
+
// EVM chains — all share EIP-55
|
|
19
|
+
ethereum: validateEvmAddress,
|
|
20
|
+
bsc: validateEvmAddress,
|
|
21
|
+
polygon: validateEvmAddress,
|
|
22
|
+
arbitrum: validateEvmAddress,
|
|
23
|
+
avalanche: validateEvmAddress,
|
|
24
|
+
base: validateEvmAddress,
|
|
25
|
+
// Litecoin: bech32 (ltc1) or base58check (L=0x30, M=0x32, 3=0x05)
|
|
26
|
+
litecoin: (addr) => {
|
|
27
|
+
if (addr.startsWith('ltc1'))
|
|
28
|
+
return validateBech32(addr, 'ltc');
|
|
29
|
+
return validateBase58Check(addr, [0x30, 0x32, 0x05]);
|
|
30
|
+
},
|
|
31
|
+
// Bitcoin Cash: legacy base58check (same as BTC) or cashaddr
|
|
32
|
+
bitcoincash: (addr) => {
|
|
33
|
+
if (addr.startsWith('bitcoincash:') || addr.startsWith('q') || addr.startsWith('p')) {
|
|
34
|
+
// CashAddr — basic format check (full cashaddr decode is complex)
|
|
35
|
+
const stripped = addr.replace('bitcoincash:', '');
|
|
36
|
+
if (/^[qp][0-9a-z]{41}$/.test(stripped))
|
|
37
|
+
return { valid: true };
|
|
38
|
+
return { valid: false, reason: 'Invalid cashaddr format' };
|
|
39
|
+
}
|
|
40
|
+
return validateBase58Check(addr, [0x00, 0x05]);
|
|
41
|
+
},
|
|
42
|
+
solana: validateSolanaAddress,
|
|
43
|
+
monero: validateMoneroAddress,
|
|
44
|
+
// Tron: base58check starting with T (version byte 0x41)
|
|
45
|
+
tron: (addr) => validateBase58Check(addr, [0x41]),
|
|
46
|
+
ton: validateTonAddress,
|
|
47
|
+
polkadot: validatePolkadotAddress,
|
|
48
|
+
// Cosmos: bech32 with "cosmos" HRP
|
|
49
|
+
cosmos: (addr) => validateBech32(addr, 'cosmos'),
|
|
50
|
+
// THORChain: bech32 with "thor" HRP
|
|
51
|
+
thorchain: (addr) => validateBech32(addr, 'thor'),
|
|
52
|
+
xrp: validateXrpAddress,
|
|
53
|
+
// Dogecoin: base58check (D=0x1e, 9/A=0x16)
|
|
54
|
+
dogecoin: (addr) => validateBase58Check(addr, [0x1e, 0x16]),
|
|
55
|
+
// Dash: base58check (X=0x4c, 7=0x10)
|
|
56
|
+
dash: (addr) => validateBase58Check(addr, [0x4c, 0x10]),
|
|
57
|
+
// Zcash: bech32 (zs1) or base58check (t1=0x1cb8, t3=0x1cbd)
|
|
58
|
+
zcash: (addr) => {
|
|
59
|
+
if (addr.startsWith('zs1'))
|
|
60
|
+
return validateBech32(addr, 'zs');
|
|
61
|
+
// Zcash transparent uses 2-byte version prefixes
|
|
62
|
+
// t1... = mainnet P2PKH, t3... = mainnet P2SH
|
|
63
|
+
if (addr.startsWith('t1') || addr.startsWith('t3')) {
|
|
64
|
+
return validateBase58Check(addr, [0x1c]); // first byte of 2-byte version
|
|
65
|
+
}
|
|
66
|
+
return { valid: false, reason: 'Zcash address must start with t1, t3, or zs1' };
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const TOKEN_TO_CHAIN = {
|
|
70
|
+
BTC: 'bitcoin',
|
|
71
|
+
'BTC-LN': 'bitcoin',
|
|
72
|
+
ETH: 'ethereum',
|
|
73
|
+
USDT: 'ethereum',
|
|
74
|
+
USDC: 'ethereum',
|
|
75
|
+
DAI: 'ethereum',
|
|
76
|
+
WBTC: 'ethereum',
|
|
77
|
+
LTC: 'litecoin',
|
|
78
|
+
BCH: 'bitcoincash',
|
|
79
|
+
SOL: 'solana',
|
|
80
|
+
BNB: 'bsc',
|
|
81
|
+
POL: 'polygon',
|
|
82
|
+
ARB: 'arbitrum',
|
|
83
|
+
TRX: 'tron',
|
|
84
|
+
TON: 'ton',
|
|
85
|
+
DOT: 'polkadot',
|
|
86
|
+
AVAX: 'avalanche',
|
|
87
|
+
ATOM: 'cosmos',
|
|
88
|
+
XRP: 'xrp',
|
|
89
|
+
DOGE: 'dogecoin',
|
|
90
|
+
DASH: 'dash',
|
|
91
|
+
RUNE: 'thorchain',
|
|
92
|
+
ZEC: 'zcash',
|
|
93
|
+
XMR: 'monero',
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Validate a cryptocurrency address for a given token or chain.
|
|
97
|
+
* Pure function — works identically in Node.js and browser.
|
|
98
|
+
*/
|
|
99
|
+
export function validateAddress(address, tokenOrChain) {
|
|
100
|
+
if (!address || !address.trim())
|
|
101
|
+
return { valid: false, reason: 'Address is empty' };
|
|
102
|
+
const chain = resolveChain(tokenOrChain);
|
|
103
|
+
const validator = CHAIN_VALIDATORS[chain];
|
|
104
|
+
if (!validator) {
|
|
105
|
+
// Unknown chain — accept any non-empty address
|
|
106
|
+
return { valid: true };
|
|
107
|
+
}
|
|
108
|
+
return validator(address.trim());
|
|
109
|
+
}
|
|
110
|
+
export function resolveChain(tokenOrChain) {
|
|
111
|
+
return TOKEN_TO_CHAIN[tokenOrChain.toUpperCase()] ?? tokenOrChain.toLowerCase();
|
|
112
|
+
}
|
|
113
|
+
export function getSupportedChains() {
|
|
114
|
+
return Object.keys(CHAIN_VALIDATORS);
|
|
115
|
+
}
|
|
116
|
+
const CHAIN_TO_TOKENS = (() => {
|
|
117
|
+
const out = {};
|
|
118
|
+
for (const [token, chain] of Object.entries(TOKEN_TO_CHAIN)) {
|
|
119
|
+
if (!out[chain])
|
|
120
|
+
out[chain] = [];
|
|
121
|
+
out[chain].push(token);
|
|
122
|
+
}
|
|
123
|
+
// Base shares stablecoins with Ethereum in practice; surface the common set
|
|
124
|
+
// so the address book and pickers don't render an empty Tokens column.
|
|
125
|
+
if (!out['base'])
|
|
126
|
+
out['base'] = ['ETH', 'USDC'];
|
|
127
|
+
return out;
|
|
128
|
+
})();
|
|
129
|
+
/** Tokens commonly received on a given chain. Used to populate the
|
|
130
|
+
* Tokens column in the address book without per-row tagging. */
|
|
131
|
+
export function tokensForChain(chain) {
|
|
132
|
+
return CHAIN_TO_TOKENS[resolveChain(chain)] ?? [];
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/address/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monero address validation.
|
|
3
|
+
* Standard: 95 chars, starts with 4 (mainnet) or 5 (testnet)
|
|
4
|
+
* Subaddress: 95 chars, starts with 8 (mainnet) or 7 (testnet)
|
|
5
|
+
* Integrated: 106 chars, starts with 4 (mainnet)
|
|
6
|
+
*
|
|
7
|
+
* Uses Monero's modified base58 which encodes in 8-byte blocks.
|
|
8
|
+
* We validate format + length rather than full checksum because
|
|
9
|
+
* Monero base58 is non-standard (no base58check).
|
|
10
|
+
*/
|
|
11
|
+
export declare function validateMoneroAddress(address: string): {
|
|
12
|
+
valid: boolean;
|
|
13
|
+
reason?: string;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=monero.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monero.d.ts","sourceRoot":"","sources":["../../src/address/monero.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAoB1F"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Monero address validation.
|
|
3
|
+
* Standard: 95 chars, starts with 4 (mainnet) or 5 (testnet)
|
|
4
|
+
* Subaddress: 95 chars, starts with 8 (mainnet) or 7 (testnet)
|
|
5
|
+
* Integrated: 106 chars, starts with 4 (mainnet)
|
|
6
|
+
*
|
|
7
|
+
* Uses Monero's modified base58 which encodes in 8-byte blocks.
|
|
8
|
+
* We validate format + length rather than full checksum because
|
|
9
|
+
* Monero base58 is non-standard (no base58check).
|
|
10
|
+
*/
|
|
11
|
+
const MONERO_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
12
|
+
export function validateMoneroAddress(address) {
|
|
13
|
+
if (address.length !== 95 && address.length !== 106) {
|
|
14
|
+
return {
|
|
15
|
+
valid: false,
|
|
16
|
+
reason: `Monero address must be 95 or 106 characters, got ${address.length}`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
const first = address[0];
|
|
20
|
+
if (first !== '4' && first !== '8' && first !== '5' && first !== '7') {
|
|
21
|
+
return { valid: false, reason: `Must start with 4, 5, 7, or 8, got '${first}'` };
|
|
22
|
+
}
|
|
23
|
+
for (const c of address) {
|
|
24
|
+
if (!MONERO_ALPHABET.includes(c)) {
|
|
25
|
+
return { valid: false, reason: `Invalid character '${c}'` };
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return { valid: true };
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=monero.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"monero.js","sourceRoot":"","sources":["../../src/address/monero.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,MAAM,eAAe,GAAG,4DAA4D,CAAC;AAErF,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,IAAI,OAAO,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QACpD,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,oDAAoD,OAAO,CAAC,MAAM,EAAE;SAC7E,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACzB,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,EAAE,CAAC;QACrE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,uCAAuC,KAAK,GAAG,EAAE,CAAC;IACnF,CAAC;IAED,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;QACxB,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACjC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,sBAAsB,CAAC,GAAG,EAAE,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polkadot SS58 address validation.
|
|
3
|
+
* Format: base58(prefix + pubkey + checksum)
|
|
4
|
+
* Network 0 = Polkadot mainnet (prefix byte 0x00)
|
|
5
|
+
*/
|
|
6
|
+
export declare function validatePolkadotAddress(address: string): {
|
|
7
|
+
valid: boolean;
|
|
8
|
+
reason?: string;
|
|
9
|
+
};
|
|
10
|
+
//# sourceMappingURL=polkadot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polkadot.d.ts","sourceRoot":"","sources":["../../src/address/polkadot.ts"],"names":[],"mappings":"AAKA;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CA8B5F"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { base58 } from '@scure/base';
|
|
2
|
+
import { blake2b } from '@noble/hashes/blake2.js';
|
|
3
|
+
const SS58_PREFIX = new TextEncoder().encode('SS58PRE');
|
|
4
|
+
/**
|
|
5
|
+
* Polkadot SS58 address validation.
|
|
6
|
+
* Format: base58(prefix + pubkey + checksum)
|
|
7
|
+
* Network 0 = Polkadot mainnet (prefix byte 0x00)
|
|
8
|
+
*/
|
|
9
|
+
export function validatePolkadotAddress(address) {
|
|
10
|
+
if (address.length < 46 || address.length > 48) {
|
|
11
|
+
return { valid: false, reason: `Expected 46-48 characters, got ${address.length}` };
|
|
12
|
+
}
|
|
13
|
+
try {
|
|
14
|
+
const decoded = base58.decode(address);
|
|
15
|
+
if (decoded.length < 35) {
|
|
16
|
+
return { valid: false, reason: 'Decoded data too short' };
|
|
17
|
+
}
|
|
18
|
+
const prefixLen = decoded[0] < 64 ? 1 : 2;
|
|
19
|
+
const pubkey = decoded.slice(prefixLen, prefixLen + 32);
|
|
20
|
+
const checksum = decoded.slice(prefixLen + 32, prefixLen + 34);
|
|
21
|
+
// Verify checksum: blake2b(SS58PRE + prefix + pubkey)[0:2]
|
|
22
|
+
const input = new Uint8Array(SS58_PREFIX.length + prefixLen + 32);
|
|
23
|
+
input.set(SS58_PREFIX);
|
|
24
|
+
input.set(decoded.slice(0, prefixLen), SS58_PREFIX.length);
|
|
25
|
+
input.set(pubkey, SS58_PREFIX.length + prefixLen);
|
|
26
|
+
const hash = blake2b(input, { dkLen: 64 });
|
|
27
|
+
if (hash[0] !== checksum[0] || hash[1] !== checksum[1]) {
|
|
28
|
+
return { valid: false, reason: 'Invalid SS58 checksum' };
|
|
29
|
+
}
|
|
30
|
+
return { valid: true };
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return { valid: false, reason: 'Invalid SS58 encoding' };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=polkadot.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"polkadot.js","sourceRoot":"","sources":["../../src/address/polkadot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAElD,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;AAExD;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAe;IACrD,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC/C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,kCAAkC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IACtF,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YACxB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;QAC5D,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,SAAS,GAAG,EAAE,CAAC,CAAC;QACxD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,EAAE,EAAE,SAAS,GAAG,EAAE,CAAC,CAAC;QAE/D,2DAA2D;QAC3D,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,WAAW,CAAC,MAAM,GAAG,SAAS,GAAG,EAAE,CAAC,CAAC;QAClE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACvB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;QAC3D,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;QAElD,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC3C,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;QAC3D,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,uBAAuB,EAAE,CAAC;IAC3D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../src/address/solana.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAc1F"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { base58 } from '@scure/base';
|
|
2
|
+
export function validateSolanaAddress(address) {
|
|
3
|
+
if (address.length < 32 || address.length > 44) {
|
|
4
|
+
return { valid: false, reason: 'Solana address must be 32-44 characters' };
|
|
5
|
+
}
|
|
6
|
+
try {
|
|
7
|
+
const decoded = base58.decode(address);
|
|
8
|
+
if (decoded.length !== 32) {
|
|
9
|
+
return { valid: false, reason: `Decoded length ${decoded.length}, expected 32 bytes` };
|
|
10
|
+
}
|
|
11
|
+
return { valid: true };
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return { valid: false, reason: 'Invalid base58 encoding' };
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=solana.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"solana.js","sourceRoot":"","sources":["../../src/address/solana.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,IAAI,OAAO,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;QAC/C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,yCAAyC,EAAE,CAAC;IAC7E,CAAC;IAED,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACvC,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YAC1B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,OAAO,CAAC,MAAM,qBAAqB,EAAE,CAAC;QACzF,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,EAAE,CAAC;IAC7D,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TON address validation.
|
|
3
|
+
* Bounceable: EQ + 46 chars base64url
|
|
4
|
+
* Non-bounceable: UQ + 46 chars base64url
|
|
5
|
+
* Raw: 0: prefix with hex (rarely used by users)
|
|
6
|
+
*/
|
|
7
|
+
export declare function validateTonAddress(address: string): {
|
|
8
|
+
valid: boolean;
|
|
9
|
+
reason?: string;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=ton.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ton.d.ts","sourceRoot":"","sources":["../../src/address/ton.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAqBvF"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TON address validation.
|
|
3
|
+
* Bounceable: EQ + 46 chars base64url
|
|
4
|
+
* Non-bounceable: UQ + 46 chars base64url
|
|
5
|
+
* Raw: 0: prefix with hex (rarely used by users)
|
|
6
|
+
*/
|
|
7
|
+
export function validateTonAddress(address) {
|
|
8
|
+
// User-friendly format: EQ/UQ + 46 base64url chars
|
|
9
|
+
if (/^(EQ|UQ)[A-Za-z0-9_-]{46}$/.test(address)) {
|
|
10
|
+
try {
|
|
11
|
+
const b64 = address.slice(2).replace(/-/g, '+').replace(/_/g, '/');
|
|
12
|
+
const decoded = Buffer.from(b64, 'base64');
|
|
13
|
+
if (decoded.length !== 34) {
|
|
14
|
+
return { valid: false, reason: `Decoded length ${decoded.length}, expected 34` };
|
|
15
|
+
}
|
|
16
|
+
return { valid: true };
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return { valid: false, reason: 'Invalid base64url encoding' };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Raw format: 0:hex (64 hex chars)
|
|
23
|
+
if (/^0:[0-9a-fA-F]{64}$/.test(address)) {
|
|
24
|
+
return { valid: true };
|
|
25
|
+
}
|
|
26
|
+
return { valid: false, reason: 'TON address must start with EQ/UQ (48 chars) or 0: (66 chars)' };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=ton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ton.js","sourceRoot":"","sources":["../../src/address/ton.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,UAAU,kBAAkB,CAAC,OAAe;IAChD,mDAAmD;IACnD,IAAI,4BAA4B,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC/C,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;YACnE,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YAC3C,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;gBAC1B,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,OAAO,CAAC,MAAM,eAAe,EAAE,CAAC;YACnF,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,4BAA4B,EAAE,CAAC;QAChE,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,IAAI,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;IACzB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,+DAA+D,EAAE,CAAC;AACnG,CAAC"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { Logger } from '../interfaces/logger.js';
|
|
2
|
+
import { ApiError, NetworkError } from '../lib/errors.js';
|
|
3
|
+
import type { CreateSwapBody, CreateSwapResponse, LimitsResponse, LiquidityResponse, PowChallenge, ProvidersResponse, QuotesResponse, RateResponse, RecentSwap, SwapAction, SwapActionResponse, SwapDetail, SwapPair, SwapTokenMap, VerifyKeysBody, VerifyKeysResponse } from '../wire/server/index.js';
|
|
4
|
+
export { ApiError, NetworkError };
|
|
5
|
+
export interface ApiClientConfig {
|
|
6
|
+
readonly baseUrl: string;
|
|
7
|
+
readonly timeout?: number;
|
|
8
|
+
readonly maxRetries?: number;
|
|
9
|
+
readonly retryBaseMs?: number;
|
|
10
|
+
readonly fetchFn?: typeof globalThis.fetch;
|
|
11
|
+
readonly logger?: Logger;
|
|
12
|
+
}
|
|
13
|
+
export interface GetQuotesParams {
|
|
14
|
+
readonly from: string;
|
|
15
|
+
readonly to: string;
|
|
16
|
+
readonly amount: string;
|
|
17
|
+
readonly fromChain?: string;
|
|
18
|
+
readonly toChain?: string;
|
|
19
|
+
}
|
|
20
|
+
export interface GetRateParams {
|
|
21
|
+
readonly from: string;
|
|
22
|
+
readonly to: string;
|
|
23
|
+
readonly fromChain?: string;
|
|
24
|
+
readonly toChain?: string;
|
|
25
|
+
}
|
|
26
|
+
export interface GetLimitsParams {
|
|
27
|
+
readonly from: string;
|
|
28
|
+
readonly to: string;
|
|
29
|
+
readonly fromChain?: string;
|
|
30
|
+
readonly toChain?: string;
|
|
31
|
+
}
|
|
32
|
+
export declare class ApiClient {
|
|
33
|
+
private readonly baseUrl;
|
|
34
|
+
private readonly timeout;
|
|
35
|
+
private readonly maxRetries;
|
|
36
|
+
private readonly retryBaseMs;
|
|
37
|
+
private readonly fetchFn;
|
|
38
|
+
private readonly logger;
|
|
39
|
+
constructor(config: ApiClientConfig);
|
|
40
|
+
getTokens(): Promise<SwapTokenMap>;
|
|
41
|
+
getPairs(): Promise<readonly SwapPair[]>;
|
|
42
|
+
getQuotes(params: GetQuotesParams): Promise<QuotesResponse>;
|
|
43
|
+
getRate(params: GetRateParams): Promise<RateResponse>;
|
|
44
|
+
getLimits(params: GetLimitsParams): Promise<LimitsResponse>;
|
|
45
|
+
getProviders(): Promise<ProvidersResponse>;
|
|
46
|
+
getLiquidity(): Promise<LiquidityResponse>;
|
|
47
|
+
getRecents(): Promise<readonly RecentSwap[]>;
|
|
48
|
+
getChallenge(): Promise<PowChallenge>;
|
|
49
|
+
createSwap(body: CreateSwapBody, powHeader?: string): Promise<CreateSwapResponse>;
|
|
50
|
+
getSwapDetail(id: string): Promise<SwapDetail>;
|
|
51
|
+
getSwapByFundingAddress(address: string): Promise<SwapDetail | null>;
|
|
52
|
+
executeAction(swapId: string, action: SwapAction, timeoutMs?: number): Promise<SwapActionResponse>;
|
|
53
|
+
verifyKeys(keys: VerifyKeysBody): Promise<VerifyKeysResponse>;
|
|
54
|
+
private buildQuery;
|
|
55
|
+
private get;
|
|
56
|
+
private post;
|
|
57
|
+
/**
|
|
58
|
+
* `X-Pow-Payload` carries a single-use proof-of-work header that the
|
|
59
|
+
* server consumes via Redis SETNX in `verifyPowSolution`. If the request
|
|
60
|
+
* fails after the server has already verified PoW (e.g. simulateSwap
|
|
61
|
+
* returns 503 because mocknet pools shifted between quote and create),
|
|
62
|
+
* a transparent retry would resubmit the same header and bounce off
|
|
63
|
+
* replay protection with `403 challenge already used`. The caller must
|
|
64
|
+
* fetch a fresh challenge instead. Detect that case and skip the retry
|
|
65
|
+
* wrapper so the original error surfaces unmodified to the caller.
|
|
66
|
+
*/
|
|
67
|
+
private hasSingleUseToken;
|
|
68
|
+
private request;
|
|
69
|
+
/**
|
|
70
|
+
* Single attempt: perform the fetch, parse the envelope, classify the result.
|
|
71
|
+
*
|
|
72
|
+
* Throw types map to {@link ErrorCategory} via the unified taxonomy:
|
|
73
|
+
* - {@link ApiError}('SCHEMA_MISMATCH') → category `protocol` → fail.
|
|
74
|
+
* - {@link ApiError}(status 4xx) → category `client-*` → bounded / fatal per status.
|
|
75
|
+
* - {@link ApiError}(status 5xx) → category `server` → unbounded retry.
|
|
76
|
+
* - {@link NetworkError} → category `network` → unbounded retry.
|
|
77
|
+
*/
|
|
78
|
+
private runOnce;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/api/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAqB1D,OAAO,KAAK,EACV,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,iBAAiB,EACjB,cAAc,EACd,YAAY,EACZ,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,UAAU,EACV,QAAQ,EACR,YAAY,EACZ,cAAc,EACd,kBAAkB,EACnB,MAAM,yBAAyB,CAAC;AAGjC,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,CAAC;AAElC,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;IAC3C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA0B;IAClD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,MAAM,EAAE,eAAe;IAS7B,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC;IAQlC,QAAQ,IAAI,OAAO,CAAC,SAAS,QAAQ,EAAE,CAAC;IAQxC,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAW3D,OAAO,CAAC,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC;IAUrD,SAAS,CAAC,MAAM,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC;IAU3D,YAAY,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAI1C,YAAY,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAI1C,UAAU,IAAI,OAAO,CAAC,SAAS,UAAU,EAAE,CAAC;IAQ5C,YAAY,IAAI,OAAO,CAAC,YAAY,CAAC;IAIrC,UAAU,CAAC,IAAI,EAAE,cAAc,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAkBjF,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAI9C,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC;IAOpE,aAAa,CACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,UAAU,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,kBAAkB,CAAC;IAWxB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAKnE,OAAO,CAAC,UAAU;IAOlB,OAAO,CAAC,GAAG;IAQX,OAAO,CAAC,IAAI;IAUZ;;;;;;;;;OASG;IACH,OAAO,CAAC,iBAAiB;YAKX,OAAO;IA2BrB;;;;;;;;OAQG;YACW,OAAO;CA2EtB"}
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { noopLogger } from '../interfaces/logger.js';
|
|
3
|
+
import { ApiError, NetworkError } from '../lib/errors.js';
|
|
4
|
+
import { withRetry } from '../lib/retry.js';
|
|
5
|
+
import { apiEnvelopeSchema, createSwapBodySchema, createSwapResponseSchema, limitsResponseSchema, liquidityResponseSchema, powChallengeSchema, providersResponseSchema, quotesResponseSchema, rateResponseSchema, recentSwapSchema, swapActionBodySchema, swapActionResponseSchema, swapDetailSchema, swapPairSchema, swapTokenMapSchema, verifyKeysBodySchema, verifyKeysResponseSchema, } from '../wire/server/index.js';
|
|
6
|
+
// Re-exported for back-compat; canonical definitions live in lib/errors.ts.
|
|
7
|
+
export { ApiError, NetworkError };
|
|
8
|
+
export class ApiClient {
|
|
9
|
+
baseUrl;
|
|
10
|
+
timeout;
|
|
11
|
+
maxRetries;
|
|
12
|
+
retryBaseMs;
|
|
13
|
+
fetchFn;
|
|
14
|
+
logger;
|
|
15
|
+
constructor(config) {
|
|
16
|
+
this.baseUrl = config.baseUrl.replace(/\/+$/, '');
|
|
17
|
+
this.timeout = config.timeout ?? 60_000;
|
|
18
|
+
this.maxRetries = config.maxRetries ?? 3;
|
|
19
|
+
this.retryBaseMs = config.retryBaseMs ?? 500;
|
|
20
|
+
this.fetchFn = config.fetchFn ?? globalThis.fetch.bind(globalThis);
|
|
21
|
+
this.logger = config.logger ?? noopLogger;
|
|
22
|
+
}
|
|
23
|
+
async getTokens() {
|
|
24
|
+
const { tokens } = await this.get('/api/v1/swap/tokens', z.object({ tokens: swapTokenMapSchema }));
|
|
25
|
+
return tokens;
|
|
26
|
+
}
|
|
27
|
+
async getPairs() {
|
|
28
|
+
const { pairs } = await this.get('/api/v1/swap/pairs', z.object({ pairs: z.array(swapPairSchema) }));
|
|
29
|
+
return pairs;
|
|
30
|
+
}
|
|
31
|
+
async getQuotes(params) {
|
|
32
|
+
const qs = this.buildQuery({
|
|
33
|
+
from: params.from,
|
|
34
|
+
to: params.to,
|
|
35
|
+
amount: params.amount,
|
|
36
|
+
fromChain: params.fromChain,
|
|
37
|
+
toChain: params.toChain,
|
|
38
|
+
});
|
|
39
|
+
return this.get(`/api/v1/swap/quotes?${qs}`, quotesResponseSchema);
|
|
40
|
+
}
|
|
41
|
+
async getRate(params) {
|
|
42
|
+
const qs = this.buildQuery({
|
|
43
|
+
from: params.from,
|
|
44
|
+
to: params.to,
|
|
45
|
+
fromChain: params.fromChain,
|
|
46
|
+
toChain: params.toChain,
|
|
47
|
+
});
|
|
48
|
+
return this.get(`/api/v1/swap/rate?${qs}`, rateResponseSchema);
|
|
49
|
+
}
|
|
50
|
+
async getLimits(params) {
|
|
51
|
+
const qs = this.buildQuery({
|
|
52
|
+
from: params.from,
|
|
53
|
+
to: params.to,
|
|
54
|
+
fromChain: params.fromChain,
|
|
55
|
+
toChain: params.toChain,
|
|
56
|
+
});
|
|
57
|
+
return this.get(`/api/v1/swap/limits?${qs}`, limitsResponseSchema);
|
|
58
|
+
}
|
|
59
|
+
async getProviders() {
|
|
60
|
+
return this.get('/api/v1/swap/providers', providersResponseSchema);
|
|
61
|
+
}
|
|
62
|
+
async getLiquidity() {
|
|
63
|
+
return this.get('/api/v1/swap/liquidity', liquidityResponseSchema);
|
|
64
|
+
}
|
|
65
|
+
async getRecents() {
|
|
66
|
+
const { recents } = await this.get('/api/v1/swap/recents', z.object({ recents: z.array(recentSwapSchema) }));
|
|
67
|
+
return recents;
|
|
68
|
+
}
|
|
69
|
+
async getChallenge() {
|
|
70
|
+
return this.get('/api/v1/pow/challenge', powChallengeSchema);
|
|
71
|
+
}
|
|
72
|
+
async createSwap(body, powHeader) {
|
|
73
|
+
const validBody = createSwapBodySchema.parse(body);
|
|
74
|
+
// Swap creation is the slowest end-to-end path: server submits the
|
|
75
|
+
// proof-of-work check, registers the THORChain memo (≥1 broadcast +
|
|
76
|
+
// poll for reference assignment), and round-trips to the engine. 15-25 s
|
|
77
|
+
// is typical; pathological cases (memo retries, slow upstream) can push
|
|
78
|
+
// toward a minute. Use a 2 min ceiling instead of the API client's
|
|
79
|
+
// generic 60 s default so the user doesn't see a spurious timeout
|
|
80
|
+
// while a real swap is mid-flight.
|
|
81
|
+
return this.post('/api/v1/swap/new', createSwapResponseSchema, validBody, powHeader ? { 'X-Pow-Payload': powHeader } : undefined, 120_000);
|
|
82
|
+
}
|
|
83
|
+
async getSwapDetail(id) {
|
|
84
|
+
return this.get(`/api/v1/swap/${encodeURIComponent(id)}`, swapDetailSchema);
|
|
85
|
+
}
|
|
86
|
+
async getSwapByFundingAddress(address) {
|
|
87
|
+
return this.get(`/api/v1/swap/get-id/${encodeURIComponent(address)}`, swapDetailSchema.nullable());
|
|
88
|
+
}
|
|
89
|
+
async executeAction(swapId, action, timeoutMs) {
|
|
90
|
+
const validBody = swapActionBodySchema.parse(action);
|
|
91
|
+
return this.post(`/api/v1/swap/${encodeURIComponent(swapId)}/action`, swapActionResponseSchema, validBody, undefined, timeoutMs);
|
|
92
|
+
}
|
|
93
|
+
async verifyKeys(keys) {
|
|
94
|
+
const validBody = verifyKeysBodySchema.parse(keys);
|
|
95
|
+
return this.post('/api/v1/swap/verify-keys', verifyKeysResponseSchema, validBody);
|
|
96
|
+
}
|
|
97
|
+
buildQuery(params) {
|
|
98
|
+
const filtered = Object.entries(params).filter((entry) => entry[1] !== undefined);
|
|
99
|
+
return new URLSearchParams(filtered).toString();
|
|
100
|
+
}
|
|
101
|
+
get(path, schema, timeoutMs) {
|
|
102
|
+
return this.request('GET', path, schema, undefined, undefined, timeoutMs);
|
|
103
|
+
}
|
|
104
|
+
post(path, schema, body, extraHeaders, timeoutMs) {
|
|
105
|
+
return this.request('POST', path, schema, body, extraHeaders, timeoutMs);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* `X-Pow-Payload` carries a single-use proof-of-work header that the
|
|
109
|
+
* server consumes via Redis SETNX in `verifyPowSolution`. If the request
|
|
110
|
+
* fails after the server has already verified PoW (e.g. simulateSwap
|
|
111
|
+
* returns 503 because mocknet pools shifted between quote and create),
|
|
112
|
+
* a transparent retry would resubmit the same header and bounce off
|
|
113
|
+
* replay protection with `403 challenge already used`. The caller must
|
|
114
|
+
* fetch a fresh challenge instead. Detect that case and skip the retry
|
|
115
|
+
* wrapper so the original error surfaces unmodified to the caller.
|
|
116
|
+
*/
|
|
117
|
+
hasSingleUseToken(extraHeaders) {
|
|
118
|
+
if (!extraHeaders)
|
|
119
|
+
return false;
|
|
120
|
+
return Object.prototype.hasOwnProperty.call(extraHeaders, 'X-Pow-Payload');
|
|
121
|
+
}
|
|
122
|
+
async request(method, path, responseSchema, body, extraHeaders, timeoutMs) {
|
|
123
|
+
const url = `${this.baseUrl}${path}`;
|
|
124
|
+
const effectiveTimeout = timeoutMs ?? this.timeout;
|
|
125
|
+
this.logger.debug({ method, path }, 'API request');
|
|
126
|
+
if (this.hasSingleUseToken(extraHeaders)) {
|
|
127
|
+
return this.runOnce(method, path, url, responseSchema, body, extraHeaders, effectiveTimeout);
|
|
128
|
+
}
|
|
129
|
+
return withRetry(async () => this.runOnce(method, path, url, responseSchema, body, extraHeaders, effectiveTimeout), {
|
|
130
|
+
maxBoundedRetries: this.maxRetries,
|
|
131
|
+
baseMs: this.retryBaseMs,
|
|
132
|
+
logger: this.logger,
|
|
133
|
+
label: `${method} ${path}`,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Single attempt: perform the fetch, parse the envelope, classify the result.
|
|
138
|
+
*
|
|
139
|
+
* Throw types map to {@link ErrorCategory} via the unified taxonomy:
|
|
140
|
+
* - {@link ApiError}('SCHEMA_MISMATCH') → category `protocol` → fail.
|
|
141
|
+
* - {@link ApiError}(status 4xx) → category `client-*` → bounded / fatal per status.
|
|
142
|
+
* - {@link ApiError}(status 5xx) → category `server` → unbounded retry.
|
|
143
|
+
* - {@link NetworkError} → category `network` → unbounded retry.
|
|
144
|
+
*/
|
|
145
|
+
async runOnce(method, path, url, responseSchema, body, extraHeaders, effectiveTimeout) {
|
|
146
|
+
const ac = new AbortController();
|
|
147
|
+
const timer = setTimeout(() => ac.abort(), effectiveTimeout);
|
|
148
|
+
let res;
|
|
149
|
+
try {
|
|
150
|
+
res = await this.fetchFn(url, {
|
|
151
|
+
method,
|
|
152
|
+
headers: {
|
|
153
|
+
'Content-Type': 'application/json',
|
|
154
|
+
Accept: 'application/json',
|
|
155
|
+
...extraHeaders,
|
|
156
|
+
},
|
|
157
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
158
|
+
signal: ac.signal,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
catch (fetchErr) {
|
|
162
|
+
clearTimeout(timer);
|
|
163
|
+
throw normaliseFetchError(fetchErr, effectiveTimeout);
|
|
164
|
+
}
|
|
165
|
+
clearTimeout(timer);
|
|
166
|
+
let raw;
|
|
167
|
+
try {
|
|
168
|
+
raw = await res.json();
|
|
169
|
+
}
|
|
170
|
+
catch (parseErr) {
|
|
171
|
+
// Body parse failure — undici / browser fetch sometimes truncate on
|
|
172
|
+
// connection reset, surface as transient network failure.
|
|
173
|
+
throw new NetworkError('Failed to parse response body', {
|
|
174
|
+
cause: parseErr,
|
|
175
|
+
details: { status: res.status },
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
const parsed = apiEnvelopeSchema(responseSchema).safeParse(raw);
|
|
179
|
+
if (!parsed.success) {
|
|
180
|
+
this.logger.error({ method, path, status: res.status, issues: parsed.error.issues }, 'Schema mismatch');
|
|
181
|
+
throw new ApiError('Server response did not match expected schema', 502, 'SCHEMA_MISMATCH', { details: { method, path, status: res.status, issues: parsed.error.issues } });
|
|
182
|
+
}
|
|
183
|
+
const envelope = parsed.data;
|
|
184
|
+
if (!envelope.success) {
|
|
185
|
+
const { code, message, details } = envelope.error;
|
|
186
|
+
this.logger.warn({ method, path, status: res.status, code }, 'API error');
|
|
187
|
+
throw new ApiError(message, res.status, code, {
|
|
188
|
+
details: typeof details === 'object' && details !== null
|
|
189
|
+
? details
|
|
190
|
+
: undefined,
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return envelope.data;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Normalise anything thrown from `fetch()` into a {@link NetworkError} so the
|
|
198
|
+
* retry classifier sees a single shape regardless of platform.
|
|
199
|
+
*
|
|
200
|
+
* Cross-platform: `TypeError` covers undici / browser fetch failures;
|
|
201
|
+
* `DOMException('AbortError')` covers per-request timeout. Other errors fall
|
|
202
|
+
* through with their original message preserved.
|
|
203
|
+
*/
|
|
204
|
+
function normaliseFetchError(err, timeoutMs) {
|
|
205
|
+
if (typeof DOMException !== 'undefined' && err instanceof DOMException && err.name === 'AbortError') {
|
|
206
|
+
return new NetworkError(`Request timeout after ${String(timeoutMs)}ms`, { cause: err });
|
|
207
|
+
}
|
|
208
|
+
if (err instanceof Error) {
|
|
209
|
+
return new NetworkError(err.message, { cause: err });
|
|
210
|
+
}
|
|
211
|
+
return new NetworkError(String(err));
|
|
212
|
+
}
|
|
213
|
+
//# sourceMappingURL=index.js.map
|