@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.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  import EventEmitter from 'eventemitter3';
2
+ import { ChainType as ChainType$1 } from '@enclave-hq/chain-utils';
2
3
  import { isAddress, getAddress, createWalletClient, custom, createPublicClient, http, verifyMessage } from 'viem';
3
4
  import { privateKeyToAccount } from 'viem/accounts';
4
5
 
@@ -31,15 +32,7 @@ var TypedEventEmitter = class {
31
32
  return this;
32
33
  }
33
34
  };
34
-
35
- // src/core/types.ts
36
- var ChainType = /* @__PURE__ */ ((ChainType4) => {
37
- ChainType4["EVM"] = "evm";
38
- ChainType4["TRON"] = "tron";
39
- ChainType4["SOLANA"] = "solana";
40
- ChainType4["COSMOS"] = "cosmos";
41
- return ChainType4;
42
- })(ChainType || {});
35
+ var ChainType = ChainType$1;
43
36
  var WalletType = /* @__PURE__ */ ((WalletType3) => {
44
37
  WalletType3["METAMASK"] = "metamask";
45
38
  WalletType3["WALLETCONNECT"] = "walletconnect";
@@ -303,14 +296,15 @@ function shortenAddress(address, chars = 4) {
303
296
  const formatted = getAddress(address);
304
297
  return `${formatted.substring(0, chars + 2)}...${formatted.substring(42 - chars)}`;
305
298
  }
306
-
307
- // src/utils/chain-info.ts
308
299
  var CHAIN_INFO = {
309
300
  // EVM Mainnet
310
301
  1: {
311
302
  id: 1,
303
+ slip44: 60,
304
+ // Ethereum SLIP-44
312
305
  name: "Ethereum Mainnet",
313
- chainType: "evm" /* EVM */,
306
+ chainType: ChainType$1.EVM,
307
+ symbol: "ETH",
314
308
  nativeCurrency: {
315
309
  name: "Ether",
316
310
  symbol: "ETH",
@@ -323,7 +317,8 @@ var CHAIN_INFO = {
323
317
  11155111: {
324
318
  id: 11155111,
325
319
  name: "Sepolia Testnet",
326
- chainType: "evm" /* EVM */,
320
+ chainType: ChainType$1.EVM,
321
+ symbol: "ETH",
327
322
  nativeCurrency: {
328
323
  name: "Sepolia Ether",
329
324
  symbol: "ETH",
@@ -335,8 +330,11 @@ var CHAIN_INFO = {
335
330
  // Binance Smart Chain
336
331
  56: {
337
332
  id: 56,
333
+ slip44: 714,
334
+ // BSC SLIP-44
338
335
  name: "BNB Smart Chain",
339
- chainType: "evm" /* EVM */,
336
+ chainType: ChainType$1.EVM,
337
+ symbol: "BNB",
340
338
  nativeCurrency: {
341
339
  name: "BNB",
342
340
  symbol: "BNB",
@@ -348,7 +346,8 @@ var CHAIN_INFO = {
348
346
  97: {
349
347
  id: 97,
350
348
  name: "BNB Smart Chain Testnet",
351
- chainType: "evm" /* EVM */,
349
+ chainType: ChainType$1.EVM,
350
+ symbol: "BNB",
352
351
  nativeCurrency: {
353
352
  name: "BNB",
354
353
  symbol: "BNB",
@@ -360,8 +359,11 @@ var CHAIN_INFO = {
360
359
  // Polygon
361
360
  137: {
362
361
  id: 137,
362
+ slip44: 966,
363
+ // Polygon SLIP-44
363
364
  name: "Polygon Mainnet",
364
- chainType: "evm" /* EVM */,
365
+ chainType: ChainType$1.EVM,
366
+ symbol: "MATIC",
365
367
  nativeCurrency: {
366
368
  name: "MATIC",
367
369
  symbol: "MATIC",
@@ -373,7 +375,8 @@ var CHAIN_INFO = {
373
375
  80002: {
374
376
  id: 80002,
375
377
  name: "Polygon Amoy Testnet",
376
- chainType: "evm" /* EVM */,
378
+ chainType: ChainType$1.EVM,
379
+ symbol: "MATIC",
377
380
  nativeCurrency: {
378
381
  name: "MATIC",
379
382
  symbol: "MATIC",
@@ -385,8 +388,11 @@ var CHAIN_INFO = {
385
388
  // Tron
386
389
  195: {
387
390
  id: 195,
391
+ slip44: 195,
392
+ // Tron SLIP-44
388
393
  name: "Tron Mainnet",
389
- chainType: "tron" /* TRON */,
394
+ chainType: ChainType$1.TRON,
395
+ symbol: "TRX",
390
396
  nativeCurrency: {
391
397
  name: "TRX",
392
398
  symbol: "TRX",
@@ -398,8 +404,11 @@ var CHAIN_INFO = {
398
404
  // Arbitrum
399
405
  42161: {
400
406
  id: 42161,
407
+ slip44: 1042161,
408
+ // Custom SLIP-44 (1000000 + 42161)
401
409
  name: "Arbitrum One",
402
- chainType: "evm" /* EVM */,
410
+ chainType: ChainType$1.EVM,
411
+ symbol: "ETH",
403
412
  nativeCurrency: {
404
413
  name: "Ether",
405
414
  symbol: "ETH",
@@ -411,8 +420,11 @@ var CHAIN_INFO = {
411
420
  // Optimism
412
421
  10: {
413
422
  id: 10,
423
+ slip44: 1000010,
424
+ // Custom SLIP-44 (1000000 + 10)
414
425
  name: "Optimism",
415
- chainType: "evm" /* EVM */,
426
+ chainType: ChainType$1.EVM,
427
+ symbol: "ETH",
416
428
  nativeCurrency: {
417
429
  name: "Ether",
418
430
  symbol: "ETH",
@@ -424,8 +436,11 @@ var CHAIN_INFO = {
424
436
  // Avalanche
425
437
  43114: {
426
438
  id: 43114,
439
+ slip44: 9e3,
440
+ // Avalanche SLIP-44
427
441
  name: "Avalanche C-Chain",
428
- chainType: "evm" /* EVM */,
442
+ chainType: ChainType$1.EVM,
443
+ symbol: "AVAX",
429
444
  nativeCurrency: {
430
445
  name: "AVAX",
431
446
  symbol: "AVAX",
@@ -442,10 +457,10 @@ function getChainType(chainId) {
442
457
  return CHAIN_INFO[chainId]?.chainType;
443
458
  }
444
459
  function isEVMChain(chainId) {
445
- return getChainType(chainId) === "evm" /* EVM */;
460
+ return getChainType(chainId) === ChainType$1.EVM;
446
461
  }
447
462
  function isTronChain(chainId) {
448
- return getChainType(chainId) === "tron" /* TRON */;
463
+ return getChainType(chainId) === ChainType$1.TRON;
449
464
  }
450
465
 
451
466
  // src/adapters/evm/metamask.ts
@@ -453,26 +468,34 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
453
468
  constructor() {
454
469
  super(...arguments);
455
470
  this.type = "metamask" /* METAMASK */;
456
- this.chainType = "evm" /* EVM */;
471
+ this.chainType = ChainType.EVM;
457
472
  this.name = "MetaMask";
458
473
  this.icon = "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg";
459
474
  this.walletClient = null;
460
475
  this.publicClient = null;
461
476
  /**
462
477
  * 处理账户变化
478
+ *
479
+ * 注意:MetaMask 的行为
480
+ * - 切换到已连接的账户:触发事件,返回新账户 ['0xNewAddress']
481
+ * - 切换到未连接的账户:不触发事件(用户需要手动断开和重新连接)
482
+ * - 锁定钱包:触发事件,返回空数组 []
463
483
  */
464
484
  this.handleAccountsChanged = (accounts) => {
485
+ console.log("[MetaMask] accountsChanged event triggered:", accounts);
465
486
  if (accounts.length === 0) {
487
+ console.log("[MetaMask] Disconnecting: wallet locked or manually disconnected");
466
488
  this.setState("disconnected" /* DISCONNECTED */);
467
489
  this.setAccount(null);
468
490
  this.emitAccountChanged(null);
469
491
  } else {
470
492
  const address = formatEVMAddress(accounts[0]);
493
+ console.log("[MetaMask] Account changed to:", address);
471
494
  const account = {
472
495
  universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
473
496
  nativeAddress: address,
474
497
  chainId: this.currentAccount.chainId,
475
- chainType: "evm" /* EVM */,
498
+ chainType: ChainType.EVM,
476
499
  isActive: true
477
500
  };
478
501
  this.setAccount(account);
@@ -524,21 +547,23 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
524
547
  if (chainId && chainId !== parsedChainId) {
525
548
  await this.switchChain(chainId);
526
549
  }
550
+ const finalChainId = chainId || parsedChainId;
551
+ const viemChain = this.getViemChain(finalChainId);
527
552
  this.walletClient = createWalletClient({
528
553
  account: accounts[0],
554
+ chain: viemChain,
529
555
  transport: custom(provider)
530
556
  });
531
- const finalChainId = chainId || parsedChainId;
532
557
  this.publicClient = createPublicClient({
533
- chain: this.getViemChain(finalChainId),
534
- transport: http()
558
+ chain: viemChain,
559
+ transport: custom(provider)
535
560
  });
536
561
  const address = formatEVMAddress(accounts[0]);
537
562
  const account = {
538
563
  universalAddress: createUniversalAddress(finalChainId, address),
539
564
  nativeAddress: address,
540
565
  chainId: finalChainId,
541
- chainType: "evm" /* EVM */,
566
+ chainType: ChainType.EVM,
542
567
  isActive: true
543
568
  };
544
569
  this.setState("connected" /* CONNECTED */);
@@ -592,6 +617,40 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
592
617
  throw error;
593
618
  }
594
619
  }
620
+ /**
621
+ * 签名交易
622
+ *
623
+ * Note: This signs a raw transaction without sending it.
624
+ * The transaction can be broadcast later using the returned signature.
625
+ */
626
+ async signTransaction(transaction) {
627
+ this.ensureConnected();
628
+ try {
629
+ const provider = this.getBrowserProvider();
630
+ const tx = {
631
+ from: this.currentAccount.nativeAddress,
632
+ to: transaction.to,
633
+ value: transaction.value ? `0x${BigInt(transaction.value).toString(16)}` : void 0,
634
+ data: transaction.data || "0x",
635
+ gas: transaction.gas ? `0x${BigInt(transaction.gas).toString(16)}` : void 0,
636
+ gasPrice: transaction.gasPrice && transaction.gasPrice !== "auto" ? `0x${BigInt(transaction.gasPrice).toString(16)}` : void 0,
637
+ maxFeePerGas: transaction.maxFeePerGas ? `0x${BigInt(transaction.maxFeePerGas).toString(16)}` : void 0,
638
+ maxPriorityFeePerGas: transaction.maxPriorityFeePerGas ? `0x${BigInt(transaction.maxPriorityFeePerGas).toString(16)}` : void 0,
639
+ nonce: transaction.nonce !== void 0 ? `0x${transaction.nonce.toString(16)}` : void 0,
640
+ chainId: transaction.chainId || this.currentAccount.chainId
641
+ };
642
+ const signature = await provider.request({
643
+ method: "eth_signTransaction",
644
+ params: [tx]
645
+ });
646
+ return signature;
647
+ } catch (error) {
648
+ if (error.code === 4001) {
649
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
650
+ }
651
+ throw error;
652
+ }
653
+ }
595
654
  /**
596
655
  * 切换链
597
656
  */
@@ -672,6 +731,16 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
672
731
  throw new Error("Wallet client not initialized");
673
732
  }
674
733
  try {
734
+ console.log("\u{1F50D} [MetaMask writeContract] params.gasPrice:", params.gasPrice, "type:", typeof params.gasPrice);
735
+ let processedGasPrice;
736
+ if (!params.gasPrice) {
737
+ processedGasPrice = void 0;
738
+ } else if (params.gasPrice === "auto") {
739
+ processedGasPrice = void 0;
740
+ } else {
741
+ processedGasPrice = BigInt(params.gasPrice);
742
+ }
743
+ console.log("\u{1F50D} [MetaMask writeContract] processedGasPrice:", processedGasPrice);
675
744
  const txHash = await this.walletClient.writeContract({
676
745
  address: params.address,
677
746
  abi: params.abi,
@@ -679,7 +748,7 @@ var MetaMaskAdapter = class extends BrowserWalletAdapter {
679
748
  ...params.args ? { args: params.args } : {},
680
749
  value: params.value ? BigInt(params.value) : void 0,
681
750
  gas: params.gas ? BigInt(params.gas) : void 0,
682
- gasPrice: params.gasPrice ? BigInt(params.gasPrice) : void 0
751
+ gasPrice: processedGasPrice
683
752
  });
684
753
  return txHash;
685
754
  } catch (error) {
@@ -822,9 +891,14 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
822
891
  constructor() {
823
892
  super(...arguments);
824
893
  this.type = "tronlink" /* TRONLINK */;
825
- this.chainType = "tron" /* TRON */;
894
+ this.chainType = ChainType.TRON;
826
895
  this.name = "TronLink";
827
896
  this.icon = "https://www.tronlink.org/static/logoIcon.svg";
897
+ /**
898
+ * 轮询检测账户变化(备用方案)
899
+ */
900
+ this.pollingInterval = null;
901
+ this.lastKnownAddress = null;
828
902
  /**
829
903
  * 处理账户变化
830
904
  */
@@ -839,7 +913,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
839
913
  universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
840
914
  nativeAddress: address,
841
915
  chainId: this.currentAccount.chainId,
842
- chainType: "tron" /* TRON */,
916
+ chainType: ChainType.TRON,
843
917
  isActive: true
844
918
  };
845
919
  this.setAccount(account);
@@ -878,7 +952,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
878
952
  universalAddress: createUniversalAddress(tronChainId, address),
879
953
  nativeAddress: address,
880
954
  chainId: tronChainId,
881
- chainType: "tron" /* TRON */,
955
+ chainType: ChainType.TRON,
882
956
  isActive: true
883
957
  };
884
958
  this.setState("connected" /* CONNECTED */);
@@ -896,20 +970,177 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
896
970
  }
897
971
  /**
898
972
  * 签名消息
973
+ *
974
+ * Note: TronLink supports two signing methods:
975
+ * - trx.sign(): Signs a transaction object
976
+ * - trx.signMessageV2(): Signs a plain text message (what we use here)
899
977
  */
900
978
  async signMessage(message) {
901
979
  this.ensureConnected();
902
980
  try {
903
981
  const tronWeb = this.getTronWeb();
904
- const signature = await tronWeb.trx.sign(message);
905
- return signature;
982
+ if (typeof tronWeb.trx.signMessageV2 === "function") {
983
+ const signature = await tronWeb.trx.signMessageV2(message);
984
+ return signature;
985
+ } else {
986
+ console.warn("[TronLink] signMessageV2 not available, falling back to sign()");
987
+ const signature = await tronWeb.trx.sign(message);
988
+ return signature;
989
+ }
906
990
  } catch (error) {
907
991
  if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
908
992
  throw new SignatureRejectedError();
909
993
  }
994
+ if (error.message?.includes("Invalid transaction")) {
995
+ throw new Error("Invalid message format. For transaction signing, use signTransaction() instead.");
996
+ }
997
+ throw error;
998
+ }
999
+ }
1000
+ /**
1001
+ * 签名交易
1002
+ *
1003
+ * Note: This uses trx.sign() which is specifically for signing transaction objects.
1004
+ * For plain text message signing, use signMessage() instead.
1005
+ */
1006
+ async signTransaction(transaction) {
1007
+ this.ensureConnected();
1008
+ try {
1009
+ const tronWeb = this.getTronWeb();
1010
+ const signature = await tronWeb.trx.sign(transaction);
1011
+ return signature;
1012
+ } catch (error) {
1013
+ if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
1014
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
1015
+ }
1016
+ if (error.message?.includes("Invalid transaction")) {
1017
+ throw new Error("Invalid transaction format. Please provide a properly formatted Tron transaction object.");
1018
+ }
910
1019
  throw error;
911
1020
  }
912
1021
  }
1022
+ /**
1023
+ * 读取合约
1024
+ */
1025
+ async readContract(params) {
1026
+ this.ensureConnected();
1027
+ try {
1028
+ const tronWeb = this.getTronWeb();
1029
+ const contract = await tronWeb.contract(params.abi, params.address);
1030
+ const result = await contract[params.functionName](...params.args || []).call();
1031
+ return result;
1032
+ } catch (error) {
1033
+ console.error("Read contract error:", error);
1034
+ throw new Error(`Failed to read contract: ${error.message}`);
1035
+ }
1036
+ }
1037
+ /**
1038
+ * 写入合约
1039
+ */
1040
+ async writeContract(params) {
1041
+ this.ensureConnected();
1042
+ try {
1043
+ const tronWeb = this.getTronWeb();
1044
+ console.log("[TronLink] writeContract params:", {
1045
+ address: params.address,
1046
+ functionName: params.functionName,
1047
+ args: params.args,
1048
+ value: params.value,
1049
+ gas: params.gas
1050
+ });
1051
+ if (!params.args || params.args.length === 0) {
1052
+ throw new Error("Contract function arguments are required");
1053
+ }
1054
+ const hasUndefined = params.args.some((arg) => arg === void 0 || arg === null);
1055
+ if (hasUndefined) {
1056
+ console.error("[TronLink] Invalid args detected:", params.args);
1057
+ throw new Error(`Invalid contract arguments: some arguments are undefined or null`);
1058
+ }
1059
+ const functionAbi = params.abi.find(
1060
+ (item) => item.name === params.functionName && item.type === "function"
1061
+ );
1062
+ if (!functionAbi) {
1063
+ throw new Error(`Function ${params.functionName} not found in ABI`);
1064
+ }
1065
+ console.log("[TronLink] Function ABI:", functionAbi);
1066
+ console.log("[TronLink] Calling with args:", params.args);
1067
+ const options = {
1068
+ feeLimit: params.gas || 1e8,
1069
+ // 默认 100 TRX 的能量限制
1070
+ callValue: params.value || 0
1071
+ // 发送的 TRX 数量(单位:SUN)
1072
+ };
1073
+ const parameter = functionAbi.inputs.map((input, index) => ({
1074
+ type: input.type,
1075
+ value: params.args[index]
1076
+ }));
1077
+ console.log("[TronLink] Transaction options:", options);
1078
+ console.log("[TronLink] Parameters:", parameter);
1079
+ const transaction = await tronWeb.transactionBuilder.triggerSmartContract(
1080
+ params.address,
1081
+ params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")",
1082
+ options,
1083
+ parameter,
1084
+ this.currentAccount.nativeAddress
1085
+ );
1086
+ console.log("[TronLink] Transaction built:", transaction);
1087
+ if (!transaction || !transaction.transaction) {
1088
+ throw new Error("Failed to build transaction");
1089
+ }
1090
+ const signedTx = await tronWeb.trx.sign(transaction.transaction);
1091
+ const broadcast = await tronWeb.trx.sendRawTransaction(signedTx);
1092
+ console.log("[TronLink] Broadcast result:", broadcast);
1093
+ if (!broadcast.result) {
1094
+ throw new Error(broadcast.message || "Transaction broadcast failed");
1095
+ }
1096
+ const txHash = broadcast.txid || broadcast.transaction?.txID;
1097
+ console.log("[TronLink] Transaction hash:", txHash);
1098
+ return txHash || "";
1099
+ } catch (error) {
1100
+ console.error("Write contract error:", error);
1101
+ if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
1102
+ throw new SignatureRejectedError("Transaction was rejected by user");
1103
+ }
1104
+ throw new Error(`Failed to write contract: ${error.message}`);
1105
+ }
1106
+ }
1107
+ /**
1108
+ * 等待交易确认
1109
+ */
1110
+ async waitForTransaction(txHash, _confirmations = 1) {
1111
+ try {
1112
+ const tronWeb = this.getTronWeb();
1113
+ let attempts = 0;
1114
+ const maxAttempts = 60;
1115
+ while (attempts < maxAttempts) {
1116
+ try {
1117
+ const txInfo = await tronWeb.trx.getTransactionInfo(txHash);
1118
+ if (txInfo && txInfo.id) {
1119
+ const receipt = {
1120
+ transactionHash: txHash,
1121
+ blockNumber: txInfo.blockNumber || 0,
1122
+ blockHash: txInfo.blockHash || "",
1123
+ from: this.currentAccount.nativeAddress,
1124
+ to: txInfo.contract_address || "",
1125
+ status: txInfo.receipt?.result === "SUCCESS" ? "success" : "failed",
1126
+ gasUsed: (txInfo.receipt?.energy_usage_total || 0).toString(),
1127
+ logs: txInfo.log || []
1128
+ };
1129
+ if (receipt.status === "failed") {
1130
+ throw new TransactionFailedError(txHash, "Transaction failed on Tron network");
1131
+ }
1132
+ return receipt;
1133
+ }
1134
+ } catch (error) {
1135
+ }
1136
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1137
+ attempts++;
1138
+ }
1139
+ throw new Error("Transaction confirmation timeout");
1140
+ } catch (error) {
1141
+ throw new Error(`Failed to wait for transaction: ${error.message}`);
1142
+ }
1143
+ }
913
1144
  /**
914
1145
  * 获取 Provider
915
1146
  */
@@ -948,9 +1179,16 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
948
1179
  setupEventListeners() {
949
1180
  if (typeof window === "undefined") return;
950
1181
  const w = window;
951
- if (w.tronLink) {
952
- w.tronLink.on("accountsChanged", this.handleAccountsChanged);
953
- w.tronLink.on("disconnect", this.handleDisconnect);
1182
+ try {
1183
+ if (w.tronLink && typeof w.tronLink.on === "function") {
1184
+ w.tronLink.on("accountsChanged", this.handleAccountsChanged);
1185
+ w.tronLink.on("disconnect", this.handleDisconnect);
1186
+ } else if (w.tronWeb && w.tronWeb.eventServer) {
1187
+ this.startPolling();
1188
+ }
1189
+ } catch (error) {
1190
+ console.warn("TronLink event listener setup failed:", error);
1191
+ this.startPolling();
954
1192
  }
955
1193
  }
956
1194
  /**
@@ -959,9 +1197,38 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
959
1197
  removeEventListeners() {
960
1198
  if (typeof window === "undefined") return;
961
1199
  const w = window;
962
- if (w.tronLink) {
963
- w.tronLink.off("accountsChanged", this.handleAccountsChanged);
964
- w.tronLink.off("disconnect", this.handleDisconnect);
1200
+ try {
1201
+ if (w.tronLink && typeof w.tronLink.off === "function") {
1202
+ w.tronLink.off("accountsChanged", this.handleAccountsChanged);
1203
+ w.tronLink.off("disconnect", this.handleDisconnect);
1204
+ }
1205
+ } catch (error) {
1206
+ console.warn("TronLink event listener removal failed:", error);
1207
+ }
1208
+ this.stopPolling();
1209
+ }
1210
+ startPolling() {
1211
+ if (this.pollingInterval) return;
1212
+ this.lastKnownAddress = this.currentAccount?.nativeAddress || null;
1213
+ this.pollingInterval = setInterval(async () => {
1214
+ try {
1215
+ const tronWeb = this.getTronWeb();
1216
+ const currentAddress = tronWeb.defaultAddress?.base58;
1217
+ if (currentAddress && currentAddress !== this.lastKnownAddress) {
1218
+ this.lastKnownAddress = currentAddress;
1219
+ this.handleAccountsChanged({ address: { base58: currentAddress } });
1220
+ } else if (!currentAddress && this.lastKnownAddress) {
1221
+ this.lastKnownAddress = null;
1222
+ this.handleAccountsChanged(null);
1223
+ }
1224
+ } catch (error) {
1225
+ }
1226
+ }, 2e3);
1227
+ }
1228
+ stopPolling() {
1229
+ if (this.pollingInterval) {
1230
+ clearInterval(this.pollingInterval);
1231
+ this.pollingInterval = null;
965
1232
  }
966
1233
  }
967
1234
  };
@@ -972,7 +1239,7 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
972
1239
  constructor() {
973
1240
  super(...arguments);
974
1241
  this.type = "private-key" /* PRIVATE_KEY */;
975
- this.chainType = "evm" /* EVM */;
1242
+ this.chainType = ChainType.EVM;
976
1243
  this.name = "Private Key (EVM)";
977
1244
  this.privateKey = null;
978
1245
  this.walletClient = null;
@@ -1002,7 +1269,7 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1002
1269
  universalAddress: createUniversalAddress(chainId, address),
1003
1270
  nativeAddress: address,
1004
1271
  chainId,
1005
- chainType: "evm" /* EVM */,
1272
+ chainType: ChainType.EVM,
1006
1273
  isActive: true
1007
1274
  };
1008
1275
  this.setState("connected" /* CONNECTED */);
@@ -1352,9 +1619,10 @@ var WalletManager = class extends TypedEventEmitter {
1352
1619
  if (!this.primaryWallet) {
1353
1620
  return;
1354
1621
  }
1622
+ const chainType = this.primaryWallet.chainType;
1355
1623
  await this.primaryWallet.disconnect();
1356
1624
  this.removeAdapterListeners(this.primaryWallet);
1357
- this.connectedWallets.delete(this.primaryWallet.chainType);
1625
+ this.connectedWallets.delete(chainType);
1358
1626
  this.primaryWallet = null;
1359
1627
  if (this.config.enableStorage) {
1360
1628
  this.saveToStorage();
@@ -1459,6 +1727,34 @@ var WalletManager = class extends TypedEventEmitter {
1459
1727
  }
1460
1728
  return adapter.signTypedData(typedData);
1461
1729
  }
1730
+ /**
1731
+ * 签名交易(使用主钱包)
1732
+ */
1733
+ async signTransaction(transaction) {
1734
+ if (!this.primaryWallet) {
1735
+ throw new WalletNotConnectedError();
1736
+ }
1737
+ if (!this.primaryWallet.signTransaction) {
1738
+ throw new Error(`signTransaction not supported by ${this.primaryWallet.type}`);
1739
+ }
1740
+ return this.primaryWallet.signTransaction(transaction);
1741
+ }
1742
+ /**
1743
+ * 使用指定链类型的钱包签名交易
1744
+ */
1745
+ async signTransactionWithChainType(transaction, chainType) {
1746
+ if (!chainType) {
1747
+ return this.signTransaction(transaction);
1748
+ }
1749
+ const adapter = this.connectedWallets.get(chainType);
1750
+ if (!adapter) {
1751
+ throw new WalletNotConnectedError(`Wallet for chain type ${chainType}`);
1752
+ }
1753
+ if (!adapter.signTransaction) {
1754
+ throw new Error(`signTransaction not supported by ${adapter.type}`);
1755
+ }
1756
+ return adapter.signTransaction(transaction);
1757
+ }
1462
1758
  // ===== 链切换 =====
1463
1759
  /**
1464
1760
  * 请求切换链(仅 EVM)
@@ -1619,6 +1915,7 @@ var WalletManager = class extends TypedEventEmitter {
1619
1915
  * 移除适配器事件监听
1620
1916
  */
1621
1917
  removeAdapterListeners(adapter) {
1918
+ if (!adapter) return;
1622
1919
  adapter.removeAllListeners();
1623
1920
  }
1624
1921
  // ===== 存储 =====
@@ -1692,7 +1989,7 @@ var AuthMessageGenerator = class {
1692
1989
  */
1693
1990
  generateAuthMessage(chainType, nonce, chainId, timestamp = Date.now(), statement) {
1694
1991
  switch (chainType) {
1695
- case "evm" /* EVM */:
1992
+ case ChainType.EVM:
1696
1993
  return this.generateEIP191Message({
1697
1994
  domain: this.domain,
1698
1995
  nonce,
@@ -1700,7 +1997,7 @@ var AuthMessageGenerator = class {
1700
1997
  timestamp,
1701
1998
  statement
1702
1999
  });
1703
- case "tron" /* TRON */:
2000
+ case ChainType.TRON:
1704
2001
  return this.generateTIP191Message({
1705
2002
  domain: this.domain,
1706
2003
  nonce,
@@ -1763,9 +2060,9 @@ var SignatureVerifier = class {
1763
2060
  */
1764
2061
  async verifySignature(message, signature, expectedAddress, chainType) {
1765
2062
  switch (chainType) {
1766
- case "evm" /* EVM */:
2063
+ case ChainType.EVM:
1767
2064
  return this.verifyEIP191Signature(message, signature, expectedAddress);
1768
- case "tron" /* TRON */:
2065
+ case ChainType.TRON:
1769
2066
  return this.verifyTIP191Signature(message, signature, expectedAddress);
1770
2067
  default:
1771
2068
  throw new Error(`Unsupported chain type: ${chainType}`);
@@ -1803,7 +2100,7 @@ var SUPPORTED_WALLETS = {
1803
2100
  ["metamask" /* METAMASK */]: {
1804
2101
  type: "metamask" /* METAMASK */,
1805
2102
  name: "MetaMask",
1806
- chainType: "evm" /* EVM */,
2103
+ chainType: ChainType.EVM,
1807
2104
  icon: "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg",
1808
2105
  downloadUrl: "https://metamask.io/download/",
1809
2106
  description: "The most popular Ethereum wallet"
@@ -1811,7 +2108,7 @@ var SUPPORTED_WALLETS = {
1811
2108
  ["walletconnect" /* WALLETCONNECT */]: {
1812
2109
  type: "walletconnect" /* WALLETCONNECT */,
1813
2110
  name: "WalletConnect",
1814
- chainType: "evm" /* EVM */,
2111
+ chainType: ChainType.EVM,
1815
2112
  icon: "https://avatars.githubusercontent.com/u/37784886",
1816
2113
  downloadUrl: "https://walletconnect.com/",
1817
2114
  description: "Connect to 170+ wallets"
@@ -1819,7 +2116,7 @@ var SUPPORTED_WALLETS = {
1819
2116
  ["coinbase-wallet" /* COINBASE_WALLET */]: {
1820
2117
  type: "coinbase-wallet" /* COINBASE_WALLET */,
1821
2118
  name: "Coinbase Wallet",
1822
- chainType: "evm" /* EVM */,
2119
+ chainType: ChainType.EVM,
1823
2120
  icon: "https://www.coinbase.com/img/favicon/favicon-96x96.png",
1824
2121
  downloadUrl: "https://www.coinbase.com/wallet",
1825
2122
  description: "Coinbase self-custody wallet"
@@ -1827,7 +2124,7 @@ var SUPPORTED_WALLETS = {
1827
2124
  ["tronlink" /* TRONLINK */]: {
1828
2125
  type: "tronlink" /* TRONLINK */,
1829
2126
  name: "TronLink",
1830
- chainType: "tron" /* TRON */,
2127
+ chainType: ChainType.TRON,
1831
2128
  icon: "https://www.tronlink.org/static/logoIcon.svg",
1832
2129
  downloadUrl: "https://www.tronlink.org/",
1833
2130
  description: "The official Tron wallet"
@@ -1835,14 +2132,14 @@ var SUPPORTED_WALLETS = {
1835
2132
  ["walletconnect-tron" /* WALLETCONNECT_TRON */]: {
1836
2133
  type: "walletconnect-tron" /* WALLETCONNECT_TRON */,
1837
2134
  name: "WalletConnect (Tron)",
1838
- chainType: "tron" /* TRON */,
2135
+ chainType: ChainType.TRON,
1839
2136
  downloadUrl: "https://walletconnect.com/",
1840
2137
  description: "WalletConnect for Tron"
1841
2138
  },
1842
2139
  ["private-key" /* PRIVATE_KEY */]: {
1843
2140
  type: "private-key" /* PRIVATE_KEY */,
1844
2141
  name: "Private Key",
1845
- chainType: "evm" /* EVM */,
2142
+ chainType: ChainType.EVM,
1846
2143
  // 可以用于任何链
1847
2144
  description: "Import wallet using private key (for development)"
1848
2145
  }
@@ -1852,12 +2149,12 @@ function getWalletMetadata(type) {
1852
2149
  }
1853
2150
  function getEVMWallets() {
1854
2151
  return Object.values(SUPPORTED_WALLETS).filter(
1855
- (wallet) => wallet.chainType === "evm" /* EVM */
2152
+ (wallet) => wallet.chainType === ChainType.EVM
1856
2153
  );
1857
2154
  }
1858
2155
  function getTronWallets() {
1859
2156
  return Object.values(SUPPORTED_WALLETS).filter(
1860
- (wallet) => wallet.chainType === "tron" /* TRON */
2157
+ (wallet) => wallet.chainType === ChainType.TRON
1861
2158
  );
1862
2159
  }
1863
2160
 
@@ -1884,7 +2181,7 @@ var WalletDetector = class {
1884
2181
  if (!metadata) {
1885
2182
  return {
1886
2183
  walletType,
1887
- chainType: "evm" /* EVM */,
2184
+ chainType: ChainType.EVM,
1888
2185
  // 默认
1889
2186
  isAvailable: false,
1890
2187
  detected: false
@@ -1923,11 +2220,11 @@ var WalletDetector = class {
1923
2220
  }
1924
2221
  }
1925
2222
  /**
1926
- * 检测 MetaMask
2223
+ * 检测 MetaMask(现在支持所有 window.ethereum 钱包)
1927
2224
  */
1928
2225
  isMetaMaskAvailable() {
1929
2226
  const w = window;
1930
- return !!(w.ethereum && w.ethereum.isMetaMask);
2227
+ return !!w.ethereum;
1931
2228
  }
1932
2229
  /**
1933
2230
  * 检测 TronLink
@@ -1992,9 +2289,9 @@ function shortenTronAddress(address, chars = 4) {
1992
2289
  // src/utils/validation.ts
1993
2290
  function validateAddress(address, chainType) {
1994
2291
  switch (chainType) {
1995
- case "evm" /* EVM */:
2292
+ case ChainType.EVM:
1996
2293
  return isValidEVMAddress(address);
1997
- case "tron" /* TRON */:
2294
+ case ChainType.TRON:
1998
2295
  return isValidTronAddress(address);
1999
2296
  default:
2000
2297
  return false;
@@ -2015,9 +2312,9 @@ function isValidSignature(signature) {
2015
2312
  }
2016
2313
  function isValidTransactionHash(txHash, chainType) {
2017
2314
  switch (chainType) {
2018
- case "evm" /* EVM */:
2315
+ case ChainType.EVM:
2019
2316
  return /^0x[0-9a-fA-F]{64}$/.test(txHash);
2020
- case "tron" /* TRON */:
2317
+ case ChainType.TRON:
2021
2318
  return /^[0-9a-fA-F]{64}$/.test(txHash);
2022
2319
  default:
2023
2320
  return false;