@gibs/bridge-sdk 1.19.0 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (111) hide show
  1. package/dist/abis.js +0 -2
  2. package/dist/bridge-limits.js +0 -38
  3. package/dist/chain-info.js +0 -116
  4. package/dist/chain-names.js +0 -151
  5. package/dist/chains.js +0 -198
  6. package/dist/cjs/abis.js +0 -2
  7. package/dist/cjs/bridge-limits.js +0 -38
  8. package/dist/cjs/chain-info.js +0 -116
  9. package/dist/cjs/chain-names.js +0 -151
  10. package/dist/cjs/chains.js +0 -198
  11. package/dist/cjs/claims.js +0 -60
  12. package/dist/cjs/config.js +1 -208
  13. package/dist/cjs/consolidated-quote.js +0 -465
  14. package/dist/cjs/destination-calldata.js +0 -71
  15. package/dist/cjs/ecosystems.js +0 -183
  16. package/dist/cjs/execution.js +0 -92
  17. package/dist/cjs/fee-type.js +0 -1
  18. package/dist/cjs/hyperliquid-execution.js +0 -98
  19. package/dist/cjs/image-links.js +0 -108
  20. package/dist/cjs/lifi-execution-guard.js +65 -172
  21. package/dist/cjs/near-intents-conformance.js +0 -110
  22. package/dist/cjs/near-intents-route.js +0 -149
  23. package/dist/cjs/near-intents.js +0 -562
  24. package/dist/cjs/origin-deposit.js +0 -56
  25. package/dist/cjs/pre-quote.js +0 -80
  26. package/dist/cjs/prices.js +0 -113
  27. package/dist/cjs/providers.js +0 -83
  28. package/dist/cjs/quote-fees.js +0 -80
  29. package/dist/cjs/referral.js +0 -75
  30. package/dist/cjs/relay-currencies.js +0 -31
  31. package/dist/cjs/relay-depository.js +52 -77
  32. package/dist/cjs/relay-quote.js +0 -394
  33. package/dist/cjs/route-steps.js +0 -100
  34. package/dist/cjs/routing/amounts.js +0 -83
  35. package/dist/cjs/routing/candidate-route.js +0 -73
  36. package/dist/cjs/routing/candidate.js +0 -46
  37. package/dist/cjs/routing/carrier-provider-key.js +0 -27
  38. package/dist/cjs/routing/carriers/omnibridge.js +0 -120
  39. package/dist/cjs/routing/carriers/pulsex-paths.js +0 -57
  40. package/dist/cjs/routing/carriers/pulsex-split.js +0 -92
  41. package/dist/cjs/routing/carriers/pulsex.js +0 -279
  42. package/dist/cjs/routing/carriers/wrap.js +0 -57
  43. package/dist/cjs/routing/composed-route-quality.js +0 -95
  44. package/dist/cjs/routing/entry-chain-anchor.js +0 -27
  45. package/dist/cjs/routing/format.js +0 -50
  46. package/dist/cjs/routing/index.js +0 -28
  47. package/dist/cjs/routing/producers.js +0 -854
  48. package/dist/cjs/routing/providers.js +0 -27
  49. package/dist/cjs/routing/search/compose.js +0 -56
  50. package/dist/cjs/routing/search/graph.js +0 -364
  51. package/dist/cjs/routing/search/plan-route-data.js +0 -508
  52. package/dist/cjs/routing/search/score.js +0 -344
  53. package/dist/cjs/routing/swap-transactions.js +0 -74
  54. package/dist/cjs/routing/usd-value.js +0 -12
  55. package/dist/cjs/settings.js +1 -456
  56. package/dist/cjs/swap-venues.js +0 -17
  57. package/dist/cjs/ton-connect.js +0 -82
  58. package/dist/cjs/ton-execution.js +0 -6
  59. package/dist/cjs/ton.js +0 -42
  60. package/dist/cjs/tron-execution.js +0 -145
  61. package/dist/claims.js +0 -60
  62. package/dist/config.js +1 -211
  63. package/dist/consolidated-quote.js +0 -465
  64. package/dist/destination-calldata.js +0 -71
  65. package/dist/ecosystems.js +0 -183
  66. package/dist/execution.js +0 -92
  67. package/dist/fee-type.js +0 -2
  68. package/dist/hyperliquid-execution.js +0 -98
  69. package/dist/image-links.js +0 -108
  70. package/dist/lifi-execution-guard.js +65 -172
  71. package/dist/near-intents-conformance.js +0 -110
  72. package/dist/near-intents-route.js +0 -149
  73. package/dist/near-intents.js +0 -562
  74. package/dist/origin-deposit.js +0 -56
  75. package/dist/pre-quote.js +0 -80
  76. package/dist/prices.js +0 -113
  77. package/dist/providers.js +0 -83
  78. package/dist/quote-fees.js +0 -80
  79. package/dist/referral.js +0 -75
  80. package/dist/relay-currencies.js +0 -31
  81. package/dist/relay-depository.js +52 -77
  82. package/dist/relay-quote.js +0 -394
  83. package/dist/route-steps.js +0 -100
  84. package/dist/routing/amounts.js +0 -83
  85. package/dist/routing/candidate-route.js +0 -73
  86. package/dist/routing/candidate.js +0 -46
  87. package/dist/routing/carrier-provider-key.js +0 -27
  88. package/dist/routing/carriers/omnibridge.js +0 -120
  89. package/dist/routing/carriers/pulsex-paths.js +0 -57
  90. package/dist/routing/carriers/pulsex-split.js +0 -92
  91. package/dist/routing/carriers/pulsex.js +0 -279
  92. package/dist/routing/carriers/wrap.js +0 -57
  93. package/dist/routing/composed-route-quality.js +0 -95
  94. package/dist/routing/entry-chain-anchor.js +0 -27
  95. package/dist/routing/format.js +0 -50
  96. package/dist/routing/index.js +0 -28
  97. package/dist/routing/producers.js +0 -854
  98. package/dist/routing/providers.js +0 -27
  99. package/dist/routing/search/compose.js +0 -56
  100. package/dist/routing/search/graph.js +0 -364
  101. package/dist/routing/search/plan-route-data.js +0 -508
  102. package/dist/routing/search/score.js +0 -344
  103. package/dist/routing/swap-transactions.js +0 -74
  104. package/dist/routing/usd-value.js +0 -12
  105. package/dist/settings.js +1 -456
  106. package/dist/swap-venues.js +0 -17
  107. package/dist/ton-connect.js +0 -82
  108. package/dist/ton-execution.js +0 -6
  109. package/dist/ton.js +0 -42
  110. package/dist/tron-execution.js +0 -145
  111. package/package.json +3 -3
@@ -2,28 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.findSwapVenue = exports.resolveSwapVenues = void 0;
4
4
  const config_js_1 = require("./config.js");
5
- /**
6
- * Merges caller venues over {@link defaultSwapVenues}. A chain present in
7
- * `overrides` replaces the default list for that chain. A chain absent from
8
- * `overrides` keeps its default list. An empty list switches swaps off on
9
- * that chain. Neither input is changed; the result is frozen.
10
- *
11
- * @param overrides - the caller's venues, or undefined for the defaults
12
- * @returns the venues to use
13
- */
14
5
  const resolveSwapVenues = (overrides) => {
15
6
  if (overrides === undefined)
16
7
  return config_js_1.defaultSwapVenues;
17
8
  return Object.freeze({ ...config_js_1.defaultSwapVenues, ...overrides });
18
9
  };
19
10
  exports.resolveSwapVenues = resolveSwapVenues;
20
- /**
21
- * Finds the venue on a chain that has the given router.
22
- *
23
- * @param venues - the venues to search
24
- * @param chainId - the numeric chain id
25
- * @param router - the router address, in any letter case
26
- * @returns the venue, or null when the chain has no venue with that router
27
- */
28
11
  const findSwapVenue = (venues, chainId, router) => venues[chainId]?.find((venue) => venue.router.toLowerCase() === router.toLowerCase()) ?? null;
29
12
  exports.findSwapVenue = findSwapVenue;
@@ -1,59 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.buildTonConnectRequest = exports.encodeTonAddress = exports.parseTonAddress = exports.tonConnectDefaultValidForSeconds = exports.tonConnectMainnetNetwork = void 0;
4
- /**
5
- * Executing a deposit on The Open Network, as pure data, with no TON library.
6
- *
7
- * This module imports nothing outside the package, so it loads anywhere: a
8
- * browser, Node, or a React Native app under Hermes, with no `Buffer` and no
9
- * polyfill. It uses only `atob` and `btoa`, which Hermes provides. The one TON
10
- * helper that needs `@ton/core`, the TEP-467 message hash, lives in
11
- * `@gibs/bridge-sdk/ton` instead.
12
- *
13
- * Relay describes a deposit as a list of internal messages carrying `to`,
14
- * `value`, `body` and a `bounce` flag. A connected wallet, however, is driven
15
- * through the TON Connect protocol, whose request shape is different in one way
16
- * that silently loses money:
17
- *
18
- * **TON Connect has no per-message `bounce` field.** A wallet derives whether a
19
- * message bounces from the FORM OF THE ADDRESS — the bounceable `EQ…` prefix or
20
- * the non-bounceable `UQ…` one. Passing Relay's address through unchanged while
21
- * dropping its `bounce: false` therefore sends a deposit to the bounceable form,
22
- * and the depository bounces the funds straight back to the sender. The transfer
23
- * looks like it succeeded and the route never fills.
24
- *
25
- * {@link buildTonConnectRequest} folds `bounce` into the address so the flag
26
- * cannot be dropped on the way to a wallet.
27
- *
28
- * Kept free of transport and of clock reads so it is fully testable: nothing
29
- * here signs, fetches, or calls `Date.now`. The caller supplies the deadline and
30
- * performs the request.
31
- *
32
- * The rules encoded here are those of Relay's own wallet adapter, which is the
33
- * only reference implementation of this mapping.
34
- */
35
- /**
36
- * The TON Connect network identifier for mainnet. Relay bridges only mainnet, so
37
- * a request is always tagged with this.
38
- */
39
4
  exports.tonConnectMainnetNetwork = '-239';
40
- /** How long a request stays valid by default, in seconds, matching Relay's adapter. */
41
5
  exports.tonConnectDefaultValidForSeconds = 300;
42
- /** Address tag byte for the bounceable (`EQ…`) form. */
43
6
  const bounceableTag = 0x11;
44
- /** Address tag byte for the non-bounceable (`UQ…`) form. */
45
7
  const nonBounceableTag = 0x51;
46
- /** Bit set on the tag byte for testnet-only addresses (`kQ…` / `0Q…`). */
47
8
  const testnetTagFlag = 0x80;
48
- /** A friendly address is a 36-byte structure: tag, workchain, hash, checksum. */
49
9
  const friendlyAddressByteLength = 36;
50
- /** An account identifier is always 32 bytes, in every address form. */
51
10
  const accountHashByteLength = 32;
52
- /**
53
- * Cyclic redundancy check (16-bit, the XModem variant) over an address body.
54
- * The Open Network appends it to every friendly address, and a re-encoded
55
- * address whose checksum is not recomputed is rejected by wallets as malformed.
56
- */
57
11
  const checksum = (data) => {
58
12
  let remainder = 0;
59
13
  for (const byte of data) {
@@ -65,7 +19,6 @@ const checksum = (data) => {
65
19
  }
66
20
  return remainder;
67
21
  };
68
- /** Decodes the url-safe base64 alphabet the friendly address form uses. */
69
22
  const decodeBase64Url = (value) => {
70
23
  const standard = value.replaceAll('-', '+').replaceAll('_', '/');
71
24
  const padded = standard.padEnd(Math.ceil(standard.length / 4) * 4, '=');
@@ -77,7 +30,6 @@ const decodeBase64Url = (value) => {
77
30
  return null;
78
31
  }
79
32
  };
80
- /** Encodes bytes back into the url-safe, unpadded base64 form. */
81
33
  const encodeBase64Url = (bytes) => {
82
34
  let binary = '';
83
35
  for (const byte of bytes) {
@@ -103,7 +55,6 @@ const parseRawAddress = (value) => {
103
55
  }
104
56
  hash[index] = byte;
105
57
  }
106
- // The raw form carries no network tag, so mainnet is the only safe assumption.
107
58
  return { workchain, hash, testOnly: false };
108
59
  };
109
60
  const parseFriendlyAddress = (value) => {
@@ -112,8 +63,6 @@ const parseFriendlyAddress = (value) => {
112
63
  return null;
113
64
  }
114
65
  const body = bytes.subarray(0, friendlyAddressByteLength - 2);
115
- // Every index below is in range: the length was checked to be exactly
116
- // `friendlyAddressByteLength` above, so the non-null assertions are sound.
117
66
  const stated = (bytes[friendlyAddressByteLength - 2] << 8) | bytes[friendlyAddressByteLength - 1];
118
67
  if (checksum(body) !== stated) {
119
68
  return null;
@@ -125,30 +74,13 @@ const parseFriendlyAddress = (value) => {
125
74
  }
126
75
  const workchainByte = bytes[1];
127
76
  return {
128
- // The masterchain is workchain -1, which travels as the byte 0xff.
129
77
  workchain: workchainByte === 0xff ? -1 : workchainByte,
130
78
  hash: bytes.slice(2, 2 + accountHashByteLength),
131
79
  testOnly: (tag & testnetTagFlag) !== 0,
132
80
  };
133
81
  };
134
- /**
135
- * Parses either address form The Open Network uses.
136
- *
137
- * @param value - a friendly (`EQ…`/`UQ…`) or raw (`0:…`) address
138
- * @returns the address parts, or null when it is neither form or fails its checksum
139
- */
140
82
  const parseTonAddress = (value) => value.includes(':') ? parseRawAddress(value) : parseFriendlyAddress(value);
141
83
  exports.parseTonAddress = parseTonAddress;
142
- /**
143
- * Re-encodes an address into the friendly form matching a bounce setting.
144
- *
145
- * This is the whole point of the module: the bounce flag has nowhere else to
146
- * live in a TON Connect request, so it has to be carried by the address itself.
147
- *
148
- * @param address - the address in either form
149
- * @param options.bounceable - whether the message may bounce back to the sender
150
- * @returns the friendly address, or null when the input cannot be parsed
151
- */
152
84
  const encodeTonAddress = (address, { bounceable }) => {
153
85
  const parsed = (0, exports.parseTonAddress)(address);
154
86
  if (parsed === null) {
@@ -165,17 +97,6 @@ const encodeTonAddress = (address, { bounceable }) => {
165
97
  return encodeBase64Url(bytes);
166
98
  };
167
99
  exports.encodeTonAddress = encodeTonAddress;
168
- /**
169
- * Builds the TON Connect request for a deposit.
170
- *
171
- * @param deposit - the parsed origin deposit
172
- * @param options.validUntil - unix seconds after which the request expires.
173
- * Supplied by the caller rather than read from a clock here so the transform
174
- * stays pure; {@link tonConnectDefaultValidForSeconds} is the usual offset.
175
- * @returns the request, or null when the deposit carries no messages or any
176
- * destination address cannot be re-encoded — never a request whose bounce
177
- * setting has been silently dropped
178
- */
179
100
  const buildTonConnectRequest = (deposit, { validUntil }) => {
180
101
  if (deposit.messages.length === 0) {
181
102
  return null;
@@ -183,8 +104,6 @@ const buildTonConnectRequest = (deposit, { validUntil }) => {
183
104
  const messages = [];
184
105
  for (const message of deposit.messages) {
185
106
  const address = (0, exports.encodeTonAddress)(message.to, { bounceable: message.bounce });
186
- // Refuse rather than fall back to the unencoded address: the fallback is
187
- // exactly the bounce-losing behaviour this module exists to prevent.
188
107
  if (address === null) {
189
108
  return null;
190
109
  }
@@ -194,7 +113,6 @@ const buildTonConnectRequest = (deposit, { validUntil }) => {
194
113
  ...(message.body ? { payload: message.body } : {}),
195
114
  });
196
115
  }
197
- // `messages[0]` is present: the empty case returned null above.
198
116
  const from = deposit.messages[0].from;
199
117
  return {
200
118
  validUntil,
@@ -14,10 +14,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- /**
18
- * The original name of `@gibs/bridge-sdk/ton`, kept so existing imports work.
19
- *
20
- * @deprecated Import from `@gibs/bridge-sdk/ton` for the full TON surface, or
21
- * from `@gibs/bridge-sdk/ton-connect` for the helpers that need no TON library.
22
- */
23
17
  __exportStar(require("./ton.js"), exports);
package/dist/cjs/ton.js CHANGED
@@ -16,59 +16,18 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.tonExternalMessageHash = void 0;
18
18
  const core_1 = require("@ton/core");
19
- /**
20
- * Everything the bridge SDK offers for The Open Network, in one entry point.
21
- *
22
- * It re-exports the pure TON Connect helpers from `./ton-connect.js` and adds
23
- * {@link tonExternalMessageHash}, the only helper that needs `@ton/core`.
24
- *
25
- * Kept apart from the root entry point on purpose. `@ton/core` uses Node's
26
- * `Buffer`, and its `@ton/crypto` dependency resolves, under React Native, to a
27
- * build that requires `expo-crypto`. An application that bridges only between
28
- * Ethereum-style chains never imports this file, so it never pays for either.
29
- */
30
19
  __exportStar(require("./ton-connect.js"), exports);
31
- /**
32
- * Derives the transaction identifier from a wallet's `sendTransaction` response.
33
- *
34
- * A wallet answers with a `boc`: the base64 bag-of-cells of the signed
35
- * external-in message it broadcast — NOT the resulting transaction, and NOT a
36
- * hash. The identifier explorers and indexers (toncenter, TonAPI) resolve a
37
- * transaction by is the hash of that external message, but it must be the
38
- * NORMALIZED hash of TEP-467, not the hash of the bytes the wallet happened to
39
- * send.
40
- *
41
- * The distinction is the whole point, and getting it wrong loses a resume record
42
- * for real funds. An external-in message can be serialized several equivalent
43
- * ways — a wallet may or may not include its own `src`, may set a non-zero
44
- * `import_fee`, may attach a `stateInit`, may store the body inline or as a
45
- * reference. The raw cell hash changes with each of those wallet-specific
46
- * choices, so it frequently does NOT match what an indexer keyed the same
47
- * transaction under. TEP-467 rebuilds the message with those variable fields
48
- * stripped (`src` to none, `import_fee` to zero, `init` dropped, body forced to a
49
- * reference) so the hash is stable across wallets and matches the indexers.
50
- *
51
- * @param boc - the wallet's base64 `boc` field from `sendTransaction`
52
- * @returns the 64-character hex normalized hash, or null when the input is not a
53
- * parseable external-in message
54
- */
55
20
  const tonExternalMessageHash = (boc) => {
56
21
  try {
57
22
  const message = (0, core_1.loadMessage)(core_1.Cell.fromBase64(boc).beginParse());
58
- // Only an external-in message has a normalized form; an internal message or
59
- // a bare cell is not the wallet's broadcast envelope and cannot be keyed.
60
23
  if (message.info.type !== 'external-in') {
61
24
  return null;
62
25
  }
63
26
  const normalized = {
64
27
  ...message,
65
- // Dropped by TEP-467 so a wallet-attached stateInit does not move the hash.
66
28
  init: null,
67
- // `src` to addr_none (undefined) and the fee to zero: both are the sender's
68
- // to choose and neither is part of what identifies the message.
69
29
  info: { ...message.info, src: undefined, importFee: 0n },
70
30
  };
71
- // `forceRef` stores the body as a reference, as the normalized form requires.
72
31
  return (0, core_1.beginCell)()
73
32
  .store((0, core_1.storeMessage)(normalized, { forceRef: true }))
74
33
  .endCell()
@@ -76,7 +35,6 @@ const tonExternalMessageHash = (boc) => {
76
35
  .toString('hex');
77
36
  }
78
37
  catch {
79
- // A malformed base64 payload or a cell tree that is not a message at all.
80
38
  return null;
81
39
  }
82
40
  };
@@ -1,72 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.readBroadcastResponse = exports.readTriggerSmartContractResponse = exports.tronErrorMessage = exports.buildTriggerSmartContractRequest = exports.isSameTronAccount = exports.normalizeTronHexAddress = exports.maximumTronFeeLimitSun = exports.defaultTronFeeLimitSun = exports.tronTriggerSmartContractPath = void 0;
4
- /**
5
- * Executing a deposit on Tron, as pure data.
6
- *
7
- * Relay does not return a broadcastable Tron transaction. It returns the
8
- * *parameters* of a `TriggerSmartContract` call — owner, contract, call value
9
- * and calldata — and nothing else. A Tron transaction additionally needs a
10
- * reference block, an expiration and a fee limit, none of which Relay supplies.
11
- * Those are produced by asking a full node to build the transaction, which is
12
- * what {@link buildTriggerSmartContractRequest} constructs the body for. The
13
- * node answers with an UNSIGNED transaction; the wallet signs it and a second
14
- * call broadcasts it.
15
- *
16
- * Three details of that exchange lose money or mislead if handled naively:
17
- *
18
- * **The `visible` flag defaults to true.** A node reads addresses as base58
19
- * unless told otherwise, but Relay returns them as hex with Tron's `41` prefix.
20
- * Omitting the flag therefore hands base58-parsing a hex string. The request
21
- * built here always states `visible: false` rather than relying on a default
22
- * that is the opposite of what the payload contains.
23
- *
24
- * **`fee_limit` is required and Relay omits it.** It caps the energy the caller
25
- * will pay for. Set too low, the call runs out of energy, reverts, and the
26
- * energy already burned is NOT refunded — the deposit fails and costs the user
27
- * anyway.
28
- *
29
- * **A rejected call still answers HTTP 200**, with the reason hex-encoded in
30
- * `result.message`. Reading the status code alone reports a failed deposit as a
31
- * success, and printing the message unmodified shows the user a wall of hex.
32
- * {@link tronErrorMessage} decodes it.
33
- *
34
- * Kept free of transport and of clock reads so it is fully testable: nothing
35
- * here signs, fetches, or calls `Date.now`. The caller performs the requests.
36
- */
37
- /** Path of the full-node endpoint that builds an unsigned contract call. */
38
4
  exports.tronTriggerSmartContractPath = '/wallet/triggersmartcontract';
39
- /**
40
- * The fee limit used when a caller states none, in sun (1 TRX = 1,000,000 sun).
41
- *
42
- * Thirty TRX, matching Relay's own wallet adapter, which is the only reference
43
- * implementation of this deposit path. It is an upper bound rather than a
44
- * charge: unused energy is not taken, so the cost of setting it generously is
45
- * only that the wallet shows a larger worst case.
46
- */
47
5
  exports.defaultTronFeeLimitSun = 30_000_000;
48
- /**
49
- * The largest fee limit a node accepts, in sun — 15,000 TRX. Documented as a
50
- * hard protocol cap, so a request above it is rejected outright rather than
51
- * clamped.
52
- */
53
6
  exports.maximumTronFeeLimitSun = 15_000_000_000;
54
- /**
55
- * Tron's `41` address prefix, the hex form's equivalent of the base58 `T`.
56
- */
57
7
  const tronHexAddressPrefix = '41';
58
- /** A hex address is the prefix byte plus a twenty-byte account identifier. */
59
8
  const tronHexAddressLength = 42;
60
- /**
61
- * Normalizes a Tron hex address for comparison.
62
- *
63
- * Wallets and quotes disagree on casing, and Relay's payload is not guaranteed
64
- * to match what a wallet reports even when both name the same account.
65
- *
66
- * @param value - an address in Tron's `41`-prefixed hex form, in any casing,
67
- * optionally written with a `0x` prefix
68
- * @returns the lowercase `41` form, or null when the value is not that form
69
- */
70
9
  const normalizeTronHexAddress = (value) => {
71
10
  const withoutPrefix = value.trim().replace(/^0x/i, '').toLowerCase();
72
11
  if (withoutPrefix.length !== tronHexAddressLength) {
@@ -78,51 +17,14 @@ const normalizeTronHexAddress = (value) => {
78
17
  return /^[0-9a-f]+$/.test(withoutPrefix) ? withoutPrefix : null;
79
18
  };
80
19
  exports.normalizeTronHexAddress = normalizeTronHexAddress;
81
- /**
82
- * Whether two Tron hex addresses name the same account.
83
- *
84
- * Used to check a deposit's owner against the connected wallet before signing.
85
- * A mismatch means the quote was built for a different account, and signing it
86
- * would spend from an account the user did not choose — or simply fail after
87
- * the user has already approved.
88
- *
89
- * @param left - an address in Tron's `41`-prefixed hex form
90
- * @param right - an address in the same form
91
- * @returns true only when both parse and name the same account
92
- */
93
20
  const isSameTronAccount = (left, right) => {
94
21
  const normalizedLeft = (0, exports.normalizeTronHexAddress)(left);
95
22
  const normalizedRight = (0, exports.normalizeTronHexAddress)(right);
96
23
  return normalizedLeft !== null && normalizedLeft === normalizedRight;
97
24
  };
98
25
  exports.isSameTronAccount = isSameTronAccount;
99
- /**
100
- * Strips the `0x` prefix Tron calldata never carries.
101
- *
102
- * Relay documents this field as bare hex, but its own adapter strips the prefix
103
- * defensively, and a prefixed value is parsed by a node as calldata beginning
104
- * with the bytes `0x` rather than being rejected — a silently wrong call.
105
- */
106
26
  const bareHex = (value) => value.replace(/^0x/i, '').toLowerCase();
107
- /**
108
- * Whether a numeric amount survives the trip through JSON as an exact integer.
109
- *
110
- * Sun amounts are 64-bit on the wire but JSON carries them as doubles, so a
111
- * large enough value would be silently rounded — into a different amount of
112
- * money than the one that was quoted.
113
- */
114
27
  const isExactInteger = (value) => value >= 0n && value <= BigInt(Number.MAX_SAFE_INTEGER);
115
- /**
116
- * Builds the body that asks a full node to construct the unsigned deposit.
117
- *
118
- * @param deposit - the parsed origin deposit
119
- * @param options.feeLimitSun - the energy spending cap in sun; defaults to
120
- * {@link defaultTronFeeLimitSun}
121
- * @returns the request body, or null when the deposit names an address that is
122
- * not Tron hex, carries a call value that cannot be represented exactly, or
123
- * the fee limit is outside what a node accepts — never a body that would be
124
- * built against a default `visible` the payload contradicts
125
- */
126
28
  const buildTriggerSmartContractRequest = (deposit, { feeLimitSun = exports.defaultTronFeeLimitSun } = {}) => {
127
29
  const ownerAddress = (0, exports.normalizeTronHexAddress)(deposit.ownerAddress);
128
30
  const contractAddress = (0, exports.normalizeTronHexAddress)(deposit.contractAddress);
@@ -145,14 +47,6 @@ const buildTriggerSmartContractRequest = (deposit, { feeLimitSun = exports.defau
145
47
  };
146
48
  };
147
49
  exports.buildTriggerSmartContractRequest = buildTriggerSmartContractRequest;
148
- /**
149
- * Decodes a node's hex-encoded failure message.
150
- *
151
- * A node reports why it refused a call in `result.message`, hex-encoded — the
152
- * bytes `4e6f20636f6e7472616374…` rather than "No contract or not a valid smart
153
- * contract". Broadcast failures report plain text in the same field, so both
154
- * are handled and a value that is not hex is passed through unchanged.
155
- */
156
50
  const decodeTronMessage = (value) => {
157
51
  const trimmed = value.trim();
158
52
  if (trimmed.length === 0 || trimmed.length % 2 !== 0 || !/^[0-9a-fA-F]+$/.test(trimmed)) {
@@ -162,26 +56,16 @@ const decodeTronMessage = (value) => {
162
56
  for (let index = 0; index < trimmed.length; index += 2) {
163
57
  decoded += String.fromCharCode(Number.parseInt(trimmed.slice(index, index + 2), 16));
164
58
  }
165
- // A hex string that decodes to control characters was a number, not a
166
- // message — return the original rather than a string of unprintable bytes.
167
59
  return /^[\x20-\x7e]*$/.test(decoded) ? decoded : trimmed;
168
60
  };
169
61
  const asRecord = (value) => typeof value === 'object' && value !== null && !Array.isArray(value)
170
62
  ? value
171
63
  : null;
172
- /**
173
- * Extracts a node's failure reason from either endpoint's response.
174
- *
175
- * @param payload - the parsed response body
176
- * @returns the decoded message, or null when the response reports no failure
177
- */
178
64
  const tronErrorMessage = (payload) => {
179
65
  const body = asRecord(payload);
180
66
  if (body === null) {
181
67
  return null;
182
68
  }
183
- // The build endpoint nests its outcome under `result`; the broadcast endpoint
184
- // reports at the top level.
185
69
  const nested = asRecord(body.result);
186
70
  const message = nested?.message ?? body.message;
187
71
  if (typeof message !== 'string') {
@@ -191,17 +75,6 @@ const tronErrorMessage = (payload) => {
191
75
  return decoded.length === 0 ? null : decoded;
192
76
  };
193
77
  exports.tronErrorMessage = tronErrorMessage;
194
- /**
195
- * Reads the unsigned transaction out of a build response.
196
- *
197
- * The response carries the transaction at the top level alongside a `result`
198
- * object stating whether the build succeeded, so the presence of a `txID` is
199
- * not on its own evidence of success.
200
- *
201
- * @param payload - the parsed `/wallet/triggersmartcontract` response
202
- * @returns the unsigned transaction to hand a wallet, or null when the node
203
- * refused the call
204
- */
205
78
  const readTriggerSmartContractResponse = (payload) => {
206
79
  const body = asRecord(payload);
207
80
  if (body === null) {
@@ -218,24 +91,6 @@ const readTriggerSmartContractResponse = (payload) => {
218
91
  return transaction;
219
92
  };
220
93
  exports.readTriggerSmartContractResponse = readTriggerSmartContractResponse;
221
- /**
222
- * Reads the transaction identifier out of a broadcast response.
223
- *
224
- * GOTCHA: a rejected broadcast answers HTTP 200, and `result` is OMITTED rather
225
- * than set to false. Testing `result === false` therefore never fires, and
226
- * trusting the status code records a deposit that never entered a block. Only
227
- * an explicit `result: true` is accepted here.
228
- *
229
- * The identifier is read from `txid` where a node reports it, falling back to
230
- * the echoed transaction's `txID`. The two spellings differ by casing and by
231
- * position: a node answers `txid`, while a wallet library that echoes the
232
- * transaction it broadcast carries `txID` inside it. Accepting only the first
233
- * would report an accepted broadcast as a failure whenever the caller is one of
234
- * those libraries.
235
- *
236
- * @param payload - the parsed `/wallet/broadcasttransaction` response
237
- * @returns the transaction identifier, or null when the broadcast was refused
238
- */
239
94
  const readBroadcastResponse = (payload) => {
240
95
  const body = asRecord(payload);
241
96
  if (body === null || body.result !== true) {
package/dist/claims.js CHANGED
@@ -1,12 +1,6 @@
1
1
  import { encodeFunctionData, isHex, numberToHex } from 'viem';
2
2
  import * as abis from './abis.js';
3
3
  const strip0x = (input) => input.replace(/^0x/, '');
4
- /**
5
- * Splits one 65-byte validator signature into its `v`, `r` and `s` parts.
6
- *
7
- * @param rawSignature - the signature as the indexer stores it, with or without a `0x` prefix
8
- * @returns the three parts, hex without prefixes
9
- */
10
4
  export const signatureToVRS = (rawSignature) => {
11
5
  const signature = strip0x(rawSignature);
12
6
  const word = 32;
@@ -17,13 +11,6 @@ export const signatureToVRS = (rawSignature) => {
17
11
  const v = signature.slice(word4);
18
12
  return { v, r, s };
19
13
  };
20
- /**
21
- * Packs signatures in the layout the bridge's `executeSignatures` reads: one
22
- * count byte, then every `v`, then every `r`, then every `s`.
23
- *
24
- * @param signatures - the split signatures, in the order the validators signed
25
- * @returns the packed signatures as one hex string
26
- */
27
14
  export const packSignatures = (signatures) => {
28
15
  const length = strip0x(numberToHex(signatures.length));
29
16
  const countByte = length.length === 1 ? `0${length}` : length;
@@ -32,43 +19,16 @@ export const packSignatures = (signatures) => {
32
19
  const s = signatures.map((signature) => signature.s).join('');
33
20
  return `0x${countByte}${v}${r}${s}`;
34
21
  };
35
- /**
36
- * The calldata for a release that pays no delivery tip: a direct call to the
37
- * destination bridge.
38
- *
39
- * @param options.encodedData - the bridge message, `UserRequest.encodedData`
40
- * @param options.encodedSignatures - the output of {@link packSignatures}
41
- * @returns the calldata for `safeExecuteSignaturesWithAutoGasLimit`
42
- */
43
22
  export const encodeReleaseWithoutTipData = ({ encodedData, encodedSignatures, }) => encodeFunctionData({
44
23
  abi: abis.relayTokensDirect,
45
24
  functionName: 'safeExecuteSignaturesWithAutoGasLimit',
46
25
  args: [encodedData, encodedSignatures],
47
26
  });
48
- /**
49
- * The calldata for a release sent through the pathway's destination output
50
- * router, the path a fee-director (delivery) request uses.
51
- *
52
- * @param options.validator - the pathway's validator contract
53
- * @param options.encodedData - the bridge message, `UserRequest.encodedData`
54
- * @param options.encodedSignatures - the output of {@link packSignatures}
55
- * @returns the calldata for the router's `safeExecuteSignaturesWithAutoGasLimit`
56
- */
57
27
  export const encodeReleaseToRouterData = ({ validator, encodedData, encodedSignatures, }) => encodeFunctionData({
58
28
  abi: abis.outputRouter,
59
29
  functionName: 'safeExecuteSignaturesWithAutoGasLimit',
60
30
  args: [validator, encodedData, encodedSignatures],
61
31
  });
62
- /**
63
- * The one place a claim's target and calldata come from. The interface's
64
- * release hook and {@link buildClaimTransaction} both call it.
65
- *
66
- * @param options.encodedData - the bridge message
67
- * @param options.signatures - the raw validator signatures, in signing order
68
- * @param options.destinationAmbAddress - the destination bridge, used by the `direct` route
69
- * @param options.via - which contract receives the claim
70
- * @returns the target contract and the calldata
71
- */
72
32
  export const claimCall = ({ encodedData, signatures, destinationAmbAddress, via, }) => {
73
33
  const encodedSignatures = packSignatures(signatures.map(signatureToVRS));
74
34
  if (via.kind === 'router') {
@@ -81,24 +41,6 @@ export const claimCall = ({ encodedData, signatures, destinationAmbAddress, via,
81
41
  };
82
42
  const isSignatureList = (value) => Array.isArray(value) && value.every((entry) => typeof entry === 'string' && isHex(entry));
83
43
  const refused = (refusal) => ({ kind: 'refused', refusal });
84
- /**
85
- * Builds the manual-claim transaction for one bridge request, or refuses with
86
- * a typed reason.
87
- *
88
- * The checks run in this order: request type, delivery, signing, then the
89
- * stored signature count. A delivered request is refused before the signing
90
- * check, because delivery also sets `finishedSigning`.
91
- *
92
- * ASSUMPTION: the signatures are only complete when every validator sent
93
- * `submitSignature` directly to the home bridge. The indexer drops a
94
- * signature sent any other way; see this module's head note. This builder
95
- * catches the drop by comparing the stored list with the required-signature
96
- * threshold, or with `confirmedSignatures` when the record carries no threshold.
97
- *
98
- * @param options.request - the indexer's `UserRequest` record
99
- * @param options.via - the claim target; see {@link ClaimRoute}
100
- * @returns a `claim` plan whose transaction runs on the destination chain, or a refusal
101
- */
102
44
  export const buildClaimTransaction = ({ request, via, }) => {
103
45
  if (request.type !== 'signature')
104
46
  return refused({ reason: 'wrong-type', type: request.type });
@@ -131,8 +73,6 @@ export const buildClaimTransaction = ({ request, via, }) => {
131
73
  to,
132
74
  data,
133
75
  value: 0n,
134
- // The calldata itself asks the bridge to pick its own gas limit
135
- // (`safeExecuteSignaturesWithAutoGasLimit`); the wallet estimates the rest.
136
76
  gasLimit: null,
137
77
  waitForReceipt: false,
138
78
  },