decane-connect-kit 0.0.1 → 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.cjs +471 -67
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -4
- package/dist/index.d.ts +31 -4
- package/dist/index.js +471 -67
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -32,8 +32,12 @@ function createRegistry(emitter) {
|
|
|
32
32
|
};
|
|
33
33
|
if (incoming.chain === "evm") {
|
|
34
34
|
account.evmProvider = incoming.provider;
|
|
35
|
-
} else {
|
|
35
|
+
} else if (incoming.chain === "solana") {
|
|
36
36
|
account.solanaProvider = incoming.provider;
|
|
37
|
+
} else if (incoming.chain === "tron") {
|
|
38
|
+
account.tronProvider = incoming.provider;
|
|
39
|
+
} else if (incoming.chain === "bitcoin") {
|
|
40
|
+
account.bitcoinProvider = incoming.provider;
|
|
37
41
|
}
|
|
38
42
|
return account;
|
|
39
43
|
}
|
|
@@ -44,12 +48,10 @@ function createRegistry(emitter) {
|
|
|
44
48
|
incoming.chain
|
|
45
49
|
].sort();
|
|
46
50
|
}
|
|
47
|
-
if (incoming.chain === "evm")
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if (incoming.chain === "
|
|
51
|
-
existing.solanaProvider = incoming.provider;
|
|
52
|
-
}
|
|
51
|
+
if (incoming.chain === "evm") existing.evmProvider = incoming.provider;
|
|
52
|
+
if (incoming.chain === "solana") existing.solanaProvider = incoming.provider;
|
|
53
|
+
if (incoming.chain === "tron") existing.tronProvider = incoming.provider;
|
|
54
|
+
if (incoming.chain === "bitcoin") existing.bitcoinProvider = incoming.provider;
|
|
53
55
|
if (!existing.icon && incoming.icon) existing.icon = incoming.icon;
|
|
54
56
|
}
|
|
55
57
|
function registerOrMerge(incoming) {
|
|
@@ -96,9 +98,9 @@ function createRegistry(emitter) {
|
|
|
96
98
|
all: () => [...wallets],
|
|
97
99
|
evm: () => wallets.filter((w) => w.chainSupport.includes("evm")),
|
|
98
100
|
solana: () => wallets.filter((w) => w.chainSupport.includes("solana")),
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
),
|
|
101
|
+
tron: () => wallets.filter((w) => w.chainSupport.includes("tron")),
|
|
102
|
+
bitcoin: () => wallets.filter((w) => w.chainSupport.includes("bitcoin")),
|
|
103
|
+
multiChain: () => wallets.filter((w) => w.chainSupport.length >= 2),
|
|
102
104
|
byId: (id) => wallets.find((w) => w.id === id)
|
|
103
105
|
}
|
|
104
106
|
};
|
|
@@ -681,11 +683,37 @@ var BUILT_IN_CHAINS = [
|
|
|
681
683
|
name: "Solana Devnet",
|
|
682
684
|
nativeCurrency: SOL,
|
|
683
685
|
blockExplorerUrl: "https://solscan.io/?cluster=devnet"
|
|
686
|
+
},
|
|
687
|
+
// ── Tron ─────────────────────────────────────────────────────────────────────
|
|
688
|
+
{
|
|
689
|
+
id: "tron:mainnet",
|
|
690
|
+
type: "tron",
|
|
691
|
+
name: "Tron",
|
|
692
|
+
nativeCurrency: { name: "Tronix", symbol: "TRX", decimals: 6 },
|
|
693
|
+
blockExplorerUrl: "https://tronscan.org"
|
|
694
|
+
},
|
|
695
|
+
{
|
|
696
|
+
id: "tron:shasta",
|
|
697
|
+
type: "tron",
|
|
698
|
+
name: "Tron Shasta Testnet",
|
|
699
|
+
nativeCurrency: { name: "Tronix", symbol: "TRX", decimals: 6 },
|
|
700
|
+
blockExplorerUrl: "https://shasta.tronscan.org",
|
|
701
|
+
isCustom: true
|
|
702
|
+
},
|
|
703
|
+
// ── Bitcoin ───────────────────────────────────────────────────────────────────
|
|
704
|
+
{
|
|
705
|
+
id: "bip122:mainnet",
|
|
706
|
+
type: "bitcoin",
|
|
707
|
+
name: "Bitcoin",
|
|
708
|
+
nativeCurrency: { name: "Bitcoin", symbol: "BTC", decimals: 8 },
|
|
709
|
+
blockExplorerUrl: "https://blockstream.info"
|
|
684
710
|
}
|
|
685
711
|
];
|
|
686
712
|
function getChainType(caip2Id) {
|
|
687
713
|
if (caip2Id.startsWith("eip155:")) return "evm";
|
|
688
714
|
if (caip2Id.startsWith("solana:")) return "solana";
|
|
715
|
+
if (caip2Id.startsWith("tron:")) return "tron";
|
|
716
|
+
if (caip2Id.startsWith("bip122:")) return "bitcoin";
|
|
689
717
|
throw new Error(`Cannot determine chain type from: ${caip2Id}`);
|
|
690
718
|
}
|
|
691
719
|
function toCAIP10(chainId, address) {
|
|
@@ -701,6 +729,14 @@ var SOLANA_METHODS = /* @__PURE__ */ new Set([
|
|
|
701
729
|
"wallet_signMessage"
|
|
702
730
|
// wallet_signTypedData is EVM-only — never included here
|
|
703
731
|
]);
|
|
732
|
+
var TRON_METHODS = /* @__PURE__ */ new Set([
|
|
733
|
+
"wallet_sendTransaction",
|
|
734
|
+
"wallet_signMessage"
|
|
735
|
+
]);
|
|
736
|
+
var BITCOIN_METHODS = /* @__PURE__ */ new Set([
|
|
737
|
+
"wallet_sendTransaction",
|
|
738
|
+
"wallet_signMessage"
|
|
739
|
+
]);
|
|
704
740
|
var CHAINS = {
|
|
705
741
|
// Tier-1
|
|
706
742
|
ETHEREUM: "eip155:1",
|
|
@@ -766,13 +802,17 @@ var CHAINS = {
|
|
|
766
802
|
LOCALHOST: "eip155:31337",
|
|
767
803
|
// Solana
|
|
768
804
|
SOLANA: "solana:mainnet",
|
|
769
|
-
SOLANA_DEVNET: "solana:devnet"
|
|
805
|
+
SOLANA_DEVNET: "solana:devnet",
|
|
806
|
+
// Tron
|
|
807
|
+
TRON: "tron:mainnet",
|
|
808
|
+
// Bitcoin
|
|
809
|
+
BITCOIN: "bip122:mainnet"
|
|
770
810
|
};
|
|
771
811
|
function validateCustomChain(chain) {
|
|
772
812
|
if (!chain || typeof chain !== "object") return false;
|
|
773
813
|
const c = chain;
|
|
774
814
|
if (typeof c.id !== "string" || !c.id) return false;
|
|
775
|
-
if (c.type !== "evm" && c.type !== "solana") return false;
|
|
815
|
+
if (c.type !== "evm" && c.type !== "solana" && c.type !== "tron" && c.type !== "bitcoin") return false;
|
|
776
816
|
if (typeof c.name !== "string" || !c.name) return false;
|
|
777
817
|
if (!c.nativeCurrency || typeof c.nativeCurrency !== "object") return false;
|
|
778
818
|
if (c.type === "evm" && (typeof c.chainId !== "number" || !c.id.startsWith("eip155:")))
|
|
@@ -991,7 +1031,12 @@ async function walletStandardRequest(wallet, method, payload, account) {
|
|
|
991
1031
|
);
|
|
992
1032
|
}
|
|
993
1033
|
}
|
|
1034
|
+
function isSolanaAccount(a) {
|
|
1035
|
+
return !a.chains?.length || a.chains.some((c) => c.startsWith("solana:"));
|
|
1036
|
+
}
|
|
994
1037
|
async function getSolanaAddress(wallet) {
|
|
1038
|
+
const pre = wallet.accounts.find(isSolanaAccount);
|
|
1039
|
+
if (pre) return base58.encode(pre.publicKey);
|
|
995
1040
|
const connectFeature = wallet.features["standard:connect"];
|
|
996
1041
|
if (!connectFeature) {
|
|
997
1042
|
throw new DecaneError(
|
|
@@ -1000,13 +1045,157 @@ async function getSolanaAddress(wallet) {
|
|
|
1000
1045
|
);
|
|
1001
1046
|
}
|
|
1002
1047
|
const { accounts } = await connectFeature.connect();
|
|
1003
|
-
|
|
1048
|
+
const solanaAccount = accounts.find(isSolanaAccount);
|
|
1049
|
+
if (!solanaAccount) {
|
|
1004
1050
|
throw new DecaneError(
|
|
1005
1051
|
4001 /* USER_REJECTED */,
|
|
1006
1052
|
"No Solana accounts returned"
|
|
1007
1053
|
);
|
|
1008
1054
|
}
|
|
1009
|
-
return base58.encode(
|
|
1055
|
+
return base58.encode(solanaAccount.publicKey);
|
|
1056
|
+
}
|
|
1057
|
+
|
|
1058
|
+
// src/tron/adapter.ts
|
|
1059
|
+
function getTronWeb() {
|
|
1060
|
+
if (typeof window === "undefined") return void 0;
|
|
1061
|
+
const win = window;
|
|
1062
|
+
return win.tronLink?.tronWeb ?? win.tronWeb;
|
|
1063
|
+
}
|
|
1064
|
+
async function getTronAddress(provider) {
|
|
1065
|
+
const addr = getTronWeb()?.defaultAddress?.base58;
|
|
1066
|
+
if (addr) return addr;
|
|
1067
|
+
try {
|
|
1068
|
+
const result = await provider.request({ method: "tron_requestAccounts" });
|
|
1069
|
+
const accounts = result;
|
|
1070
|
+
if (accounts?.[0]) return accounts[0];
|
|
1071
|
+
} catch {
|
|
1072
|
+
}
|
|
1073
|
+
const result2 = await provider.request({ method: "tron_accounts" }).catch(() => null);
|
|
1074
|
+
const accounts2 = result2;
|
|
1075
|
+
if (accounts2?.[0]) return accounts2[0];
|
|
1076
|
+
throw new DecaneError(4001 /* USER_REJECTED */, "No Tron accounts returned");
|
|
1077
|
+
}
|
|
1078
|
+
async function tronRequest(provider, method, payload, account) {
|
|
1079
|
+
switch (method) {
|
|
1080
|
+
case "wallet_signMessage":
|
|
1081
|
+
return provider.request({
|
|
1082
|
+
method: "tron_signMessage",
|
|
1083
|
+
params: { message: payload }
|
|
1084
|
+
});
|
|
1085
|
+
case "wallet_sendTransaction": {
|
|
1086
|
+
const tronWeb = getTronWeb();
|
|
1087
|
+
const p = payload;
|
|
1088
|
+
const toAddress = p.to;
|
|
1089
|
+
const sunAmount = typeof p.value === "string" ? parseInt(p.value, 10) : p.value ?? 0;
|
|
1090
|
+
let unsignedTx;
|
|
1091
|
+
if (tronWeb?.transactionBuilder?.sendTrx) {
|
|
1092
|
+
if (p.data && p.data !== "0x") {
|
|
1093
|
+
const res = await tronWeb.transactionBuilder.triggerSmartContract(
|
|
1094
|
+
toAddress,
|
|
1095
|
+
"transfer(address,uint256)",
|
|
1096
|
+
{ callValue: 0, feeLimit: 1e8 },
|
|
1097
|
+
[],
|
|
1098
|
+
account
|
|
1099
|
+
);
|
|
1100
|
+
unsignedTx = res.transaction;
|
|
1101
|
+
} else {
|
|
1102
|
+
unsignedTx = await tronWeb.transactionBuilder.sendTrx(toAddress, sunAmount, account);
|
|
1103
|
+
}
|
|
1104
|
+
} else {
|
|
1105
|
+
const host = tronWeb?.fullNode?.host ?? "https://api.trongrid.io";
|
|
1106
|
+
const endpoint = p.data && p.data !== "0x" ? `${host}/wallet/triggersmartcontract` : `${host}/wallet/createtransaction`;
|
|
1107
|
+
const body = p.data && p.data !== "0x" ? {
|
|
1108
|
+
owner_address: account,
|
|
1109
|
+
contract_address: toAddress,
|
|
1110
|
+
function_selector: "transfer(address,uint256)",
|
|
1111
|
+
fee_limit: 1e8,
|
|
1112
|
+
call_value: 0,
|
|
1113
|
+
visible: true
|
|
1114
|
+
} : {
|
|
1115
|
+
owner_address: account,
|
|
1116
|
+
to_address: toAddress,
|
|
1117
|
+
amount: sunAmount,
|
|
1118
|
+
visible: true
|
|
1119
|
+
};
|
|
1120
|
+
const res = await fetch(endpoint, {
|
|
1121
|
+
method: "POST",
|
|
1122
|
+
headers: { "Content-Type": "application/json" },
|
|
1123
|
+
body: JSON.stringify(body)
|
|
1124
|
+
});
|
|
1125
|
+
if (!res.ok) {
|
|
1126
|
+
throw new DecaneError(
|
|
1127
|
+
5022 /* PROVIDER_ERROR */,
|
|
1128
|
+
`Failed to build Tron transaction: ${res.statusText}`
|
|
1129
|
+
);
|
|
1130
|
+
}
|
|
1131
|
+
const json = await res.json();
|
|
1132
|
+
unsignedTx = json.transaction ?? json;
|
|
1133
|
+
}
|
|
1134
|
+
let signedTx;
|
|
1135
|
+
if (tronWeb?.trx?.sign) {
|
|
1136
|
+
signedTx = await tronWeb.trx.sign(unsignedTx);
|
|
1137
|
+
} else {
|
|
1138
|
+
signedTx = await provider.request({
|
|
1139
|
+
method: "tron_signTransaction",
|
|
1140
|
+
params: unsignedTx
|
|
1141
|
+
});
|
|
1142
|
+
}
|
|
1143
|
+
let txid;
|
|
1144
|
+
if (tronWeb?.trx?.sendRawTransaction) {
|
|
1145
|
+
const result = await tronWeb.trx.sendRawTransaction(signedTx);
|
|
1146
|
+
txid = result?.txid;
|
|
1147
|
+
} else {
|
|
1148
|
+
const result = await provider.request({
|
|
1149
|
+
method: "tron_sendRawTransaction",
|
|
1150
|
+
params: signedTx
|
|
1151
|
+
});
|
|
1152
|
+
txid = result?.txid;
|
|
1153
|
+
}
|
|
1154
|
+
if (!txid) {
|
|
1155
|
+
throw new DecaneError(5022 /* PROVIDER_ERROR */, "Tron transaction broadcast failed");
|
|
1156
|
+
}
|
|
1157
|
+
return txid;
|
|
1158
|
+
}
|
|
1159
|
+
default:
|
|
1160
|
+
throw new DecaneError(
|
|
1161
|
+
5030 /* METHOD_NOT_SUPPORTED */,
|
|
1162
|
+
`Tron adapter: unsupported method ${method}`
|
|
1163
|
+
);
|
|
1164
|
+
}
|
|
1165
|
+
}
|
|
1166
|
+
|
|
1167
|
+
// src/bitcoin/adapter.ts
|
|
1168
|
+
async function getBitcoinAddress(provider) {
|
|
1169
|
+
const result = await provider.requestAccounts();
|
|
1170
|
+
if (!result || result.length === 0) {
|
|
1171
|
+
throw new DecaneError(4001 /* USER_REJECTED */, "No Bitcoin accounts returned");
|
|
1172
|
+
}
|
|
1173
|
+
const first = result[0];
|
|
1174
|
+
return typeof first === "string" ? first : first.address;
|
|
1175
|
+
}
|
|
1176
|
+
async function bitcoinRequest(provider, method, payload, account) {
|
|
1177
|
+
switch (method) {
|
|
1178
|
+
case "wallet_signMessage":
|
|
1179
|
+
return provider.signMessage(payload);
|
|
1180
|
+
case "wallet_sendTransaction": {
|
|
1181
|
+
const { to, value } = payload;
|
|
1182
|
+
if (provider.sendBitcoin) {
|
|
1183
|
+
return provider.sendBitcoin(to, value);
|
|
1184
|
+
}
|
|
1185
|
+
if (provider.send) {
|
|
1186
|
+
return provider.send({ to, value, from: account });
|
|
1187
|
+
}
|
|
1188
|
+
throw new DecaneError(
|
|
1189
|
+
5030 /* METHOD_NOT_SUPPORTED */,
|
|
1190
|
+
"Bitcoin wallet does not support sendBitcoin"
|
|
1191
|
+
);
|
|
1192
|
+
}
|
|
1193
|
+
default:
|
|
1194
|
+
throw new DecaneError(
|
|
1195
|
+
5030 /* METHOD_NOT_SUPPORTED */,
|
|
1196
|
+
`Bitcoin adapter: unsupported method ${method}`
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
1010
1199
|
}
|
|
1011
1200
|
|
|
1012
1201
|
// src/core/router.ts
|
|
@@ -1057,20 +1246,23 @@ function createRouter(opts) {
|
|
|
1057
1246
|
const chainType = getChainType(chainId);
|
|
1058
1247
|
if (chainType === "evm" && !connectedWallet.evmProvider) continue;
|
|
1059
1248
|
if (chainType === "solana" && !connectedWallet.solanaProvider) continue;
|
|
1249
|
+
if (chainType === "tron" && !connectedWallet.tronProvider) continue;
|
|
1250
|
+
if (chainType === "bitcoin" && !connectedWallet.bitcoinProvider) continue;
|
|
1060
1251
|
let address;
|
|
1061
1252
|
if (chainType === "evm") {
|
|
1062
1253
|
address = await getEvmAddress(connectedWallet.evmProvider);
|
|
1063
1254
|
if (chain.isCustom) {
|
|
1064
|
-
await addEthereumChain(
|
|
1065
|
-
connectedWallet.evmProvider,
|
|
1066
|
-
chain
|
|
1067
|
-
).catch(() => {
|
|
1255
|
+
await addEthereumChain(connectedWallet.evmProvider, chain).catch(() => {
|
|
1068
1256
|
});
|
|
1069
1257
|
}
|
|
1070
|
-
} else {
|
|
1258
|
+
} else if (chainType === "solana") {
|
|
1071
1259
|
address = await getSolanaAddress(connectedWallet.solanaProvider);
|
|
1260
|
+
} else if (chainType === "tron") {
|
|
1261
|
+
address = await getTronAddress(connectedWallet.tronProvider);
|
|
1262
|
+
} else {
|
|
1263
|
+
address = await getBitcoinAddress(connectedWallet.bitcoinProvider);
|
|
1072
1264
|
}
|
|
1073
|
-
const methodSet = chainType === "evm" ? EVM_METHODS : SOLANA_METHODS;
|
|
1265
|
+
const methodSet = chainType === "evm" ? EVM_METHODS : chainType === "solana" ? SOLANA_METHODS : chainType === "tron" ? TRON_METHODS : BITCOIN_METHODS;
|
|
1074
1266
|
const grantedMethods = (scope?.methods ?? []).filter(
|
|
1075
1267
|
(m) => methodSet.has(m)
|
|
1076
1268
|
);
|
|
@@ -1149,19 +1341,13 @@ function createRouter(opts) {
|
|
|
1149
1341
|
);
|
|
1150
1342
|
}
|
|
1151
1343
|
if (chainType === "evm") {
|
|
1152
|
-
return eip1193Request(
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
);
|
|
1344
|
+
return eip1193Request(wallet.evmProvider, method, payload, account);
|
|
1345
|
+
} else if (chainType === "solana") {
|
|
1346
|
+
return walletStandardRequest(wallet.solanaProvider, method, payload, account);
|
|
1347
|
+
} else if (chainType === "tron") {
|
|
1348
|
+
return tronRequest(wallet.tronProvider, method, payload, account);
|
|
1158
1349
|
} else {
|
|
1159
|
-
return
|
|
1160
|
-
wallet.solanaProvider,
|
|
1161
|
-
method,
|
|
1162
|
-
payload,
|
|
1163
|
-
account
|
|
1164
|
-
);
|
|
1350
|
+
return bitcoinRequest(wallet.bitcoinProvider, method, payload, account);
|
|
1165
1351
|
}
|
|
1166
1352
|
}
|
|
1167
1353
|
return { request };
|
|
@@ -1216,6 +1402,12 @@ function createProvider(opts) {
|
|
|
1216
1402
|
get multiChainWallets() {
|
|
1217
1403
|
return registry.get.multiChain();
|
|
1218
1404
|
},
|
|
1405
|
+
get tronWallets() {
|
|
1406
|
+
return registry.get.tron();
|
|
1407
|
+
},
|
|
1408
|
+
get bitcoinWallets() {
|
|
1409
|
+
return registry.get.bitcoin();
|
|
1410
|
+
},
|
|
1219
1411
|
// ── Connection ──────────────────────────────────────────────────────────
|
|
1220
1412
|
async connect(wallet, preferredChain) {
|
|
1221
1413
|
if (session.get()) {
|
|
@@ -1224,13 +1416,19 @@ function createProvider(opts) {
|
|
|
1224
1416
|
}
|
|
1225
1417
|
_connectedWallet = wallet;
|
|
1226
1418
|
const support = wallet.chainSupport;
|
|
1227
|
-
|
|
1419
|
+
const hasEvm = support.includes("evm") && preferredChain !== "solana" && preferredChain !== "tron" && preferredChain !== "bitcoin";
|
|
1420
|
+
const hasSol = support.includes("solana") && preferredChain !== "evm" && preferredChain !== "tron" && preferredChain !== "bitcoin";
|
|
1421
|
+
const hasTron = support.includes("tron") && preferredChain !== "evm" && preferredChain !== "solana" && preferredChain !== "bitcoin";
|
|
1422
|
+
const hasBitcoin = support.includes("bitcoin") && preferredChain !== "evm" && preferredChain !== "solana" && preferredChain !== "tron";
|
|
1423
|
+
if (hasEvm) {
|
|
1228
1424
|
_activeChain = config.defaultChain?.startsWith("eip155:") ? config.defaultChain : "eip155:1";
|
|
1229
|
-
} else {
|
|
1425
|
+
} else if (hasSol) {
|
|
1230
1426
|
_activeChain = "solana:mainnet";
|
|
1427
|
+
} else if (hasTron) {
|
|
1428
|
+
_activeChain = "tron:mainnet";
|
|
1429
|
+
} else if (hasBitcoin) {
|
|
1430
|
+
_activeChain = "bip122:mainnet";
|
|
1231
1431
|
}
|
|
1232
|
-
const hasEvm = support.includes("evm") && preferredChain !== "solana";
|
|
1233
|
-
const hasSol = support.includes("solana") && preferredChain !== "evm";
|
|
1234
1432
|
const required = {};
|
|
1235
1433
|
const optional = {};
|
|
1236
1434
|
if (hasEvm) {
|
|
@@ -1254,6 +1452,34 @@ function createProvider(opts) {
|
|
|
1254
1452
|
_activeChain = solChain;
|
|
1255
1453
|
}
|
|
1256
1454
|
}
|
|
1455
|
+
if (hasTron) {
|
|
1456
|
+
const tronChain = "tron:mainnet";
|
|
1457
|
+
const scope = {
|
|
1458
|
+
methods: ["wallet_sendTransaction", "wallet_signMessage"],
|
|
1459
|
+
accounts: [],
|
|
1460
|
+
events: []
|
|
1461
|
+
};
|
|
1462
|
+
if (hasEvm || hasSol) {
|
|
1463
|
+
optional[tronChain] = scope;
|
|
1464
|
+
} else {
|
|
1465
|
+
required[tronChain] = scope;
|
|
1466
|
+
_activeChain = tronChain;
|
|
1467
|
+
}
|
|
1468
|
+
}
|
|
1469
|
+
if (hasBitcoin) {
|
|
1470
|
+
const btcChain = "bip122:mainnet";
|
|
1471
|
+
const scope = {
|
|
1472
|
+
methods: ["wallet_sendTransaction", "wallet_signMessage"],
|
|
1473
|
+
accounts: [],
|
|
1474
|
+
events: []
|
|
1475
|
+
};
|
|
1476
|
+
if (hasEvm || hasSol || hasTron) {
|
|
1477
|
+
optional[btcChain] = scope;
|
|
1478
|
+
} else {
|
|
1479
|
+
required[btcChain] = scope;
|
|
1480
|
+
_activeChain = btcChain;
|
|
1481
|
+
}
|
|
1482
|
+
}
|
|
1257
1483
|
await router.request({
|
|
1258
1484
|
method: "wallet_requestPermissions",
|
|
1259
1485
|
params: [{ requiredScopes: required, optionalScopes: optional }, wallet.id]
|
|
@@ -1321,6 +1547,58 @@ function createProvider(opts) {
|
|
|
1321
1547
|
return provider;
|
|
1322
1548
|
}
|
|
1323
1549
|
|
|
1550
|
+
// src/evm/bitcoinSnap.ts
|
|
1551
|
+
var BITCOIN_SNAP_IDS = [
|
|
1552
|
+
"npm:@metamask/bitcoin-snap",
|
|
1553
|
+
"npm:@consensys/btc-snap"
|
|
1554
|
+
];
|
|
1555
|
+
async function detectBitcoinSnap(provider) {
|
|
1556
|
+
try {
|
|
1557
|
+
const snaps = await provider.request({ method: "wallet_getSnaps" });
|
|
1558
|
+
if (!snaps) return null;
|
|
1559
|
+
for (const id of BITCOIN_SNAP_IDS) {
|
|
1560
|
+
const snap = snaps[id];
|
|
1561
|
+
if (snap && snap.blocked !== true) return id;
|
|
1562
|
+
}
|
|
1563
|
+
return null;
|
|
1564
|
+
} catch {
|
|
1565
|
+
return null;
|
|
1566
|
+
}
|
|
1567
|
+
}
|
|
1568
|
+
function makeBitcoinSnapProvider(snapId, evmProvider) {
|
|
1569
|
+
function invoke(method, params) {
|
|
1570
|
+
return evmProvider.request({
|
|
1571
|
+
method: "wallet_invokeSnap",
|
|
1572
|
+
params: [{ snapId, request: { method, params } }]
|
|
1573
|
+
});
|
|
1574
|
+
}
|
|
1575
|
+
return {
|
|
1576
|
+
async requestAccounts() {
|
|
1577
|
+
const result = await invoke("btc_getAddress").catch(() => invoke("btc_getPublicKey"));
|
|
1578
|
+
if (typeof result === "string") return [result];
|
|
1579
|
+
if (Array.isArray(result)) return result;
|
|
1580
|
+
return [];
|
|
1581
|
+
},
|
|
1582
|
+
async signMessage(message) {
|
|
1583
|
+
return invoke("btc_signMessage", [message]);
|
|
1584
|
+
},
|
|
1585
|
+
async sendBitcoin(to, value) {
|
|
1586
|
+
return invoke("btc_sendBitcoin", [{ to, satoshis: value }]);
|
|
1587
|
+
}
|
|
1588
|
+
};
|
|
1589
|
+
}
|
|
1590
|
+
async function tryRegisterBitcoinSnap(registry, name, icon, rdns, evmProvider) {
|
|
1591
|
+
const snapId = await detectBitcoinSnap(evmProvider);
|
|
1592
|
+
if (!snapId) return;
|
|
1593
|
+
registry.registerOrMerge({
|
|
1594
|
+
chain: "bitcoin",
|
|
1595
|
+
name,
|
|
1596
|
+
icon,
|
|
1597
|
+
rdns,
|
|
1598
|
+
provider: makeBitcoinSnapProvider(snapId, evmProvider)
|
|
1599
|
+
});
|
|
1600
|
+
}
|
|
1601
|
+
|
|
1324
1602
|
// src/evm/discovery.ts
|
|
1325
1603
|
function startEvmDiscovery(registry) {
|
|
1326
1604
|
if (typeof window === "undefined") return;
|
|
@@ -1340,6 +1618,14 @@ function startEvmDiscovery(registry) {
|
|
|
1340
1618
|
uuid: info.uuid,
|
|
1341
1619
|
provider
|
|
1342
1620
|
});
|
|
1621
|
+
tryRegisterBitcoinSnap(
|
|
1622
|
+
registry,
|
|
1623
|
+
info.name,
|
|
1624
|
+
info.icon,
|
|
1625
|
+
info.rdns,
|
|
1626
|
+
provider
|
|
1627
|
+
).catch(() => {
|
|
1628
|
+
});
|
|
1343
1629
|
}
|
|
1344
1630
|
);
|
|
1345
1631
|
window.dispatchEvent(new CustomEvent("eip6963:requestProvider"));
|
|
@@ -1380,6 +1666,53 @@ function startSolanaDiscovery(registry) {
|
|
|
1380
1666
|
);
|
|
1381
1667
|
}
|
|
1382
1668
|
|
|
1669
|
+
// src/tron/discovery.ts
|
|
1670
|
+
var TRONLINK_RDNS = "link.tron.tronlink";
|
|
1671
|
+
var TRONLINK_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNGRjAwMTMiLz48cG9seWdvbiBwb2ludHM9IjEyLDkgMjMsMTYgMTIsMjMiIGZpbGw9IndoaXRlIi8+PC9zdmc+";
|
|
1672
|
+
function startTronDiscovery(registry) {
|
|
1673
|
+
let registered = false;
|
|
1674
|
+
function tryRegister() {
|
|
1675
|
+
if (registered || !window.tronLink) return;
|
|
1676
|
+
registered = true;
|
|
1677
|
+
registry.registerOrMerge({
|
|
1678
|
+
chain: "tron",
|
|
1679
|
+
name: "TronLink",
|
|
1680
|
+
icon: TRONLINK_ICON,
|
|
1681
|
+
rdns: TRONLINK_RDNS,
|
|
1682
|
+
provider: window.tronLink
|
|
1683
|
+
});
|
|
1684
|
+
}
|
|
1685
|
+
tryRegister();
|
|
1686
|
+
window.addEventListener("tronLink#initialized", tryRegister, { once: true });
|
|
1687
|
+
const start = Date.now();
|
|
1688
|
+
const poll = setInterval(() => {
|
|
1689
|
+
tryRegister();
|
|
1690
|
+
if (registered || Date.now() - start > 3e3) clearInterval(poll);
|
|
1691
|
+
}, 200);
|
|
1692
|
+
}
|
|
1693
|
+
|
|
1694
|
+
// src/bitcoin/discovery.ts
|
|
1695
|
+
var BTC_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiI+PGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNGNzkzMUEiLz48dGV4dCB4PSIxNi41IiB5PSIyMiIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZm9udC1zaXplPSIxNiIgZm9udC13ZWlnaHQ9IjcwMCIgZmlsbD0id2hpdGUiIGZvbnQtZmFtaWx5PSJBcmlhbCxzeXN0ZW0tdWkiPuKmojwvdGV4dD48L3N2Zz4=";
|
|
1696
|
+
function startBitcoinDiscovery(registry) {
|
|
1697
|
+
setTimeout(() => {
|
|
1698
|
+
const candidates = [
|
|
1699
|
+
{ name: "Unisat", rdns: "io.unisat.wallet", provider: window.unisat },
|
|
1700
|
+
// OKX shares rdns with its EVM provider — merges into the EVM entry automatically
|
|
1701
|
+
{ name: "OKX Wallet", rdns: "com.okex.okxwallet", provider: window.okxwallet?.bitcoin }
|
|
1702
|
+
];
|
|
1703
|
+
for (const { name, rdns, provider } of candidates) {
|
|
1704
|
+
if (!provider) continue;
|
|
1705
|
+
registry.registerOrMerge({
|
|
1706
|
+
chain: "bitcoin",
|
|
1707
|
+
name,
|
|
1708
|
+
icon: BTC_ICON,
|
|
1709
|
+
rdns,
|
|
1710
|
+
provider
|
|
1711
|
+
});
|
|
1712
|
+
}
|
|
1713
|
+
}, 150);
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1383
1716
|
// src/factory.ts
|
|
1384
1717
|
function createDecane(config = {}) {
|
|
1385
1718
|
const emitter = createEmitter();
|
|
@@ -1393,6 +1726,8 @@ function createDecane(config = {}) {
|
|
|
1393
1726
|
const router = createRouter({ registry, session, chainStore });
|
|
1394
1727
|
startEvmDiscovery(registry);
|
|
1395
1728
|
startSolanaDiscovery(registry);
|
|
1729
|
+
startTronDiscovery(registry);
|
|
1730
|
+
startBitcoinDiscovery(registry);
|
|
1396
1731
|
return createProvider({ config, registry, session, chainStore, router, emitter });
|
|
1397
1732
|
}
|
|
1398
1733
|
|
|
@@ -1560,6 +1895,67 @@ function WalletIcon({ src, name, size = 36 }) {
|
|
|
1560
1895
|
initial
|
|
1561
1896
|
);
|
|
1562
1897
|
}
|
|
1898
|
+
function EthCircle({ size }) {
|
|
1899
|
+
const s = size;
|
|
1900
|
+
return /* @__PURE__ */ React.createElement("svg", { width: s, height: s, viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ React.createElement("circle", { cx: "8", cy: "8", r: "8", fill: "#627EEA" }), /* @__PURE__ */ React.createElement("polygon", { points: "8,2.5 11.5,8 8,9.8 4.5,8", fill: "white", fillOpacity: "0.9" }), /* @__PURE__ */ React.createElement("polygon", { points: "8,9.8 11.5,8 8,13.5", fill: "white", fillOpacity: "0.6" }), /* @__PURE__ */ React.createElement("polygon", { points: "8,9.8 4.5,8 8,13.5", fill: "white", fillOpacity: "0.8" }), /* @__PURE__ */ React.createElement("polygon", { points: "8,2.5 8,9.8 4.5,8", fill: "white", fillOpacity: "0.6" }));
|
|
1901
|
+
}
|
|
1902
|
+
function SolCircle({ size }) {
|
|
1903
|
+
const s = size;
|
|
1904
|
+
return /* @__PURE__ */ React.createElement("svg", { width: s, height: s, viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ React.createElement("circle", { cx: "8", cy: "8", r: "8", fill: "#9945FF" }), /* @__PURE__ */ React.createElement("rect", { x: "4", y: "4.5", width: "7", height: "1.5", rx: "0.75", fill: "white", fillOpacity: "0.95" }), /* @__PURE__ */ React.createElement("rect", { x: "4", y: "7.25", width: "7", height: "1.5", rx: "0.75", fill: "white", fillOpacity: "0.95" }), /* @__PURE__ */ React.createElement("rect", { x: "4", y: "10", width: "5.5", height: "1.5", rx: "0.75", fill: "white", fillOpacity: "0.95" }));
|
|
1905
|
+
}
|
|
1906
|
+
function TronCircle({ size }) {
|
|
1907
|
+
const s = size;
|
|
1908
|
+
return /* @__PURE__ */ React.createElement("svg", { width: s, height: s, viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ React.createElement("circle", { cx: "8", cy: "8", r: "8", fill: "#FF0013" }), /* @__PURE__ */ React.createElement("polygon", { points: "6,4.5 12,8 6,11.5", fill: "white", fillOpacity: "0.95" }));
|
|
1909
|
+
}
|
|
1910
|
+
function BitcoinCircle({ size }) {
|
|
1911
|
+
const s = size;
|
|
1912
|
+
return /* @__PURE__ */ React.createElement("svg", { width: s, height: s, viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ React.createElement("circle", { cx: "8", cy: "8", r: "8", fill: "#F7931A" }), /* @__PURE__ */ React.createElement(
|
|
1913
|
+
"text",
|
|
1914
|
+
{
|
|
1915
|
+
x: "8.3",
|
|
1916
|
+
y: "11.5",
|
|
1917
|
+
textAnchor: "middle",
|
|
1918
|
+
fontSize: "8",
|
|
1919
|
+
fontWeight: "700",
|
|
1920
|
+
fill: "white",
|
|
1921
|
+
fontFamily: "Arial, system-ui"
|
|
1922
|
+
},
|
|
1923
|
+
"\u20BF"
|
|
1924
|
+
));
|
|
1925
|
+
}
|
|
1926
|
+
function ChainCircleIcon({ chain, size }) {
|
|
1927
|
+
switch (chain) {
|
|
1928
|
+
case "evm":
|
|
1929
|
+
return /* @__PURE__ */ React.createElement(EthCircle, { size });
|
|
1930
|
+
case "solana":
|
|
1931
|
+
return /* @__PURE__ */ React.createElement(SolCircle, { size });
|
|
1932
|
+
case "tron":
|
|
1933
|
+
return /* @__PURE__ */ React.createElement(TronCircle, { size });
|
|
1934
|
+
case "bitcoin":
|
|
1935
|
+
return /* @__PURE__ */ React.createElement(BitcoinCircle, { size });
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
var CHAIN_ORDER = ["evm", "solana", "tron", "bitcoin"];
|
|
1939
|
+
function ChainIconStack({ support, size = 16 }) {
|
|
1940
|
+
const ordered = CHAIN_ORDER.filter((c) => support.includes(c));
|
|
1941
|
+
if (ordered.length === 0) return null;
|
|
1942
|
+
const overlap = Math.round(size * 0.35);
|
|
1943
|
+
return /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", flexShrink: 0 } }, ordered.map((chain, i) => /* @__PURE__ */ React.createElement(
|
|
1944
|
+
"div",
|
|
1945
|
+
{
|
|
1946
|
+
key: chain,
|
|
1947
|
+
style: {
|
|
1948
|
+
marginLeft: i === 0 ? 0 : `-${overlap}px`,
|
|
1949
|
+
zIndex: ordered.length - i,
|
|
1950
|
+
position: "relative",
|
|
1951
|
+
borderRadius: "50%",
|
|
1952
|
+
lineHeight: 0,
|
|
1953
|
+
boxShadow: i > 0 ? `0 0 0 1.5px var(--dc-bg, #fff)` : void 0
|
|
1954
|
+
}
|
|
1955
|
+
},
|
|
1956
|
+
/* @__PURE__ */ React.createElement(ChainCircleIcon, { chain, size })
|
|
1957
|
+
)));
|
|
1958
|
+
}
|
|
1563
1959
|
|
|
1564
1960
|
// src/ui/WalletSelector.tsx
|
|
1565
1961
|
var FONT_URL = "https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@400;500;600;700;800&display=swap";
|
|
@@ -1586,21 +1982,6 @@ function injectFont() {
|
|
|
1586
1982
|
link.href = FONT_URL;
|
|
1587
1983
|
document.head.appendChild(link);
|
|
1588
1984
|
}
|
|
1589
|
-
var badgeBase = {
|
|
1590
|
-
display: "inline-flex",
|
|
1591
|
-
alignItems: "center",
|
|
1592
|
-
padding: "3px 8px",
|
|
1593
|
-
borderRadius: 20,
|
|
1594
|
-
fontSize: 10,
|
|
1595
|
-
fontWeight: 700,
|
|
1596
|
-
letterSpacing: "0.04em",
|
|
1597
|
-
textTransform: "uppercase"
|
|
1598
|
-
};
|
|
1599
|
-
function ChainBadges({ chainSupport }) {
|
|
1600
|
-
const hasEvm = chainSupport.includes("evm");
|
|
1601
|
-
const hasSol = chainSupport.includes("solana");
|
|
1602
|
-
return /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 4 } }, hasEvm && /* @__PURE__ */ React2.createElement("span", { style: { ...badgeBase, background: "var(--dc-badge-evm)", color: "var(--dc-badge-evm-text)" } }, "EVM"), hasSol && /* @__PURE__ */ React2.createElement("span", { style: { ...badgeBase, background: "var(--dc-badge-sol)", color: "var(--dc-badge-sol-text)", border: "1px solid var(--dc-border)" } }, "SVM"));
|
|
1603
|
-
}
|
|
1604
1985
|
function WalletRow({ wallet, onClick }) {
|
|
1605
1986
|
const [hovered, setHovered] = useState(false);
|
|
1606
1987
|
const [focused, setFocused] = useState(false);
|
|
@@ -1630,7 +2011,7 @@ function WalletRow({ wallet, onClick }) {
|
|
|
1630
2011
|
},
|
|
1631
2012
|
/* @__PURE__ */ React2.createElement(WalletIcon, { src: wallet.icon || void 0, name: wallet.name, size: 38 }),
|
|
1632
2013
|
/* @__PURE__ */ React2.createElement("span", { style: { flex: 1, fontSize: 14, fontWeight: 600, color: "var(--dc-text)", letterSpacing: "-0.01em" } }, wallet.name),
|
|
1633
|
-
/* @__PURE__ */ React2.createElement(
|
|
2014
|
+
/* @__PURE__ */ React2.createElement(ChainIconStack, { support: wallet.chainSupport, size: 16 }),
|
|
1634
2015
|
/* @__PURE__ */ React2.createElement(
|
|
1635
2016
|
"svg",
|
|
1636
2017
|
{
|
|
@@ -1757,17 +2138,19 @@ function WalletSelector({
|
|
|
1757
2138
|
const cs = w.chainSupport;
|
|
1758
2139
|
if (networks === "evm") return cs.includes("evm");
|
|
1759
2140
|
if (networks === "solana") return cs.includes("solana");
|
|
2141
|
+
if (networks === "tron") return cs.includes("tron");
|
|
2142
|
+
if (networks === "bitcoin") return cs.includes("bitcoin");
|
|
1760
2143
|
return true;
|
|
1761
2144
|
});
|
|
1762
|
-
const baseWallets = filter === "evm" ? networkWallets.filter((w) => w.chainSupport.includes("evm")) : filter === "solana" ? networkWallets.filter((w) => w.chainSupport.includes("solana")) : networkWallets;
|
|
2145
|
+
const baseWallets = filter === "evm" ? networkWallets.filter((w) => w.chainSupport.includes("evm")) : filter === "solana" ? networkWallets.filter((w) => w.chainSupport.includes("solana")) : filter === "tron" ? networkWallets.filter((w) => w.chainSupport.includes("tron")) : filter === "bitcoin" ? networkWallets.filter((w) => w.chainSupport.includes("bitcoin")) : networkWallets;
|
|
1763
2146
|
const filtered = q ? baseWallets.filter((w) => w.name.toLowerCase().includes(q)) : baseWallets;
|
|
1764
2147
|
function handleWalletClick(wallet) {
|
|
1765
2148
|
const cs = wallet.chainSupport;
|
|
1766
|
-
const isMulti = cs.
|
|
2149
|
+
const isMulti = cs.length >= 2;
|
|
1767
2150
|
if (isMulti && networks === "all") {
|
|
1768
2151
|
setPendingWallet(wallet);
|
|
1769
2152
|
} else {
|
|
1770
|
-
const preference = networks === "evm" ? "evm" : networks === "solana" ? "solana" : void 0;
|
|
2153
|
+
const preference = networks === "evm" ? "evm" : networks === "solana" ? "solana" : networks === "tron" ? "tron" : networks === "bitcoin" ? "bitcoin" : void 0;
|
|
1771
2154
|
onConnect(wallet, preference);
|
|
1772
2155
|
onClose();
|
|
1773
2156
|
}
|
|
@@ -1902,28 +2285,44 @@ function WalletSelector({
|
|
|
1902
2285
|
},
|
|
1903
2286
|
/* @__PURE__ */ React2.createElement(WalletIcon, { src: pendingWallet.icon || void 0, name: pendingWallet.name, size: 36 }),
|
|
1904
2287
|
/* @__PURE__ */ React2.createElement("div", null, /* @__PURE__ */ React2.createElement("div", { style: { fontSize: 14, fontWeight: 700, color: "var(--dc-text)" } }, pendingWallet.name), /* @__PURE__ */ React2.createElement("div", { style: { fontSize: 11, color: "var(--dc-text-muted)", marginTop: 2 } }, "Multi-chain wallet detected"))
|
|
1905
|
-
), /* @__PURE__ */ React2.createElement("div", { style: { padding: "0 12px 20px", display: "flex", flexDirection: "column", gap: 8 } }, /* @__PURE__ */ React2.createElement(
|
|
2288
|
+
), /* @__PURE__ */ React2.createElement("div", { style: { padding: "0 12px 20px", display: "flex", flexDirection: "column", gap: 8 } }, pendingWallet.chainSupport.includes("evm") && /* @__PURE__ */ React2.createElement(
|
|
1906
2289
|
ChainOption,
|
|
1907
2290
|
{
|
|
1908
2291
|
label: "EVM networks",
|
|
1909
2292
|
description: "Connect your Ethereum-compatible address only",
|
|
1910
|
-
badges: /* @__PURE__ */ React2.createElement(
|
|
2293
|
+
badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["evm"], size: 18 }),
|
|
1911
2294
|
onClick: () => handleChainChoice("evm")
|
|
1912
2295
|
}
|
|
1913
|
-
), /* @__PURE__ */ React2.createElement(
|
|
2296
|
+
), pendingWallet.chainSupport.includes("solana") && /* @__PURE__ */ React2.createElement(
|
|
1914
2297
|
ChainOption,
|
|
1915
2298
|
{
|
|
1916
2299
|
label: "Solana network",
|
|
1917
2300
|
description: "Connect your Solana address only",
|
|
1918
|
-
badges: /* @__PURE__ */ React2.createElement(
|
|
2301
|
+
badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["solana"], size: 18 }),
|
|
1919
2302
|
onClick: () => handleChainChoice("solana")
|
|
1920
2303
|
}
|
|
2304
|
+
), pendingWallet.chainSupport.includes("tron") && /* @__PURE__ */ React2.createElement(
|
|
2305
|
+
ChainOption,
|
|
2306
|
+
{
|
|
2307
|
+
label: "Tron network",
|
|
2308
|
+
description: "Connect your Tron address only",
|
|
2309
|
+
badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["tron"], size: 18 }),
|
|
2310
|
+
onClick: () => handleChainChoice("tron")
|
|
2311
|
+
}
|
|
2312
|
+
), pendingWallet.chainSupport.includes("bitcoin") && /* @__PURE__ */ React2.createElement(
|
|
2313
|
+
ChainOption,
|
|
2314
|
+
{
|
|
2315
|
+
label: "Bitcoin network",
|
|
2316
|
+
description: "Connect your Bitcoin address only",
|
|
2317
|
+
badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: ["bitcoin"], size: 18 }),
|
|
2318
|
+
onClick: () => handleChainChoice("bitcoin")
|
|
2319
|
+
}
|
|
1921
2320
|
), /* @__PURE__ */ React2.createElement(
|
|
1922
2321
|
ChainOption,
|
|
1923
2322
|
{
|
|
1924
|
-
label: "
|
|
1925
|
-
description: "Connect
|
|
1926
|
-
badges: /* @__PURE__ */ React2.createElement(
|
|
2323
|
+
label: "All networks",
|
|
2324
|
+
description: "Connect all supported addresses together",
|
|
2325
|
+
badges: /* @__PURE__ */ React2.createElement(ChainIconStack, { support: pendingWallet.chainSupport, size: 18 }),
|
|
1927
2326
|
onClick: () => handleChainChoice(void 0)
|
|
1928
2327
|
}
|
|
1929
2328
|
)))
|
|
@@ -1998,7 +2397,7 @@ function WalletSelector({
|
|
|
1998
2397
|
e.currentTarget.style.borderColor = "var(--dc-border)";
|
|
1999
2398
|
}
|
|
2000
2399
|
}
|
|
2001
|
-
)), networks === "all" && /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 4, marginBottom: 10 } }, /* @__PURE__ */ React2.createElement(FilterTab, { label: "All", active: filter === "all", onClick: () => setFilter("all") }), /* @__PURE__ */ React2.createElement(FilterTab, { label: "EVM", active: filter === "evm", onClick: () => setFilter("evm") }), /* @__PURE__ */ React2.createElement(FilterTab, { label: "Solana", active: filter === "solana", onClick: () => setFilter("solana") }))), /* @__PURE__ */ React2.createElement("div", { style: { overflowY: "auto", flex: 1, padding: "0 12px 20px" } }, filtered.length > 0 ? /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 2 } }, filtered.map((w) => /* @__PURE__ */ React2.createElement(WalletRow, { key: w.id, wallet: w, onClick: () => handleWalletClick(w) }))) : /* @__PURE__ */ React2.createElement("div", { style: { textAlign: "center", padding: "32px 16px", color: "var(--dc-text-muted)", fontSize: 13 } }, q ? `No wallets matching "${q}"` : "No wallets detected")), /* @__PURE__ */ React2.createElement("div", { style: { padding: "10px 20px 14px", borderTop: "1px solid var(--dc-border)", textAlign: "center", fontSize: 11, color: "var(--dc-text-muted)" } }, "Don't see your wallet? Make sure it's installed and unlocked"))
|
|
2400
|
+
)), networks === "all" && /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", gap: 4, marginBottom: 10 } }, /* @__PURE__ */ React2.createElement(FilterTab, { label: "All", active: filter === "all", onClick: () => setFilter("all") }), /* @__PURE__ */ React2.createElement(FilterTab, { label: "EVM", active: filter === "evm", onClick: () => setFilter("evm") }), /* @__PURE__ */ React2.createElement(FilterTab, { label: "Solana", active: filter === "solana", onClick: () => setFilter("solana") }), provider.tronWallets && provider.tronWallets.length > 0 && /* @__PURE__ */ React2.createElement(FilterTab, { label: "Tron", active: filter === "tron", onClick: () => setFilter("tron") }), provider.bitcoinWallets && provider.bitcoinWallets.length > 0 && /* @__PURE__ */ React2.createElement(FilterTab, { label: "Bitcoin", active: filter === "bitcoin", onClick: () => setFilter("bitcoin") }))), /* @__PURE__ */ React2.createElement("div", { style: { overflowY: "auto", flex: 1, padding: "0 12px 20px" } }, filtered.length > 0 ? /* @__PURE__ */ React2.createElement("div", { style: { display: "flex", flexDirection: "column", gap: 2 } }, filtered.map((w) => /* @__PURE__ */ React2.createElement(WalletRow, { key: w.id, wallet: w, onClick: () => handleWalletClick(w) }))) : /* @__PURE__ */ React2.createElement("div", { style: { textAlign: "center", padding: "32px 16px", color: "var(--dc-text-muted)", fontSize: 13 } }, q ? `No wallets matching "${q}"` : "No wallets detected")), /* @__PURE__ */ React2.createElement("div", { style: { padding: "10px 20px 14px", borderTop: "1px solid var(--dc-border)", textAlign: "center", fontSize: 11, color: "var(--dc-text-muted)" } }, "Don't see your wallet? Make sure it's installed and unlocked"))
|
|
2002
2401
|
)
|
|
2003
2402
|
)
|
|
2004
2403
|
);
|
|
@@ -2060,6 +2459,11 @@ function useDecaneContext() {
|
|
|
2060
2459
|
|
|
2061
2460
|
// src/ui/hooks.ts
|
|
2062
2461
|
import { useState as useState3, useEffect as useEffect2, useCallback as useCallback3 } from "react";
|
|
2462
|
+
function toDecaneError(err) {
|
|
2463
|
+
if (err instanceof DecaneError) return err;
|
|
2464
|
+
const msg = err instanceof Error ? err.message : err?.message != null ? String(err.message) : String(err);
|
|
2465
|
+
return new DecaneError(5022 /* PROVIDER_ERROR */, msg);
|
|
2466
|
+
}
|
|
2063
2467
|
function useDecane() {
|
|
2064
2468
|
const { provider, theme, setTheme } = useDecaneContext();
|
|
2065
2469
|
const [, forceUpdate] = useState3(0);
|
|
@@ -2137,7 +2541,7 @@ function useChainSwitch() {
|
|
|
2137
2541
|
});
|
|
2138
2542
|
forceUpdate((n) => n + 1);
|
|
2139
2543
|
} catch (err) {
|
|
2140
|
-
const e =
|
|
2544
|
+
const e = toDecaneError(err);
|
|
2141
2545
|
setError(e);
|
|
2142
2546
|
throw err;
|
|
2143
2547
|
} finally {
|
|
@@ -2188,7 +2592,7 @@ function useSignMessage() {
|
|
|
2188
2592
|
setSignature(sig);
|
|
2189
2593
|
return sig;
|
|
2190
2594
|
} catch (err) {
|
|
2191
|
-
const e =
|
|
2595
|
+
const e = toDecaneError(err);
|
|
2192
2596
|
setError(e);
|
|
2193
2597
|
throw err;
|
|
2194
2598
|
} finally {
|
|
@@ -2226,7 +2630,7 @@ function useSendTransaction() {
|
|
|
2226
2630
|
setTxHash(hash);
|
|
2227
2631
|
return hash;
|
|
2228
2632
|
} catch (err) {
|
|
2229
|
-
const e =
|
|
2633
|
+
const e = toDecaneError(err);
|
|
2230
2634
|
setError(e);
|
|
2231
2635
|
throw err;
|
|
2232
2636
|
} finally {
|
|
@@ -2263,7 +2667,7 @@ function useSignTypedData() {
|
|
|
2263
2667
|
setSignature(sig);
|
|
2264
2668
|
return sig;
|
|
2265
2669
|
} catch (err) {
|
|
2266
|
-
const e =
|
|
2670
|
+
const e = toDecaneError(err);
|
|
2267
2671
|
setError(e);
|
|
2268
2672
|
throw err;
|
|
2269
2673
|
} finally {
|