@vultisig/core-chain 2.26.0 → 2.27.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/CHANGELOG.md +83 -0
- package/dist/chains/cosmos/account/getCosmosAccountInfo.d.ts +1 -0
- package/dist/chains/cosmos/account/getCosmosAccountInfo.d.ts.map +1 -1
- package/dist/chains/cosmos/account/getCosmosAccountInfo.js +112 -30
- package/dist/chains/cosmos/account/getCosmosAccountInfo.js.map +1 -1
- package/dist/chains/cosmos/parseUint64.d.ts +6 -0
- package/dist/chains/cosmos/parseUint64.d.ts.map +1 -0
- package/dist/chains/cosmos/parseUint64.js +12 -0
- package/dist/chains/cosmos/parseUint64.js.map +1 -0
- package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.d.ts.map +1 -1
- package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.js +3 -28
- package/dist/chains/cosmos/qbtc/claim/broadcastClaimTx.js.map +1 -1
- package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.d.ts.map +1 -1
- package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.js +11 -13
- package/dist/chains/cosmos/qbtc/getQbtcAccountInfo.js.map +1 -1
- package/dist/chains/cosmos/qbtc/waitForQbtcTxInclusion.d.ts +32 -0
- package/dist/chains/cosmos/qbtc/waitForQbtcTxInclusion.d.ts.map +1 -0
- package/dist/chains/cosmos/qbtc/waitForQbtcTxInclusion.js +33 -0
- package/dist/chains/cosmos/qbtc/waitForQbtcTxInclusion.js.map +1 -0
- package/dist/coin/balance/getEvmChainBalances.d.ts +6 -0
- package/dist/coin/balance/getEvmChainBalances.d.ts.map +1 -1
- package/dist/coin/balance/getEvmChainBalances.js +11 -5
- package/dist/coin/balance/getEvmChainBalances.js.map +1 -1
- package/dist/coin/price/resolveTokenPriceId.d.ts +8 -10
- package/dist/coin/price/resolveTokenPriceId.d.ts.map +1 -1
- package/dist/coin/price/resolveTokenPriceId.js +21 -14
- package/dist/coin/price/resolveTokenPriceId.js.map +1 -1
- package/dist/swap/general/GeneralSwapQuote.d.ts +19 -3
- package/dist/swap/general/GeneralSwapQuote.d.ts.map +1 -1
- package/dist/swap/general/cowswap/sign/buildCowSwapOrderTypedData.d.ts +0 -9
- package/dist/swap/general/cowswap/sign/buildCowSwapOrderTypedData.d.ts.map +1 -1
- package/dist/swap/general/cowswap/sign/buildCowSwapOrderTypedData.js +52 -22
- package/dist/swap/general/cowswap/sign/buildCowSwapOrderTypedData.js.map +1 -1
- package/dist/swap/general/knownAggregatorRouters.d.ts +59 -2
- package/dist/swap/general/knownAggregatorRouters.d.ts.map +1 -1
- package/dist/swap/general/knownAggregatorRouters.js +118 -12
- package/dist/swap/general/knownAggregatorRouters.js.map +1 -1
- package/dist/swap/general/kyber/chains.d.ts +1 -1
- package/dist/swap/general/kyber/chains.d.ts.map +1 -1
- package/dist/swap/general/kyber/chains.js +5 -2
- package/dist/swap/general/kyber/chains.js.map +1 -1
- package/dist/swap/general/lifi/api/getLifiSwapQuote.d.ts +2 -9
- package/dist/swap/general/lifi/api/getLifiSwapQuote.d.ts.map +1 -1
- package/dist/swap/general/lifi/api/getLifiSwapQuote.js +29 -81
- package/dist/swap/general/lifi/api/getLifiSwapQuote.js.map +1 -1
- package/dist/swap/general/lifi/api/lifiSlippage.d.ts +25 -0
- package/dist/swap/general/lifi/api/lifiSlippage.d.ts.map +1 -0
- package/dist/swap/general/lifi/api/lifiSlippage.js +51 -0
- package/dist/swap/general/lifi/api/lifiSlippage.js.map +1 -0
- package/dist/swap/general/oneInch/api/getOneInchSwapQuote.d.ts.map +1 -1
- package/dist/swap/general/oneInch/api/getOneInchSwapQuote.js +8 -0
- package/dist/swap/general/oneInch/api/getOneInchSwapQuote.js.map +1 -1
- package/dist/swap/general/swapkit/api/getSwapKitQuote.d.ts.map +1 -1
- package/dist/swap/general/swapkit/api/getSwapKitQuote.js +23 -2
- package/dist/swap/general/swapkit/api/getSwapKitQuote.js.map +1 -1
- package/dist/swap/general/swapkit/getSwapKitTrackerUrl.d.ts +43 -0
- package/dist/swap/general/swapkit/getSwapKitTrackerUrl.d.ts.map +1 -0
- package/dist/swap/general/swapkit/getSwapKitTrackerUrl.js +47 -0
- package/dist/swap/general/swapkit/getSwapKitTrackerUrl.js.map +1 -0
- package/dist/swap/native/NativeSwapChain.d.ts +2 -0
- package/dist/swap/native/NativeSwapChain.d.ts.map +1 -1
- package/dist/swap/native/NativeSwapChain.js +1 -0
- package/dist/swap/native/NativeSwapChain.js.map +1 -1
- package/dist/swap/native/halts/getNativeSwapTradingHalt.d.ts.map +1 -1
- package/dist/swap/native/halts/getNativeSwapTradingHalt.js +2 -2
- package/dist/swap/native/halts/getNativeSwapTradingHalt.js.map +1 -1
- package/dist/swap/native/limitSwapMemo.d.ts.map +1 -1
- package/dist/swap/native/limitSwapMemo.js +1 -24
- package/dist/swap/native/limitSwapMemo.js.map +1 -1
- package/dist/swap/native/minimum/getNativeSwapMinAmountIn.d.ts.map +1 -1
- package/dist/swap/native/minimum/getNativeSwapMinAmountIn.js +9 -3
- package/dist/swap/native/minimum/getNativeSwapMinAmountIn.js.map +1 -1
- package/dist/swap/native/thorchainMemoAsset.d.ts +76 -0
- package/dist/swap/native/thorchainMemoAsset.d.ts.map +1 -0
- package/dist/swap/native/thorchainMemoAsset.js +126 -0
- package/dist/swap/native/thorchainMemoAsset.js.map +1 -0
- package/dist/swap/quote/findSwapQuote.d.ts.map +1 -1
- package/dist/swap/quote/findSwapQuote.js +6 -1
- package/dist/swap/quote/findSwapQuote.js.map +1 -1
- package/dist/swap/swapEnabledChains.d.ts.map +1 -1
- package/dist/swap/swapEnabledChains.js +12 -0
- package/dist/swap/swapEnabledChains.js.map +1 -1
- package/dist/swap/utils/getSwapExplorerUrl/index.d.ts +10 -7
- package/dist/swap/utils/getSwapExplorerUrl/index.d.ts.map +1 -1
- package/dist/swap/utils/getSwapExplorerUrl/index.js +13 -12
- package/dist/swap/utils/getSwapExplorerUrl/index.js.map +1 -1
- package/dist/tx/broadcast/resolvers/bittensor.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/bittensor.js +21 -15
- package/dist/tx/broadcast/resolvers/bittensor.js.map +1 -1
- package/dist/tx/broadcast/resolvers/cosmos.d.ts +1 -0
- package/dist/tx/broadcast/resolvers/cosmos.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/cosmos.js +30 -2
- package/dist/tx/broadcast/resolvers/cosmos.js.map +1 -1
- package/dist/tx/broadcast/resolvers/polkadot.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/polkadot.js +3 -36
- package/dist/tx/broadcast/resolvers/polkadot.js.map +1 -1
- package/dist/tx/broadcast/resolvers/qbtc.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/qbtc.js +37 -7
- package/dist/tx/broadcast/resolvers/qbtc.js.map +1 -1
- package/dist/tx/broadcast/resolvers/substrate.d.ts +8 -0
- package/dist/tx/broadcast/resolvers/substrate.d.ts.map +1 -0
- package/dist/tx/broadcast/resolvers/substrate.js +15 -0
- package/dist/tx/broadcast/resolvers/substrate.js.map +1 -0
- package/dist/tx/broadcast/resolvers/sui.d.ts +8 -0
- package/dist/tx/broadcast/resolvers/sui.d.ts.map +1 -1
- package/dist/tx/broadcast/resolvers/sui.js +33 -7
- package/dist/tx/broadcast/resolvers/sui.js.map +1 -1
- package/dist/tx/broadcast/transientRetry.d.ts +17 -0
- package/dist/tx/broadcast/transientRetry.d.ts.map +1 -1
- package/dist/tx/broadcast/transientRetry.js +23 -0
- package/dist/tx/broadcast/transientRetry.js.map +1 -1
- package/dist/tx/status/resolvers/cardano.d.ts.map +1 -1
- package/dist/tx/status/resolvers/cardano.js +19 -3
- package/dist/tx/status/resolvers/cardano.js.map +1 -1
- package/package.json +32 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,88 @@
|
|
|
1
1
|
# @vultisig/core-chain
|
|
2
2
|
|
|
3
|
+
## 2.27.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1499](https://github.com/vultisig/vultisig-sdk/pull/1499) [`3bc880a`](https://github.com/vultisig/vultisig-sdk/commit/3bc880a06b90fa64793983ba498f11fdc55e2115) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Expose `getThorchainMemoAsset`, a `Coin` -> THORChain memo-asset converter, plus `isThorchainRoutable` and `isThorchainSecuredAssetId`, from `@vultisig/core-chain/swap/native/thorchainMemoAsset`.
|
|
8
|
+
|
|
9
|
+
`buildLimitSwapMemo` takes `source_asset` / `target_asset` as pre-formatted THORChain notation, but nothing produced those strings from a `Coin`. Market swaps never needed it — the memo comes back on the server quote — but limit swaps build the memo locally, so every consumer had to derive the notation itself. Since the memo _is_ the order, a divergence there misroutes funds.
|
|
10
|
+
|
|
11
|
+
Notation is derived from `toNativeSwapAsset`, the converter the market-swap path already uses, so the package has exactly one definition of a THORChain asset string. The only thing layered on top is abbreviating an L1 contract to its last 6 characters: memo bytes are capped at 80 on UTXO sources, while the swap API is given the full address. Secured assets are left un-abbreviated because the trailing address is part of the denom that identifies them.
|
|
12
|
+
|
|
13
|
+
`limitSwapMemo`'s prefix -> chain map is now derived by inverting the new chain -> prefix map rather than being hand-maintained alongside it, so the two directions cannot drift. Behaviour is unchanged — the inversion reproduces the previous map exactly.
|
|
14
|
+
|
|
15
|
+
`@vultisig/sdk` is bumped because it bundles `packages/core/chain` source rather than depending on the published package, so it needs a fresh tarball to carry this change. The helper is not re-exported from the SDK's public API, hence a patch rather than a minor.
|
|
16
|
+
|
|
17
|
+
Note: `buildLimitSwapMemo` still does not accept secured assets — its `assertValidPoolId` check requires dotted `CHAIN.ASSET` notation and rejects the `CHAIN-ASSET` form. That gap predates this helper (iOS has the same one) and is tracked separately; a regression test pins it so it cannot change silently.
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- [#1432](https://github.com/vultisig/vultisig-sdk/pull/1432) [`5d46269`](https://github.com/vultisig/vultisig-sdk/commit/5d46269396fd0dbcf9d84f0201a494dffafc1a36) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Fix the Bittensor broadcast assuming success on a malformed RPC response. `broadcastBittensorTx` only inspected `response.error`; a body with neither `error` nor `result` (truncated / malformed gateway response) fell through and returned `undefined` — reported as a successful broadcast. It now forces hash verification when `result` is absent, mirroring the Polkadot resolver's JSON-RPC 2.0 guard.
|
|
22
|
+
|
|
23
|
+
- [#1461](https://github.com/vultisig/vultisig-sdk/pull/1461) [`9d50ac5`](https://github.com/vultisig/vultisig-sdk/commit/9d50ac5c586d058aabdbfb413e7be163a222da89) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Resolve Cardano transaction status through the existing Koios proxy instead of the unsupported Blockchair route.
|
|
24
|
+
|
|
25
|
+
- [#1474](https://github.com/vultisig/vultisig-sdk/pull/1474) [`c443b9c`](https://github.com/vultisig/vultisig-sdk/commit/c443b9ce699ef76f1407d0386ed20fbc7e3f253f) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Route SwapKit transaction links through its public tracker across the shared core and SDK APIs.
|
|
26
|
+
|
|
27
|
+
- [#1462](https://github.com/vultisig/vultisig-sdk/pull/1462) [`a4d8bbe`](https://github.com/vultisig/vultisig-sdk/commit/a4d8bbe81a94019aea5193a411a091ccb2e98682) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Close a co-signer swap-guard gap where enforcement was keyed purely on the untrusted `provider` string (sdk#1457). CowSwap is now an enforced provider - its swap-leg destination and ERC-20 approval spender are always the same fixed GPv2VaultRelayer contract, so it is exactly as allow-listable as 1inch/Kyber's routers, and a payload can no longer relabel itself `cowswap` to dodge a router check. The log-only fallback for unenforced providers is now a closed list of the values the codebase actually produces (`li.fi`, `swapkit`, and the legacy unattributed `''` some historical mobile payloads carry) instead of accepting any string - a `provider` outside every known value is rejected fail-closed. The CowSwap allow-list entry is CHAIN-SCOPED to `cowSwapSupportedChains` (Ethereum/Arbitrum/Base/Avalanche): the GPv2VaultRelayer is a deterministic address that resolves on every EVM chain, but CoW has not deployed the stack on the others (`eth_getCode` is `0x` on CronosChain/zkSync/Blast), so accepting it chain-agnostically would have let a payload relabelled `cowswap` on an unsupported chain pass both guards and have the co-signer sign an ERC-20 approve to an address anyone can later claim. `li.fi`/`swapkit` (and the legacy `''`, which is also the proto3 default an attacker gets simply by clearing the field) remain the residual gap (they legitimately route through many different contracts and cannot be address-allow-listed); fully closing that needs the provider identity to be a trusted proto oneof discriminant rather than a free string, which is a larger cross-repo, cross-consumer schema change tracked separately in sdk#1457.
|
|
28
|
+
|
|
29
|
+
- [#1316](https://github.com/vultisig/vultisig-sdk/pull/1316) [`69a3f75`](https://github.com/vultisig/vultisig-sdk/commit/69a3f75c265e19682e6dbdac0fdb640c53d73b33) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Stop reporting Cosmos broadcast as successful when the transaction is included on-chain but execution failed (DeliverTx code !== 0), and make sure the broadcast retry wrapper never misreads that failure as a transient transport error and resends it.
|
|
30
|
+
|
|
31
|
+
- [#1273](https://github.com/vultisig/vultisig-sdk/pull/1273) [`e3d8568`](https://github.com/vultisig/vultisig-sdk/commit/e3d8568a04a6dcd977ccaeeeb5bcf5da080fd275) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Return the Cosmos transaction hash when CosmJS accepts a broadcast but times out waiting for indexing, leaving confirmation to status polling instead of reporting broadcast failure.
|
|
32
|
+
|
|
33
|
+
- [#1427](https://github.com/vultisig/vultisig-sdk/pull/1427) [`47a63df`](https://github.com/vultisig/vultisig-sdk/commit/47a63dfc8613405b7be1105233627e66a163d7c7) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Re-check the CowSwap order receiver at the signing (EIP-712 digest construction) step, not only at quote time. `assertValidCustomRecipient` rejects a zero/burn/malformed receiver when a quote is built, but an MPC co-signer never sees the quote — it decodes a `cowswap-order:` blob from the KeysignPayload (shape-validated only) and builds the digest to sign. `buildCowSwapOrderTypedData` now refuses a zero, burn (`0x…dead`), or malformed-non-EVM receiver, so a hand-built payload can't be signed into an order that sends the buy tokens to an unrecoverable address. vultisig always sets an explicit receiver (never CowSwap's `address(0)` sentinel), so no legitimately-produced order is affected.
|
|
34
|
+
|
|
35
|
+
- [#1399](https://github.com/vultisig/vultisig-sdk/pull/1399) [`ceccf56`](https://github.com/vultisig/vultisig-sdk/commit/ceccf5633ebd7d838e26e2fcbac151c52d26af85) Thanks [@NeOMakinG](https://github.com/NeOMakinG)! - Fix a `0X`-prefixed (uppercase-X) burn recipient slipping the custom-recipient
|
|
36
|
+
guard on native THOR/Maya cross-chain swaps.
|
|
37
|
+
|
|
38
|
+
`findSwapQuote`'s `isEvmAddress` shape check was case-sensitive on the `0x`
|
|
39
|
+
prefix, so a recipient like `0X000…dEaD` failed the check, skipped the
|
|
40
|
+
zero/burn-address branch, and — on a native route where the CowSwap format
|
|
41
|
+
gate is unreachable — passed straight through as the swap destination, an
|
|
42
|
+
unrecoverable sink. The gate is now case-insensitive on the prefix (`/i`),
|
|
43
|
+
matching the Go guard; the burn comparison already lowercases, so this only
|
|
44
|
+
closes the bypass without changing any accepted address.
|
|
45
|
+
|
|
46
|
+
- [#1472](https://github.com/vultisig/vultisig-sdk/pull/1472) [`b5f880a`](https://github.com/vultisig/vultisig-sdk/commit/b5f880a2dea1e06239b6ccb1a35fbdb4994d5917) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Align Bittensor broadcast error handling with the shared Substrate safeguards.
|
|
47
|
+
|
|
48
|
+
- [#895](https://github.com/vultisig/vultisig-sdk/pull/895) [`0c4a090`](https://github.com/vultisig/vultisig-sdk/commit/0c4a090bc4f3868e2a3a20c9f12742344cf8350e) Thanks [@NeOMakinG](https://github.com/NeOMakinG)! - fix(swap): expose inner-executor approvalAddress on EVM swap routes (LiFi + SwapKit)
|
|
49
|
+
|
|
50
|
+
EVM aggregator routes (LI.FI, SwapKit) can delegate the ERC-20 `transferFrom` to an
|
|
51
|
+
inner executor contract that is distinct from the outer `tx.to` router. Approving only
|
|
52
|
+
`tx.to` leads to an "ERC20: transfer amount exceeds allowance" revert on-chain.
|
|
53
|
+
|
|
54
|
+
This fix threads the route's real spender address through as `evm.approvalAddress` on
|
|
55
|
+
`GeneralSwapTx`. Consumers building an ERC-20 approve leg MUST use this field as the
|
|
56
|
+
spender when present, falling back to `to` only when absent.
|
|
57
|
+
|
|
58
|
+
- [#1285](https://github.com/vultisig/vultisig-sdk/pull/1285) [`8a0bca6`](https://github.com/vultisig/vultisig-sdk/commit/8a0bca688ec606292df587559115cafcc3287fcf) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Fix fiat pricing for known non-EVM token identifiers.
|
|
59
|
+
|
|
60
|
+
- [#1431](https://github.com/vultisig/vultisig-sdk/pull/1431) [`8c02c8c`](https://github.com/vultisig/vultisig-sdk/commit/8c02c8c7e8463b5d57fbd5c338a1f95c6129feb2) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Reject a non-zero `tx.value` from a 1inch quote for a token-source swap. 1inch's `tx.value` flows through from the untrusted quote response verbatim (unlike Kyber, which constructs `value` itself), so a compromised/buggy response could set a non-zero value on a token→token swap and move native gas-coin the user never authorized alongside the swap. A token-source swap pulls the sell token via ERC-20 allowance, so `value` must be `0`; native-source swaps (where `value` is legitimately the sell amount) are unaffected.
|
|
61
|
+
|
|
62
|
+
- [#1415](https://github.com/vultisig/vultisig-sdk/pull/1415) [`01a66cf`](https://github.com/vultisig/vultisig-sdk/commit/01a66cf5c0110ea1ea439ddbca8e6b75179fc0c5) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Preserve exact uint64 Cosmos account sequences through account lookup and signing payload construction.
|
|
63
|
+
|
|
64
|
+
- [#1429](https://github.com/vultisig/vultisig-sdk/pull/1429) [`7226d49`](https://github.com/vultisig/vultisig-sdk/commit/7226d49d42cec673465aac5b49b54d4e47628ab6) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Fix the QBTC send broadcast reporting a false success on a DeliverTx failure. `broadcastQbtcTx` uses `BROADCAST_MODE_SYNC`, which only surfaces the CheckTx (mempool-admission) code — a DeliverTx execution failure (out-of-gas, revert) still returns `code: 0` at broadcast time — and the resolver returned success after only that check, with no inclusion poll. It also read `data.tx_response?.code && …`, treating a missing `tx_response` as success. The resolver now polls for inclusion and re-checks the DeliverTx `code` (mirroring the QBTC claim helper, whose `waitForTxInclusion` is extracted to a shared `waitForQbtcTxInclusion`): a confirmed DeliverTx failure throws a non-retryable error, an unconfirmable inclusion (timeout / transient RPC error) is left in-flight for the status resolver, and a missing/failed CheckTx code is verified by hash instead of trusted.
|
|
65
|
+
|
|
66
|
+
- [#1428](https://github.com/vultisig/vultisig-sdk/pull/1428) [`0de8684`](https://github.com/vultisig/vultisig-sdk/commit/0de8684706f1b538a459acca0e55bf15c95a91f3) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Fix the React Native LiFi quote override applying a flat 1% slippage and discarding the caller's slippage. `platforms/react-native/overrides/getLifiSwapQuote.ts` hardcoded `slippage: 0.01` and had no `slippage`/`ticker` input, so on RN (most users) every LiFi quote used 1% — stable pairs that get the 0.3% tier on the core path got 1% (a wider MEV/loss surface), and an explicit tight-tolerance request was silently dropped (LiFi bakes `minAmountOut` from it). The tiered/override resolution (`resolveLifiSlippage`) is now extracted to a shared `lifi/api/lifiSlippage` module that both the core path and the RN override use, so they resolve slippage identically.
|
|
67
|
+
|
|
68
|
+
- [#1377](https://github.com/vultisig/vultisig-sdk/pull/1377) [`a971dfa`](https://github.com/vultisig/vultisig-sdk/commit/a971dfa99274b419863f83a078868f25a8241235) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Re-assert the aggregator router allow-list (1inch/kyber) and the Solana Jupiter
|
|
69
|
+
program + fund-movement guard on the MPC co-signer signing-input path, not only
|
|
70
|
+
at quote construction. Every co-signer independently rebuilds the signing input
|
|
71
|
+
from the shared KeysignPayload, so a compromised initiator could otherwise hand
|
|
72
|
+
a co-signer an unvalidated swap destination (EVM `quote.tx.to`) or a spliced
|
|
73
|
+
drain instruction (Solana `quote.tx.data`) and have it signed verbatim. Both
|
|
74
|
+
guards are pure gates: they fail closed for enforced providers or no-op, and
|
|
75
|
+
never mutate the signed bytes, so cross-device pre-signing hash agreement is
|
|
76
|
+
unchanged.
|
|
77
|
+
|
|
78
|
+
- [#1430](https://github.com/vultisig/vultisig-sdk/pull/1430) [`d01ac2e`](https://github.com/vultisig/vultisig-sdk/commit/d01ac2ee87d080def76454adcf5313726a916ed8) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Fix the Sui broadcast reporting a false success for a transaction that aborted on-chain (sdk#1398). `broadcastSuiTx` called `executeTransactionBlock` without requesting effects, so a tx that executed but aborted (MoveAbort / InsufficientGas) resolved with a digest — an RPC-level success that is not execution success — and was returned as a successful broadcast. It now requests `showEffects` and throws unless `effects.status.status === 'success'` — mirroring the Sui status resolver, so a missing or unknown status fails closed instead of defaulting to success. The throw is a `DeliverTxFailedError` so the transient-retry wrapper cannot re-broadcast an already-aborted transaction. An RPC-level error still falls through to `verifyBroadcastByHash` unchanged.
|
|
79
|
+
|
|
80
|
+
- [#1413](https://github.com/vultisig/vultisig-sdk/pull/1413) [`358c27b`](https://github.com/vultisig/vultisig-sdk/commit/358c27ba3bdd94813d00ec966ba43c8cc46f49e0) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Fix `RawBroadcastService`'s Sui raw-broadcast path reporting a false success for a transaction that failed on-chain (sdk#1398). It called `executeTransactionBlock` without requesting effects, so a tx that reverted (MoveAbort / InsufficientGas) resolved with a digest — an RPC-level success that is not execution success — and was returned as broadcast. It now requests `showEffects` and asserts the effects status via the shared `assertSuiTxSucceeded` helper (extracted from the `broadcastSuiTx` resolver, which already guarded against this), throwing a non-retryable error on a failed execution instead of reporting success.
|
|
81
|
+
|
|
82
|
+
- [#1377](https://github.com/vultisig/vultisig-sdk/pull/1377) [`a971dfa`](https://github.com/vultisig/vultisig-sdk/commit/a971dfa99274b419863f83a078868f25a8241235) Thanks [@gomesalexandre](https://github.com/gomesalexandre)! - Bind the ERC-20 approval spender to the verified swap router on the co-signer signing-input path for enforced aggregator providers (1inch/kyber). Follow-up to the signing-path router guard: `quote.tx.to` was re-asserted, but `erc20ApprovePayload.spender` is a separate wire field the approve resolver reads verbatim, so a payload could pass the router check yet still carry an approve granting an attacker an allowance (approval-drain). The bind runs in the approve branch (where the field is still present) and requires `spender === quote.tx.to` for enforced providers; unenforced providers stay unbound (notably cowswap, whose spender is legitimately the GPv2VaultRelayer, not `tx.to`). Monotonic gate: throws or no-ops, never mutates signed bytes. Initiators set the two equal by construction, so only a hand-built/tampered payload trips it.
|
|
83
|
+
|
|
84
|
+
- [#1271](https://github.com/vultisig/vultisig-sdk/pull/1271) [`3a40960`](https://github.com/vultisig/vultisig-sdk/commit/3a40960cc6391b69bbe6371874889b64399d64b9) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Swap surface hygiene: SwapService.getQuote now forwards affiliateConfig (per-provider fee-owner overrides) to core findSwapQuote instead of silently dropping it - the field is added to SwapQuoteParams, default behavior unchanged when omitted. The swapEnabledChains aggregate now unions every provider list (kyber/jupiter/cowswap were missing, complete only by accident via LiFi's superset), and kyberSwapEnabledChains drops Zksync/Blast, which Kyber's API 404s on.
|
|
85
|
+
|
|
3
86
|
## 2.26.0
|
|
4
87
|
|
|
5
88
|
### Minor Changes
|
|
@@ -6,6 +6,7 @@ type CosmosAccountInfo = {
|
|
|
6
6
|
pubkey: Pubkey | null;
|
|
7
7
|
accountNumber: bigint;
|
|
8
8
|
sequence: number;
|
|
9
|
+
sequenceBigInt: bigint;
|
|
9
10
|
latestBlock: string;
|
|
10
11
|
};
|
|
11
12
|
export declare const getCosmosAccountInfo: ({ chain, address, }: ChainAccount<CosmosChain>) => Promise<CosmosAccountInfo>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getCosmosAccountInfo.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/account/getCosmosAccountInfo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAS,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAA;
|
|
1
|
+
{"version":3,"file":"getCosmosAccountInfo.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/account/getCosmosAccountInfo.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAS,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAC/D,OAAO,EAAE,YAAY,EAAE,MAAM,mCAAmC,CAAA;AAmMhE,KAAK,iBAAiB,GAAG;IACvB,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACrB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAU,qBAGxC,YAAY,CAAC,WAAW,CAAC,KAAG,OAAO,CAAC,iBAAiB,CAyDvD,CAAA"}
|
|
@@ -1,24 +1,44 @@
|
|
|
1
1
|
import { Chain } from '@vultisig/core-chain/Chain';
|
|
2
2
|
import { getCosmosClient } from '@vultisig/core-chain/chains/cosmos/client';
|
|
3
3
|
import { getCosmosRpcUrl } from '@vultisig/core-chain/chains/cosmos/getCosmosRpcUrl';
|
|
4
|
+
import { parseUint64 } from '@vultisig/core-chain/chains/cosmos/parseUint64';
|
|
5
|
+
import { HttpResponseError } from '@vultisig/lib-utils/fetch/HttpResponseError';
|
|
4
6
|
import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
|
|
5
7
|
const parseLcdAccount = (resp) => {
|
|
6
8
|
const acc = resp.account;
|
|
9
|
+
// An HTTP-success response without the auth account envelope is malformed,
|
|
10
|
+
// not authoritative evidence that the account does not exist. Only a
|
|
11
|
+
// transport-level not-found result (handled by tryLcd) may fall through to
|
|
12
|
+
// the new-account sequence-zero default.
|
|
7
13
|
if (!acc)
|
|
8
|
-
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
const sequence = Number(base.sequence ?? '0');
|
|
13
|
-
if (!Number.isFinite(sequence))
|
|
14
|
-
return null;
|
|
15
|
-
return { accountNumber, sequence };
|
|
14
|
+
throw new Error('Invalid Cosmos account data: missing account');
|
|
15
|
+
const nestedBase = acc.base_vesting_account?.base_account ?? acc.base_account;
|
|
16
|
+
if (!nestedBase && acc['@type'] && acc['@type'] !== '/cosmos.auth.v1beta1.BaseAccount') {
|
|
17
|
+
throw new Error(`Invalid Cosmos account data: unsupported account type ${acc['@type']}`);
|
|
16
18
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return null;
|
|
19
|
+
const base = nestedBase ?? acc;
|
|
20
|
+
if (typeof base.address !== 'string' || base.address.length === 0) {
|
|
21
|
+
throw new Error('Invalid Cosmos account data: missing address');
|
|
21
22
|
}
|
|
23
|
+
// ProtoJSON omits implicit-presence uint64 fields when their value is zero.
|
|
24
|
+
// Once a supported account envelope/base-account shape is established,
|
|
25
|
+
// absence therefore means 0n. Present malformed or out-of-range values must
|
|
26
|
+
// still fail closed through parseUint64.
|
|
27
|
+
const accountNumber = base.account_number === undefined
|
|
28
|
+
? 0n
|
|
29
|
+
: parseUint64({
|
|
30
|
+
value: base.account_number,
|
|
31
|
+
field: 'account_number',
|
|
32
|
+
context: 'Cosmos account',
|
|
33
|
+
});
|
|
34
|
+
const sequenceBigInt = base.sequence === undefined
|
|
35
|
+
? 0n
|
|
36
|
+
: parseUint64({
|
|
37
|
+
value: base.sequence,
|
|
38
|
+
field: 'sequence',
|
|
39
|
+
context: 'Cosmos account',
|
|
40
|
+
});
|
|
41
|
+
return { address: base.address, accountNumber, sequence: Number(sequenceBigInt), sequenceBigInt };
|
|
22
42
|
};
|
|
23
43
|
// LCD fallback for Tendermint-RPC account lookups that return null.
|
|
24
44
|
// Native @cosmjs/stargate.getAccount() returns null in TWO indistinguishable
|
|
@@ -58,45 +78,106 @@ const COSMOS_LCD_FALLBACK_URLS = {
|
|
|
58
78
|
[Chain.Dydx]: 'https://dydx-api.polkachu.com',
|
|
59
79
|
[Chain.Akash]: 'https://akash-api.polkachu.com',
|
|
60
80
|
};
|
|
81
|
+
const isAuthoritativeCosmosAccountNotFound = (error) => {
|
|
82
|
+
if (error.status !== 404)
|
|
83
|
+
return false;
|
|
84
|
+
const body = error.body;
|
|
85
|
+
if (typeof body === 'string') {
|
|
86
|
+
return /account[^\n]*not found|no account found/i.test(body);
|
|
87
|
+
}
|
|
88
|
+
if (!body || typeof body !== 'object')
|
|
89
|
+
return false;
|
|
90
|
+
const message = typeof body.message === 'string'
|
|
91
|
+
? body.message
|
|
92
|
+
: typeof body.error === 'string'
|
|
93
|
+
? body.error
|
|
94
|
+
: null;
|
|
95
|
+
return message !== null && /account[^\n]*not found|no account found/i.test(message);
|
|
96
|
+
};
|
|
61
97
|
const tryLcd = async (base, address) => {
|
|
98
|
+
let resp;
|
|
62
99
|
try {
|
|
63
|
-
|
|
64
|
-
return parseLcdAccount(resp);
|
|
100
|
+
resp = await queryUrl(`${base}/cosmos/auth/v1beta1/accounts/${address}`);
|
|
65
101
|
}
|
|
66
|
-
catch {
|
|
67
|
-
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (error instanceof HttpResponseError && isAuthoritativeCosmosAccountNotFound(error)) {
|
|
104
|
+
return { status: 'not-found' };
|
|
105
|
+
}
|
|
106
|
+
return { status: 'unavailable', error };
|
|
68
107
|
}
|
|
108
|
+
// A transport failure can try another endpoint, but malformed response data
|
|
109
|
+
// is an integrity failure. Propagate it so signing cannot silently fall
|
|
110
|
+
// through to sequence 0.
|
|
111
|
+
const account = parseLcdAccount(resp);
|
|
112
|
+
if (account.address !== address) {
|
|
113
|
+
throw new Error(`Invalid Cosmos account data: address mismatch (${account.address})`);
|
|
114
|
+
}
|
|
115
|
+
return { status: 'found', account };
|
|
69
116
|
};
|
|
70
117
|
const fetchAccountViaLcd = async (chain, address) => {
|
|
71
118
|
const base = getCosmosRpcUrl(chain);
|
|
72
119
|
if (!base)
|
|
73
120
|
return null;
|
|
74
121
|
const primary = await tryLcd(base, address);
|
|
75
|
-
if (primary)
|
|
76
|
-
return primary;
|
|
77
|
-
//
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
122
|
+
if (primary.status === 'found')
|
|
123
|
+
return primary.account;
|
|
124
|
+
// A structured 404 is authoritative evidence that the account is absent;
|
|
125
|
+
// this is the only LCD outcome allowed to use the new-account zero default.
|
|
126
|
+
if (primary.status === 'not-found')
|
|
127
|
+
return null;
|
|
128
|
+
// Network/5xx failure is not evidence that the account is absent. Try the
|
|
129
|
+
// registered fallback, then propagate the failure if exact data is still
|
|
130
|
+
// unavailable instead of silently constructing a sequence-zero payload.
|
|
81
131
|
const fallback = COSMOS_LCD_FALLBACK_URLS[chain];
|
|
82
132
|
if (!fallback)
|
|
133
|
+
throw primary.error;
|
|
134
|
+
const secondary = await tryLcd(fallback, address);
|
|
135
|
+
if (secondary.status === 'found')
|
|
136
|
+
return secondary.account;
|
|
137
|
+
if (secondary.status === 'not-found')
|
|
83
138
|
return null;
|
|
84
|
-
|
|
139
|
+
throw secondary.error;
|
|
85
140
|
};
|
|
86
141
|
export const getCosmosAccountInfo = async ({ chain, address, }) => {
|
|
87
142
|
const client = await getCosmosClient(chain);
|
|
88
|
-
const
|
|
143
|
+
const accountResultPromise = client.getAccount(address).then(value => ({ value, error: undefined }), (error) => ({ value: null, error }));
|
|
144
|
+
const [accountResult, block] = await Promise.all([accountResultPromise, client.getBlock()]);
|
|
145
|
+
const accountInfo = accountResult.value;
|
|
89
146
|
let accountNumber = accountInfo?.accountNumber;
|
|
90
147
|
let sequence = accountInfo?.sequence;
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
148
|
+
let sequenceBigInt;
|
|
149
|
+
if (accountInfo && Number.isSafeInteger(accountInfo.sequence) && accountInfo.sequence >= 0) {
|
|
150
|
+
sequenceBigInt = BigInt(accountInfo.sequence);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
// RPC returned null or a sequence that its number-based API cannot
|
|
154
|
+
// represent exactly. Prefer the LCD's raw uint64 string in both cases.
|
|
155
|
+
let lcd;
|
|
156
|
+
try {
|
|
157
|
+
lcd = await fetchAccountViaLcd(chain, address);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
if (accountResult.error)
|
|
161
|
+
throw accountResult.error;
|
|
162
|
+
if (accountInfo) {
|
|
163
|
+
throw new Error('Cosmos account sequence cannot be represented exactly', { cause: error });
|
|
164
|
+
}
|
|
165
|
+
throw error;
|
|
166
|
+
}
|
|
97
167
|
if (lcd) {
|
|
98
168
|
accountNumber = lcd.accountNumber;
|
|
99
169
|
sequence = lcd.sequence;
|
|
170
|
+
sequenceBigInt = lcd.sequenceBigInt;
|
|
171
|
+
}
|
|
172
|
+
else if (accountResult.error) {
|
|
173
|
+
// CosmJS decodes sequence through Uint64.toNumber(), which rejects
|
|
174
|
+
// before getAccount() can return when the chain value exceeds the
|
|
175
|
+
// safe-number range. Recover through LCD, but retain the original RPC
|
|
176
|
+
// failure when exact recovery is unavailable.
|
|
177
|
+
throw accountResult.error;
|
|
178
|
+
}
|
|
179
|
+
else if (accountInfo) {
|
|
180
|
+
throw new Error('Cosmos account sequence cannot be represented exactly');
|
|
100
181
|
}
|
|
101
182
|
}
|
|
102
183
|
const blockTimestampStr = block.header.time;
|
|
@@ -108,6 +189,7 @@ export const getCosmosAccountInfo = async ({ chain, address, }) => {
|
|
|
108
189
|
pubkey: accountInfo?.pubkey ?? null,
|
|
109
190
|
accountNumber: accountNumber ?? 0n,
|
|
110
191
|
sequence: sequence ?? 0,
|
|
192
|
+
sequenceBigInt: sequenceBigInt ?? 0n,
|
|
111
193
|
latestBlock,
|
|
112
194
|
};
|
|
113
195
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getCosmosAccountInfo.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/account/getCosmosAccountInfo.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAe,MAAM,4BAA4B,CAAA;AAE/D,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAA;AAC3E,OAAO,EAAE,eAAe,EAAE,MAAM,oDAAoD,CAAA;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;
|
|
1
|
+
{"version":3,"file":"getCosmosAccountInfo.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/account/getCosmosAccountInfo.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseUint64.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/parseUint64.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,GAAI,2BAA2B;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,KAAG,MAW3G,CAAA"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const maxUint64 = (1n << 64n) - 1n;
|
|
2
|
+
export const parseUint64 = ({ value, field, context }) => {
|
|
3
|
+
if (typeof value !== 'string' || !/^\d+$/.test(value)) {
|
|
4
|
+
throw new Error(`Invalid ${context} ${field}: expected an unsigned integer`);
|
|
5
|
+
}
|
|
6
|
+
const parsed = BigInt(value);
|
|
7
|
+
if (parsed > maxUint64) {
|
|
8
|
+
throw new Error(`Invalid ${context} ${field}: exceeds uint64`);
|
|
9
|
+
}
|
|
10
|
+
return parsed;
|
|
11
|
+
};
|
|
12
|
+
//# sourceMappingURL=parseUint64.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parseUint64.js","sourceRoot":"","sources":["../../../../../../packages/core/chain/chains/cosmos/parseUint64.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,GAAG,EAAE,CAAA;AAElC,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAsD,EAAU,EAAE;IACnH,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,WAAW,OAAO,IAAI,KAAK,gCAAgC,CAAC,CAAA;IAC9E,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IAC5B,IAAI,MAAM,GAAG,SAAS,EAAE,CAAC;QACvB,MAAM,IAAI,KAAK,CAAC,WAAW,OAAO,IAAI,KAAK,kBAAkB,CAAC,CAAA;IAChE,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broadcastClaimTx.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/qbtc/claim/broadcastClaimTx.ts"],"names":[],"mappings":"AAGA,KAAK,eAAe,GAAG;IACrB,8BAA8B;IAC9B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAA;IACpB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,KAAK,qBAAqB,GAAG;IAC3B,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAA;IACrB,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qEAAqE;IACrE,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACjC,CAAA;
|
|
1
|
+
{"version":3,"file":"broadcastClaimTx.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/qbtc/claim/broadcastClaimTx.ts"],"names":[],"mappings":"AAGA,KAAK,eAAe,GAAG;IACrB,8BAA8B;IAC9B,kBAAkB,EAAE,MAAM,CAAA;IAC1B,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAA;IACpB,qEAAqE;IACrE,YAAY,EAAE,MAAM,CAAA;IACpB,wBAAwB;IACxB,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAED,KAAK,qBAAqB,GAAG;IAC3B,2CAA2C;IAC3C,aAAa,EAAE,MAAM,CAAA;IACrB,uDAAuD;IACvD,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,qEAAqE;IACrE,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACjC,CAAA;AA2CD,KAAK,yBAAyB,GAAG;IAC/B,sEAAsE;IACtE,MAAM,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,kBAAkB,CAAC,EAAE,MAAM,CAAA;IAC3B,sCAAsC;IACtC,uBAAuB,CAAC,EAAE,MAAM,CAAA;CACjC,CAAA;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,oBAAoB,GAAU,0DAIxC,yBAAyB,KAAG,OAAO,CAAC,eAAe,CAiBrD,CAAA;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,gBAAgB,GAAU,yEAKpC,qBAAqB,KAAG,OAAO,CAAC,eAAe,CAiDjD,CAAA"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { qbtcRestUrl } from '@vultisig/core-chain/chains/cosmos/qbtc/tendermintRpcUrl';
|
|
2
|
-
import {
|
|
2
|
+
import { waitForQbtcTxInclusion } from '@vultisig/core-chain/chains/cosmos/qbtc/waitForQbtcTxInclusion';
|
|
3
3
|
const claimWithProofEventType = 'claim_with_proof';
|
|
4
4
|
const findEventAttr = (events, type, key) => events?.find(e => e.type === type)?.attributes?.find(a => a.key === key)?.value;
|
|
5
5
|
const parseClaimResultFromEvents = (events, txHash) => ({
|
|
@@ -14,31 +14,6 @@ const idempotentResult = (txHash) => ({
|
|
|
14
14
|
utxosSkipped: 0,
|
|
15
15
|
txHash,
|
|
16
16
|
});
|
|
17
|
-
/**
|
|
18
|
-
* Polls `/cosmos/tx/v1beta1/txs/{txHash}` until the tx is included in a
|
|
19
|
-
* block (200 OK) or the timeout fires. 404 means "not yet included" and
|
|
20
|
-
* triggers a retry. Other non-2xx statuses propagate as errors so we
|
|
21
|
-
* don't mask infra failures as "still pending".
|
|
22
|
-
*/
|
|
23
|
-
const waitForTxInclusion = async ({ txHash, timeoutMs, intervalMs, }) => {
|
|
24
|
-
const url = `${qbtcRestUrl}/cosmos/tx/v1beta1/txs/${txHash}`;
|
|
25
|
-
const deadline = Date.now() + timeoutMs;
|
|
26
|
-
while (Date.now() <= deadline) {
|
|
27
|
-
const response = await fetch(url);
|
|
28
|
-
if (response.ok) {
|
|
29
|
-
const data = await response.json();
|
|
30
|
-
if (data.tx_response)
|
|
31
|
-
return data.tx_response;
|
|
32
|
-
throw new Error(`QBTC claim tx ${txHash}: missing tx_response on inclusion query`);
|
|
33
|
-
}
|
|
34
|
-
if (response.status !== 404) {
|
|
35
|
-
const text = await response.text();
|
|
36
|
-
throw new Error(`QBTC claim inclusion query failed (${response.status}): ${text}`);
|
|
37
|
-
}
|
|
38
|
-
await sleep(intervalMs);
|
|
39
|
-
}
|
|
40
|
-
throw new Error(`QBTC claim tx ${txHash} not included within ${timeoutMs}ms`);
|
|
41
|
-
};
|
|
42
17
|
/**
|
|
43
18
|
* Polls the chain for an already-broadcast claim tx (e.g. one submitted by
|
|
44
19
|
* the proof service via `generateClaimProof({ broadcast: true })`) and parses
|
|
@@ -48,7 +23,7 @@ const waitForTxInclusion = async ({ txHash, timeoutMs, intervalMs, }) => {
|
|
|
48
23
|
* didn't broadcast the tx themselves can still show real claim amounts.
|
|
49
24
|
*/
|
|
50
25
|
export const waitForClaimTxResult = async ({ txHash, inclusionTimeoutMs = 30_000, inclusionPollIntervalMs = 1_000, }) => {
|
|
51
|
-
const included = await
|
|
26
|
+
const included = await waitForQbtcTxInclusion({
|
|
52
27
|
txHash,
|
|
53
28
|
timeoutMs: inclusionTimeoutMs,
|
|
54
29
|
intervalMs: inclusionPollIntervalMs,
|
|
@@ -102,7 +77,7 @@ export const broadcastClaimTx = async ({ txBytesBase64, txHash, inclusionTimeout
|
|
|
102
77
|
throw new Error(`QBTC claim tx error: ${log}`);
|
|
103
78
|
}
|
|
104
79
|
// CheckTx passed; wait for DeliverTx events.
|
|
105
|
-
const included = await
|
|
80
|
+
const included = await waitForQbtcTxInclusion({
|
|
106
81
|
txHash,
|
|
107
82
|
timeoutMs: inclusionTimeoutMs,
|
|
108
83
|
intervalMs: inclusionPollIntervalMs,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"broadcastClaimTx.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/qbtc/claim/broadcastClaimTx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0DAA0D,CAAA;AACtF,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"broadcastClaimTx.js","sourceRoot":"","sources":["../../../../../../../../packages/core/chain/chains/cosmos/qbtc/claim/broadcastClaimTx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0DAA0D,CAAA;AACtF,OAAO,EAAE,sBAAsB,EAAE,MAAM,gEAAgE,CAAA;AAkDvG,MAAM,uBAAuB,GAAG,kBAAkB,CAAA;AAElD,MAAM,aAAa,GAAG,CAAC,MAA6B,EAAE,IAAY,EAAE,GAAW,EAAsB,EAAE,CACrG,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,GAAG,CAAC,EAAE,KAAK,CAAA;AAEjF,MAAM,0BAA0B,GAAG,CAAC,MAA6B,EAAE,MAAc,EAAmB,EAAE,CAAC,CAAC;IACtG,kBAAkB,EAAE,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,uBAAuB,EAAE,cAAc,CAAC,IAAI,GAAG,CAAC;IACjG,YAAY,EAAE,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,uBAAuB,EAAE,eAAe,CAAC,IAAI,GAAG,CAAC;IAC5F,YAAY,EAAE,MAAM,CAAC,aAAa,CAAC,MAAM,EAAE,uBAAuB,EAAE,eAAe,CAAC,IAAI,GAAG,CAAC;IAC5F,MAAM;CACP,CAAC,CAAA;AAEF,MAAM,gBAAgB,GAAG,CAAC,MAAc,EAAmB,EAAE,CAAC,CAAC;IAC7D,kBAAkB,EAAE,EAAE;IACtB,YAAY,EAAE,CAAC;IACf,YAAY,EAAE,CAAC;IACf,MAAM;CACP,CAAC,CAAA;AAWF;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,EAAE,EACzC,MAAM,EACN,kBAAkB,GAAG,MAAM,EAC3B,uBAAuB,GAAG,KAAK,GACL,EAA4B,EAAE;IACxD,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC;QAC5C,MAAM;QACN,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,uBAAuB;KACpC,CAAC,CAAA;IAEF,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,iBAAiB,MAAM,wCAAwC,CAAC,CAAA;IAClF,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAA;QAC5C,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAA;IAChD,CAAC;IAED,OAAO,0BAA0B,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC5D,CAAC,CAAA;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,EACrC,aAAa,EACb,MAAM,EACN,kBAAkB,GAAG,MAAM,EAC3B,uBAAuB,GAAG,KAAK,GACT,EAA4B,EAAE;IACpD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,wBAAwB,EAAE;QACnE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,QAAQ,EAAE,aAAa;YACvB,IAAI,EAAE,qBAAqB;SAC5B,CAAC;KACH,CAAC,CAAA;IAEF,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;QAClC,IAAI,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC;YAChD,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAA;QACjC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAA;IAC9E,CAAC;IAED,MAAM,IAAI,GAA2B,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;IAE1D,IAAI,OAAO,IAAI,CAAC,WAAW,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAA;IAC1E,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QAChC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,IAAI,IAAI,CAAC,WAAW,CAAC,GAAG,CAAA;QAC5D,IAAI,GAAG,EAAE,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC;YAChD,OAAO,gBAAgB,CAAC,MAAM,CAAC,CAAA;QACjC,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAA;IAChD,CAAC;IAED,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,MAAM,sBAAsB,CAAC;QAC5C,MAAM;QACN,SAAS,EAAE,kBAAkB;QAC7B,UAAU,EAAE,uBAAuB;KACpC,CAAC,CAAA;IAEF,IAAI,OAAO,QAAQ,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,KAAK,CAAC,iBAAiB,MAAM,wCAAwC,CAAC,CAAA;IAClF,CAAC;IAED,IAAI,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,GAAG,CAAA;QAC5C,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAA;IAChD,CAAC;IAED,OAAO,0BAA0B,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC5D,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getQbtcAccountInfo.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/qbtc/getQbtcAccountInfo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getQbtcAccountInfo.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/qbtc/getQbtcAccountInfo.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,kBAAkB,GAAU,aAAa;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE;;;;;;;EA6BxE,CAAA"}
|
|
@@ -1,23 +1,21 @@
|
|
|
1
|
+
import { parseUint64 } from '@vultisig/core-chain/chains/cosmos/parseUint64';
|
|
1
2
|
import { qbtcRestUrl } from '@vultisig/core-chain/chains/cosmos/qbtc/tendermintRpcUrl';
|
|
2
3
|
import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
|
|
3
|
-
const maxUint64 = (1n << 64n) - 1n;
|
|
4
|
-
const parseUint64 = (value, field) => {
|
|
5
|
-
if (typeof value !== 'string' || !/^\d+$/.test(value)) {
|
|
6
|
-
throw new Error(`Invalid QBTC ${field}: expected an unsigned integer`);
|
|
7
|
-
}
|
|
8
|
-
const parsed = BigInt(value);
|
|
9
|
-
if (parsed > maxUint64) {
|
|
10
|
-
throw new Error(`Invalid QBTC ${field}: exceeds uint64`);
|
|
11
|
-
}
|
|
12
|
-
return parsed;
|
|
13
|
-
};
|
|
14
4
|
export const getQbtcAccountInfo = async ({ address }) => {
|
|
15
5
|
const [accountData, blockData] = await Promise.all([
|
|
16
6
|
queryUrl(`${qbtcRestUrl}/cosmos/auth/v1beta1/accounts/${address}`),
|
|
17
7
|
queryUrl(`${qbtcRestUrl}/cosmos/base/tendermint/v1beta1/blocks/latest`),
|
|
18
8
|
]);
|
|
19
|
-
const accountNumberBigInt = parseUint64(
|
|
20
|
-
|
|
9
|
+
const accountNumberBigInt = parseUint64({
|
|
10
|
+
value: accountData.account.account_number,
|
|
11
|
+
field: 'account_number',
|
|
12
|
+
context: 'QBTC',
|
|
13
|
+
});
|
|
14
|
+
const sequenceBigInt = parseUint64({
|
|
15
|
+
value: accountData.account.sequence,
|
|
16
|
+
field: 'sequence',
|
|
17
|
+
context: 'QBTC',
|
|
18
|
+
});
|
|
21
19
|
const blockTimestampStr = blockData.block.header.time;
|
|
22
20
|
const blockTimestampNs = BigInt(new Date(blockTimestampStr).getTime()) * 1000000n;
|
|
23
21
|
const timeoutNs = blockTimestampNs + 600000000000n;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getQbtcAccountInfo.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/qbtc/getQbtcAccountInfo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"getQbtcAccountInfo.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/qbtc/getQbtcAccountInfo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,gDAAgD,CAAA;AAC5E,OAAO,EAAE,WAAW,EAAE,MAAM,0DAA0D,CAAA;AACtF,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAmB7D,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,EAAE,EAAE,OAAO,EAAuB,EAAE,EAAE;IAC3E,MAAM,CAAC,WAAW,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QACjD,QAAQ,CAAkB,GAAG,WAAW,iCAAiC,OAAO,EAAE,CAAC;QACnF,QAAQ,CAAgB,GAAG,WAAW,+CAA+C,CAAC;KACvF,CAAC,CAAA;IAEF,MAAM,mBAAmB,GAAG,WAAW,CAAC;QACtC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,cAAc;QACzC,KAAK,EAAE,gBAAgB;QACvB,OAAO,EAAE,MAAM;KAChB,CAAC,CAAA;IACF,MAAM,cAAc,GAAG,WAAW,CAAC;QACjC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC,QAAQ;QACnC,KAAK,EAAE,UAAU;QACjB,OAAO,EAAE,MAAM;KAChB,CAAC,CAAA;IACF,MAAM,iBAAiB,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAA;IACrD,MAAM,gBAAgB,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC,OAAO,EAAE,CAAC,GAAG,QAAU,CAAA;IACnF,MAAM,SAAS,GAAG,gBAAgB,GAAG,aAAgB,CAAA;IACrD,MAAM,WAAW,GAAG,GAAG,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,IAAI,SAAS,EAAE,CAAA;IAEnE,OAAO;QACL,OAAO;QACP,aAAa,EAAE,MAAM,CAAC,mBAAmB,CAAC;QAC1C,QAAQ,EAAE,MAAM,CAAC,cAAc,CAAC;QAChC,mBAAmB;QACnB,cAAc;QACd,WAAW;KACZ,CAAA;AACH,CAAC,CAAA"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export type QbtcTxEventAttribute = {
|
|
2
|
+
key: string;
|
|
3
|
+
value?: string;
|
|
4
|
+
};
|
|
5
|
+
export type QbtcTxEvent = {
|
|
6
|
+
type: string;
|
|
7
|
+
attributes?: QbtcTxEventAttribute[];
|
|
8
|
+
};
|
|
9
|
+
export type QbtcTxResponse = {
|
|
10
|
+
code?: number;
|
|
11
|
+
txhash?: string;
|
|
12
|
+
raw_log?: string;
|
|
13
|
+
log?: string;
|
|
14
|
+
events?: QbtcTxEvent[];
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Polls `/cosmos/tx/v1beta1/txs/{txHash}` until the tx is included in a block (200 OK) or the
|
|
18
|
+
* timeout fires. 404 means "not yet included" and triggers a retry. Other non-2xx statuses
|
|
19
|
+
* propagate as errors so we don't mask infra failures as "still pending".
|
|
20
|
+
*
|
|
21
|
+
* QBTC broadcasts use `BROADCAST_MODE_SYNC`, which only surfaces the CheckTx (mempool-admission)
|
|
22
|
+
* code — a DeliverTx failure (out-of-gas, execution revert) still returns `code: 0` at broadcast
|
|
23
|
+
* time. Both the claim helper (broadcastClaimTx) and the send broadcast resolver
|
|
24
|
+
* (tx/broadcast/resolvers/qbtc) poll here and re-check the included `code` so an execution failure
|
|
25
|
+
* isn't reported as a successful broadcast.
|
|
26
|
+
*/
|
|
27
|
+
export declare const waitForQbtcTxInclusion: ({ txHash, timeoutMs, intervalMs, }: {
|
|
28
|
+
txHash: string;
|
|
29
|
+
timeoutMs: number;
|
|
30
|
+
intervalMs: number;
|
|
31
|
+
}) => Promise<QbtcTxResponse>;
|
|
32
|
+
//# sourceMappingURL=waitForQbtcTxInclusion.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waitForQbtcTxInclusion.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/qbtc/waitForQbtcTxInclusion.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,oBAAoB,GAAG;IACjC,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAA;CACpC,CAAA;AAED,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,WAAW,EAAE,CAAA;CACvB,CAAA;AAMD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,GAAU,oCAI1C;IACD,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB,KAAG,OAAO,CAAC,cAAc,CAsBzB,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { qbtcRestUrl } from '@vultisig/core-chain/chains/cosmos/qbtc/tendermintRpcUrl';
|
|
2
|
+
import { sleep } from '@vultisig/lib-utils/sleep';
|
|
3
|
+
/**
|
|
4
|
+
* Polls `/cosmos/tx/v1beta1/txs/{txHash}` until the tx is included in a block (200 OK) or the
|
|
5
|
+
* timeout fires. 404 means "not yet included" and triggers a retry. Other non-2xx statuses
|
|
6
|
+
* propagate as errors so we don't mask infra failures as "still pending".
|
|
7
|
+
*
|
|
8
|
+
* QBTC broadcasts use `BROADCAST_MODE_SYNC`, which only surfaces the CheckTx (mempool-admission)
|
|
9
|
+
* code — a DeliverTx failure (out-of-gas, execution revert) still returns `code: 0` at broadcast
|
|
10
|
+
* time. Both the claim helper (broadcastClaimTx) and the send broadcast resolver
|
|
11
|
+
* (tx/broadcast/resolvers/qbtc) poll here and re-check the included `code` so an execution failure
|
|
12
|
+
* isn't reported as a successful broadcast.
|
|
13
|
+
*/
|
|
14
|
+
export const waitForQbtcTxInclusion = async ({ txHash, timeoutMs, intervalMs, }) => {
|
|
15
|
+
const url = `${qbtcRestUrl}/cosmos/tx/v1beta1/txs/${txHash}`;
|
|
16
|
+
const deadline = Date.now() + timeoutMs;
|
|
17
|
+
while (Date.now() <= deadline) {
|
|
18
|
+
const response = await fetch(url);
|
|
19
|
+
if (response.ok) {
|
|
20
|
+
const data = await response.json();
|
|
21
|
+
if (data.tx_response)
|
|
22
|
+
return data.tx_response;
|
|
23
|
+
throw new Error(`QBTC tx ${txHash}: missing tx_response on inclusion query`);
|
|
24
|
+
}
|
|
25
|
+
if (response.status !== 404) {
|
|
26
|
+
const text = await response.text();
|
|
27
|
+
throw new Error(`QBTC inclusion query failed (${response.status}): ${text}`);
|
|
28
|
+
}
|
|
29
|
+
await sleep(intervalMs);
|
|
30
|
+
}
|
|
31
|
+
throw new Error(`QBTC tx ${txHash} not included within ${timeoutMs}ms`);
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=waitForQbtcTxInclusion.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waitForQbtcTxInclusion.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/chains/cosmos/qbtc/waitForQbtcTxInclusion.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,0DAA0D,CAAA;AACtF,OAAO,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAA;AAwBjD;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,EAC3C,MAAM,EACN,SAAS,EACT,UAAU,GAKX,EAA2B,EAAE;IAC5B,MAAM,GAAG,GAAG,GAAG,WAAW,0BAA0B,MAAM,EAAE,CAAA;IAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;IAEvC,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAA;QAEjC,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,GAAyB,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YACxD,IAAI,IAAI,CAAC,WAAW;gBAAE,OAAO,IAAI,CAAC,WAAW,CAAA;YAC7C,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,0CAA0C,CAAC,CAAA;QAC9E,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAA;YAClC,MAAM,IAAI,KAAK,CAAC,gCAAgC,QAAQ,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAA;QAC9E,CAAC;QAED,MAAM,KAAK,CAAC,UAAU,CAAC,CAAA;IACzB,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,WAAW,MAAM,wBAAwB,SAAS,IAAI,CAAC,CAAA;AACzE,CAAC,CAAA"}
|
|
@@ -6,6 +6,12 @@ export type GetEvmChainBalancesInput = {
|
|
|
6
6
|
address: Address;
|
|
7
7
|
coins: AccountCoinKey<EvmChain>[];
|
|
8
8
|
};
|
|
9
|
+
/**
|
|
10
|
+
* Balances keyed by `accountCoinKeyToString`. A key is present ONLY when the balance was actually
|
|
11
|
+
* READ: a present `0n` is a genuine zero balance, an ABSENT key means "unknown, the call failed".
|
|
12
|
+
* Callers must not conflate the two — caching/emitting a fabricated zero for a coin the user owns
|
|
13
|
+
* shows a real 0 for an owned asset until the cache expires.
|
|
14
|
+
*/
|
|
9
15
|
export type EvmChainBalances = Record<string, bigint>;
|
|
10
16
|
export declare const getEvmChainBalances: (input: GetEvmChainBalancesInput) => Promise<EvmChainBalances>;
|
|
11
17
|
//# sourceMappingURL=getEvmChainBalances.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getEvmChainBalances.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/balance/getEvmChainBalances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAErD,OAAO,EAAE,cAAc,EAA0B,MAAM,uCAAuC,CAAA;AAE9F,OAAO,EAAE,OAAO,EAAsB,MAAM,MAAM,CAAA;AAMlD,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,QAAQ,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAA;CAClC,CAAA;AAED,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"getEvmChainBalances.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/coin/balance/getEvmChainBalances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAErD,OAAO,EAAE,cAAc,EAA0B,MAAM,uCAAuC,CAAA;AAE9F,OAAO,EAAE,OAAO,EAAsB,MAAM,MAAM,CAAA;AAMlD,MAAM,MAAM,wBAAwB,GAAG;IACrC,KAAK,EAAE,QAAQ,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAA;CAClC,CAAA;AAED;;;;;GAKG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAmBrD,eAAO,MAAM,mBAAmB,GAAU,OAAO,wBAAwB,KAAG,OAAO,CAAC,gBAAgB,CAuDnG,CAAA"}
|