@vultisig/core-mpc 1.8.17 → 1.8.19

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 (59) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/dist/keysign/chainSpecific/index.js +1 -1
  3. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/buildSimulateTxBytes.d.ts +27 -0
  4. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/buildSimulateTxBytes.d.ts.map +1 -0
  5. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/buildSimulateTxBytes.js +64 -0
  6. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/buildSimulateTxBytes.js.map +1 -0
  7. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/estimateCosmosGasLimit.d.ts +24 -0
  8. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/estimateCosmosGasLimit.d.ts.map +1 -0
  9. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/estimateCosmosGasLimit.js +43 -0
  10. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/estimateCosmosGasLimit.js.map +1 -0
  11. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/scaleCosmosGasLimit.d.ts +21 -0
  12. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/scaleCosmosGasLimit.d.ts.map +1 -0
  13. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/scaleCosmosGasLimit.js +21 -0
  14. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/scaleCosmosGasLimit.js.map +1 -0
  15. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/simulateCosmosGas.d.ts +16 -0
  16. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/simulateCosmosGas.d.ts.map +1 -0
  17. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/simulateCosmosGas.js +23 -0
  18. package/dist/keysign/chainSpecific/resolvers/cosmos/gasEstimation/simulateCosmosGas.js.map +1 -0
  19. package/dist/keysign/chainSpecific/resolvers/cosmos/index.d.ts +3 -0
  20. package/dist/keysign/chainSpecific/resolvers/cosmos/index.d.ts.map +1 -0
  21. package/dist/keysign/chainSpecific/resolvers/{cosmos.js → cosmos/index.js} +35 -3
  22. package/dist/keysign/chainSpecific/resolvers/cosmos/index.js.map +1 -0
  23. package/dist/keysign/chainSpecific/resolvers/ripple.d.ts.map +1 -1
  24. package/dist/keysign/chainSpecific/resolvers/ripple.js +18 -6
  25. package/dist/keysign/chainSpecific/resolvers/ripple.js.map +1 -1
  26. package/dist/keysign/chainSpecific/resolvers/sui/index.d.ts.map +1 -1
  27. package/dist/keysign/chainSpecific/resolvers/sui/index.js +28 -4
  28. package/dist/keysign/chainSpecific/resolvers/sui/index.js.map +1 -1
  29. package/dist/keysign/chainSpecific/resolvers/ton/index.d.ts.map +1 -1
  30. package/dist/keysign/chainSpecific/resolvers/ton/index.js +10 -1
  31. package/dist/keysign/chainSpecific/resolvers/ton/index.js.map +1 -1
  32. package/dist/keysign/fee/resolvers/cosmos.d.ts +4 -0
  33. package/dist/keysign/fee/resolvers/cosmos.d.ts.map +1 -1
  34. package/dist/keysign/fee/resolvers/cosmos.js +16 -1
  35. package/dist/keysign/fee/resolvers/cosmos.js.map +1 -1
  36. package/dist/keysign/signingInputs/resolvers/cardano.d.ts.map +1 -1
  37. package/dist/keysign/signingInputs/resolvers/cardano.js +16 -1
  38. package/dist/keysign/signingInputs/resolvers/cardano.js.map +1 -1
  39. package/dist/keysign/signingInputs/resolvers/cosmos/index.d.ts.map +1 -1
  40. package/dist/keysign/signingInputs/resolvers/cosmos/index.js +13 -5
  41. package/dist/keysign/signingInputs/resolvers/cosmos/index.js.map +1 -1
  42. package/dist/keysign/utils/resolvePolkadotToAddress.d.ts.map +1 -1
  43. package/dist/keysign/utils/resolvePolkadotToAddress.js +15 -3
  44. package/dist/keysign/utils/resolvePolkadotToAddress.js.map +1 -1
  45. package/dist/keysign/utxo/getKeysignUtxoInfo.d.ts.map +1 -1
  46. package/dist/keysign/utxo/getKeysignUtxoInfo.js +44 -4
  47. package/dist/keysign/utxo/getKeysignUtxoInfo.js.map +1 -1
  48. package/dist/types/vultisig/keysign/v1/blockchain_specific_pb.d.ts +15 -1
  49. package/dist/types/vultisig/keysign/v1/blockchain_specific_pb.d.ts.map +1 -1
  50. package/dist/types/vultisig/keysign/v1/blockchain_specific_pb.js +5 -1
  51. package/dist/types/vultisig/keysign/v1/blockchain_specific_pb.js.map +1 -1
  52. package/dist/types/vultisig/keysign/v1/utxo_info_pb.d.ts +46 -0
  53. package/dist/types/vultisig/keysign/v1/utxo_info_pb.d.ts.map +1 -1
  54. package/dist/types/vultisig/keysign/v1/utxo_info_pb.js +7 -2
  55. package/dist/types/vultisig/keysign/v1/utxo_info_pb.js.map +1 -1
  56. package/package.json +25 -5
  57. package/dist/keysign/chainSpecific/resolvers/cosmos.d.ts +0 -3
  58. package/dist/keysign/chainSpecific/resolvers/cosmos.d.ts.map +0 -1
  59. package/dist/keysign/chainSpecific/resolvers/cosmos.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,59 @@
1
1
  # @vultisig/core-mpc
2
2
 
3
+ ## 1.8.19
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1014](https://github.com/vultisig/vultisig-sdk/pull/1014) [`c41a219`](https://github.com/vultisig/vultisig-sdk/commit/c41a21950c4cccf70c8298b8e595acf64c276d8c) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - feat(cosmos): initiator-side dynamic gas — simulate native sends and relay `CosmosSpecific.gas_limit`
8
+
9
+ `getCosmosChainSpecific` now simulates native Cosmos bank sends via
10
+ `/cosmos/tx/v1beta1/simulate` and relays the padded (`× 1.3`) `gas_used` to
11
+ co-signers in `CosmosSpecific.gas_limit`. The signing-inputs resolver already
12
+ honors this field (scaling the fee amount accordingly) and falls back to the
13
+ static per-chain gas limit when it is absent or zero, so:
14
+
15
+ - Only native bank sends are simulated (a relayed dapp `signData`, token / IBC /
16
+ contract / staking txs, and vault-based chains keep the static limit).
17
+ - Estimation fails closed: any simulate/build error leaves the field unset, so
18
+ simulation never blocks signing and peers converge on the static limit.
19
+ - The relayed limit is part of the SignDoc every device hashes; because it is
20
+ computed with exact integer math (ceil of `gas_used × 13 / 10`) and honored
21
+ identically across peers, cross-device co-signing stays byte-identical.
22
+
23
+ Mirrors the iOS `CosmosGasEstimator` implementation.
24
+
25
+ - Updated dependencies [[`c41a219`](https://github.com/vultisig/vultisig-sdk/commit/c41a21950c4cccf70c8298b8e595acf64c276d8c)]:
26
+ - @vultisig/core-chain@2.23.2
27
+
28
+ ## 1.8.18
29
+
30
+ ### Patch Changes
31
+
32
+ - [#956](https://github.com/vultisig/vultisig-sdk/pull/956) [`f72cbc3`](https://github.com/vultisig/vultisig-sdk/commit/f72cbc35a23edb2b14984fce0a16495a3339e5e6) Thanks [@gastonm5](https://github.com/gastonm5)! - fix(cardano): attach and plan per-UTXO native-token data for MPC keysign parity
33
+
34
+ Adopts commondata's `UtxoInfo.cardano_tokens` across all three missing
35
+ layers, mirroring the mainnet-tested iOS implementation byte-for-byte:
36
+
37
+ - Regenerates `utxo_info_pb.ts` so `CardanoTokenAsset` /
38
+ `UtxoInfo.cardanoTokens` exist and can be decoded off the keysign wire.
39
+ - The keysign initiator fetches Cardano UTXOs with Koios `_extended` and
40
+ attaches per-UTXO native assets (UTXOs ordered by `(hash, index)`, assets
41
+ by `(policyId, assetNameHex)`, hex lowercased) so co-signers see
42
+ deterministic, token-aware payload bytes.
43
+ - The Cardano signing-inputs resolver maps `cardanoTokens` onto WalletCore
44
+ `TxInput.token_amount` (minimal big-endian amount bytes), letting the
45
+ planner reconcile input tokens into the change output.
46
+
47
+ Fixes MPC co-signing for any Cardano address holding native tokens:
48
+ iOS/macOS-initiated sends no longer fail keysign with a pre-image hash
49
+ mismatch, and SDK-initiated sends no longer build token-dropping bodies
50
+ that the node rejects at broadcast (Ogmios 3123 "value not conserved").
51
+
52
+ - [#985](https://github.com/vultisig/vultisig-sdk/pull/985) [`2f23526`](https://github.com/vultisig/vultisig-sdk/commit/2f23526e39d22f8f13aea1310ba4106137f3484c) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Regenerate keysign protobuf types from latest commondata: add `CosmosSpecific.gasLimit` (field 7) and the `TransactionType.QBTC_CLAIM_WITH_PROOF` enum value.
53
+
54
+ - Updated dependencies [[`f72cbc3`](https://github.com/vultisig/vultisig-sdk/commit/f72cbc35a23edb2b14984fce0a16495a3339e5e6), [`119d96d`](https://github.com/vultisig/vultisig-sdk/commit/119d96d5b2c9e1e2d8b322bf31d83f3ac4294244)]:
55
+ - @vultisig/core-chain@2.23.1
56
+
3
57
  ## 1.8.17
4
58
 
5
59
  ### Patch Changes
@@ -3,7 +3,7 @@ import { getKeysignCoin } from '../utils/getKeysignCoin.js';
3
3
  import { chainSpecificRecord } from './KeysignChainSpecific.js';
4
4
  import { getBittensorChainSpecific } from './resolvers/bittensor/index.js';
5
5
  import { getCardanoChainSpecific } from './resolvers/cardano.js';
6
- import { getCosmosChainSpecific } from './resolvers/cosmos.js';
6
+ import { getCosmosChainSpecific } from './resolvers/cosmos/index.js';
7
7
  import { getEvmChainSpecific } from './resolvers/evm.js';
8
8
  import { getMayaChainSpecific } from './resolvers/maya.js';
9
9
  import { getPolkadotChainSpecific } from './resolvers/polkadot/index.js';
@@ -0,0 +1,27 @@
1
+ import { CosmosChain } from '@vultisig/core-chain/Chain';
2
+ import { WalletCore } from '@trustwallet/wallet-core';
3
+ type BuildSimulateTxBytesInput = {
4
+ walletCore: WalletCore;
5
+ chain: CosmosChain;
6
+ hexPublicKey: string;
7
+ fromAddress: string;
8
+ toAddress: string;
9
+ /** send amount in base units (matches the real send so simulated gas lines up) */
10
+ amount: string;
11
+ denom: string;
12
+ memo?: string;
13
+ accountNumber: bigint;
14
+ sequence: bigint;
15
+ };
16
+ /**
17
+ * Builds the base64 `tx_bytes` (protobuf `TxRaw`) for a native bank send,
18
+ * carrying a 64-byte dummy signature. `/cosmos/tx/v1beta1/simulate` decodes
19
+ * this and runs it against current state while skipping signature
20
+ * verification, so the bogus signature is accepted. Models only a native
21
+ * `MsgSend` — callers must restrict simulation to native sends.
22
+ *
23
+ * Mirrors iOS `CosmosGasEstimator.buildSimulateTxBytes`.
24
+ */
25
+ export declare const buildSimulateTxBytes: ({ walletCore, chain, hexPublicKey, fromAddress, toAddress, amount, denom, memo, accountNumber, sequence, }: BuildSimulateTxBytesInput) => string;
26
+ export {};
27
+ //# sourceMappingURL=buildSimulateTxBytes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildSimulateTxBytes.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/gasEstimation/buildSimulateTxBytes.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAOxD,OAAO,EAAM,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAGzD,KAAK,yBAAyB,GAAG;IAC/B,UAAU,EAAE,UAAU,CAAA;IACtB,KAAK,EAAE,WAAW,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,GAAI,4GAWlC,yBAAyB,KAAG,MAoD9B,CAAA"}
@@ -0,0 +1,64 @@
1
+ import { Buffer } from 'buffer';
2
+ import { cosmosFeeCoinDenom } from '@vultisig/core-chain/chains/cosmos/cosmosFeeCoinDenom';
3
+ import { getCosmosGasLimit } from '@vultisig/core-chain/chains/cosmos/cosmosGasLimitRecord';
4
+ import { getTwChainId } from '@vultisig/core-chain/chains/evm/tx/tw/getTwChainId';
5
+ import { assertErrorMessage } from '@vultisig/lib-utils/error/assertErrorMessage';
6
+ import { getCoinType } from '@vultisig/core-chain/coin/coinType';
7
+ import { parseCosmosSerialized } from '@vultisig/core-chain/chains/cosmos/utils/parseCosmosSerialized';
8
+ import { TW } from '@trustwallet/wallet-core';
9
+ import Long from 'long';
10
+ /**
11
+ * Builds the base64 `tx_bytes` (protobuf `TxRaw`) for a native bank send,
12
+ * carrying a 64-byte dummy signature. `/cosmos/tx/v1beta1/simulate` decodes
13
+ * this and runs it against current state while skipping signature
14
+ * verification, so the bogus signature is accepted. Models only a native
15
+ * `MsgSend` — callers must restrict simulation to native sends.
16
+ *
17
+ * Mirrors iOS `CosmosGasEstimator.buildSimulateTxBytes`.
18
+ */
19
+ export const buildSimulateTxBytes = ({ walletCore, chain, hexPublicKey, fromAddress, toAddress, amount, denom, memo, accountNumber, sequence, }) => {
20
+ const coinType = getCoinType({ walletCore, chain });
21
+ const publicKeyData = new Uint8Array(Buffer.from(hexPublicKey, 'hex'));
22
+ const input = TW.Cosmos.Proto.SigningInput.create({
23
+ publicKey: publicKeyData,
24
+ signingMode: TW.Cosmos.Proto.SigningMode.Protobuf,
25
+ chainId: getTwChainId({ walletCore, chain }),
26
+ accountNumber: Long.fromString(accountNumber.toString()),
27
+ sequence: Long.fromString(sequence.toString()),
28
+ mode: TW.Cosmos.Proto.BroadcastMode.SYNC,
29
+ // A non-empty memo grows the tx body, which the node charges gas for.
30
+ // Include it so the simulated gas matches the real send.
31
+ ...(memo ? { memo } : {}),
32
+ // Simulate ignores the fee, but the tx must still be well-formed.
33
+ fee: TW.Cosmos.Proto.Fee.create({
34
+ gas: Long.fromBigInt(getCosmosGasLimit({ chain })),
35
+ amounts: [TW.Cosmos.Proto.Amount.create({ denom: cosmosFeeCoinDenom[chain], amount: '1' })],
36
+ }),
37
+ messages: [
38
+ TW.Cosmos.Proto.Message.create({
39
+ sendCoinsMessage: TW.Cosmos.Proto.Message.Send.create({
40
+ fromAddress,
41
+ toAddress,
42
+ amounts: [TW.Cosmos.Proto.Amount.create({ denom, amount })],
43
+ }),
44
+ }),
45
+ ],
46
+ });
47
+ const inputData = TW.Cosmos.Proto.SigningInput.encode(input).finish();
48
+ const preOutput = TW.TxCompiler.Proto.PreSigningOutput.decode(walletCore.TransactionCompiler.preImageHashes(coinType, inputData));
49
+ assertErrorMessage(preOutput.errorMessage);
50
+ // The node skips sig verification in simulate mode, so a fixed 64-byte dummy
51
+ // compact signature is enough to assemble a decodable TxRaw.
52
+ const signatures = walletCore.DataVector.create();
53
+ signatures.add(new Uint8Array(64).fill(1));
54
+ const publicKeys = walletCore.DataVector.create();
55
+ publicKeys.add(publicKeyData);
56
+ const compiled = walletCore.TransactionCompiler.compileWithSignatures(coinType, inputData, signatures, publicKeys);
57
+ const output = TW.Cosmos.Proto.SigningOutput.decode(compiled);
58
+ // WalletCore may set a non-fatal errorMessage for the dummy signature while
59
+ // still emitting usable tx_bytes (the real signing path tolerates this too),
60
+ // so treat a missing/empty tx_bytes — surfaced by the parser — as the real
61
+ // failure signal rather than errorMessage.
62
+ return parseCosmosSerialized(output.serialized).tx_bytes;
63
+ };
64
+ //# sourceMappingURL=buildSimulateTxBytes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buildSimulateTxBytes.js","sourceRoot":"","sources":["../../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/gasEstimation/buildSimulateTxBytes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { WalletCore } from '@trustwallet/wallet-core';
2
+ import { KeysignPayload } from '@vultisig/core-mpc/types/vultisig/keysign/v1/keysign_message_pb';
3
+ type EstimateCosmosGasLimitInput = {
4
+ walletCore: WalletCore;
5
+ keysignPayload: KeysignPayload;
6
+ accountNumber: bigint;
7
+ sequence: bigint;
8
+ };
9
+ /**
10
+ * Initiator-side dynamic gas estimation for a native Cosmos bank send.
11
+ *
12
+ * Simulates the send via `/cosmos/tx/v1beta1/simulate` and returns the padded
13
+ * (`× 1.3`) gas limit the initiator relays to co-signers in
14
+ * `CosmosSpecific.gas_limit`. Returns `undefined` on ANY failure — network
15
+ * error, malformed tx, or zero `gas_used` — so the caller falls back to the
16
+ * static per-chain gas limit and simulation never blocks signing.
17
+ *
18
+ * Mirrors iOS `CosmosGasEstimator.estimateGasLimit`. The caller
19
+ * (`getCosmosChainSpecific`) is responsible for restricting this to native
20
+ * sends; a `MsgSend` is the only shape modeled here.
21
+ */
22
+ export declare const estimateCosmosGasLimit: ({ walletCore, keysignPayload, accountNumber, sequence, }: EstimateCosmosGasLimitInput) => Promise<bigint | undefined>;
23
+ export {};
24
+ //# sourceMappingURL=estimateCosmosGasLimit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimateCosmosGasLimit.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/gasEstimation/estimateCosmosGasLimit.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAIrD,OAAO,EAAE,cAAc,EAAE,MAAM,iEAAiE,CAAA;AAOhG,KAAK,2BAA2B,GAAG;IACjC,UAAU,EAAE,UAAU,CAAA;IACtB,cAAc,EAAE,cAAc,CAAA;IAC9B,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,sBAAsB,GAAU,0DAK1C,2BAA2B,KAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAyB1D,CAAA"}
@@ -0,0 +1,43 @@
1
+ import { cosmosFeeCoinDenom } from '@vultisig/core-chain/chains/cosmos/cosmosFeeCoinDenom';
2
+ import { attempt } from '@vultisig/lib-utils/attempt';
3
+ import { shouldBePresent } from '@vultisig/lib-utils/assert/shouldBePresent';
4
+ import { getKeysignCoin } from '../../../../utils/getKeysignCoin.js';
5
+ import { buildSimulateTxBytes } from './buildSimulateTxBytes.js';
6
+ import { scaleCosmosGasLimit } from './scaleCosmosGasLimit.js';
7
+ import { simulateCosmosGas } from './simulateCosmosGas.js';
8
+ /**
9
+ * Initiator-side dynamic gas estimation for a native Cosmos bank send.
10
+ *
11
+ * Simulates the send via `/cosmos/tx/v1beta1/simulate` and returns the padded
12
+ * (`× 1.3`) gas limit the initiator relays to co-signers in
13
+ * `CosmosSpecific.gas_limit`. Returns `undefined` on ANY failure — network
14
+ * error, malformed tx, or zero `gas_used` — so the caller falls back to the
15
+ * static per-chain gas limit and simulation never blocks signing.
16
+ *
17
+ * Mirrors iOS `CosmosGasEstimator.estimateGasLimit`. The caller
18
+ * (`getCosmosChainSpecific`) is responsible for restricting this to native
19
+ * sends; a `MsgSend` is the only shape modeled here.
20
+ */
21
+ export const estimateCosmosGasLimit = async ({ walletCore, keysignPayload, accountNumber, sequence, }) => {
22
+ const coin = getKeysignCoin(keysignPayload);
23
+ const { chain } = coin;
24
+ const { hexPublicKey } = shouldBePresent(keysignPayload.coin);
25
+ const result = await attempt(async () => {
26
+ const txBytes = buildSimulateTxBytes({
27
+ walletCore,
28
+ chain,
29
+ hexPublicKey,
30
+ fromAddress: coin.address,
31
+ toAddress: keysignPayload.toAddress,
32
+ amount: keysignPayload.toAmount,
33
+ denom: cosmosFeeCoinDenom[chain],
34
+ memo: keysignPayload.memo,
35
+ accountNumber,
36
+ sequence,
37
+ });
38
+ const gasUsed = await simulateCosmosGas({ chain, txBytes });
39
+ return scaleCosmosGasLimit(gasUsed);
40
+ });
41
+ return 'data' in result ? result.data : undefined;
42
+ };
43
+ //# sourceMappingURL=estimateCosmosGasLimit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimateCosmosGasLimit.js","sourceRoot":"","sources":["../../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/gasEstimation/estimateCosmosGasLimit.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uDAAuD,CAAA;AAE1F,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAA;AAI5E,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAA;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAA;AASvD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,KAAK,EAAE,EAC3C,UAAU,EACV,cAAc,EACd,aAAa,EACb,QAAQ,GACoB,EAA+B,EAAE;IAC7D,MAAM,IAAI,GAAG,cAAc,CAAc,cAAc,CAAC,CAAA;IACxD,MAAM,EAAE,KAAK,EAAE,GAAG,IAAI,CAAA;IACtB,MAAM,EAAE,YAAY,EAAE,GAAG,eAAe,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;IAE7D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,KAAK,IAAI,EAAE;QACtC,MAAM,OAAO,GAAG,oBAAoB,CAAC;YACnC,UAAU;YACV,KAAK;YACL,YAAY;YACZ,WAAW,EAAE,IAAI,CAAC,OAAO;YACzB,SAAS,EAAE,cAAc,CAAC,SAAS;YACnC,MAAM,EAAE,cAAc,CAAC,QAAQ;YAC/B,KAAK,EAAE,kBAAkB,CAAC,KAAK,CAAC;YAChC,IAAI,EAAE,cAAc,CAAC,IAAI;YACzB,aAAa;YACb,QAAQ;SACT,CAAC,CAAA;QAEF,MAAM,OAAO,GAAG,MAAM,iBAAiB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAA;QAE3D,OAAO,mBAAmB,CAAC,OAAO,CAAC,CAAA;IACrC,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAA;AACnD,CAAC,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Safety multiplier applied to the node's reported `gas_used`, expressed as a
3
+ * rational `numerator/denominator` so the scaling stays exact integer math (the
4
+ * gas limit is part of the SignDoc, so a float here would risk cross-device
5
+ * divergence). `13/10` = 1.3×, matching the cosmjs default multiplier and iOS
6
+ * (`CosmosGasEstimator.safetyMultiplier`). The node's `gas_used` is a tight
7
+ * lower bound; padding keeps the tx from running out of gas on-chain due to
8
+ * execution nondeterminism.
9
+ */
10
+ export declare const cosmosGasSafetyMultiplier: {
11
+ readonly numerator: 13n;
12
+ readonly denominator: 10n;
13
+ };
14
+ /**
15
+ * `ceil(gasUsed × 1.3)` in exact integer arithmetic.
16
+ *
17
+ * Ceiling (not floor/round) so the padded limit never lands below `gas_used`,
18
+ * and so it matches iOS's `NSDecimalRound(.up)` byte-for-byte.
19
+ */
20
+ export declare const scaleCosmosGasLimit: (gasUsed: bigint) => bigint;
21
+ //# sourceMappingURL=scaleCosmosGasLimit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaleCosmosGasLimit.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/gasEstimation/scaleCosmosGasLimit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,eAAO,MAAM,yBAAyB;;;CAAgD,CAAA;AAEtF;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,GAAI,SAAS,MAAM,KAAG,MAGrD,CAAA"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Safety multiplier applied to the node's reported `gas_used`, expressed as a
3
+ * rational `numerator/denominator` so the scaling stays exact integer math (the
4
+ * gas limit is part of the SignDoc, so a float here would risk cross-device
5
+ * divergence). `13/10` = 1.3×, matching the cosmjs default multiplier and iOS
6
+ * (`CosmosGasEstimator.safetyMultiplier`). The node's `gas_used` is a tight
7
+ * lower bound; padding keeps the tx from running out of gas on-chain due to
8
+ * execution nondeterminism.
9
+ */
10
+ export const cosmosGasSafetyMultiplier = { numerator: 13n, denominator: 10n };
11
+ /**
12
+ * `ceil(gasUsed × 1.3)` in exact integer arithmetic.
13
+ *
14
+ * Ceiling (not floor/round) so the padded limit never lands below `gas_used`,
15
+ * and so it matches iOS's `NSDecimalRound(.up)` byte-for-byte.
16
+ */
17
+ export const scaleCosmosGasLimit = (gasUsed) => {
18
+ const { numerator, denominator } = cosmosGasSafetyMultiplier;
19
+ return (gasUsed * numerator + denominator - 1n) / denominator;
20
+ };
21
+ //# sourceMappingURL=scaleCosmosGasLimit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaleCosmosGasLimit.js","sourceRoot":"","sources":["../../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/gasEstimation/scaleCosmosGasLimit.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,EAAW,CAAA;AAEtF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,OAAe,EAAU,EAAE;IAC7D,MAAM,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,yBAAyB,CAAA;IAC5D,OAAO,CAAC,OAAO,GAAG,SAAS,GAAG,WAAW,GAAG,EAAE,CAAC,GAAG,WAAW,CAAA;AAC/D,CAAC,CAAA"}
@@ -0,0 +1,16 @@
1
+ import { CosmosChain } from '@vultisig/core-chain/Chain';
2
+ type SimulateCosmosGasInput = {
3
+ chain: CosmosChain;
4
+ /** base64-encoded protobuf `TxRaw` carrying a dummy signature */
5
+ txBytes: string;
6
+ };
7
+ /**
8
+ * Calls the LCD `/cosmos/tx/v1beta1/simulate` endpoint and returns the node's
9
+ * reported `gas_used`. The endpoint decodes the tx and runs it against current
10
+ * state WITHOUT verifying the signature, so the dummy signature in `txBytes` is
11
+ * accepted. Throws on a network/parse failure or a non-positive `gas_used` so
12
+ * the caller can fail closed to the static per-chain gas limit.
13
+ */
14
+ export declare const simulateCosmosGas: ({ chain, txBytes }: SimulateCosmosGasInput) => Promise<bigint>;
15
+ export {};
16
+ //# sourceMappingURL=simulateCosmosGas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulateCosmosGas.d.ts","sourceRoot":"","sources":["../../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/gasEstimation/simulateCosmosGas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAA;AAIxD,KAAK,sBAAsB,GAAG;IAC5B,KAAK,EAAE,WAAW,CAAA;IAClB,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AASD;;;;;;GAMG;AACH,eAAO,MAAM,iBAAiB,GAAU,oBAAoB,sBAAsB,KAAG,OAAO,CAAC,MAAM,CAelG,CAAA"}
@@ -0,0 +1,23 @@
1
+ import { getCosmosRpcUrl } from '@vultisig/core-chain/chains/cosmos/getCosmosRpcUrl';
2
+ import { queryUrl } from '@vultisig/lib-utils/query/queryUrl';
3
+ /**
4
+ * Calls the LCD `/cosmos/tx/v1beta1/simulate` endpoint and returns the node's
5
+ * reported `gas_used`. The endpoint decodes the tx and runs it against current
6
+ * state WITHOUT verifying the signature, so the dummy signature in `txBytes` is
7
+ * accepted. Throws on a network/parse failure or a non-positive `gas_used` so
8
+ * the caller can fail closed to the static per-chain gas limit.
9
+ */
10
+ export const simulateCosmosGas = async ({ chain, txBytes }) => {
11
+ const url = `${getCosmosRpcUrl(chain)}/cosmos/tx/v1beta1/simulate`;
12
+ const response = await queryUrl(url, {
13
+ method: 'POST',
14
+ headers: { 'Content-Type': 'application/json' },
15
+ body: { tx_bytes: txBytes },
16
+ });
17
+ const gasUsed = BigInt(response.gas_info?.gas_used ?? '0');
18
+ if (gasUsed <= 0n) {
19
+ throw new Error(`Cosmos simulate returned non-positive gas_used on ${chain}`);
20
+ }
21
+ return gasUsed;
22
+ };
23
+ //# sourceMappingURL=simulateCosmosGas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"simulateCosmosGas.js","sourceRoot":"","sources":["../../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/gasEstimation/simulateCosmosGas.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,oDAAoD,CAAA;AACpF,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAe7D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,EAAE,EAAE,KAAK,EAAE,OAAO,EAA0B,EAAmB,EAAE;IACrG,MAAM,GAAG,GAAG,GAAG,eAAe,CAAC,KAAK,CAAC,6BAA6B,CAAA;IAElE,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAmB,GAAG,EAAE;QACrD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;KAC5B,CAAC,CAAA;IAEF,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,IAAI,GAAG,CAAC,CAAA;IAC1D,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CAAC,qDAAqD,KAAK,EAAE,CAAC,CAAA;IAC/E,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import { GetChainSpecificResolver } from '../../resolver.js';
2
+ export declare const getCosmosChainSpecific: GetChainSpecificResolver<'cosmosSpecific'>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/index.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAwBzD,eAAO,MAAM,sBAAsB,EAAE,wBAAwB,CAAC,gBAAgB,CAwE7E,CAAA"}
@@ -3,8 +3,10 @@ import { Chain } from '@vultisig/core-chain/Chain';
3
3
  import { getCosmosAccountInfo } from '@vultisig/core-chain/chains/cosmos/account/getCosmosAccountInfo';
4
4
  import { getCosmosFeeAmount } from '@vultisig/core-chain/chains/cosmos/gas';
5
5
  import { applyTerraClassicTax, getTerraClassicTaxCap, getTerraClassicTaxRate, } from '@vultisig/core-chain/chains/cosmos/terraClassicTax';
6
+ import { isFeeCoin } from '@vultisig/core-chain/coin/utils/isFeeCoin';
6
7
  import { CosmosSpecificSchema, TransactionType, } from '@vultisig/core-mpc/types/vultisig/keysign/v1/blockchain_specific_pb';
7
- import { getKeysignCoin } from '../../utils/getKeysignCoin.js';
8
+ import { getKeysignCoin } from '../../../utils/getKeysignCoin.js';
9
+ import { estimateCosmosGasLimit } from './gasEstimation/estimateCosmosGasLimit.js';
8
10
  /**
9
11
  * Computes the Terra Classic stability-tax surcharge for a USTC (uusd) send.
10
12
  *
@@ -25,7 +27,7 @@ async function computeUstcBurnTaxAmount(toAmount) {
25
27
  const tax = applyTerraClassicTax(BigInt(toAmount), 'uusd', rate, { uusd: cap });
26
28
  return tax.toString();
27
29
  }
28
- export const getCosmosChainSpecific = async ({ keysignPayload, transactionType = TransactionType.UNSPECIFIED, timeoutTimestamp, }) => {
30
+ export const getCosmosChainSpecific = async ({ keysignPayload, walletCore, transactionType = TransactionType.UNSPECIFIED, timeoutTimestamp, }) => {
29
31
  const coin = getKeysignCoin(keysignPayload);
30
32
  const { accountNumber, sequence, latestBlock } = await getCosmosAccountInfo(coin);
31
33
  // For TerraClassic USTC (uusd) sends, pre-compute the burn-tax surcharge
@@ -46,11 +48,41 @@ export const getCosmosChainSpecific = async ({ keysignPayload, transactionType =
46
48
  burnTaxBaseDenom = '0';
47
49
  }
48
50
  }
51
+ // Initiator-side dynamic gas: simulate a native send via
52
+ // `/cosmos/tx/v1beta1/simulate` and relay the padded gas limit to co-signers
53
+ // in `CosmosSpecific.gas_limit`. The signing-inputs resolver honors this
54
+ // value (and scales the fee amount accordingly) when it is present and > 0,
55
+ // otherwise every device falls back to the static per-chain gas limit. Only
56
+ // native bank sends are simulated — the simulate tx models a `MsgSend`, so
57
+ // token/IBC/contract/staking txs (non-UNSPECIFIED transactionType, or a
58
+ // relayed dapp signData) keep the static limit. Fails closed: any simulation
59
+ // error returns undefined and the field stays unset.
60
+ // Optional chaining is deliberate: this gate runs at initiator build time on
61
+ // payloads that can be shaped by external callers (dapp / inpage-provider),
62
+ // and it sits outside the fail-closed estimator below — a payload missing the
63
+ // `signData` oneof wrapper must be treated as "no relayed sign data" rather
64
+ // than throw here.
65
+ const hasRelayedSignData = keysignPayload.signData?.case !== undefined;
66
+ const isNativeSend = transactionType === TransactionType.UNSPECIFIED &&
67
+ !hasRelayedSignData &&
68
+ isFeeCoin(coin) &&
69
+ !!keysignPayload.toAddress &&
70
+ /^[0-9]+$/.test(keysignPayload.toAmount) &&
71
+ BigInt(keysignPayload.toAmount) > 0n;
72
+ const gasLimit = isNativeSend
73
+ ? await estimateCosmosGasLimit({
74
+ walletCore,
75
+ keysignPayload,
76
+ accountNumber: BigInt(accountNumber),
77
+ sequence: BigInt(sequence),
78
+ })
79
+ : undefined;
49
80
  return create(CosmosSpecificSchema, {
50
81
  accountNumber: BigInt(accountNumber),
51
82
  sequence: BigInt(sequence),
52
83
  transactionType,
53
84
  gas: await getCosmosFeeAmount(coin),
85
+ gasLimit,
54
86
  ibcDenomTraces: {
55
87
  latestBlock: timeoutTimestamp ? `${latestBlock.split('_')[0]}_${timeoutTimestamp}` : latestBlock,
56
88
  baseDenom: burnTaxBaseDenom,
@@ -58,4 +90,4 @@ export const getCosmosChainSpecific = async ({ keysignPayload, transactionType =
58
90
  },
59
91
  });
60
92
  };
61
- //# sourceMappingURL=cosmos.js.map
93
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/cosmos/index.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ripple.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAKtD,eAAO,MAAM,sBAAsB,EAAE,wBAAwB,CAAC,gBAAgB,CAgC7E,CAAA"}
1
+ {"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ripple.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAKtD,eAAO,MAAM,sBAAsB,EAAE,wBAAwB,CAAC,gBAAgB,CA+C7E,CAAA"}
@@ -21,17 +21,29 @@ export const getRippleChainSpecific = async ({ keysignPayload }) => {
21
21
  const { base_fee, reserve_base } = shouldBePresent(validated_ledger);
22
22
  const computedFee = ((BigInt(base_fee) * BigInt(load_factor)) / BigInt(load_base)) * baseFeeMultiplier;
23
23
  const networkFee = maxBigInt(computedFee, minProtocolFee);
24
- const getAccountActivationFee = () => {
25
- if ('error' in destinationAccountResult && isInError(destinationAccountResult.error, 'Account not found')) {
26
- return BigInt(reserve_base);
24
+ // XRPL base reserve is a requirement on the Payment AMOUNT (the drops that
25
+ // fund/activate the destination account), NOT on the Fee. The Fee is BURNED
26
+ // by the network — it never reaches the recipient. The previous code added
27
+ // reserve_base to `gas` (which becomes TW.Ripple SigningInput.fee), so every
28
+ // send to a not-yet-activated XRP address burned ~1 XRP (the reserve) for
29
+ // nothing, on top of the actual send amount. Reserve spec:
30
+ // https://xrpl.org/docs/concepts/accounts/reserves
31
+ const destinationUnfunded = 'error' in destinationAccountResult && isInError(destinationAccountResult.error, 'Account not found');
32
+ if (destinationUnfunded) {
33
+ const toAmount = BigInt(shouldBePresent(keysignPayload.toAmount));
34
+ if (toAmount < BigInt(reserve_base)) {
35
+ throw new Error(`Cannot send to XRP account ${toAddress}: it is not yet activated, and XRPL requires the ` +
36
+ `Payment amount to be at least the base reserve (${reserve_base} drops) to create a new ` +
37
+ `account. The send amount is ${toAmount.toString()} drops. Increase the amount to at least ` +
38
+ `the reserve, or send to an already-activated account.`);
27
39
  }
28
- return 0n;
29
- };
40
+ }
30
41
  const { account_data, ledger_current_index } = senderAccount;
31
42
  return create(RippleSpecificSchema, {
32
43
  sequence: BigInt(account_data.Sequence),
33
44
  lastLedgerSequence: BigInt((ledger_current_index ?? 0) + 60),
34
- gas: networkFee + getAccountActivationFee(),
45
+ // Fee is the network fee only — the reserve rides on the Payment amount.
46
+ gas: networkFee,
35
47
  });
36
48
  };
37
49
  //# sourceMappingURL=ripple.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ripple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAA;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAA;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qEAAqE,CAAA;AAC1G,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAG3D,MAAM,cAAc,GAAG,GAAG,CAAA;AAC1B,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAE5B,MAAM,CAAC,MAAM,sBAAsB,GAA+C,KAAK,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE;IAC7G,MAAM,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,cAAc,CAAC,CAAA;IAClD,MAAM,SAAS,GAAG,eAAe,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;IAE3D,MAAM,CAAC,aAAa,EAAE,WAAW,EAAE,wBAAwB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC/E,oBAAoB,CAAC,OAAO,CAAC;QAC7B,oBAAoB,EAAE;QACtB,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;KACzC,CAAC,CAAA;IAEF,MAAM,EAAE,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,WAAW,CAAA;IAChE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAA;IAEpE,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,iBAAiB,CAAA;IAEtG,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;IAEzD,MAAM,uBAAuB,GAAG,GAAG,EAAE;QACnC,IAAI,OAAO,IAAI,wBAAwB,IAAI,SAAS,CAAC,wBAAwB,CAAC,KAAK,EAAE,mBAAmB,CAAC,EAAE,CAAC;YAC1G,OAAO,MAAM,CAAC,YAAY,CAAC,CAAA;QAC7B,CAAC;QAED,OAAO,EAAE,CAAA;IACX,CAAC,CAAA;IAED,MAAM,EAAE,YAAY,EAAE,oBAAoB,EAAE,GAAG,aAAa,CAAA;IAE5D,OAAO,MAAM,CAAC,oBAAoB,EAAE;QAClC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;QACvC,kBAAkB,EAAE,MAAM,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QAC5D,GAAG,EAAE,UAAU,GAAG,uBAAuB,EAAE;KAC5C,CAAC,CAAA;AACJ,CAAC,CAAA"}
1
+ {"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ripple.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAA;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,iDAAiD,CAAA;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qEAAqE,CAAA;AAC1G,OAAO,EAAE,eAAe,EAAE,MAAM,4CAA4C,CAAA;AAC5E,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AACrD,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAA;AAC/D,OAAO,EAAE,SAAS,EAAE,MAAM,oCAAoC,CAAA;AAE9D,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAG3D,MAAM,cAAc,GAAG,GAAG,CAAA;AAC1B,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAE5B,MAAM,CAAC,MAAM,sBAAsB,GAA+C,KAAK,EAAE,EAAE,cAAc,EAAE,EAAE,EAAE;IAC7G,MAAM,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,cAAc,CAAC,CAAA;IAClD,MAAM,SAAS,GAAG,eAAe,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;IAE3D,MAAM,CAAC,aAAa,EAAE,WAAW,EAAE,wBAAwB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC/E,oBAAoB,CAAC,OAAO,CAAC;QAC7B,oBAAoB,EAAE;QACtB,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;KACzC,CAAC,CAAA;IAEF,MAAM,EAAE,gBAAgB,EAAE,WAAW,EAAE,SAAS,EAAE,GAAG,WAAW,CAAA;IAChE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,eAAe,CAAC,gBAAgB,CAAC,CAAA;IAEpE,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,iBAAiB,CAAA;IAEtG,MAAM,UAAU,GAAG,SAAS,CAAC,WAAW,EAAE,cAAc,CAAC,CAAA;IAEzD,2EAA2E;IAC3E,4EAA4E;IAC5E,2EAA2E;IAC3E,6EAA6E;IAC7E,0EAA0E;IAC1E,2DAA2D;IAC3D,mDAAmD;IACnD,MAAM,mBAAmB,GACvB,OAAO,IAAI,wBAAwB,IAAI,SAAS,CAAC,wBAAwB,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAA;IAEvG,IAAI,mBAAmB,EAAE,CAAC;QACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC,CAAA;QACjE,IAAI,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CACb,8BAA8B,SAAS,mDAAmD;gBACxF,mDAAmD,YAAY,0BAA0B;gBACzF,+BAA+B,QAAQ,CAAC,QAAQ,EAAE,0CAA0C;gBAC5F,uDAAuD,CAC1D,CAAA;QACH,CAAC;IACH,CAAC;IAED,MAAM,EAAE,YAAY,EAAE,oBAAoB,EAAE,GAAG,aAAa,CAAA;IAE5D,OAAO,MAAM,CAAC,oBAAoB,EAAE;QAClC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;QACvC,kBAAkB,EAAE,MAAM,CAAC,CAAC,oBAAoB,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QAC5D,yEAAyE;QACzE,GAAG,EAAE,UAAU;KAChB,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/sui/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAGzD,eAAO,MAAM,mBAAmB,EAAE,wBAAwB,CAAC,gBAAgB,CAwC1E,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/sui/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAGzD,eAAO,MAAM,mBAAmB,EAAE,wBAAwB,CAAC,gBAAgB,CAkE1E,CAAA"}
@@ -16,10 +16,34 @@ export const getSuiChainSpecific = async ({ keysignPayload, walletCore, }) => {
16
16
  const coin = getKeysignCoin(keysignPayload);
17
17
  const { address } = coin;
18
18
  const client = getSuiClient();
19
- const { data } = await client.getAllCoins({
20
- owner: address,
21
- });
22
- const coins = data.map((coin) => create(SuiCoinSchema, coin));
19
+ // `getAllCoins` is paginated (~50 objects/page). Sui's object-per-coin model
20
+ // makes >50 coin objects realistic for an active wallet (dust, partial fills,
21
+ // repeated small transfers, staking rewards), so reading only the first page
22
+ // silently truncates the coin set. That set feeds both `gasCoins` (native SUI
23
+ // objects for the Pay/PaySui gas payment) and `inputCoins` (the coinType being
24
+ // sent) downstream, so a truncated page produces a broken send ("insufficient
25
+ // balance" despite adequate holdings, or an empty inputCoins array if none of
26
+ // the sent coinType's objects land on page 1) even though the getBalance-based
27
+ // display path shows the correct aggregate total. Follow the cursor to
28
+ // completion, mirroring the Solana SPL pagination fix (sdk#962).
29
+ // Bound the cursor loop: a buggy/misbehaving RPC that keeps returning
30
+ // hasNextPage=true with a non-advancing cursor would otherwise spin forever.
31
+ // 200 pages ≈ 10k coin objects — far beyond any real wallet — so hitting the
32
+ // cap means the cursor is stuck; fail CLOSED (throw) rather than hang or
33
+ // silently truncate the coin set and under-fund the send.
34
+ const MAX_COIN_PAGES = 200;
35
+ const rawCoins = [];
36
+ let cursor = undefined;
37
+ let pages = 0;
38
+ do {
39
+ const page = await client.getAllCoins({ owner: address, cursor });
40
+ rawCoins.push(...page.data);
41
+ cursor = page.hasNextPage ? page.nextCursor : null;
42
+ if (++pages >= MAX_COIN_PAGES && cursor) {
43
+ throw new Error(`getSuiChainSpecific: getAllCoins exceeded ${MAX_COIN_PAGES} pages for ${address} — refusing to build a send from a possibly-truncated or looping coin set`);
44
+ }
45
+ } while (cursor);
46
+ const coins = rawCoins.map((coin) => create(SuiCoinSchema, coin));
23
47
  const referenceGasPrice = await client.getReferenceGasPrice();
24
48
  const chainSpecific = create(SuiSpecificSchema, {
25
49
  coins,
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/sui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qEAAqE,CAAA;AACtH,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAGnE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAE9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAA+C,KAAK,EAAE,EACpF,cAAc,EACd,UAAU,GACX,EAAE,EAAE;IACH,0EAA0E;IAC1E,uEAAuE;IACvE,4EAA4E;IAC5E,uEAAuE;IACvE,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAA;IACtC,CAAC;IAED,MAAM,IAAI,GAAG,cAAc,CAAC,cAAc,CAAC,CAAA;IAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IACxB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAA;IAE7B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;QACxC,KAAK,EAAE,OAAO;KACf,CAAC,CAAA;IAEF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,IAAgB,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAA;IAEzE,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC,oBAAoB,EAAE,CAAA;IAE7D,MAAM,aAAa,GAAG,MAAM,CAAC,iBAAiB,EAAE;QAC9C,KAAK;QACL,iBAAiB,EAAE,iBAAiB,CAAC,QAAQ,EAAE;QAC/C,SAAS,EAAE,YAAY,CAAC,QAAQ,EAAE;KACnC,CAAC,CAAA;IAEF,OAAO,YAAY,CACjB,OAAO,CACL,sBAAsB,CAAC;QACrB,cAAc;QACd,aAAa;QACb,UAAU;KACX,CAAC,CACH,EACD,aAAa,CACd,CAAA;AACH,CAAC,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/sui/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AACrE,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,qEAAqE,CAAA;AACtH,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAGnE,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAE9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,UAAU,CAAA;AAEjD,MAAM,CAAC,MAAM,mBAAmB,GAA+C,KAAK,EAAE,EACpF,cAAc,EACd,UAAU,GACX,EAAE,EAAE;IACH,0EAA0E;IAC1E,uEAAuE;IACvE,4EAA4E;IAC5E,uEAAuE;IACvE,IAAI,cAAc,CAAC,QAAQ,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/C,OAAO,MAAM,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAA;IACtC,CAAC;IAED,MAAM,IAAI,GAAG,cAAc,CAAC,cAAc,CAAC,CAAA;IAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IACxB,MAAM,MAAM,GAAG,YAAY,EAAE,CAAA;IAE7B,6EAA6E;IAC7E,8EAA8E;IAC9E,6EAA6E;IAC7E,8EAA8E;IAC9E,+EAA+E;IAC/E,8EAA8E;IAC9E,8EAA8E;IAC9E,+EAA+E;IAC/E,uEAAuE;IACvE,iEAAiE;IACjE,sEAAsE;IACtE,6EAA6E;IAC7E,6EAA6E;IAC7E,yEAAyE;IACzE,0DAA0D;IAC1D,MAAM,cAAc,GAAG,GAAG,CAAA;IAC1B,MAAM,QAAQ,GAAiB,EAAE,CAAA;IACjC,IAAI,MAAM,GAA8B,SAAS,CAAA;IACjD,IAAI,KAAK,GAAG,CAAC,CAAA;IACb,GAAG,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAA;QACjE,QAAQ,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,CAAA;QAC3B,MAAM,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAA;QAClD,IAAI,EAAE,KAAK,IAAI,cAAc,IAAI,MAAM,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CACb,6CAA6C,cAAc,cAAc,OAAO,2EAA2E,CAC5J,CAAA;QACH,CAAC;IACH,CAAC,QAAQ,MAAM,EAAC;IAEhB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAgB,EAAE,EAAE,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC,CAAA;IAE7E,MAAM,iBAAiB,GAAG,MAAM,MAAM,CAAC,oBAAoB,EAAE,CAAA;IAE7D,MAAM,aAAa,GAAG,MAAM,CAAC,iBAAiB,EAAE;QAC9C,KAAK;QACL,iBAAiB,EAAE,iBAAiB,CAAC,QAAQ,EAAE;QAC/C,SAAS,EAAE,YAAY,CAAC,QAAQ,EAAE;KACnC,CAAC,CAAA;IAEF,OAAO,YAAY,CACjB,OAAO,CACL,sBAAsB,CAAC;QACrB,cAAc;QACd,aAAa;QACb,UAAU;KACX,CAAC,CACH,EACD,aAAa,CACd,CAAA;AACH,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ton/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAIzD,eAAO,MAAM,mBAAmB,EAAE,wBAAwB,CAAC,aAAa,CA2DvE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ton/index.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAIzD,eAAO,MAAM,mBAAmB,EAAE,wBAAwB,CAAC,aAAa,CAoEvE,CAAA"}
@@ -12,8 +12,17 @@ export const getTonChainSpecific = async ({ keysignPayload }) => {
12
12
  const coin = getKeysignCoin(keysignPayload);
13
13
  const { address } = coin;
14
14
  const receiver = keysignPayload.toAddress;
15
+ // Read seqno defensively. A TON wallet that has RECEIVED funds but never SENT
16
+ // is still UNINITIALIZED (its contract deploys on the first outgoing tx via
17
+ // StateInit); getExtendedAddressInformation returns an `uninited.accountState`
18
+ // result with NO `seqno` field, so `account_state.seqno` on the raw result is
19
+ // undefined — optional-chain to seqno 0 (the signing path then correctly
20
+ // attaches StateInit for seqno === 0), matching the abts side's
21
+ // `?.account_state?.seqno ?? 0`. A genuine RPC failure (`{ ok:false }`) is now
22
+ // caught inside `getTonAccountInfo`, which throws a descriptive error rather
23
+ // than returning null and crashing this destructure.
15
24
  const { account_state } = await getTonAccountInfo(address);
16
- const sequenceNumber = BigInt(account_state.seqno || 0);
25
+ const sequenceNumber = BigInt(account_state?.seqno ?? 0);
17
26
  const getSendMaxAmount = async () => {
18
27
  if (coin.id)
19
28
  return false;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ton/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ton/index.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,10 @@ import { FeeAmountResolver } from '../resolver.js';
5
5
  * via signAmino / signDirect) into `THORChainSpecific.fee` /
6
6
  * `CosmosSpecific.gas` at keysign-payload build time, so every consumer —
7
7
  * including this resolver — agrees on what the chain will charge.
8
+ *
9
+ * When a dynamic `CosmosSpecific.gas_limit` is relayed, the displayed fee is
10
+ * scaled by the same rule the signing-inputs resolver applies, so the Network
11
+ * Fee row matches what the chain actually charges.
8
12
  */
9
13
  export declare const getCosmosFeeAmount: FeeAmountResolver;
10
14
  //# sourceMappingURL=cosmos.d.ts.map