@enclave-hq/wallet-sdk 1.0.0 → 1.0.2

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.
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  var EventEmitter = require('eventemitter3');
6
+ var chainUtils = require('@enclave-hq/chain-utils');
6
7
  var viem = require('viem');
7
8
  var accounts = require('viem/accounts');
8
9
 
@@ -39,15 +40,7 @@ var TypedEventEmitter = class {
39
40
  return this;
40
41
  }
41
42
  };
42
-
43
- // src/core/types.ts
44
- var ChainType = /* @__PURE__ */ ((ChainType4) => {
45
- ChainType4["EVM"] = "evm";
46
- ChainType4["TRON"] = "tron";
47
- ChainType4["SOLANA"] = "solana";
48
- ChainType4["COSMOS"] = "cosmos";
49
- return ChainType4;
50
- })(ChainType || {});
43
+ var ChainType = chainUtils.ChainType;
51
44
  var WalletType = /* @__PURE__ */ ((WalletType3) => {
52
45
  WalletType3["METAMASK"] = "metamask";
53
46
  WalletType3["WALLETCONNECT"] = "walletconnect";
@@ -311,14 +304,15 @@ function shortenAddress(address, chars = 4) {
311
304
  const formatted = viem.getAddress(address);
312
305
  return `${formatted.substring(0, chars + 2)}...${formatted.substring(42 - chars)}`;
313
306
  }
314
-
315
- // src/utils/chain-info.ts
316
307
  var CHAIN_INFO = {
317
308
  // EVM Mainnet
318
309
  1: {
319
310
  id: 1,
311
+ slip44: 60,
312
+ // Ethereum SLIP-44
320
313
  name: "Ethereum Mainnet",
321
- chainType: "evm" /* EVM */,
314
+ chainType: chainUtils.ChainType.EVM,
315
+ symbol: "ETH",
322
316
  nativeCurrency: {
323
317
  name: "Ether",
324
318
  symbol: "ETH",
@@ -331,7 +325,8 @@ var CHAIN_INFO = {
331
325
  11155111: {
332
326
  id: 11155111,
333
327
  name: "Sepolia Testnet",
334
- chainType: "evm" /* EVM */,
328
+ chainType: chainUtils.ChainType.EVM,
329
+ symbol: "ETH",
335
330
  nativeCurrency: {
336
331
  name: "Sepolia Ether",
337
332
  symbol: "ETH",
@@ -343,8 +338,11 @@ var CHAIN_INFO = {
343
338
  // Binance Smart Chain
344
339
  56: {
345
340
  id: 56,
341
+ slip44: 714,
342
+ // BSC SLIP-44
346
343
  name: "BNB Smart Chain",
347
- chainType: "evm" /* EVM */,
344
+ chainType: chainUtils.ChainType.EVM,
345
+ symbol: "BNB",
348
346
  nativeCurrency: {
349
347
  name: "BNB",
350
348
  symbol: "BNB",
@@ -356,7 +354,8 @@ var CHAIN_INFO = {
356
354
  97: {
357
355
  id: 97,
358
356
  name: "BNB Smart Chain Testnet",
359
- chainType: "evm" /* EVM */,
357
+ chainType: chainUtils.ChainType.EVM,
358
+ symbol: "BNB",
360
359
  nativeCurrency: {
361
360
  name: "BNB",
362
361
  symbol: "BNB",
@@ -368,8 +367,11 @@ var CHAIN_INFO = {
368
367
  // Polygon
369
368
  137: {
370
369
  id: 137,
370
+ slip44: 966,
371
+ // Polygon SLIP-44
371
372
  name: "Polygon Mainnet",
372
- chainType: "evm" /* EVM */,
373
+ chainType: chainUtils.ChainType.EVM,
374
+ symbol: "MATIC",
373
375
  nativeCurrency: {
374
376
  name: "MATIC",
375
377
  symbol: "MATIC",
@@ -381,7 +383,8 @@ var CHAIN_INFO = {
381
383
  80002: {
382
384
  id: 80002,
383
385
  name: "Polygon Amoy Testnet",
384
- chainType: "evm" /* EVM */,
386
+ chainType: chainUtils.ChainType.EVM,
387
+ symbol: "MATIC",
385
388
  nativeCurrency: {
386
389
  name: "MATIC",
387
390
  symbol: "MATIC",
@@ -393,8 +396,11 @@ var CHAIN_INFO = {
393
396
  // Tron
394
397
  195: {
395
398
  id: 195,
399
+ slip44: 195,
400
+ // Tron SLIP-44
396
401
  name: "Tron Mainnet",
397
- chainType: "tron" /* TRON */,
402
+ chainType: chainUtils.ChainType.TRON,
403
+ symbol: "TRX",
398
404
  nativeCurrency: {
399
405
  name: "TRX",
400
406
  symbol: "TRX",
@@ -406,8 +412,11 @@ var CHAIN_INFO = {
406
412
  // Arbitrum
407
413
  42161: {
408
414
  id: 42161,
415
+ slip44: 1042161,
416
+ // Custom SLIP-44 (1000000 + 42161)
409
417
  name: "Arbitrum One",
410
- chainType: "evm" /* EVM */,
418
+ chainType: chainUtils.ChainType.EVM,
419
+ symbol: "ETH",
411
420
  nativeCurrency: {
412
421
  name: "Ether",
413
422
  symbol: "ETH",
@@ -419,8 +428,11 @@ var CHAIN_INFO = {
419
428
  // Optimism
420
429
  10: {
421
430
  id: 10,
431
+ slip44: 1000010,
432
+ // Custom SLIP-44 (1000000 + 10)
422
433
  name: "Optimism",
423
- chainType: "evm" /* EVM */,
434
+ chainType: chainUtils.ChainType.EVM,
435
+ symbol: "ETH",
424
436
  nativeCurrency: {
425
437
  name: "Ether",
426
438
  symbol: "ETH",
@@ -432,8 +444,11 @@ var CHAIN_INFO = {
432
444
  // Avalanche
433
445
  43114: {
434
446
  id: 43114,
447
+ slip44: 9e3,
448
+ // Avalanche SLIP-44
435
449
  name: "Avalanche C-Chain",
436
- chainType: "evm" /* EVM */,
450
+ chainType: chainUtils.ChainType.EVM,
451
+ symbol: "AVAX",
437
452
  nativeCurrency: {
438
453
  name: "AVAX",
439
454
  symbol: "AVAX",
@@ -450,10 +465,10 @@ function getChainType(chainId) {
450
465
  return CHAIN_INFO[chainId]?.chainType;
451
466
  }
452
467
  function isEVMChain(chainId) {
453
- return getChainType(chainId) === "evm" /* EVM */;
468
+ return getChainType(chainId) === chainUtils.ChainType.EVM;
454
469
  }
455
470
  function isTronChain(chainId) {
456
- return getChainType(chainId) === "tron" /* TRON */;
471
+ return getChainType(chainId) === chainUtils.ChainType.TRON;
457
472
  }
458
473
 
459
474
  // src/adapters/evm/metamask.ts
@@ -461,26 +476,34 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
461
476
  constructor() {
462
477
  super(...arguments);
463
478
  this.type = "metamask" /* METAMASK */;
464
- this.chainType = "evm" /* EVM */;
479
+ this.chainType = ChainType.EVM;
465
480
  this.name = "MetaMask";
466
481
  this.icon = "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg";
467
482
  this.walletClient = null;
468
483
  this.publicClient = null;
469
484
  /**
470
485
  * 处理账户变化
486
+ *
487
+ * 注意:MetaMask 的行为
488
+ * - 切换到已连接的账户:触发事件,返回新账户 ['0xNewAddress']
489
+ * - 切换到未连接的账户:不触发事件(用户需要手动断开和重新连接)
490
+ * - 锁定钱包:触发事件,返回空数组 []
471
491
  */
472
492
  this.handleAccountsChanged = (accounts) => {
493
+ console.log("[MetaMask] accountsChanged event triggered:", accounts);
473
494
  if (accounts.length === 0) {
495
+ console.log("[MetaMask] Disconnecting: wallet locked or manually disconnected");
474
496
  this.setState("disconnected" /* DISCONNECTED */);
475
497
  this.setAccount(null);
476
498
  this.emitAccountChanged(null);
477
499
  } else {
478
500
  const address = formatEVMAddress(accounts[0]);
501
+ console.log("[MetaMask] Account changed to:", address);
479
502
  const account = {
480
503
  universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
481
504
  nativeAddress: address,
482
505
  chainId: this.currentAccount.chainId,
483
- chainType: "evm" /* EVM */,
506
+ chainType: ChainType.EVM,
484
507
  isActive: true
485
508
  };
486
509
  this.setAccount(account);
@@ -532,21 +555,23 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
532
555
  if (chainId && chainId !== parsedChainId) {
533
556
  await this.switchChain(chainId);
534
557
  }
558
+ const finalChainId = chainId || parsedChainId;
559
+ const viemChain = this.getViemChain(finalChainId);
535
560
  this.walletClient = viem.createWalletClient({
536
561
  account: accounts[0],
562
+ chain: viemChain,
537
563
  transport: viem.custom(provider)
538
564
  });
539
- const finalChainId = chainId || parsedChainId;
540
565
  this.publicClient = viem.createPublicClient({
541
- chain: this.getViemChain(finalChainId),
542
- transport: viem.http()
566
+ chain: viemChain,
567
+ transport: viem.custom(provider)
543
568
  });
544
569
  const address = formatEVMAddress(accounts[0]);
545
570
  const account = {
546
571
  universalAddress: createUniversalAddress(finalChainId, address),
547
572
  nativeAddress: address,
548
573
  chainId: finalChainId,
549
- chainType: "evm" /* EVM */,
574
+ chainType: ChainType.EVM,
550
575
  isActive: true
551
576
  };
552
577
  this.setState("connected" /* CONNECTED */);
@@ -600,6 +625,40 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
600
625
  throw error;
601
626
  }
602
627
  }
628
+ /**
629
+ * 签名交易
630
+ *
631
+ * Note: This signs a raw transaction without sending it.
632
+ * The transaction can be broadcast later using the returned signature.
633
+ */
634
+ async signTransaction(transaction) {
635
+ this.ensureConnected();
636
+ try {
637
+ const provider = this.getBrowserProvider();
638
+ const tx = {
639
+ from: this.currentAccount.nativeAddress,
640
+ to: transaction.to,
641
+ value: transaction.value ? `0x${BigInt(transaction.value).toString(16)}` : void 0,
642
+ data: transaction.data || "0x",
643
+ gas: transaction.gas ? `0x${BigInt(transaction.gas).toString(16)}` : void 0,
644
+ gasPrice: transaction.gasPrice && transaction.gasPrice !== "auto" ? `0x${BigInt(transaction.gasPrice).toString(16)}` : void 0,
645
+ maxFeePerGas: transaction.maxFeePerGas ? `0x${BigInt(transaction.maxFeePerGas).toString(16)}` : void 0,
646
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas ? `0x${BigInt(transaction.maxPriorityFeePerGas).toString(16)}` : void 0,
647
+ nonce: transaction.nonce !== void 0 ? `0x${transaction.nonce.toString(16)}` : void 0,
648
+ chainId: transaction.chainId || this.currentAccount.chainId
649
+ };
650
+ const signature = await provider.request({
651
+ method: "eth_signTransaction",
652
+ params: [tx]
653
+ });
654
+ return signature;
655
+ } catch (error) {
656
+ if (error.code === 4001) {
657
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
658
+ }
659
+ throw error;
660
+ }
661
+ }
603
662
  /**
604
663
  * 切换链
605
664
  */
@@ -680,6 +739,16 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
680
739
  throw new Error("Wallet client not initialized");
681
740
  }
682
741
  try {
742
+ console.log("\u{1F50D} [MetaMask writeContract] params.gasPrice:", params.gasPrice, "type:", typeof params.gasPrice);
743
+ let processedGasPrice;
744
+ if (!params.gasPrice) {
745
+ processedGasPrice = void 0;
746
+ } else if (params.gasPrice === "auto") {
747
+ processedGasPrice = void 0;
748
+ } else {
749
+ processedGasPrice = BigInt(params.gasPrice);
750
+ }
751
+ console.log("\u{1F50D} [MetaMask writeContract] processedGasPrice:", processedGasPrice);
683
752
  const txHash = await this.walletClient.writeContract({
684
753
  address: params.address,
685
754
  abi: params.abi,
@@ -687,7 +756,7 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
687
756
  ...params.args ? { args: params.args } : {},
688
757
  value: params.value ? BigInt(params.value) : void 0,
689
758
  gas: params.gas ? BigInt(params.gas) : void 0,
690
- gasPrice: params.gasPrice ? BigInt(params.gasPrice) : void 0
759
+ gasPrice: processedGasPrice
691
760
  });
692
761
  return txHash;
693
762
  } catch (error) {
@@ -830,9 +899,14 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
830
899
  constructor() {
831
900
  super(...arguments);
832
901
  this.type = "tronlink" /* TRONLINK */;
833
- this.chainType = "tron" /* TRON */;
902
+ this.chainType = ChainType.TRON;
834
903
  this.name = "TronLink";
835
904
  this.icon = "https://www.tronlink.org/static/logoIcon.svg";
905
+ /**
906
+ * 轮询检测账户变化(备用方案)
907
+ */
908
+ this.pollingInterval = null;
909
+ this.lastKnownAddress = null;
836
910
  /**
837
911
  * 处理账户变化
838
912
  */
@@ -847,7 +921,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
847
921
  universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
848
922
  nativeAddress: address,
849
923
  chainId: this.currentAccount.chainId,
850
- chainType: "tron" /* TRON */,
924
+ chainType: ChainType.TRON,
851
925
  isActive: true
852
926
  };
853
927
  this.setAccount(account);
@@ -886,7 +960,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
886
960
  universalAddress: createUniversalAddress(tronChainId, address),
887
961
  nativeAddress: address,
888
962
  chainId: tronChainId,
889
- chainType: "tron" /* TRON */,
963
+ chainType: ChainType.TRON,
890
964
  isActive: true
891
965
  };
892
966
  this.setState("connected" /* CONNECTED */);
@@ -904,20 +978,177 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
904
978
  }
905
979
  /**
906
980
  * 签名消息
981
+ *
982
+ * Note: TronLink supports two signing methods:
983
+ * - trx.sign(): Signs a transaction object
984
+ * - trx.signMessageV2(): Signs a plain text message (what we use here)
907
985
  */
908
986
  async signMessage(message) {
909
987
  this.ensureConnected();
910
988
  try {
911
989
  const tronWeb = this.getTronWeb();
912
- const signature = await tronWeb.trx.sign(message);
913
- return signature;
990
+ if (typeof tronWeb.trx.signMessageV2 === "function") {
991
+ const signature = await tronWeb.trx.signMessageV2(message);
992
+ return signature;
993
+ } else {
994
+ console.warn("[TronLink] signMessageV2 not available, falling back to sign()");
995
+ const signature = await tronWeb.trx.sign(message);
996
+ return signature;
997
+ }
914
998
  } catch (error) {
915
999
  if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
916
1000
  throw new SignatureRejectedError();
917
1001
  }
1002
+ if (error.message?.includes("Invalid transaction")) {
1003
+ throw new Error("Invalid message format. For transaction signing, use signTransaction() instead.");
1004
+ }
1005
+ throw error;
1006
+ }
1007
+ }
1008
+ /**
1009
+ * 签名交易
1010
+ *
1011
+ * Note: This uses trx.sign() which is specifically for signing transaction objects.
1012
+ * For plain text message signing, use signMessage() instead.
1013
+ */
1014
+ async signTransaction(transaction) {
1015
+ this.ensureConnected();
1016
+ try {
1017
+ const tronWeb = this.getTronWeb();
1018
+ const signature = await tronWeb.trx.sign(transaction);
1019
+ return signature;
1020
+ } catch (error) {
1021
+ if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
1022
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
1023
+ }
1024
+ if (error.message?.includes("Invalid transaction")) {
1025
+ throw new Error("Invalid transaction format. Please provide a properly formatted Tron transaction object.");
1026
+ }
918
1027
  throw error;
919
1028
  }
920
1029
  }
1030
+ /**
1031
+ * 读取合约
1032
+ */
1033
+ async readContract(params) {
1034
+ this.ensureConnected();
1035
+ try {
1036
+ const tronWeb = this.getTronWeb();
1037
+ const contract = await tronWeb.contract(params.abi, params.address);
1038
+ const result = await contract[params.functionName](...params.args || []).call();
1039
+ return result;
1040
+ } catch (error) {
1041
+ console.error("Read contract error:", error);
1042
+ throw new Error(`Failed to read contract: ${error.message}`);
1043
+ }
1044
+ }
1045
+ /**
1046
+ * 写入合约
1047
+ */
1048
+ async writeContract(params) {
1049
+ this.ensureConnected();
1050
+ try {
1051
+ const tronWeb = this.getTronWeb();
1052
+ console.log("[TronLink] writeContract params:", {
1053
+ address: params.address,
1054
+ functionName: params.functionName,
1055
+ args: params.args,
1056
+ value: params.value,
1057
+ gas: params.gas
1058
+ });
1059
+ if (!params.args || params.args.length === 0) {
1060
+ throw new Error("Contract function arguments are required");
1061
+ }
1062
+ const hasUndefined = params.args.some((arg) => arg === void 0 || arg === null);
1063
+ if (hasUndefined) {
1064
+ console.error("[TronLink] Invalid args detected:", params.args);
1065
+ throw new Error(`Invalid contract arguments: some arguments are undefined or null`);
1066
+ }
1067
+ const functionAbi = params.abi.find(
1068
+ (item) => item.name === params.functionName && item.type === "function"
1069
+ );
1070
+ if (!functionAbi) {
1071
+ throw new Error(`Function ${params.functionName} not found in ABI`);
1072
+ }
1073
+ console.log("[TronLink] Function ABI:", functionAbi);
1074
+ console.log("[TronLink] Calling with args:", params.args);
1075
+ const options = {
1076
+ feeLimit: params.gas || 1e8,
1077
+ // 默认 100 TRX 的能量限制
1078
+ callValue: params.value || 0
1079
+ // 发送的 TRX 数量(单位:SUN)
1080
+ };
1081
+ const parameter = functionAbi.inputs.map((input, index) => ({
1082
+ type: input.type,
1083
+ value: params.args[index]
1084
+ }));
1085
+ console.log("[TronLink] Transaction options:", options);
1086
+ console.log("[TronLink] Parameters:", parameter);
1087
+ const transaction = await tronWeb.transactionBuilder.triggerSmartContract(
1088
+ params.address,
1089
+ params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")",
1090
+ options,
1091
+ parameter,
1092
+ this.currentAccount.nativeAddress
1093
+ );
1094
+ console.log("[TronLink] Transaction built:", transaction);
1095
+ if (!transaction || !transaction.transaction) {
1096
+ throw new Error("Failed to build transaction");
1097
+ }
1098
+ const signedTx = await tronWeb.trx.sign(transaction.transaction);
1099
+ const broadcast = await tronWeb.trx.sendRawTransaction(signedTx);
1100
+ console.log("[TronLink] Broadcast result:", broadcast);
1101
+ if (!broadcast.result) {
1102
+ throw new Error(broadcast.message || "Transaction broadcast failed");
1103
+ }
1104
+ const txHash = broadcast.txid || broadcast.transaction?.txID;
1105
+ console.log("[TronLink] Transaction hash:", txHash);
1106
+ return txHash || "";
1107
+ } catch (error) {
1108
+ console.error("Write contract error:", error);
1109
+ if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
1110
+ throw new SignatureRejectedError("Transaction was rejected by user");
1111
+ }
1112
+ throw new Error(`Failed to write contract: ${error.message}`);
1113
+ }
1114
+ }
1115
+ /**
1116
+ * 等待交易确认
1117
+ */
1118
+ async waitForTransaction(txHash, _confirmations = 1) {
1119
+ try {
1120
+ const tronWeb = this.getTronWeb();
1121
+ let attempts = 0;
1122
+ const maxAttempts = 60;
1123
+ while (attempts < maxAttempts) {
1124
+ try {
1125
+ const txInfo = await tronWeb.trx.getTransactionInfo(txHash);
1126
+ if (txInfo && txInfo.id) {
1127
+ const receipt = {
1128
+ transactionHash: txHash,
1129
+ blockNumber: txInfo.blockNumber || 0,
1130
+ blockHash: txInfo.blockHash || "",
1131
+ from: this.currentAccount.nativeAddress,
1132
+ to: txInfo.contract_address || "",
1133
+ status: txInfo.receipt?.result === "SUCCESS" ? "success" : "failed",
1134
+ gasUsed: (txInfo.receipt?.energy_usage_total || 0).toString(),
1135
+ logs: txInfo.log || []
1136
+ };
1137
+ if (receipt.status === "failed") {
1138
+ throw new TransactionFailedError(txHash, "Transaction failed on Tron network");
1139
+ }
1140
+ return receipt;
1141
+ }
1142
+ } catch (error) {
1143
+ }
1144
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1145
+ attempts++;
1146
+ }
1147
+ throw new Error("Transaction confirmation timeout");
1148
+ } catch (error) {
1149
+ throw new Error(`Failed to wait for transaction: ${error.message}`);
1150
+ }
1151
+ }
921
1152
  /**
922
1153
  * 获取 Provider
923
1154
  */
@@ -956,9 +1187,16 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
956
1187
  setupEventListeners() {
957
1188
  if (typeof window === "undefined") return;
958
1189
  const w = window;
959
- if (w.tronLink) {
960
- w.tronLink.on("accountsChanged", this.handleAccountsChanged);
961
- w.tronLink.on("disconnect", this.handleDisconnect);
1190
+ try {
1191
+ if (w.tronLink && typeof w.tronLink.on === "function") {
1192
+ w.tronLink.on("accountsChanged", this.handleAccountsChanged);
1193
+ w.tronLink.on("disconnect", this.handleDisconnect);
1194
+ } else if (w.tronWeb && w.tronWeb.eventServer) {
1195
+ this.startPolling();
1196
+ }
1197
+ } catch (error) {
1198
+ console.warn("TronLink event listener setup failed:", error);
1199
+ this.startPolling();
962
1200
  }
963
1201
  }
964
1202
  /**
@@ -967,9 +1205,38 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
967
1205
  removeEventListeners() {
968
1206
  if (typeof window === "undefined") return;
969
1207
  const w = window;
970
- if (w.tronLink) {
971
- w.tronLink.off("accountsChanged", this.handleAccountsChanged);
972
- w.tronLink.off("disconnect", this.handleDisconnect);
1208
+ try {
1209
+ if (w.tronLink && typeof w.tronLink.off === "function") {
1210
+ w.tronLink.off("accountsChanged", this.handleAccountsChanged);
1211
+ w.tronLink.off("disconnect", this.handleDisconnect);
1212
+ }
1213
+ } catch (error) {
1214
+ console.warn("TronLink event listener removal failed:", error);
1215
+ }
1216
+ this.stopPolling();
1217
+ }
1218
+ startPolling() {
1219
+ if (this.pollingInterval) return;
1220
+ this.lastKnownAddress = this.currentAccount?.nativeAddress || null;
1221
+ this.pollingInterval = setInterval(async () => {
1222
+ try {
1223
+ const tronWeb = this.getTronWeb();
1224
+ const currentAddress = tronWeb.defaultAddress?.base58;
1225
+ if (currentAddress && currentAddress !== this.lastKnownAddress) {
1226
+ this.lastKnownAddress = currentAddress;
1227
+ this.handleAccountsChanged({ address: { base58: currentAddress } });
1228
+ } else if (!currentAddress && this.lastKnownAddress) {
1229
+ this.lastKnownAddress = null;
1230
+ this.handleAccountsChanged(null);
1231
+ }
1232
+ } catch (error) {
1233
+ }
1234
+ }, 2e3);
1235
+ }
1236
+ stopPolling() {
1237
+ if (this.pollingInterval) {
1238
+ clearInterval(this.pollingInterval);
1239
+ this.pollingInterval = null;
973
1240
  }
974
1241
  }
975
1242
  };
@@ -980,7 +1247,7 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
980
1247
  constructor() {
981
1248
  super(...arguments);
982
1249
  this.type = "private-key" /* PRIVATE_KEY */;
983
- this.chainType = "evm" /* EVM */;
1250
+ this.chainType = ChainType.EVM;
984
1251
  this.name = "Private Key (EVM)";
985
1252
  this.privateKey = null;
986
1253
  this.walletClient = null;
@@ -1010,7 +1277,7 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1010
1277
  universalAddress: createUniversalAddress(chainId, address),
1011
1278
  nativeAddress: address,
1012
1279
  chainId,
1013
- chainType: "evm" /* EVM */,
1280
+ chainType: ChainType.EVM,
1014
1281
  isActive: true
1015
1282
  };
1016
1283
  this.setState("connected" /* CONNECTED */);
@@ -1360,9 +1627,10 @@ var WalletManager = class extends TypedEventEmitter {
1360
1627
  if (!this.primaryWallet) {
1361
1628
  return;
1362
1629
  }
1630
+ const chainType = this.primaryWallet.chainType;
1363
1631
  await this.primaryWallet.disconnect();
1364
1632
  this.removeAdapterListeners(this.primaryWallet);
1365
- this.connectedWallets.delete(this.primaryWallet.chainType);
1633
+ this.connectedWallets.delete(chainType);
1366
1634
  this.primaryWallet = null;
1367
1635
  if (this.config.enableStorage) {
1368
1636
  this.saveToStorage();
@@ -1467,6 +1735,34 @@ var WalletManager = class extends TypedEventEmitter {
1467
1735
  }
1468
1736
  return adapter.signTypedData(typedData);
1469
1737
  }
1738
+ /**
1739
+ * 签名交易(使用主钱包)
1740
+ */
1741
+ async signTransaction(transaction) {
1742
+ if (!this.primaryWallet) {
1743
+ throw new WalletNotConnectedError();
1744
+ }
1745
+ if (!this.primaryWallet.signTransaction) {
1746
+ throw new Error(`signTransaction not supported by ${this.primaryWallet.type}`);
1747
+ }
1748
+ return this.primaryWallet.signTransaction(transaction);
1749
+ }
1750
+ /**
1751
+ * 使用指定链类型的钱包签名交易
1752
+ */
1753
+ async signTransactionWithChainType(transaction, chainType) {
1754
+ if (!chainType) {
1755
+ return this.signTransaction(transaction);
1756
+ }
1757
+ const adapter = this.connectedWallets.get(chainType);
1758
+ if (!adapter) {
1759
+ throw new WalletNotConnectedError(`Wallet for chain type ${chainType}`);
1760
+ }
1761
+ if (!adapter.signTransaction) {
1762
+ throw new Error(`signTransaction not supported by ${adapter.type}`);
1763
+ }
1764
+ return adapter.signTransaction(transaction);
1765
+ }
1470
1766
  // ===== 链切换 =====
1471
1767
  /**
1472
1768
  * 请求切换链(仅 EVM)
@@ -1627,6 +1923,7 @@ var WalletManager = class extends TypedEventEmitter {
1627
1923
  * 移除适配器事件监听
1628
1924
  */
1629
1925
  removeAdapterListeners(adapter) {
1926
+ if (!adapter) return;
1630
1927
  adapter.removeAllListeners();
1631
1928
  }
1632
1929
  // ===== 存储 =====
@@ -1700,7 +1997,7 @@ var AuthMessageGenerator = class {
1700
1997
  */
1701
1998
  generateAuthMessage(chainType, nonce, chainId, timestamp = Date.now(), statement) {
1702
1999
  switch (chainType) {
1703
- case "evm" /* EVM */:
2000
+ case ChainType.EVM:
1704
2001
  return this.generateEIP191Message({
1705
2002
  domain: this.domain,
1706
2003
  nonce,
@@ -1708,7 +2005,7 @@ var AuthMessageGenerator = class {
1708
2005
  timestamp,
1709
2006
  statement
1710
2007
  });
1711
- case "tron" /* TRON */:
2008
+ case ChainType.TRON:
1712
2009
  return this.generateTIP191Message({
1713
2010
  domain: this.domain,
1714
2011
  nonce,
@@ -1771,9 +2068,9 @@ var SignatureVerifier = class {
1771
2068
  */
1772
2069
  async verifySignature(message, signature, expectedAddress, chainType) {
1773
2070
  switch (chainType) {
1774
- case "evm" /* EVM */:
2071
+ case ChainType.EVM:
1775
2072
  return this.verifyEIP191Signature(message, signature, expectedAddress);
1776
- case "tron" /* TRON */:
2073
+ case ChainType.TRON:
1777
2074
  return this.verifyTIP191Signature(message, signature, expectedAddress);
1778
2075
  default:
1779
2076
  throw new Error(`Unsupported chain type: ${chainType}`);
@@ -1811,7 +2108,7 @@ var SUPPORTED_WALLETS = {
1811
2108
  ["metamask" /* METAMASK */]: {
1812
2109
  type: "metamask" /* METAMASK */,
1813
2110
  name: "MetaMask",
1814
- chainType: "evm" /* EVM */,
2111
+ chainType: ChainType.EVM,
1815
2112
  icon: "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg",
1816
2113
  downloadUrl: "https://metamask.io/download/",
1817
2114
  description: "The most popular Ethereum wallet"
@@ -1819,7 +2116,7 @@ var SUPPORTED_WALLETS = {
1819
2116
  ["walletconnect" /* WALLETCONNECT */]: {
1820
2117
  type: "walletconnect" /* WALLETCONNECT */,
1821
2118
  name: "WalletConnect",
1822
- chainType: "evm" /* EVM */,
2119
+ chainType: ChainType.EVM,
1823
2120
  icon: "https://avatars.githubusercontent.com/u/37784886",
1824
2121
  downloadUrl: "https://walletconnect.com/",
1825
2122
  description: "Connect to 170+ wallets"
@@ -1827,7 +2124,7 @@ var SUPPORTED_WALLETS = {
1827
2124
  ["coinbase-wallet" /* COINBASE_WALLET */]: {
1828
2125
  type: "coinbase-wallet" /* COINBASE_WALLET */,
1829
2126
  name: "Coinbase Wallet",
1830
- chainType: "evm" /* EVM */,
2127
+ chainType: ChainType.EVM,
1831
2128
  icon: "https://www.coinbase.com/img/favicon/favicon-96x96.png",
1832
2129
  downloadUrl: "https://www.coinbase.com/wallet",
1833
2130
  description: "Coinbase self-custody wallet"
@@ -1835,7 +2132,7 @@ var SUPPORTED_WALLETS = {
1835
2132
  ["tronlink" /* TRONLINK */]: {
1836
2133
  type: "tronlink" /* TRONLINK */,
1837
2134
  name: "TronLink",
1838
- chainType: "tron" /* TRON */,
2135
+ chainType: ChainType.TRON,
1839
2136
  icon: "https://www.tronlink.org/static/logoIcon.svg",
1840
2137
  downloadUrl: "https://www.tronlink.org/",
1841
2138
  description: "The official Tron wallet"
@@ -1843,14 +2140,14 @@ var SUPPORTED_WALLETS = {
1843
2140
  ["walletconnect-tron" /* WALLETCONNECT_TRON */]: {
1844
2141
  type: "walletconnect-tron" /* WALLETCONNECT_TRON */,
1845
2142
  name: "WalletConnect (Tron)",
1846
- chainType: "tron" /* TRON */,
2143
+ chainType: ChainType.TRON,
1847
2144
  downloadUrl: "https://walletconnect.com/",
1848
2145
  description: "WalletConnect for Tron"
1849
2146
  },
1850
2147
  ["private-key" /* PRIVATE_KEY */]: {
1851
2148
  type: "private-key" /* PRIVATE_KEY */,
1852
2149
  name: "Private Key",
1853
- chainType: "evm" /* EVM */,
2150
+ chainType: ChainType.EVM,
1854
2151
  // 可以用于任何链
1855
2152
  description: "Import wallet using private key (for development)"
1856
2153
  }
@@ -1860,12 +2157,12 @@ function getWalletMetadata(type) {
1860
2157
  }
1861
2158
  function getEVMWallets() {
1862
2159
  return Object.values(SUPPORTED_WALLETS).filter(
1863
- (wallet) => wallet.chainType === "evm" /* EVM */
2160
+ (wallet) => wallet.chainType === ChainType.EVM
1864
2161
  );
1865
2162
  }
1866
2163
  function getTronWallets() {
1867
2164
  return Object.values(SUPPORTED_WALLETS).filter(
1868
- (wallet) => wallet.chainType === "tron" /* TRON */
2165
+ (wallet) => wallet.chainType === ChainType.TRON
1869
2166
  );
1870
2167
  }
1871
2168
 
@@ -1892,7 +2189,7 @@ var WalletDetector = class {
1892
2189
  if (!metadata) {
1893
2190
  return {
1894
2191
  walletType,
1895
- chainType: "evm" /* EVM */,
2192
+ chainType: ChainType.EVM,
1896
2193
  // 默认
1897
2194
  isAvailable: false,
1898
2195
  detected: false
@@ -1931,11 +2228,11 @@ var WalletDetector = class {
1931
2228
  }
1932
2229
  }
1933
2230
  /**
1934
- * 检测 MetaMask
2231
+ * 检测 MetaMask(现在支持所有 window.ethereum 钱包)
1935
2232
  */
1936
2233
  isMetaMaskAvailable() {
1937
2234
  const w = window;
1938
- return !!(w.ethereum && w.ethereum.isMetaMask);
2235
+ return !!w.ethereum;
1939
2236
  }
1940
2237
  /**
1941
2238
  * 检测 TronLink
@@ -2000,9 +2297,9 @@ function shortenTronAddress(address, chars = 4) {
2000
2297
  // src/utils/validation.ts
2001
2298
  function validateAddress(address, chainType) {
2002
2299
  switch (chainType) {
2003
- case "evm" /* EVM */:
2300
+ case ChainType.EVM:
2004
2301
  return isValidEVMAddress(address);
2005
- case "tron" /* TRON */:
2302
+ case ChainType.TRON:
2006
2303
  return isValidTronAddress(address);
2007
2304
  default:
2008
2305
  return false;
@@ -2023,9 +2320,9 @@ function isValidSignature(signature) {
2023
2320
  }
2024
2321
  function isValidTransactionHash(txHash, chainType) {
2025
2322
  switch (chainType) {
2026
- case "evm" /* EVM */:
2323
+ case ChainType.EVM:
2027
2324
  return /^0x[0-9a-fA-F]{64}$/.test(txHash);
2028
- case "tron" /* TRON */:
2325
+ case ChainType.TRON:
2029
2326
  return /^[0-9a-fA-F]{64}$/.test(txHash);
2030
2327
  default:
2031
2328
  return false;