@vultisig/core-mpc 2.1.1 → 3.0.1

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 (47) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/dist/keysign/chainSpecific/KeysignChainSpecific.d.ts +0 -1
  3. package/dist/keysign/chainSpecific/KeysignChainSpecific.d.ts.map +1 -1
  4. package/dist/keysign/chainSpecific/KeysignChainSpecific.js +0 -1
  5. package/dist/keysign/chainSpecific/KeysignChainSpecific.js.map +1 -1
  6. package/dist/keysign/chainSpecific/resolver.d.ts +10 -0
  7. package/dist/keysign/chainSpecific/resolver.d.ts.map +1 -1
  8. package/dist/keysign/chainSpecific/resolvers/ripple.d.ts +11 -0
  9. package/dist/keysign/chainSpecific/resolvers/ripple.d.ts.map +1 -1
  10. package/dist/keysign/chainSpecific/resolvers/ripple.js +110 -5
  11. package/dist/keysign/chainSpecific/resolvers/ripple.js.map +1 -1
  12. package/dist/keysign/chainSpecific/resolvers/ton/index.d.ts.map +1 -1
  13. package/dist/keysign/chainSpecific/resolvers/ton/index.js +79 -29
  14. package/dist/keysign/chainSpecific/resolvers/ton/index.js.map +1 -1
  15. package/dist/keysign/chainSpecific/resolvers/tron/index.d.ts +18 -0
  16. package/dist/keysign/chainSpecific/resolvers/tron/index.d.ts.map +1 -1
  17. package/dist/keysign/chainSpecific/resolvers/tron/index.js +66 -7
  18. package/dist/keysign/chainSpecific/resolvers/tron/index.js.map +1 -1
  19. package/dist/keysign/error.d.ts +1 -1
  20. package/dist/keysign/error.d.ts.map +1 -1
  21. package/dist/keysign/error.js.map +1 -1
  22. package/dist/keysign/send/build.d.ts +2 -1
  23. package/dist/keysign/send/build.d.ts.map +1 -1
  24. package/dist/keysign/send/build.js +55 -0
  25. package/dist/keysign/send/build.js.map +1 -1
  26. package/dist/keysign/signingInputs/resolvers/ripple.d.ts.map +1 -1
  27. package/dist/keysign/signingInputs/resolvers/ripple.js +55 -17
  28. package/dist/keysign/signingInputs/resolvers/ripple.js.map +1 -1
  29. package/dist/keysign/signingInputs/resolvers/ton/index.d.ts.map +1 -1
  30. package/dist/keysign/signingInputs/resolvers/ton/index.js +5 -1
  31. package/dist/keysign/signingInputs/resolvers/ton/index.js.map +1 -1
  32. package/dist/keysign/signingInputs/resolvers/ton/jetton.d.ts.map +1 -1
  33. package/dist/keysign/signingInputs/resolvers/ton/jetton.js +11 -3
  34. package/dist/keysign/signingInputs/resolvers/ton/jetton.js.map +1 -1
  35. package/dist/keysign/signingInputs/resolvers/ton/native.d.ts +0 -2
  36. package/dist/keysign/signingInputs/resolvers/ton/native.d.ts.map +1 -1
  37. package/dist/keysign/signingInputs/resolvers/ton/native.js +4 -17
  38. package/dist/keysign/signingInputs/resolvers/ton/native.js.map +1 -1
  39. package/dist/keysign/utils/isRippleTrustSet.d.ts +8 -23
  40. package/dist/keysign/utils/isRippleTrustSet.d.ts.map +1 -1
  41. package/dist/keysign/utils/isRippleTrustSet.js +15 -24
  42. package/dist/keysign/utils/isRippleTrustSet.js.map +1 -1
  43. package/dist/types/vultisig/keysign/v1/blockchain_specific_pb.d.ts +9 -1
  44. package/dist/types/vultisig/keysign/v1/blockchain_specific_pb.d.ts.map +1 -1
  45. package/dist/types/vultisig/keysign/v1/blockchain_specific_pb.js +9 -1
  46. package/dist/types/vultisig/keysign/v1/blockchain_specific_pb.js.map +1 -1
  47. package/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,75 @@
1
1
  # @vultisig/core-mpc
2
2
 
3
+ ## 3.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#2323](https://github.com/vultisig/vultisig-sdk/pull/2323) [`8a50970`](https://github.com/vultisig/vultisig-sdk/commit/8a50970438de64cdbeb281cf73925026e3ce3cf7) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Refuse XRPL issued-currency Payments the ledger would reject — a destination holding no trust line for the token, and an issuer that charges a transfer fee the payload cannot yet cover with a SendMax — instead of burning the fee on-chain. Accept the lowercase standard currency codes XRPL permits, report bad amounts and unusable destinations as domain errors, and pin both encoders against a shared issued-currency signing vector.
8
+
9
+ - [#2310](https://github.com/vultisig/vultisig-sdk/pull/2310) [`af6c643`](https://github.com/vultisig/vultisig-sdk/commit/af6c643e9afa39cb0b4432a01cec40e4de4d8ecc) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - fix(ton): let a dApp deadline tighten the signed expiry
10
+
11
+ `getTonChainSpecific` always signed `expireAt = now + 600`, so the `valid_until` a TonConnect `sendTransaction` carries never reached the wallet message: a request with a 60-second window was signed with a ten-minute one, and a broadcast landing after the dApp's window could execute on chain while the dApp already treated it as expired and retried.
12
+
13
+ `GetChainSpecificInput` now takes an optional `validUntil` (unix seconds) for `tonSpecific`. The signed `expireAt` is `min(now + 600, validUntil)` — the wallet's own window remains the ceiling — and a deadline already in the past fails the build instead of signing a transaction the network would reject. Callers that pass nothing keep the previous behaviour; co-signers read `expireAt` from the payload, so only what the initiator writes changes.
14
+
15
+ The expiry is computed last, after the seqno, bounceability and jetton-metadata lookups: each is a network round trip, so a deadline still ahead when the build starts can be behind by the time it finishes, and the wallet's own ten-minute window now starts when the payload is finished rather than being partly spent on those lookups.
16
+
17
+ - Updated dependencies [[`8a50970`](https://github.com/vultisig/vultisig-sdk/commit/8a50970438de64cdbeb281cf73925026e3ce3cf7), [`af6c643`](https://github.com/vultisig/vultisig-sdk/commit/af6c643e9afa39cb0b4432a01cec40e4de4d8ecc), [`20de22f`](https://github.com/vultisig/vultisig-sdk/commit/20de22f49c244ffc065011291754f89ef0d6e61a), [`34f0faa`](https://github.com/vultisig/vultisig-sdk/commit/34f0faa7208ad594b8d18a3a2806c0f7867f2c85)]:
18
+ - @vultisig/core-chain@5.1.0
19
+
20
+ ## 3.0.0
21
+
22
+ ### Major Changes
23
+
24
+ - [#2237](https://github.com/vultisig/vultisig-sdk/pull/2237) [`7d4c116`](https://github.com/vultisig/vultisig-sdk/commit/7d4c116cc7a940e96abf075790c4a387edd03987) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - Remove Kujira (KUJI) chain support. Kujira wound down in 2025 and every RPC/LCD endpoint the SDK shipped for it is now dead (the polkachu hosts no longer resolve; publicnode 404s), so balances, sends, swaps, staking and governance on Kujira cannot function.
25
+
26
+ `Chain.Kujira` / `CosmosChain.Kujira` are removed from the chain union, along with the Kujira entries in the chain registry, cosmos RPC/LCD/fee/gas/memo tables, SwapKit + Skip + native-swap routing, the Kujira token list, IBC chain-id mapping, governance config and address derivation.
27
+
28
+ The IBC tables in `tools/prep/ibcTransfer.ts` are keyed by raw chain-ID rather than the `Chain` enum, so they are cleared explicitly: `kaiyo-1` is dropped from `IBC_CHAIN_REVISION` and the `osmosis-1/channel-259` route from `IBC_CHANNEL_DEST`. `supportedIbcDestinationsFrom('osmosis-1')` no longer advertises `kaiyo-1`, and `resolveSourceChannelByDestChain('osmosis-1', 'kaiyo-1')` returns `null`.
29
+
30
+ `COSMOS_CHAIN_ID_HRP` keeps its `kaiyo-1` → `kujira` entry: it is a pure bech32-prefix lookup that makes nothing routable, and it is still needed to decode historic `kujira1…` addresses.
31
+
32
+ The `chains/cosmos/thor/kujira-merge` module is intentionally **kept**: it describes the six Kujira-origin tokens (KUJI, rKUJI, FUZN, NSTK, WINK, LVN) that migrated onto THORChain as `thor.*` secured assets, plus their IBC representations on Cosmos Hub and Osmosis. Those assets are unaffected and keep resolving.
33
+
34
+ Consumers holding a persisted `Chain.Kujira` value must drop it — the symbol no longer type-checks.
35
+
36
+ - [#2298](https://github.com/vultisig/vultisig-sdk/pull/2298) [`1716a79`](https://github.com/vultisig/vultisig-sdk/commit/1716a7946bf617ff16f8bb15f33b279efbb4a87d) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - fix(ton): one correct comment validator, run before the user signs
37
+
38
+ TON comment length was checked against a fixed 123 bytes wherever it was checked at all. That number is right for a native transfer, where the comment is the message body's own cell, and wrong for a jetton transfer, where the comment rides inline in the transfer body's `forward_payload` and shares one 1023-bit cell with the opcode, query id, amount, both addresses and the forward amount. The real jetton cap is roughly 34–39 bytes and SHRINKS as the amount grows, because `VarUInteger 16` widens a byte at a time. Anything above it reached WalletCore, which refuses to pack the cell and fails the keysign with a bare "Internal error" — after the user had reviewed and approved the transaction. Memos are load-bearing on TON; an exchange deposit without the right one loses the funds.
39
+
40
+ New `@vultisig/core-chain/chains/ton/comment` owns the rule for both shapes: `tonNativeCommentMaxBytes`, `getTonJettonCommentMaxBytes({ amount, isActiveDestination })`, `getTonCommentMaxBytes` for a send form that wants to count down against the real limit, and `validateTonComment`. The amount-dependent widths are measured by encoding them, not predicted, and a test drives real WalletCore at each cap and one byte past it to prove the two agree.
41
+
42
+ `buildSendKeysignPayload` now validates the memo at the end of the build, where the final signed amount and `isActiveDestination` are both known, and raises a non-retryable `BuildKeysignPayloadError('ton-memo-too-long')`. That moves the failure from keysign to the point where the payload is assembled — the verify screen — for every consumer, with no client-side change. The signing-input resolvers still validate, so a payload built by another device or an older client cannot get an unpackable comment signed here either.
43
+
44
+ **Breaking:** `validateTonComment` is no longer exported from `@vultisig/core-mpc/keysign/signingInputs/resolvers/ton/native`, and takes `{ memo, jetton? }` instead of a bare string. Import it from `@vultisig/core-chain/chains/ton/comment`. `validateTonMemo` in the SDK's TON surface keeps its signature and gains an optional second argument for jetton context.
45
+
46
+ ### Minor Changes
47
+
48
+ - [#2316](https://github.com/vultisig/vultisig-sdk/pull/2316) [`b19c5d5`](https://github.com/vultisig/vultisig-sdk/commit/b19c5d56f4d00d92493f8da74ff80d92b1d87c68) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Add exact XRP Ledger issued-currency Payments and authoritative delivered-amount receipts for XRP, issued currencies, and MPTs while preserving native XRP and explicit TrustSet behavior.
49
+
50
+ ### Patch Changes
51
+
52
+ - [#2282](https://github.com/vultisig/vultisig-sdk/pull/2282) [`a711b6c`](https://github.com/vultisig/vultisig-sdk/commit/a711b6ca8a8a7ae39d0efbb1c919b23b6538a1b8) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - fix(ton): derive each dApp message's bounce flag from its own destination
53
+
54
+ A dApp `signTon` batch stamped every message with the single wallet-level `TonSpecific.bounceable`, which the chain-specific resolver computes from the first message's destination alone. The bounce bit a message declares lives in its own address tag — `EQ…`/`kQ…` bounceable, `UQ…`/`0Q…` not, a raw `workchain:hex` address none — so a batch with mixed destinations, or a first destination that is not yet deployed, signed the wrong bit on some of its messages, and a co-signer deriving the flag per address computed a different hash for the same payload.
55
+
56
+ Each dApp message now takes the flag from its own destination (`getTonMessageBounceable` in `@vultisig/core-chain/chains/ton/messageBounce`); a raw `workchain:hex` address carries no tag, so it defaults to bounceable — an already-deployed contract must refund a rejection — unless the message carries `stateInit`, the deployment case whose destination has no code yet to bounce from. Every raw spelling WalletCore signs counts as the same account here: leading zeros, an explicit sign and a `0x`-prefixed hash all name one address and compile to one pre-image, so `00:<hash>` cannot be signed non-bounceable while `0:<hash>` is signed bounceable. App-initiated single sends are unchanged and keep the wallet-level flag and the nominator-pool override.
57
+
58
+ The bounce bit is part of the signed body, so TON signing hashes move for dApp batches whose destinations do not all share the first message's flag. Co-signers must apply the same per-message rule.
59
+
60
+ - [#2255](https://github.com/vultisig/vultisig-sdk/pull/2255) [`ef6a8bb`](https://github.com/vultisig/vultisig-sdk/commit/ef6a8bb0007c6576179e5a8cb10aa47820075b57) Thanks [@Ehsan-saradar](https://github.com/Ehsan-saradar)! - fix(ton): send swap deposits bounceable so a rejected deposit is refunded
61
+
62
+ TON transfers were marked bounceable only when the destination string started with `E`. Swap providers hand back deposit addresses in the `UQ…` (non-bounceable) form, so every TON swap deposit went out non-bounceable — and a router or escrow contract that rejects a message (expired quote, paused pool, closed route) _absorbs_ a non-bounceable transfer instead of returning it. The funds were gone.
63
+
64
+ Swap deposits are now always sent bounceable. The prefix check is replaced by a real read of the address's bounce tag, so raw `0:hex` destinations — which declare no bounceability at all and which the prefix check silently treated as non-bounceable — default to bounceable, the safe side for anything that might be a contract. Sends to an undeployed account stay non-bounceable, since such an account cannot accept a bounceable message, and an explicit `UQ…` destination is still honoured.
65
+
66
+ Adds `getTonAddressBounceability` to `@vultisig/core-chain/chains/ton/address`.
67
+
68
+ - [#2318](https://github.com/vultisig/vultisig-sdk/pull/2318) [`26a83ed`](https://github.com/vultisig/vultisig-sdk/commit/26a83ed417c9543f9c92d28cbb1bd35f0f914817) Thanks [@rcoderdev](https://github.com/rcoderdev)! - Fix TRON transaction lifecycle safety across fee preparation, status polling, and broadcast. Native TRX bandwidth estimates now measure the WalletCore-serialized signed transaction including memo bytes, default transaction times use the fetched block timestamp, expired raw transactions terminate polling, and successful broadcasts must return the deterministic local transaction hash.
69
+
70
+ - Updated dependencies [[`1b3fb49`](https://github.com/vultisig/vultisig-sdk/commit/1b3fb498ad3f78b84b92b9f09b41fe8956fc5e9a), [`7d4c116`](https://github.com/vultisig/vultisig-sdk/commit/7d4c116cc7a940e96abf075790c4a387edd03987), [`7b65284`](https://github.com/vultisig/vultisig-sdk/commit/7b65284f7fe73f538283a201a416efdbbda0830c), [`1716a79`](https://github.com/vultisig/vultisig-sdk/commit/1716a7946bf617ff16f8bb15f33b279efbb4a87d), [`a711b6c`](https://github.com/vultisig/vultisig-sdk/commit/a711b6ca8a8a7ae39d0efbb1c919b23b6538a1b8), [`ef6a8bb`](https://github.com/vultisig/vultisig-sdk/commit/ef6a8bb0007c6576179e5a8cb10aa47820075b57), [`26a83ed`](https://github.com/vultisig/vultisig-sdk/commit/26a83ed417c9543f9c92d28cbb1bd35f0f914817), [`b19c5d5`](https://github.com/vultisig/vultisig-sdk/commit/b19c5d56f4d00d92493f8da74ff80d92b1d87c68)]:
71
+ - @vultisig/core-chain@5.0.0
72
+
3
73
  ## 2.1.1
4
74
 
5
75
  ### Patch Changes
@@ -28,7 +28,6 @@ export declare const chainSpecificRecord: {
28
28
  readonly Cosmos: "cosmosSpecific";
29
29
  readonly Osmosis: "cosmosSpecific";
30
30
  readonly Dydx: "cosmosSpecific";
31
- readonly Kujira: "cosmosSpecific";
32
31
  readonly Terra: "cosmosSpecific";
33
32
  readonly TerraClassic: "cosmosSpecific";
34
33
  readonly Noble: "cosmosSpecific";
@@ -1 +1 @@
1
- {"version":3,"file":"KeysignChainSpecific.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/mpc/keysign/chainSpecific/KeysignChainSpecific.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iEAAiE,CAAA;AAGhG,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,oBAAoB,CAAC,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,CAAA;AAExH,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAA;AAElE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqD2B,CAAA;AAE3D,eAAO,MAAM,0BAA0B,GAAI,CAAC,SAAS,uBAAuB,EAC1E,oBAAoB,cAAc,CAAC,oBAAoB,CAAC,EACxD,cAAc,CAAC,KACd,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC,OAAO,CAMpD,CAAA"}
1
+ {"version":3,"file":"KeysignChainSpecific.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/mpc/keysign/chainSpecific/KeysignChainSpecific.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,MAAM,iEAAiE,CAAA;AAGhG,MAAM,MAAM,oBAAoB,GAAG,OAAO,CAAC,cAAc,CAAC,oBAAoB,CAAC,EAAE;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,CAAA;AAExH,MAAM,MAAM,uBAAuB,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAA;AAElE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoD2B,CAAA;AAE3D,eAAO,MAAM,0BAA0B,GAAI,CAAC,SAAS,uBAAuB,EAC1E,oBAAoB,cAAc,CAAC,oBAAoB,CAAC,EACxD,cAAc,CAAC,KACd,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC,OAAO,CAMpD,CAAA"}
@@ -24,7 +24,6 @@ export const chainSpecificRecord = {
24
24
  [Chain.Cosmos]: 'cosmosSpecific',
25
25
  [Chain.Osmosis]: 'cosmosSpecific',
26
26
  [Chain.Dydx]: 'cosmosSpecific',
27
- [Chain.Kujira]: 'cosmosSpecific',
28
27
  [Chain.Terra]: 'cosmosSpecific',
29
28
  [Chain.TerraClassic]: 'cosmosSpecific',
30
29
  [Chain.Noble]: 'cosmosSpecific',
@@ -1 +1 @@
1
- {"version":3,"file":"KeysignChainSpecific.js","sourceRoot":"","sources":["../../../../../../packages/core/mpc/keysign/chainSpecific/KeysignChainSpecific.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"KeysignChainSpecific.js","sourceRoot":"","sources":["../../../../../../packages/core/mpc/keysign/chainSpecific/KeysignChainSpecific.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAA;AAElD,OAAO,EAAE,0BAA0B,EAAE,MAAM,gDAAgD,CAAA;AAM3F,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,kBAAkB;IACpC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,kBAAkB;IACrC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,kBAAkB;IAChC,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,kBAAkB;IACvC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,kBAAkB;IAC/B,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,kBAAkB;IACjC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,kBAAkB;IACpC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,kBAAkB;IACpC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,kBAAkB;IACnC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,kBAAkB;IAClC,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,kBAAkB;IAClC,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,kBAAkB;IACvC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,kBAAkB;IAC/B,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,kBAAkB;IAErC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,cAAc;IAC/B,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,cAAc;IACnC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,cAAc;IAChC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,cAAc;IAChC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,cAAc;IAC5B,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,cAAc;IAE7B,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,gBAAgB;IAChC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,gBAAgB;IACjC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,gBAAgB;IAC9B,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,gBAAgB;IAC/B,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,gBAAgB;IACtC,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,gBAAgB;IAC/B,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,gBAAgB;IAE/B,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,mBAAmB;IAEtC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,cAAc;IAEjC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,gBAAgB;IAE7B,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,gBAAgB;IAEhC,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,kBAAkB;IAEpC,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,kBAAkB;IAErC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,aAAa;IAE1B,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,gBAAgB;IAEhC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,cAAc;IAE5B,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,SAAS;IAE1B,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,gBAAgB;CAC2B,CAAA;AAE3D,MAAM,CAAC,MAAM,0BAA0B,GAAG,CACxC,kBAAwD,EACxD,YAAe,EACsC,EAAE;IACvD,IAAI,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAA;IAChD,CAAC;IAED,OAAO,0BAA0B,CAAC,kBAAkB,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,CAAQ,CAAA;AAC7F,CAAC,CAAA"}
@@ -40,6 +40,16 @@ export type GetChainSpecificInput<C extends KeysignChainSpecificKey = KeysignCha
40
40
  refBlockBytesHex?: string;
41
41
  refBlockHashHex?: string;
42
42
  thirdPartyGasLimitEstimation?: bigint;
43
+ } : C extends 'rippleSpecific' ? {
44
+ /** Explicit send intent overrides the legacy issuer-address TrustSet inference. */
45
+ transactionType?: TransactionType.RIPPLE_PAYMENT | TransactionType.RIPPLE_TRUST_SET;
46
+ } : C extends 'tonSpecific' ? {
47
+ /**
48
+ * Deadline (unix seconds) a dApp attached to the request — a TonConnect
49
+ * `sendTransaction` `valid_until`. Caps the wallet's own expiry; a deadline
50
+ * already in the past fails the build instead of signing a dead transaction.
51
+ */
52
+ validUntil?: number;
43
53
  } : {});
44
54
  export type GetChainSpecificResolver<C extends KeysignChainSpecificKey = KeysignChainSpecificKey> = Resolver<GetChainSpecificInput<C>, Promise<ValueForCase<C>>>;
45
55
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/mpc/keysign/chainSpecific/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qEAAqE,CAAA;AAC1G,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAEtF,KAAK,YAAY,CAAC,CAAC,SAAS,uBAAuB,IAAI,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC,OAAO,CAAC,CAAA;AAE1G,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,uBAAuB,GAAG,uBAAuB,IAAI;IAC/F,cAAc,EAAE,cAAc,CAAA;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,GAAG,CAAC,CAAC,SAAS,kBAAkB,GAC7B;IACE,WAAW,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;IAChC,4BAA4B,CAAC,EAAE,MAAM,CAAA;CACtC,GACD,CAAC,SAAS,cAAc,GACtB;IAAE,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,GAClD,CAAC,SAAS,gBAAgB,GACxB;IACE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,GACD,CAAC,SAAS,mBAAmB,GAC3B;IACE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC,GACD,CAAC,SAAS,cAAc,GACtB;IACE,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,GACD,CAAC,SAAS,cAAc,GACtB;IACE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4BAA4B,CAAC,EAAE,MAAM,CAAA;CACtC,GACD,EAAE,CAAC,CAAA;AAEjB,MAAM,MAAM,wBAAwB,CAAC,CAAC,SAAS,uBAAuB,GAAG,uBAAuB,IAAI,QAAQ,CAC1G,qBAAqB,CAAC,CAAC,CAAC,EACxB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CACzB,CAAA"}
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../../../../../packages/core/mpc/keysign/chainSpecific/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qEAAqE,CAAA;AAC1G,OAAO,EAAE,QAAQ,EAAE,MAAM,oCAAoC,CAAA;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAA;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAA;AAEpC,OAAO,EAAE,cAAc,EAAE,MAAM,oDAAoD,CAAA;AACnF,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAC3C,OAAO,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAA;AAEtF,KAAK,YAAY,CAAC,CAAC,SAAS,uBAAuB,IAAI,OAAO,CAAC,oBAAoB,EAAE;IAAE,IAAI,EAAE,CAAC,CAAA;CAAE,CAAC,CAAC,OAAO,CAAC,CAAA;AAE1G,MAAM,MAAM,qBAAqB,CAAC,CAAC,SAAS,uBAAuB,GAAG,uBAAuB,IAAI;IAC/F,cAAc,EAAE,cAAc,CAAA;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,0EAA0E;IAC1E,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB,GAAG,CAAC,CAAC,SAAS,kBAAkB,GAC7B;IACE,WAAW,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,CAAA;IAChC,4BAA4B,CAAC,EAAE,MAAM,CAAA;CACtC,GACD,CAAC,SAAS,cAAc,GACtB;IAAE,WAAW,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAA;CAAE,GAClD,CAAC,SAAS,gBAAgB,GACxB;IACE,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,eAAe,CAAA;IACjC,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,GACD,CAAC,SAAS,mBAAmB,GAC3B;IACE,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,eAAe,CAAC,EAAE,eAAe,CAAA;CAClC,GACD,CAAC,SAAS,cAAc,GACtB;IACE,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,GACD,CAAC,SAAS,cAAc,GACtB;IACE,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,4BAA4B,CAAC,EAAE,MAAM,CAAA;CACtC,GACD,CAAC,SAAS,gBAAgB,GACxB;IACE,mFAAmF;IACnF,eAAe,CAAC,EAAE,eAAe,CAAC,cAAc,GAAG,eAAe,CAAC,gBAAgB,CAAA;CACpF,GACD,CAAC,SAAS,aAAa,GACrB;IACE;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,GACD,EAAE,CAAC,CAAA;AAErB,MAAM,MAAM,wBAAwB,CAAC,CAAC,SAAS,uBAAuB,GAAG,uBAAuB,IAAI,QAAQ,CAC1G,qBAAqB,CAAC,CAAC,CAAC,EACxB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CACzB,CAAA"}
@@ -1,4 +1,15 @@
1
1
  import { GetChainSpecificResolver } from '../resolver.js';
2
2
  export declare const getRippleLastLedgerSequence: (ledgerCurrentIndex: number | undefined) => bigint;
3
+ /**
4
+ * Resolves the per-ceremony XRPL fields — sequence, network fee, ledger
5
+ * validity window, destination tag and the operation discriminator — and
6
+ * refuses, before the user reviews anything, a transaction the ledger would
7
+ * apply without delivering: a Payment missing a required DestinationTag, a
8
+ * native send too small to activate a fresh destination, and an issued-currency
9
+ * Payment whose destination or issuer cannot receive it.
10
+ *
11
+ * Deterministic bad input surfaces as a [BuildKeysignPayloadError] so callers
12
+ * stop retrying; lookups that merely failed stay retryable.
13
+ */
3
14
  export declare const getRippleChainSpecific: GetChainSpecificResolver<'rippleSpecific'>;
4
15
  //# sourceMappingURL=ripple.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ripple.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAOtD,eAAO,MAAM,2BAA2B,GAAI,oBAAoB,MAAM,GAAG,SAAS,KAAG,MAMpF,CAAA;AAED,eAAO,MAAM,sBAAsB,EAAE,wBAAwB,CAAC,gBAAgB,CA8F7E,CAAA"}
1
+ {"version":3,"file":"ripple.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ripple.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,aAAa,CAAA;AAmFtD,eAAO,MAAM,2BAA2B,GAAI,oBAAoB,MAAM,GAAG,SAAS,KAAG,MAMpF,CAAA;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,sBAAsB,EAAE,wBAAwB,CAAC,gBAAgB,CAsJ7E,CAAA"}
@@ -1,9 +1,12 @@
1
1
  import { create } from '@bufbuild/protobuf';
2
2
  import { getRippleAccountInfo } from '@vultisig/core-chain/chains/ripple/account/info';
3
+ import { getRippleAccountLines } from '@vultisig/core-chain/chains/ripple/account/lines';
4
+ import { parseRippleTokenId } from '@vultisig/core-chain/chains/ripple/issuedCurrency';
5
+ import { findRippleTrustLine } from '@vultisig/core-chain/chains/ripple/trustLine';
3
6
  import { getRippleNetworkInfo } from '@vultisig/core-chain/chains/ripple/network/info';
4
7
  import { RippleSpecificSchema, TransactionType, } from '@vultisig/core-mpc/types/vultisig/keysign/v1/blockchain_specific_pb';
5
8
  import { shouldBePresent } from '@vultisig/lib-utils/assert/shouldBePresent';
6
- import { attempt } from '@vultisig/lib-utils/attempt';
9
+ import { attempt, withFallback } from '@vultisig/lib-utils/attempt';
7
10
  import { isInError } from '@vultisig/lib-utils/error/isInError';
8
11
  import { maxBigInt } from '@vultisig/lib-utils/math/maxBigInt';
9
12
  import { BuildKeysignPayloadError } from '../../error.js';
@@ -14,13 +17,74 @@ const minProtocolFee = 15n;
14
17
  const baseFeeMultiplier = 2n;
15
18
  const rippleRequireDestinationTagFlag = 0x00020000;
16
19
  const lastLedgerSequenceOffset = 60;
20
+ /**
21
+ * `AccountRoot.TransferRate` encoding for "no transfer fee". The field is
22
+ * absent or zero on most issuers; anything above this billionths-denominated
23
+ * unit rate means the issuer charges a fee on every hop.
24
+ * @see https://xrpl.org/docs/concepts/tokens/transfer-fees
25
+ */
26
+ const rippleNoTransferFeeRate = 1_000_000_000;
27
+ /**
28
+ * Rejects an issued-currency Payment the XRP Ledger would refuse to deliver,
29
+ * while the payload is still being built.
30
+ *
31
+ * Both shapes it catches are *applied* transactions on-ledger: the fee is
32
+ * burned and the sequence consumed even though nothing moves. A destination
33
+ * holding no trust line for the exact (currency, issuer) fails with
34
+ * tecNO_LINE/tecPATH_DRY, and an issuer charging a TransferRate fails with
35
+ * tecPATH_PARTIAL because the sender owes `Amount x (1 + rate)` while XRPL
36
+ * defaults SendMax to Amount alone.
37
+ *
38
+ * Fails closed: a lookup that does not come back is not evidence of a usable
39
+ * trust line, and those failures stay retryable rather than becoming a
40
+ * [BuildKeysignPayloadError].
41
+ *
42
+ * Not for redemptions — sending a token back to its own issuer needs no trust
43
+ * line and pays no transfer fee. Callers skip it in that case.
44
+ */
45
+ const assertRippleTokenIsDeliverable = async ({ ticker, senderAddress, toAddress, issuedCurrency, }) => {
46
+ const [linesResult, issuerResult] = await Promise.all([
47
+ attempt(getRippleAccountLines(toAddress)),
48
+ // An issuer never charges itself a transfer fee on its own token.
49
+ senderAddress === issuedCurrency.issuer ? undefined : attempt(getRippleAccountInfo(issuedCurrency.issuer)),
50
+ ]);
51
+ if ('error' in linesResult) {
52
+ throw new Error(`Unable to verify whether XRP destination ${toAddress} holds a trust line for ${ticker}`);
53
+ }
54
+ if (!findRippleTrustLine({ lines: linesResult.data, ...issuedCurrency })) {
55
+ throw new BuildKeysignPayloadError('ripple-destination-trust-line-missing', `Cannot send ${ticker} to ${toAddress}: that account holds no trust line for this token, ` +
56
+ 'so the XRP Ledger would reject the payment. The recipient has to open one first.');
57
+ }
58
+ if (issuerResult === undefined) {
59
+ return;
60
+ }
61
+ if ('error' in issuerResult) {
62
+ throw new Error(`Unable to verify whether the ${ticker} issuer charges an XRP transfer fee`);
63
+ }
64
+ const { TransferRate } = issuerResult.data.account_data;
65
+ if (TransferRate !== undefined && TransferRate > rippleNoTransferFeeRate) {
66
+ throw new BuildKeysignPayloadError('ripple-issuer-transfer-fee-unsupported', `Cannot send ${ticker}: its issuer charges a transfer fee, which needs a SendMax this ` +
67
+ 'payload cannot express yet. Sending it back to the issuer still works.');
68
+ }
69
+ };
17
70
  export const getRippleLastLedgerSequence = (ledgerCurrentIndex) => {
18
71
  if (ledgerCurrentIndex === undefined || !Number.isSafeInteger(ledgerCurrentIndex) || ledgerCurrentIndex <= 0) {
19
72
  throw new Error('Ripple account_info response is missing a valid ledger_current_index.');
20
73
  }
21
74
  return BigInt(ledgerCurrentIndex + lastLedgerSequenceOffset);
22
75
  };
23
- export const getRippleChainSpecific = async ({ keysignPayload, destinationTag, }) => {
76
+ /**
77
+ * Resolves the per-ceremony XRPL fields — sequence, network fee, ledger
78
+ * validity window, destination tag and the operation discriminator — and
79
+ * refuses, before the user reviews anything, a transaction the ledger would
80
+ * apply without delivering: a Payment missing a required DestinationTag, a
81
+ * native send too small to activate a fresh destination, and an issued-currency
82
+ * Payment whose destination or issuer cannot receive it.
83
+ *
84
+ * Deterministic bad input surfaces as a [BuildKeysignPayloadError] so callers
85
+ * stop retrying; lookups that merely failed stay retryable.
86
+ */
87
+ export const getRippleChainSpecific = async ({ keysignPayload, destinationTag, transactionType, }) => {
24
88
  const coin = getKeysignCoin(keysignPayload);
25
89
  const { address } = coin;
26
90
  // A dApp-supplied transaction (OfferCreate, OfferCancel, …) carries no
@@ -32,6 +96,26 @@ export const getRippleChainSpecific = async ({ keysignPayload, destinationTag, }
32
96
  destinationTag,
33
97
  memo: keysignPayload.memo,
34
98
  });
99
+ // Preserve existing trust-line callers, but an ordinary send explicitly
100
+ // selects Payment: sending tokens back to their issuer is also a Payment.
101
+ const isTrustSet = transactionType === undefined
102
+ ? originatesRippleTrustSet(keysignPayload)
103
+ : transactionType === TransactionType.RIPPLE_TRUST_SET;
104
+ // A verbatim dApp transaction is signed exactly as supplied, so the token
105
+ // pre-flights below — which describe a Payment this resolver would build —
106
+ // do not apply to it.
107
+ const isVerbatimDappTx = keysignPayload.signData.case === 'signRipple';
108
+ const isIssuedCurrencySend = !isTrustSet && !isVerbatimDappTx && !!keysignPayload.coin && !keysignPayload.coin.isNativeToken;
109
+ // A payload with no parseable token id cannot name an asset to pre-flight.
110
+ // The signing-input resolver rejects that shape outright; here it only means
111
+ // there is nothing to look up.
112
+ const tokenId = isIssuedCurrencySend ? coin.id : undefined;
113
+ const issuedCurrency = tokenId
114
+ ? withFallback(attempt(() => parseRippleTokenId(tokenId)), undefined)
115
+ : undefined;
116
+ // Sending a token back to its issuer redeems it: the issuer needs no trust
117
+ // line to itself and charges no transfer fee, so neither pre-flight applies.
118
+ const redeemsToIssuer = issuedCurrency !== undefined && toAddress === issuedCurrency.issuer;
35
119
  const [senderAccount, networkInfo, destinationAccountResult] = await Promise.all([
36
120
  getRippleAccountInfo(address),
37
121
  getRippleNetworkInfo(),
@@ -54,7 +138,7 @@ export const getRippleChainSpecific = async ({ keysignPayload, destinationTag, }
54
138
  // XRP Ledger rejects a Payment to an account with lsfRequireDestTag when no
55
139
  // tag is present. Fail closed on lookup errors other than an unfunded
56
140
  // destination: without an account object there is no RequireDestTag flag.
57
- if (toAddress && destinationAccountResult !== undefined && !coin.id && effectiveDestinationTag === undefined) {
141
+ if (toAddress && destinationAccountResult !== undefined && !isTrustSet && effectiveDestinationTag === undefined) {
58
142
  if ('error' in destinationAccountResult) {
59
143
  if (!destinationUnfunded) {
60
144
  // This lookup can fail transiently, so keep it retryable. Only
@@ -67,6 +151,16 @@ export const getRippleChainSpecific = async ({ keysignPayload, destinationTag, }
67
151
  }
68
152
  }
69
153
  if (destinationUnfunded) {
154
+ // A TrustSet is addressed to the issuer, not to a payee. Saying "activate
155
+ // it before sending tokens" would tell the user to fund somebody else's
156
+ // account; an issuer that does not exist simply cannot be trusted.
157
+ if (isTrustSet) {
158
+ throw new BuildKeysignPayloadError('ripple-trust-line-issuer-not-activated', `Cannot open an XRP trust line to ${toAddress}: that issuer account does not exist on the ledger.`);
159
+ }
160
+ if (!keysignPayload.coin?.isNativeToken) {
161
+ throw new BuildKeysignPayloadError('ripple-destination-not-activated', `Cannot send an XRP issued currency to ${toAddress}: the destination account is not activated. ` +
162
+ 'Activate it with the XRP base reserve before sending tokens.');
163
+ }
70
164
  const toAmount = BigInt(shouldBePresent(keysignPayload.toAmount));
71
165
  if (toAmount < BigInt(reserve_base)) {
72
166
  throw new Error(`Cannot send to XRP account ${toAddress}: it is not yet activated, and XRPL requires the ` +
@@ -75,6 +169,14 @@ export const getRippleChainSpecific = async ({ keysignPayload, destinationTag, }
75
169
  `the reserve, or send to an already-activated account.`);
76
170
  }
77
171
  }
172
+ if (issuedCurrency && toAddress && !redeemsToIssuer) {
173
+ await assertRippleTokenIsDeliverable({
174
+ ticker: coin.ticker,
175
+ senderAddress: address,
176
+ toAddress,
177
+ issuedCurrency,
178
+ });
179
+ }
78
180
  const { account_data, ledger_current_index: ledgerCurrentIndex } = senderAccount;
79
181
  // State the operation on the wire rather than leaving every signer to infer
80
182
  // it from the coin. A non-native Ripple coin means either "open a trust line"
@@ -85,14 +187,17 @@ export const getRippleChainSpecific = async ({ keysignPayload, destinationTag, }
85
187
  // Only genuine originations are declared. Stamping a token send would make
86
188
  // every signer agree to build a TrustSet from it, which is worse than the
87
189
  // divergence: the ceremony completes over an operation nobody asked for.
88
- const isTrustSet = originatesRippleTrustSet(keysignPayload);
89
190
  return create(RippleSpecificSchema, {
90
191
  sequence: BigInt(account_data.Sequence),
91
192
  lastLedgerSequence: getRippleLastLedgerSequence(ledgerCurrentIndex),
92
193
  // Fee is the network fee only — the reserve rides on the Payment amount.
93
194
  gas: networkFee,
94
195
  ...(effectiveDestinationTag !== undefined ? { destinationTag: effectiveDestinationTag } : {}),
95
- ...(isTrustSet ? { transactionType: TransactionType.RIPPLE_TRUST_SET } : {}),
196
+ ...(isTrustSet
197
+ ? { transactionType: TransactionType.RIPPLE_TRUST_SET }
198
+ : transactionType === TransactionType.RIPPLE_PAYMENT
199
+ ? { transactionType: TransactionType.RIPPLE_PAYMENT }
200
+ : {}),
96
201
  });
97
202
  };
98
203
  //# 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,EACL,oBAAoB,EACpB,eAAe,GAChB,MAAM,qEAAqE,CAAA;AAC5E,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,wBAAwB,EAAE,MAAM,aAAa,CAAA;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAA;AAC3D,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAA;AAGxE,MAAM,cAAc,GAAG,GAAG,CAAA;AAC1B,MAAM,iBAAiB,GAAG,EAAE,CAAA;AAC5B,MAAM,+BAA+B,GAAG,UAAU,CAAA;AAClD,MAAM,wBAAwB,GAAG,EAAE,CAAA;AAEnC,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,kBAAsC,EAAU,EAAE;IAC5F,IAAI,kBAAkB,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,IAAI,CAAC,EAAE,CAAC;QAC7G,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAA;IAC1F,CAAC;IAED,OAAO,MAAM,CAAC,kBAAkB,GAAG,wBAAwB,CAAC,CAAA;AAC9D,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,sBAAsB,GAA+C,KAAK,EAAE,EACvF,cAAc,EACd,cAAc,GACf,EAAE,EAAE;IACH,MAAM,IAAI,GAAG,cAAc,CAAC,cAAc,CAAC,CAAA;IAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAExB,uEAAuE;IACvE,0EAA0E;IAC1E,2EAA2E;IAC3E,oEAAoE;IACpE,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,IAAI,SAAS,CAAA;IAEvD,MAAM,uBAAuB,GAAG,qBAAqB,CAAC;QACpD,cAAc;QACd,IAAI,EAAE,cAAc,CAAC,IAAI;KAC1B,CAAC,CAAA;IAEF,MAAM,CAAC,aAAa,EAAE,WAAW,EAAE,wBAAwB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC/E,oBAAoB,CAAC,OAAO,CAAC;QAC7B,oBAAoB,EAAE;QACtB,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS;KACjE,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,wBAAwB,KAAK,SAAS;QACtC,OAAO,IAAI,wBAAwB;QACnC,SAAS,CAAC,wBAAwB,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAA;IAEhE,4EAA4E;IAC5E,sEAAsE;IACtE,0EAA0E;IAC1E,IAAI,SAAS,IAAI,wBAAwB,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,uBAAuB,KAAK,SAAS,EAAE,CAAC;QAC7G,IAAI,OAAO,IAAI,wBAAwB,EAAE,CAAC;YACxC,IAAI,CAAC,mBAAmB,EAAE,CAAC;gBACzB,+DAA+D;gBAC/D,kEAAkE;gBAClE,MAAM,IAAI,KAAK,CAAC,4CAA4C,SAAS,4BAA4B,CAAC,CAAA;YACpG,CAAC;QACH,CAAC;aAAM,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,YAAY,CAAC,KAAK,GAAG,+BAA+B,CAAC,KAAK,CAAC,EAAE,CAAC;YACtG,MAAM,IAAI,wBAAwB,CAChC,iCAAiC,EACjC,mBAAmB,SAAS,4BAA4B,CACzD,CAAA;QACH,CAAC;IACH,CAAC;IAED,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,kBAAkB,EAAE,GAAG,aAAa,CAAA;IAEhF,4EAA4E;IAC5E,8EAA8E;IAC9E,4EAA4E;IAC5E,yEAAyE;IACzE,gDAAgD;IAChD,EAAE;IACF,2EAA2E;IAC3E,0EAA0E;IAC1E,yEAAyE;IACzE,MAAM,UAAU,GAAG,wBAAwB,CAAC,cAAc,CAAC,CAAA;IAE3D,OAAO,MAAM,CAAC,oBAAoB,EAAE;QAClC,QAAQ,EAAE,MAAM,CAAC,YAAY,CAAC,QAAQ,CAAC;QACvC,kBAAkB,EAAE,2BAA2B,CAAC,kBAAkB,CAAC;QACnE,yEAAyE;QACzE,GAAG,EAAE,UAAU;QACf,GAAG,CAAC,uBAAuB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,uBAAuB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7F,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,eAAe,CAAC,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC7E,CAAC,CAAA;AACJ,CAAC,CAAA"}
1
+ {"version":3,"file":"ripple.js","sourceRoot":"","sources":["../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ripple.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ton/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAIzD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,wBAAwB,CAAC,aAAa,CAuEvE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/ton/index.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAkCzD;;;;;;GAMG;AACH,eAAO,MAAM,mBAAmB,EAAE,wBAAwB,CAAC,aAAa,CAyGvE,CAAA"}
@@ -1,10 +1,33 @@
1
1
  import { create } from '@bufbuild/protobuf';
2
2
  import { getTonAccountInfo } from '@vultisig/core-chain/chains/ton/account/getTonAccountInfo';
3
+ import { getTonAddressBounceability } from '@vultisig/core-chain/chains/ton/address';
3
4
  import { getJettonWalletAddress, getTonWalletState } from '@vultisig/core-chain/chains/ton/api';
4
5
  import { TonSpecificSchema } from '@vultisig/core-mpc/types/vultisig/keysign/v1/blockchain_specific_pb';
5
6
  import { attempt } from '@vultisig/lib-utils/attempt';
7
+ import { getKeysignSwapPayload } from '../../../swap/getKeysignSwapPayload.js';
6
8
  import { getKeysignCoin } from '../../../utils/getKeysignCoin.js';
7
9
  const tonWalletStateUninitialized = 'uninit';
10
+ /** How long a wallet message stays valid when the caller sets no tighter deadline. */
11
+ const tonWalletExpirySeconds = 600;
12
+ /**
13
+ * The `expireAt` to sign. The wallet's own 10-minute window is the ceiling; a dApp
14
+ * deadline (`valid_until`) can only tighten it, never extend it. A deadline that has
15
+ * already passed by build time fails here rather than producing a transaction the
16
+ * network will reject.
17
+ */
18
+ const resolveTonExpireAt = ({ now, validUntil }) => {
19
+ const walletDeadline = now + tonWalletExpirySeconds;
20
+ if (validUntil === undefined) {
21
+ return walletDeadline;
22
+ }
23
+ // Whole seconds only: flooring first means a deadline less than a second out is
24
+ // caught here rather than signed as an expiry equal to `now`.
25
+ const deadline = Number.isFinite(validUntil) ? Math.floor(validUntil) : Number.NaN;
26
+ if (!(deadline > now)) {
27
+ throw new Error(`TON request deadline (valid_until ${validUntil}) has already passed`);
28
+ }
29
+ return Math.min(walletDeadline, deadline);
30
+ };
8
31
  /**
9
32
  * Resolves the TON-specific keysign fields: the sender's seqno, an expiry, whether the
10
33
  * transfer bounces on rejection, and — for Jettons — the sender's Jetton wallet and
@@ -12,7 +35,7 @@ const tonWalletStateUninitialized = 'uninit';
12
35
  * rather than inferred, so an ordinary send that happens to sit close to the balance is
13
36
  * not relabelled a MAX send.
14
37
  */
15
- export const getTonChainSpecific = async ({ keysignPayload, sendMaxAmount = false, }) => {
38
+ export const getTonChainSpecific = async ({ keysignPayload, sendMaxAmount = false, validUntil, }) => {
16
39
  const coin = getKeysignCoin(keysignPayload);
17
40
  const { address } = coin;
18
41
  const receiver = keysignPayload.toAddress;
@@ -27,31 +50,40 @@ export const getTonChainSpecific = async ({ keysignPayload, sendMaxAmount = fals
27
50
  // than returning null and crashing this destructure.
28
51
  const { account_state } = await getTonAccountInfo(address);
29
52
  const sequenceNumber = BigInt(account_state?.seqno ?? 0);
53
+ // Whether the transfer goes out bounceable, which decides what happens to the funds
54
+ // when the destination rejects the message: a bounceable transfer is refunded, a
55
+ // non-bounceable one is absorbed by the destination and gone.
30
56
  const getIsBounceable = async () => {
31
- if (receiver) {
32
- const { data: walletState } = await attempt(getTonWalletState(receiver));
33
- const isUninitialized = walletState === tonWalletStateUninitialized;
34
- if (!isUninitialized && receiver.startsWith('E')) {
35
- return true;
36
- }
57
+ if (!receiver) {
58
+ return false;
59
+ }
60
+ // A swap deposit lands on a router or escrow contract, and there are ordinary
61
+ // reasons for such a contract to reject: an expired quote, a paused pool, a
62
+ // route that closed between quote and broadcast. Those have to come back.
63
+ if (getKeysignSwapPayload(keysignPayload)) {
64
+ return true;
37
65
  }
38
- return false;
66
+ // An undeployed account has no code to reject anything, so a bounceable message
67
+ // is simply returned and the transfer never lands. Those must go non-bounceable.
68
+ const { data: walletState } = await attempt(getTonWalletState(receiver));
69
+ if (walletState === tonWalletStateUninitialized) {
70
+ return false;
71
+ }
72
+ // A raw `0:hex` destination declares no intent, so it defaults to bounceable —
73
+ // the safe side for anything that might be a contract. Only an explicit `UQ…`
74
+ // opts out.
75
+ return getTonAddressBounceability(receiver) !== 'nonBounceable';
39
76
  };
40
- const result = create(TonSpecificSchema, {
41
- sequenceNumber,
42
- expireAt: BigInt(Math.floor(Date.now() / 1000) + 600),
43
- bounceable: await getIsBounceable(),
44
- sendMaxAmount,
45
- jettonAddress: '',
46
- isActiveDestination: false,
47
- });
48
- if (coin.id) {
49
- // A Jetton transfer is a message to the SENDER's own jetton wallet, so without
50
- // that address there is no transaction to build. Leaving the empty-string default
51
- // in place does not stop anything downstream — the signing path's presence check
52
- // only rejects null/undefined — so a failed lookup would otherwise be signed as a
53
- // transfer to nowhere. This lookup fails transiently (RPC timeout, indexer lag),
54
- // so it stays a plain retryable Error rather than a BuildKeysignPayloadError.
77
+ // A Jetton transfer is a message to the SENDER's own jetton wallet, so without
78
+ // that address there is no transaction to build. Leaving the empty-string default
79
+ // in place does not stop anything downstream — the signing path's presence check
80
+ // only rejects null/undefined — so a failed lookup would otherwise be signed as a
81
+ // transfer to nowhere. This lookup fails transiently (RPC timeout, indexer lag),
82
+ // so it stays a plain retryable Error rather than a BuildKeysignPayloadError.
83
+ const getJettonFields = async () => {
84
+ if (!coin.id) {
85
+ return { jettonAddress: '', isActiveDestination: false };
86
+ }
55
87
  const jettonWallet = await attempt(getJettonWalletAddress({
56
88
  ownerAddress: address,
57
89
  jettonMasterAddress: coin.id,
@@ -60,12 +92,30 @@ export const getTonChainSpecific = async ({ keysignPayload, sendMaxAmount = fals
60
92
  throw new Error(`Unable to resolve the ${coin.ticker} jetton wallet owned by ${address}. ` +
61
93
  'Refusing to build a Jetton transfer without it.', 'error' in jettonWallet ? { cause: jettonWallet.error } : undefined);
62
94
  }
63
- result.jettonAddress = jettonWallet.data;
64
- if (receiver) {
65
- const { data: destWalletState } = await attempt(getTonWalletState(receiver));
66
- result.isActiveDestination = destWalletState !== tonWalletStateUninitialized;
95
+ if (!receiver) {
96
+ return { jettonAddress: jettonWallet.data, isActiveDestination: false };
67
97
  }
68
- }
69
- return result;
98
+ const { data: destWalletState } = await attempt(getTonWalletState(receiver));
99
+ return {
100
+ jettonAddress: jettonWallet.data,
101
+ isActiveDestination: destWalletState !== tonWalletStateUninitialized,
102
+ };
103
+ };
104
+ const bounceable = await getIsBounceable();
105
+ const { jettonAddress, isActiveDestination } = await getJettonFields();
106
+ // Read the clock last. Every lookup above is a network round trip, and a deadline
107
+ // that was still ahead when the build started can be behind by the time it
108
+ // finishes — computing the expiry up front would sign that dead deadline instead
109
+ // of refusing it, and would also spend part of the wallet's own ten-minute window
110
+ // on the lookups.
111
+ const expireAt = BigInt(resolveTonExpireAt({ now: Math.floor(Date.now() / 1000), validUntil }));
112
+ return create(TonSpecificSchema, {
113
+ sequenceNumber,
114
+ expireAt,
115
+ bounceable,
116
+ sendMaxAmount,
117
+ jettonAddress,
118
+ isActiveDestination,
119
+ });
70
120
  };
71
121
  //# sourceMappingURL=index.js.map
@@ -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":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,2DAA2D,CAAA;AAC7F,OAAO,EAAE,0BAA0B,EAAE,MAAM,yCAAyC,CAAA;AACpF,OAAO,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAA;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,qEAAqE,CAAA;AACvG,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAA;AAErD,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAA;AAC3E,OAAO,EAAE,cAAc,EAAE,MAAM,+BAA+B,CAAA;AAG9D,MAAM,2BAA2B,GAAG,QAAQ,CAAA;AAE5C,sFAAsF;AACtF,MAAM,sBAAsB,GAAG,GAAG,CAAA;AAOlC;;;;;GAKG;AACH,MAAM,kBAAkB,GAAG,CAAC,EAAE,GAAG,EAAE,UAAU,EAA2B,EAAU,EAAE;IAClF,MAAM,cAAc,GAAG,GAAG,GAAG,sBAAsB,CAAA;IACnD,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC7B,OAAO,cAAc,CAAA;IACvB,CAAC;IAED,gFAAgF;IAChF,8DAA8D;IAC9D,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAA;IAClF,IAAI,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,qCAAqC,UAAU,sBAAsB,CAAC,CAAA;IACxF,CAAC;IAED,OAAO,IAAI,CAAC,GAAG,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAA;AAC3C,CAAC,CAAA;AAED;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAA4C,KAAK,EAAE,EACjF,cAAc,EACd,aAAa,GAAG,KAAK,EACrB,UAAU,GACX,EAAE,EAAE;IACH,MAAM,IAAI,GAAG,cAAc,CAAC,cAAc,CAAC,CAAA;IAC3C,MAAM,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IACxB,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,CAAA;IAEzC,8EAA8E;IAC9E,4EAA4E;IAC5E,+EAA+E;IAC/E,8EAA8E;IAC9E,yEAAyE;IACzE,gEAAgE;IAChE,+EAA+E;IAC/E,6EAA6E;IAC7E,qDAAqD;IACrD,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAA;IAC1D,MAAM,cAAc,GAAG,MAAM,CAAC,aAAa,EAAE,KAAK,IAAI,CAAC,CAAC,CAAA;IAExD,oFAAoF;IACpF,iFAAiF;IACjF,8DAA8D;IAC9D,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;QACjC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,KAAK,CAAA;QACd,CAAC;QAED,8EAA8E;QAC9E,4EAA4E;QAC5E,0EAA0E;QAC1E,IAAI,qBAAqB,CAAC,cAAc,CAAC,EAAE,CAAC;YAC1C,OAAO,IAAI,CAAA;QACb,CAAC;QAED,gFAAgF;QAChF,iFAAiF;QACjF,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAA;QACxE,IAAI,WAAW,KAAK,2BAA2B,EAAE,CAAC;YAChD,OAAO,KAAK,CAAA;QACd,CAAC;QAED,+EAA+E;QAC/E,8EAA8E;QAC9E,YAAY;QACZ,OAAO,0BAA0B,CAAC,QAAQ,CAAC,KAAK,eAAe,CAAA;IACjE,CAAC,CAAA;IAED,+EAA+E;IAC/E,kFAAkF;IAClF,iFAAiF;IACjF,kFAAkF;IAClF,iFAAiF;IACjF,8EAA8E;IAC9E,MAAM,eAAe,GAAG,KAAK,IAAI,EAAE;QACjC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC;YACb,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAA;QAC1D,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,OAAO,CAChC,sBAAsB,CAAC;YACrB,YAAY,EAAE,OAAO;YACrB,mBAAmB,EAAE,IAAI,CAAC,EAAE;SAC7B,CAAC,CACH,CAAA;QAED,IAAI,OAAO,IAAI,YAAY,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,yBAAyB,IAAI,CAAC,MAAM,2BAA2B,OAAO,IAAI;gBACxE,iDAAiD,EACnD,OAAO,IAAI,YAAY,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CACpE,CAAA;QACH,CAAC;QAED,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,OAAO,EAAE,aAAa,EAAE,YAAY,CAAC,IAAI,EAAE,mBAAmB,EAAE,KAAK,EAAE,CAAA;QACzE,CAAC;QAED,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,GAAG,MAAM,OAAO,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAA;QAE5E,OAAO;YACL,aAAa,EAAE,YAAY,CAAC,IAAI;YAChC,mBAAmB,EAAE,eAAe,KAAK,2BAA2B;SACrE,CAAA;IACH,CAAC,CAAA;IAED,MAAM,UAAU,GAAG,MAAM,eAAe,EAAE,CAAA;IAC1C,MAAM,EAAE,aAAa,EAAE,mBAAmB,EAAE,GAAG,MAAM,eAAe,EAAE,CAAA;IAEtE,kFAAkF;IAClF,2EAA2E;IAC3E,iFAAiF;IACjF,kFAAkF;IAClF,kBAAkB;IAClB,MAAM,QAAQ,GAAG,MAAM,CAAC,kBAAkB,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAA;IAE/F,OAAO,MAAM,CAAC,iBAAiB,EAAE;QAC/B,cAAc;QACd,QAAQ;QACR,UAAU;QACV,aAAa;QACb,aAAa;QACb,mBAAmB;KACpB,CAAC,CAAA;AACJ,CAAC,CAAA"}
@@ -1,3 +1,21 @@
1
+ import { getTronBlockInfo } from '@vultisig/core-chain/chains/tron/getTronBlockInfo';
2
+ import { type WalletCore } from '@trustwallet/wallet-core';
1
3
  import { GetChainSpecificResolver } from '../../resolver.js';
4
+ type NativeTronBandwidthInput = {
5
+ walletCore: WalletCore;
6
+ fromAddress: string;
7
+ toAddress: string;
8
+ amount: bigint;
9
+ memo: string;
10
+ blockInfo: Awaited<ReturnType<typeof getTronBlockInfo>>;
11
+ };
12
+ /**
13
+ * TRON charges bandwidth for the serialized signed transaction, not for a
14
+ * fixed transfer template. WalletCore exposes the exact raw_data bytes through
15
+ * its pre-signing output; the remaining signed envelope consists of the
16
+ * length-delimited raw_data field and one 65-byte secp256k1 signature.
17
+ */
18
+ export declare const getNativeTronBandwidthBytes: ({ walletCore, fromAddress, toAddress, amount, memo, blockInfo, }: NativeTronBandwidthInput) => number;
2
19
  export declare const getTronChainSpecific: GetChainSpecificResolver<'tronSpecific'>;
20
+ export {};
3
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/tron/index.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAyBzD,eAAO,MAAM,oBAAoB,EAAE,wBAAwB,CAAC,cAAc,CA2CzE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/mpc/keysign/chainSpecific/resolvers/tron/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mDAAmD,CAAA;AAKpF,OAAO,EAAM,KAAK,UAAU,EAAE,MAAM,0BAA0B,CAAA;AAK9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AA0BzD,KAAK,wBAAwB,GAAG;IAC9B,UAAU,EAAE,UAAU,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAC,CAAA;CACxD,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,2BAA2B,GAAI,kEAOzC,wBAAwB,KAAG,MAqC7B,CAAA;AAgBD,eAAO,MAAM,oBAAoB,EAAE,wBAAwB,CAAC,cAAc,CAmDzE,CAAA"}