@meshconnect/uwc-tron-connector 0.1.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 (80) hide show
  1. package/dist/events/state-machine.d.ts +26 -0
  2. package/dist/events/state-machine.d.ts.map +1 -0
  3. package/dist/events/state-machine.js +21 -0
  4. package/dist/events/state-machine.js.map +1 -0
  5. package/dist/index.d.ts +7 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +3 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/rest/abi.d.ts +23 -0
  10. package/dist/rest/abi.d.ts.map +1 -0
  11. package/dist/rest/abi.js +28 -0
  12. package/dist/rest/abi.js.map +1 -0
  13. package/dist/rest/address.d.ts +45 -0
  14. package/dist/rest/address.d.ts.map +1 -0
  15. package/dist/rest/address.js +124 -0
  16. package/dist/rest/address.js.map +1 -0
  17. package/dist/rest/trongrid-client.d.ts +57 -0
  18. package/dist/rest/trongrid-client.d.ts.map +1 -0
  19. package/dist/rest/trongrid-client.js +133 -0
  20. package/dist/rest/trongrid-client.js.map +1 -0
  21. package/dist/shared/error-utils.d.ts +9 -0
  22. package/dist/shared/error-utils.d.ts.map +1 -0
  23. package/dist/shared/error-utils.js +52 -0
  24. package/dist/shared/error-utils.js.map +1 -0
  25. package/dist/tron-connector.d.ts +85 -0
  26. package/dist/tron-connector.d.ts.map +1 -0
  27. package/dist/tron-connector.js +456 -0
  28. package/dist/tron-connector.js.map +1 -0
  29. package/dist/types.d.ts +8 -0
  30. package/dist/types.d.ts.map +1 -0
  31. package/dist/types.js +2 -0
  32. package/dist/types.js.map +1 -0
  33. package/dist/wallets/base.d.ts +87 -0
  34. package/dist/wallets/base.d.ts.map +1 -0
  35. package/dist/wallets/base.js +118 -0
  36. package/dist/wallets/base.js.map +1 -0
  37. package/dist/wallets/bitget.d.ts +8 -0
  38. package/dist/wallets/bitget.d.ts.map +1 -0
  39. package/dist/wallets/bitget.js +14 -0
  40. package/dist/wallets/bitget.js.map +1 -0
  41. package/dist/wallets/okx.d.ts +4 -0
  42. package/dist/wallets/okx.d.ts.map +1 -0
  43. package/dist/wallets/okx.js +10 -0
  44. package/dist/wallets/okx.js.map +1 -0
  45. package/dist/wallets/registry.d.ts +8 -0
  46. package/dist/wallets/registry.d.ts.map +1 -0
  47. package/dist/wallets/registry.js +18 -0
  48. package/dist/wallets/registry.js.map +1 -0
  49. package/dist/wallets/tokenpocket.d.ts +9 -0
  50. package/dist/wallets/tokenpocket.d.ts.map +1 -0
  51. package/dist/wallets/tokenpocket.js +15 -0
  52. package/dist/wallets/tokenpocket.js.map +1 -0
  53. package/dist/wallets/tronlink.d.ts +8 -0
  54. package/dist/wallets/tronlink.d.ts.map +1 -0
  55. package/dist/wallets/tronlink.js +15 -0
  56. package/dist/wallets/tronlink.js.map +1 -0
  57. package/dist/wallets/trust.d.ts +9 -0
  58. package/dist/wallets/trust.d.ts.map +1 -0
  59. package/dist/wallets/trust.js +15 -0
  60. package/dist/wallets/trust.js.map +1 -0
  61. package/package.json +34 -0
  62. package/src/events/state-machine.ts +44 -0
  63. package/src/index.ts +17 -0
  64. package/src/rest/abi.test.ts +25 -0
  65. package/src/rest/abi.ts +33 -0
  66. package/src/rest/address.test.ts +55 -0
  67. package/src/rest/address.ts +140 -0
  68. package/src/rest/trongrid-client.test.ts +169 -0
  69. package/src/rest/trongrid-client.ts +205 -0
  70. package/src/shared/error-utils.ts +60 -0
  71. package/src/tron-connector.test.ts +612 -0
  72. package/src/tron-connector.ts +568 -0
  73. package/src/types.ts +11 -0
  74. package/src/wallets/base.ts +184 -0
  75. package/src/wallets/bitget.ts +17 -0
  76. package/src/wallets/okx.ts +10 -0
  77. package/src/wallets/registry.ts +26 -0
  78. package/src/wallets/tokenpocket.ts +15 -0
  79. package/src/wallets/tronlink.ts +15 -0
  80. package/src/wallets/trust.ts +18 -0
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Minimal connection state machine + subscription surface.
3
+ *
4
+ * The connector exposes a single `onStateChange` callback rather than the
5
+ * full wallet event set — enough for `core` to react to disconnects and
6
+ * account changes without leaking per-wallet event shapes.
7
+ */
8
+ import type { TronWalletId } from '@meshconnect/uwc-types';
9
+ export type TronConnectionStatus = 'disconnected' | 'connecting' | 'connected';
10
+ export interface TronConnectionState {
11
+ status: TronConnectionStatus;
12
+ /** Active wallet id, when connected/connecting. */
13
+ walletId?: TronWalletId;
14
+ /** Active account address (base58), when connected. */
15
+ address?: string;
16
+ }
17
+ export type TronStateListener = (state: TronConnectionState) => void;
18
+ export declare class TronStateMachine {
19
+ private state;
20
+ private readonly listeners;
21
+ get(): TronConnectionState;
22
+ set(next: TronConnectionState): void;
23
+ /** Subscribe to state transitions. Returns an unsubscribe function. */
24
+ subscribe(listener: TronStateListener): () => void;
25
+ }
26
+ //# sourceMappingURL=state-machine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.d.ts","sourceRoot":"","sources":["../../src/events/state-machine.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAA;AAE1D,MAAM,MAAM,oBAAoB,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,CAAA;AAE9E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,oBAAoB,CAAA;IAC5B,mDAAmD;IACnD,QAAQ,CAAC,EAAE,YAAY,CAAA;IACvB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAA;AAEpE,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,KAAK,CAAkD;IAC/D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA+B;IAEzD,GAAG,IAAI,mBAAmB;IAI1B,GAAG,CAAC,IAAI,EAAE,mBAAmB,GAAG,IAAI;IAOpC,uEAAuE;IACvE,SAAS,CAAC,QAAQ,EAAE,iBAAiB,GAAG,MAAM,IAAI;CAMnD"}
@@ -0,0 +1,21 @@
1
+ export class TronStateMachine {
2
+ state = { status: 'disconnected' };
3
+ listeners = new Set();
4
+ get() {
5
+ return this.state;
6
+ }
7
+ set(next) {
8
+ this.state = next;
9
+ for (const listener of this.listeners) {
10
+ listener(next);
11
+ }
12
+ }
13
+ /** Subscribe to state transitions. Returns an unsubscribe function. */
14
+ subscribe(listener) {
15
+ this.listeners.add(listener);
16
+ return () => {
17
+ this.listeners.delete(listener);
18
+ };
19
+ }
20
+ }
21
+ //# sourceMappingURL=state-machine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-machine.js","sourceRoot":"","sources":["../../src/events/state-machine.ts"],"names":[],"mappings":"AAqBA,MAAM,OAAO,gBAAgB;IACnB,KAAK,GAAwB,EAAE,MAAM,EAAE,cAAc,EAAE,CAAA;IAC9C,SAAS,GAAG,IAAI,GAAG,EAAqB,CAAA;IAEzD,GAAG;QACD,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,GAAG,CAAC,IAAyB;QAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,CAAA;QAChB,CAAC;IACH,CAAC;IAED,uEAAuE;IACvE,SAAS,CAAC,QAA2B;QACnC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QAC5B,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;QACjC,CAAC,CAAA;IACH,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export { TronConnector } from './tron-connector';
2
+ export { ALL_TRON_WALLET_IDS, TRON_WALLET_REGISTRY, isTronWalletId } from './wallets/registry';
3
+ export type { TronWalletWrapper, InjectedTronProvider } from './wallets/base';
4
+ export type { TronConnectionState, TronConnectionStatus, TronStateListener } from './events/state-machine';
5
+ export type { UnsignedTronTransaction, SignedTronTransaction } from './rest/trongrid-client';
6
+ export type { TronConnectorConfig, TronGridConfig, TronWalletId } from './types';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACf,MAAM,oBAAoB,CAAA;AAC3B,YAAY,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAA;AAC7E,YAAY,EACV,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EAClB,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EACV,uBAAuB,EACvB,qBAAqB,EACtB,MAAM,wBAAwB,CAAA;AAC/B,YAAY,EAAE,mBAAmB,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { TronConnector } from './tron-connector';
2
+ export { ALL_TRON_WALLET_IDS, TRON_WALLET_REGISTRY, isTronWalletId } from './wallets/registry';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACf,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * ABI-encode the arguments for `transfer(address,uint256)` (TRC20 / TEP-20).
3
+ *
4
+ * The full-node `/wallet/triggersmartcontract` endpoint takes the function
5
+ * selector as a literal string and the *arguments* as a hex `parameter` blob.
6
+ * Each argument is left-padded to a 32-byte (64-hex-char) word:
7
+ * - address: the bare 20-byte body, left-padded to 32 bytes.
8
+ * - uint256: the amount, left-padded to 32 bytes.
9
+ *
10
+ * @param to recipient address (base58 or hex)
11
+ * @param amount token amount in base units
12
+ * @returns 128-hex-char parameter string (no `0x` prefix)
13
+ */
14
+ export declare function encodeTrc20TransferParams(to: string, amount: number | bigint): string;
15
+ /** Function selector string the full node hashes for a TRC20 transfer. */
16
+ export declare const TRC20_TRANSFER_SELECTOR = "transfer(address,uint256)";
17
+ /**
18
+ * The 4-byte selector (8 hex chars) for `transfer(address,uint256)` —
19
+ * `keccak256("transfer(address,uint256)")[:4]`, same as ERC-20. Used to
20
+ * reconstruct and verify the full call data the node built before signing.
21
+ */
22
+ export declare const TRC20_TRANSFER_SELECTOR_HASH = "a9059cbb";
23
+ //# sourceMappingURL=abi.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abi.d.ts","sourceRoot":"","sources":["../../src/rest/abi.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,wBAAgB,yBAAyB,CACvC,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAIR;AAED,0EAA0E;AAC1E,eAAO,MAAM,uBAAuB,8BAA8B,CAAA;AAElE;;;;GAIG;AACH,eAAO,MAAM,4BAA4B,aAAa,CAAA"}
@@ -0,0 +1,28 @@
1
+ import { tronAddressToEvmHex } from './address';
2
+ /**
3
+ * ABI-encode the arguments for `transfer(address,uint256)` (TRC20 / TEP-20).
4
+ *
5
+ * The full-node `/wallet/triggersmartcontract` endpoint takes the function
6
+ * selector as a literal string and the *arguments* as a hex `parameter` blob.
7
+ * Each argument is left-padded to a 32-byte (64-hex-char) word:
8
+ * - address: the bare 20-byte body, left-padded to 32 bytes.
9
+ * - uint256: the amount, left-padded to 32 bytes.
10
+ *
11
+ * @param to recipient address (base58 or hex)
12
+ * @param amount token amount in base units
13
+ * @returns 128-hex-char parameter string (no `0x` prefix)
14
+ */
15
+ export function encodeTrc20TransferParams(to, amount) {
16
+ const addressWord = tronAddressToEvmHex(to).padStart(64, '0');
17
+ const amountWord = BigInt(amount).toString(16).padStart(64, '0');
18
+ return addressWord + amountWord;
19
+ }
20
+ /** Function selector string the full node hashes for a TRC20 transfer. */
21
+ export const TRC20_TRANSFER_SELECTOR = 'transfer(address,uint256)';
22
+ /**
23
+ * The 4-byte selector (8 hex chars) for `transfer(address,uint256)` —
24
+ * `keccak256("transfer(address,uint256)")[:4]`, same as ERC-20. Used to
25
+ * reconstruct and verify the full call data the node built before signing.
26
+ */
27
+ export const TRC20_TRANSFER_SELECTOR_HASH = 'a9059cbb';
28
+ //# sourceMappingURL=abi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"abi.js","sourceRoot":"","sources":["../../src/rest/abi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAA;AAE/C;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,yBAAyB,CACvC,EAAU,EACV,MAAuB;IAEvB,MAAM,WAAW,GAAG,mBAAmB,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAChE,OAAO,WAAW,GAAG,UAAU,CAAA;AACjC,CAAC;AAED,0EAA0E;AAC1E,MAAM,CAAC,MAAM,uBAAuB,GAAG,2BAA2B,CAAA;AAElE;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,UAAU,CAAA"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Tron address utilities — base58check ↔ hex, dependency-free.
3
+ *
4
+ * A Tron address has two on-the-wire forms:
5
+ * - base58check (`T...`): Base58Check of `0x41 ‖ <20-byte body> ‖ <4-byte checksum>`.
6
+ * - hex (`41` + 40 hex chars): the 21-byte payload (`0x41` prefix + 20-byte body).
7
+ *
8
+ * The full-node HTTP API accepts base58 directly when `visible: true` is set, so
9
+ * build/broadcast never needs conversion. The one place we DO need it is the
10
+ * TRC20 ABI parameter, which encodes the recipient as the bare 20-byte body.
11
+ *
12
+ * Decoding base58 is pure bigint math (no hashing), so the conversion helpers
13
+ * (`tronAddressToHex` / `tronAddressToEvmHex`) stay synchronous and do NOT
14
+ * verify the 4-byte checksum — that's the hot path used for already-validated
15
+ * addresses. Checksum verification is provided separately by the async
16
+ * `assertValidTronChecksum` (SubtleCrypto), which the connector calls on the
17
+ * TRC20 recipient — the one case the node never validates (it's encoded as raw
18
+ * hex, not sent as base58).
19
+ */
20
+ /**
21
+ * Convert a base58 Tron address (`T...`) to its 21-byte hex form
22
+ * (`41` + 40 hex chars). Already-hex input (with or without `0x`) is normalised
23
+ * and returned as-is.
24
+ */
25
+ export declare function tronAddressToHex(address: string): string;
26
+ /**
27
+ * Convert a Tron address to its bare 20-byte EVM-style hex body (no `0x41`
28
+ * prefix, no `0x`). This is the form used inside TRC20 ABI parameters.
29
+ */
30
+ export declare function tronAddressToEvmHex(address: string): string;
31
+ /**
32
+ * Validate a base58 Tron address's 0x41 prefix and 4-byte Base58Check checksum
33
+ * (first 4 bytes of `sha256(sha256(payload))`). Throws on mismatch.
34
+ *
35
+ * This matters for the TRC20 recipient: native transfers send the address as
36
+ * base58 with `visible:true`, so the node validates it — but TRC20 encodes the
37
+ * recipient as a raw 20-byte hex word, so the node never sees the base58 form.
38
+ * Without this check a typo'd-but-structurally-valid address would silently
39
+ * send funds to the wrong, unrecoverable destination.
40
+ *
41
+ * Hex inputs carry no base58 checksum, so they pass through unchecked.
42
+ * Async because it uses SubtleCrypto for SHA-256 (no hashing dependency).
43
+ */
44
+ export declare function assertValidTronChecksum(address: string): Promise<void>;
45
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../../src/rest/address.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAyCH;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBxD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE3D;AAYD;;;;;;;;;;;;GAYG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuB5E"}
@@ -0,0 +1,124 @@
1
+ /**
2
+ * Tron address utilities — base58check ↔ hex, dependency-free.
3
+ *
4
+ * A Tron address has two on-the-wire forms:
5
+ * - base58check (`T...`): Base58Check of `0x41 ‖ <20-byte body> ‖ <4-byte checksum>`.
6
+ * - hex (`41` + 40 hex chars): the 21-byte payload (`0x41` prefix + 20-byte body).
7
+ *
8
+ * The full-node HTTP API accepts base58 directly when `visible: true` is set, so
9
+ * build/broadcast never needs conversion. The one place we DO need it is the
10
+ * TRC20 ABI parameter, which encodes the recipient as the bare 20-byte body.
11
+ *
12
+ * Decoding base58 is pure bigint math (no hashing), so the conversion helpers
13
+ * (`tronAddressToHex` / `tronAddressToEvmHex`) stay synchronous and do NOT
14
+ * verify the 4-byte checksum — that's the hot path used for already-validated
15
+ * addresses. Checksum verification is provided separately by the async
16
+ * `assertValidTronChecksum` (SubtleCrypto), which the connector calls on the
17
+ * TRC20 recipient — the one case the node never validates (it's encoded as raw
18
+ * hex, not sent as base58).
19
+ */
20
+ const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
21
+ /** Decode a Base58 string to bytes (big-endian). Throws on invalid characters. */
22
+ function base58Decode(input) {
23
+ if (input.length === 0)
24
+ throw new Error('tron address: empty base58 string');
25
+ let value = 0n;
26
+ for (const char of input) {
27
+ const index = BASE58_ALPHABET.indexOf(char);
28
+ if (index === -1) {
29
+ throw new Error(`tron address: invalid base58 character "${char}"`);
30
+ }
31
+ value = value * 58n + BigInt(index);
32
+ }
33
+ const bytes = [];
34
+ while (value > 0n) {
35
+ bytes.unshift(Number(value & 0xffn));
36
+ value >>= 8n;
37
+ }
38
+ // Each leading '1' in base58 represents a leading zero byte.
39
+ for (const char of input) {
40
+ if (char !== '1')
41
+ break;
42
+ bytes.unshift(0);
43
+ }
44
+ return Uint8Array.from(bytes);
45
+ }
46
+ function toHex(bytes) {
47
+ let out = '';
48
+ for (const byte of bytes) {
49
+ out += byte.toString(16).padStart(2, '0');
50
+ }
51
+ return out;
52
+ }
53
+ /**
54
+ * Convert a base58 Tron address (`T...`) to its 21-byte hex form
55
+ * (`41` + 40 hex chars). Already-hex input (with or without `0x`) is normalised
56
+ * and returned as-is.
57
+ */
58
+ export function tronAddressToHex(address) {
59
+ // Accept hex passthrough so callers can mix forms.
60
+ const stripped = address.startsWith('0x') ? address.slice(2) : address;
61
+ if (/^41[0-9a-fA-F]{40}$/.test(stripped)) {
62
+ return stripped.toLowerCase();
63
+ }
64
+ const decoded = base58Decode(address);
65
+ // 25 bytes = 21-byte payload (0x41 + 20-byte body) + 4-byte checksum.
66
+ if (decoded.length !== 25) {
67
+ throw new Error(`tron address: expected 25 bytes after base58 decode, got ${decoded.length}`);
68
+ }
69
+ const payload = decoded.subarray(0, 21);
70
+ if (payload[0] !== 0x41) {
71
+ throw new Error('tron address: missing 0x41 Tron address prefix');
72
+ }
73
+ return toHex(payload);
74
+ }
75
+ /**
76
+ * Convert a Tron address to its bare 20-byte EVM-style hex body (no `0x41`
77
+ * prefix, no `0x`). This is the form used inside TRC20 ABI parameters.
78
+ */
79
+ export function tronAddressToEvmHex(address) {
80
+ return tronAddressToHex(address).slice(2);
81
+ }
82
+ /**
83
+ * SHA-256 via SubtleCrypto. Re-wraps the input with `Uint8Array.from` so it is
84
+ * an ArrayBuffer-backed view (satisfies `digest`'s `BufferSource` param without
85
+ * naming the DOM type, which our lint's `no-undef` doesn't recognize).
86
+ */
87
+ async function sha256(bytes) {
88
+ const digest = await crypto.subtle.digest('SHA-256', Uint8Array.from(bytes));
89
+ return new Uint8Array(digest);
90
+ }
91
+ /**
92
+ * Validate a base58 Tron address's 0x41 prefix and 4-byte Base58Check checksum
93
+ * (first 4 bytes of `sha256(sha256(payload))`). Throws on mismatch.
94
+ *
95
+ * This matters for the TRC20 recipient: native transfers send the address as
96
+ * base58 with `visible:true`, so the node validates it — but TRC20 encodes the
97
+ * recipient as a raw 20-byte hex word, so the node never sees the base58 form.
98
+ * Without this check a typo'd-but-structurally-valid address would silently
99
+ * send funds to the wrong, unrecoverable destination.
100
+ *
101
+ * Hex inputs carry no base58 checksum, so they pass through unchecked.
102
+ * Async because it uses SubtleCrypto for SHA-256 (no hashing dependency).
103
+ */
104
+ export async function assertValidTronChecksum(address) {
105
+ const stripped = address.startsWith('0x') ? address.slice(2) : address;
106
+ if (/^41[0-9a-fA-F]{40}$/.test(stripped))
107
+ return; // hex form: no checksum to verify
108
+ const decoded = base58Decode(address);
109
+ if (decoded.length !== 25) {
110
+ throw new Error(`tron address: expected 25 bytes after base58 decode, got ${decoded.length}`);
111
+ }
112
+ const payload = decoded.subarray(0, 21);
113
+ if (payload[0] !== 0x41) {
114
+ throw new Error('tron address: missing 0x41 Tron address prefix');
115
+ }
116
+ const expected = decoded.subarray(21, 25);
117
+ const round2 = await sha256(await sha256(payload));
118
+ for (let i = 0; i < 4; i++) {
119
+ if (round2[i] !== expected[i]) {
120
+ throw new Error('tron address: base58 checksum mismatch (possible typo in recipient address)');
121
+ }
122
+ }
123
+ }
124
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../../src/rest/address.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ import type { NetworkId, TronGridConfig } from '@meshconnect/uwc-types';
2
+ /**
3
+ * The minimal shape of an unsigned Tron transaction returned by
4
+ * `/wallet/createtransaction` and `/wallet/triggersmartcontract`.
5
+ *
6
+ * Only `txID` + `raw_data*` are load-bearing for sign/broadcast; the struct
7
+ * carries more fields that pass through opaquely. Typed loosely on purpose so
8
+ * a node-version change to the surrounding shape doesn't break the contract.
9
+ */
10
+ export interface UnsignedTronTransaction {
11
+ txID?: string;
12
+ raw_data?: unknown;
13
+ raw_data_hex?: string;
14
+ visible?: boolean;
15
+ [key: string]: unknown;
16
+ }
17
+ /** A transaction with the wallet's signature appended, ready to broadcast. */
18
+ export interface SignedTronTransaction extends UnsignedTronTransaction {
19
+ signature?: string[];
20
+ }
21
+ /**
22
+ * Thin `fetch` wrapper over the three Tron full-node HTTP endpoints this
23
+ * connector needs. No SDK, no `tronweb` — the `/wallet/*` paths are the Tron
24
+ * full-node API standard, identical across TronGrid and any full node.
25
+ */
26
+ export declare class TronGridClient {
27
+ private readonly baseUrl;
28
+ private readonly apiKey;
29
+ private readonly feeLimitSun;
30
+ constructor(networkId: NetworkId, config?: TronGridConfig);
31
+ /** Build an unsigned native TRX transfer. Amounts are in SUN. */
32
+ createTransaction(params: {
33
+ from: string;
34
+ to: string;
35
+ amount: number;
36
+ }): Promise<UnsignedTronTransaction>;
37
+ /** Build an unsigned TRC20 `transfer(address,uint256)` transaction. */
38
+ createTrc20Transfer(params: {
39
+ from: string;
40
+ to: string;
41
+ amount: number;
42
+ contractAddress: string;
43
+ }): Promise<UnsignedTronTransaction>;
44
+ /** Broadcast a signed transaction. Returns the on-chain txid. */
45
+ broadcastTransaction(signed: SignedTronTransaction): Promise<string>;
46
+ private post;
47
+ }
48
+ /**
49
+ * Full nodes often return `message` as hex-encoded ASCII
50
+ * (e.g. `"434f4e54524143545f56414c4944415445..."`). Decode when it looks like
51
+ * hex AND the result is printable ASCII; otherwise pass the string through
52
+ * unchanged. The printable check avoids mangling a message that happens to be
53
+ * an all-hex, even-length word (e.g. `"deadbeef"`), which would decode to
54
+ * non-printable bytes.
55
+ */
56
+ export declare function decodeHexMessage(message: string | undefined): string;
57
+ //# sourceMappingURL=trongrid-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trongrid-client.d.ts","sourceRoot":"","sources":["../../src/rest/trongrid-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAA;AAGvE;;;;;;;GAOG;AACH,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAED,8EAA8E;AAC9E,MAAM,WAAW,qBAAsB,SAAQ,uBAAuB;IACpE,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;CACrB;AAmBD;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAQ;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoB;IAC3C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;gBAExB,SAAS,EAAE,SAAS,EAAE,MAAM,GAAE,cAAmB;IAmC7D,iEAAiE;IAC3D,iBAAiB,CAAC,MAAM,EAAE;QAC9B,IAAI,EAAE,MAAM,CAAA;QACZ,EAAE,EAAE,MAAM,CAAA;QACV,MAAM,EAAE,MAAM,CAAA;KACf,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAmBpC,uEAAuE;IACjE,mBAAmB,CAAC,MAAM,EAAE;QAChC,IAAI,EAAE,MAAM,CAAA;QACZ,EAAE,EAAE,MAAM,CAAA;QACV,MAAM,EAAE,MAAM,CAAA;QACd,eAAe,EAAE,MAAM,CAAA;KACxB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAyBpC,iEAAiE;IAC3D,oBAAoB,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,CAAC;YAsB5D,IAAI;CAkBnB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAYpE"}
@@ -0,0 +1,133 @@
1
+ import { encodeTrc20TransferParams, TRC20_TRANSFER_SELECTOR } from './abi';
2
+ const DEFAULT_ENDPOINTS = {
3
+ 'tron:0x2b6653dc': 'https://api.trongrid.io', // Mainnet
4
+ 'tron:0x94a9059e': 'https://api.shasta.trongrid.io', // Shasta testnet
5
+ 'tron:0xcd8690dc': 'https://nile.trongrid.io' // Nile testnet
6
+ };
7
+ const DEFAULT_FEE_LIMIT_SUN = 100_000_000; // 100 TRX
8
+ /**
9
+ * Thin `fetch` wrapper over the three Tron full-node HTTP endpoints this
10
+ * connector needs. No SDK, no `tronweb` — the `/wallet/*` paths are the Tron
11
+ * full-node API standard, identical across TronGrid and any full node.
12
+ */
13
+ export class TronGridClient {
14
+ baseUrl;
15
+ apiKey;
16
+ feeLimitSun;
17
+ constructor(networkId, config = {}) {
18
+ const url = config.endpoints?.[networkId] ?? DEFAULT_ENDPOINTS[networkId];
19
+ if (!url) {
20
+ throw new Error(`tron-connector: no full-node endpoint configured for network "${networkId}". ` +
21
+ `Pass one via TronConnectorConfig.tronGrid.endpoints.`);
22
+ }
23
+ // Reject plaintext endpoints: we send the TRON-PRO-API-KEY header and the
24
+ // unsigned tx in the body, so an `http://` host would leak both. Allow
25
+ // loopback http for local dev nodes (e.g. a tron-quickstart container).
26
+ if (/^http:\/\//i.test(url) &&
27
+ !/^http:\/\/(localhost|127\.0\.0\.1)/i.test(url)) {
28
+ throw new Error(`tron-connector: refusing non-https endpoint "${url}" (would send the API key + tx in cleartext)`);
29
+ }
30
+ // Normalise away trailing slashes so path concatenation is predictable.
31
+ // Done with a plain loop (no regex) to avoid any backtracking concern.
32
+ let base = url;
33
+ while (base.endsWith('/'))
34
+ base = base.slice(0, -1);
35
+ this.baseUrl = base;
36
+ this.apiKey = config.apiKey;
37
+ const feeLimit = config.feeLimitSun ?? DEFAULT_FEE_LIMIT_SUN;
38
+ if (!Number.isInteger(feeLimit) || feeLimit <= 0) {
39
+ throw new Error(`tron-connector: feeLimitSun must be a positive integer (SUN), got ${feeLimit}`);
40
+ }
41
+ this.feeLimitSun = feeLimit;
42
+ }
43
+ /** Build an unsigned native TRX transfer. Amounts are in SUN. */
44
+ async createTransaction(params) {
45
+ const tx = await this.post('/wallet/createtransaction', {
46
+ owner_address: params.from,
47
+ to_address: params.to,
48
+ amount: params.amount,
49
+ visible: true
50
+ });
51
+ if (tx.Error) {
52
+ throw new Error(`tron-connector: createtransaction failed — ${tx.Error}`);
53
+ }
54
+ if (!tx.txID) {
55
+ throw new Error('tron-connector: createtransaction returned no txID');
56
+ }
57
+ return tx;
58
+ }
59
+ /** Build an unsigned TRC20 `transfer(address,uint256)` transaction. */
60
+ async createTrc20Transfer(params) {
61
+ const response = await this.post('/wallet/triggersmartcontract', {
62
+ owner_address: params.from,
63
+ contract_address: params.contractAddress,
64
+ function_selector: TRC20_TRANSFER_SELECTOR,
65
+ parameter: encodeTrc20TransferParams(params.to, params.amount),
66
+ fee_limit: this.feeLimitSun,
67
+ call_value: 0,
68
+ visible: true
69
+ });
70
+ if (!response.result?.result || !response.transaction?.txID) {
71
+ throw new Error(`tron-connector: triggersmartcontract failed — ${decodeHexMessage(response.result?.message) ||
72
+ response.result?.code ||
73
+ 'unknown error'}`);
74
+ }
75
+ return response.transaction;
76
+ }
77
+ /** Broadcast a signed transaction. Returns the on-chain txid. */
78
+ async broadcastTransaction(signed) {
79
+ const response = await this.post('/wallet/broadcasttransaction', signed);
80
+ // The node returns `{ result: false, message: <hex> }` on rejection even
81
+ // when a txid is echoed back — treat anything other than `result: true` as
82
+ // failure.
83
+ if (response.result !== true) {
84
+ throw new Error(decodeHexMessage(response.message) ||
85
+ response.code ||
86
+ 'tron-connector: broadcast rejected by node');
87
+ }
88
+ const txid = response.txid ?? response.transaction?.txID ?? signed.txID;
89
+ if (!txid) {
90
+ throw new Error('tron-connector: broadcast returned no txid');
91
+ }
92
+ return txid;
93
+ }
94
+ async post(path, body) {
95
+ const headers = {
96
+ 'Content-Type': 'application/json'
97
+ };
98
+ if (this.apiKey)
99
+ headers['TRON-PRO-API-KEY'] = this.apiKey;
100
+ const response = await fetch(`${this.baseUrl}${path}`, {
101
+ method: 'POST',
102
+ headers,
103
+ body: JSON.stringify(body)
104
+ });
105
+ if (!response.ok) {
106
+ throw new Error(`tron-connector: ${path} responded ${response.status} ${response.statusText}`);
107
+ }
108
+ return (await response.json());
109
+ }
110
+ }
111
+ /**
112
+ * Full nodes often return `message` as hex-encoded ASCII
113
+ * (e.g. `"434f4e54524143545f56414c4944415445..."`). Decode when it looks like
114
+ * hex AND the result is printable ASCII; otherwise pass the string through
115
+ * unchanged. The printable check avoids mangling a message that happens to be
116
+ * an all-hex, even-length word (e.g. `"deadbeef"`), which would decode to
117
+ * non-printable bytes.
118
+ */
119
+ export function decodeHexMessage(message) {
120
+ if (!message)
121
+ return '';
122
+ if (!/^[0-9a-fA-F]+$/.test(message) || message.length % 2 !== 0) {
123
+ return message;
124
+ }
125
+ let decoded = '';
126
+ for (let i = 0; i < message.length; i += 2) {
127
+ decoded += String.fromCharCode(parseInt(message.slice(i, i + 2), 16));
128
+ }
129
+ // Printable ASCII (incl. common whitespace) → it was hex-encoded text.
130
+ // Anything else → the input was more likely a literal string; keep it.
131
+ return /^[\x20-\x7e\t\n\r]*$/.test(decoded) ? decoded : message;
132
+ }
133
+ //# sourceMappingURL=trongrid-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trongrid-client.js","sourceRoot":"","sources":["../../src/rest/trongrid-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Translate an unknown error (from a wallet `request`/`sign` call or a node
3
+ * response) into a `WalletConnectorError`. User-rejection signals are tagged
4
+ * `type: 'rejected'`; everything else is `type: 'unknown'`.
5
+ *
6
+ * Throws — never returns.
7
+ */
8
+ export declare function parseError(error: unknown): never;
9
+ //# sourceMappingURL=error-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-utils.d.ts","sourceRoot":"","sources":["../../src/shared/error-utils.ts"],"names":[],"mappings":"AAqBA;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,CA+BhD"}
@@ -0,0 +1,52 @@
1
+ import { WalletConnectorError } from '@meshconnect/uwc-types';
2
+ const REJECTION_PATTERNS = [
3
+ 'user rejected',
4
+ 'user denied',
5
+ 'user cancelled',
6
+ 'user canceled',
7
+ 'rejected by user',
8
+ 'denied by user',
9
+ 'cancelled by user',
10
+ 'canceled by user',
11
+ 'user disapproved',
12
+ 'user declined',
13
+ 'action_rejected',
14
+ 'reject request',
15
+ 'user rejects',
16
+ 'wallet rejected',
17
+ 'confirmation declined'
18
+ ];
19
+ /**
20
+ * Translate an unknown error (from a wallet `request`/`sign` call or a node
21
+ * response) into a `WalletConnectorError`. User-rejection signals are tagged
22
+ * `type: 'rejected'`; everything else is `type: 'unknown'`.
23
+ *
24
+ * Throws — never returns.
25
+ */
26
+ export function parseError(error) {
27
+ if (error instanceof WalletConnectorError)
28
+ throw error;
29
+ let message = '';
30
+ let isRejected = false;
31
+ if (error && typeof error === 'object') {
32
+ const errObj = error;
33
+ // 4001 is the de-facto user-rejected code across injected wallets.
34
+ if (errObj.code === 4001 || errObj.code === 'ACTION_REJECTED') {
35
+ isRejected = true;
36
+ }
37
+ message = errObj.message ?? errObj.error?.message ?? String(error);
38
+ }
39
+ else {
40
+ message = String(error);
41
+ }
42
+ if (!isRejected) {
43
+ const lower = message.toLowerCase();
44
+ isRejected = REJECTION_PATTERNS.some(pattern => lower.includes(pattern));
45
+ }
46
+ const walletError = {
47
+ type: isRejected ? 'rejected' : 'unknown',
48
+ message
49
+ };
50
+ throw new WalletConnectorError(walletError);
51
+ }
52
+ //# sourceMappingURL=error-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"error-utils.js","sourceRoot":"","sources":["../../src/shared/error-utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAE7D,MAAM,kBAAkB,GAAG;IACzB,eAAe;IACf,aAAa;IACb,gBAAgB;IAChB,eAAe;IACf,kBAAkB;IAClB,gBAAgB;IAChB,mBAAmB;IACnB,kBAAkB;IAClB,kBAAkB;IAClB,eAAe;IACf,iBAAiB;IACjB,gBAAgB;IAChB,cAAc;IACd,iBAAiB;IACjB,uBAAuB;CACxB,CAAA;AAED;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,IAAI,KAAK,YAAY,oBAAoB;QAAE,MAAM,KAAK,CAAA;IAEtD,IAAI,OAAO,GAAG,EAAE,CAAA;IAChB,IAAI,UAAU,GAAG,KAAK,CAAA;IAEtB,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QACvC,MAAM,MAAM,GAAG,KAId,CAAA;QACD,mEAAmE;QACnE,IAAI,MAAM,CAAC,IAAI,KAAK,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YAC9D,UAAU,GAAG,IAAI,CAAA;QACnB,CAAC;QACD,OAAO,GAAG,MAAM,CAAC,OAAO,IAAI,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAA;IACpE,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,CAAA;IACzB,CAAC;IAED,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,KAAK,GAAG,OAAO,CAAC,WAAW,EAAE,CAAA;QACnC,UAAU,GAAG,kBAAkB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAA;IAC1E,CAAC;IAED,MAAM,WAAW,GAAgB;QAC/B,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS;QACzC,OAAO;KACR,CAAA;IACD,MAAM,IAAI,oBAAoB,CAAC,WAAW,CAAC,CAAA;AAC7C,CAAC"}