@enclave-hq/wallet-sdk 1.0.0 → 1.0.1

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 ? `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
  */
@@ -822,9 +881,14 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
822
881
  constructor() {
823
882
  super(...arguments);
824
883
  this.type = "tronlink" /* TRONLINK */;
825
- this.chainType = "tron" /* TRON */;
884
+ this.chainType = ChainType.TRON;
826
885
  this.name = "TronLink";
827
886
  this.icon = "https://www.tronlink.org/static/logoIcon.svg";
887
+ /**
888
+ * 轮询检测账户变化(备用方案)
889
+ */
890
+ this.pollingInterval = null;
891
+ this.lastKnownAddress = null;
828
892
  /**
829
893
  * 处理账户变化
830
894
  */
@@ -839,7 +903,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
839
903
  universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
840
904
  nativeAddress: address,
841
905
  chainId: this.currentAccount.chainId,
842
- chainType: "tron" /* TRON */,
906
+ chainType: ChainType.TRON,
843
907
  isActive: true
844
908
  };
845
909
  this.setAccount(account);
@@ -878,7 +942,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
878
942
  universalAddress: createUniversalAddress(tronChainId, address),
879
943
  nativeAddress: address,
880
944
  chainId: tronChainId,
881
- chainType: "tron" /* TRON */,
945
+ chainType: ChainType.TRON,
882
946
  isActive: true
883
947
  };
884
948
  this.setState("connected" /* CONNECTED */);
@@ -896,20 +960,177 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
896
960
  }
897
961
  /**
898
962
  * 签名消息
963
+ *
964
+ * Note: TronLink supports two signing methods:
965
+ * - trx.sign(): Signs a transaction object
966
+ * - trx.signMessageV2(): Signs a plain text message (what we use here)
899
967
  */
900
968
  async signMessage(message) {
901
969
  this.ensureConnected();
902
970
  try {
903
971
  const tronWeb = this.getTronWeb();
904
- const signature = await tronWeb.trx.sign(message);
905
- return signature;
972
+ if (typeof tronWeb.trx.signMessageV2 === "function") {
973
+ const signature = await tronWeb.trx.signMessageV2(message);
974
+ return signature;
975
+ } else {
976
+ console.warn("[TronLink] signMessageV2 not available, falling back to sign()");
977
+ const signature = await tronWeb.trx.sign(message);
978
+ return signature;
979
+ }
906
980
  } catch (error) {
907
981
  if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
908
982
  throw new SignatureRejectedError();
909
983
  }
984
+ if (error.message?.includes("Invalid transaction")) {
985
+ throw new Error("Invalid message format. For transaction signing, use signTransaction() instead.");
986
+ }
910
987
  throw error;
911
988
  }
912
989
  }
990
+ /**
991
+ * 签名交易
992
+ *
993
+ * Note: This uses trx.sign() which is specifically for signing transaction objects.
994
+ * For plain text message signing, use signMessage() instead.
995
+ */
996
+ async signTransaction(transaction) {
997
+ this.ensureConnected();
998
+ try {
999
+ const tronWeb = this.getTronWeb();
1000
+ const signature = await tronWeb.trx.sign(transaction);
1001
+ return signature;
1002
+ } catch (error) {
1003
+ if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
1004
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
1005
+ }
1006
+ if (error.message?.includes("Invalid transaction")) {
1007
+ throw new Error("Invalid transaction format. Please provide a properly formatted Tron transaction object.");
1008
+ }
1009
+ throw error;
1010
+ }
1011
+ }
1012
+ /**
1013
+ * 读取合约
1014
+ */
1015
+ async readContract(params) {
1016
+ this.ensureConnected();
1017
+ try {
1018
+ const tronWeb = this.getTronWeb();
1019
+ const contract = await tronWeb.contract(params.abi, params.address);
1020
+ const result = await contract[params.functionName](...params.args || []).call();
1021
+ return result;
1022
+ } catch (error) {
1023
+ console.error("Read contract error:", error);
1024
+ throw new Error(`Failed to read contract: ${error.message}`);
1025
+ }
1026
+ }
1027
+ /**
1028
+ * 写入合约
1029
+ */
1030
+ async writeContract(params) {
1031
+ this.ensureConnected();
1032
+ try {
1033
+ const tronWeb = this.getTronWeb();
1034
+ console.log("[TronLink] writeContract params:", {
1035
+ address: params.address,
1036
+ functionName: params.functionName,
1037
+ args: params.args,
1038
+ value: params.value,
1039
+ gas: params.gas
1040
+ });
1041
+ if (!params.args || params.args.length === 0) {
1042
+ throw new Error("Contract function arguments are required");
1043
+ }
1044
+ const hasUndefined = params.args.some((arg) => arg === void 0 || arg === null);
1045
+ if (hasUndefined) {
1046
+ console.error("[TronLink] Invalid args detected:", params.args);
1047
+ throw new Error(`Invalid contract arguments: some arguments are undefined or null`);
1048
+ }
1049
+ const functionAbi = params.abi.find(
1050
+ (item) => item.name === params.functionName && item.type === "function"
1051
+ );
1052
+ if (!functionAbi) {
1053
+ throw new Error(`Function ${params.functionName} not found in ABI`);
1054
+ }
1055
+ console.log("[TronLink] Function ABI:", functionAbi);
1056
+ console.log("[TronLink] Calling with args:", params.args);
1057
+ const options = {
1058
+ feeLimit: params.gas || 1e8,
1059
+ // 默认 100 TRX 的能量限制
1060
+ callValue: params.value || 0
1061
+ // 发送的 TRX 数量(单位:SUN)
1062
+ };
1063
+ const parameter = functionAbi.inputs.map((input, index) => ({
1064
+ type: input.type,
1065
+ value: params.args[index]
1066
+ }));
1067
+ console.log("[TronLink] Transaction options:", options);
1068
+ console.log("[TronLink] Parameters:", parameter);
1069
+ const transaction = await tronWeb.transactionBuilder.triggerSmartContract(
1070
+ params.address,
1071
+ params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")",
1072
+ options,
1073
+ parameter,
1074
+ this.currentAccount.nativeAddress
1075
+ );
1076
+ console.log("[TronLink] Transaction built:", transaction);
1077
+ if (!transaction || !transaction.transaction) {
1078
+ throw new Error("Failed to build transaction");
1079
+ }
1080
+ const signedTx = await tronWeb.trx.sign(transaction.transaction);
1081
+ const broadcast = await tronWeb.trx.sendRawTransaction(signedTx);
1082
+ console.log("[TronLink] Broadcast result:", broadcast);
1083
+ if (!broadcast.result) {
1084
+ throw new Error(broadcast.message || "Transaction broadcast failed");
1085
+ }
1086
+ const txHash = broadcast.txid || broadcast.transaction?.txID;
1087
+ console.log("[TronLink] Transaction hash:", txHash);
1088
+ return txHash || "";
1089
+ } catch (error) {
1090
+ console.error("Write contract error:", error);
1091
+ if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
1092
+ throw new SignatureRejectedError("Transaction was rejected by user");
1093
+ }
1094
+ throw new Error(`Failed to write contract: ${error.message}`);
1095
+ }
1096
+ }
1097
+ /**
1098
+ * 等待交易确认
1099
+ */
1100
+ async waitForTransaction(txHash, _confirmations = 1) {
1101
+ try {
1102
+ const tronWeb = this.getTronWeb();
1103
+ let attempts = 0;
1104
+ const maxAttempts = 60;
1105
+ while (attempts < maxAttempts) {
1106
+ try {
1107
+ const txInfo = await tronWeb.trx.getTransactionInfo(txHash);
1108
+ if (txInfo && txInfo.id) {
1109
+ const receipt = {
1110
+ transactionHash: txHash,
1111
+ blockNumber: txInfo.blockNumber || 0,
1112
+ blockHash: txInfo.blockHash || "",
1113
+ from: this.currentAccount.nativeAddress,
1114
+ to: txInfo.contract_address || "",
1115
+ status: txInfo.receipt?.result === "SUCCESS" ? "success" : "failed",
1116
+ gasUsed: (txInfo.receipt?.energy_usage_total || 0).toString(),
1117
+ logs: txInfo.log || []
1118
+ };
1119
+ if (receipt.status === "failed") {
1120
+ throw new TransactionFailedError(txHash, "Transaction failed on Tron network");
1121
+ }
1122
+ return receipt;
1123
+ }
1124
+ } catch (error) {
1125
+ }
1126
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1127
+ attempts++;
1128
+ }
1129
+ throw new Error("Transaction confirmation timeout");
1130
+ } catch (error) {
1131
+ throw new Error(`Failed to wait for transaction: ${error.message}`);
1132
+ }
1133
+ }
913
1134
  /**
914
1135
  * 获取 Provider
915
1136
  */
@@ -948,9 +1169,16 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
948
1169
  setupEventListeners() {
949
1170
  if (typeof window === "undefined") return;
950
1171
  const w = window;
951
- if (w.tronLink) {
952
- w.tronLink.on("accountsChanged", this.handleAccountsChanged);
953
- w.tronLink.on("disconnect", this.handleDisconnect);
1172
+ try {
1173
+ if (w.tronLink && typeof w.tronLink.on === "function") {
1174
+ w.tronLink.on("accountsChanged", this.handleAccountsChanged);
1175
+ w.tronLink.on("disconnect", this.handleDisconnect);
1176
+ } else if (w.tronWeb && w.tronWeb.eventServer) {
1177
+ this.startPolling();
1178
+ }
1179
+ } catch (error) {
1180
+ console.warn("TronLink event listener setup failed:", error);
1181
+ this.startPolling();
954
1182
  }
955
1183
  }
956
1184
  /**
@@ -959,9 +1187,38 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
959
1187
  removeEventListeners() {
960
1188
  if (typeof window === "undefined") return;
961
1189
  const w = window;
962
- if (w.tronLink) {
963
- w.tronLink.off("accountsChanged", this.handleAccountsChanged);
964
- w.tronLink.off("disconnect", this.handleDisconnect);
1190
+ try {
1191
+ if (w.tronLink && typeof w.tronLink.off === "function") {
1192
+ w.tronLink.off("accountsChanged", this.handleAccountsChanged);
1193
+ w.tronLink.off("disconnect", this.handleDisconnect);
1194
+ }
1195
+ } catch (error) {
1196
+ console.warn("TronLink event listener removal failed:", error);
1197
+ }
1198
+ this.stopPolling();
1199
+ }
1200
+ startPolling() {
1201
+ if (this.pollingInterval) return;
1202
+ this.lastKnownAddress = this.currentAccount?.nativeAddress || null;
1203
+ this.pollingInterval = setInterval(async () => {
1204
+ try {
1205
+ const tronWeb = this.getTronWeb();
1206
+ const currentAddress = tronWeb.defaultAddress?.base58;
1207
+ if (currentAddress && currentAddress !== this.lastKnownAddress) {
1208
+ this.lastKnownAddress = currentAddress;
1209
+ this.handleAccountsChanged({ address: { base58: currentAddress } });
1210
+ } else if (!currentAddress && this.lastKnownAddress) {
1211
+ this.lastKnownAddress = null;
1212
+ this.handleAccountsChanged(null);
1213
+ }
1214
+ } catch (error) {
1215
+ }
1216
+ }, 2e3);
1217
+ }
1218
+ stopPolling() {
1219
+ if (this.pollingInterval) {
1220
+ clearInterval(this.pollingInterval);
1221
+ this.pollingInterval = null;
965
1222
  }
966
1223
  }
967
1224
  };
@@ -972,7 +1229,7 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
972
1229
  constructor() {
973
1230
  super(...arguments);
974
1231
  this.type = "private-key" /* PRIVATE_KEY */;
975
- this.chainType = "evm" /* EVM */;
1232
+ this.chainType = ChainType.EVM;
976
1233
  this.name = "Private Key (EVM)";
977
1234
  this.privateKey = null;
978
1235
  this.walletClient = null;
@@ -1002,7 +1259,7 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1002
1259
  universalAddress: createUniversalAddress(chainId, address),
1003
1260
  nativeAddress: address,
1004
1261
  chainId,
1005
- chainType: "evm" /* EVM */,
1262
+ chainType: ChainType.EVM,
1006
1263
  isActive: true
1007
1264
  };
1008
1265
  this.setState("connected" /* CONNECTED */);
@@ -1352,9 +1609,10 @@ var WalletManager = class extends TypedEventEmitter {
1352
1609
  if (!this.primaryWallet) {
1353
1610
  return;
1354
1611
  }
1612
+ const chainType = this.primaryWallet.chainType;
1355
1613
  await this.primaryWallet.disconnect();
1356
1614
  this.removeAdapterListeners(this.primaryWallet);
1357
- this.connectedWallets.delete(this.primaryWallet.chainType);
1615
+ this.connectedWallets.delete(chainType);
1358
1616
  this.primaryWallet = null;
1359
1617
  if (this.config.enableStorage) {
1360
1618
  this.saveToStorage();
@@ -1459,6 +1717,34 @@ var WalletManager = class extends TypedEventEmitter {
1459
1717
  }
1460
1718
  return adapter.signTypedData(typedData);
1461
1719
  }
1720
+ /**
1721
+ * 签名交易(使用主钱包)
1722
+ */
1723
+ async signTransaction(transaction) {
1724
+ if (!this.primaryWallet) {
1725
+ throw new WalletNotConnectedError();
1726
+ }
1727
+ if (!this.primaryWallet.signTransaction) {
1728
+ throw new Error(`signTransaction not supported by ${this.primaryWallet.type}`);
1729
+ }
1730
+ return this.primaryWallet.signTransaction(transaction);
1731
+ }
1732
+ /**
1733
+ * 使用指定链类型的钱包签名交易
1734
+ */
1735
+ async signTransactionWithChainType(transaction, chainType) {
1736
+ if (!chainType) {
1737
+ return this.signTransaction(transaction);
1738
+ }
1739
+ const adapter = this.connectedWallets.get(chainType);
1740
+ if (!adapter) {
1741
+ throw new WalletNotConnectedError(`Wallet for chain type ${chainType}`);
1742
+ }
1743
+ if (!adapter.signTransaction) {
1744
+ throw new Error(`signTransaction not supported by ${adapter.type}`);
1745
+ }
1746
+ return adapter.signTransaction(transaction);
1747
+ }
1462
1748
  // ===== 链切换 =====
1463
1749
  /**
1464
1750
  * 请求切换链(仅 EVM)
@@ -1619,6 +1905,7 @@ var WalletManager = class extends TypedEventEmitter {
1619
1905
  * 移除适配器事件监听
1620
1906
  */
1621
1907
  removeAdapterListeners(adapter) {
1908
+ if (!adapter) return;
1622
1909
  adapter.removeAllListeners();
1623
1910
  }
1624
1911
  // ===== 存储 =====
@@ -1692,7 +1979,7 @@ var AuthMessageGenerator = class {
1692
1979
  */
1693
1980
  generateAuthMessage(chainType, nonce, chainId, timestamp = Date.now(), statement) {
1694
1981
  switch (chainType) {
1695
- case "evm" /* EVM */:
1982
+ case ChainType.EVM:
1696
1983
  return this.generateEIP191Message({
1697
1984
  domain: this.domain,
1698
1985
  nonce,
@@ -1700,7 +1987,7 @@ var AuthMessageGenerator = class {
1700
1987
  timestamp,
1701
1988
  statement
1702
1989
  });
1703
- case "tron" /* TRON */:
1990
+ case ChainType.TRON:
1704
1991
  return this.generateTIP191Message({
1705
1992
  domain: this.domain,
1706
1993
  nonce,
@@ -1763,9 +2050,9 @@ var SignatureVerifier = class {
1763
2050
  */
1764
2051
  async verifySignature(message, signature, expectedAddress, chainType) {
1765
2052
  switch (chainType) {
1766
- case "evm" /* EVM */:
2053
+ case ChainType.EVM:
1767
2054
  return this.verifyEIP191Signature(message, signature, expectedAddress);
1768
- case "tron" /* TRON */:
2055
+ case ChainType.TRON:
1769
2056
  return this.verifyTIP191Signature(message, signature, expectedAddress);
1770
2057
  default:
1771
2058
  throw new Error(`Unsupported chain type: ${chainType}`);
@@ -1803,7 +2090,7 @@ var SUPPORTED_WALLETS = {
1803
2090
  ["metamask" /* METAMASK */]: {
1804
2091
  type: "metamask" /* METAMASK */,
1805
2092
  name: "MetaMask",
1806
- chainType: "evm" /* EVM */,
2093
+ chainType: ChainType.EVM,
1807
2094
  icon: "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg",
1808
2095
  downloadUrl: "https://metamask.io/download/",
1809
2096
  description: "The most popular Ethereum wallet"
@@ -1811,7 +2098,7 @@ var SUPPORTED_WALLETS = {
1811
2098
  ["walletconnect" /* WALLETCONNECT */]: {
1812
2099
  type: "walletconnect" /* WALLETCONNECT */,
1813
2100
  name: "WalletConnect",
1814
- chainType: "evm" /* EVM */,
2101
+ chainType: ChainType.EVM,
1815
2102
  icon: "https://avatars.githubusercontent.com/u/37784886",
1816
2103
  downloadUrl: "https://walletconnect.com/",
1817
2104
  description: "Connect to 170+ wallets"
@@ -1819,7 +2106,7 @@ var SUPPORTED_WALLETS = {
1819
2106
  ["coinbase-wallet" /* COINBASE_WALLET */]: {
1820
2107
  type: "coinbase-wallet" /* COINBASE_WALLET */,
1821
2108
  name: "Coinbase Wallet",
1822
- chainType: "evm" /* EVM */,
2109
+ chainType: ChainType.EVM,
1823
2110
  icon: "https://www.coinbase.com/img/favicon/favicon-96x96.png",
1824
2111
  downloadUrl: "https://www.coinbase.com/wallet",
1825
2112
  description: "Coinbase self-custody wallet"
@@ -1827,7 +2114,7 @@ var SUPPORTED_WALLETS = {
1827
2114
  ["tronlink" /* TRONLINK */]: {
1828
2115
  type: "tronlink" /* TRONLINK */,
1829
2116
  name: "TronLink",
1830
- chainType: "tron" /* TRON */,
2117
+ chainType: ChainType.TRON,
1831
2118
  icon: "https://www.tronlink.org/static/logoIcon.svg",
1832
2119
  downloadUrl: "https://www.tronlink.org/",
1833
2120
  description: "The official Tron wallet"
@@ -1835,14 +2122,14 @@ var SUPPORTED_WALLETS = {
1835
2122
  ["walletconnect-tron" /* WALLETCONNECT_TRON */]: {
1836
2123
  type: "walletconnect-tron" /* WALLETCONNECT_TRON */,
1837
2124
  name: "WalletConnect (Tron)",
1838
- chainType: "tron" /* TRON */,
2125
+ chainType: ChainType.TRON,
1839
2126
  downloadUrl: "https://walletconnect.com/",
1840
2127
  description: "WalletConnect for Tron"
1841
2128
  },
1842
2129
  ["private-key" /* PRIVATE_KEY */]: {
1843
2130
  type: "private-key" /* PRIVATE_KEY */,
1844
2131
  name: "Private Key",
1845
- chainType: "evm" /* EVM */,
2132
+ chainType: ChainType.EVM,
1846
2133
  // 可以用于任何链
1847
2134
  description: "Import wallet using private key (for development)"
1848
2135
  }
@@ -1852,12 +2139,12 @@ function getWalletMetadata(type) {
1852
2139
  }
1853
2140
  function getEVMWallets() {
1854
2141
  return Object.values(SUPPORTED_WALLETS).filter(
1855
- (wallet) => wallet.chainType === "evm" /* EVM */
2142
+ (wallet) => wallet.chainType === ChainType.EVM
1856
2143
  );
1857
2144
  }
1858
2145
  function getTronWallets() {
1859
2146
  return Object.values(SUPPORTED_WALLETS).filter(
1860
- (wallet) => wallet.chainType === "tron" /* TRON */
2147
+ (wallet) => wallet.chainType === ChainType.TRON
1861
2148
  );
1862
2149
  }
1863
2150
 
@@ -1884,7 +2171,7 @@ var WalletDetector = class {
1884
2171
  if (!metadata) {
1885
2172
  return {
1886
2173
  walletType,
1887
- chainType: "evm" /* EVM */,
2174
+ chainType: ChainType.EVM,
1888
2175
  // 默认
1889
2176
  isAvailable: false,
1890
2177
  detected: false
@@ -1992,9 +2279,9 @@ function shortenTronAddress(address, chars = 4) {
1992
2279
  // src/utils/validation.ts
1993
2280
  function validateAddress(address, chainType) {
1994
2281
  switch (chainType) {
1995
- case "evm" /* EVM */:
2282
+ case ChainType.EVM:
1996
2283
  return isValidEVMAddress(address);
1997
- case "tron" /* TRON */:
2284
+ case ChainType.TRON:
1998
2285
  return isValidTronAddress(address);
1999
2286
  default:
2000
2287
  return false;
@@ -2015,9 +2302,9 @@ function isValidSignature(signature) {
2015
2302
  }
2016
2303
  function isValidTransactionHash(txHash, chainType) {
2017
2304
  switch (chainType) {
2018
- case "evm" /* EVM */:
2305
+ case ChainType.EVM:
2019
2306
  return /^0x[0-9a-fA-F]{64}$/.test(txHash);
2020
- case "tron" /* TRON */:
2307
+ case ChainType.TRON:
2021
2308
  return /^[0-9a-fA-F]{64}$/.test(txHash);
2022
2309
  default:
2023
2310
  return false;