@gibs/bridge-sdk 1.13.0 → 1.17.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 (217) hide show
  1. package/README.md +244 -18
  2. package/abis/package.json +6 -0
  3. package/bridge-limits/package.json +6 -0
  4. package/chain-info/package.json +6 -0
  5. package/chain-names/package.json +6 -0
  6. package/chains/package.json +6 -0
  7. package/claims/package.json +6 -0
  8. package/config/package.json +6 -0
  9. package/consolidated-quote/package.json +6 -0
  10. package/destination-calldata/package.json +6 -0
  11. package/dist/chain-info.d.ts +1 -1
  12. package/dist/chain-info.js +11 -12
  13. package/dist/chains.d.ts +25 -0
  14. package/dist/chains.js +55 -20
  15. package/dist/cjs/abis.d.ts +1 -0
  16. package/dist/cjs/abis.js +19 -0
  17. package/dist/cjs/bridge-limits.d.ts +103 -0
  18. package/dist/cjs/bridge-limits.js +89 -0
  19. package/dist/cjs/chain-info.d.ts +169 -0
  20. package/dist/cjs/chain-info.js +452 -0
  21. package/dist/cjs/chain-names.d.ts +160 -0
  22. package/dist/cjs/chain-names.js +207 -0
  23. package/dist/cjs/chains.d.ts +90 -0
  24. package/dist/cjs/chains.js +357 -0
  25. package/dist/cjs/claims.d.ts +198 -0
  26. package/dist/cjs/claims.js +182 -0
  27. package/dist/cjs/config.d.ts +240 -0
  28. package/dist/cjs/config.js +537 -0
  29. package/dist/cjs/consolidated-quote.d.ts +648 -0
  30. package/dist/cjs/consolidated-quote.js +1048 -0
  31. package/dist/cjs/destination-calldata.d.ts +118 -0
  32. package/dist/cjs/destination-calldata.js +156 -0
  33. package/dist/cjs/ecosystems.d.ts +217 -0
  34. package/dist/cjs/ecosystems.js +298 -0
  35. package/dist/cjs/execution.d.ts +346 -0
  36. package/dist/cjs/execution.js +468 -0
  37. package/dist/cjs/fee-type.d.ts +10 -0
  38. package/dist/cjs/fee-type.js +10 -0
  39. package/dist/cjs/hyperliquid-execution.d.ts +152 -0
  40. package/dist/cjs/hyperliquid-execution.js +175 -0
  41. package/dist/cjs/image-links.d.ts +117 -0
  42. package/dist/cjs/image-links.js +153 -0
  43. package/dist/cjs/index.d.ts +23 -0
  44. package/dist/cjs/index.js +39 -0
  45. package/dist/cjs/lifi-execution-guard.d.ts +210 -0
  46. package/dist/cjs/lifi-execution-guard.js +409 -0
  47. package/dist/cjs/near-intents-conformance.d.ts +85 -0
  48. package/dist/cjs/near-intents-conformance.js +337 -0
  49. package/dist/cjs/near-intents-route.d.ts +47 -0
  50. package/dist/cjs/near-intents-route.js +303 -0
  51. package/dist/cjs/near-intents.d.ts +524 -0
  52. package/dist/cjs/near-intents.js +1071 -0
  53. package/dist/cjs/origin-deposit.d.ts +326 -0
  54. package/dist/cjs/origin-deposit.js +82 -0
  55. package/dist/cjs/package.json +3 -0
  56. package/dist/cjs/pre-quote.d.ts +198 -0
  57. package/dist/cjs/pre-quote.js +180 -0
  58. package/dist/cjs/prices.d.ts +107 -0
  59. package/dist/cjs/prices.js +172 -0
  60. package/dist/cjs/providers.d.ts +238 -0
  61. package/dist/cjs/providers.js +171 -0
  62. package/dist/cjs/quote-fees.d.ts +102 -0
  63. package/dist/cjs/quote-fees.js +201 -0
  64. package/dist/cjs/referral.d.ts +85 -0
  65. package/dist/cjs/referral.js +85 -0
  66. package/dist/cjs/relay-currencies.d.ts +47 -0
  67. package/dist/cjs/relay-currencies.js +95 -0
  68. package/dist/cjs/relay-depository.d.ts +2 -0
  69. package/dist/cjs/relay-depository.js +85 -0
  70. package/dist/cjs/relay-quote.d.ts +301 -0
  71. package/dist/cjs/relay-quote.js +996 -0
  72. package/dist/cjs/route-steps.d.ts +138 -0
  73. package/dist/cjs/route-steps.js +310 -0
  74. package/dist/cjs/routing/amounts.d.ts +80 -0
  75. package/dist/cjs/routing/amounts.js +126 -0
  76. package/dist/cjs/routing/candidate-route.d.ts +43 -0
  77. package/dist/cjs/routing/candidate-route.js +50 -0
  78. package/dist/cjs/routing/candidate.d.ts +237 -0
  79. package/dist/cjs/routing/candidate.js +100 -0
  80. package/dist/cjs/routing/carriers/ask-answer.d.ts +77 -0
  81. package/dist/cjs/routing/carriers/ask-answer.js +2 -0
  82. package/dist/cjs/routing/carriers/omnibridge.d.ts +137 -0
  83. package/dist/cjs/routing/carriers/omnibridge.js +459 -0
  84. package/dist/cjs/routing/carriers/pulsex-paths.d.ts +80 -0
  85. package/dist/cjs/routing/carriers/pulsex-paths.js +97 -0
  86. package/dist/cjs/routing/carriers/pulsex-split.d.ts +175 -0
  87. package/dist/cjs/routing/carriers/pulsex-split.js +193 -0
  88. package/dist/cjs/routing/carriers/pulsex.d.ts +159 -0
  89. package/dist/cjs/routing/carriers/pulsex.js +565 -0
  90. package/dist/cjs/routing/carriers/wrap.d.ts +25 -0
  91. package/dist/cjs/routing/carriers/wrap.js +119 -0
  92. package/dist/cjs/routing/composed-route-quality.d.ts +125 -0
  93. package/dist/cjs/routing/composed-route-quality.js +144 -0
  94. package/dist/cjs/routing/entry-chain-anchor.d.ts +88 -0
  95. package/dist/cjs/routing/entry-chain-anchor.js +59 -0
  96. package/dist/cjs/routing/format.d.ts +31 -0
  97. package/dist/cjs/routing/format.js +64 -0
  98. package/dist/cjs/routing/index.d.ts +38 -0
  99. package/dist/cjs/routing/index.js +134 -0
  100. package/dist/cjs/routing/producers.d.ts +770 -0
  101. package/dist/cjs/routing/producers.js +1617 -0
  102. package/dist/cjs/routing/providers.d.ts +31 -0
  103. package/dist/cjs/routing/providers.js +48 -0
  104. package/dist/cjs/routing/route-data.d.ts +355 -0
  105. package/dist/cjs/routing/route-data.js +2 -0
  106. package/dist/cjs/routing/search/compose.d.ts +168 -0
  107. package/dist/cjs/routing/search/compose.js +104 -0
  108. package/dist/cjs/routing/search/graph.d.ts +668 -0
  109. package/dist/cjs/routing/search/graph.js +461 -0
  110. package/dist/cjs/routing/search/plan-route-data.d.ts +269 -0
  111. package/dist/cjs/routing/search/plan-route-data.js +848 -0
  112. package/dist/cjs/routing/search/score.d.ts +356 -0
  113. package/dist/cjs/routing/search/score.js +445 -0
  114. package/dist/cjs/routing/swap-transactions.d.ts +91 -0
  115. package/dist/cjs/routing/swap-transactions.js +131 -0
  116. package/dist/cjs/routing/usd-value.d.ts +17 -0
  117. package/dist/cjs/routing/usd-value.js +29 -0
  118. package/dist/cjs/settings.d.ts +785 -0
  119. package/dist/cjs/settings.js +1074 -0
  120. package/dist/cjs/ton-connect.d.ts +98 -0
  121. package/dist/cjs/ton-connect.js +206 -0
  122. package/dist/cjs/ton-execution.d.ts +7 -0
  123. package/dist/cjs/ton-execution.js +23 -0
  124. package/dist/cjs/ton.d.ts +37 -0
  125. package/dist/cjs/ton.js +83 -0
  126. package/dist/cjs/tron-execution.d.ts +146 -0
  127. package/dist/cjs/tron-execution.js +248 -0
  128. package/dist/cjs/types.d.ts +51 -0
  129. package/dist/cjs/types.js +2 -0
  130. package/dist/claims.d.ts +198 -0
  131. package/dist/claims.js +140 -0
  132. package/dist/config.d.ts +24 -0
  133. package/dist/config.js +39 -5
  134. package/dist/consolidated-quote.d.ts +109 -15
  135. package/dist/consolidated-quote.js +310 -52
  136. package/dist/execution.d.ts +346 -0
  137. package/dist/execution.js +428 -0
  138. package/dist/hyperliquid-execution.js +2 -3
  139. package/dist/index.d.ts +3 -0
  140. package/dist/index.js +3 -0
  141. package/dist/lifi-execution-guard.d.ts +13 -2
  142. package/dist/lifi-execution-guard.js +4 -0
  143. package/dist/near-intents.js +2 -3
  144. package/dist/pre-quote.d.ts +6 -6
  145. package/dist/pre-quote.js +10 -14
  146. package/dist/providers.d.ts +17 -0
  147. package/dist/providers.js +6 -0
  148. package/dist/referral.d.ts +12 -4
  149. package/dist/referral.js +12 -4
  150. package/dist/relay-depository.d.ts +2 -0
  151. package/dist/relay-depository.js +82 -0
  152. package/dist/relay-quote.js +2 -3
  153. package/dist/routing/candidate.d.ts +3 -3
  154. package/dist/routing/candidate.js +3 -3
  155. package/dist/routing/carriers/ask-answer.d.ts +19 -0
  156. package/dist/routing/carriers/omnibridge.js +23 -21
  157. package/dist/routing/carriers/pulsex-paths.d.ts +80 -0
  158. package/dist/routing/carriers/pulsex-paths.js +92 -0
  159. package/dist/routing/carriers/pulsex-split.d.ts +175 -0
  160. package/dist/routing/carriers/pulsex-split.js +185 -0
  161. package/dist/routing/carriers/pulsex.d.ts +69 -21
  162. package/dist/routing/carriers/pulsex.js +184 -65
  163. package/dist/routing/composed-route-quality.d.ts +28 -6
  164. package/dist/routing/composed-route-quality.js +36 -5
  165. package/dist/routing/entry-chain-anchor.d.ts +1 -1
  166. package/dist/routing/entry-chain-anchor.js +1 -1
  167. package/dist/routing/index.d.ts +7 -3
  168. package/dist/routing/index.js +7 -3
  169. package/dist/routing/producers.js +1 -1
  170. package/dist/routing/providers.d.ts +5 -0
  171. package/dist/routing/providers.js +5 -0
  172. package/dist/routing/search/graph.d.ts +29 -0
  173. package/dist/routing/search/plan-route-data.d.ts +25 -0
  174. package/dist/routing/search/plan-route-data.js +43 -7
  175. package/dist/routing/search/score.d.ts +33 -1
  176. package/dist/routing/search/score.js +41 -6
  177. package/dist/routing/swap-transactions.d.ts +91 -0
  178. package/dist/routing/swap-transactions.js +125 -0
  179. package/dist/settings.d.ts +94 -1
  180. package/dist/settings.js +95 -3
  181. package/dist/ton-connect.d.ts +98 -0
  182. package/dist/ton-connect.js +200 -0
  183. package/dist/ton-execution.d.ts +4 -114
  184. package/dist/ton-execution.js +4 -244
  185. package/dist/ton.d.ts +37 -0
  186. package/dist/ton.js +65 -0
  187. package/docs/examples/example-a-ether-to-pulse.ts +300 -0
  188. package/docs/examples/example-b-token-pulsechain-to-ethereum.ts +270 -0
  189. package/docs/examples/shared.ts +261 -0
  190. package/docs/examples/tsconfig.json +18 -0
  191. package/docs/integration-guide.md +617 -0
  192. package/ecosystems/package.json +6 -0
  193. package/execution/package.json +6 -0
  194. package/fee-type/package.json +6 -0
  195. package/hyperliquid-execution/package.json +6 -0
  196. package/image-links/package.json +6 -0
  197. package/lifi-execution-guard/package.json +6 -0
  198. package/llms.txt +234 -0
  199. package/near-intents/package.json +6 -0
  200. package/near-intents-route/package.json +6 -0
  201. package/origin-deposit/package.json +6 -0
  202. package/package.json +818 -10
  203. package/pre-quote/package.json +6 -0
  204. package/prices/package.json +6 -0
  205. package/providers/package.json +6 -0
  206. package/quote-fees/package.json +6 -0
  207. package/referral/package.json +6 -0
  208. package/relay-currencies/package.json +6 -0
  209. package/relay-quote/package.json +6 -0
  210. package/route-steps/package.json +6 -0
  211. package/routing/package.json +6 -0
  212. package/settings/package.json +6 -0
  213. package/ton/package.json +6 -0
  214. package/ton-connect/package.json +6 -0
  215. package/ton-execution/package.json +6 -0
  216. package/tron-execution/package.json +6 -0
  217. package/types/package.json +6 -0
@@ -0,0 +1,98 @@
1
+ import type { TonDeposit } from './origin-deposit.js';
2
+ /**
3
+ * Executing a deposit on The Open Network, as pure data, with no TON library.
4
+ *
5
+ * This module imports nothing outside the package, so it loads anywhere: a
6
+ * browser, Node, or a React Native app under Hermes, with no `Buffer` and no
7
+ * polyfill. It uses only `atob` and `btoa`, which Hermes provides. The one TON
8
+ * helper that needs `@ton/core`, the TEP-467 message hash, lives in
9
+ * `@gibs/bridge-sdk/ton` instead.
10
+ *
11
+ * Relay describes a deposit as a list of internal messages carrying `to`,
12
+ * `value`, `body` and a `bounce` flag. A connected wallet, however, is driven
13
+ * through the TON Connect protocol, whose request shape is different in one way
14
+ * that silently loses money:
15
+ *
16
+ * **TON Connect has no per-message `bounce` field.** A wallet derives whether a
17
+ * message bounces from the FORM OF THE ADDRESS — the bounceable `EQ…` prefix or
18
+ * the non-bounceable `UQ…` one. Passing Relay's address through unchanged while
19
+ * dropping its `bounce: false` therefore sends a deposit to the bounceable form,
20
+ * and the depository bounces the funds straight back to the sender. The transfer
21
+ * looks like it succeeded and the route never fills.
22
+ *
23
+ * {@link buildTonConnectRequest} folds `bounce` into the address so the flag
24
+ * cannot be dropped on the way to a wallet.
25
+ *
26
+ * Kept free of transport and of clock reads so it is fully testable: nothing
27
+ * here signs, fetches, or calls `Date.now`. The caller supplies the deadline and
28
+ * performs the request.
29
+ *
30
+ * The rules encoded here are those of Relay's own wallet adapter, which is the
31
+ * only reference implementation of this mapping.
32
+ */
33
+ /**
34
+ * The TON Connect network identifier for mainnet. Relay bridges only mainnet, so
35
+ * a request is always tagged with this.
36
+ */
37
+ export declare const tonConnectMainnetNetwork = "-239";
38
+ /** How long a request stays valid by default, in seconds, matching Relay's adapter. */
39
+ export declare const tonConnectDefaultValidForSeconds = 300;
40
+ /** An address split into the parts that survive a change of encoding. */
41
+ type ParsedTonAddress = {
42
+ workchain: number;
43
+ hash: Uint8Array;
44
+ /** Preserved rather than assumed: re-encoding a testnet address as mainnet would misdirect it. */
45
+ testOnly: boolean;
46
+ };
47
+ /**
48
+ * Parses either address form The Open Network uses.
49
+ *
50
+ * @param value - a friendly (`EQ…`/`UQ…`) or raw (`0:…`) address
51
+ * @returns the address parts, or null when it is neither form or fails its checksum
52
+ */
53
+ export declare const parseTonAddress: (value: string) => ParsedTonAddress | null;
54
+ /**
55
+ * Re-encodes an address into the friendly form matching a bounce setting.
56
+ *
57
+ * This is the whole point of the module: the bounce flag has nowhere else to
58
+ * live in a TON Connect request, so it has to be carried by the address itself.
59
+ *
60
+ * @param address - the address in either form
61
+ * @param options.bounceable - whether the message may bounce back to the sender
62
+ * @returns the friendly address, or null when the input cannot be parsed
63
+ */
64
+ export declare const encodeTonAddress: (address: string, { bounceable }: {
65
+ bounceable: boolean;
66
+ }) => string | null;
67
+ /** One message of a TON Connect request. Note `address`/`amount`, not `to`/`value`. */
68
+ export type TonConnectMessage = {
69
+ address: string;
70
+ /** Attached amount in nanotons, as a decimal string. */
71
+ amount: string;
72
+ /** Base64 bag-of-cells body, omitted when the message carries none. */
73
+ payload?: string;
74
+ };
75
+ /** The request handed to a wallet's TON Connect `sendTransaction` call. */
76
+ export type TonConnectRequest = {
77
+ /** Unix seconds after which a wallet must refuse the request. */
78
+ validUntil: number;
79
+ network: string;
80
+ /** The sending account, when the deposit names one. */
81
+ from?: string;
82
+ messages: TonConnectMessage[];
83
+ };
84
+ /**
85
+ * Builds the TON Connect request for a deposit.
86
+ *
87
+ * @param deposit - the parsed origin deposit
88
+ * @param options.validUntil - unix seconds after which the request expires.
89
+ * Supplied by the caller rather than read from a clock here so the transform
90
+ * stays pure; {@link tonConnectDefaultValidForSeconds} is the usual offset.
91
+ * @returns the request, or null when the deposit carries no messages or any
92
+ * destination address cannot be re-encoded — never a request whose bounce
93
+ * setting has been silently dropped
94
+ */
95
+ export declare const buildTonConnectRequest: (deposit: TonDeposit, { validUntil }: {
96
+ validUntil: number;
97
+ }) => TonConnectRequest | null;
98
+ export {};
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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
+ exports.tonConnectMainnetNetwork = '-239';
40
+ /** How long a request stays valid by default, in seconds, matching Relay's adapter. */
41
+ exports.tonConnectDefaultValidForSeconds = 300;
42
+ /** Address tag byte for the bounceable (`EQ…`) form. */
43
+ const bounceableTag = 0x11;
44
+ /** Address tag byte for the non-bounceable (`UQ…`) form. */
45
+ const nonBounceableTag = 0x51;
46
+ /** Bit set on the tag byte for testnet-only addresses (`kQ…` / `0Q…`). */
47
+ const testnetTagFlag = 0x80;
48
+ /** A friendly address is a 36-byte structure: tag, workchain, hash, checksum. */
49
+ const friendlyAddressByteLength = 36;
50
+ /** An account identifier is always 32 bytes, in every address form. */
51
+ 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
+ const checksum = (data) => {
58
+ let remainder = 0;
59
+ for (const byte of data) {
60
+ remainder ^= byte << 8;
61
+ for (let bit = 0; bit < 8; bit += 1) {
62
+ remainder =
63
+ remainder & 0x8000 ? ((remainder << 1) ^ 0x1021) & 0xffff : (remainder << 1) & 0xffff;
64
+ }
65
+ }
66
+ return remainder;
67
+ };
68
+ /** Decodes the url-safe base64 alphabet the friendly address form uses. */
69
+ const decodeBase64Url = (value) => {
70
+ const standard = value.replaceAll('-', '+').replaceAll('_', '/');
71
+ const padded = standard.padEnd(Math.ceil(standard.length / 4) * 4, '=');
72
+ try {
73
+ const binary = atob(padded);
74
+ return Uint8Array.from(binary, (character) => character.charCodeAt(0));
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ };
80
+ /** Encodes bytes back into the url-safe, unpadded base64 form. */
81
+ const encodeBase64Url = (bytes) => {
82
+ let binary = '';
83
+ for (const byte of bytes) {
84
+ binary += String.fromCharCode(byte);
85
+ }
86
+ return btoa(binary).replaceAll('+', '-').replaceAll('/', '_').replaceAll('=', '');
87
+ };
88
+ const parseRawAddress = (value) => {
89
+ const separator = value.indexOf(':');
90
+ if (separator < 0) {
91
+ return null;
92
+ }
93
+ const workchain = Number(value.slice(0, separator));
94
+ const hex = value.slice(separator + 1);
95
+ if (!Number.isInteger(workchain) || hex.length !== accountHashByteLength * 2) {
96
+ return null;
97
+ }
98
+ const hash = new Uint8Array(accountHashByteLength);
99
+ for (let index = 0; index < accountHashByteLength; index += 1) {
100
+ const byte = Number.parseInt(hex.slice(index * 2, index * 2 + 2), 16);
101
+ if (Number.isNaN(byte)) {
102
+ return null;
103
+ }
104
+ hash[index] = byte;
105
+ }
106
+ // The raw form carries no network tag, so mainnet is the only safe assumption.
107
+ return { workchain, hash, testOnly: false };
108
+ };
109
+ const parseFriendlyAddress = (value) => {
110
+ const bytes = decodeBase64Url(value);
111
+ if (bytes === null || bytes.length !== friendlyAddressByteLength) {
112
+ return null;
113
+ }
114
+ 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
+ const stated = (bytes[friendlyAddressByteLength - 2] << 8) | bytes[friendlyAddressByteLength - 1];
118
+ if (checksum(body) !== stated) {
119
+ return null;
120
+ }
121
+ const tag = bytes[0];
122
+ const withoutTestFlag = tag & ~testnetTagFlag;
123
+ if (withoutTestFlag !== bounceableTag && withoutTestFlag !== nonBounceableTag) {
124
+ return null;
125
+ }
126
+ const workchainByte = bytes[1];
127
+ return {
128
+ // The masterchain is workchain -1, which travels as the byte 0xff.
129
+ workchain: workchainByte === 0xff ? -1 : workchainByte,
130
+ hash: bytes.slice(2, 2 + accountHashByteLength),
131
+ testOnly: (tag & testnetTagFlag) !== 0,
132
+ };
133
+ };
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
+ const parseTonAddress = (value) => value.includes(':') ? parseRawAddress(value) : parseFriendlyAddress(value);
141
+ 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
+ const encodeTonAddress = (address, { bounceable }) => {
153
+ const parsed = (0, exports.parseTonAddress)(address);
154
+ if (parsed === null) {
155
+ return null;
156
+ }
157
+ const bytes = new Uint8Array(friendlyAddressByteLength);
158
+ bytes[0] =
159
+ (bounceable ? bounceableTag : nonBounceableTag) | (parsed.testOnly ? testnetTagFlag : 0);
160
+ bytes[1] = parsed.workchain < 0 ? 0xff : parsed.workchain;
161
+ bytes.set(parsed.hash, 2);
162
+ const stated = checksum(bytes.subarray(0, friendlyAddressByteLength - 2));
163
+ bytes[friendlyAddressByteLength - 2] = (stated >> 8) & 0xff;
164
+ bytes[friendlyAddressByteLength - 1] = stated & 0xff;
165
+ return encodeBase64Url(bytes);
166
+ };
167
+ 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
+ const buildTonConnectRequest = (deposit, { validUntil }) => {
180
+ if (deposit.messages.length === 0) {
181
+ return null;
182
+ }
183
+ const messages = [];
184
+ for (const message of deposit.messages) {
185
+ 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
+ if (address === null) {
189
+ return null;
190
+ }
191
+ messages.push({
192
+ address,
193
+ amount: message.value.toString(),
194
+ ...(message.body ? { payload: message.body } : {}),
195
+ });
196
+ }
197
+ // `messages[0]` is present: the empty case returned null above.
198
+ const from = deposit.messages[0].from;
199
+ return {
200
+ validUntil,
201
+ network: exports.tonConnectMainnetNetwork,
202
+ ...(from === null ? {} : { from }),
203
+ messages,
204
+ };
205
+ };
206
+ exports.buildTonConnectRequest = buildTonConnectRequest;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * The original name of `@gibs/bridge-sdk/ton`, kept so existing imports work.
3
+ *
4
+ * @deprecated Import from `@gibs/bridge-sdk/ton` for the full TON surface, or
5
+ * from `@gibs/bridge-sdk/ton-connect` for the helpers that need no TON library.
6
+ */
7
+ export * from './ton.js';
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
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
+ __exportStar(require("./ton.js"), exports);
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Everything the bridge SDK offers for The Open Network, in one entry point.
3
+ *
4
+ * It re-exports the pure TON Connect helpers from `./ton-connect.js` and adds
5
+ * {@link tonExternalMessageHash}, the only helper that needs `@ton/core`.
6
+ *
7
+ * Kept apart from the root entry point on purpose. `@ton/core` uses Node's
8
+ * `Buffer`, and its `@ton/crypto` dependency resolves, under React Native, to a
9
+ * build that requires `expo-crypto`. An application that bridges only between
10
+ * Ethereum-style chains never imports this file, so it never pays for either.
11
+ */
12
+ export * from './ton-connect.js';
13
+ /**
14
+ * Derives the transaction identifier from a wallet's `sendTransaction` response.
15
+ *
16
+ * A wallet answers with a `boc`: the base64 bag-of-cells of the signed
17
+ * external-in message it broadcast — NOT the resulting transaction, and NOT a
18
+ * hash. The identifier explorers and indexers (toncenter, TonAPI) resolve a
19
+ * transaction by is the hash of that external message, but it must be the
20
+ * NORMALIZED hash of TEP-467, not the hash of the bytes the wallet happened to
21
+ * send.
22
+ *
23
+ * The distinction is the whole point, and getting it wrong loses a resume record
24
+ * for real funds. An external-in message can be serialized several equivalent
25
+ * ways — a wallet may or may not include its own `src`, may set a non-zero
26
+ * `import_fee`, may attach a `stateInit`, may store the body inline or as a
27
+ * reference. The raw cell hash changes with each of those wallet-specific
28
+ * choices, so it frequently does NOT match what an indexer keyed the same
29
+ * transaction under. TEP-467 rebuilds the message with those variable fields
30
+ * stripped (`src` to none, `import_fee` to zero, `init` dropped, body forced to a
31
+ * reference) so the hash is stable across wallets and matches the indexers.
32
+ *
33
+ * @param boc - the wallet's base64 `boc` field from `sendTransaction`
34
+ * @returns the 64-character hex normalized hash, or null when the input is not a
35
+ * parseable external-in message
36
+ */
37
+ export declare const tonExternalMessageHash: (boc: string) => string | null;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.tonExternalMessageHash = void 0;
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
+ __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
+ const tonExternalMessageHash = (boc) => {
56
+ try {
57
+ 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
+ if (message.info.type !== 'external-in') {
61
+ return null;
62
+ }
63
+ const normalized = {
64
+ ...message,
65
+ // Dropped by TEP-467 so a wallet-attached stateInit does not move the hash.
66
+ 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
+ info: { ...message.info, src: undefined, importFee: 0n },
70
+ };
71
+ // `forceRef` stores the body as a reference, as the normalized form requires.
72
+ return (0, core_1.beginCell)()
73
+ .store((0, core_1.storeMessage)(normalized, { forceRef: true }))
74
+ .endCell()
75
+ .hash()
76
+ .toString('hex');
77
+ }
78
+ catch {
79
+ // A malformed base64 payload or a cell tree that is not a message at all.
80
+ return null;
81
+ }
82
+ };
83
+ exports.tonExternalMessageHash = tonExternalMessageHash;
@@ -0,0 +1,146 @@
1
+ import type { TronDeposit } from './origin-deposit.js';
2
+ /**
3
+ * Executing a deposit on Tron, as pure data.
4
+ *
5
+ * Relay does not return a broadcastable Tron transaction. It returns the
6
+ * *parameters* of a `TriggerSmartContract` call — owner, contract, call value
7
+ * and calldata — and nothing else. A Tron transaction additionally needs a
8
+ * reference block, an expiration and a fee limit, none of which Relay supplies.
9
+ * Those are produced by asking a full node to build the transaction, which is
10
+ * what {@link buildTriggerSmartContractRequest} constructs the body for. The
11
+ * node answers with an UNSIGNED transaction; the wallet signs it and a second
12
+ * call broadcasts it.
13
+ *
14
+ * Three details of that exchange lose money or mislead if handled naively:
15
+ *
16
+ * **The `visible` flag defaults to true.** A node reads addresses as base58
17
+ * unless told otherwise, but Relay returns them as hex with Tron's `41` prefix.
18
+ * Omitting the flag therefore hands base58-parsing a hex string. The request
19
+ * built here always states `visible: false` rather than relying on a default
20
+ * that is the opposite of what the payload contains.
21
+ *
22
+ * **`fee_limit` is required and Relay omits it.** It caps the energy the caller
23
+ * will pay for. Set too low, the call runs out of energy, reverts, and the
24
+ * energy already burned is NOT refunded — the deposit fails and costs the user
25
+ * anyway.
26
+ *
27
+ * **A rejected call still answers HTTP 200**, with the reason hex-encoded in
28
+ * `result.message`. Reading the status code alone reports a failed deposit as a
29
+ * success, and printing the message unmodified shows the user a wall of hex.
30
+ * {@link tronErrorMessage} decodes it.
31
+ *
32
+ * Kept free of transport and of clock reads so it is fully testable: nothing
33
+ * here signs, fetches, or calls `Date.now`. The caller performs the requests.
34
+ */
35
+ /** Path of the full-node endpoint that builds an unsigned contract call. */
36
+ export declare const tronTriggerSmartContractPath = "/wallet/triggersmartcontract";
37
+ /**
38
+ * The fee limit used when a caller states none, in sun (1 TRX = 1,000,000 sun).
39
+ *
40
+ * Thirty TRX, matching Relay's own wallet adapter, which is the only reference
41
+ * implementation of this deposit path. It is an upper bound rather than a
42
+ * charge: unused energy is not taken, so the cost of setting it generously is
43
+ * only that the wallet shows a larger worst case.
44
+ */
45
+ export declare const defaultTronFeeLimitSun = 30000000;
46
+ /**
47
+ * The largest fee limit a node accepts, in sun — 15,000 TRX. Documented as a
48
+ * hard protocol cap, so a request above it is rejected outright rather than
49
+ * clamped.
50
+ */
51
+ export declare const maximumTronFeeLimitSun = 15000000000;
52
+ /**
53
+ * The body of a `/wallet/triggersmartcontract` request.
54
+ *
55
+ * Field names are the node's own snake_case, deliberately: this object is
56
+ * serialized and posted verbatim, so renaming to the codebase's conventions
57
+ * would only invite a translation step that can drift.
58
+ */
59
+ export type TriggerSmartContractRequest = {
60
+ owner_address: string;
61
+ contract_address: string;
62
+ /** Calldata as bare hex, with no `0x` prefix. */
63
+ data: string;
64
+ /** Native TRX sent with the call, in sun. */
65
+ call_value: number;
66
+ /** Energy spending cap, in sun. */
67
+ fee_limit: number;
68
+ /** Always false — the addresses above are hex, not base58. See the module note. */
69
+ visible: false;
70
+ };
71
+ /**
72
+ * Normalizes a Tron hex address for comparison.
73
+ *
74
+ * Wallets and quotes disagree on casing, and Relay's payload is not guaranteed
75
+ * to match what a wallet reports even when both name the same account.
76
+ *
77
+ * @param value - an address in Tron's `41`-prefixed hex form, in any casing,
78
+ * optionally written with a `0x` prefix
79
+ * @returns the lowercase `41` form, or null when the value is not that form
80
+ */
81
+ export declare const normalizeTronHexAddress: (value: string) => string | null;
82
+ /**
83
+ * Whether two Tron hex addresses name the same account.
84
+ *
85
+ * Used to check a deposit's owner against the connected wallet before signing.
86
+ * A mismatch means the quote was built for a different account, and signing it
87
+ * would spend from an account the user did not choose — or simply fail after
88
+ * the user has already approved.
89
+ *
90
+ * @param left - an address in Tron's `41`-prefixed hex form
91
+ * @param right - an address in the same form
92
+ * @returns true only when both parse and name the same account
93
+ */
94
+ export declare const isSameTronAccount: (left: string, right: string) => boolean;
95
+ /**
96
+ * Builds the body that asks a full node to construct the unsigned deposit.
97
+ *
98
+ * @param deposit - the parsed origin deposit
99
+ * @param options.feeLimitSun - the energy spending cap in sun; defaults to
100
+ * {@link defaultTronFeeLimitSun}
101
+ * @returns the request body, or null when the deposit names an address that is
102
+ * not Tron hex, carries a call value that cannot be represented exactly, or
103
+ * the fee limit is outside what a node accepts — never a body that would be
104
+ * built against a default `visible` the payload contradicts
105
+ */
106
+ export declare const buildTriggerSmartContractRequest: (deposit: TronDeposit, { feeLimitSun }?: {
107
+ feeLimitSun?: number;
108
+ }) => TriggerSmartContractRequest | null;
109
+ /**
110
+ * Extracts a node's failure reason from either endpoint's response.
111
+ *
112
+ * @param payload - the parsed response body
113
+ * @returns the decoded message, or null when the response reports no failure
114
+ */
115
+ export declare const tronErrorMessage: (payload: unknown) => string | null;
116
+ /**
117
+ * Reads the unsigned transaction out of a build response.
118
+ *
119
+ * The response carries the transaction at the top level alongside a `result`
120
+ * object stating whether the build succeeded, so the presence of a `txID` is
121
+ * not on its own evidence of success.
122
+ *
123
+ * @param payload - the parsed `/wallet/triggersmartcontract` response
124
+ * @returns the unsigned transaction to hand a wallet, or null when the node
125
+ * refused the call
126
+ */
127
+ export declare const readTriggerSmartContractResponse: (payload: unknown) => Record<string, unknown> | null;
128
+ /**
129
+ * Reads the transaction identifier out of a broadcast response.
130
+ *
131
+ * GOTCHA: a rejected broadcast answers HTTP 200, and `result` is OMITTED rather
132
+ * than set to false. Testing `result === false` therefore never fires, and
133
+ * trusting the status code records a deposit that never entered a block. Only
134
+ * an explicit `result: true` is accepted here.
135
+ *
136
+ * The identifier is read from `txid` where a node reports it, falling back to
137
+ * the echoed transaction's `txID`. The two spellings differ by casing and by
138
+ * position: a node answers `txid`, while a wallet library that echoes the
139
+ * transaction it broadcast carries `txID` inside it. Accepting only the first
140
+ * would report an accepted broadcast as a failure whenever the caller is one of
141
+ * those libraries.
142
+ *
143
+ * @param payload - the parsed `/wallet/broadcasttransaction` response
144
+ * @returns the transaction identifier, or null when the broadcast was refused
145
+ */
146
+ export declare const readBroadcastResponse: (payload: unknown) => string | null;