@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swapEnabledChains.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/swap/swapEnabledChains.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"swapEnabledChains.d.ts","sourceRoot":"","sources":["../../../../../packages/core/chain/swap/swapEnabledChains.ts"],"names":[],"mappings":"AAcA,eAAO,MAAM,iBAAiB,kgCAQpB,CAAA"}
|
|
@@ -1,10 +1,22 @@
|
|
|
1
|
+
import { cowSwapSupportedChains } from '@vultisig/core-chain/swap/general/cowswap/config';
|
|
2
|
+
import { jupiterSwapEnabledChains } from '@vultisig/core-chain/swap/general/jupiter/JupiterSwapEnabledChains';
|
|
3
|
+
import { kyberSwapEnabledChains } from '@vultisig/core-chain/swap/general/kyber/chains';
|
|
1
4
|
import { lifiSwapEnabledChains } from '@vultisig/core-chain/swap/general/lifi/LifiSwapEnabledChains';
|
|
2
5
|
import { oneInchSwapEnabledChains } from '@vultisig/core-chain/swap/general/oneInch/OneInchSwapEnabledChains';
|
|
3
6
|
import { swapKitEnabledChains } from '@vultisig/core-chain/swap/general/swapkit/SwapKitEnabledChains';
|
|
4
7
|
import { nativeSwapEnabledChains } from '@vultisig/core-chain/swap/native/NativeSwapChain';
|
|
8
|
+
// EVERY provider's enabled-chain list must appear in this union (sdk#1151).
|
|
9
|
+
// It used to omit Kyber/Jupiter/CowSwap and was complete only by accident —
|
|
10
|
+
// LiFi's list happened to be a superset of theirs. The first provider added
|
|
11
|
+
// on a chain LiFi doesn't serve would have silently under-reported
|
|
12
|
+
// isSwapSupported/getSupportedChains (which drive the swap picker and the
|
|
13
|
+
// Swap primary action). Correctness-by-construction beats a hidden invariant.
|
|
5
14
|
export const swapEnabledChains = [
|
|
6
15
|
...nativeSwapEnabledChains,
|
|
16
|
+
...cowSwapSupportedChains,
|
|
17
|
+
...kyberSwapEnabledChains,
|
|
7
18
|
...oneInchSwapEnabledChains,
|
|
19
|
+
...jupiterSwapEnabledChains,
|
|
8
20
|
...lifiSwapEnabledChains,
|
|
9
21
|
...swapKitEnabledChains,
|
|
10
22
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"swapEnabledChains.js","sourceRoot":"","sources":["../../../../../packages/core/chain/swap/swapEnabledChains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,8DAA8D,CAAA;AACpG,OAAO,EAAE,wBAAwB,EAAE,MAAM,oEAAoE,CAAA;AAC7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,gEAAgE,CAAA;AACrG,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAE1F,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,GAAG,uBAAuB;IAC1B,GAAG,wBAAwB;IAC3B,GAAG,qBAAqB;IACxB,GAAG,oBAAoB;CACf,CAAA"}
|
|
1
|
+
{"version":3,"file":"swapEnabledChains.js","sourceRoot":"","sources":["../../../../../packages/core/chain/swap/swapEnabledChains.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,kDAAkD,CAAA;AACzF,OAAO,EAAE,wBAAwB,EAAE,MAAM,oEAAoE,CAAA;AAC7G,OAAO,EAAE,sBAAsB,EAAE,MAAM,gDAAgD,CAAA;AACvF,OAAO,EAAE,qBAAqB,EAAE,MAAM,8DAA8D,CAAA;AACpG,OAAO,EAAE,wBAAwB,EAAE,MAAM,oEAAoE,CAAA;AAC7G,OAAO,EAAE,oBAAoB,EAAE,MAAM,gEAAgE,CAAA;AACrG,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAA;AAE1F,4EAA4E;AAC5E,4EAA4E;AAC5E,4EAA4E;AAC5E,mEAAmE;AACnE,0EAA0E;AAC1E,8EAA8E;AAC9E,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,GAAG,uBAAuB;IAC1B,GAAG,sBAAsB;IACzB,GAAG,sBAAsB;IACzB,GAAG,wBAAwB;IAC3B,GAAG,wBAAwB;IAC3B,GAAG,qBAAqB;IACxB,GAAG,oBAAoB;CACf,CAAA"}
|
|
@@ -3,22 +3,25 @@ import { Chain } from '@vultisig/core-chain/Chain';
|
|
|
3
3
|
* Swap-provider scanners covered by `getSwapExplorerUrl`.
|
|
4
4
|
*
|
|
5
5
|
* - `li.fi` → scan.li.fi (or orb.helius.dev for Solana settlement)
|
|
6
|
+
* - `swapkit` → track.swapkit.dev
|
|
7
|
+
* - `cowswap` → explorer.cow.fi order page
|
|
6
8
|
* - `thorchain` / `mayachain` → native chain scanner
|
|
7
|
-
* - `1inch`, `kyber`, `
|
|
9
|
+
* - `1inch`, `kyber`, `jupiter` → source-chain explorer fallback
|
|
8
10
|
*
|
|
9
11
|
* Keep this union in sync with iOS `ExplorerLinkBuilder.swift` and Android
|
|
10
12
|
* `ExplorerLinkRepository.getSwapProgressLink`.
|
|
11
13
|
*/
|
|
12
|
-
export declare const swapExplorerProviders: readonly ["1inch", "
|
|
14
|
+
export declare const swapExplorerProviders: readonly ["1inch", "li.fi", "kyber", "swapkit", "cowswap", "jupiter", "mayachain", "thorchain"];
|
|
13
15
|
export type SwapExplorerProvider = (typeof swapExplorerProviders)[number];
|
|
14
16
|
export type GetSwapExplorerUrlInput = {
|
|
15
17
|
provider: SwapExplorerProvider;
|
|
16
|
-
txHash: string;
|
|
17
18
|
/**
|
|
18
|
-
* The
|
|
19
|
-
* for
|
|
20
|
-
*
|
|
19
|
+
* The provider-specific tracking identifier. This is an on-chain transaction
|
|
20
|
+
* hash for every provider except CowSwap, where it must be the 56-byte order
|
|
21
|
+
* UID returned when the off-chain order is submitted.
|
|
21
22
|
*/
|
|
23
|
+
txHash: string;
|
|
24
|
+
/** The source chain. Unsupported CowSwap chains throw at runtime. */
|
|
22
25
|
fromChain: Chain;
|
|
23
26
|
};
|
|
24
27
|
/**
|
|
@@ -28,7 +31,7 @@ export type GetSwapExplorerUrlInput = {
|
|
|
28
31
|
* so every consumer (vultisig-windows, vultiagent-app, future RN SDK) routes
|
|
29
32
|
* tx-history links to the same scanner.
|
|
30
33
|
*
|
|
31
|
-
* For aggregators without a public per-tx page (`1inch`, `kyber`, `
|
|
34
|
+
* For aggregators without a public per-tx page (`1inch`, `kyber`, `jupiter`),
|
|
32
35
|
* the source-chain explorer is returned so the row never renders as a dead link.
|
|
33
36
|
*/
|
|
34
37
|
export declare const getSwapExplorerUrl: ({ provider, txHash, fromChain }: GetSwapExplorerUrlInput) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/swap/utils/getSwapExplorerUrl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/swap/utils/getSwapExplorerUrl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAMlD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,qBAAqB,iGAA+D,CAAA;AAEjG,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,qBAAqB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEzE,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,EAAE,oBAAoB,CAAA;IAC9B;;;;OAIG;IACH,MAAM,EAAE,MAAM,CAAA;IACd,qEAAqE;IACrE,SAAS,EAAE,KAAK,CAAA;CACjB,CAAA;AAKD;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAAI,iCAAiC,uBAAuB,KAAG,MAkC7F,CAAA"}
|
|
@@ -1,24 +1,21 @@
|
|
|
1
1
|
import { Chain } from '@vultisig/core-chain/Chain';
|
|
2
|
+
import { getCowSwapExplorerOrderUrl } from '@vultisig/core-chain/swap/general/cowswap/getCowSwapExplorerOrderUrl';
|
|
3
|
+
import { generalSwapProviders } from '@vultisig/core-chain/swap/general/GeneralSwapProvider';
|
|
4
|
+
import { getSwapKitTrackerUrl } from '@vultisig/core-chain/swap/general/swapkit/getSwapKitTrackerUrl';
|
|
2
5
|
import { getBlockExplorerUrl } from '@vultisig/core-chain/utils/getBlockExplorerUrl';
|
|
3
6
|
/**
|
|
4
7
|
* Swap-provider scanners covered by `getSwapExplorerUrl`.
|
|
5
8
|
*
|
|
6
9
|
* - `li.fi` → scan.li.fi (or orb.helius.dev for Solana settlement)
|
|
10
|
+
* - `swapkit` → track.swapkit.dev
|
|
11
|
+
* - `cowswap` → explorer.cow.fi order page
|
|
7
12
|
* - `thorchain` / `mayachain` → native chain scanner
|
|
8
|
-
* - `1inch`, `kyber`, `
|
|
13
|
+
* - `1inch`, `kyber`, `jupiter` → source-chain explorer fallback
|
|
9
14
|
*
|
|
10
15
|
* Keep this union in sync with iOS `ExplorerLinkBuilder.swift` and Android
|
|
11
16
|
* `ExplorerLinkRepository.getSwapProgressLink`.
|
|
12
17
|
*/
|
|
13
|
-
export const swapExplorerProviders = [
|
|
14
|
-
'1inch',
|
|
15
|
-
'kyber',
|
|
16
|
-
'li.fi',
|
|
17
|
-
'mayachain',
|
|
18
|
-
'swapkit',
|
|
19
|
-
'jupiter',
|
|
20
|
-
'thorchain',
|
|
21
|
-
];
|
|
18
|
+
export const swapExplorerProviders = [...generalSwapProviders, 'mayachain', 'thorchain'];
|
|
22
19
|
const stripHexPrefix = (value) => value.startsWith('0x') || value.startsWith('0X') ? value.slice(2) : value;
|
|
23
20
|
/**
|
|
24
21
|
* Resolve the canonical "view on explorer" URL for a swap-provider transaction.
|
|
@@ -27,11 +24,13 @@ const stripHexPrefix = (value) => value.startsWith('0x') || value.startsWith('0X
|
|
|
27
24
|
* so every consumer (vultisig-windows, vultiagent-app, future RN SDK) routes
|
|
28
25
|
* tx-history links to the same scanner.
|
|
29
26
|
*
|
|
30
|
-
* For aggregators without a public per-tx page (`1inch`, `kyber`, `
|
|
27
|
+
* For aggregators without a public per-tx page (`1inch`, `kyber`, `jupiter`),
|
|
31
28
|
* the source-chain explorer is returned so the row never renders as a dead link.
|
|
32
29
|
*/
|
|
33
30
|
export const getSwapExplorerUrl = ({ provider, txHash, fromChain }) => {
|
|
34
31
|
switch (provider) {
|
|
32
|
+
case 'cowswap':
|
|
33
|
+
return getCowSwapExplorerOrderUrl({ chain: fromChain, uid: txHash });
|
|
35
34
|
case 'li.fi':
|
|
36
35
|
// LI.FI's scanner has no per-tx page for Solana cross-chain settlement;
|
|
37
36
|
// Helius is the canonical view there.
|
|
@@ -43,9 +42,11 @@ export const getSwapExplorerUrl = ({ provider, txHash, fromChain }) => {
|
|
|
43
42
|
return `https://runescan.io/tx/${stripHexPrefix(txHash)}`;
|
|
44
43
|
case 'mayachain':
|
|
45
44
|
return `https://www.explorer.mayachain.info/tx/${stripHexPrefix(txHash)}`;
|
|
45
|
+
case 'swapkit':
|
|
46
|
+
return (getSwapKitTrackerUrl({ chain: fromChain, txHash }) ??
|
|
47
|
+
getBlockExplorerUrl({ chain: fromChain, entity: 'tx', value: txHash }));
|
|
46
48
|
case '1inch':
|
|
47
49
|
case 'kyber':
|
|
48
|
-
case 'swapkit':
|
|
49
50
|
case 'jupiter':
|
|
50
51
|
// No public aggregator scanner. Source-chain explorer keeps the link
|
|
51
52
|
// useful (Etherscan / Solscan / etc.) without fabricating a URL.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/swap/utils/getSwapExplorerUrl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAA;AAEpF
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/swap/utils/getSwapExplorerUrl/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAClD,OAAO,EAAE,0BAA0B,EAAE,MAAM,sEAAsE,CAAA;AACjH,OAAO,EAAE,oBAAoB,EAAE,MAAM,uDAAuD,CAAA;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,gEAAgE,CAAA;AACrG,OAAO,EAAE,mBAAmB,EAAE,MAAM,gDAAgD,CAAA;AAEpF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,GAAG,oBAAoB,EAAE,WAAW,EAAE,WAAW,CAAU,CAAA;AAgBjG,MAAM,cAAc,GAAG,CAAC,KAAa,EAAU,EAAE,CAC/C,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AAE3E;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAA2B,EAAU,EAAE;IACrG,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,SAAS;YACZ,OAAO,0BAA0B,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAA;QACtE,KAAK,OAAO;YACV,wEAAwE;YACxE,sCAAsC;YACtC,IAAI,SAAS,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;gBAC/B,OAAO,6BAA6B,MAAM,EAAE,CAAA;YAC9C,CAAC;YACD,OAAO,yBAAyB,MAAM,EAAE,CAAA;QAC1C,KAAK,WAAW;YACd,OAAO,0BAA0B,cAAc,CAAC,MAAM,CAAC,EAAE,CAAA;QAC3D,KAAK,WAAW;YACd,OAAO,0CAA0C,cAAc,CAAC,MAAM,CAAC,EAAE,CAAA;QAC3E,KAAK,SAAS;YACZ,OAAO,CACL,oBAAoB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;gBAClD,mBAAmB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CACvE,CAAA;QACH,KAAK,OAAO,CAAC;QACb,KAAK,OAAO,CAAC;QACb,KAAK,SAAS;YACZ,qEAAqE;YACrE,iEAAiE;YACjE,OAAO,mBAAmB,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAA;QAC/E,OAAO,CAAC,CAAC,CAAC;YACR,0EAA0E;YAC1E,uEAAuE;YACvE,iEAAiE;YACjE,MAAM,WAAW,GAAU,QAAQ,CAAA;YACnC,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAA;QAC3E,CAAC;IACH,CAAC;AACH,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bittensor.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/bittensor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAKvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"bittensor.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/bittensor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAKvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AASjD,eAAO,MAAM,oBAAoB,EAAE,mBAAmB,CAAC,UAAU,CAAC,SAAS,CA0B1E,CAAA"}
|
|
@@ -2,24 +2,30 @@ import { bittensorRpcUrl } from '@vultisig/core-chain/chains/bittensor/client';
|
|
|
2
2
|
import { ensureHexPrefix } from '@vultisig/lib-utils/hex/ensureHexPrefix';
|
|
3
3
|
import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
|
|
4
4
|
import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
|
|
5
|
+
import { formatSubstrateRpcError, isIdempotentSubstrateBroadcastError } from './substrate.js';
|
|
5
6
|
export const broadcastBittensorTx = async ({ chain, tx }) => {
|
|
6
7
|
const hexWithPrefix = ensureHexPrefix(Buffer.from(tx.encoded).toString('hex'));
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
8
|
+
try {
|
|
9
|
+
const response = await queryUrl(bittensorRpcUrl, {
|
|
10
|
+
body: {
|
|
11
|
+
jsonrpc: '2.0',
|
|
12
|
+
method: 'author_submitExtrinsic',
|
|
13
|
+
params: [hexWithPrefix],
|
|
14
|
+
id: 1,
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
if (response.error) {
|
|
18
|
+
if (isIdempotentSubstrateBroadcastError(response.error)) {
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
throw new Error(`Bittensor broadcast failed: ${formatSubstrateRpcError(response.error)}`);
|
|
20
22
|
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
if (!response.result) {
|
|
24
|
+
throw new Error('Bittensor broadcast failed: missing extrinsic hash in RPC response');
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
await verifyBroadcastByHash({ chain, tx, error });
|
|
23
29
|
}
|
|
24
30
|
};
|
|
25
31
|
//# sourceMappingURL=bittensor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bittensor.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/bittensor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,8CAA8C,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAG7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"bittensor.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/bittensor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,8CAA8C,CAAA;AAC9E,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAG7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,EAAE,uBAAuB,EAAE,mCAAmC,EAAqB,MAAM,aAAa,CAAA;AAO7G,MAAM,CAAC,MAAM,oBAAoB,GAA8C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IACrG,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;IAE9E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAc,eAAe,EAAE;YAC5D,IAAI,EAAE;gBACJ,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,wBAAwB;gBAChC,MAAM,EAAE,CAAC,aAAa,CAAC;gBACvB,EAAE,EAAE,CAAC;aACN;SACF,CAAC,CAAA;QAEF,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,IAAI,mCAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,OAAM;YACR,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,+BAA+B,uBAAuB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC3F,CAAC;QAED,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAA;QACvF,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IACnD,CAAC;AACH,CAAC,CAAA"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { CosmosChain } from '@vultisig/core-chain/Chain';
|
|
2
2
|
import { BroadcastTxResolver } from '../resolver.js';
|
|
3
|
+
export declare const getCosmosBroadcastTimeoutTxId: (error: unknown) => string | undefined;
|
|
3
4
|
export declare const broadcastCosmosTx: BroadcastTxResolver<CosmosChain>;
|
|
4
5
|
//# sourceMappingURL=cosmos.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cosmos.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cosmos.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cosmos.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cosmos.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAKxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAIjD,eAAO,MAAM,6BAA6B,GAAI,OAAO,OAAO,KAAG,MAAM,GAAG,SAMvE,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,mBAAmB,CAAC,WAAW,CAqC9D,CAAA"}
|
|
@@ -1,19 +1,47 @@
|
|
|
1
|
+
import { assertIsDeliverTxSuccess, TimeoutError } from '@cosmjs/stargate';
|
|
1
2
|
import { getCosmosClient } from '@vultisig/core-chain/chains/cosmos/client';
|
|
2
3
|
import { attempt } from '@vultisig/lib-utils/attempt';
|
|
3
4
|
import { isInError } from '@vultisig/lib-utils/error/isInError';
|
|
5
|
+
import { DeliverTxFailedError } from '../transientRetry.js';
|
|
4
6
|
import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
|
|
7
|
+
export const getCosmosBroadcastTimeoutTxId = (error) => {
|
|
8
|
+
if (!(error instanceof TimeoutError))
|
|
9
|
+
return undefined;
|
|
10
|
+
const { txId } = error;
|
|
11
|
+
return txId.trim() || undefined;
|
|
12
|
+
};
|
|
5
13
|
export const broadcastCosmosTx = async ({ chain, tx }) => {
|
|
6
14
|
const { serialized } = tx;
|
|
7
15
|
const { tx_bytes } = JSON.parse(serialized);
|
|
8
16
|
const decodedTxBytes = Buffer.from(tx_bytes, 'base64');
|
|
9
17
|
const client = await getCosmosClient(chain);
|
|
10
|
-
const { error } = await attempt(client.broadcastTx(decodedTxBytes));
|
|
11
|
-
if (
|
|
18
|
+
const { data, error } = await attempt(client.broadcastTx(decodedTxBytes));
|
|
19
|
+
if (data) {
|
|
20
|
+
// client.broadcastTx resolves (does not throw) once the tx is INCLUDED in a
|
|
21
|
+
// block, even when execution itself failed (DeliverTx code !== 0 — e.g.
|
|
22
|
+
// out-of-gas, wasm revert, a THORChain/Maya deposit-handler rejection). The
|
|
23
|
+
// tx is on-chain but nothing moved, so this must not be reported as success.
|
|
24
|
+
try {
|
|
25
|
+
assertIsDeliverTxSuccess(data);
|
|
26
|
+
}
|
|
27
|
+
catch (deliverTxError) {
|
|
28
|
+
// Marker type, not a bare Error: cosmos has no resolver-owned retry, so
|
|
29
|
+
// this throws into `withTransientBroadcastRetry`. A rawLog like "wasm
|
|
30
|
+
// contract aborted" would otherwise match the transient message regex
|
|
31
|
+
// and get resent, then swallowed as an idempotent "already in cache"
|
|
32
|
+
// success — reopening the bug this assert exists to close.
|
|
33
|
+
const message = deliverTxError instanceof Error ? deliverTxError.message : String(deliverTxError);
|
|
34
|
+
throw new DeliverTxFailedError(message, { cause: deliverTxError });
|
|
35
|
+
}
|
|
12
36
|
return;
|
|
13
37
|
}
|
|
14
38
|
if (isInError(error, 'tx already exists in cache')) {
|
|
15
39
|
return;
|
|
16
40
|
}
|
|
41
|
+
const timeoutTxId = getCosmosBroadcastTimeoutTxId(error);
|
|
42
|
+
if (timeoutTxId) {
|
|
43
|
+
return timeoutTxId;
|
|
44
|
+
}
|
|
17
45
|
await verifyBroadcastByHash({ chain, tx, error });
|
|
18
46
|
};
|
|
19
47
|
//# sourceMappingURL=cosmos.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cosmos.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cosmos.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cosmos.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cosmos.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAEzE,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAA;AAC3E,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAG/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAAC,KAAc,EAAsB,EAAE;IAClF,IAAI,CAAC,CAAC,KAAK,YAAY,YAAY,CAAC;QAAE,OAAO,SAAS,CAAA;IAEtD,MAAM,EAAE,IAAI,EAAE,GAAG,KAAK,CAAA;IAEtB,OAAO,IAAI,CAAC,IAAI,EAAE,IAAI,SAAS,CAAA;AACjC,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,iBAAiB,GAAqC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IACzF,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAAA;IACzB,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAA;IAC3C,MAAM,cAAc,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAA;IAEtD,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAAC,MAAM,CAAC,WAAW,CAAC,cAAc,CAAC,CAAC,CAAA;IAEzE,IAAI,IAAI,EAAE,CAAC;QACT,4EAA4E;QAC5E,wEAAwE;QACxE,4EAA4E;QAC5E,6EAA6E;QAC7E,IAAI,CAAC;YACH,wBAAwB,CAAC,IAAI,CAAC,CAAA;QAChC,CAAC;QAAC,OAAO,cAAc,EAAE,CAAC;YACxB,wEAAwE;YACxE,sEAAsE;YACtE,sEAAsE;YACtE,qEAAqE;YACrE,2DAA2D;YAC3D,MAAM,OAAO,GAAG,cAAc,YAAY,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,CAAA;YACjG,MAAM,IAAI,oBAAoB,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAA;QACpE,CAAC;QACD,OAAM;IACR,CAAC;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,4BAA4B,CAAC,EAAE,CAAC;QACnD,OAAM;IACR,CAAC;IAED,MAAM,WAAW,GAAG,6BAA6B,CAAC,KAAK,CAAC,CAAA;IACxD,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,WAAW,CAAA;IACpB,CAAC;IAED,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;AACnD,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polkadot.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/polkadot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAKvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"polkadot.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/polkadot.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAKvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AASjD,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,UAAU,CAAC,QAAQ,CAiCxE,CAAA"}
|
|
@@ -2,39 +2,7 @@ import { ensureHexPrefix } from '@vultisig/lib-utils/hex/ensureHexPrefix';
|
|
|
2
2
|
import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
|
|
3
3
|
import { polkadotRpcUrl } from '../../../chains/polkadot/client.js';
|
|
4
4
|
import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
|
|
5
|
-
|
|
6
|
-
* Substrate Pool errors that mean "this extrinsic is already in the pool /
|
|
7
|
-
* imported / banned because a peer just submitted it." In an MPC ceremony,
|
|
8
|
-
* the initiator and the joiner both broadcast the same signed extrinsic; the
|
|
9
|
-
* slower device hits exactly these messages while the tx is in fact already
|
|
10
|
-
* on chain. Treat them as idempotent successes — the alternative is showing
|
|
11
|
-
* the slower device a "Signing Error" screen for a transaction that did
|
|
12
|
-
* confirm. Fast path so we don't rely on `verifyBroadcastByHash`, which can't
|
|
13
|
-
* help on Polkadot until tx-status polling moves off the gated Subscan API.
|
|
14
|
-
*
|
|
15
|
-
* Substrate sources for the exact strings:
|
|
16
|
-
* substrate/client/transaction-pool/api/src/error.rs (AlreadyImported,
|
|
17
|
-
* TemporarilyBanned, NoTagsProvided, ImmediatelyDropped) and
|
|
18
|
-
* primitives/runtime/src/transaction_validity.rs (Stale).
|
|
19
|
-
*/
|
|
20
|
-
const idempotentBroadcastErrorPatterns = [
|
|
21
|
-
/already imported/i,
|
|
22
|
-
/already known/i,
|
|
23
|
-
/temporarily banned/i,
|
|
24
|
-
];
|
|
25
|
-
const isIdempotentBroadcastError = (text) => idempotentBroadcastErrorPatterns.some(pattern => pattern.test(text));
|
|
26
|
-
/**
|
|
27
|
-
* Substrate's JSON-RPC error shape is `{ code, message, data? }`. For
|
|
28
|
-
* `InvalidTransaction::*` rejections (code 1010) the `message` is the
|
|
29
|
-
* generic `"Invalid Transaction"` and the specific reason ("Transaction has
|
|
30
|
-
* a bad signature", "Transaction is outdated", "Inability to pay some fees",
|
|
31
|
-
* etc.) lives in `data`. Surfacing only `message` makes every failure look
|
|
32
|
-
* identical in the UI and strips the information we need to triage.
|
|
33
|
-
*/
|
|
34
|
-
const formatRpcError = ({ code, message, data }) => {
|
|
35
|
-
const head = message ?? `code ${code}`;
|
|
36
|
-
return data ? `${head}: ${data}` : head;
|
|
37
|
-
};
|
|
5
|
+
import { formatSubstrateRpcError, isIdempotentSubstrateBroadcastError } from './substrate.js';
|
|
38
6
|
export const broadcastPolkadotTx = async ({ chain, tx }) => {
|
|
39
7
|
const hexWithPrefix = ensureHexPrefix(Buffer.from(tx.encoded).toString('hex'));
|
|
40
8
|
try {
|
|
@@ -51,11 +19,10 @@ export const broadcastPolkadotTx = async ({ chain, tx }) => {
|
|
|
51
19
|
// already submitted this exact tx; the node tells us with a Pool error
|
|
52
20
|
// (string usually in `message`) or, less commonly, an Invalid
|
|
53
21
|
// Transaction variant whose duplicate signal lives in `data`.
|
|
54
|
-
|
|
55
|
-
if (isIdempotentBroadcastError(errorText)) {
|
|
22
|
+
if (isIdempotentSubstrateBroadcastError(response.error)) {
|
|
56
23
|
return;
|
|
57
24
|
}
|
|
58
|
-
throw new Error(`Polkadot broadcast failed: ${
|
|
25
|
+
throw new Error(`Polkadot broadcast failed: ${formatSubstrateRpcError(response.error)}`);
|
|
59
26
|
}
|
|
60
27
|
// Per JSON-RPC 2.0 a valid response must have exactly one of `result` /
|
|
61
28
|
// `error`. If both are missing (malformed gateway response, truncated
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"polkadot.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/polkadot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAEhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;
|
|
1
|
+
{"version":3,"file":"polkadot.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/polkadot.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAE7D,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAA;AAEhE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,EAAE,uBAAuB,EAAE,mCAAmC,EAAqB,MAAM,aAAa,CAAA;AAO7G,MAAM,CAAC,MAAM,mBAAmB,GAA6C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IACnG,MAAM,aAAa,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAA;IAE9E,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAc,cAAc,EAAE;YAC3D,IAAI,EAAE;gBACJ,OAAO,EAAE,KAAK;gBACd,MAAM,EAAE,wBAAwB;gBAChC,MAAM,EAAE,CAAC,aAAa,CAAC;gBACvB,EAAE,EAAE,CAAC;aACN;SACF,CAAC,CAAA;QAEF,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnB,sEAAsE;YACtE,uEAAuE;YACvE,8DAA8D;YAC9D,8DAA8D;YAC9D,IAAI,mCAAmC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACxD,OAAM;YACR,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,8BAA8B,uBAAuB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;QAC1F,CAAC;QAED,wEAAwE;QACxE,sEAAsE;QACtE,qEAAqE;QACrE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAA;QACtF,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;IACnD,CAAC;AACH,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qbtc.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/qbtc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"qbtc.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/qbtc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAMlD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AASjD,eAAO,MAAM,eAAe,EAAE,mBAAmB,CAAC,OAAO,KAAK,CAAC,IAAI,CAqElE,CAAA"}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { qbtcRestUrl } from '@vultisig/core-chain/chains/cosmos/qbtc/tendermintRpcUrl';
|
|
2
|
+
import { waitForQbtcTxInclusion } from '@vultisig/core-chain/chains/cosmos/qbtc/waitForQbtcTxInclusion';
|
|
2
3
|
import { attempt } from '@vultisig/lib-utils/attempt';
|
|
3
4
|
import { isInError } from '@vultisig/lib-utils/error/isInError';
|
|
5
|
+
import { DeliverTxFailedError } from '../transientRetry.js';
|
|
4
6
|
import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
|
|
7
|
+
// QBTC block time is ~5-7s; give a DeliverTx a generous window to land before treating the tx as
|
|
8
|
+
// in-flight (the status resolver reports the final code either way).
|
|
9
|
+
const QBTC_INCLUSION_TIMEOUT_MS = 30_000;
|
|
10
|
+
const QBTC_INCLUSION_POLL_INTERVAL_MS = 1_000;
|
|
5
11
|
export const broadcastQbtcTx = async ({ chain, tx }) => {
|
|
6
12
|
const { serialized } = tx;
|
|
7
13
|
const { tx_bytes } = JSON.parse(serialized);
|
|
@@ -23,17 +29,41 @@ export const broadcastQbtcTx = async ({ chain, tx }) => {
|
|
|
23
29
|
return;
|
|
24
30
|
}
|
|
25
31
|
const data = (await resp.json());
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
32
|
+
const checkTx = data.tx_response;
|
|
33
|
+
// CheckTx (mempool admission). A missing code, or a non-zero code, is NOT a confirmed on-chain
|
|
34
|
+
// state — verify by hash rather than trusting it. Reading it as `code && code !== 0` (the old
|
|
35
|
+
// guard) treated a MISSING tx_response as a silent success: half of this false-success bug.
|
|
36
|
+
if (typeof checkTx?.code !== 'number' || checkTx.code !== 0) {
|
|
37
|
+
const log = checkTx?.raw_log || checkTx?.log;
|
|
38
|
+
if (log && isInError(log, 'tx already exists in cache')) {
|
|
39
|
+
return;
|
|
29
40
|
}
|
|
30
|
-
|
|
31
|
-
|
|
41
|
+
const err = new Error(`QBTC CheckTx failed: ${log ?? 'missing tx_response.code'}`);
|
|
42
|
+
await verifyBroadcastByHash({ chain, tx, error: err });
|
|
32
43
|
return;
|
|
33
44
|
}
|
|
34
|
-
|
|
45
|
+
// CheckTx passed — but BROADCAST_MODE_SYNC only surfaces CheckTx. A DeliverTx failure (out-of-gas,
|
|
46
|
+
// execution revert) still comes back code=0 HERE, so returning now would report an on-chain tx that
|
|
47
|
+
// moved nothing as a success. Poll for inclusion and re-check the DeliverTx code (mirrors the QBTC
|
|
48
|
+
// claim helper, broadcastClaimTx). A CONFIRMED DeliverTx failure throws a non-retryable
|
|
49
|
+
// DeliverTxFailedError; if we cannot confirm within the window (timeout / transient RPC error) the
|
|
50
|
+
// tx is in the mempool, not failed, so leave it in-flight — the status resolver reports the final
|
|
51
|
+
// code.
|
|
52
|
+
const txHash = checkTx.txhash;
|
|
53
|
+
if (!txHash) {
|
|
54
|
+
await verifyBroadcastByHash({ chain, tx, error: new Error('QBTC broadcast: missing txhash on CheckTx response') });
|
|
35
55
|
return;
|
|
36
56
|
}
|
|
37
|
-
|
|
57
|
+
const { data: included, error: inclusionError } = await attempt(waitForQbtcTxInclusion({
|
|
58
|
+
txHash,
|
|
59
|
+
timeoutMs: QBTC_INCLUSION_TIMEOUT_MS,
|
|
60
|
+
intervalMs: QBTC_INCLUSION_POLL_INTERVAL_MS,
|
|
61
|
+
}));
|
|
62
|
+
if (inclusionError || included === undefined || typeof included.code !== 'number') {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (included.code !== 0) {
|
|
66
|
+
throw new DeliverTxFailedError(`QBTC transaction execution failed: ${included.raw_log || included.log}`);
|
|
67
|
+
}
|
|
38
68
|
};
|
|
39
69
|
//# sourceMappingURL=qbtc.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"qbtc.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/qbtc.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,0DAA0D,CAAA;AACtF,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAG/D,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,MAAM,CAAC,MAAM,eAAe,GAA2C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IAC7F,MAAM,EAAE,UAAU,EAAE,GAAG,EAAE,CAAA;IACzB,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAyB,CAAA;IAEnE,MAAM,IAAI,GAAG,MAAM,KAAK,CAAC,GAAG,WAAW,wBAAwB,EAAE;QAC/D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,QAAQ;YACR,IAAI,EAAE,qBAAqB;SAC5B,CAAC;KACH,CAAC,CAAA;IAEF,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;QACb,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,CAAA;QAC9B,IAAI,SAAS,CAAC,IAAI,EAAE,4BAA4B,CAAC,EAAE,CAAC;YAClD,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,0BAA0B,IAAI,CAAC,MAAM,MAAM,IAAI,EAAE,CAAC,CAAA;QACxE,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAA;QACtD,OAAM;IACR,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,EAAE,CAE9B,CAAA;IACD,MAAM,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"qbtc.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/qbtc.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type SubstrateRpcError = {
|
|
2
|
+
code: number;
|
|
3
|
+
message?: string;
|
|
4
|
+
data?: string;
|
|
5
|
+
};
|
|
6
|
+
export declare const isIdempotentSubstrateBroadcastError: ({ message, data }: SubstrateRpcError) => boolean;
|
|
7
|
+
export declare const formatSubstrateRpcError: ({ code, message, data }: SubstrateRpcError) => string;
|
|
8
|
+
//# sourceMappingURL=substrate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"substrate.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/substrate.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC9B,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,CAAA;AAWD,eAAO,MAAM,mCAAmC,GAAI,mBAAmB,iBAAiB,KAAG,OACO,CAAA;AAIlG,eAAO,MAAM,uBAAuB,GAAI,yBAAyB,iBAAiB,KAAG,MAGpF,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// These pool errors mean another MPC peer has already submitted the same
|
|
2
|
+
// deterministic extrinsic. Treat them as idempotent success so the slower peer
|
|
3
|
+
// does not show a signing failure for a transaction that is already in flight.
|
|
4
|
+
const idempotentBroadcastErrorPatterns = [/already imported/i, /already known/i];
|
|
5
|
+
// `TemporarilyBanned` is deliberately not a fast success. Substrate bans
|
|
6
|
+
// hashes after known block imports, but it can also ban transactions removed
|
|
7
|
+
// as invalid or dropped. Only hash verification can disambiguate those cases.
|
|
8
|
+
export const isIdempotentSubstrateBroadcastError = ({ message, data }) => idempotentBroadcastErrorPatterns.some(pattern => pattern.test(`${message ?? ''} ${data ?? ''}`));
|
|
9
|
+
// Substrate often carries the actionable InvalidTransaction reason in `data`
|
|
10
|
+
// while `message` contains only the generic "Invalid Transaction" label.
|
|
11
|
+
export const formatSubstrateRpcError = ({ code, message, data }) => {
|
|
12
|
+
const head = message ?? `code ${code}`;
|
|
13
|
+
return data ? `${head}: ${data}` : head;
|
|
14
|
+
};
|
|
15
|
+
//# sourceMappingURL=substrate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"substrate.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/substrate.ts"],"names":[],"mappings":"AAMA,yEAAyE;AACzE,+EAA+E;AAC/E,+EAA+E;AAC/E,MAAM,gCAAgC,GAAsB,CAAC,mBAAmB,EAAE,gBAAgB,CAAC,CAAA;AAEnG,yEAAyE;AACzE,6EAA6E;AAC7E,8EAA8E;AAE9E,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,EAAE,OAAO,EAAE,IAAI,EAAqB,EAAW,EAAE,CACnG,gCAAgC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,OAAO,IAAI,EAAE,IAAI,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC,CAAA;AAElG,6EAA6E;AAC7E,yEAAyE;AACzE,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAqB,EAAU,EAAE;IAC5F,MAAM,IAAI,GAAG,OAAO,IAAI,QAAQ,IAAI,EAAE,CAAA;IACtC,OAAO,IAAI,CAAC,CAAC,CAAC,GAAG,IAAI,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAA;AACzC,CAAC,CAAA"}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
import { OtherChain } from '@vultisig/core-chain/Chain';
|
|
2
2
|
import { BroadcastTxResolver } from '../resolver.js';
|
|
3
|
+
type SuiExecutionEffects = {
|
|
4
|
+
status?: {
|
|
5
|
+
status?: string;
|
|
6
|
+
error?: string | null;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
export declare const assertSuiTxSucceeded: (effects: SuiExecutionEffects | null | undefined) => void;
|
|
3
10
|
export declare const broadcastSuiTx: BroadcastTxResolver<OtherChain.Sui>;
|
|
11
|
+
export {};
|
|
4
12
|
//# sourceMappingURL=sui.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sui.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/sui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;
|
|
1
|
+
{"version":3,"file":"sui.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/sui.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAIvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAIjD,KAAK,mBAAmB,GAAG;IACzB,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KACtB,CAAA;CACF,CAAA;AAED,eAAO,MAAM,oBAAoB,GAAI,SAAS,mBAAmB,GAAG,IAAI,GAAG,SAAS,KAAG,IAQtF,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,CAkC9D,CAAA"}
|
|
@@ -1,14 +1,40 @@
|
|
|
1
1
|
import { getSuiClient } from '@vultisig/core-chain/chains/sui/client';
|
|
2
|
+
import { attempt } from '@vultisig/lib-utils/attempt';
|
|
3
|
+
import { DeliverTxFailedError } from '../transientRetry.js';
|
|
2
4
|
import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
|
|
5
|
+
export const assertSuiTxSucceeded = (effects) => {
|
|
6
|
+
const executionStatus = effects?.status?.status;
|
|
7
|
+
if (executionStatus === 'success')
|
|
8
|
+
return;
|
|
9
|
+
throw new DeliverTxFailedError(`Sui transaction failed on-chain: ${effects?.status?.error ?? executionStatus ?? 'no effects status returned'}`);
|
|
10
|
+
};
|
|
3
11
|
export const broadcastSuiTx = async ({ chain, tx }) => {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
const { data: response, error } = await attempt(getSuiClient().executeTransactionBlock({
|
|
13
|
+
transactionBlock: tx.unsignedTx,
|
|
14
|
+
signature: [tx.signature],
|
|
15
|
+
// sdk#1398: without requesting effects, executeTransactionBlock resolves with a digest even
|
|
16
|
+
// when the tx executed but ABORTED (MoveAbort / InsufficientGas) — an RPC-level success that
|
|
17
|
+
// is NOT execution success. Ask for effects so we can tell the two apart.
|
|
18
|
+
options: { showEffects: true },
|
|
19
|
+
}));
|
|
20
|
+
if (error) {
|
|
11
21
|
await verifyBroadcastByHash({ chain, tx, error });
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (!response) {
|
|
25
|
+
return;
|
|
12
26
|
}
|
|
27
|
+
// Mirror the status resolver (status/resolvers/sui.ts): ONLY an explicit 'success' effects status
|
|
28
|
+
// is execution success. A 'failure' (MoveAbort / InsufficientGas) — or a missing/unknown status —
|
|
29
|
+
// must NOT be returned as a digest-carrying successful broadcast (that's the sdk#1398 bug). Thrown
|
|
30
|
+
// outside the RPC-error path above so it isn't fed back into verifyBroadcastByHash — the tx is
|
|
31
|
+
// on-chain and failed, not un-broadcast.
|
|
32
|
+
//
|
|
33
|
+
// Throw DeliverTxFailedError (not a bare Error) so isTransientBroadcastError short-circuits on the
|
|
34
|
+
// `instanceof` BEFORE its message-regex runs: a Sui abort error string routinely contains
|
|
35
|
+
// "aborted"/"timed out", which the transient patterns match — a bare Error would be misclassified
|
|
36
|
+
// as transient and the aborted tx re-sent by withTransientBroadcastRetry.
|
|
37
|
+
assertSuiTxSucceeded(response.effects);
|
|
38
|
+
return response;
|
|
13
39
|
};
|
|
14
40
|
//# sourceMappingURL=sui.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sui.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/sui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;
|
|
1
|
+
{"version":3,"file":"sui.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/sui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAGrD,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAShE,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,OAA+C,EAAQ,EAAE;IAC5F,MAAM,eAAe,GAAG,OAAO,EAAE,MAAM,EAAE,MAAM,CAAA;IAE/C,IAAI,eAAe,KAAK,SAAS;QAAE,OAAM;IAEzC,MAAM,IAAI,oBAAoB,CAC5B,oCAAoC,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,eAAe,IAAI,4BAA4B,EAAE,CAChH,CAAA;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,cAAc,GAAwC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IACzF,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAC7C,YAAY,EAAE,CAAC,uBAAuB,CAAC;QACrC,gBAAgB,EAAE,EAAE,CAAC,UAAU;QAC/B,SAAS,EAAE,CAAC,EAAE,CAAC,SAAS,CAAC;QACzB,4FAA4F;QAC5F,6FAA6F;QAC7F,0EAA0E;QAC1E,OAAO,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE;KAC/B,CAAC,CACH,CAAA;IAED,IAAI,KAAK,EAAE,CAAC;QACV,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QACjD,OAAM;IACR,CAAC;IAED,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAM;IACR,CAAC;IAED,kGAAkG;IAClG,kGAAkG;IAClG,mGAAmG;IACnG,+FAA+F;IAC/F,yCAAyC;IACzC,EAAE;IACF,mGAAmG;IACnG,0FAA0F;IAC1F,kGAAkG;IAClG,0EAA0E;IAC1E,oBAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;IAEtC,OAAO,QAAQ,CAAA;AACjB,CAAC,CAAA"}
|
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A transaction was included on-chain but its execution genuinely failed
|
|
3
|
+
* (e.g. Cosmos DeliverTx code !== 0 — a wasm revert, out-of-gas, a
|
|
4
|
+
* THORChain/Maya deposit-handler rejection). This is a terminal, non-transient
|
|
5
|
+
* outcome even though the chain-controlled error text can read exactly like
|
|
6
|
+
* a transient one (a cosmwasm revert's rawLog routinely says "aborted"; a
|
|
7
|
+
* contract can literally say "timed out" or "connection reset" as text).
|
|
8
|
+
* Retrying would just re-send the same bytes, get "tx already exists in
|
|
9
|
+
* cache" back, and have that swallowed as success — reopening the false-
|
|
10
|
+
* success bug the throw exists to close. Resolvers that assert on-chain
|
|
11
|
+
* execution success throw this instead of a bare Error so
|
|
12
|
+
* `isTransientBroadcastError` can short-circuit before the message-regex
|
|
13
|
+
* test ever runs.
|
|
14
|
+
*/
|
|
15
|
+
export declare class DeliverTxFailedError extends Error {
|
|
16
|
+
constructor(message: string, options?: ErrorOptions);
|
|
17
|
+
}
|
|
1
18
|
export declare const broadcastRetryMaxAttempts = 3;
|
|
2
19
|
export declare const isTransientBroadcastError: (error: unknown) => boolean;
|
|
3
20
|
export declare const withTransientBroadcastRetry: <T>(operation: () => Promise<T>) => Promise<T>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transientRetry.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/tx/broadcast/transientRetry.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,yBAAyB,IAAI,CAAA;AA4C1C,eAAO,MAAM,yBAAyB,GAAI,OAAO,OAAO,KAAG,
|
|
1
|
+
{"version":3,"file":"transientRetry.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/chain/tx/broadcast/transientRetry.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAIpD;AAED,eAAO,MAAM,yBAAyB,IAAI,CAAA;AA4C1C,eAAO,MAAM,yBAAyB,GAAI,OAAO,OAAO,KAAG,OAoC1D,CAAA;AAED,eAAO,MAAM,2BAA2B,GAAU,CAAC,EAAE,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,KAAG,OAAO,CAAC,CAAC,CAkB3F,CAAA"}
|