@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.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 ? `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
  */
@@ -830,9 +889,14 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
830
889
  constructor() {
831
890
  super(...arguments);
832
891
  this.type = "tronlink" /* TRONLINK */;
833
- this.chainType = "tron" /* TRON */;
892
+ this.chainType = ChainType.TRON;
834
893
  this.name = "TronLink";
835
894
  this.icon = "https://www.tronlink.org/static/logoIcon.svg";
895
+ /**
896
+ * 轮询检测账户变化(备用方案)
897
+ */
898
+ this.pollingInterval = null;
899
+ this.lastKnownAddress = null;
836
900
  /**
837
901
  * 处理账户变化
838
902
  */
@@ -847,7 +911,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
847
911
  universalAddress: createUniversalAddress(this.currentAccount.chainId, address),
848
912
  nativeAddress: address,
849
913
  chainId: this.currentAccount.chainId,
850
- chainType: "tron" /* TRON */,
914
+ chainType: ChainType.TRON,
851
915
  isActive: true
852
916
  };
853
917
  this.setAccount(account);
@@ -886,7 +950,7 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
886
950
  universalAddress: createUniversalAddress(tronChainId, address),
887
951
  nativeAddress: address,
888
952
  chainId: tronChainId,
889
- chainType: "tron" /* TRON */,
953
+ chainType: ChainType.TRON,
890
954
  isActive: true
891
955
  };
892
956
  this.setState("connected" /* CONNECTED */);
@@ -904,20 +968,177 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
904
968
  }
905
969
  /**
906
970
  * 签名消息
971
+ *
972
+ * Note: TronLink supports two signing methods:
973
+ * - trx.sign(): Signs a transaction object
974
+ * - trx.signMessageV2(): Signs a plain text message (what we use here)
907
975
  */
908
976
  async signMessage(message) {
909
977
  this.ensureConnected();
910
978
  try {
911
979
  const tronWeb = this.getTronWeb();
912
- const signature = await tronWeb.trx.sign(message);
913
- return signature;
980
+ if (typeof tronWeb.trx.signMessageV2 === "function") {
981
+ const signature = await tronWeb.trx.signMessageV2(message);
982
+ return signature;
983
+ } else {
984
+ console.warn("[TronLink] signMessageV2 not available, falling back to sign()");
985
+ const signature = await tronWeb.trx.sign(message);
986
+ return signature;
987
+ }
914
988
  } catch (error) {
915
989
  if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
916
990
  throw new SignatureRejectedError();
917
991
  }
992
+ if (error.message?.includes("Invalid transaction")) {
993
+ throw new Error("Invalid message format. For transaction signing, use signTransaction() instead.");
994
+ }
918
995
  throw error;
919
996
  }
920
997
  }
998
+ /**
999
+ * 签名交易
1000
+ *
1001
+ * Note: This uses trx.sign() which is specifically for signing transaction objects.
1002
+ * For plain text message signing, use signMessage() instead.
1003
+ */
1004
+ async signTransaction(transaction) {
1005
+ this.ensureConnected();
1006
+ try {
1007
+ const tronWeb = this.getTronWeb();
1008
+ const signature = await tronWeb.trx.sign(transaction);
1009
+ return signature;
1010
+ } catch (error) {
1011
+ if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
1012
+ throw new SignatureRejectedError("Transaction signature was rejected by user");
1013
+ }
1014
+ if (error.message?.includes("Invalid transaction")) {
1015
+ throw new Error("Invalid transaction format. Please provide a properly formatted Tron transaction object.");
1016
+ }
1017
+ throw error;
1018
+ }
1019
+ }
1020
+ /**
1021
+ * 读取合约
1022
+ */
1023
+ async readContract(params) {
1024
+ this.ensureConnected();
1025
+ try {
1026
+ const tronWeb = this.getTronWeb();
1027
+ const contract = await tronWeb.contract(params.abi, params.address);
1028
+ const result = await contract[params.functionName](...params.args || []).call();
1029
+ return result;
1030
+ } catch (error) {
1031
+ console.error("Read contract error:", error);
1032
+ throw new Error(`Failed to read contract: ${error.message}`);
1033
+ }
1034
+ }
1035
+ /**
1036
+ * 写入合约
1037
+ */
1038
+ async writeContract(params) {
1039
+ this.ensureConnected();
1040
+ try {
1041
+ const tronWeb = this.getTronWeb();
1042
+ console.log("[TronLink] writeContract params:", {
1043
+ address: params.address,
1044
+ functionName: params.functionName,
1045
+ args: params.args,
1046
+ value: params.value,
1047
+ gas: params.gas
1048
+ });
1049
+ if (!params.args || params.args.length === 0) {
1050
+ throw new Error("Contract function arguments are required");
1051
+ }
1052
+ const hasUndefined = params.args.some((arg) => arg === void 0 || arg === null);
1053
+ if (hasUndefined) {
1054
+ console.error("[TronLink] Invalid args detected:", params.args);
1055
+ throw new Error(`Invalid contract arguments: some arguments are undefined or null`);
1056
+ }
1057
+ const functionAbi = params.abi.find(
1058
+ (item) => item.name === params.functionName && item.type === "function"
1059
+ );
1060
+ if (!functionAbi) {
1061
+ throw new Error(`Function ${params.functionName} not found in ABI`);
1062
+ }
1063
+ console.log("[TronLink] Function ABI:", functionAbi);
1064
+ console.log("[TronLink] Calling with args:", params.args);
1065
+ const options = {
1066
+ feeLimit: params.gas || 1e8,
1067
+ // 默认 100 TRX 的能量限制
1068
+ callValue: params.value || 0
1069
+ // 发送的 TRX 数量(单位:SUN)
1070
+ };
1071
+ const parameter = functionAbi.inputs.map((input, index) => ({
1072
+ type: input.type,
1073
+ value: params.args[index]
1074
+ }));
1075
+ console.log("[TronLink] Transaction options:", options);
1076
+ console.log("[TronLink] Parameters:", parameter);
1077
+ const transaction = await tronWeb.transactionBuilder.triggerSmartContract(
1078
+ params.address,
1079
+ params.functionName + "(" + functionAbi.inputs.map((i) => i.type).join(",") + ")",
1080
+ options,
1081
+ parameter,
1082
+ this.currentAccount.nativeAddress
1083
+ );
1084
+ console.log("[TronLink] Transaction built:", transaction);
1085
+ if (!transaction || !transaction.transaction) {
1086
+ throw new Error("Failed to build transaction");
1087
+ }
1088
+ const signedTx = await tronWeb.trx.sign(transaction.transaction);
1089
+ const broadcast = await tronWeb.trx.sendRawTransaction(signedTx);
1090
+ console.log("[TronLink] Broadcast result:", broadcast);
1091
+ if (!broadcast.result) {
1092
+ throw new Error(broadcast.message || "Transaction broadcast failed");
1093
+ }
1094
+ const txHash = broadcast.txid || broadcast.transaction?.txID;
1095
+ console.log("[TronLink] Transaction hash:", txHash);
1096
+ return txHash || "";
1097
+ } catch (error) {
1098
+ console.error("Write contract error:", error);
1099
+ if (error.message?.includes("User rejected") || error.message?.includes("Confirmation declined")) {
1100
+ throw new SignatureRejectedError("Transaction was rejected by user");
1101
+ }
1102
+ throw new Error(`Failed to write contract: ${error.message}`);
1103
+ }
1104
+ }
1105
+ /**
1106
+ * 等待交易确认
1107
+ */
1108
+ async waitForTransaction(txHash, _confirmations = 1) {
1109
+ try {
1110
+ const tronWeb = this.getTronWeb();
1111
+ let attempts = 0;
1112
+ const maxAttempts = 60;
1113
+ while (attempts < maxAttempts) {
1114
+ try {
1115
+ const txInfo = await tronWeb.trx.getTransactionInfo(txHash);
1116
+ if (txInfo && txInfo.id) {
1117
+ const receipt = {
1118
+ transactionHash: txHash,
1119
+ blockNumber: txInfo.blockNumber || 0,
1120
+ blockHash: txInfo.blockHash || "",
1121
+ from: this.currentAccount.nativeAddress,
1122
+ to: txInfo.contract_address || "",
1123
+ status: txInfo.receipt?.result === "SUCCESS" ? "success" : "failed",
1124
+ gasUsed: (txInfo.receipt?.energy_usage_total || 0).toString(),
1125
+ logs: txInfo.log || []
1126
+ };
1127
+ if (receipt.status === "failed") {
1128
+ throw new TransactionFailedError(txHash, "Transaction failed on Tron network");
1129
+ }
1130
+ return receipt;
1131
+ }
1132
+ } catch (error) {
1133
+ }
1134
+ await new Promise((resolve) => setTimeout(resolve, 1e3));
1135
+ attempts++;
1136
+ }
1137
+ throw new Error("Transaction confirmation timeout");
1138
+ } catch (error) {
1139
+ throw new Error(`Failed to wait for transaction: ${error.message}`);
1140
+ }
1141
+ }
921
1142
  /**
922
1143
  * 获取 Provider
923
1144
  */
@@ -956,9 +1177,16 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
956
1177
  setupEventListeners() {
957
1178
  if (typeof window === "undefined") return;
958
1179
  const w = window;
959
- if (w.tronLink) {
960
- w.tronLink.on("accountsChanged", this.handleAccountsChanged);
961
- w.tronLink.on("disconnect", this.handleDisconnect);
1180
+ try {
1181
+ if (w.tronLink && typeof w.tronLink.on === "function") {
1182
+ w.tronLink.on("accountsChanged", this.handleAccountsChanged);
1183
+ w.tronLink.on("disconnect", this.handleDisconnect);
1184
+ } else if (w.tronWeb && w.tronWeb.eventServer) {
1185
+ this.startPolling();
1186
+ }
1187
+ } catch (error) {
1188
+ console.warn("TronLink event listener setup failed:", error);
1189
+ this.startPolling();
962
1190
  }
963
1191
  }
964
1192
  /**
@@ -967,9 +1195,38 @@ var _TronLinkAdapter = class _TronLinkAdapter extends BrowserWalletAdapter {
967
1195
  removeEventListeners() {
968
1196
  if (typeof window === "undefined") return;
969
1197
  const w = window;
970
- if (w.tronLink) {
971
- w.tronLink.off("accountsChanged", this.handleAccountsChanged);
972
- w.tronLink.off("disconnect", this.handleDisconnect);
1198
+ try {
1199
+ if (w.tronLink && typeof w.tronLink.off === "function") {
1200
+ w.tronLink.off("accountsChanged", this.handleAccountsChanged);
1201
+ w.tronLink.off("disconnect", this.handleDisconnect);
1202
+ }
1203
+ } catch (error) {
1204
+ console.warn("TronLink event listener removal failed:", error);
1205
+ }
1206
+ this.stopPolling();
1207
+ }
1208
+ startPolling() {
1209
+ if (this.pollingInterval) return;
1210
+ this.lastKnownAddress = this.currentAccount?.nativeAddress || null;
1211
+ this.pollingInterval = setInterval(async () => {
1212
+ try {
1213
+ const tronWeb = this.getTronWeb();
1214
+ const currentAddress = tronWeb.defaultAddress?.base58;
1215
+ if (currentAddress && currentAddress !== this.lastKnownAddress) {
1216
+ this.lastKnownAddress = currentAddress;
1217
+ this.handleAccountsChanged({ address: { base58: currentAddress } });
1218
+ } else if (!currentAddress && this.lastKnownAddress) {
1219
+ this.lastKnownAddress = null;
1220
+ this.handleAccountsChanged(null);
1221
+ }
1222
+ } catch (error) {
1223
+ }
1224
+ }, 2e3);
1225
+ }
1226
+ stopPolling() {
1227
+ if (this.pollingInterval) {
1228
+ clearInterval(this.pollingInterval);
1229
+ this.pollingInterval = null;
973
1230
  }
974
1231
  }
975
1232
  };
@@ -980,7 +1237,7 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
980
1237
  constructor() {
981
1238
  super(...arguments);
982
1239
  this.type = "private-key" /* PRIVATE_KEY */;
983
- this.chainType = "evm" /* EVM */;
1240
+ this.chainType = ChainType.EVM;
984
1241
  this.name = "Private Key (EVM)";
985
1242
  this.privateKey = null;
986
1243
  this.walletClient = null;
@@ -1010,7 +1267,7 @@ var EVMPrivateKeyAdapter = class extends WalletAdapter {
1010
1267
  universalAddress: createUniversalAddress(chainId, address),
1011
1268
  nativeAddress: address,
1012
1269
  chainId,
1013
- chainType: "evm" /* EVM */,
1270
+ chainType: ChainType.EVM,
1014
1271
  isActive: true
1015
1272
  };
1016
1273
  this.setState("connected" /* CONNECTED */);
@@ -1360,9 +1617,10 @@ var WalletManager = class extends TypedEventEmitter {
1360
1617
  if (!this.primaryWallet) {
1361
1618
  return;
1362
1619
  }
1620
+ const chainType = this.primaryWallet.chainType;
1363
1621
  await this.primaryWallet.disconnect();
1364
1622
  this.removeAdapterListeners(this.primaryWallet);
1365
- this.connectedWallets.delete(this.primaryWallet.chainType);
1623
+ this.connectedWallets.delete(chainType);
1366
1624
  this.primaryWallet = null;
1367
1625
  if (this.config.enableStorage) {
1368
1626
  this.saveToStorage();
@@ -1467,6 +1725,34 @@ var WalletManager = class extends TypedEventEmitter {
1467
1725
  }
1468
1726
  return adapter.signTypedData(typedData);
1469
1727
  }
1728
+ /**
1729
+ * 签名交易(使用主钱包)
1730
+ */
1731
+ async signTransaction(transaction) {
1732
+ if (!this.primaryWallet) {
1733
+ throw new WalletNotConnectedError();
1734
+ }
1735
+ if (!this.primaryWallet.signTransaction) {
1736
+ throw new Error(`signTransaction not supported by ${this.primaryWallet.type}`);
1737
+ }
1738
+ return this.primaryWallet.signTransaction(transaction);
1739
+ }
1740
+ /**
1741
+ * 使用指定链类型的钱包签名交易
1742
+ */
1743
+ async signTransactionWithChainType(transaction, chainType) {
1744
+ if (!chainType) {
1745
+ return this.signTransaction(transaction);
1746
+ }
1747
+ const adapter = this.connectedWallets.get(chainType);
1748
+ if (!adapter) {
1749
+ throw new WalletNotConnectedError(`Wallet for chain type ${chainType}`);
1750
+ }
1751
+ if (!adapter.signTransaction) {
1752
+ throw new Error(`signTransaction not supported by ${adapter.type}`);
1753
+ }
1754
+ return adapter.signTransaction(transaction);
1755
+ }
1470
1756
  // ===== 链切换 =====
1471
1757
  /**
1472
1758
  * 请求切换链(仅 EVM)
@@ -1627,6 +1913,7 @@ var WalletManager = class extends TypedEventEmitter {
1627
1913
  * 移除适配器事件监听
1628
1914
  */
1629
1915
  removeAdapterListeners(adapter) {
1916
+ if (!adapter) return;
1630
1917
  adapter.removeAllListeners();
1631
1918
  }
1632
1919
  // ===== 存储 =====
@@ -1700,7 +1987,7 @@ var AuthMessageGenerator = class {
1700
1987
  */
1701
1988
  generateAuthMessage(chainType, nonce, chainId, timestamp = Date.now(), statement) {
1702
1989
  switch (chainType) {
1703
- case "evm" /* EVM */:
1990
+ case ChainType.EVM:
1704
1991
  return this.generateEIP191Message({
1705
1992
  domain: this.domain,
1706
1993
  nonce,
@@ -1708,7 +1995,7 @@ var AuthMessageGenerator = class {
1708
1995
  timestamp,
1709
1996
  statement
1710
1997
  });
1711
- case "tron" /* TRON */:
1998
+ case ChainType.TRON:
1712
1999
  return this.generateTIP191Message({
1713
2000
  domain: this.domain,
1714
2001
  nonce,
@@ -1771,9 +2058,9 @@ var SignatureVerifier = class {
1771
2058
  */
1772
2059
  async verifySignature(message, signature, expectedAddress, chainType) {
1773
2060
  switch (chainType) {
1774
- case "evm" /* EVM */:
2061
+ case ChainType.EVM:
1775
2062
  return this.verifyEIP191Signature(message, signature, expectedAddress);
1776
- case "tron" /* TRON */:
2063
+ case ChainType.TRON:
1777
2064
  return this.verifyTIP191Signature(message, signature, expectedAddress);
1778
2065
  default:
1779
2066
  throw new Error(`Unsupported chain type: ${chainType}`);
@@ -1811,7 +2098,7 @@ var SUPPORTED_WALLETS = {
1811
2098
  ["metamask" /* METAMASK */]: {
1812
2099
  type: "metamask" /* METAMASK */,
1813
2100
  name: "MetaMask",
1814
- chainType: "evm" /* EVM */,
2101
+ chainType: ChainType.EVM,
1815
2102
  icon: "https://upload.wikimedia.org/wikipedia/commons/3/36/MetaMask_Fox.svg",
1816
2103
  downloadUrl: "https://metamask.io/download/",
1817
2104
  description: "The most popular Ethereum wallet"
@@ -1819,7 +2106,7 @@ var SUPPORTED_WALLETS = {
1819
2106
  ["walletconnect" /* WALLETCONNECT */]: {
1820
2107
  type: "walletconnect" /* WALLETCONNECT */,
1821
2108
  name: "WalletConnect",
1822
- chainType: "evm" /* EVM */,
2109
+ chainType: ChainType.EVM,
1823
2110
  icon: "https://avatars.githubusercontent.com/u/37784886",
1824
2111
  downloadUrl: "https://walletconnect.com/",
1825
2112
  description: "Connect to 170+ wallets"
@@ -1827,7 +2114,7 @@ var SUPPORTED_WALLETS = {
1827
2114
  ["coinbase-wallet" /* COINBASE_WALLET */]: {
1828
2115
  type: "coinbase-wallet" /* COINBASE_WALLET */,
1829
2116
  name: "Coinbase Wallet",
1830
- chainType: "evm" /* EVM */,
2117
+ chainType: ChainType.EVM,
1831
2118
  icon: "https://www.coinbase.com/img/favicon/favicon-96x96.png",
1832
2119
  downloadUrl: "https://www.coinbase.com/wallet",
1833
2120
  description: "Coinbase self-custody wallet"
@@ -1835,7 +2122,7 @@ var SUPPORTED_WALLETS = {
1835
2122
  ["tronlink" /* TRONLINK */]: {
1836
2123
  type: "tronlink" /* TRONLINK */,
1837
2124
  name: "TronLink",
1838
- chainType: "tron" /* TRON */,
2125
+ chainType: ChainType.TRON,
1839
2126
  icon: "https://www.tronlink.org/static/logoIcon.svg",
1840
2127
  downloadUrl: "https://www.tronlink.org/",
1841
2128
  description: "The official Tron wallet"
@@ -1843,14 +2130,14 @@ var SUPPORTED_WALLETS = {
1843
2130
  ["walletconnect-tron" /* WALLETCONNECT_TRON */]: {
1844
2131
  type: "walletconnect-tron" /* WALLETCONNECT_TRON */,
1845
2132
  name: "WalletConnect (Tron)",
1846
- chainType: "tron" /* TRON */,
2133
+ chainType: ChainType.TRON,
1847
2134
  downloadUrl: "https://walletconnect.com/",
1848
2135
  description: "WalletConnect for Tron"
1849
2136
  },
1850
2137
  ["private-key" /* PRIVATE_KEY */]: {
1851
2138
  type: "private-key" /* PRIVATE_KEY */,
1852
2139
  name: "Private Key",
1853
- chainType: "evm" /* EVM */,
2140
+ chainType: ChainType.EVM,
1854
2141
  // 可以用于任何链
1855
2142
  description: "Import wallet using private key (for development)"
1856
2143
  }
@@ -1860,12 +2147,12 @@ function getWalletMetadata(type) {
1860
2147
  }
1861
2148
  function getEVMWallets() {
1862
2149
  return Object.values(SUPPORTED_WALLETS).filter(
1863
- (wallet) => wallet.chainType === "evm" /* EVM */
2150
+ (wallet) => wallet.chainType === ChainType.EVM
1864
2151
  );
1865
2152
  }
1866
2153
  function getTronWallets() {
1867
2154
  return Object.values(SUPPORTED_WALLETS).filter(
1868
- (wallet) => wallet.chainType === "tron" /* TRON */
2155
+ (wallet) => wallet.chainType === ChainType.TRON
1869
2156
  );
1870
2157
  }
1871
2158
 
@@ -1892,7 +2179,7 @@ var WalletDetector = class {
1892
2179
  if (!metadata) {
1893
2180
  return {
1894
2181
  walletType,
1895
- chainType: "evm" /* EVM */,
2182
+ chainType: ChainType.EVM,
1896
2183
  // 默认
1897
2184
  isAvailable: false,
1898
2185
  detected: false
@@ -2000,9 +2287,9 @@ function shortenTronAddress(address, chars = 4) {
2000
2287
  // src/utils/validation.ts
2001
2288
  function validateAddress(address, chainType) {
2002
2289
  switch (chainType) {
2003
- case "evm" /* EVM */:
2290
+ case ChainType.EVM:
2004
2291
  return isValidEVMAddress(address);
2005
- case "tron" /* TRON */:
2292
+ case ChainType.TRON:
2006
2293
  return isValidTronAddress(address);
2007
2294
  default:
2008
2295
  return false;
@@ -2023,9 +2310,9 @@ function isValidSignature(signature) {
2023
2310
  }
2024
2311
  function isValidTransactionHash(txHash, chainType) {
2025
2312
  switch (chainType) {
2026
- case "evm" /* EVM */:
2313
+ case ChainType.EVM:
2027
2314
  return /^0x[0-9a-fA-F]{64}$/.test(txHash);
2028
- case "tron" /* TRON */:
2315
+ case ChainType.TRON:
2029
2316
  return /^[0-9a-fA-F]{64}$/.test(txHash);
2030
2317
  default:
2031
2318
  return false;