otx-btc-wallet-connectors 0.1.0
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/README.md +554 -0
- package/dist/base-IAFq7sd8.d.mts +53 -0
- package/dist/base-IAFq7sd8.d.ts +53 -0
- package/dist/binance/index.d.mts +81 -0
- package/dist/binance/index.d.ts +81 -0
- package/dist/binance/index.js +13 -0
- package/dist/binance/index.js.map +1 -0
- package/dist/binance/index.mjs +4 -0
- package/dist/binance/index.mjs.map +1 -0
- package/dist/bitget/index.d.mts +84 -0
- package/dist/bitget/index.d.ts +84 -0
- package/dist/bitget/index.js +13 -0
- package/dist/bitget/index.js.map +1 -0
- package/dist/bitget/index.mjs +4 -0
- package/dist/bitget/index.mjs.map +1 -0
- package/dist/chunk-5Z5Q2Y75.mjs +91 -0
- package/dist/chunk-5Z5Q2Y75.mjs.map +1 -0
- package/dist/chunk-7KK2LZLZ.mjs +208 -0
- package/dist/chunk-7KK2LZLZ.mjs.map +1 -0
- package/dist/chunk-AW2JZIHR.mjs +753 -0
- package/dist/chunk-AW2JZIHR.mjs.map +1 -0
- package/dist/chunk-EIJOSZXZ.js +331 -0
- package/dist/chunk-EIJOSZXZ.js.map +1 -0
- package/dist/chunk-EQHR7P7G.js +541 -0
- package/dist/chunk-EQHR7P7G.js.map +1 -0
- package/dist/chunk-EWRXLZO4.mjs +539 -0
- package/dist/chunk-EWRXLZO4.mjs.map +1 -0
- package/dist/chunk-FISNQZZ7.js +802 -0
- package/dist/chunk-FISNQZZ7.js.map +1 -0
- package/dist/chunk-HL4WDMGS.js +200 -0
- package/dist/chunk-HL4WDMGS.js.map +1 -0
- package/dist/chunk-IPYWR76I.js +314 -0
- package/dist/chunk-IPYWR76I.js.map +1 -0
- package/dist/chunk-JYYNWR5G.js +142 -0
- package/dist/chunk-JYYNWR5G.js.map +1 -0
- package/dist/chunk-LNKTYZJM.js +701 -0
- package/dist/chunk-LNKTYZJM.js.map +1 -0
- package/dist/chunk-LVZMONQL.mjs +699 -0
- package/dist/chunk-LVZMONQL.mjs.map +1 -0
- package/dist/chunk-MFXLQWOE.js +93 -0
- package/dist/chunk-MFXLQWOE.js.map +1 -0
- package/dist/chunk-NBIA4TTE.mjs +204 -0
- package/dist/chunk-NBIA4TTE.mjs.map +1 -0
- package/dist/chunk-O4DD2XJ2.js +206 -0
- package/dist/chunk-O4DD2XJ2.js.map +1 -0
- package/dist/chunk-P7HVBU2B.mjs +140 -0
- package/dist/chunk-P7HVBU2B.mjs.map +1 -0
- package/dist/chunk-Q7QVQYEB.js +210 -0
- package/dist/chunk-Q7QVQYEB.js.map +1 -0
- package/dist/chunk-RLZEG6KL.mjs +329 -0
- package/dist/chunk-RLZEG6KL.mjs.map +1 -0
- package/dist/chunk-SYLDBJ75.mjs +246 -0
- package/dist/chunk-SYLDBJ75.mjs.map +1 -0
- package/dist/chunk-TTEUU3CI.mjs +198 -0
- package/dist/chunk-TTEUU3CI.mjs.map +1 -0
- package/dist/chunk-V66BXDTR.mjs +292 -0
- package/dist/chunk-V66BXDTR.mjs.map +1 -0
- package/dist/chunk-X77ZT4OI.js +268 -0
- package/dist/chunk-X77ZT4OI.js.map +1 -0
- package/dist/imtoken/index.d.mts +116 -0
- package/dist/imtoken/index.d.ts +116 -0
- package/dist/imtoken/index.js +14 -0
- package/dist/imtoken/index.js.map +1 -0
- package/dist/imtoken/index.mjs +5 -0
- package/dist/imtoken/index.mjs.map +1 -0
- package/dist/index.d.mts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +170 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +13 -0
- package/dist/index.mjs.map +1 -0
- package/dist/ledger/index.d.mts +290 -0
- package/dist/ledger/index.d.ts +290 -0
- package/dist/ledger/index.js +14 -0
- package/dist/ledger/index.js.map +1 -0
- package/dist/ledger/index.mjs +5 -0
- package/dist/ledger/index.mjs.map +1 -0
- package/dist/okx/index.d.mts +88 -0
- package/dist/okx/index.d.ts +88 -0
- package/dist/okx/index.js +13 -0
- package/dist/okx/index.js.map +1 -0
- package/dist/okx/index.mjs +4 -0
- package/dist/okx/index.mjs.map +1 -0
- package/dist/phantom/index.d.mts +96 -0
- package/dist/phantom/index.d.ts +96 -0
- package/dist/phantom/index.js +14 -0
- package/dist/phantom/index.js.map +1 -0
- package/dist/phantom/index.mjs +5 -0
- package/dist/phantom/index.mjs.map +1 -0
- package/dist/psbt-builder-CFOs69Z5.d.mts +131 -0
- package/dist/psbt-builder-CFOs69Z5.d.ts +131 -0
- package/dist/trezor/index.d.mts +155 -0
- package/dist/trezor/index.d.ts +155 -0
- package/dist/trezor/index.js +14 -0
- package/dist/trezor/index.js.map +1 -0
- package/dist/trezor/index.mjs +5 -0
- package/dist/trezor/index.mjs.map +1 -0
- package/dist/unisat/index.d.mts +75 -0
- package/dist/unisat/index.d.ts +75 -0
- package/dist/unisat/index.js +13 -0
- package/dist/unisat/index.js.map +1 -0
- package/dist/unisat/index.mjs +4 -0
- package/dist/unisat/index.mjs.map +1 -0
- package/dist/utils/index.d.mts +398 -0
- package/dist/utils/index.d.ts +398 -0
- package/dist/utils/index.js +120 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/index.mjs +3 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/xverse/index.d.mts +79 -0
- package/dist/xverse/index.d.ts +79 -0
- package/dist/xverse/index.js +13 -0
- package/dist/xverse/index.js.map +1 -0
- package/dist/xverse/index.mjs +4 -0
- package/dist/xverse/index.mjs.map +1 -0
- package/package.json +108 -0
- package/src/base.ts +132 -0
- package/src/binance/BinanceConnector.ts +307 -0
- package/src/binance/index.ts +1 -0
- package/src/bitget/BitgetConnector.ts +301 -0
- package/src/bitget/index.ts +1 -0
- package/src/imtoken/ImTokenConnector.ts +420 -0
- package/src/imtoken/index.ts +2 -0
- package/src/index.ts +78 -0
- package/src/ledger/LedgerConnector.ts +1019 -0
- package/src/ledger/index.ts +8 -0
- package/src/okx/OKXConnector.ts +230 -0
- package/src/okx/index.ts +1 -0
- package/src/phantom/PhantomConnector.ts +381 -0
- package/src/phantom/index.ts +2 -0
- package/src/trezor/TrezorConnector.ts +824 -0
- package/src/trezor/index.ts +6 -0
- package/src/unisat/UnisatConnector.ts +312 -0
- package/src/unisat/index.ts +1 -0
- package/src/utils/blockstream.ts +230 -0
- package/src/utils/btc-service.ts +364 -0
- package/src/utils/index.ts +56 -0
- package/src/utils/mempool.ts +232 -0
- package/src/utils/psbt-builder.ts +492 -0
- package/src/utils/types.ts +183 -0
- package/src/xverse/XverseConnector.ts +479 -0
- package/src/xverse/index.ts +1 -0
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkFISNQZZ7_js = require('./chunk-FISNQZZ7.js');
|
|
4
|
+
var chunkMFXLQWOE_js = require('./chunk-MFXLQWOE.js');
|
|
5
|
+
var bitcoin = require('bitcoinjs-lib');
|
|
6
|
+
|
|
7
|
+
function _interopNamespace(e) {
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n.default = e;
|
|
22
|
+
return Object.freeze(n);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
var bitcoin__namespace = /*#__PURE__*/_interopNamespace(bitcoin);
|
|
26
|
+
|
|
27
|
+
var IMTOKEN_ICON = "data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MyIgaGVpZ2h0PSI5MyIgdmlld0JveD0iMCAwIDkzIDkzIiBmaWxsPSJub25lIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzIwMzVfMzk1KSI+CjxtYXNrIGlkPSJtYXNrMF8yMDM1XzM5NSIgc3R5bGU9Im1hc2stdHlwZTpsdW1pbmFuY2UiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjAiIHk9IjAiIHdpZHRoPSI5MyIgaGVpZ2h0PSI5MyI+CjxwYXRoIGQ9Ik05MyAwSDBWOTNIOTNWMFoiIGZpbGw9IndoaXRlIi8+CjwvbWFzaz4KPGcgbWFzaz0idXJsKCNtYXNrMF8yMDM1XzM5NSkiPgo8bWFzayBpZD0ibWFzazFfMjAzNV8zOTUiIHN0eWxlPSJtYXNrLXR5cGU6bHVtaW5hbmNlIiBtYXNrVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4PSIwIiB5PSIwIiB3aWR0aD0iOTMiIGhlaWdodD0iOTMiPgo8cGF0aCBkPSJNOTIuODc2OCAwSDAuMDU4MTA1NVY5M0g5Mi44NzY4VjBaIiBmaWxsPSJ3aGl0ZSIvPgo8L21hc2s+CjxnIG1hc2s9InVybCgjbWFzazFfMjAzNV8zOTUpIj4KPHBhdGggZD0iTTcyLjEwNSAwSDIwLjk4MjJDOS40NjgyMiAwIDAuMTM0Mjc3IDkuMzUyMTkgMC4xMzQyNzcgMjAuODg4N1Y3Mi4xMTEzQzAuMTM0Mjc3IDgzLjY0NzkgOS40NjgyMiA5MyAyMC45ODIyIDkzSDcyLjEwNUM4My42MTkxIDkzIDkyLjk1MyA4My42NDc5IDkyLjk1MyA3Mi4xMTEzVjIwLjg4ODdDOTIuOTUzIDkuMzUyMTkgODMuNjE5MSAwIDcyLjEwNSAwWiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzIwMzVfMzk1KSIvPgo8cGF0aCBkPSJNNzUuNjc1MyAyOC43NTI0Qzc3LjYwNTYgNTQuOTQ3OSA2MC44IDY3LjMyOTEgNDUuNzM0MSA2OC42NDk0QzMxLjcyNzQgNjkuODc2OCAxOC41NDMgNjEuMjUzNCAxNy4zODYzIDQ4LjAwNDFDMTYuNDMyMiAzNy4wNTgxIDIzLjE4NDMgMzIuMzk3OSAyOC40ODkzIDMxLjkzMzVDMzMuOTQ1NCAzMS40NTQxIDM4LjUzMDcgMzUuMjI0MyAzOC45Mjg1IDM5Ljc4OTFDMzkuMzExNSA0NC4xNzc3IDM2LjU3ODQgNDYuMTc1NCAzNC42Nzc3IDQ2LjM0MTZDMzMuMTc0NCA0Ni40NzM2IDMxLjI4MzIgNDUuNTU5MyAzMS4xMTI1IDQzLjU5NTlDMzAuOTY2IDQxLjkwODggMzEuNjA1NCA0MS42NzkxIDMxLjQ0OTEgMzkuODg2OEMzMS4xNzEgMzYuNjk2MSAyOC4zOTQxIDM2LjMyNDUgMjYuODczOCAzNi40NTY1QzI1LjAzMzkgMzYuNjE4IDIxLjY5NTcgMzguNzY5NSAyMi4xNjQyIDQ0LjEyODhDMjIuNjM1MiA0OS41MzQ2IDI3LjgwODMgNTMuODA2MSAzNC41ODk3IDUzLjIxMkM0MS45MDc5IDUyLjU3MTMgNDcuMDAzIDQ2Ljg2MjQgNDcuMzg2MiAzOC44NTUxQzQ3LjM4MjYgMzguNDMxIDQ3LjQ3MTggMzguMDExMiA0Ny42NDczIDM3LjYyNTJMNDcuNjQ5NiAzNy42MTU2QzQ3LjcyODUgMzcuNDQ3NyA0Ny44MjA4IDM3LjI4NjYgNDcuOTI1NCAzNy4xMzM5QzQ4LjA4MTYgMzYuODk5MiA0OC4yODE4IDM2LjY0IDQ4LjU0MDMgMzYuMzU2M0M0OC41NDI4IDM2LjM0OSA0OC41NDI4IDM2LjM0OSA0OC41NDc3IDM2LjM0OUM0OC43MzU1IDM2LjEzNjMgNDguOTYyNSAzNS45MDY1IDQ5LjIxODcgMzUuNjU5NUM1Mi40MTU1IDMyLjYzNzUgNjMuOTI4MiAyNS41MTA1IDc0LjgxNjMgMjcuNzY3MkM3NS4wNDY2IDI3LjgxNjYgNzUuMjU0NSAyNy45MzkyIDc1LjQwOTMgMjguMTE2OUM3NS41NjQxIDI4LjI5NDUgNzUuNjU3MyAyOC41MTc0IDc1LjY3NTMgMjguNzUyNFoiIGZpbGw9IndoaXRlIi8+CjwvZz4KPC9nPgo8L2c+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMjAzNV8zOTUiIHgxPSI5Mi44OTc1IiB5MT0iMTUuNzE1NCIgeDI9IjMuMjE5OTciIHkyPSI1MC42NTA0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwQ0M1RkYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDA3RkZGIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfMjAzNV8zOTUiPgo8cmVjdCB3aWR0aD0iOTMiIGhlaWdodD0iOTMiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==";
|
|
28
|
+
var ImTokenConnector = class extends chunkMFXLQWOE_js.BaseConnector {
|
|
29
|
+
constructor() {
|
|
30
|
+
super(...arguments);
|
|
31
|
+
this.id = "imtoken";
|
|
32
|
+
this.name = "imToken";
|
|
33
|
+
this.icon = IMTOKEN_ICON;
|
|
34
|
+
this.downloadUrl = "https://token.im/download";
|
|
35
|
+
this._publicKey = null;
|
|
36
|
+
this._address = null;
|
|
37
|
+
this._network = "mainnet";
|
|
38
|
+
this._removeAccountChangeListener = null;
|
|
39
|
+
this._removeNetworkChangeListener = null;
|
|
40
|
+
}
|
|
41
|
+
getProvider() {
|
|
42
|
+
if (typeof window === "undefined")
|
|
43
|
+
return void 0;
|
|
44
|
+
return window.bitcoin;
|
|
45
|
+
}
|
|
46
|
+
async connect(network = "mainnet") {
|
|
47
|
+
this.ensureInstalled();
|
|
48
|
+
const provider = this.getProvider();
|
|
49
|
+
try {
|
|
50
|
+
await this.trySwitchNetwork(provider, network);
|
|
51
|
+
const accounts = await provider.request({ method: "btc_requestAccounts" });
|
|
52
|
+
if (!accounts || accounts.length === 0) {
|
|
53
|
+
throw new Error("No accounts found");
|
|
54
|
+
}
|
|
55
|
+
this._publicKey = await provider.request({ method: "btc_getPublicKey" });
|
|
56
|
+
this._address = accounts[0] ?? "";
|
|
57
|
+
this._network = network;
|
|
58
|
+
this.setupEventListeners();
|
|
59
|
+
return {
|
|
60
|
+
address: this._address,
|
|
61
|
+
publicKey: this._publicKey,
|
|
62
|
+
type: this.inferAddressType(this._address)
|
|
63
|
+
};
|
|
64
|
+
} catch (error) {
|
|
65
|
+
this.handleError(error);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async trySwitchNetwork(provider, network) {
|
|
69
|
+
try {
|
|
70
|
+
const imTokenNetwork = this.mapToImTokenNetwork(network);
|
|
71
|
+
await provider.request({ method: "btc_switchNetwork", params: [imTokenNetwork] });
|
|
72
|
+
} catch {
|
|
73
|
+
console.warn("imToken network switching may not be supported");
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
setupEventListeners() {
|
|
77
|
+
const provider = this.getProvider();
|
|
78
|
+
if (!provider || typeof provider.on !== "function")
|
|
79
|
+
return;
|
|
80
|
+
this.removeEventListeners();
|
|
81
|
+
const handleAccountsChanged = (...args) => {
|
|
82
|
+
const accounts = args[0];
|
|
83
|
+
if (!accounts || accounts.length === 0) {
|
|
84
|
+
this.emitAccountsChanged([]);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
provider.request({ method: "btc_getPublicKey" }).then((publicKey) => {
|
|
88
|
+
this._publicKey = publicKey;
|
|
89
|
+
const walletAccounts = accounts.map((address) => ({
|
|
90
|
+
address,
|
|
91
|
+
publicKey,
|
|
92
|
+
type: this.inferAddressType(address)
|
|
93
|
+
}));
|
|
94
|
+
this.emitAccountsChanged(walletAccounts);
|
|
95
|
+
}).catch(() => {
|
|
96
|
+
this.emitAccountsChanged([]);
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
const handleNetworkChanged = () => {
|
|
100
|
+
provider.request({ method: "btc_getNetwork" }).then((network) => {
|
|
101
|
+
const btcNetwork = this.mapNetwork(network);
|
|
102
|
+
this.emitNetworkChanged(btcNetwork);
|
|
103
|
+
}).catch(() => {
|
|
104
|
+
});
|
|
105
|
+
};
|
|
106
|
+
provider.on("accountsChanged", handleAccountsChanged);
|
|
107
|
+
provider.on("networkChanged", handleNetworkChanged);
|
|
108
|
+
this._removeAccountChangeListener = () => {
|
|
109
|
+
provider.removeListener("accountsChanged", handleAccountsChanged);
|
|
110
|
+
};
|
|
111
|
+
this._removeNetworkChangeListener = () => {
|
|
112
|
+
provider.removeListener("networkChanged", handleNetworkChanged);
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
removeEventListeners() {
|
|
116
|
+
this._removeAccountChangeListener?.();
|
|
117
|
+
this._removeAccountChangeListener = null;
|
|
118
|
+
this._removeNetworkChangeListener?.();
|
|
119
|
+
this._removeNetworkChangeListener = null;
|
|
120
|
+
}
|
|
121
|
+
async disconnect() {
|
|
122
|
+
this.removeEventListeners();
|
|
123
|
+
this._publicKey = null;
|
|
124
|
+
this._address = null;
|
|
125
|
+
this.cleanup();
|
|
126
|
+
}
|
|
127
|
+
async getAccounts() {
|
|
128
|
+
this.ensureInstalled();
|
|
129
|
+
const provider = this.getProvider();
|
|
130
|
+
try {
|
|
131
|
+
const addresses = await provider.request({ method: "btc_requestAccounts" });
|
|
132
|
+
const publicKey = await provider.request({ method: "btc_getPublicKey" });
|
|
133
|
+
this._publicKey = publicKey;
|
|
134
|
+
return addresses.map((address) => ({
|
|
135
|
+
address,
|
|
136
|
+
publicKey,
|
|
137
|
+
type: this.inferAddressType(address)
|
|
138
|
+
}));
|
|
139
|
+
} catch (error) {
|
|
140
|
+
this.handleError(error);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Sign a message using BIP-322 simple format
|
|
145
|
+
* Note: Only bip322-simple is supported by imToken
|
|
146
|
+
*/
|
|
147
|
+
async signMessage(message) {
|
|
148
|
+
this.ensureInstalled();
|
|
149
|
+
const provider = this.getProvider();
|
|
150
|
+
try {
|
|
151
|
+
return await provider.request({
|
|
152
|
+
method: "btc_signMessage",
|
|
153
|
+
params: [message, "bip322-simple"]
|
|
154
|
+
});
|
|
155
|
+
} catch (error) {
|
|
156
|
+
this.handleError(error);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
async signPsbt(psbtHex, options) {
|
|
160
|
+
this.ensureInstalled();
|
|
161
|
+
const provider = this.getProvider();
|
|
162
|
+
try {
|
|
163
|
+
const autoFinalize = options?.autoFinalize ?? true;
|
|
164
|
+
return await provider.request({
|
|
165
|
+
method: "btc_signPsbt",
|
|
166
|
+
params: [psbtHex, autoFinalize]
|
|
167
|
+
});
|
|
168
|
+
} catch (error) {
|
|
169
|
+
this.handleError(error);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async signPsbts(psbtHexs) {
|
|
173
|
+
this.ensureInstalled();
|
|
174
|
+
const provider = this.getProvider();
|
|
175
|
+
try {
|
|
176
|
+
return await provider.request({
|
|
177
|
+
method: "btc_signPsbts",
|
|
178
|
+
params: [psbtHexs]
|
|
179
|
+
});
|
|
180
|
+
} catch (error) {
|
|
181
|
+
this.handleError(error);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Send Bitcoin transaction
|
|
186
|
+
* Builds a PSBT using bitcoinjs-lib, signs it with imToken, and broadcasts
|
|
187
|
+
*
|
|
188
|
+
* @param to - Recipient address
|
|
189
|
+
* @param satoshis - Amount to send in satoshis
|
|
190
|
+
* @param options - Send options (feeRate, etc.)
|
|
191
|
+
* @returns Transaction ID after broadcast
|
|
192
|
+
*/
|
|
193
|
+
async sendTransaction(to, satoshis, options) {
|
|
194
|
+
this.ensureInstalled();
|
|
195
|
+
const provider = this.getProvider();
|
|
196
|
+
if (!this._address || !this._publicKey) {
|
|
197
|
+
throw new Error("Not connected. Please call connect() first.");
|
|
198
|
+
}
|
|
199
|
+
const btcNetwork = chunkFISNQZZ7_js.getBitcoinJsNetwork(this._network);
|
|
200
|
+
const {
|
|
201
|
+
psbtHex,
|
|
202
|
+
selectedUtxos
|
|
203
|
+
} = await chunkFISNQZZ7_js.generatePsbtForSend(
|
|
204
|
+
to,
|
|
205
|
+
satoshis,
|
|
206
|
+
this._address,
|
|
207
|
+
this._publicKey,
|
|
208
|
+
this._network,
|
|
209
|
+
options
|
|
210
|
+
);
|
|
211
|
+
const signedPsbtHex = await provider.request({
|
|
212
|
+
method: "btc_signPsbt",
|
|
213
|
+
params: [psbtHex, false]
|
|
214
|
+
});
|
|
215
|
+
const signedPsbt = bitcoin__namespace.Psbt.fromHex(signedPsbtHex, { network: btcNetwork });
|
|
216
|
+
chunkFISNQZZ7_js.finalizeAllInputs(signedPsbt, selectedUtxos.length);
|
|
217
|
+
const tx = signedPsbt.extractTransaction();
|
|
218
|
+
const txHex = tx.toHex();
|
|
219
|
+
try {
|
|
220
|
+
const txid = await provider.request({
|
|
221
|
+
method: "btc_sendRawTransaction",
|
|
222
|
+
params: [txHex]
|
|
223
|
+
});
|
|
224
|
+
return txid;
|
|
225
|
+
} catch {
|
|
226
|
+
const btcService = new chunkFISNQZZ7_js.BtcService(this._network);
|
|
227
|
+
return await btcService.broadcastTransaction(txHex);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Broadcast a raw transaction
|
|
232
|
+
*/
|
|
233
|
+
async broadcastTransaction(txHex) {
|
|
234
|
+
this.ensureInstalled();
|
|
235
|
+
const provider = this.getProvider();
|
|
236
|
+
try {
|
|
237
|
+
return await provider.request({
|
|
238
|
+
method: "btc_sendRawTransaction",
|
|
239
|
+
params: [txHex]
|
|
240
|
+
});
|
|
241
|
+
} catch (error) {
|
|
242
|
+
this.handleError(error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async getNetwork() {
|
|
246
|
+
this.ensureInstalled();
|
|
247
|
+
const provider = this.getProvider();
|
|
248
|
+
try {
|
|
249
|
+
const network = await provider.request({ method: "btc_getNetwork" });
|
|
250
|
+
return this.mapNetwork(network);
|
|
251
|
+
} catch (error) {
|
|
252
|
+
this.handleError(error);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
async switchNetwork(network) {
|
|
256
|
+
this.ensureInstalled();
|
|
257
|
+
const provider = this.getProvider();
|
|
258
|
+
try {
|
|
259
|
+
const imTokenNetwork = this.mapToImTokenNetwork(network);
|
|
260
|
+
await provider.request({ method: "btc_switchNetwork", params: [imTokenNetwork] });
|
|
261
|
+
} catch (error) {
|
|
262
|
+
this.handleError(error);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Get the public key (cached from connect)
|
|
267
|
+
*/
|
|
268
|
+
getPublicKey() {
|
|
269
|
+
return this._publicKey;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Get balance for an address
|
|
273
|
+
*/
|
|
274
|
+
async getBalance(address) {
|
|
275
|
+
this.ensureInstalled();
|
|
276
|
+
const provider = this.getProvider();
|
|
277
|
+
try {
|
|
278
|
+
return await provider.request({
|
|
279
|
+
method: "btc_getBalance",
|
|
280
|
+
params: [address]
|
|
281
|
+
});
|
|
282
|
+
} catch (error) {
|
|
283
|
+
this.handleError(error);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
mapNetwork(network) {
|
|
287
|
+
switch (network.toLowerCase()) {
|
|
288
|
+
case "mainnet":
|
|
289
|
+
return "mainnet";
|
|
290
|
+
case "signet":
|
|
291
|
+
return "signet";
|
|
292
|
+
case "testnet":
|
|
293
|
+
return "testnet";
|
|
294
|
+
default:
|
|
295
|
+
return "mainnet";
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
mapToImTokenNetwork(network) {
|
|
299
|
+
switch (network) {
|
|
300
|
+
case "mainnet":
|
|
301
|
+
return "mainnet";
|
|
302
|
+
case "signet":
|
|
303
|
+
case "testnet":
|
|
304
|
+
case "testnet4":
|
|
305
|
+
return "signet";
|
|
306
|
+
default:
|
|
307
|
+
return "mainnet";
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
|
|
312
|
+
exports.ImTokenConnector = ImTokenConnector;
|
|
313
|
+
//# sourceMappingURL=out.js.map
|
|
314
|
+
//# sourceMappingURL=chunk-IPYWR76I.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/imtoken/ImTokenConnector.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n WalletAccount,\n BitcoinNetwork,\n SignPsbtOptions,\n} from 'otx-btc-wallet-core';\nimport * as bitcoin from 'bitcoinjs-lib';\nimport { BaseConnector } from '../base';\nimport { BtcService } from '../utils';\nimport {\n generatePsbtForSend,\n finalizeAllInputs,\n getBitcoinJsNetwork,\n type GeneratePsbtOptions,\n} from '../utils';\n\n/**\n * Options for sendTransaction method\n */\nexport interface ImTokenSendOptions extends GeneratePsbtOptions {\n // Additional imToken-specific options can be added here\n}\n\n/**\n * imToken Bitcoin provider interface\n * Provider is accessible via window.bitcoin\n * @see https://imtoken.gitbook.io/developers/products/webview/bitcoin\n */\ninterface ImTokenBitcoinProvider {\n request(params: { method: 'btc_requestAccounts' }): Promise<string[]>;\n request(params: { method: 'btc_getNetwork' }): Promise<string>;\n request(params: { method: 'btc_getPublicKey' }): Promise<string>;\n request(params: { method: 'btc_getBalance'; params: [string] }): Promise<number>;\n request(params: { method: 'btc_signPsbt'; params: [string, boolean?] }): Promise<string>;\n request(params: { method: 'btc_signPsbts'; params: [string[]] }): Promise<string[]>;\n request(params: {\n method: 'btc_signMessage';\n params: [string, 'bip322-simple' | 'bip322-full' | 'bip322-legacy'];\n }): Promise<string>;\n request(params: { method: 'btc_sendRawTransaction'; params: [string] }): Promise<string>;\n request(params: { method: 'btc_switchNetwork'; params: [string] }): Promise<null>;\n on(event: 'accountsChanged', callback: (...args: unknown[]) => void): void;\n on(event: 'networkChanged', callback: (...args: unknown[]) => void): void;\n removeListener(event: string, callback: (...args: unknown[]) => void): void;\n}\n\n// Extend window type\ndeclare global {\n interface Window {\n bitcoin?: ImTokenBitcoinProvider;\n }\n}\n\n// imToken wallet icon\nconst IMTOKEN_ICON =\n 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSI5MyIgaGVpZ2h0PSI5MyIgdmlld0JveD0iMCAwIDkzIDkzIiBmaWxsPSJub25lIj4KPGcgY2xpcC1wYXRoPSJ1cmwoI2NsaXAwXzIwMzVfMzk1KSI+CjxtYXNrIGlkPSJtYXNrMF8yMDM1XzM5NSIgc3R5bGU9Im1hc2stdHlwZTpsdW1pbmFuY2UiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjAiIHk9IjAiIHdpZHRoPSI5MyIgaGVpZ2h0PSI5MyI+CjxwYXRoIGQ9Ik05MyAwSDBWOTNIOTNWMFoiIGZpbGw9IndoaXRlIi8+CjwvbWFzaz4KPGcgbWFzaz0idXJsKCNtYXNrMF8yMDM1XzM5NSkiPgo8bWFzayBpZD0ibWFzazFfMjAzNV8zOTUiIHN0eWxlPSJtYXNrLXR5cGU6bHVtaW5hbmNlIiBtYXNrVW5pdHM9InVzZXJTcGFjZU9uVXNlIiB4PSIwIiB5PSIwIiB3aWR0aD0iOTMiIGhlaWdodD0iOTMiPgo8cGF0aCBkPSJNOTIuODc2OCAwSDAuMDU4MTA1NVY5M0g5Mi44NzY4VjBaIiBmaWxsPSJ3aGl0ZSIvPgo8L21hc2s+CjxnIG1hc2s9InVybCgjbWFzazFfMjAzNV8zOTUpIj4KPHBhdGggZD0iTTcyLjEwNSAwSDIwLjk4MjJDOS40NjgyMiAwIDAuMTM0Mjc3IDkuMzUyMTkgMC4xMzQyNzcgMjAuODg4N1Y3Mi4xMTEzQzAuMTM0Mjc3IDgzLjY0NzkgOS40NjgyMiA5MyAyMC45ODIyIDkzSDcyLjEwNUM4My42MTkxIDkzIDkyLjk1MyA4My42NDc5IDkyLjk1MyA3Mi4xMTEzVjIwLjg4ODdDOTIuOTUzIDkuMzUyMTkgODMuNjE5MSAwIDcyLjEwNSAwWiIgZmlsbD0idXJsKCNwYWludDBfbGluZWFyXzIwMzVfMzk1KSIvPgo8cGF0aCBkPSJNNzUuNjc1MyAyOC43NTI0Qzc3LjYwNTYgNTQuOTQ3OSA2MC44IDY3LjMyOTEgNDUuNzM0MSA2OC42NDk0QzMxLjcyNzQgNjkuODc2OCAxOC41NDMgNjEuMjUzNCAxNy4zODYzIDQ4LjAwNDFDMTYuNDMyMiAzNy4wNTgxIDIzLjE4NDMgMzIuMzk3OSAyOC40ODkzIDMxLjkzMzVDMzMuOTQ1NCAzMS40NTQxIDM4LjUzMDcgMzUuMjI0MyAzOC45Mjg1IDM5Ljc4OTFDMzkuMzExNSA0NC4xNzc3IDM2LjU3ODQgNDYuMTc1NCAzNC42Nzc3IDQ2LjM0MTZDMzMuMTc0NCA0Ni40NzM2IDMxLjI4MzIgNDUuNTU5MyAzMS4xMTI1IDQzLjU5NTlDMzAuOTY2IDQxLjkwODggMzEuNjA1NCA0MS42NzkxIDMxLjQ0OTEgMzkuODg2OEMzMS4xNzEgMzYuNjk2MSAyOC4zOTQxIDM2LjMyNDUgMjYuODczOCAzNi40NTY1QzI1LjAzMzkgMzYuNjE4IDIxLjY5NTcgMzguNzY5NSAyMi4xNjQyIDQ0LjEyODhDMjIuNjM1MiA0OS41MzQ2IDI3LjgwODMgNTMuODA2MSAzNC41ODk3IDUzLjIxMkM0MS45MDc5IDUyLjU3MTMgNDcuMDAzIDQ2Ljg2MjQgNDcuMzg2MiAzOC44NTUxQzQ3LjM4MjYgMzguNDMxIDQ3LjQ3MTggMzguMDExMiA0Ny42NDczIDM3LjYyNTJMNDcuNjQ5NiAzNy42MTU2QzQ3LjcyODUgMzcuNDQ3NyA0Ny44MjA4IDM3LjI4NjYgNDcuOTI1NCAzNy4xMzM5QzQ4LjA4MTYgMzYuODk5MiA0OC4yODE4IDM2LjY0IDQ4LjU0MDMgMzYuMzU2M0M0OC41NDI4IDM2LjM0OSA0OC41NDI4IDM2LjM0OSA0OC41NDc3IDM2LjM0OUM0OC43MzU1IDM2LjEzNjMgNDguOTYyNSAzNS45MDY1IDQ5LjIxODcgMzUuNjU5NUM1Mi40MTU1IDMyLjYzNzUgNjMuOTI4MiAyNS41MTA1IDc0LjgxNjMgMjcuNzY3MkM3NS4wNDY2IDI3LjgxNjYgNzUuMjU0NSAyNy45MzkyIDc1LjQwOTMgMjguMTE2OUM3NS41NjQxIDI4LjI5NDUgNzUuNjU3MyAyOC41MTc0IDc1LjY3NTMgMjguNzUyNFoiIGZpbGw9IndoaXRlIi8+CjwvZz4KPC9nPgo8L2c+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMjAzNV8zOTUiIHgxPSI5Mi44OTc1IiB5MT0iMTUuNzE1NCIgeDI9IjMuMjE5OTciIHkyPSI1MC42NTA0IiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+CjxzdG9wIHN0b3AtY29sb3I9IiMwQ0M1RkYiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMDA3RkZGIi8+CjwvbGluZWFyR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfMjAzNV8zOTUiPgo8cmVjdCB3aWR0aD0iOTMiIGhlaWdodD0iOTMiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==';\n\n/**\n * imToken network type\n */\ntype ImTokenNetwork = 'mainnet' | 'signet';\n\n/**\n * imToken Wallet Connector\n *\n * @see https://imtoken.gitbook.io/developers/products/webview/bitcoin\n */\nexport class ImTokenConnector extends BaseConnector {\n readonly id = 'imtoken';\n readonly name = 'imToken';\n readonly icon = IMTOKEN_ICON;\n readonly downloadUrl = 'https://token.im/download';\n\n private _publicKey: string | null = null;\n private _address: string | null = null;\n private _network: BitcoinNetwork = 'mainnet';\n private _removeAccountChangeListener: (() => void) | null = null;\n private _removeNetworkChangeListener: (() => void) | null = null;\n\n protected getProvider(): ImTokenBitcoinProvider | undefined {\n if (typeof window === 'undefined') return undefined;\n return window.bitcoin;\n }\n\n async connect(network: BitcoinNetwork = 'mainnet'): Promise<WalletAccount> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n // Switch network first (may not be supported yet)\n await this.trySwitchNetwork(provider, network);\n\n // Request accounts\n const accounts = await provider.request({ method: 'btc_requestAccounts' });\n if (!accounts || accounts.length === 0) {\n throw new Error('No accounts found');\n }\n\n // Get public key\n this._publicKey = await provider.request({ method: 'btc_getPublicKey' });\n this._address = accounts[0] ?? '';\n this._network = network;\n\n // Setup event listeners\n this.setupEventListeners();\n\n return {\n address: this._address,\n publicKey: this._publicKey,\n type: this.inferAddressType(this._address),\n };\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async trySwitchNetwork(\n provider: ImTokenBitcoinProvider,\n network: BitcoinNetwork\n ): Promise<void> {\n try {\n const imTokenNetwork = this.mapToImTokenNetwork(network);\n await provider.request({ method: 'btc_switchNetwork', params: [imTokenNetwork] });\n } catch {\n // Network switching might not be supported yet, continue with current network\n console.warn('imToken network switching may not be supported');\n }\n }\n\n private setupEventListeners(): void {\n const provider = this.getProvider();\n if (!provider || typeof provider.on !== 'function') return;\n\n // Remove existing listeners\n this.removeEventListeners();\n\n // Account change listener\n const handleAccountsChanged = (...args: unknown[]) => {\n const accounts = args[0] as string[];\n if (!accounts || accounts.length === 0) {\n this.emitAccountsChanged([]);\n return;\n }\n\n provider\n .request({ method: 'btc_getPublicKey' })\n .then((publicKey) => {\n this._publicKey = publicKey;\n const walletAccounts: WalletAccount[] = accounts.map((address) => ({\n address,\n publicKey,\n type: this.inferAddressType(address),\n }));\n this.emitAccountsChanged(walletAccounts);\n })\n .catch(() => {\n this.emitAccountsChanged([]);\n });\n };\n\n // Network change listener\n const handleNetworkChanged = () => {\n // When network changes, we need to re-fetch network info\n provider\n .request({ method: 'btc_getNetwork' })\n .then((network) => {\n const btcNetwork = this.mapNetwork(network);\n this.emitNetworkChanged(btcNetwork);\n })\n .catch(() => {\n // Ignore errors\n });\n };\n\n provider.on('accountsChanged', handleAccountsChanged);\n provider.on('networkChanged', handleNetworkChanged);\n\n this._removeAccountChangeListener = () => {\n provider.removeListener('accountsChanged', handleAccountsChanged);\n };\n this._removeNetworkChangeListener = () => {\n provider.removeListener('networkChanged', handleNetworkChanged);\n };\n }\n\n private removeEventListeners(): void {\n this._removeAccountChangeListener?.();\n this._removeAccountChangeListener = null;\n\n this._removeNetworkChangeListener?.();\n this._removeNetworkChangeListener = null;\n }\n\n async disconnect(): Promise<void> {\n this.removeEventListeners();\n this._publicKey = null;\n this._address = null;\n this.cleanup();\n }\n\n async getAccounts(): Promise<WalletAccount[]> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const addresses = await provider.request({ method: 'btc_requestAccounts' });\n const publicKey = await provider.request({ method: 'btc_getPublicKey' });\n this._publicKey = publicKey;\n\n return addresses.map((address) => ({\n address,\n publicKey,\n type: this.inferAddressType(address),\n }));\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Sign a message using BIP-322 simple format\n * Note: Only bip322-simple is supported by imToken\n */\n async signMessage(message: string): Promise<string> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n return await provider.request({\n method: 'btc_signMessage',\n params: [message, 'bip322-simple'],\n });\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const autoFinalize = options?.autoFinalize ?? true;\n return await provider.request({\n method: 'btc_signPsbt',\n params: [psbtHex, autoFinalize],\n });\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async signPsbts(psbtHexs: string[]): Promise<string[]> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n return await provider.request({\n method: 'btc_signPsbts',\n params: [psbtHexs],\n });\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Send Bitcoin transaction\n * Builds a PSBT using bitcoinjs-lib, signs it with imToken, and broadcasts\n *\n * @param to - Recipient address\n * @param satoshis - Amount to send in satoshis\n * @param options - Send options (feeRate, etc.)\n * @returns Transaction ID after broadcast\n */\n async sendTransaction(\n to: string,\n satoshis: number,\n options?: ImTokenSendOptions\n ): Promise<string> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n if (!this._address || !this._publicKey) {\n throw new Error('Not connected. Please call connect() first.');\n }\n\n const btcNetwork = getBitcoinJsNetwork(this._network);\n\n // 1. Generate PSBT using the utility\n const {\n psbtHex,\n selectedUtxos,\n } = await generatePsbtForSend(\n to,\n satoshis,\n this._address,\n this._publicKey,\n this._network,\n options\n );\n\n // 2. Sign PSBT with imToken (autoFinalize = false to handle finalization ourselves)\n const signedPsbtHex = await provider.request({\n method: 'btc_signPsbt',\n params: [psbtHex, false],\n });\n\n // 3. Parse signed PSBT and finalize\n const signedPsbt = bitcoin.Psbt.fromHex(signedPsbtHex, { network: btcNetwork });\n finalizeAllInputs(signedPsbt, selectedUtxos.length);\n\n // 4. Extract transaction\n const tx = signedPsbt.extractTransaction();\n const txHex = tx.toHex();\n\n // 5. Broadcast using imToken or fallback to BtcService\n try {\n const txid = await provider.request({\n method: 'btc_sendRawTransaction',\n params: [txHex],\n });\n return txid;\n } catch {\n // Fallback to BtcService broadcast\n const btcService = new BtcService(this._network);\n return await btcService.broadcastTransaction(txHex);\n }\n }\n\n /**\n * Broadcast a raw transaction\n */\n async broadcastTransaction(txHex: string): Promise<string> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n return await provider.request({\n method: 'btc_sendRawTransaction',\n params: [txHex],\n });\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async getNetwork(): Promise<BitcoinNetwork> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const network = await provider.request({ method: 'btc_getNetwork' });\n return this.mapNetwork(network);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async switchNetwork(network: BitcoinNetwork): Promise<void> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const imTokenNetwork = this.mapToImTokenNetwork(network);\n await provider.request({ method: 'btc_switchNetwork', params: [imTokenNetwork] });\n } catch (error) {\n this.handleError(error);\n }\n }\n\n /**\n * Get the public key (cached from connect)\n */\n getPublicKey(): string | null {\n return this._publicKey;\n }\n\n /**\n * Get balance for an address\n */\n async getBalance(address: string): Promise<number> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n return await provider.request({\n method: 'btc_getBalance',\n params: [address],\n });\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private mapNetwork(network: string): BitcoinNetwork {\n switch (network.toLowerCase()) {\n case 'mainnet':\n return 'mainnet';\n case 'signet':\n return 'signet';\n case 'testnet':\n return 'testnet';\n default:\n return 'mainnet';\n }\n }\n\n private mapToImTokenNetwork(network: BitcoinNetwork): ImTokenNetwork {\n switch (network) {\n case 'mainnet':\n return 'mainnet';\n case 'signet':\n case 'testnet':\n case 'testnet4':\n return 'signet';\n default:\n return 'mainnet';\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkMFXLQWOE_js = require('./chunk-MFXLQWOE.js');
|
|
4
|
+
|
|
5
|
+
// src/okx/OKXConnector.ts
|
|
6
|
+
var OKX_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF83MDM1XzUxNDgpIj4KPG1hc2sgaWQ9Im1hc2swXzcwMzVfNTE0OCIgc3R5bGU9Im1hc2stdHlwZTpsdW1pbmFuY2UiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjAiIHk9IjAiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj4KPHBhdGggZD0iTTIwMCAwSDBWMjAwSDIwMFYwWiIgZmlsbD0id2hpdGUiLz4KPC9tYXNrPgo8ZyBtYXNrPSJ1cmwoI21hc2swXzcwMzVfNTE0OCkiPgo8cGF0aCBkPSJNMTU3LjA2OCAwSDQyLjkzMkMxOS4yMjEzIDAgMCAxOS4yMjEzIDAgNDIuOTMyVjE1Ny4wNjhDMCAxODAuNzc5IDE5LjIyMTMgMjAwIDQyLjkzMiAyMDBIMTU3LjA2OEMxODAuNzc5IDIwMCAyMDAgMTgwLjc3OSAyMDAgMTU3LjA2OFY0Mi45MzJDMjAwIDE5LjIyMTMgMTgwLjc3OSAwIDE1Ny4wNjggMFoiIGZpbGw9ImJsYWNrIi8+CjwvZz4KPHBhdGggZD0iTTExNi44MzYgODEuNjY3Mkg4NC4xOTI2QzgyLjgwNTggODEuNjY3MiA4MS42ODE0IDgyLjc5MTIgODEuNjgxNCA4NC4xNzhWMTE2LjgyMkM4MS42ODE0IDExOC4yMDkgODIuODA1OCAxMTkuMzMzIDg0LjE5MjYgMTE5LjMzM0gxMTYuODM2QzExOC4yMjMgMTE5LjMzMyAxMTkuMzQ4IDExOC4yMDkgMTE5LjM0OCAxMTYuODIyVjg0LjE3OEMxMTkuMzQ4IDgyLjc5MTIgMTE4LjIyMyA4MS42NjcyIDExNi44MzYgODEuNjY3MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik03OS4xNTUgNDRINDYuNTExM0M0NS4xMjQ1IDQ0IDQ0IDQ1LjEyNCA0NCA0Ni41MTEyVjc5LjE1NUM0NCA4MC41NDE4IDQ1LjEyNDUgODEuNjY2MiA0Ni41MTEzIDgxLjY2NjJINzkuMTU1QzgwLjU0MjMgODEuNjY2MiA4MS42NjYyIDgwLjU0MTggODEuNjY2MiA3OS4xNTVWNDYuNTExMkM4MS42NjYyIDQ1LjEyNCA4MC41NDIzIDQ0IDc5LjE1NSA0NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xNTQuNDg3IDQ0SDEyMS44NDNDMTIwLjQ1NiA0NCAxMTkuMzMyIDQ1LjEyNCAxMTkuMzMyIDQ2LjUxMTJWNzkuMTU1QzExOS4zMzIgODAuNTQxOCAxMjAuNDU2IDgxLjY2NjIgMTIxLjg0MyA4MS42NjYySDE1NC40ODdDMTU1Ljg3NCA4MS42NjYyIDE1Ni45OTggODAuNTQxOCAxNTYuOTk4IDc5LjE1NVY0Ni41MTEyQzE1Ni45OTggNDUuMTI0IDE1NS44NzQgNDQgMTU0LjQ4NyA0NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik03OS4xNTUgMTE5LjMzMUg0Ni41MTEzQzQ1LjEyNDUgMTE5LjMzMSA0NCAxMjAuNDU1IDQ0IDEyMS44NDJWMTU0LjQ4NkM0NCAxNTUuODczIDQ1LjEyNDUgMTU2Ljk5OCA0Ni41MTEzIDE1Ni45OThINzkuMTU1QzgwLjU0MjMgMTU2Ljk5OCA4MS42NjYyIDE1NS44NzMgODEuNjY2MiAxNTQuNDg2VjEyMS44NDJDODEuNjY2MiAxMjAuNDU1IDgwLjU0MjMgMTE5LjMzMSA3OS4xNTUgMTE5LjMzMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xNTQuNDg3IDExOS4zMzFIMTIxLjg0M0MxMjAuNDU2IDExOS4zMzEgMTE5LjMzMiAxMjAuNDU1IDExOS4zMzIgMTIxLjg0MlYxNTQuNDg2QzExOS4zMzIgMTU1Ljg3MyAxMjAuNDU2IDE1Ni45OTggMTIxLjg0MyAxNTYuOTk4SDE1NC40ODdDMTU1Ljg3NCAxNTYuOTk4IDE1Ni45OTggMTU1Ljg3MyAxNTYuOTk4IDE1NC40ODZWMTIxLjg0MkMxNTYuOTk4IDEyMC40NTUgMTU1Ljg3NCAxMTkuMzMxIDE1NC40ODcgMTE5LjMzMVoiIGZpbGw9IndoaXRlIi8+CjwvZz4KPGRlZnM+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNzAzNV81MTQ4Ij4KPHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==";
|
|
7
|
+
var OKXConnector = class extends chunkMFXLQWOE_js.BaseConnector {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.id = "okx";
|
|
11
|
+
this.name = "OKX Wallet";
|
|
12
|
+
this.icon = OKX_ICON;
|
|
13
|
+
}
|
|
14
|
+
getProvider() {
|
|
15
|
+
if (typeof window === "undefined")
|
|
16
|
+
return void 0;
|
|
17
|
+
return window.okxwallet?.bitcoin;
|
|
18
|
+
}
|
|
19
|
+
async connect() {
|
|
20
|
+
this.ensureInstalled();
|
|
21
|
+
const provider = this.getProvider();
|
|
22
|
+
try {
|
|
23
|
+
const result = await provider.connect();
|
|
24
|
+
this.setupListeners();
|
|
25
|
+
return {
|
|
26
|
+
address: result.address,
|
|
27
|
+
publicKey: result.publicKey,
|
|
28
|
+
type: this.inferAddressType(result.address)
|
|
29
|
+
};
|
|
30
|
+
} catch (error) {
|
|
31
|
+
this.handleError(error);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
async disconnect() {
|
|
35
|
+
this._unsubscribeAccounts?.();
|
|
36
|
+
this._unsubscribeNetwork?.();
|
|
37
|
+
this.cleanup();
|
|
38
|
+
}
|
|
39
|
+
async getAccounts() {
|
|
40
|
+
this.ensureInstalled();
|
|
41
|
+
const provider = this.getProvider();
|
|
42
|
+
try {
|
|
43
|
+
const addresses = await provider.getAccounts();
|
|
44
|
+
const publicKey = await provider.getPublicKey();
|
|
45
|
+
return addresses.map((address) => ({
|
|
46
|
+
address,
|
|
47
|
+
publicKey,
|
|
48
|
+
type: this.inferAddressType(address)
|
|
49
|
+
}));
|
|
50
|
+
} catch (error) {
|
|
51
|
+
this.handleError(error);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
async signMessage(message) {
|
|
55
|
+
this.ensureInstalled();
|
|
56
|
+
const provider = this.getProvider();
|
|
57
|
+
try {
|
|
58
|
+
return await provider.signMessage(message);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
this.handleError(error);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async signPsbt(psbtHex, options) {
|
|
64
|
+
this.ensureInstalled();
|
|
65
|
+
const provider = this.getProvider();
|
|
66
|
+
try {
|
|
67
|
+
const okxOptions = {
|
|
68
|
+
autoFinalized: options?.autoFinalize ?? true
|
|
69
|
+
};
|
|
70
|
+
if (options?.toSignInputs) {
|
|
71
|
+
okxOptions.toSignInputs = options.toSignInputs;
|
|
72
|
+
}
|
|
73
|
+
return await provider.signPsbt(psbtHex, okxOptions);
|
|
74
|
+
} catch (error) {
|
|
75
|
+
this.handleError(error);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async sendTransaction(to, satoshis) {
|
|
79
|
+
this.ensureInstalled();
|
|
80
|
+
const provider = this.getProvider();
|
|
81
|
+
try {
|
|
82
|
+
return await provider.sendBitcoin(to, satoshis);
|
|
83
|
+
} catch (error) {
|
|
84
|
+
this.handleError(error);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
async getNetwork() {
|
|
88
|
+
this.ensureInstalled();
|
|
89
|
+
const provider = this.getProvider();
|
|
90
|
+
try {
|
|
91
|
+
const network = await provider.getNetwork();
|
|
92
|
+
return this.mapNetwork(network);
|
|
93
|
+
} catch (error) {
|
|
94
|
+
this.handleError(error);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
// OKX does not support switchNetwork via API - users must switch manually in extension
|
|
98
|
+
setupListeners() {
|
|
99
|
+
const provider = this.getProvider();
|
|
100
|
+
if (!provider)
|
|
101
|
+
return;
|
|
102
|
+
const handleAccountChanged = (data) => {
|
|
103
|
+
const walletAccount = {
|
|
104
|
+
address: data.address,
|
|
105
|
+
publicKey: data.publicKey,
|
|
106
|
+
type: this.inferAddressType(data.address)
|
|
107
|
+
};
|
|
108
|
+
this.emitAccountsChanged([walletAccount]);
|
|
109
|
+
};
|
|
110
|
+
const handleNetworkChanged = (network) => {
|
|
111
|
+
const btcNetwork = this.mapNetwork(network);
|
|
112
|
+
this.emitNetworkChanged(btcNetwork);
|
|
113
|
+
};
|
|
114
|
+
provider.on("accountChanged", handleAccountChanged);
|
|
115
|
+
provider.on("networkChanged", handleNetworkChanged);
|
|
116
|
+
this._unsubscribeAccounts = () => {
|
|
117
|
+
provider.removeListener("accountChanged", handleAccountChanged);
|
|
118
|
+
};
|
|
119
|
+
this._unsubscribeNetwork = () => {
|
|
120
|
+
provider.removeListener("networkChanged", handleNetworkChanged);
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
mapNetwork(network) {
|
|
124
|
+
switch (network.toLowerCase()) {
|
|
125
|
+
case "livenet":
|
|
126
|
+
case "mainnet":
|
|
127
|
+
return "mainnet";
|
|
128
|
+
case "testnet":
|
|
129
|
+
return "testnet";
|
|
130
|
+
case "testnet4":
|
|
131
|
+
return "testnet4";
|
|
132
|
+
case "signet":
|
|
133
|
+
return "signet";
|
|
134
|
+
default:
|
|
135
|
+
return "mainnet";
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
exports.OKXConnector = OKXConnector;
|
|
141
|
+
//# sourceMappingURL=out.js.map
|
|
142
|
+
//# sourceMappingURL=chunk-JYYNWR5G.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/okx/OKXConnector.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n WalletAccount,\n BitcoinNetwork,\n SignPsbtOptions,\n} from 'otx-btc-wallet-core';\nimport { BaseConnector } from '../base';\n\n/**\n * OKX sign PSBT options\n * @see https://web3.okx.com/build/dev-docs/sdks/chains/bitcoin/provider\n */\ninterface OKXSignPsbtOptions {\n autoFinalized?: boolean;\n toSignInputs?: Array<{\n index: number;\n address?: string;\n publicKey?: string;\n sighashTypes?: number[];\n disableTweakSigner?: boolean;\n }>;\n}\n\n/**\n * OKX account changed event data\n */\ninterface OKXAccountChangedData {\n address: string;\n publicKey: string;\n compressedPublicKey: string;\n}\n\n/**\n * OKX Bitcoin provider interface\n * @see https://web3.okx.com/build/dev-docs/sdks/chains/bitcoin/provider\n */\ninterface OKXBitcoinProvider {\n connect(): Promise<{ address: string; publicKey: string }>;\n requestAccounts(): Promise<string[]>;\n getAccounts(): Promise<string[]>;\n getPublicKey(): Promise<string>;\n getNetwork(): Promise<string>;\n getBalance(): Promise<{ confirmed: number; unconfirmed: number; total: number }>;\n signMessage(message: string, type?: 'ecdsa' | 'bip322-simple'): Promise<string>;\n signPsbt(psbtHex: string, options?: OKXSignPsbtOptions): Promise<string>;\n signPsbts(psbtHexs: string[], options?: OKXSignPsbtOptions[]): Promise<string[]>;\n pushPsbt(psbtHex: string): Promise<string>;\n sendBitcoin(toAddress: string, satoshis: number, options?: { feeRate?: number }): Promise<string>;\n on(event: 'accountChanged', callback: (data: OKXAccountChangedData) => void): void;\n on(event: 'accountsChanged', callback: (addresses: string[]) => void): void;\n on(event: 'networkChanged', callback: (network: string) => void): void;\n removeListener(event: 'accountChanged', callback: (data: OKXAccountChangedData) => void): void;\n removeListener(event: 'accountsChanged', callback: (addresses: string[]) => void): void;\n removeListener(event: 'networkChanged', callback: (network: string) => void): void;\n}\n\n// Extend window type\ndeclare global {\n interface Window {\n okxwallet?: {\n bitcoin?: OKXBitcoinProvider;\n };\n }\n}\n\n// OKX wallet icon\nconst OKX_ICON =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF83MDM1XzUxNDgpIj4KPG1hc2sgaWQ9Im1hc2swXzcwMzVfNTE0OCIgc3R5bGU9Im1hc2stdHlwZTpsdW1pbmFuY2UiIG1hc2tVbml0cz0idXNlclNwYWNlT25Vc2UiIHg9IjAiIHk9IjAiIHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIj4KPHBhdGggZD0iTTIwMCAwSDBWMjAwSDIwMFYwWiIgZmlsbD0id2hpdGUiLz4KPC9tYXNrPgo8ZyBtYXNrPSJ1cmwoI21hc2swXzcwMzVfNTE0OCkiPgo8cGF0aCBkPSJNMTU3LjA2OCAwSDQyLjkzMkMxOS4yMjEzIDAgMCAxOS4yMjEzIDAgNDIuOTMyVjE1Ny4wNjhDMCAxODAuNzc5IDE5LjIyMTMgMjAwIDQyLjkzMiAyMDBIMTU3LjA2OEMxODAuNzc5IDIwMCAyMDAgMTgwLjc3OSAyMDAgMTU3LjA2OFY0Mi45MzJDMjAwIDE5LjIyMTMgMTgwLjc3OSAwIDE1Ny4wNjggMFoiIGZpbGw9ImJsYWNrIi8+CjwvZz4KPHBhdGggZD0iTTExNi44MzYgODEuNjY3Mkg4NC4xOTI2QzgyLjgwNTggODEuNjY3MiA4MS42ODE0IDgyLjc5MTIgODEuNjgxNCA4NC4xNzhWMTE2LjgyMkM4MS42ODE0IDExOC4yMDkgODIuODA1OCAxMTkuMzMzIDg0LjE5MjYgMTE5LjMzM0gxMTYuODM2QzExOC4yMjMgMTE5LjMzMyAxMTkuMzQ4IDExOC4yMDkgMTE5LjM0OCAxMTYuODIyVjg0LjE3OEMxMTkuMzQ4IDgyLjc5MTIgMTE4LjIyMyA4MS42NjcyIDExNi44MzYgODEuNjY3MloiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik03OS4xNTUgNDRINDYuNTExM0M0NS4xMjQ1IDQ0IDQ0IDQ1LjEyNCA0NCA0Ni41MTEyVjc5LjE1NUM0NCA4MC41NDE4IDQ1LjEyNDUgODEuNjY2MiA0Ni41MTEzIDgxLjY2NjJINzkuMTU1QzgwLjU0MjMgODEuNjY2MiA4MS42NjYyIDgwLjU0MTggODEuNjY2MiA3OS4xNTVWNDYuNTExMkM4MS42NjYyIDQ1LjEyNCA4MC41NDIzIDQ0IDc5LjE1NSA0NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xNTQuNDg3IDQ0SDEyMS44NDNDMTIwLjQ1NiA0NCAxMTkuMzMyIDQ1LjEyNCAxMTkuMzMyIDQ2LjUxMTJWNzkuMTU1QzExOS4zMzIgODAuNTQxOCAxMjAuNDU2IDgxLjY2NjIgMTIxLjg0MyA4MS42NjYySDE1NC40ODdDMTU1Ljg3NCA4MS42NjYyIDE1Ni45OTggODAuNTQxOCAxNTYuOTk4IDc5LjE1NVY0Ni41MTEyQzE1Ni45OTggNDUuMTI0IDE1NS44NzQgNDQgMTU0LjQ4NyA0NFoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik03OS4xNTUgMTE5LjMzMUg0Ni41MTEzQzQ1LjEyNDUgMTE5LjMzMSA0NCAxMjAuNDU1IDQ0IDEyMS44NDJWMTU0LjQ4NkM0NCAxNTUuODczIDQ1LjEyNDUgMTU2Ljk5OCA0Ni41MTEzIDE1Ni45OThINzkuMTU1QzgwLjU0MjMgMTU2Ljk5OCA4MS42NjYyIDE1NS44NzMgODEuNjY2MiAxNTQuNDg2VjEyMS44NDJDODEuNjY2MiAxMjAuNDU1IDgwLjU0MjMgMTE5LjMzMSA3OS4xNTUgMTE5LjMzMVoiIGZpbGw9IndoaXRlIi8+CjxwYXRoIGQ9Ik0xNTQuNDg3IDExOS4zMzFIMTIxLjg0M0MxMjAuNDU2IDExOS4zMzEgMTE5LjMzMiAxMjAuNDU1IDExOS4zMzIgMTIxLjg0MlYxNTQuNDg2QzExOS4zMzIgMTU1Ljg3MyAxMjAuNDU2IDE1Ni45OTggMTIxLjg0MyAxNTYuOTk4SDE1NC40ODdDMTU1Ljg3NCAxNTYuOTk4IDE1Ni45OTggMTU1Ljg3MyAxNTYuOTk4IDE1NC40ODZWMTIxLjg0MkMxNTYuOTk4IDEyMC40NTUgMTU1Ljg3NCAxMTkuMzMxIDE1NC40ODcgMTE5LjMzMVoiIGZpbGw9IndoaXRlIi8+CjwvZz4KPGRlZnM+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNzAzNV81MTQ4Ij4KPHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIGZpbGw9IndoaXRlIi8+CjwvY2xpcFBhdGg+CjwvZGVmcz4KPC9zdmc+Cg==';\n\n/**\n * OKX Wallet Connector\n *\n * @see https://www.okx.com/web3/build/docs/sdks/app-connect-overview\n */\nexport class OKXConnector extends BaseConnector {\n readonly id = 'okx';\n readonly name = 'OKX Wallet';\n readonly icon = OKX_ICON;\n\n private _unsubscribeAccounts?: () => void;\n private _unsubscribeNetwork?: () => void;\n\n protected getProvider(): OKXBitcoinProvider | undefined {\n if (typeof window === 'undefined') return undefined;\n return window.okxwallet?.bitcoin;\n }\n\n async connect(): Promise<WalletAccount> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const result = await provider.connect();\n\n this.setupListeners();\n\n return {\n address: result.address,\n publicKey: result.publicKey,\n type: this.inferAddressType(result.address),\n };\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async disconnect(): Promise<void> {\n this._unsubscribeAccounts?.();\n this._unsubscribeNetwork?.();\n this.cleanup();\n }\n\n async getAccounts(): Promise<WalletAccount[]> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const addresses = await provider.getAccounts();\n const publicKey = await provider.getPublicKey();\n\n return addresses.map((address) => ({\n address,\n publicKey,\n type: this.inferAddressType(address),\n }));\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async signMessage(message: string): Promise<string> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n return await provider.signMessage(message);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const okxOptions: OKXSignPsbtOptions = {\n autoFinalized: options?.autoFinalize ?? true,\n };\n\n if (options?.toSignInputs) {\n okxOptions.toSignInputs = options.toSignInputs;\n }\n\n return await provider.signPsbt(psbtHex, okxOptions);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async sendTransaction(to: string, satoshis: number): Promise<string> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n return await provider.sendBitcoin(to, satoshis);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async getNetwork(): Promise<BitcoinNetwork> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const network = await provider.getNetwork();\n return this.mapNetwork(network);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n // OKX does not support switchNetwork via API - users must switch manually in extension\n\n private setupListeners(): void {\n const provider = this.getProvider();\n if (!provider) return;\n\n // accountChanged returns object with address, publicKey, compressedPublicKey\n const handleAccountChanged = (data: OKXAccountChangedData) => {\n const walletAccount: WalletAccount = {\n address: data.address,\n publicKey: data.publicKey,\n type: this.inferAddressType(data.address),\n };\n this.emitAccountsChanged([walletAccount]);\n };\n\n const handleNetworkChanged = (network: string) => {\n const btcNetwork = this.mapNetwork(network);\n this.emitNetworkChanged(btcNetwork);\n };\n\n provider.on('accountChanged', handleAccountChanged);\n provider.on('networkChanged', handleNetworkChanged);\n\n this._unsubscribeAccounts = () => {\n provider.removeListener('accountChanged', handleAccountChanged);\n };\n this._unsubscribeNetwork = () => {\n provider.removeListener('networkChanged', handleNetworkChanged);\n };\n }\n\n private mapNetwork(network: string): BitcoinNetwork {\n switch (network.toLowerCase()) {\n case 'livenet':\n case 'mainnet':\n return 'mainnet';\n case 'testnet':\n return 'testnet';\n case 'testnet4':\n return 'testnet4';\n case 'signet':\n return 'signet';\n default:\n return 'mainnet';\n }\n }\n}\n"]}
|