@t402/wdk 2.3.0 → 2.4.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 (40) hide show
  1. package/README.md +8 -0
  2. package/dist/cjs/adapters/index.d.ts +5 -0
  3. package/dist/cjs/adapters/index.js +455 -0
  4. package/dist/cjs/adapters/index.js.map +1 -0
  5. package/dist/cjs/adapters/svm-adapter.d.ts +125 -0
  6. package/dist/cjs/adapters/svm-adapter.js +132 -0
  7. package/dist/cjs/adapters/svm-adapter.js.map +1 -0
  8. package/dist/cjs/adapters/ton-adapter.d.ts +139 -0
  9. package/dist/cjs/adapters/ton-adapter.js +152 -0
  10. package/dist/cjs/adapters/ton-adapter.js.map +1 -0
  11. package/dist/cjs/adapters/tron-adapter.d.ts +139 -0
  12. package/dist/cjs/adapters/tron-adapter.js +221 -0
  13. package/dist/cjs/adapters/tron-adapter.js.map +1 -0
  14. package/dist/cjs/index.d.ts +292 -217
  15. package/dist/cjs/index.js +1042 -23
  16. package/dist/cjs/index.js.map +1 -1
  17. package/dist/cjs/types-V7c-qhn6.d.ts +489 -0
  18. package/dist/esm/adapters/index.d.mts +5 -0
  19. package/dist/esm/adapters/index.mjs +21 -0
  20. package/dist/esm/adapters/index.mjs.map +1 -0
  21. package/dist/esm/adapters/svm-adapter.d.mts +125 -0
  22. package/dist/esm/adapters/svm-adapter.mjs +9 -0
  23. package/dist/esm/adapters/svm-adapter.mjs.map +1 -0
  24. package/dist/esm/adapters/ton-adapter.d.mts +139 -0
  25. package/dist/esm/adapters/ton-adapter.mjs +9 -0
  26. package/dist/esm/adapters/ton-adapter.mjs.map +1 -0
  27. package/dist/esm/adapters/tron-adapter.d.mts +139 -0
  28. package/dist/esm/adapters/tron-adapter.mjs +9 -0
  29. package/dist/esm/adapters/tron-adapter.mjs.map +1 -0
  30. package/dist/esm/chunk-HB2DGKQ3.mjs +196 -0
  31. package/dist/esm/chunk-HB2DGKQ3.mjs.map +1 -0
  32. package/dist/esm/chunk-MCFHZSF7.mjs +107 -0
  33. package/dist/esm/chunk-MCFHZSF7.mjs.map +1 -0
  34. package/dist/esm/chunk-YWBJJV5M.mjs +117 -0
  35. package/dist/esm/chunk-YWBJJV5M.mjs.map +1 -0
  36. package/dist/esm/index.d.mts +292 -217
  37. package/dist/esm/index.mjs +640 -23
  38. package/dist/esm/index.mjs.map +1 -1
  39. package/dist/esm/types-V7c-qhn6.d.mts +489 -0
  40. package/package.json +70 -6
package/dist/cjs/index.js CHANGED
@@ -61,11 +61,20 @@ __export(index_exports, {
61
61
  WDKErrorCode: () => WDKErrorCode,
62
62
  WDKInitializationError: () => WDKInitializationError,
63
63
  WDKSigner: () => WDKSigner,
64
+ WDKSvmSignerAdapter: () => WDKSvmSignerAdapter,
65
+ WDKTonSignerAdapter: () => WDKTonSignerAdapter,
66
+ WDKTronSignerAdapter: () => WDKTronSignerAdapter,
67
+ WDK_COMPATIBILITY: () => WDK_COMPATIBILITY,
64
68
  WdkBridge: () => WdkBridge,
69
+ checkWalletEvmCompatibility: () => checkWalletEvmCompatibility,
70
+ checkWdkCompatibility: () => checkWdkCompatibility,
65
71
  createDirectBridge: () => createDirectBridge,
66
72
  createLedgerSigner: () => createLedgerSigner,
67
73
  createTrezorSigner: () => createTrezorSigner,
68
74
  createWDKSigner: () => createWDKSigner,
75
+ createWDKSvmSigner: () => createWDKSvmSigner,
76
+ createWDKTonSigner: () => createWDKTonSigner,
77
+ createWDKTronSigner: () => createWDKTronSigner,
69
78
  detectHardwareWalletSupport: () => detectHardwareWalletSupport,
70
79
  getBridgeableChains: () => import_evm3.getBridgeableChains,
71
80
  getChainFromNetwork: () => getChainFromNetwork,
@@ -73,6 +82,7 @@ __export(index_exports, {
73
82
  getNetworkFromChain: () => getNetworkFromChain,
74
83
  getPreferredToken: () => getPreferredToken,
75
84
  getUsdt0Chains: () => getUsdt0Chains,
85
+ getWalletModuleMinVersion: () => getWalletModuleMinVersion,
76
86
  hasErrorCode: () => hasErrorCode,
77
87
  isHardwareWalletSupported: () => isHardwareWalletSupported,
78
88
  isWDKError: () => isWDKError,
@@ -84,6 +94,411 @@ __export(index_exports, {
84
94
  });
85
95
  module.exports = __toCommonJS(index_exports);
86
96
 
97
+ // src/adapters/ton-adapter.ts
98
+ var WDKTonAddress = class {
99
+ constructor(_address) {
100
+ this._address = _address;
101
+ }
102
+ toString() {
103
+ return this._address;
104
+ }
105
+ toRawString() {
106
+ return this._address;
107
+ }
108
+ };
109
+ var WDKTonSignerAdapter = class {
110
+ _account;
111
+ _address = null;
112
+ _initialized = false;
113
+ constructor(account) {
114
+ if (!account) {
115
+ throw new Error("WDK TON account is required");
116
+ }
117
+ this._account = account;
118
+ }
119
+ /**
120
+ * Get the wallet address
121
+ * @throws Error if not initialized
122
+ */
123
+ get address() {
124
+ if (!this._address) {
125
+ throw new Error(
126
+ "TON signer not initialized. Call initialize() first or use createWDKTonSigner()."
127
+ );
128
+ }
129
+ return this._address;
130
+ }
131
+ /**
132
+ * Check if the adapter is initialized
133
+ */
134
+ get isInitialized() {
135
+ return this._initialized;
136
+ }
137
+ /**
138
+ * Initialize the adapter by fetching the address
139
+ * Must be called before using the signer
140
+ */
141
+ async initialize() {
142
+ if (this._initialized) {
143
+ return;
144
+ }
145
+ const addressStr = await this._account.getAddress();
146
+ this._address = new WDKTonAddress(addressStr);
147
+ this._initialized = true;
148
+ }
149
+ /**
150
+ * Sign an internal message for Jetton transfer
151
+ *
152
+ * Attempts to build a proper signed Cell using @ton/core if available.
153
+ * Falls back to a simplified wrapper that embeds the raw signature.
154
+ *
155
+ * @param params - Message parameters
156
+ * @returns Signed external message as Cell (BOC)
157
+ */
158
+ async signMessage(params) {
159
+ const msgHash = params.body.hash();
160
+ const signature = await this._account.signMessage(msgHash);
161
+ try {
162
+ const tonCore = await import("@ton/core");
163
+ const sigBuffer = Buffer.from(signature.buffer, signature.byteOffset, signature.byteLength);
164
+ const bodyBoc = params.body.toBoc();
165
+ const bocBuffer = Buffer.from(bodyBoc.buffer, bodyBoc.byteOffset, bodyBoc.byteLength);
166
+ const signedCell = tonCore.beginCell().storeBuffer(sigBuffer).storeSlice(tonCore.Cell.fromBoc(bocBuffer)[0].beginParse()).endCell();
167
+ return signedCell;
168
+ } catch {
169
+ return {
170
+ hash: () => msgHash,
171
+ toBoc: () => signature
172
+ };
173
+ }
174
+ }
175
+ /**
176
+ * Get current seqno for the wallet
177
+ * Used for replay protection
178
+ */
179
+ async getSeqno() {
180
+ return this._account.getSeqno();
181
+ }
182
+ /**
183
+ * Get TON balance in nanoTON
184
+ */
185
+ async getBalance() {
186
+ return this._account.getBalance();
187
+ }
188
+ /**
189
+ * Get Jetton balance
190
+ * @param jettonMaster - Jetton master contract address
191
+ */
192
+ async getJettonBalance(jettonMaster) {
193
+ return this._account.getJettonBalance(jettonMaster);
194
+ }
195
+ /**
196
+ * Get the underlying WDK account
197
+ * Useful for advanced operations not covered by this adapter
198
+ */
199
+ getWDKAccount() {
200
+ return this._account;
201
+ }
202
+ };
203
+ async function createWDKTonSigner(account) {
204
+ const adapter = new WDKTonSignerAdapter(account);
205
+ await adapter.initialize();
206
+ return adapter;
207
+ }
208
+
209
+ // src/adapters/svm-adapter.ts
210
+ var WDKSvmSignerAdapter = class {
211
+ _account;
212
+ _address = null;
213
+ _initialized = false;
214
+ constructor(account) {
215
+ if (!account) {
216
+ throw new Error("WDK Solana account is required");
217
+ }
218
+ this._account = account;
219
+ }
220
+ /**
221
+ * Get the wallet address (base58)
222
+ * @throws Error if not initialized
223
+ */
224
+ get address() {
225
+ if (!this._address) {
226
+ throw new Error(
227
+ "Solana signer not initialized. Call initialize() first or use createWDKSvmSigner()."
228
+ );
229
+ }
230
+ return this._address;
231
+ }
232
+ /**
233
+ * Check if the adapter is initialized
234
+ */
235
+ get isInitialized() {
236
+ return this._initialized;
237
+ }
238
+ /**
239
+ * Initialize the adapter by fetching the address
240
+ * Must be called before using the signer
241
+ */
242
+ async initialize() {
243
+ if (this._initialized) {
244
+ return;
245
+ }
246
+ const addressStr = await this._account.getAddress();
247
+ this._address = addressStr;
248
+ this._initialized = true;
249
+ }
250
+ /**
251
+ * Sign transactions with this signer
252
+ *
253
+ * This method signs the message bytes of each transaction and returns
254
+ * signature dictionaries mapping address to signature.
255
+ *
256
+ * @param transactions - Array of transactions to sign
257
+ * @returns Array of signature dictionaries
258
+ */
259
+ async signTransactions(transactions) {
260
+ if (!transactions || transactions.length === 0) {
261
+ return [];
262
+ }
263
+ const results = [];
264
+ for (const tx of transactions) {
265
+ if (!tx.messageBytes || tx.messageBytes.length === 0) {
266
+ throw new Error("Transaction messageBytes must not be empty");
267
+ }
268
+ const signature = await this._account.sign(tx.messageBytes);
269
+ results.push({
270
+ [this._address]: signature
271
+ });
272
+ }
273
+ return results;
274
+ }
275
+ /**
276
+ * Sign a single message (utility method)
277
+ * @param message - Message bytes to sign
278
+ * @returns Signature bytes
279
+ */
280
+ async sign(message) {
281
+ return this._account.sign(message);
282
+ }
283
+ /**
284
+ * Get SOL balance in lamports
285
+ */
286
+ async getBalance() {
287
+ return this._account.getBalance();
288
+ }
289
+ /**
290
+ * Get SPL token balance
291
+ * @param mint - Token mint address
292
+ */
293
+ async getTokenBalance(mint) {
294
+ return this._account.getTokenBalance(mint);
295
+ }
296
+ /**
297
+ * Transfer SPL tokens
298
+ * @param params - Transfer parameters
299
+ * @returns Transaction signature
300
+ */
301
+ async transfer(params) {
302
+ return this._account.transfer(params);
303
+ }
304
+ };
305
+ async function createWDKSvmSigner(account) {
306
+ const adapter = new WDKSvmSignerAdapter(account);
307
+ await adapter.initialize();
308
+ return adapter;
309
+ }
310
+
311
+ // src/adapters/tron-adapter.ts
312
+ var WDKTronSignerAdapter = class {
313
+ _account;
314
+ _address = null;
315
+ _initialized = false;
316
+ _rpcUrl;
317
+ constructor(account, rpcUrl = "https://api.trongrid.io") {
318
+ if (!account) {
319
+ throw new Error("WDK TRON account is required");
320
+ }
321
+ this._account = account;
322
+ this._rpcUrl = rpcUrl;
323
+ }
324
+ /**
325
+ * Get the wallet address (T-prefix base58check)
326
+ * @throws Error if not initialized
327
+ */
328
+ get address() {
329
+ if (!this._address) {
330
+ throw new Error(
331
+ "TRON signer not initialized. Call initialize() first or use createWDKTronSigner()."
332
+ );
333
+ }
334
+ return this._address;
335
+ }
336
+ /**
337
+ * Check if the adapter is initialized
338
+ */
339
+ get isInitialized() {
340
+ return this._initialized;
341
+ }
342
+ /**
343
+ * Initialize the adapter by fetching the address
344
+ * Must be called before using the signer
345
+ */
346
+ async initialize() {
347
+ if (this._initialized) {
348
+ return;
349
+ }
350
+ this._address = await this._account.getAddress();
351
+ this._initialized = true;
352
+ }
353
+ /**
354
+ * Sign a TRC20 transfer transaction
355
+ *
356
+ * This method:
357
+ * 1. Builds a TRC20 transfer transaction
358
+ * 2. Signs it using the WDK account
359
+ * 3. Returns the hex-encoded signed transaction
360
+ *
361
+ * @param params - Transaction parameters
362
+ * @returns Hex-encoded signed transaction
363
+ */
364
+ async signTransaction(params) {
365
+ if (!params.contractAddress) {
366
+ throw new Error("contractAddress is required");
367
+ }
368
+ if (!params.to) {
369
+ throw new Error("recipient address (to) is required");
370
+ }
371
+ if (!params.amount || BigInt(params.amount) <= 0n) {
372
+ throw new Error("amount must be a positive value");
373
+ }
374
+ const blockInfo = await this.getBlockInfo();
375
+ const feeLimit = params.feeLimit ?? 1e8;
376
+ const transaction = await this.buildTrc20Transaction({
377
+ contractAddress: params.contractAddress,
378
+ to: params.to,
379
+ amount: params.amount,
380
+ feeLimit,
381
+ refBlockBytes: blockInfo.refBlockBytes,
382
+ refBlockHash: blockInfo.refBlockHash,
383
+ expiration: params.expiration ?? blockInfo.expiration
384
+ });
385
+ const signedTx = await this._account.signTransaction(transaction);
386
+ return this.serializeTransaction(signedTx);
387
+ }
388
+ /**
389
+ * Get the current reference block info for transaction building
390
+ * This is required for TRON's replay protection mechanism
391
+ */
392
+ async getBlockInfo() {
393
+ try {
394
+ const response = await fetch(`${this._rpcUrl}/wallet/getnowblock`, {
395
+ method: "POST",
396
+ headers: { "Content-Type": "application/json" },
397
+ body: JSON.stringify({})
398
+ });
399
+ if (!response.ok) {
400
+ throw new Error(`Failed to get block info: ${response.status}`);
401
+ }
402
+ const block = await response.json();
403
+ const blockNum = block.block_header.raw_data.number;
404
+ const refBlockBytes = blockNum.toString(16).padStart(8, "0").slice(-4);
405
+ const refBlockHash = block.blockID.slice(16, 32);
406
+ const expiration = block.block_header.raw_data.timestamp + 6e4;
407
+ return {
408
+ refBlockBytes,
409
+ refBlockHash,
410
+ expiration
411
+ };
412
+ } catch (error) {
413
+ throw new Error(
414
+ `Failed to get TRON block info: ${error instanceof Error ? error.message : String(error)}`
415
+ );
416
+ }
417
+ }
418
+ /**
419
+ * Build a TRC20 transfer transaction
420
+ */
421
+ async buildTrc20Transaction(params) {
422
+ const functionSelector = "transfer(address,uint256)";
423
+ const toAddressHex = this.addressToHex(params.to).slice(2).padStart(64, "0");
424
+ const amountHex = BigInt(params.amount).toString(16).padStart(64, "0");
425
+ const parameter = toAddressHex + amountHex;
426
+ try {
427
+ const response = await fetch(`${this._rpcUrl}/wallet/triggersmartcontract`, {
428
+ method: "POST",
429
+ headers: { "Content-Type": "application/json" },
430
+ body: JSON.stringify({
431
+ owner_address: this.addressToHex(this._address),
432
+ contract_address: this.addressToHex(params.contractAddress),
433
+ function_selector: functionSelector,
434
+ parameter,
435
+ fee_limit: params.feeLimit
436
+ })
437
+ });
438
+ if (!response.ok) {
439
+ throw new Error(`Failed to build transaction: ${response.status}`);
440
+ }
441
+ const result = await response.json();
442
+ if (result.result?.code) {
443
+ throw new Error(`Transaction build failed: ${result.result.message}`);
444
+ }
445
+ return result.transaction;
446
+ } catch (error) {
447
+ throw new Error(
448
+ `Failed to build TRC20 transaction: ${error instanceof Error ? error.message : String(error)}`
449
+ );
450
+ }
451
+ }
452
+ /**
453
+ * Serialize a signed transaction to hex format
454
+ */
455
+ serializeTransaction(signedTx) {
456
+ if (signedTx.signature && signedTx.signature.length > 0) {
457
+ return JSON.stringify(signedTx);
458
+ }
459
+ return signedTx.raw_data_hex;
460
+ }
461
+ /**
462
+ * Convert TRON base58 address to hex format
463
+ */
464
+ addressToHex(address) {
465
+ if (address.startsWith("41") || address.startsWith("0x")) {
466
+ return address.startsWith("0x") ? "41" + address.slice(2) : address;
467
+ }
468
+ const ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
469
+ let num = BigInt(0);
470
+ for (const char of address) {
471
+ num = num * BigInt(58) + BigInt(ALPHABET.indexOf(char));
472
+ }
473
+ let hex = num.toString(16);
474
+ let leadingZeros = 0;
475
+ for (const char of address) {
476
+ if (char === "1") leadingZeros++;
477
+ else break;
478
+ }
479
+ hex = "00".repeat(leadingZeros) + hex;
480
+ return hex.slice(0, 42);
481
+ }
482
+ /**
483
+ * Get TRX balance in SUN
484
+ */
485
+ async getBalance() {
486
+ return this._account.getBalance();
487
+ }
488
+ /**
489
+ * Get TRC20 token balance
490
+ * @param contractAddress - TRC20 contract address
491
+ */
492
+ async getTrc20Balance(contractAddress) {
493
+ return this._account.getTrc20Balance(contractAddress);
494
+ }
495
+ };
496
+ async function createWDKTronSigner(account, rpcUrl) {
497
+ const adapter = new WDKTronSignerAdapter(account, rpcUrl);
498
+ await adapter.initialize();
499
+ return adapter;
500
+ }
501
+
87
502
  // src/cache.ts
88
503
  var DEFAULT_CACHE_CONFIG = {
89
504
  defaultTTL: 3e4,
@@ -573,6 +988,11 @@ var DEFAULT_CHAINS = {
573
988
  network: "eip155:130",
574
989
  name: "unichain"
575
990
  },
991
+ optimism: {
992
+ chainId: 10,
993
+ network: "eip155:10",
994
+ name: "optimism"
995
+ },
576
996
  polygon: {
577
997
  chainId: 137,
578
998
  network: "eip155:137",
@@ -584,6 +1004,7 @@ var DEFAULT_RPC_ENDPOINTS = {
584
1004
  arbitrum: "https://arb1.arbitrum.io/rpc",
585
1005
  base: "https://mainnet.base.org",
586
1006
  ink: "https://rpc-gel.inkonchain.com",
1007
+ optimism: "https://mainnet.optimism.io",
587
1008
  polygon: "https://polygon-rpc.com"
588
1009
  };
589
1010
  var USDT0_ADDRESSES = {
@@ -591,7 +1012,7 @@ var USDT0_ADDRESSES = {
591
1012
  arbitrum: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
592
1013
  ink: "0x0200C29006150606B650577BBE7B6248F58470c1",
593
1014
  berachain: "0x779Ded0c9e1022225f8E0630b35a9b54bE713736",
594
- unichain: "0x588ce4F028D8e7B53B687865d6A67b3A54C75518"
1015
+ unichain: "0x9151434b16b9763660705744891fA906F660EcC5"
595
1016
  };
596
1017
  var USDC_ADDRESSES = {
597
1018
  ethereum: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
@@ -770,6 +1191,9 @@ var WDKErrorCode = /* @__PURE__ */ ((WDKErrorCode2) => {
770
1191
  WDKErrorCode2[WDKErrorCode2["RPC_TIMEOUT"] = 8002] = "RPC_TIMEOUT";
771
1192
  WDKErrorCode2[WDKErrorCode2["RPC_RATE_LIMITED"] = 8003] = "RPC_RATE_LIMITED";
772
1193
  WDKErrorCode2[WDKErrorCode2["RPC_CONNECTION_FAILED"] = 8004] = "RPC_CONNECTION_FAILED";
1194
+ WDKErrorCode2[WDKErrorCode2["PROTOCOL_NOT_REGISTERED"] = 8101] = "PROTOCOL_NOT_REGISTERED";
1195
+ WDKErrorCode2[WDKErrorCode2["PROTOCOL_EXECUTION_FAILED"] = 8102] = "PROTOCOL_EXECUTION_FAILED";
1196
+ WDKErrorCode2[WDKErrorCode2["INVALID_PARAMETER"] = 8103] = "INVALID_PARAMETER";
773
1197
  WDKErrorCode2[WDKErrorCode2["UNKNOWN_ERROR"] = 9999] = "UNKNOWN_ERROR";
774
1198
  return WDKErrorCode2;
775
1199
  })(WDKErrorCode || {});
@@ -1351,6 +1775,13 @@ var WDKSigner = class {
1351
1775
  }
1352
1776
  try {
1353
1777
  const account = await this.getAccount();
1778
+ if (!account.estimateGas) {
1779
+ throw new TransactionError(
1780
+ 6002 /* GAS_ESTIMATION_FAILED */,
1781
+ `Gas estimation is not supported by this WDK account on ${this._chain}`,
1782
+ { chain: this._chain, context: { to: params.to } }
1783
+ );
1784
+ }
1354
1785
  return await withRetry(async () => {
1355
1786
  const estimatePromise = account.estimateGas({
1356
1787
  to: params.to,
@@ -1455,24 +1886,45 @@ var T402WDK = class _T402WDK {
1455
1886
  static _WDK = null;
1456
1887
  static _WalletManagerEvm = null;
1457
1888
  static _BridgeUsdt0Evm = null;
1889
+ // Multi-chain wallet module storage
1890
+ static _WalletModules = {};
1891
+ static _ProtocolModules = {};
1892
+ // Multi-chain signer caches
1893
+ _tonSignerCache = /* @__PURE__ */ new Map();
1894
+ _svmSignerCache = /* @__PURE__ */ new Map();
1895
+ _tronSignerCache = /* @__PURE__ */ new Map();
1458
1896
  /**
1459
1897
  * Register the Tether WDK modules
1460
1898
  *
1461
1899
  * This must be called before creating T402WDK instances if you want
1462
1900
  * to use the actual WDK. Otherwise, a mock implementation is used.
1463
1901
  *
1464
- * @throws {WDKInitializationError} If registration fails
1902
+ * Supports two registration patterns:
1465
1903
  *
1466
- * @example
1467
- * ```typescript
1468
- * import WDK from '@tetherto/wdk';
1469
- * import WalletManagerEvm from '@tetherto/wdk-wallet-evm';
1470
- * import BridgeUsdt0Evm from '@tetherto/wdk-protocol-bridge-usdt0-evm';
1904
+ * 1. Legacy (EVM-only):
1905
+ * ```typescript
1906
+ * T402WDK.registerWDK(WDK, WalletManagerEvm, BridgeUsdt0Evm);
1907
+ * ```
1471
1908
  *
1472
- * T402WDK.registerWDK(WDK, WalletManagerEvm, BridgeUsdt0Evm);
1473
- * ```
1909
+ * 2. Unified (multi-chain):
1910
+ * ```typescript
1911
+ * T402WDK.registerWDK(WDK, {
1912
+ * wallets: {
1913
+ * evm: WalletManagerEvm,
1914
+ * ton: WalletManagerTon,
1915
+ * solana: WalletManagerSolana,
1916
+ * tron: WalletManagerTron,
1917
+ * },
1918
+ * protocols: {
1919
+ * bridgeUsdt0Evm: BridgeUsdt0Evm,
1920
+ * bridgeUsdt0Ton: BridgeUsdt0Ton,
1921
+ * }
1922
+ * });
1923
+ * ```
1924
+ *
1925
+ * @throws {WDKInitializationError} If registration fails
1474
1926
  */
1475
- static registerWDK(WDK, WalletManagerEvm, BridgeUsdt0Evm) {
1927
+ static registerWDK(WDK, modulesOrWalletManager, BridgeUsdt0Evm) {
1476
1928
  if (!WDK) {
1477
1929
  throw new WDKInitializationError("WDK constructor is required");
1478
1930
  }
@@ -1480,8 +1932,18 @@ var T402WDK = class _T402WDK {
1480
1932
  throw new WDKInitializationError("WDK must be a constructor function");
1481
1933
  }
1482
1934
  _T402WDK._WDK = WDK;
1483
- _T402WDK._WalletManagerEvm = WalletManagerEvm ?? null;
1484
- _T402WDK._BridgeUsdt0Evm = BridgeUsdt0Evm ?? null;
1935
+ if (modulesOrWalletManager && typeof modulesOrWalletManager === "object" && ("wallets" in modulesOrWalletManager || "protocols" in modulesOrWalletManager)) {
1936
+ const modules = modulesOrWalletManager;
1937
+ _T402WDK._WalletModules = modules.wallets ?? {};
1938
+ _T402WDK._ProtocolModules = modules.protocols ?? {};
1939
+ _T402WDK._WalletManagerEvm = modules.wallets?.evm ?? null;
1940
+ _T402WDK._BridgeUsdt0Evm = modules.protocols?.bridgeUsdt0Evm ?? null;
1941
+ } else {
1942
+ _T402WDK._WalletManagerEvm = modulesOrWalletManager ?? null;
1943
+ _T402WDK._BridgeUsdt0Evm = BridgeUsdt0Evm ?? null;
1944
+ _T402WDK._WalletModules = { evm: modulesOrWalletManager };
1945
+ _T402WDK._ProtocolModules = { bridgeUsdt0Evm: BridgeUsdt0Evm };
1946
+ }
1485
1947
  }
1486
1948
  /**
1487
1949
  * Check if WDK is registered
@@ -1501,6 +1963,40 @@ var T402WDK = class _T402WDK {
1501
1963
  static isBridgeRegistered() {
1502
1964
  return _T402WDK._BridgeUsdt0Evm !== null;
1503
1965
  }
1966
+ /**
1967
+ * Check if TON wallet manager is registered
1968
+ */
1969
+ static isTonRegistered() {
1970
+ return _T402WDK._WalletModules.ton !== void 0;
1971
+ }
1972
+ /**
1973
+ * Check if Solana wallet manager is registered
1974
+ */
1975
+ static isSolanaRegistered() {
1976
+ return _T402WDK._WalletModules.solana !== void 0;
1977
+ }
1978
+ /**
1979
+ * Check if TRON wallet manager is registered
1980
+ */
1981
+ static isTronRegistered() {
1982
+ return _T402WDK._WalletModules.tron !== void 0;
1983
+ }
1984
+ /**
1985
+ * Get all registered wallet modules
1986
+ */
1987
+ static getRegisteredWalletModules() {
1988
+ return Object.keys(_T402WDK._WalletModules).filter(
1989
+ (key) => _T402WDK._WalletModules[key] !== void 0
1990
+ );
1991
+ }
1992
+ /**
1993
+ * Get all registered protocol modules
1994
+ */
1995
+ static getRegisteredProtocolModules() {
1996
+ return Object.keys(_T402WDK._ProtocolModules).filter(
1997
+ (key) => _T402WDK._ProtocolModules[key] !== void 0
1998
+ );
1999
+ }
1504
2000
  /**
1505
2001
  * Generate a new random seed phrase
1506
2002
  *
@@ -1522,6 +2018,124 @@ var T402WDK = class _T402WDK {
1522
2018
  );
1523
2019
  }
1524
2020
  }
2021
+ /**
2022
+ * Quick setup: seed phrase + chains + modules → ready-to-use T402WDK.
2023
+ *
2024
+ * Registers all provided wallet/protocol modules and creates a fully
2025
+ * configured instance in a single call.
2026
+ *
2027
+ * @example
2028
+ * ```typescript
2029
+ * import WDK from '@tetherto/wdk';
2030
+ * import WalletManagerEvm from '@tetherto/wdk-wallet-evm';
2031
+ * import BridgeUsdt0Evm from '@tetherto/wdk-protocol-bridge-usdt0-evm';
2032
+ *
2033
+ * const wallet = T402WDK.create({
2034
+ * seedPhrase: 'your twelve word seed phrase ...',
2035
+ * chains: {
2036
+ * arbitrum: 'https://arb1.arbitrum.io/rpc',
2037
+ * base: 'https://mainnet.base.org',
2038
+ * },
2039
+ * modules: {
2040
+ * wallets: { evm: WalletManagerEvm },
2041
+ * protocols: { bridgeUsdt0Evm: BridgeUsdt0Evm },
2042
+ * },
2043
+ * });
2044
+ * ```
2045
+ */
2046
+ static create(WDK, config) {
2047
+ _T402WDK.registerWDK(WDK, config.modules);
2048
+ return new _T402WDK(config.seedPhrase, config.chains, config.options);
2049
+ }
2050
+ /**
2051
+ * Create a T402WDK from a pre-configured @tetherto/wdk instance.
2052
+ *
2053
+ * Wraps an existing WDK instance (already has wallets/protocols registered)
2054
+ * into a T402WDK without re-registering modules.
2055
+ *
2056
+ * @param wdkInstance - A pre-configured WDK instance
2057
+ * @param config - EVM chain configuration (RPC endpoints)
2058
+ * @param options - Additional options
2059
+ */
2060
+ static fromWDK(wdkInstance, config = {}, options) {
2061
+ if (!wdkInstance) {
2062
+ throw new WDKInitializationError("WDK instance is required");
2063
+ }
2064
+ const instance = new _T402WDK("__from_wdk__", config, options);
2065
+ instance._wdk = wdkInstance;
2066
+ instance._initializationError = null;
2067
+ return instance;
2068
+ }
2069
+ /**
2070
+ * Get all signers as an array ready for T402 HTTP clients.
2071
+ *
2072
+ * Returns signer entries for all configured EVM chains, plus any
2073
+ * registered non-EVM chains (TON, Solana, TRON).
2074
+ *
2075
+ * @example
2076
+ * ```typescript
2077
+ * const signers = await wallet.getAllSigners();
2078
+ * const client = createT402HTTPClient({ signers });
2079
+ * ```
2080
+ */
2081
+ async getAllSigners(options) {
2082
+ const accountIndex = options?.accountIndex ?? 0;
2083
+ const schemes = options?.schemes ?? ["exact"];
2084
+ const includeNonEvm = options?.includeNonEvm ?? true;
2085
+ const entries = [];
2086
+ for (const chain of this.getConfiguredChains()) {
2087
+ const config = this._normalizedChains.get(chain);
2088
+ if (!config) continue;
2089
+ try {
2090
+ const signer = await this.getSigner(chain, accountIndex);
2091
+ for (const scheme of schemes) {
2092
+ entries.push({
2093
+ scheme,
2094
+ network: config.network,
2095
+ signer,
2096
+ family: "evm"
2097
+ });
2098
+ }
2099
+ } catch {
2100
+ }
2101
+ }
2102
+ if (!includeNonEvm) {
2103
+ return entries;
2104
+ }
2105
+ if (_T402WDK.isTonRegistered()) {
2106
+ try {
2107
+ const signer = await this.getTonSigner(accountIndex);
2108
+ for (const scheme of schemes) {
2109
+ entries.push({ scheme, network: "ton:mainnet", signer, family: "ton" });
2110
+ }
2111
+ } catch {
2112
+ }
2113
+ }
2114
+ if (_T402WDK.isSolanaRegistered()) {
2115
+ try {
2116
+ const signer = await this.getSvmSigner(accountIndex);
2117
+ for (const scheme of schemes) {
2118
+ entries.push({
2119
+ scheme,
2120
+ network: "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
2121
+ signer,
2122
+ family: "svm"
2123
+ });
2124
+ }
2125
+ } catch {
2126
+ }
2127
+ }
2128
+ if (_T402WDK.isTronRegistered()) {
2129
+ try {
2130
+ const signer = await this.getTronSigner(accountIndex);
2131
+ for (const scheme of schemes) {
2132
+ entries.push({ scheme, network: "tron:mainnet", signer, family: "tron" });
2133
+ }
2134
+ } catch {
2135
+ }
2136
+ }
2137
+ return entries;
2138
+ }
1525
2139
  /**
1526
2140
  * Create a new T402WDK instance
1527
2141
  *
@@ -1531,16 +2145,19 @@ var T402WDK = class _T402WDK {
1531
2145
  * @throws {WDKInitializationError} If seed phrase is invalid
1532
2146
  */
1533
2147
  constructor(seedPhrase, config = {}, options = {}) {
1534
- if (!seedPhrase || typeof seedPhrase !== "string") {
1535
- throw new WDKInitializationError("Seed phrase is required and must be a string");
1536
- }
1537
- const words = seedPhrase.trim().split(/\s+/);
1538
- const validWordCounts = [12, 15, 18, 21, 24];
1539
- if (!validWordCounts.includes(words.length)) {
1540
- throw new WDKInitializationError(
1541
- `Invalid seed phrase: expected 12, 15, 18, 21, or 24 words, got ${words.length}`,
1542
- { context: { wordCount: words.length } }
1543
- );
2148
+ const isFromWDK = seedPhrase === "__from_wdk__";
2149
+ if (!isFromWDK) {
2150
+ if (!seedPhrase || typeof seedPhrase !== "string") {
2151
+ throw new WDKInitializationError("Seed phrase is required and must be a string");
2152
+ }
2153
+ const words = seedPhrase.trim().split(/\s+/);
2154
+ const validWordCounts = [12, 15, 18, 21, 24];
2155
+ if (!validWordCounts.includes(words.length)) {
2156
+ throw new WDKInitializationError(
2157
+ `Invalid seed phrase: expected 12, 15, 18, 21, or 24 words, got ${words.length}`,
2158
+ { context: { wordCount: words.length } }
2159
+ );
2160
+ }
1544
2161
  }
1545
2162
  this._seedPhrase = seedPhrase;
1546
2163
  this._balanceCache = new BalanceCache(options.cache);
@@ -1558,7 +2175,7 @@ var T402WDK = class _T402WDK {
1558
2175
  }
1559
2176
  }
1560
2177
  this._addDefaultChainsIfNeeded();
1561
- if (_T402WDK._WDK) {
2178
+ if (!isFromWDK && _T402WDK._WDK) {
1562
2179
  this._initializeWDK();
1563
2180
  }
1564
2181
  }
@@ -1720,6 +2337,195 @@ var T402WDK = class _T402WDK {
1720
2337
  */
1721
2338
  clearSignerCache() {
1722
2339
  this._signerCache.clear();
2340
+ this._tonSignerCache.clear();
2341
+ this._svmSignerCache.clear();
2342
+ this._tronSignerCache.clear();
2343
+ }
2344
+ // ========== Multi-Chain Signers ==========
2345
+ /**
2346
+ * Get a TON signer for T402 payments
2347
+ *
2348
+ * @param accountIndex - HD wallet account index (default: 0)
2349
+ * @throws {ChainError} If TON wallet manager is not registered
2350
+ * @returns An initialized ClientTonSigner
2351
+ *
2352
+ * @example
2353
+ * ```typescript
2354
+ * const tonSigner = await wallet.getTonSigner();
2355
+ *
2356
+ * const client = createT402HTTPClient({
2357
+ * signers: [{ scheme: 'exact', network: 'ton:mainnet', signer: tonSigner }]
2358
+ * });
2359
+ * ```
2360
+ */
2361
+ async getTonSigner(accountIndex = 0) {
2362
+ const cached = this._tonSignerCache.get(accountIndex);
2363
+ if (cached) {
2364
+ return cached;
2365
+ }
2366
+ if (!_T402WDK._WalletModules.ton) {
2367
+ throw new ChainError(
2368
+ 2002 /* CHAIN_NOT_SUPPORTED */,
2369
+ "TON wallet manager not registered. Call T402WDK.registerWDK(WDK, { wallets: { ton: WalletManagerTon } }).",
2370
+ { chain: "ton" }
2371
+ );
2372
+ }
2373
+ try {
2374
+ const account = await this.wdk.getAccount("ton", accountIndex);
2375
+ const signer = await createWDKTonSigner(account);
2376
+ this._tonSignerCache.set(accountIndex, signer);
2377
+ return signer;
2378
+ } catch (error) {
2379
+ if (isWDKError(error)) {
2380
+ throw error;
2381
+ }
2382
+ throw wrapError(error, 3001 /* SIGNER_NOT_INITIALIZED */, "Failed to create TON signer", {
2383
+ chain: "ton",
2384
+ accountIndex
2385
+ });
2386
+ }
2387
+ }
2388
+ /**
2389
+ * Get a Solana (SVM) signer for T402 payments
2390
+ *
2391
+ * @param accountIndex - HD wallet account index (default: 0)
2392
+ * @throws {ChainError} If Solana wallet manager is not registered
2393
+ * @returns An initialized TransactionSigner (ClientSvmSigner)
2394
+ *
2395
+ * @example
2396
+ * ```typescript
2397
+ * const svmSigner = await wallet.getSvmSigner();
2398
+ *
2399
+ * const client = createT402HTTPClient({
2400
+ * signers: [{ scheme: 'exact', network: 'solana:mainnet', signer: svmSigner }]
2401
+ * });
2402
+ * ```
2403
+ */
2404
+ async getSvmSigner(accountIndex = 0) {
2405
+ const cached = this._svmSignerCache.get(accountIndex);
2406
+ if (cached) {
2407
+ return cached;
2408
+ }
2409
+ if (!_T402WDK._WalletModules.solana) {
2410
+ throw new ChainError(
2411
+ 2002 /* CHAIN_NOT_SUPPORTED */,
2412
+ "Solana wallet manager not registered. Call T402WDK.registerWDK(WDK, { wallets: { solana: WalletManagerSolana } }).",
2413
+ { chain: "solana" }
2414
+ );
2415
+ }
2416
+ try {
2417
+ const account = await this.wdk.getAccount(
2418
+ "solana",
2419
+ accountIndex
2420
+ );
2421
+ const signer = await createWDKSvmSigner(account);
2422
+ this._svmSignerCache.set(accountIndex, signer);
2423
+ return signer;
2424
+ } catch (error) {
2425
+ if (isWDKError(error)) {
2426
+ throw error;
2427
+ }
2428
+ throw wrapError(
2429
+ error,
2430
+ 3001 /* SIGNER_NOT_INITIALIZED */,
2431
+ "Failed to create Solana signer",
2432
+ { chain: "solana", accountIndex }
2433
+ );
2434
+ }
2435
+ }
2436
+ /**
2437
+ * Get a TRON signer for T402 payments
2438
+ *
2439
+ * @param accountIndex - HD wallet account index (default: 0)
2440
+ * @param rpcUrl - Optional custom RPC URL (default: https://api.trongrid.io)
2441
+ * @throws {ChainError} If TRON wallet manager is not registered
2442
+ * @returns An initialized ClientTronSigner
2443
+ *
2444
+ * @example
2445
+ * ```typescript
2446
+ * const tronSigner = await wallet.getTronSigner();
2447
+ *
2448
+ * const client = createT402HTTPClient({
2449
+ * signers: [{ scheme: 'exact', network: 'tron:mainnet', signer: tronSigner }]
2450
+ * });
2451
+ * ```
2452
+ */
2453
+ async getTronSigner(accountIndex = 0, rpcUrl) {
2454
+ if (!rpcUrl) {
2455
+ const cached = this._tronSignerCache.get(accountIndex);
2456
+ if (cached) {
2457
+ return cached;
2458
+ }
2459
+ }
2460
+ if (!_T402WDK._WalletModules.tron) {
2461
+ throw new ChainError(
2462
+ 2002 /* CHAIN_NOT_SUPPORTED */,
2463
+ "TRON wallet manager not registered. Call T402WDK.registerWDK(WDK, { wallets: { tron: WalletManagerTron } }).",
2464
+ { chain: "tron" }
2465
+ );
2466
+ }
2467
+ try {
2468
+ const account = await this.wdk.getAccount("tron", accountIndex);
2469
+ const signer = await createWDKTronSigner(account, rpcUrl);
2470
+ if (!rpcUrl) {
2471
+ this._tronSignerCache.set(accountIndex, signer);
2472
+ }
2473
+ return signer;
2474
+ } catch (error) {
2475
+ if (isWDKError(error)) {
2476
+ throw error;
2477
+ }
2478
+ throw wrapError(error, 3001 /* SIGNER_NOT_INITIALIZED */, "Failed to create TRON signer", {
2479
+ chain: "tron",
2480
+ accountIndex
2481
+ });
2482
+ }
2483
+ }
2484
+ /**
2485
+ * Get a signer for a specific chain family
2486
+ *
2487
+ * @param family - Chain family (evm, svm, ton, tron)
2488
+ * @param chainOrIndex - Chain name for EVM, or account index for others
2489
+ * @param accountIndex - Account index (only used for EVM)
2490
+ * @throws {ChainError} If chain family is not supported or not configured
2491
+ * @returns An appropriate signer for the chain family
2492
+ *
2493
+ * @example
2494
+ * ```typescript
2495
+ * // Get EVM signer for Arbitrum
2496
+ * const evmSigner = await wallet.getSignerByFamily('evm', 'arbitrum');
2497
+ *
2498
+ * // Get TON signer
2499
+ * const tonSigner = await wallet.getSignerByFamily('ton');
2500
+ *
2501
+ * // Get Solana signer with account index 1
2502
+ * const svmSigner = await wallet.getSignerByFamily('svm', 1);
2503
+ * ```
2504
+ */
2505
+ async getSignerByFamily(family, chainOrIndex, accountIndex = 0) {
2506
+ switch (family) {
2507
+ case "evm":
2508
+ if (typeof chainOrIndex !== "string") {
2509
+ throw new ChainError(
2510
+ 2003 /* INVALID_CHAIN_CONFIG */,
2511
+ 'EVM signers require a chain name (e.g., "arbitrum", "ethereum")',
2512
+ { chain: family }
2513
+ );
2514
+ }
2515
+ return this.getSigner(chainOrIndex, accountIndex);
2516
+ case "ton":
2517
+ return this.getTonSigner(typeof chainOrIndex === "number" ? chainOrIndex : accountIndex);
2518
+ case "svm":
2519
+ return this.getSvmSigner(typeof chainOrIndex === "number" ? chainOrIndex : accountIndex);
2520
+ case "tron":
2521
+ return this.getTronSigner(typeof chainOrIndex === "number" ? chainOrIndex : accountIndex);
2522
+ default:
2523
+ throw new ChainError(
2524
+ 2002 /* CHAIN_NOT_SUPPORTED */,
2525
+ `Chain family "${family}" is not supported. Available: evm, ton, svm, tron`,
2526
+ { chain: family }
2527
+ );
2528
+ }
1723
2529
  }
1724
2530
  /**
1725
2531
  * Get wallet address for a chain
@@ -2067,6 +2873,118 @@ var T402WDK = class _T402WDK {
2067
2873
  }
2068
2874
  return (0, import_evm.getBridgeableChains)().filter((chain) => chain !== fromChain);
2069
2875
  }
2876
+ // ========== Swap Protocol ==========
2877
+ /**
2878
+ * Check if the Velora swap protocol is registered and available
2879
+ */
2880
+ canSwap() {
2881
+ return _T402WDK._ProtocolModules.swapVeloraEvm !== void 0;
2882
+ }
2883
+ /**
2884
+ * Get a swap quote for converting a token to USDT0
2885
+ *
2886
+ * @param chain - Chain name (e.g., "ethereum", "arbitrum")
2887
+ * @param fromToken - Input token address
2888
+ * @param amount - Amount to swap in smallest units
2889
+ * @throws {WDKError} If swap protocol is not registered or quote fails
2890
+ */
2891
+ async getSwapQuote(chain, fromToken, amount) {
2892
+ if (!this.canSwap()) {
2893
+ throw new WDKError(
2894
+ 8101 /* PROTOCOL_NOT_REGISTERED */,
2895
+ "Velora swap protocol not registered. Call T402WDK.registerWDK(WDK, { protocols: { swapVeloraEvm: SwapVeloraEvm } })."
2896
+ );
2897
+ }
2898
+ const usdt0Address = USDT0_ADDRESSES[chain];
2899
+ if (!usdt0Address) {
2900
+ throw new ChainError(
2901
+ 2002 /* CHAIN_NOT_SUPPORTED */,
2902
+ `Chain "${chain}" does not have a known USDT0 address`,
2903
+ { chain }
2904
+ );
2905
+ }
2906
+ try {
2907
+ const result = await this.wdk.executeProtocol("swap-velora", {
2908
+ action: "quote",
2909
+ chain,
2910
+ fromToken,
2911
+ toToken: usdt0Address,
2912
+ amount: amount.toString()
2913
+ });
2914
+ return result;
2915
+ } catch (error) {
2916
+ throw wrapError(
2917
+ error,
2918
+ 8102 /* PROTOCOL_EXECUTION_FAILED */,
2919
+ `Failed to get swap quote on ${chain}`,
2920
+ { chain, fromToken, amount: amount.toString() }
2921
+ );
2922
+ }
2923
+ }
2924
+ /**
2925
+ * Swap any token to USDT0 for payment
2926
+ *
2927
+ * Uses the Velora protocol to execute a token swap on the specified chain.
2928
+ *
2929
+ * @param params - Swap parameters
2930
+ * @throws {WDKError} If swap protocol is not registered or swap fails
2931
+ *
2932
+ * @example
2933
+ * ```typescript
2934
+ * // Swap 0.1 WETH to USDT0 on Arbitrum
2935
+ * const result = await wallet.swapAndPay({
2936
+ * chain: 'arbitrum',
2937
+ * fromToken: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1', // WETH
2938
+ * amount: 100000000000000000n, // 0.1 WETH
2939
+ * maxSlippage: 0.005,
2940
+ * });
2941
+ * ```
2942
+ */
2943
+ async swapAndPay(params) {
2944
+ if (!this.canSwap()) {
2945
+ throw new WDKError(
2946
+ 8101 /* PROTOCOL_NOT_REGISTERED */,
2947
+ "Velora swap protocol not registered. Call T402WDK.registerWDK(WDK, { protocols: { swapVeloraEvm: SwapVeloraEvm } })."
2948
+ );
2949
+ }
2950
+ const usdt0Address = USDT0_ADDRESSES[params.chain];
2951
+ if (!usdt0Address) {
2952
+ throw new ChainError(
2953
+ 2002 /* CHAIN_NOT_SUPPORTED */,
2954
+ `Chain "${params.chain}" does not have a known USDT0 address`,
2955
+ { chain: params.chain }
2956
+ );
2957
+ }
2958
+ if (params.maxSlippage !== void 0 && (params.maxSlippage < 0 || params.maxSlippage > 0.5)) {
2959
+ throw new WDKError(
2960
+ 8103 /* INVALID_PARAMETER */,
2961
+ "maxSlippage must be between 0 and 0.5 (0% to 50%)"
2962
+ );
2963
+ }
2964
+ try {
2965
+ const result = await this.wdk.executeProtocol("swap-velora", {
2966
+ action: "swap",
2967
+ chain: params.chain,
2968
+ fromToken: params.fromToken,
2969
+ toToken: usdt0Address,
2970
+ amount: params.amount.toString(),
2971
+ maxSlippage: params.maxSlippage ?? 5e-3
2972
+ });
2973
+ this._balanceCache.invalidateChain(params.chain);
2974
+ return result;
2975
+ } catch (error) {
2976
+ throw wrapError(
2977
+ error,
2978
+ 8102 /* PROTOCOL_EXECUTION_FAILED */,
2979
+ `Failed to execute swap on ${params.chain}`,
2980
+ {
2981
+ chain: params.chain,
2982
+ fromToken: params.fromToken,
2983
+ amount: params.amount.toString()
2984
+ }
2985
+ );
2986
+ }
2987
+ }
2070
2988
  // ========== Cache Management ==========
2071
2989
  /**
2072
2990
  * Check if balance caching is enabled
@@ -2120,6 +3038,9 @@ var T402WDK = class _T402WDK {
2120
3038
  dispose() {
2121
3039
  this._balanceCache.dispose();
2122
3040
  this._signerCache.clear();
3041
+ this._tonSignerCache.clear();
3042
+ this._svmSignerCache.clear();
3043
+ this._tronSignerCache.clear();
2123
3044
  }
2124
3045
  };
2125
3046
  function formatTokenAmount(amount, decimals) {
@@ -2203,6 +3124,94 @@ function createDirectBridge(signer, chain) {
2203
3124
  // src/index.ts
2204
3125
  var import_evm3 = require("@t402/evm");
2205
3126
 
3127
+ // src/compatibility.ts
3128
+ var WDK_COMPATIBILITY = {
3129
+ /** Minimum supported @tetherto/wdk version */
3130
+ minVersion: "1.0.0-beta.0",
3131
+ /** Versions that have been tested */
3132
+ testedVersions: ["1.0.0-beta.3", "1.0.0-beta.4", "1.0.0-beta.5"],
3133
+ /** Tested wallet-evm module versions */
3134
+ walletEvmVersions: ["1.0.0-beta.5", "2.0.0-rc.1"],
3135
+ /** Feature availability by @tetherto/wdk core version */
3136
+ features: {
3137
+ signTypedData: "1.0.0-beta.0",
3138
+ estimateGas: "1.0.0-beta.3",
3139
+ multiChainWallets: "1.0.0-beta.0",
3140
+ bridgeProtocol: "1.0.0-beta.3",
3141
+ swapProtocol: "1.0.0-beta.4"
3142
+ },
3143
+ /** Known wallet module minimum versions */
3144
+ walletModuleVersions: {
3145
+ evm: "1.0.0-beta.5",
3146
+ ton: "1.0.0-beta.7",
3147
+ btc: "1.0.0-beta.5",
3148
+ tron: "1.0.0-beta.4",
3149
+ solana: "1.0.0-beta.5",
3150
+ spark: "1.0.0-beta.6"
3151
+ }
3152
+ };
3153
+ function parseVersion(version) {
3154
+ const match = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/);
3155
+ if (!match) {
3156
+ return { major: 0, minor: 0, patch: 0, prerelease: "" };
3157
+ }
3158
+ return {
3159
+ major: parseInt(match[1], 10),
3160
+ minor: parseInt(match[2], 10),
3161
+ patch: parseInt(match[3], 10),
3162
+ prerelease: match[4] ?? ""
3163
+ };
3164
+ }
3165
+ function compareVersions(a, b) {
3166
+ const va = parseVersion(a);
3167
+ const vb = parseVersion(b);
3168
+ if (va.major !== vb.major) return va.major < vb.major ? -1 : 1;
3169
+ if (va.minor !== vb.minor) return va.minor < vb.minor ? -1 : 1;
3170
+ if (va.patch !== vb.patch) return va.patch < vb.patch ? -1 : 1;
3171
+ if (va.prerelease && !vb.prerelease) return -1;
3172
+ if (!va.prerelease && vb.prerelease) return 1;
3173
+ if (va.prerelease && vb.prerelease) {
3174
+ return va.prerelease < vb.prerelease ? -1 : va.prerelease > vb.prerelease ? 1 : 0;
3175
+ }
3176
+ return 0;
3177
+ }
3178
+ function checkWdkCompatibility(version) {
3179
+ const warnings = [];
3180
+ if (compareVersions(version, WDK_COMPATIBILITY.minVersion) < 0) {
3181
+ return {
3182
+ compatible: false,
3183
+ warnings: [
3184
+ `@tetherto/wdk ${version} is below minimum supported version ${WDK_COMPATIBILITY.minVersion}`
3185
+ ]
3186
+ };
3187
+ }
3188
+ const isTested = WDK_COMPATIBILITY.testedVersions.includes(version);
3189
+ if (!isTested) {
3190
+ warnings.push(
3191
+ `@tetherto/wdk ${version} has not been explicitly tested. Tested versions: ${WDK_COMPATIBILITY.testedVersions.join(", ")}`
3192
+ );
3193
+ }
3194
+ for (const [feature, minFeatureVersion] of Object.entries(WDK_COMPATIBILITY.features)) {
3195
+ if (compareVersions(version, minFeatureVersion) < 0) {
3196
+ warnings.push(`Feature '${feature}' requires @tetherto/wdk >= ${minFeatureVersion}`);
3197
+ }
3198
+ }
3199
+ return { compatible: true, warnings };
3200
+ }
3201
+ function checkWalletEvmCompatibility(version) {
3202
+ const warnings = [];
3203
+ const isTested = WDK_COMPATIBILITY.walletEvmVersions.includes(version);
3204
+ if (!isTested) {
3205
+ warnings.push(
3206
+ `@tetherto/wdk-wallet-evm ${version} has not been explicitly tested. Tested versions: ${WDK_COMPATIBILITY.walletEvmVersions.join(", ")}`
3207
+ );
3208
+ }
3209
+ return { compatible: true, warnings };
3210
+ }
3211
+ function getWalletModuleMinVersion(module2) {
3212
+ return WDK_COMPATIBILITY.walletModuleVersions[module2];
3213
+ }
3214
+
2206
3215
  // src/hardware/types.ts
2207
3216
  var HardwareWalletErrorCode = /* @__PURE__ */ ((HardwareWalletErrorCode2) => {
2208
3217
  HardwareWalletErrorCode2["DEVICE_NOT_FOUND"] = "DEVICE_NOT_FOUND";
@@ -2858,11 +3867,20 @@ function isHardwareWalletSupported() {
2858
3867
  WDKErrorCode,
2859
3868
  WDKInitializationError,
2860
3869
  WDKSigner,
3870
+ WDKSvmSignerAdapter,
3871
+ WDKTonSignerAdapter,
3872
+ WDKTronSignerAdapter,
3873
+ WDK_COMPATIBILITY,
2861
3874
  WdkBridge,
3875
+ checkWalletEvmCompatibility,
3876
+ checkWdkCompatibility,
2862
3877
  createDirectBridge,
2863
3878
  createLedgerSigner,
2864
3879
  createTrezorSigner,
2865
3880
  createWDKSigner,
3881
+ createWDKSvmSigner,
3882
+ createWDKTonSigner,
3883
+ createWDKTronSigner,
2866
3884
  detectHardwareWalletSupport,
2867
3885
  getBridgeableChains,
2868
3886
  getChainFromNetwork,
@@ -2870,6 +3888,7 @@ function isHardwareWalletSupported() {
2870
3888
  getNetworkFromChain,
2871
3889
  getPreferredToken,
2872
3890
  getUsdt0Chains,
3891
+ getWalletModuleMinVersion,
2873
3892
  hasErrorCode,
2874
3893
  isHardwareWalletSupported,
2875
3894
  isWDKError,