@vultisig/core-chain 2.39.0 → 4.0.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.
Files changed (100) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/dist/chains/cardano/cip30/cardanoTxBodyHash.js +1 -1
  3. package/dist/chains/cardano/cip30/cardanoTxBodyHash.js.map +1 -1
  4. package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.js +2 -2
  5. package/dist/chains/cosmos/qbtc/claim/computeClaimHashes.js.map +1 -1
  6. package/dist/chains/solana/kamino/config.d.ts +11 -2
  7. package/dist/chains/solana/kamino/config.d.ts.map +1 -1
  8. package/dist/chains/solana/kamino/config.js +12 -2
  9. package/dist/chains/solana/kamino/config.js.map +1 -1
  10. package/dist/chains/sui/sign.js +1 -1
  11. package/dist/chains/sui/sign.js.map +1 -1
  12. package/dist/coin/balance/resolvers/bittensor.js +2 -2
  13. package/dist/coin/balance/resolvers/bittensor.js.map +1 -1
  14. package/dist/coin/balance/resolvers/polkadot.js +2 -2
  15. package/dist/coin/balance/resolvers/polkadot.js.map +1 -1
  16. package/dist/coin/balance/resolvers/ripple.d.ts +13 -0
  17. package/dist/coin/balance/resolvers/ripple.d.ts.map +1 -1
  18. package/dist/coin/balance/resolvers/ripple.js +14 -6
  19. package/dist/coin/balance/resolvers/ripple.js.map +1 -1
  20. package/dist/coin/find/resolvers/evm/index.d.ts.map +1 -1
  21. package/dist/coin/find/resolvers/evm/index.js +14 -6
  22. package/dist/coin/find/resolvers/evm/index.js.map +1 -1
  23. package/dist/coin/knownTokens/index.d.ts.map +1 -1
  24. package/dist/coin/knownTokens/index.js +11 -0
  25. package/dist/coin/knownTokens/index.js.map +1 -1
  26. package/dist/coin/price/evm/getErc20Prices.d.ts.map +1 -1
  27. package/dist/coin/price/evm/getErc20Prices.js +28 -1
  28. package/dist/coin/price/evm/getErc20Prices.js.map +1 -1
  29. package/dist/coin/price/evm/getEvmVaultTokenPrices.d.ts +16 -0
  30. package/dist/coin/price/evm/getEvmVaultTokenPrices.d.ts.map +1 -0
  31. package/dist/coin/price/evm/getEvmVaultTokenPrices.js +67 -0
  32. package/dist/coin/price/evm/getEvmVaultTokenPrices.js.map +1 -0
  33. package/dist/coin/price/evm/getLifiTokenPrices.d.ts +15 -0
  34. package/dist/coin/price/evm/getLifiTokenPrices.d.ts.map +1 -0
  35. package/dist/coin/price/evm/getLifiTokenPrices.js +28 -0
  36. package/dist/coin/price/evm/getLifiTokenPrices.js.map +1 -0
  37. package/dist/coin/price/getUsdToFiatRate.d.ts +8 -0
  38. package/dist/coin/price/getUsdToFiatRate.d.ts.map +1 -0
  39. package/dist/coin/price/getUsdToFiatRate.js +20 -0
  40. package/dist/coin/price/getUsdToFiatRate.js.map +1 -0
  41. package/dist/publicKey/address/cardano.js +1 -1
  42. package/dist/publicKey/address/cardano.js.map +1 -1
  43. package/dist/publicKey/address/deriveQbtcAddress.js +2 -2
  44. package/dist/publicKey/address/deriveQbtcAddress.js.map +1 -1
  45. package/dist/swap/quote/getSwapQuoteSafetyFingerprint.js +2 -2
  46. package/dist/swap/quote/getSwapQuoteSafetyFingerprint.js.map +1 -1
  47. package/dist/tx/broadcast/index.d.ts +2 -0
  48. package/dist/tx/broadcast/index.d.ts.map +1 -1
  49. package/dist/tx/broadcast/index.js +34 -3
  50. package/dist/tx/broadcast/index.js.map +1 -1
  51. package/dist/tx/broadcast/resolver.d.ts +35 -1
  52. package/dist/tx/broadcast/resolver.d.ts.map +1 -1
  53. package/dist/tx/broadcast/resolver.js +42 -1
  54. package/dist/tx/broadcast/resolver.js.map +1 -1
  55. package/dist/tx/broadcast/resolvers/bittensor.d.ts.map +1 -1
  56. package/dist/tx/broadcast/resolvers/bittensor.js +17 -6
  57. package/dist/tx/broadcast/resolvers/bittensor.js.map +1 -1
  58. package/dist/tx/broadcast/resolvers/cardano.d.ts.map +1 -1
  59. package/dist/tx/broadcast/resolvers/cardano.js +26 -16
  60. package/dist/tx/broadcast/resolvers/cardano.js.map +1 -1
  61. package/dist/tx/broadcast/resolvers/cosmos.d.ts.map +1 -1
  62. package/dist/tx/broadcast/resolvers/cosmos.js +33 -31
  63. package/dist/tx/broadcast/resolvers/cosmos.js.map +1 -1
  64. package/dist/tx/broadcast/resolvers/evm.d.ts.map +1 -1
  65. package/dist/tx/broadcast/resolvers/evm.js +21 -9
  66. package/dist/tx/broadcast/resolvers/evm.js.map +1 -1
  67. package/dist/tx/broadcast/resolvers/polkadot.d.ts.map +1 -1
  68. package/dist/tx/broadcast/resolvers/polkadot.js +23 -4
  69. package/dist/tx/broadcast/resolvers/polkadot.js.map +1 -1
  70. package/dist/tx/broadcast/resolvers/qbtc.d.ts.map +1 -1
  71. package/dist/tx/broadcast/resolvers/qbtc.js +69 -52
  72. package/dist/tx/broadcast/resolvers/qbtc.js.map +1 -1
  73. package/dist/tx/broadcast/resolvers/ripple.d.ts.map +1 -1
  74. package/dist/tx/broadcast/resolvers/ripple.js +24 -9
  75. package/dist/tx/broadcast/resolvers/ripple.js.map +1 -1
  76. package/dist/tx/broadcast/resolvers/solana.d.ts.map +1 -1
  77. package/dist/tx/broadcast/resolvers/solana.js +19 -10
  78. package/dist/tx/broadcast/resolvers/solana.js.map +1 -1
  79. package/dist/tx/broadcast/resolvers/sui.d.ts.map +1 -1
  80. package/dist/tx/broadcast/resolvers/sui.js +20 -14
  81. package/dist/tx/broadcast/resolvers/sui.js.map +1 -1
  82. package/dist/tx/broadcast/resolvers/ton.d.ts.map +1 -1
  83. package/dist/tx/broadcast/resolvers/ton.js +16 -5
  84. package/dist/tx/broadcast/resolvers/ton.js.map +1 -1
  85. package/dist/tx/broadcast/resolvers/tron.d.ts.map +1 -1
  86. package/dist/tx/broadcast/resolvers/tron.js +15 -6
  87. package/dist/tx/broadcast/resolvers/tron.js.map +1 -1
  88. package/dist/tx/broadcast/resolvers/utxo.d.ts.map +1 -1
  89. package/dist/tx/broadcast/resolvers/utxo.js +27 -17
  90. package/dist/tx/broadcast/resolvers/utxo.js.map +1 -1
  91. package/dist/tx/broadcast/transientRetry.d.ts.map +1 -1
  92. package/dist/tx/broadcast/transientRetry.js +4 -2
  93. package/dist/tx/broadcast/transientRetry.js.map +1 -1
  94. package/dist/tx/broadcast/verifyBroadcastByHash.d.ts +1 -1
  95. package/dist/tx/broadcast/verifyBroadcastByHash.d.ts.map +1 -1
  96. package/dist/tx/broadcast/verifyBroadcastByHash.js +1 -1
  97. package/dist/tx/broadcast/verifyBroadcastByHash.js.map +1 -1
  98. package/dist/tx/hash/resolvers/cardano.js +1 -1
  99. package/dist/tx/hash/resolvers/cardano.js.map +1 -1
  100. package/package.json +18 -3
@@ -3,6 +3,7 @@ import { getCosmosClient } from '@vultisig/core-chain/chains/cosmos/client';
3
3
  import { attempt } from '@vultisig/lib-utils/attempt';
4
4
  import { isInError } from '@vultisig/lib-utils/error/isInError';
5
5
  import { toCosmosSequenceMismatchError } from '../cosmosSequenceMismatch.js';
6
+ import { broadcastAccepted, broadcastFailed, isRetryableBroadcastCause } from '../resolver.js';
6
7
  import { DeliverTxFailedError } from '../transientRetry.js';
7
8
  import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
8
9
  export { CosmosSequenceMismatchError, toCosmosSequenceMismatchError } from '../cosmosSequenceMismatch.js';
@@ -13,41 +14,42 @@ export const getCosmosBroadcastTimeoutTxId = (error) => {
13
14
  return txId.trim() || undefined;
14
15
  };
15
16
  export const broadcastCosmosTx = async ({ chain, tx }) => {
16
- const { serialized } = tx;
17
- const { tx_bytes } = JSON.parse(serialized);
18
- const decodedTxBytes = Buffer.from(tx_bytes, 'base64');
19
- const client = await getCosmosClient(chain);
20
- const { data, error } = await attempt(client.broadcastTx(decodedTxBytes));
21
- if (data) {
22
- // client.broadcastTx resolves (does not throw) once the tx is INCLUDED in a
23
- // block, even when execution itself failed (DeliverTx code !== 0 — e.g.
24
- // out-of-gas, wasm revert, a THORChain/Maya deposit-handler rejection). The
25
- // tx is on-chain but nothing moved, so this must not be reported as success.
17
+ try {
18
+ const { serialized } = tx;
19
+ const { tx_bytes } = JSON.parse(serialized);
20
+ const decodedTxBytes = Buffer.from(tx_bytes, 'base64');
21
+ const client = await getCosmosClient(chain);
22
+ const result = await attempt(client.broadcastTx(decodedTxBytes));
23
+ if (result.data !== undefined) {
24
+ try {
25
+ assertIsDeliverTxSuccess(result.data);
26
+ }
27
+ catch (deliverTxError) {
28
+ const message = deliverTxError instanceof Error ? deliverTxError.message : String(deliverTxError);
29
+ return broadcastFailed(new DeliverTxFailedError(message, { cause: deliverTxError }), false, {
30
+ provider: result.data,
31
+ });
32
+ }
33
+ return broadcastAccepted(result.data.transactionHash, { provider: result.data });
34
+ }
35
+ const { error } = result;
36
+ if (isInError(error, 'tx already exists in cache')) {
37
+ return broadcastAccepted();
38
+ }
39
+ const timeoutTxId = getCosmosBroadcastTimeoutTxId(error);
40
+ if (timeoutTxId) {
41
+ return broadcastAccepted(timeoutTxId);
42
+ }
43
+ const verificationError = toCosmosSequenceMismatchError(error) ?? error;
26
44
  try {
27
- assertIsDeliverTxSuccess(data);
45
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error: verificationError }));
28
46
  }
29
- catch (deliverTxError) {
30
- // Marker type, not a bare Error: cosmos has no resolver-owned retry, so
31
- // this throws into `withTransientBroadcastRetry`. A rawLog like "wasm
32
- // contract aborted" would otherwise match the transient message regex
33
- // and get resent, then swallowed as an idempotent "already in cache"
34
- // success — reopening the bug this assert exists to close.
35
- const message = deliverTxError instanceof Error ? deliverTxError.message : String(deliverTxError);
36
- throw new DeliverTxFailedError(message, { cause: deliverTxError });
47
+ catch (cause) {
48
+ return broadcastFailed(cause, isRetryableBroadcastCause(cause));
37
49
  }
38
- return;
39
- }
40
- if (isInError(error, 'tx already exists in cache')) {
41
- return;
42
50
  }
43
- const timeoutTxId = getCosmosBroadcastTimeoutTxId(error);
44
- if (timeoutTxId) {
45
- return timeoutTxId;
51
+ catch (cause) {
52
+ return broadcastFailed(cause, isRetryableBroadcastCause(cause));
46
53
  }
47
- // Keep the hash-verification safety net first: another MPC participant may
48
- // have successfully broadcast these same bytes just before this node returned
49
- // a sequence rejection. When the hash is genuinely unknown, replace the raw
50
- // code-32 message with direction-aware recovery guidance.
51
- await verifyBroadcastByHash({ chain, tx, error: toCosmosSequenceMismatchError(error) ?? error });
52
54
  };
53
55
  //# sourceMappingURL=cosmos.js.map
@@ -1 +1 @@
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;AAE/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAA;AAEzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,OAAO,EAAE,2BAA2B,EAAE,6BAA6B,EAAE,MAAM,2BAA2B,CAAA;AAEtG,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,2EAA2E;IAC3E,8EAA8E;IAC9E,4EAA4E;IAC5E,0DAA0D;IAC1D,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,6BAA6B,CAAC,KAAK,CAAC,IAAI,KAAK,EAAE,CAAC,CAAA;AAClG,CAAC,CAAA"}
1
+ {"version":3,"file":"cosmos.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/cosmos.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAMrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAGjD,eAAO,MAAM,cAAc,EAAE,mBAAmB,CAAC,QAAQ,CAkBxD,CAAA"}
1
+ {"version":3,"file":"evm.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/evm.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAA;AAMrD,OAAO,EAAsC,mBAAmB,EAA6B,MAAM,aAAa,CAAA;AAGhH,eAAO,MAAM,cAAc,EAAE,mBAAmB,CAAC,QAAQ,CA2BxD,CAAA"}
@@ -2,18 +2,30 @@ import { getEvmClient } from '@vultisig/core-chain/chains/evm/client';
2
2
  import { attempt } from '@vultisig/lib-utils/attempt';
3
3
  import { isInError } from '@vultisig/lib-utils/error/isInError';
4
4
  import { ensureHexPrefix } from '@vultisig/lib-utils/hex/ensureHexPrefix';
5
+ import { broadcastAccepted, broadcastFailed, isRetryableBroadcastCause } from '../resolver.js';
5
6
  import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
6
7
  export const broadcastEvmTx = async ({ chain, tx }) => {
7
- const client = getEvmClient(chain);
8
- const { error } = await attempt(client.sendRawTransaction({
9
- serializedTransaction: ensureHexPrefix(Buffer.from(tx.encoded).toString('hex')),
10
- }));
11
- if (!error) {
12
- return;
8
+ try {
9
+ const client = getEvmClient(chain);
10
+ const result = await attempt(client.sendRawTransaction({
11
+ serializedTransaction: ensureHexPrefix(Buffer.from(tx.encoded).toString('hex')),
12
+ }));
13
+ if ('data' in result) {
14
+ return broadcastAccepted(result.data);
15
+ }
16
+ const { error } = result;
17
+ if (error && isInError(error, 'already known', 'transaction already exists', 'tx already in mempool')) {
18
+ return broadcastAccepted();
19
+ }
20
+ try {
21
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
22
+ }
23
+ catch (cause) {
24
+ return broadcastFailed(cause, isRetryableBroadcastCause(error));
25
+ }
13
26
  }
14
- if (isInError(error, 'already known', 'transaction already exists', 'tx already in mempool')) {
15
- return;
27
+ catch (cause) {
28
+ return broadcastFailed(cause, isRetryableBroadcastCause(cause));
16
29
  }
17
- await verifyBroadcastByHash({ chain, tx, error });
18
30
  };
19
31
  //# sourceMappingURL=evm.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"evm.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/evm.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AAGzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,MAAM,CAAC,MAAM,cAAc,GAAkC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IACnF,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;IAElC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,OAAO,CAC7B,MAAM,CAAC,kBAAkB,CAAC;QACxB,qBAAqB,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;KAChF,CAAC,CACH,CAAA;IAED,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAM;IACR,CAAC;IAED,IAAI,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE,4BAA4B,EAAE,uBAAuB,CAAC,EAAE,CAAC;QAC7F,OAAM;IACR,CAAC;IAED,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;AACnD,CAAC,CAAA"}
1
+ {"version":3,"file":"evm.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/evm.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AACrE,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAA;AAEzE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAuB,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAChH,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE,MAAM,CAAC,MAAM,cAAc,GAAkC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IACnF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,YAAY,CAAC,KAAK,CAAC,CAAA;QAElC,MAAM,MAAM,GAAG,MAAM,OAAO,CAC1B,MAAM,CAAC,kBAAkB,CAAC;YACxB,qBAAqB,EAAE,eAAe,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;SAChF,CAAC,CACH,CAAA;QAED,IAAI,MAAM,IAAI,MAAM,EAAE,CAAC;YACrB,OAAO,iBAAiB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACvC,CAAC;QAED,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,CAAA;QACxB,IAAI,KAAK,IAAI,SAAS,CAAC,KAAK,EAAE,eAAe,EAAE,4BAA4B,EAAE,uBAAuB,CAAC,EAAE,CAAC;YACtG,OAAO,iBAAiB,EAAE,CAAA;QAC5B,CAAC;QAED,IAAI,CAAC;YACH,OAAO,iBAAiB,CAAC,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;QAC7E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAA;QACjE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAA;IACjE,CAAC;AACH,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;AASjD,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,UAAU,CAAC,QAAQ,CAiCxE,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,EAAsC,mBAAmB,EAA6B,MAAM,aAAa,CAAA;AAShH,eAAO,MAAM,mBAAmB,EAAE,mBAAmB,CAAC,UAAU,CAAC,QAAQ,CAgDxE,CAAA"}
@@ -1,6 +1,7 @@
1
1
  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
+ import { broadcastAccepted, broadcastFailed, isRetryableBroadcastCause } from '../resolver.js';
4
5
  import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
5
6
  import { formatSubstrateRpcError, isIdempotentSubstrateBroadcastError } from './substrate.js';
6
7
  export const broadcastPolkadotTx = async ({ chain, tx }) => {
@@ -20,19 +21,37 @@ export const broadcastPolkadotTx = async ({ chain, tx }) => {
20
21
  // (string usually in `message`) or, less commonly, an Invalid
21
22
  // Transaction variant whose duplicate signal lives in `data`.
22
23
  if (isIdempotentSubstrateBroadcastError(response.error)) {
23
- return;
24
+ return broadcastAccepted();
25
+ }
26
+ const error = new Error(`Polkadot broadcast failed: ${formatSubstrateRpcError(response.error)}`);
27
+ try {
28
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
29
+ }
30
+ catch (cause) {
31
+ return broadcastFailed(cause, false);
24
32
  }
25
- throw new Error(`Polkadot broadcast failed: ${formatSubstrateRpcError(response.error)}`);
26
33
  }
27
34
  // Per JSON-RPC 2.0 a valid response must have exactly one of `result` /
28
35
  // `error`. If both are missing (malformed gateway response, truncated
29
36
  // body, …) do not silently assume success — force hash verification.
30
37
  if (!response.result) {
31
- throw new Error('Polkadot broadcast failed: missing extrinsic hash in RPC response');
38
+ const error = new Error('Polkadot broadcast failed: missing extrinsic hash in RPC response');
39
+ try {
40
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
41
+ }
42
+ catch (cause) {
43
+ return broadcastFailed(cause, false);
44
+ }
32
45
  }
46
+ return broadcastAccepted(response.result);
33
47
  }
34
48
  catch (error) {
35
- await verifyBroadcastByHash({ chain, tx, error });
49
+ try {
50
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
51
+ }
52
+ catch (cause) {
53
+ return broadcastFailed(cause, isRetryableBroadcastCause(error));
54
+ }
36
55
  }
37
56
  };
38
57
  //# sourceMappingURL=polkadot.js.map
@@ -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;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
+ {"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;AAChE,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAuB,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAChH,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,OAAO,iBAAiB,EAAE,CAAA;YAC5B,CAAC;YACD,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,8BAA8B,uBAAuB,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;YAChG,IAAI,CAAC;gBACH,OAAO,iBAAiB,CAAC,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YAC7E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,sEAAsE;QACtE,qEAAqE;QACrE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;YACrB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,mEAAmE,CAAC,CAAA;YAC5F,IAAI,CAAC;gBACH,OAAO,iBAAiB,CAAC,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;YAC7E,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,eAAe,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;YACtC,CAAC;QACH,CAAC;QACD,OAAO,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;IAC3C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC;YACH,OAAO,iBAAiB,CAAC,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;QAC7E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,eAAe,CAAC,KAAK,EAAE,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAA;QACjE,CAAC;IACH,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;AAMlD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AASjD,eAAO,MAAM,eAAe,EAAE,mBAAmB,CAAC,OAAO,KAAK,CAAC,IAAI,CAqElE,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;AAOlD,OAAO,EAAsC,mBAAmB,EAA6B,MAAM,aAAa,CAAA;AAShH,eAAO,MAAM,eAAe,EAAE,mBAAmB,CAAC,OAAO,KAAK,CAAC,IAAI,CAoFlE,CAAA"}
@@ -2,6 +2,8 @@ import { qbtcRestUrl } from '@vultisig/core-chain/chains/cosmos/qbtc/tendermintR
2
2
  import { waitForQbtcTxInclusion } from '@vultisig/core-chain/chains/cosmos/qbtc/waitForQbtcTxInclusion';
3
3
  import { attempt } from '@vultisig/lib-utils/attempt';
4
4
  import { isInError } from '@vultisig/lib-utils/error/isInError';
5
+ import { HttpResponseError } from '@vultisig/lib-utils/fetch/HttpResponseError';
6
+ import { broadcastAccepted, broadcastFailed, isRetryableBroadcastCause } from '../resolver.js';
5
7
  import { DeliverTxFailedError } from '../transientRetry.js';
6
8
  import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
7
9
  // QBTC block time is ~5-7s; give a DeliverTx a generous window to land before treating the tx as
@@ -9,61 +11,76 @@ import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
9
11
  const QBTC_INCLUSION_TIMEOUT_MS = 30_000;
10
12
  const QBTC_INCLUSION_POLL_INTERVAL_MS = 1_000;
11
13
  export const broadcastQbtcTx = async ({ chain, tx }) => {
12
- const { serialized } = tx;
13
- const { tx_bytes } = JSON.parse(serialized);
14
- const resp = await fetch(`${qbtcRestUrl}/cosmos/tx/v1beta1/txs`, {
15
- method: 'POST',
16
- headers: { 'Content-Type': 'application/json' },
17
- body: JSON.stringify({
18
- tx_bytes,
19
- mode: 'BROADCAST_MODE_SYNC',
20
- }),
21
- });
22
- if (!resp.ok) {
23
- const text = await resp.text();
24
- if (isInError(text, 'tx already exists in cache')) {
25
- return;
14
+ try {
15
+ const { serialized } = tx;
16
+ const { tx_bytes } = JSON.parse(serialized);
17
+ const resp = await fetch(`${qbtcRestUrl}/cosmos/tx/v1beta1/txs`, {
18
+ method: 'POST',
19
+ headers: { 'Content-Type': 'application/json' },
20
+ body: JSON.stringify({
21
+ tx_bytes,
22
+ mode: 'BROADCAST_MODE_SYNC',
23
+ }),
24
+ });
25
+ if (!resp.ok) {
26
+ const text = await resp.text();
27
+ if (isInError(text, 'tx already exists in cache')) {
28
+ return broadcastAccepted();
29
+ }
30
+ const err = new HttpResponseError({
31
+ message: `QBTC broadcast failed (${resp.status}): ${text}`,
32
+ status: resp.status,
33
+ statusText: resp.statusText,
34
+ url: resp.url || `${qbtcRestUrl}/cosmos/tx/v1beta1/txs`,
35
+ body: text,
36
+ });
37
+ try {
38
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error: err }));
39
+ }
40
+ catch (cause) {
41
+ return broadcastFailed(cause, isRetryableBroadcastCause(err));
42
+ }
26
43
  }
27
- const err = new Error(`QBTC broadcast failed (${resp.status}): ${text}`);
28
- await verifyBroadcastByHash({ chain, tx, error: err });
29
- return;
30
- }
31
- const data = (await resp.json());
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;
44
+ const data = (await resp.json());
45
+ const checkTx = data.tx_response;
46
+ if (typeof checkTx?.code !== 'number' || checkTx.code !== 0) {
47
+ const log = checkTx?.raw_log || checkTx?.log;
48
+ if (log && isInError(log, 'tx already exists in cache')) {
49
+ return broadcastAccepted();
50
+ }
51
+ const error = new Error(`QBTC CheckTx failed: ${log ?? 'missing tx_response.code'}`);
52
+ try {
53
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
54
+ }
55
+ catch (cause) {
56
+ return broadcastFailed(cause, false);
57
+ }
40
58
  }
41
- const err = new Error(`QBTC CheckTx failed: ${log ?? 'missing tx_response.code'}`);
42
- await verifyBroadcastByHash({ chain, tx, error: err });
43
- return;
44
- }
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') });
55
- return;
56
- }
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;
59
+ const txHash = checkTx.txhash;
60
+ if (!txHash) {
61
+ const error = new Error('QBTC broadcast: missing txhash on CheckTx response');
62
+ try {
63
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
64
+ }
65
+ catch (cause) {
66
+ return broadcastFailed(cause, false);
67
+ }
68
+ }
69
+ const { data: included, error: inclusionError } = await attempt(waitForQbtcTxInclusion({
70
+ txHash,
71
+ timeoutMs: QBTC_INCLUSION_TIMEOUT_MS,
72
+ intervalMs: QBTC_INCLUSION_POLL_INTERVAL_MS,
73
+ }));
74
+ if (inclusionError || included === undefined || typeof included.code !== 'number') {
75
+ return broadcastAccepted(txHash);
76
+ }
77
+ if (included.code !== 0) {
78
+ return broadcastFailed(new DeliverTxFailedError(`QBTC transaction execution failed: ${included.raw_log || included.log}`), false);
79
+ }
80
+ return broadcastAccepted(txHash, { provider: included });
64
81
  }
65
- if (included.code !== 0) {
66
- throw new DeliverTxFailedError(`QBTC transaction execution failed: ${included.raw_log || included.log}`);
82
+ catch (cause) {
83
+ return broadcastFailed(cause, isRetryableBroadcastCause(cause));
67
84
  }
68
85
  };
69
86
  //# sourceMappingURL=qbtc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"qbtc.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/qbtc.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"qbtc.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/qbtc.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/ripple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAGvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AA8BjD,eAAO,MAAM,4BAA4B,GAAI,cAAc,MAAM,KAAG,OAAuC,CAAA;AAE3G,eAAO,MAAM,iBAAiB,EAAE,mBAAmB,CAAC,UAAU,CAAC,MAAM,CA0CpE,CAAA"}
1
+ {"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/ripple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAGvD,OAAO,EAAsC,mBAAmB,EAA6B,MAAM,aAAa,CAAA;AA8BhH,eAAO,MAAM,4BAA4B,GAAI,cAAc,MAAM,KAAG,OAAuC,CAAA;AAE3G,eAAO,MAAM,iBAAiB,EAAE,mBAAmB,CAAC,UAAU,CAAC,MAAM,CAqDpE,CAAA"}
@@ -1,4 +1,5 @@
1
1
  import { getRippleClient } from '@vultisig/core-chain/chains/ripple/client';
2
+ import { broadcastAccepted, broadcastFailed, isRetryableBroadcastCause } from '../resolver.js';
2
3
  import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
3
4
  /**
4
5
  * Engine result codes from XRPL `submit` that indicate the tx may already
@@ -28,7 +29,13 @@ import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
28
29
  const PEER_RACE_ENGINE_RESULTS = new Set(['tefALREADY', 'tefPAST_SEQ']);
29
30
  export const isRippleInFlightEngineResult = (engineResult) => engineResult === 'terQUEUED';
30
31
  export const broadcastRippleTx = async ({ chain, tx }) => {
31
- const client = await getRippleClient();
32
+ let client;
33
+ try {
34
+ client = await getRippleClient();
35
+ }
36
+ catch (cause) {
37
+ return broadcastFailed(cause, isRetryableBroadcastCause(cause));
38
+ }
32
39
  // RPC-level errors (network blip, connection drop) get the safety-net
33
40
  // verify-by-hash path: another peer's broadcast may have landed the tx.
34
41
  let response;
@@ -39,13 +46,17 @@ export const broadcastRippleTx = async ({ chain, tx }) => {
39
46
  });
40
47
  }
41
48
  catch (error) {
42
- await verifyBroadcastByHash({ chain, tx, error });
43
- return;
49
+ try {
50
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
51
+ }
52
+ catch (cause) {
53
+ return broadcastFailed(cause, isRetryableBroadcastCause(error));
54
+ }
44
55
  }
45
56
  const engineResultCode = response?.result?.engine_result_code;
46
57
  if (typeof engineResultCode !== 'number' || engineResultCode === 0) {
47
58
  // tesSUCCESS (applied / queued for next ledger). All good.
48
- return;
59
+ return broadcastAccepted(response?.result?.tx_json?.hash);
49
60
  }
50
61
  const engineResult = response.result.engine_result ?? 'unknown';
51
62
  const engineResultMessage = response.result.engine_result_message ?? '';
@@ -53,14 +64,18 @@ export const broadcastRippleTx = async ({ chain, tx }) => {
53
64
  if (PEER_RACE_ENGINE_RESULTS.has(engineResult)) {
54
65
  // Duplicate / past-sequence: fast MPC peer's broadcast may have
55
66
  // already landed the tx. Verify before swallowing.
56
- await verifyBroadcastByHash({ chain, tx, error });
57
- return;
67
+ try {
68
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error }));
69
+ }
70
+ catch (cause) {
71
+ return broadcastFailed(cause, false);
72
+ }
58
73
  }
59
74
  if (isRippleInFlightEngineResult(engineResult)) {
60
- return;
75
+ return broadcastAccepted(response?.result?.tx_json?.hash);
61
76
  }
62
77
  // Authoritative rejection at preflight (tem*/tec*/tel*/remaining ter*/remaining tef*).
63
- // Propagate so the caller sees the real failure instead of a fake hash.
64
- throw error;
78
+ // Return it through the shared contract so callers never receive a raw throw.
79
+ return broadcastFailed(error, false);
65
80
  };
66
81
  //# sourceMappingURL=ripple.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/ripple.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,2CAA2C,CAAA;AAG3E,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAA;AAEhE;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,wBAAwB,GAAG,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAA;AAEvE,MAAM,CAAC,MAAM,4BAA4B,GAAG,CAAC,YAAoB,EAAW,EAAE,CAAC,YAAY,KAAK,WAAW,CAAA;AAE3G,MAAM,CAAC,MAAM,iBAAiB,GAA2C,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,EAAE;IAC/F,MAAM,MAAM,GAAG,MAAM,eAAe,EAAE,CAAA;IAEtC,sEAAsE;IACtE,wEAAwE;IACxE,IAAI,QAAQ,CAAA;IACZ,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC;YAC9B,OAAO,EAAE,QAAQ;YACjB,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;SACjD,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QACjD,OAAM;IACR,CAAC;IAED,MAAM,gBAAgB,GAAG,QAAQ,EAAE,MAAM,EAAE,kBAAkB,CAAA;IAC7D,IAAI,OAAO,gBAAgB,KAAK,QAAQ,IAAI,gBAAgB,KAAK,CAAC,EAAE,CAAC;QACnE,2DAA2D;QAC3D,OAAM;IACR,CAAC;IAED,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,IAAI,SAAS,CAAA;IAC/D,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,CAAC,qBAAqB,IAAI,EAAE,CAAA;IACvE,MAAM,KAAK,GAAG,IAAI,KAAK,CACrB,8BAA8B,YAAY,GAAG,mBAAmB,CAAC,CAAC,CAAC,MAAM,mBAAmB,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACtG,CAAA;IAED,IAAI,wBAAwB,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/C,gEAAgE;QAChE,mDAAmD;QACnD,MAAM,qBAAqB,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,CAAA;QACjD,OAAM;IACR,CAAC;IAED,IAAI,4BAA4B,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/C,OAAM;IACR,CAAC;IAED,uFAAuF;IACvF,wEAAwE;IACxE,MAAM,KAAK,CAAA;AACb,CAAC,CAAA"}
1
+ {"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/ripple.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/solana.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAMvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAuDjD,eAAO,MAAM,iBAAiB,EAAE,mBAAmB,CAAC,UAAU,CAAC,MAAM,CA2CpE,CAAA"}
1
+ {"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/solana.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAMvD,OAAO,EAAsC,mBAAmB,EAA6B,MAAM,aAAa,CAAA;AAwDhH,eAAO,MAAM,iBAAiB,EAAE,mBAAmB,CAAC,UAAU,CAAC,MAAM,CAiDpE,CAAA"}
@@ -3,6 +3,7 @@ import { getSolanaClient } from '@vultisig/core-chain/chains/solana/client';
3
3
  import { sendJitoTransaction } from '@vultisig/core-chain/chains/solana/jito';
4
4
  import { isInError } from '@vultisig/lib-utils/error/isInError';
5
5
  import base58 from 'bs58';
6
+ import { broadcastAccepted, broadcastFailed, isRetryableBroadcastCause } from '../resolver.js';
6
7
  import { verifyBroadcastByHash } from '../verifyBroadcastByHash.js';
7
8
  const solanaStandardRpcMaxAttempts = 3;
8
9
  const solanaStandardRpcRetryDelayMs = 500;
@@ -33,11 +34,10 @@ const sendSolanaRawTransaction = async (rawTransaction) => {
33
34
  const client = getSolanaClient();
34
35
  for (let attempt = 1; attempt <= solanaStandardRpcMaxAttempts; attempt++) {
35
36
  try {
36
- await client.sendRawTransaction(rawTransaction, {
37
+ return await client.sendRawTransaction(rawTransaction, {
37
38
  skipPreflight: false,
38
39
  preflightCommitment: 'confirmed',
39
40
  });
40
- return;
41
41
  }
42
42
  catch (error) {
43
43
  if (isTransientBlockhashError(error) && attempt < solanaStandardRpcMaxAttempts) {
@@ -47,9 +47,16 @@ const sendSolanaRawTransaction = async (rawTransaction) => {
47
47
  throw error;
48
48
  }
49
49
  }
50
+ throw new Error('Solana broadcast retry loop exhausted');
50
51
  };
51
52
  export const broadcastSolanaTx = async ({ chain, tx }) => {
52
- const rawTransaction = base58.decode(tx.encoded);
53
+ let rawTransaction;
54
+ try {
55
+ rawTransaction = base58.decode(tx.encoded);
56
+ }
57
+ catch (cause) {
58
+ return broadcastFailed(cause, false);
59
+ }
53
60
  // Try JITO first for MEV protection, but still relay through standard RPC.
54
61
  // JITO can accept sendTransaction without the signature later appearing in
55
62
  // public Solana history, so standard RPC propagation is the durable signal.
@@ -60,7 +67,7 @@ export const broadcastSolanaTx = async ({ chain, tx }) => {
60
67
  console.warn('[solana] JITO sendTransaction failed, falling back to standard RPC:', err);
61
68
  }
62
69
  try {
63
- await sendSolanaRawTransaction(rawTransaction);
70
+ return broadcastAccepted(await sendSolanaRawTransaction(rawTransaction));
64
71
  }
65
72
  catch (error) {
66
73
  // A duplicate-signature error means the node already accepted this exact
@@ -83,13 +90,15 @@ export const broadcastSolanaTx = async ({ chain, tx }) => {
83
90
  // raw-SDK consumer that broadcasts and skips that confirmation poll is
84
91
  // exposed to the optimistic result; the CLI agent always confirms.
85
92
  if (isInError(error, 'already been processed', 'AlreadyProcessed')) {
86
- return;
93
+ return broadcastAccepted();
94
+ }
95
+ const cause = withSolanaBroadcastReason(error);
96
+ try {
97
+ return broadcastAccepted(await verifyBroadcastByHash({ chain, tx, error: cause }));
98
+ }
99
+ catch (verifiedCause) {
100
+ return broadcastFailed(verifiedCause, isTransientBlockhashError(error) || isRetryableBroadcastCause(error));
87
101
  }
88
- await verifyBroadcastByHash({
89
- chain,
90
- tx,
91
- error: withSolanaBroadcastReason(error),
92
- });
93
102
  }
94
103
  };
95
104
  //# sourceMappingURL=solana.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"solana.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/solana.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"solana.js","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/solana.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sui.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/sui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAEvD,OAAO,EAGL,wBAAwB,EACzB,MAAM,mDAAmD,CAAA;AAG1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AAIjD,eAAO,MAAM,oBAAoB,GAAI,QAAQ,wBAAwB,GAAG,IAAI,GAAG,SAAS,KAAG,IAI1F,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,CAkC9D,CAAA"}
1
+ {"version":3,"file":"sui.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/chain/tx/broadcast/resolvers/sui.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAA;AAEvD,OAAO,EAIL,wBAAwB,EACzB,MAAM,mDAAmD,CAAA;AAG1D,OAAO,EAAsC,mBAAmB,EAA6B,MAAM,aAAa,CAAA;AAIhH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,wBAAwB,GAAG,IAAI,GAAG,SAAS,KAAG,IAI1F,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,mBAAmB,CAAC,UAAU,CAAC,GAAG,CAuC9D,CAAA"}