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,210 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkMFXLQWOE_js = require('./chunk-MFXLQWOE.js');
|
|
4
|
+
|
|
5
|
+
// src/unisat/UnisatConnector.ts
|
|
6
|
+
var UNISAT_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF83MDM3XzkxKSI+CjxwYXRoIGQ9Ik0yMDAgMEgwVjIwMEgyMDBWMFoiIGZpbGw9ImJsYWNrIi8+CjxtYXNrIGlkPSJtYXNrMF83MDM3XzkxIiBzdHlsZT0ibWFzay10eXBlOmx1bWluYW5jZSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeD0iNDEiIHk9IjI0IiB3aWR0aD0iMTE5IiBoZWlnaHQ9IjE1MiI+CjxwYXRoIGQ9Ik0xNTkuNDQ0IDI0SDQxVjE3NS4xMTJIMTU5LjQ0NFYyNFoiIGZpbGw9IndoaXRlIi8+CjwvbWFzaz4KPGcgbWFzaz0idXJsKCNtYXNrMF83MDM3XzkxKSI+CjxwYXRoIGQ9Ik0xMjQuNTQ3IDM3LjU5NjdMMTU1LjU1NyA2OC4zMTAyQzE1OC4xOTcgNzAuOTE5MSAxNTkuNDk2IDczLjU1ODcgMTU5LjQ1NSA3Ni4yMTg3QzE1OS40MTQgNzguODc4OCAxNTguMjc4IDgxLjMwMzUgMTU2LjA1OCA4My41MDMyQzE1My43MzYgODUuODA1MiAxNTEuMjI5IDg2Ljk3MTUgMTQ4LjU0OSA4Ny4wMjI3QzE0NS44NjggODcuMDYzNiAxNDMuMjA4IDg1Ljc3NDUgMTQwLjU2OSA4My4xNjU2TDEwOC44NTIgNTEuNzU2NEMxMDUuMjUxIDQ4LjE4NTggMTAxLjc3MyA0NS42NTg3IDk4LjQyNyA0NC4xNzUyQzk1LjA4MTUgNDIuNjkxNyA5MS41NjIgNDIuNDU2NCA4Ny44Nzg4IDQzLjQ3OTVDODQuMTg1NCA0NC40OTI0IDgwLjIyNiA0Ny4xMDEzIDc1Ljk4MDIgNTEuMjk2QzcwLjEyOCA1Ny4wOTcgNjcuMzM1IDYyLjUzOTkgNjcuNjIxNCA2Ny42MjQ3QzY3LjkwNzkgNzIuNzA5NSA3MC44MTM1IDc3Ljk4ODcgNzYuMzI4IDgzLjQ0MThMMTA4LjMgMTE1LjExN0MxMTAuOTcgMTE3Ljc1NyAxMTIuMjggMTIwLjM5NyAxMTIuMjM5IDEyMy4wMTZDMTEyLjE5OCAxMjUuNjQ1IDExMS4wNTIgMTI4LjA3IDEwOC43OTEgMTMwLjMxQzEwNi41NCAxMzIuNTQxIDEwNC4wNTQgMTMzLjcwNyAxMDEuMzUzIDEzMy43OTlDOTguNjUyMSAxMzMuODkxIDk1Ljk2MTMgMTMyLjYxMiA5My4zMDEzIDEyOS45NzNMNjIuMjkxMSA5OS4yNTlDNTcuMjQ3MiA5NC4yNjYyIDUzLjYwNSA4OS41Mzk1IDUxLjM2NDQgODUuMDc4OEM0OS4xMjM4IDgwLjYxODEgNDguMjg0OCA3NS41NzQyIDQ4Ljg2OCA2OS45NDcxQzQ5LjM4OTggNjUuMTI4MyA1MC45MzQ3IDYwLjQ2MyA1My41MTI5IDU1Ljk0MDlDNTYuMDgwOSA1MS40MTg4IDU5Ljc2NCA0Ni43OTQ0IDY0LjU0MTkgNDIuMDU3NEM3MC4yMzAzIDM2LjQyMDEgNzUuNjYzIDMyLjEwMjcgODAuODM5OSAyOS4wOTQ3Qzg2LjAwNjYgMjYuMDg2OCA5MS4wMDk1IDI0LjQxOTIgOTUuODM4NSAyNC4wNzEzQzEwMC42NzggMjMuNzIzNSAxMDUuNDQ1IDI0LjY4NTIgMTEwLjE2MiAyNi45NTY1QzExNC44NzkgMjkuMjI3NyAxMTkuNjY3IDMyLjc2NzcgMTI0LjUzNyAzNy41OTY3SDEyNC41NDdaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNzAzN185MSkiLz4KPHBhdGggZD0iTTc1Ljg5NzkgMTYxLjUyNUw0NC44OTggMTMwLjgxMkM0Mi4yNTg0IDEyOC4xOTMgNDAuOTU5IDEyNS41NjMgNDEgMTIyLjkwM0M0MS4wNDA5IDEyMC4yNDMgNDIuMTc2NSAxMTcuODE4IDQ0LjM5NjcgMTE1LjYxOUM0Ni43MTkxIDExMy4zMTcgNDkuMjI1NyAxMTIuMTUgNTEuOTA2MiAxMTIuMDk5QzU0LjU4NjcgMTEyLjA1OCA1Ny4yNDY4IDExMy4zMzcgNTkuODg2NCAxMTUuOTU2TDkxLjU5MjMgMTQ3LjM2NUM5NS4yMDM4IDE1MC45MzYgOTguNjcyMSAxNTMuNDYzIDEwMi4wMTggMTU0Ljk0N0MxMDUuMzYzIDE1Ni40MyAxMDguODgzIDE1Ni42NTUgMTEyLjU3NiAxNTUuNjQyQzExNi4yNyAxNTQuNjI5IDEyMC4yMjkgMTUyLjAyMSAxMjQuNDc1IDE0Ny44MTZDMTMwLjMyNyAxNDIuMDE1IDEzMy4xMiAxMzYuNTcyIDEzMi44MzQgMTMxLjQ4N0MxMzIuNTQ3IDEyNi40MDIgMTI5LjY0MSAxMjEuMTIzIDEyNC4xMjcgMTE1LjY2TDEwNy4wOTIgOTguOTMyQzEwNC40MjIgOTYuMjkyNCAxMDMuMTEyIDkzLjY1MjggMTAzLjE1MyA5MS4wMzM2QzEwMy4xOTQgODguNDA0MyAxMDQuMzQgODUuOTc5NSAxMDYuNjAxIDgzLjczODlDMTA4Ljg1MiA4MS41MDg2IDExMS4zMzggODAuMzQyMiAxMTQuMDM5IDgwLjI1MDJDMTE2Ljc0IDgwLjE1ODEgMTE5LjQzMSA4MS40MzcgMTIyLjA5MSA4NC4wNzY2TDEzOC4xNTQgOTkuODQyNUMxNDMuMTk4IDEwNC44MzUgMTQ2Ljg0IDEwOS41NjIgMTQ5LjA4IDExNC4wMjNDMTUxLjMyMSAxMTguNDgzIDE1Mi4xNiAxMjMuNTI3IDE1MS41NzcgMTI5LjE1NEMxNTEuMDU1IDEzMy45NzMgMTQ5LjUxIDEzOC42MzggMTQ2LjkzMiAxNDMuMTYxQzE0NC4zNjQgMTQ3LjY4MyAxNDAuNjgxIDE1Mi4zMDcgMTM1LjkwMyAxNTcuMDQ0QzEzMC4yMTQgMTYyLjY4MSAxMjQuNzgyIDE2Ni45OTkgMTE5LjYwNSAxNzAuMDA3QzExNC40MjggMTczLjAxNSAxMDkuNDI1IDE3NC42OTIgMTA0LjU4NiAxNzUuMDRDOTkuNzQ2NCAxNzUuMzg4IDk0Ljk3ODcgMTc0LjQyNiA5MC4yNjIyIDE3Mi4xNTVDODUuNTQ1OCAxNjkuODg0IDgwLjc1NzYgMTY2LjM0NCA3NS44ODc3IDE2MS41MTVMNzUuODk3OSAxNjEuNTI1WiIgZmlsbD0idXJsKCNwYWludDFfbGluZWFyXzcwMzdfOTEpIi8+CjxwYXRoIGQ9Ik05NS4yMzQzIDgyLjI3NUMxMDEuNTIzIDgyLjI3NSAxMDYuNjIxIDc3LjE3NjggMTA2LjYyMSA3MC44ODc5QzEwNi42MjEgNjQuNTk5IDEwMS41MjMgNTkuNTAwOCA5NS4yMzQzIDU5LjUwMDhDODguOTQ1NCA1OS41MDA4IDgzLjg0NzIgNjQuNTk5IDgzLjg0NzIgNzAuODg3OUM4My44NDcyIDc3LjE3NjggODguOTQ1NCA4Mi4yNzUgOTUuMjM0MyA4Mi4yNzVaIiBmaWxsPSJ1cmwoI3BhaW50Ml9yYWRpYWxfNzAzN185MSkiLz4KPC9nPgo8L2c+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNzAzN185MSIgeDE9IjE1MC40NTciIHkxPSI1NS40OTA1IiB4Mj0iNTQuMzU0OSIgeTI9Ijk4LjE5ODYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzIwMUMxQiIvPgo8c3RvcCBvZmZzZXQ9IjAuMzYiIHN0b3AtY29sb3I9IiM3NzM5MEQiLz4KPHN0b3Agb2Zmc2V0PSIwLjY3IiBzdG9wLWNvbG9yPSIjRUE4MTAxIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0Y0Qjg1MiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MV9saW5lYXJfNzAzN185MSIgeDE9IjUyLjY0NDIiIHkxPSIxNDQuODk3IiB4Mj0iMTY0LjAwOCIgeTI9IjExMS43NTIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzFGMUQxQyIvPgo8c3RvcCBvZmZzZXQ9IjAuMzciIHN0b3AtY29sb3I9IiM3NzM5MEQiLz4KPHN0b3Agb2Zmc2V0PSIwLjY3IiBzdG9wLWNvbG9yPSIjRUE4MTAxIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0Y0RkI1MiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50Ml9yYWRpYWxfNzAzN185MSIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSg5NS4yMzQzIDcwLjg5ODEpIHNjYWxlKDExLjM4NzEgMTEuMzg3MSkiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRjRCODUyIi8+CjxzdG9wIG9mZnNldD0iMC4zMyIgc3RvcC1jb2xvcj0iI0VBODEwMSIvPgo8c3RvcCBvZmZzZXQ9IjAuNjQiIHN0b3AtY29sb3I9IiM3NzM5MEQiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMjExQzFEIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNzAzN185MSI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiByeD0iMzUuNTU1NiIgZmlsbD0id2hpdGUiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K";
|
|
7
|
+
var UnisatConnector = class extends chunkMFXLQWOE_js.BaseConnector {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
this.id = "unisat";
|
|
11
|
+
this.name = "Unisat Wallet";
|
|
12
|
+
this.icon = UNISAT_ICON;
|
|
13
|
+
this.BITCOIN_TESTNET4 = "BITCOIN_TESTNET4";
|
|
14
|
+
}
|
|
15
|
+
getProvider() {
|
|
16
|
+
if (typeof window === "undefined")
|
|
17
|
+
return void 0;
|
|
18
|
+
return window.unisat_wallet;
|
|
19
|
+
}
|
|
20
|
+
async connect(network = "mainnet") {
|
|
21
|
+
this.ensureInstalled();
|
|
22
|
+
const provider = this.getProvider();
|
|
23
|
+
try {
|
|
24
|
+
const initialAccounts = await provider.requestAccounts();
|
|
25
|
+
if (!initialAccounts || initialAccounts.length === 0) {
|
|
26
|
+
throw new Error("No accounts found");
|
|
27
|
+
}
|
|
28
|
+
await this.checkAndSwitchNetwork(provider, network);
|
|
29
|
+
const accounts = await provider.getAccounts();
|
|
30
|
+
const publicKey = await provider.getPublicKey();
|
|
31
|
+
this.setupListeners();
|
|
32
|
+
return {
|
|
33
|
+
address: accounts[0] ?? "",
|
|
34
|
+
publicKey,
|
|
35
|
+
type: this.inferAddressType(accounts[0] ?? "")
|
|
36
|
+
};
|
|
37
|
+
} catch (error) {
|
|
38
|
+
this.handleError(error);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
async disconnect() {
|
|
42
|
+
this._unsubscribeAccounts?.();
|
|
43
|
+
this._unsubscribeNetwork?.();
|
|
44
|
+
this.cleanup();
|
|
45
|
+
}
|
|
46
|
+
async getAccounts() {
|
|
47
|
+
this.ensureInstalled();
|
|
48
|
+
const provider = this.getProvider();
|
|
49
|
+
try {
|
|
50
|
+
const addresses = await provider.getAccounts();
|
|
51
|
+
const publicKey = await provider.getPublicKey();
|
|
52
|
+
return addresses.map((address) => ({
|
|
53
|
+
address,
|
|
54
|
+
publicKey,
|
|
55
|
+
type: this.inferAddressType(address)
|
|
56
|
+
}));
|
|
57
|
+
} catch (error) {
|
|
58
|
+
this.handleError(error);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
async signMessage(message) {
|
|
62
|
+
this.ensureInstalled();
|
|
63
|
+
const provider = this.getProvider();
|
|
64
|
+
try {
|
|
65
|
+
return await provider.signMessage(message);
|
|
66
|
+
} catch (error) {
|
|
67
|
+
this.handleError(error);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async signPsbt(psbtHex, options) {
|
|
71
|
+
this.ensureInstalled();
|
|
72
|
+
const provider = this.getProvider();
|
|
73
|
+
try {
|
|
74
|
+
const unisatOptions = {
|
|
75
|
+
autoFinalized: options?.autoFinalize ?? true
|
|
76
|
+
};
|
|
77
|
+
if (options?.toSignInputs) {
|
|
78
|
+
unisatOptions.toSignInputs = options.toSignInputs;
|
|
79
|
+
}
|
|
80
|
+
return await provider.signPsbt(psbtHex, unisatOptions);
|
|
81
|
+
} catch (error) {
|
|
82
|
+
this.handleError(error);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async signPsbts(psbtHexs, options) {
|
|
86
|
+
this.ensureInstalled();
|
|
87
|
+
const provider = this.getProvider();
|
|
88
|
+
try {
|
|
89
|
+
const unisatOptions = {
|
|
90
|
+
autoFinalized: options?.autoFinalize ?? true
|
|
91
|
+
};
|
|
92
|
+
if (options?.toSignInputs) {
|
|
93
|
+
unisatOptions.toSignInputs = options.toSignInputs;
|
|
94
|
+
}
|
|
95
|
+
const optionsArray = psbtHexs.map(() => unisatOptions);
|
|
96
|
+
return await provider.signPsbts(psbtHexs, optionsArray);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
this.handleError(error);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async sendTransaction(to, satoshis) {
|
|
102
|
+
this.ensureInstalled();
|
|
103
|
+
const provider = this.getProvider();
|
|
104
|
+
try {
|
|
105
|
+
return await provider.sendBitcoin(to, satoshis);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
this.handleError(error);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async getNetwork() {
|
|
111
|
+
this.ensureInstalled();
|
|
112
|
+
const provider = this.getProvider();
|
|
113
|
+
try {
|
|
114
|
+
const network = await provider.getNetwork();
|
|
115
|
+
return this.mapNetwork(network);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
this.handleError(error);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
async switchNetwork(network) {
|
|
121
|
+
this.ensureInstalled();
|
|
122
|
+
const provider = this.getProvider();
|
|
123
|
+
try {
|
|
124
|
+
const unisatNetwork = this.mapToUnisatNetwork(network);
|
|
125
|
+
await provider.switchNetwork(unisatNetwork);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
this.handleError(error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
async checkAndSwitchNetwork(provider, network) {
|
|
131
|
+
const currentNetwork = await provider.getNetwork();
|
|
132
|
+
const targetNetwork = this.mapToUnisatNetwork(network);
|
|
133
|
+
if (currentNetwork !== targetNetwork) {
|
|
134
|
+
await provider.switchNetwork(targetNetwork);
|
|
135
|
+
}
|
|
136
|
+
if (network === "testnet4") {
|
|
137
|
+
const currentChain = await provider.getChain();
|
|
138
|
+
if (currentChain.enum !== this.BITCOIN_TESTNET4) {
|
|
139
|
+
await provider.switchChain(this.BITCOIN_TESTNET4);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
setupListeners() {
|
|
144
|
+
const provider = this.getProvider();
|
|
145
|
+
if (!provider)
|
|
146
|
+
return;
|
|
147
|
+
const handleAccountsChanged = (arg) => {
|
|
148
|
+
const accounts = arg;
|
|
149
|
+
if (!Array.isArray(accounts) || accounts.length === 0) {
|
|
150
|
+
this.emitAccountsChanged([]);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
provider.getPublicKey().then((publicKey) => {
|
|
154
|
+
const walletAccounts = accounts.map((address) => ({
|
|
155
|
+
address,
|
|
156
|
+
publicKey,
|
|
157
|
+
type: this.inferAddressType(address)
|
|
158
|
+
}));
|
|
159
|
+
this.emitAccountsChanged(walletAccounts);
|
|
160
|
+
}).catch(() => {
|
|
161
|
+
this.emitAccountsChanged([]);
|
|
162
|
+
});
|
|
163
|
+
};
|
|
164
|
+
const handleNetworkChanged = (arg) => {
|
|
165
|
+
const network = arg;
|
|
166
|
+
const btcNetwork = this.mapNetwork(network);
|
|
167
|
+
this.emitNetworkChanged(btcNetwork);
|
|
168
|
+
};
|
|
169
|
+
provider.on("accountsChanged", handleAccountsChanged);
|
|
170
|
+
provider.on("networkChanged", handleNetworkChanged);
|
|
171
|
+
this._unsubscribeAccounts = () => {
|
|
172
|
+
provider.removeListener("accountsChanged", handleAccountsChanged);
|
|
173
|
+
};
|
|
174
|
+
this._unsubscribeNetwork = () => {
|
|
175
|
+
provider.removeListener("networkChanged", handleNetworkChanged);
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
mapNetwork(network) {
|
|
179
|
+
switch (network.toLowerCase()) {
|
|
180
|
+
case "livenet":
|
|
181
|
+
case "mainnet":
|
|
182
|
+
return "mainnet";
|
|
183
|
+
case "testnet":
|
|
184
|
+
return "testnet";
|
|
185
|
+
case "testnet4":
|
|
186
|
+
return "testnet4";
|
|
187
|
+
case "signet":
|
|
188
|
+
return "signet";
|
|
189
|
+
default:
|
|
190
|
+
return "mainnet";
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
mapToUnisatNetwork(network) {
|
|
194
|
+
switch (network) {
|
|
195
|
+
case "mainnet":
|
|
196
|
+
return "livenet";
|
|
197
|
+
case "testnet":
|
|
198
|
+
case "testnet4":
|
|
199
|
+
return "testnet";
|
|
200
|
+
case "signet":
|
|
201
|
+
return "signet";
|
|
202
|
+
default:
|
|
203
|
+
return "livenet";
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
exports.UnisatConnector = UnisatConnector;
|
|
209
|
+
//# sourceMappingURL=out.js.map
|
|
210
|
+
//# sourceMappingURL=chunk-Q7QVQYEB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/unisat/UnisatConnector.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 * Unisat network types\n * @see https://docs.unisat.io/dev/unisat-developer-service/unisat-wallet#switchnetwork\n */\ntype UnisatNetwork = 'livenet' | 'testnet' | 'testnet4' | 'signet';\n\n// Unisat wallet provider type\ninterface UnisatProvider {\n requestAccounts(): Promise<string[]>;\n getAccounts(): Promise<string[]>;\n getPublicKey(): Promise<string>;\n getNetwork(): Promise<string>;\n getChain(): Promise<{\n enum: string\n name: string\n network: string\n }>\n switchChain(chain: string): Promise<{\n enum: string\n name: string\n network: string\n }>\n switchNetwork(network: UnisatNetwork): Promise<void>;\n signMessage(message: string, type?: string): Promise<string>;\n signPsbt(psbtHex: string, options?: UnisatSignOptions): Promise<string>;\n signPsbts(psbtHexs: string[], options?: UnisatSignOptions[]): Promise<string[]>;\n sendBitcoin(to: string, satoshis: number, options?: object): Promise<string>;\n on(event: string, callback: (arg: unknown) => void): void;\n removeListener(event: string, callback: (arg: unknown) => void): void;\n}\n\ninterface UnisatSignOptions {\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// Extend window type\ndeclare global {\n interface Window {\n unisat_wallet?: UnisatProvider;\n }\n}\n\n// Unisat wallet icon (SVG as base64)\nconst UNISAT_ICON =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF83MDM3XzkxKSI+CjxwYXRoIGQ9Ik0yMDAgMEgwVjIwMEgyMDBWMFoiIGZpbGw9ImJsYWNrIi8+CjxtYXNrIGlkPSJtYXNrMF83MDM3XzkxIiBzdHlsZT0ibWFzay10eXBlOmx1bWluYW5jZSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeD0iNDEiIHk9IjI0IiB3aWR0aD0iMTE5IiBoZWlnaHQ9IjE1MiI+CjxwYXRoIGQ9Ik0xNTkuNDQ0IDI0SDQxVjE3NS4xMTJIMTU5LjQ0NFYyNFoiIGZpbGw9IndoaXRlIi8+CjwvbWFzaz4KPGcgbWFzaz0idXJsKCNtYXNrMF83MDM3XzkxKSI+CjxwYXRoIGQ9Ik0xMjQuNTQ3IDM3LjU5NjdMMTU1LjU1NyA2OC4zMTAyQzE1OC4xOTcgNzAuOTE5MSAxNTkuNDk2IDczLjU1ODcgMTU5LjQ1NSA3Ni4yMTg3QzE1OS40MTQgNzguODc4OCAxNTguMjc4IDgxLjMwMzUgMTU2LjA1OCA4My41MDMyQzE1My43MzYgODUuODA1MiAxNTEuMjI5IDg2Ljk3MTUgMTQ4LjU0OSA4Ny4wMjI3QzE0NS44NjggODcuMDYzNiAxNDMuMjA4IDg1Ljc3NDUgMTQwLjU2OSA4My4xNjU2TDEwOC44NTIgNTEuNzU2NEMxMDUuMjUxIDQ4LjE4NTggMTAxLjc3MyA0NS42NTg3IDk4LjQyNyA0NC4xNzUyQzk1LjA4MTUgNDIuNjkxNyA5MS41NjIgNDIuNDU2NCA4Ny44Nzg4IDQzLjQ3OTVDODQuMTg1NCA0NC40OTI0IDgwLjIyNiA0Ny4xMDEzIDc1Ljk4MDIgNTEuMjk2QzcwLjEyOCA1Ny4wOTcgNjcuMzM1IDYyLjUzOTkgNjcuNjIxNCA2Ny42MjQ3QzY3LjkwNzkgNzIuNzA5NSA3MC44MTM1IDc3Ljk4ODcgNzYuMzI4IDgzLjQ0MThMMTA4LjMgMTE1LjExN0MxMTAuOTcgMTE3Ljc1NyAxMTIuMjggMTIwLjM5NyAxMTIuMjM5IDEyMy4wMTZDMTEyLjE5OCAxMjUuNjQ1IDExMS4wNTIgMTI4LjA3IDEwOC43OTEgMTMwLjMxQzEwNi41NCAxMzIuNTQxIDEwNC4wNTQgMTMzLjcwNyAxMDEuMzUzIDEzMy43OTlDOTguNjUyMSAxMzMuODkxIDk1Ljk2MTMgMTMyLjYxMiA5My4zMDEzIDEyOS45NzNMNjIuMjkxMSA5OS4yNTlDNTcuMjQ3MiA5NC4yNjYyIDUzLjYwNSA4OS41Mzk1IDUxLjM2NDQgODUuMDc4OEM0OS4xMjM4IDgwLjYxODEgNDguMjg0OCA3NS41NzQyIDQ4Ljg2OCA2OS45NDcxQzQ5LjM4OTggNjUuMTI4MyA1MC45MzQ3IDYwLjQ2MyA1My41MTI5IDU1Ljk0MDlDNTYuMDgwOSA1MS40MTg4IDU5Ljc2NCA0Ni43OTQ0IDY0LjU0MTkgNDIuMDU3NEM3MC4yMzAzIDM2LjQyMDEgNzUuNjYzIDMyLjEwMjcgODAuODM5OSAyOS4wOTQ3Qzg2LjAwNjYgMjYuMDg2OCA5MS4wMDk1IDI0LjQxOTIgOTUuODM4NSAyNC4wNzEzQzEwMC42NzggMjMuNzIzNSAxMDUuNDQ1IDI0LjY4NTIgMTEwLjE2MiAyNi45NTY1QzExNC44NzkgMjkuMjI3NyAxMTkuNjY3IDMyLjc2NzcgMTI0LjUzNyAzNy41OTY3SDEyNC41NDdaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNzAzN185MSkiLz4KPHBhdGggZD0iTTc1Ljg5NzkgMTYxLjUyNUw0NC44OTggMTMwLjgxMkM0Mi4yNTg0IDEyOC4xOTMgNDAuOTU5IDEyNS41NjMgNDEgMTIyLjkwM0M0MS4wNDA5IDEyMC4yNDMgNDIuMTc2NSAxMTcuODE4IDQ0LjM5NjcgMTE1LjYxOUM0Ni43MTkxIDExMy4zMTcgNDkuMjI1NyAxMTIuMTUgNTEuOTA2MiAxMTIuMDk5QzU0LjU4NjcgMTEyLjA1OCA1Ny4yNDY4IDExMy4zMzcgNTkuODg2NCAxMTUuOTU2TDkxLjU5MjMgMTQ3LjM2NUM5NS4yMDM4IDE1MC45MzYgOTguNjcyMSAxNTMuNDYzIDEwMi4wMTggMTU0Ljk0N0MxMDUuMzYzIDE1Ni40MyAxMDguODgzIDE1Ni42NTUgMTEyLjU3NiAxNTUuNjQyQzExNi4yNyAxNTQuNjI5IDEyMC4yMjkgMTUyLjAyMSAxMjQuNDc1IDE0Ny44MTZDMTMwLjMyNyAxNDIuMDE1IDEzMy4xMiAxMzYuNTcyIDEzMi44MzQgMTMxLjQ4N0MxMzIuNTQ3IDEyNi40MDIgMTI5LjY0MSAxMjEuMTIzIDEyNC4xMjcgMTE1LjY2TDEwNy4wOTIgOTguOTMyQzEwNC40MjIgOTYuMjkyNCAxMDMuMTEyIDkzLjY1MjggMTAzLjE1MyA5MS4wMzM2QzEwMy4xOTQgODguNDA0MyAxMDQuMzQgODUuOTc5NSAxMDYuNjAxIDgzLjczODlDMTA4Ljg1MiA4MS41MDg2IDExMS4zMzggODAuMzQyMiAxMTQuMDM5IDgwLjI1MDJDMTE2Ljc0IDgwLjE1ODEgMTE5LjQzMSA4MS40MzcgMTIyLjA5MSA4NC4wNzY2TDEzOC4xNTQgOTkuODQyNUMxNDMuMTk4IDEwNC44MzUgMTQ2Ljg0IDEwOS41NjIgMTQ5LjA4IDExNC4wMjNDMTUxLjMyMSAxMTguNDgzIDE1Mi4xNiAxMjMuNTI3IDE1MS41NzcgMTI5LjE1NEMxNTEuMDU1IDEzMy45NzMgMTQ5LjUxIDEzOC42MzggMTQ2LjkzMiAxNDMuMTYxQzE0NC4zNjQgMTQ3LjY4MyAxNDAuNjgxIDE1Mi4zMDcgMTM1LjkwMyAxNTcuMDQ0QzEzMC4yMTQgMTYyLjY4MSAxMjQuNzgyIDE2Ni45OTkgMTE5LjYwNSAxNzAuMDA3QzExNC40MjggMTczLjAxNSAxMDkuNDI1IDE3NC42OTIgMTA0LjU4NiAxNzUuMDRDOTkuNzQ2NCAxNzUuMzg4IDk0Ljk3ODcgMTc0LjQyNiA5MC4yNjIyIDE3Mi4xNTVDODUuNTQ1OCAxNjkuODg0IDgwLjc1NzYgMTY2LjM0NCA3NS44ODc3IDE2MS41MTVMNzUuODk3OSAxNjEuNTI1WiIgZmlsbD0idXJsKCNwYWludDFfbGluZWFyXzcwMzdfOTEpIi8+CjxwYXRoIGQ9Ik05NS4yMzQzIDgyLjI3NUMxMDEuNTIzIDgyLjI3NSAxMDYuNjIxIDc3LjE3NjggMTA2LjYyMSA3MC44ODc5QzEwNi42MjEgNjQuNTk5IDEwMS41MjMgNTkuNTAwOCA5NS4yMzQzIDU5LjUwMDhDODguOTQ1NCA1OS41MDA4IDgzLjg0NzIgNjQuNTk5IDgzLjg0NzIgNzAuODg3OUM4My44NDcyIDc3LjE3NjggODguOTQ1NCA4Mi4yNzUgOTUuMjM0MyA4Mi4yNzVaIiBmaWxsPSJ1cmwoI3BhaW50Ml9yYWRpYWxfNzAzN185MSkiLz4KPC9nPgo8L2c+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfNzAzN185MSIgeDE9IjE1MC40NTciIHkxPSI1NS40OTA1IiB4Mj0iNTQuMzU0OSIgeTI9Ijk4LjE5ODYiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzIwMUMxQiIvPgo8c3RvcCBvZmZzZXQ9IjAuMzYiIHN0b3AtY29sb3I9IiM3NzM5MEQiLz4KPHN0b3Agb2Zmc2V0PSIwLjY3IiBzdG9wLWNvbG9yPSIjRUE4MTAxIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0Y0Qjg1MiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MV9saW5lYXJfNzAzN185MSIgeDE9IjUyLjY0NDIiIHkxPSIxNDQuODk3IiB4Mj0iMTY0LjAwOCIgeTI9IjExMS43NTIiIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agc3RvcC1jb2xvcj0iIzFGMUQxQyIvPgo8c3RvcCBvZmZzZXQ9IjAuMzciIHN0b3AtY29sb3I9IiM3NzM5MEQiLz4KPHN0b3Agb2Zmc2V0PSIwLjY3IiBzdG9wLWNvbG9yPSIjRUE4MTAxIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iI0Y0RkI1MiIvPgo8L2xpbmVhckdyYWRpZW50Pgo8cmFkaWFsR3JhZGllbnQgaWQ9InBhaW50Ml9yYWRpYWxfNzAzN185MSIgY3g9IjAiIGN5PSIwIiByPSIxIiBncmFkaWVudFVuaXRzPSJ1c2VyU3BhY2VPblVzZSIgZ3JhZGllbnRUcmFuc2Zvcm09InRyYW5zbGF0ZSg5NS4yMzQzIDcwLjg5ODEpIHNjYWxlKDExLjM4NzEgMTEuMzg3MSkiPgo8c3RvcCBzdG9wLWNvbG9yPSIjRjRCODUyIi8+CjxzdG9wIG9mZnNldD0iMC4zMyIgc3RvcC1jb2xvcj0iI0VBODEwMSIvPgo8c3RvcCBvZmZzZXQ9IjAuNjQiIHN0b3AtY29sb3I9IiM3NzM5MEQiLz4KPHN0b3Agb2Zmc2V0PSIxIiBzdG9wLWNvbG9yPSIjMjExQzFEIi8+CjwvcmFkaWFsR3JhZGllbnQ+CjxjbGlwUGF0aCBpZD0iY2xpcDBfNzAzN185MSI+CjxyZWN0IHdpZHRoPSIyMDAiIGhlaWdodD0iMjAwIiByeD0iMzUuNTU1NiIgZmlsbD0id2hpdGUiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K';\n\n/**\n * Unisat Wallet Connector\n *\n * @see https://docs.unisat.io/dev/unisat-developer-service/unisat-wallet\n */\nexport class UnisatConnector extends BaseConnector {\n readonly id = 'unisat';\n readonly name = 'Unisat Wallet';\n readonly icon = UNISAT_ICON;\n readonly BITCOIN_TESTNET4 = 'BITCOIN_TESTNET4'\n private _unsubscribeAccounts?: () => void;\n private _unsubscribeNetwork?: () => void;\n\n protected getProvider(): UnisatProvider | undefined {\n if (typeof window === 'undefined') return undefined;\n return window.unisat_wallet;\n }\n\n async connect(network: BitcoinNetwork = 'mainnet'): Promise<WalletAccount> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n // First request accounts to trigger wallet popup\n const initialAccounts = await provider.requestAccounts();\n if (!initialAccounts || initialAccounts.length === 0) {\n throw new Error('No accounts found');\n }\n\n // Switch network if needed\n await this.checkAndSwitchNetwork(provider, network);\n\n // Get accounts AFTER network switch (address changes per network)\n const accounts = await provider.getAccounts();\n const publicKey = await provider.getPublicKey();\n\n // Setup event listeners\n this.setupListeners();\n\n return {\n address: accounts[0] ?? '',\n publicKey,\n type: this.inferAddressType(accounts[0] ?? ''),\n };\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async disconnect(): Promise<void> {\n // Unisat doesn't have a disconnect method, just cleanup listeners\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 unisatOptions: UnisatSignOptions = {\n autoFinalized: options?.autoFinalize ?? true,\n };\n\n // Only add toSignInputs if defined\n if (options?.toSignInputs) {\n unisatOptions.toSignInputs = options.toSignInputs;\n }\n return await provider.signPsbt(psbtHex, unisatOptions);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async signPsbts(\n psbtHexs: string[],\n options?: SignPsbtOptions\n ): Promise<string[]> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const unisatOptions: UnisatSignOptions = {\n autoFinalized: options?.autoFinalize ?? true,\n };\n\n // Only add toSignInputs if defined\n if (options?.toSignInputs) {\n unisatOptions.toSignInputs = options.toSignInputs;\n }\n\n // Create options array for each PSBT\n const optionsArray = psbtHexs.map(() => unisatOptions);\n\n return await provider.signPsbts(psbtHexs, optionsArray);\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 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 async switchNetwork(network: BitcoinNetwork): Promise<void> {\n this.ensureInstalled();\n const provider = this.getProvider()!;\n\n try {\n const unisatNetwork = this.mapToUnisatNetwork(network);\n await provider.switchNetwork(unisatNetwork);\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async checkAndSwitchNetwork(provider: UnisatProvider, network: BitcoinNetwork): Promise<void> {\n const currentNetwork = await provider.getNetwork();\n const targetNetwork = this.mapToUnisatNetwork(network);\n if (currentNetwork !== targetNetwork) {\n await provider.switchNetwork(targetNetwork);\n }\n // testnet4 requires additional chain switch\n if (network === 'testnet4') {\n const currentChain = await provider.getChain();\n if (currentChain.enum !== this.BITCOIN_TESTNET4) {\n await provider.switchChain(this.BITCOIN_TESTNET4);\n }\n }\n }\n\n private setupListeners(): void {\n const provider = this.getProvider();\n if (!provider) return;\n\n // Account change listener - wrap to handle unknown arg type\n const handleAccountsChanged = (arg: unknown) => {\n const accounts = arg as string[];\n if (!Array.isArray(accounts) || accounts.length === 0) {\n this.emitAccountsChanged([]);\n return;\n }\n\n provider.getPublicKey().then((publicKey) => {\n const walletAccounts: WalletAccount[] = accounts.map((address) => ({\n address,\n publicKey,\n type: this.inferAddressType(address),\n }));\n this.emitAccountsChanged(walletAccounts);\n }).catch(() => {\n // If we can't get public key, emit empty to trigger disconnect\n this.emitAccountsChanged([]);\n });\n };\n\n // Network change listener\n const handleNetworkChanged = (arg: unknown) => {\n const network = arg as string;\n const btcNetwork = this.mapNetwork(network);\n this.emitNetworkChanged(btcNetwork);\n };\n\n provider.on('accountsChanged', handleAccountsChanged);\n provider.on('networkChanged', handleNetworkChanged);\n\n this._unsubscribeAccounts = () => {\n provider.removeListener('accountsChanged', handleAccountsChanged);\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 private mapToUnisatNetwork(network: BitcoinNetwork): UnisatNetwork {\n switch (network) {\n case 'mainnet':\n return 'livenet';\n case 'testnet':\n case 'testnet4':\n return 'testnet';\n case 'signet':\n return 'signet';\n default:\n return 'livenet';\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { BaseConnector } from './chunk-5Z5Q2Y75.mjs';
|
|
2
|
+
|
|
3
|
+
// src/xverse/XverseConnector.ts
|
|
4
|
+
var XVERSE_ICON = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF83MDM3XzEwMykiPgo8cGF0aCBkPSJNMjAwIDBIMFYyMDBIMjAwVjBaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNzAzN18xMDMpIi8+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMV83MDM3XzEwMykiPgo8cGF0aCBkPSJNMTU5LjM2NyAxNTcuNDQ1VjEzNS43MThDMTU5LjM2NyAxMzQuODU2IDE1OS4wMjUgMTM0LjAzNCAxNTguNDE0IDEzMy40MjRMNjUuOTY2NCA0MC45NzU2QzY1LjM1NTkgNDAuMzY1MSA2NC41MzQyIDQwLjAyMjggNjMuNjcyNiA0MC4wMjI4SDQxLjk0NTZDNDAuODczIDQwLjAyMjggNDAgNDAuODk1NyA0MCA0MS45Njg0VjYyLjE1NDlDNDAgNjMuMDE2NSA0MC4zNDIzIDYzLjgzOCA0MC45NTI4IDY0LjQ0ODZMNzQuMTM2OCA5Ny42MzI0Qzc0Ljg5NTYgOTguMzkxNiA3NC44OTU2IDk5LjYyNCA3NC4xMzY4IDEwMC4zODNMNDAuNTcwNiAxMzMuOTQ5QzQwLjIwNTQgMTM0LjMxNCA0MCAxMzQuODEgNDAgMTM1LjMyNFYxNTcuNDQ1QzQwIDE1OC41MTcgNDAuODczIDE1OS4zOTEgNDEuOTQ1NiAxNTkuMzkxSDc4LjI1MDVDNzkuMzIzMiAxNTkuMzkxIDgwLjE5NiAxNTguNTE3IDgwLjE5NiAxNTcuNDQ1VjE0NC40MTNDODAuMTk2IDE0My45IDgwLjQwMTYgMTQzLjQwMyA4MC43NjY4IDE0My4wMzhMOTguNzczNiAxMjUuMDMxQzk5LjUzMjQgMTI0LjI3MiAxMDAuNzY1IDEyNC4yNzIgMTAxLjUyNCAxMjUuMDMxTDEzNC45MzYgMTU4LjQ0NEMxMzUuNTQ2IDE1OS4wNTQgMTM2LjM2OCAxNTkuMzk2IDEzNy4yMyAxNTkuMzk2SDE1Ny40MTZDMTU4LjQ4OSAxNTkuMzk2IDE1OS4zNjIgMTU4LjUyMyAxNTkuMzYyIDE1Ny40NTFMMTU5LjM2NyAxNTcuNDQ1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExMC45MzggNjguNzk2SDEyOS4xMjJDMTMwLjIgNjguNzk2IDEzMS4wNzkgNjkuNjc0NyAxMzEuMDc5IDcwLjc1MzFWODguOTM2OEMxMzEuMDc5IDkwLjY4MjggMTMzLjE5IDkxLjU1NiAxMzQuNDIyIDkwLjMxNzZMMTU5LjM2NyA2NS4zMzI4QzE1OS43MzIgNjQuOTY3NiAxNTkuOTM4IDY0LjQ3MTMgMTU5LjkzOCA2My45NTJWNDIuMDcwOUMxNTkuOTM4IDQwLjk5MjUgMTU5LjA2NCA0MC4xMTM5IDE1Ny45ODEgNDAuMTEzOUwxMzUuNzc0IDQwLjA4NTRDMTM1LjI1NiA0MC4wODU0IDEzNC43NTkgNDAuMjkwOCAxMzQuMzg4IDQwLjY1NTlMMTA5LjU1MiA2NS40NTI2QzEwOC4zMTkgNjYuNjg1IDEwOS4xOTIgNjguNzk2IDExMC45MzIgNjguNzk2SDExMC45MzhaIiBmaWxsPSIjRUU3QTMwIi8+CjwvZz4KPC9nPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzcwMzdfMTAzIiB4MT0iMTAwIiB5MT0iMCIgeDI9IjEwMCIgeTI9IjIwMCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMEYwRjBGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzE4MTgxOCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzcwMzdfMTAzIj4KPHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHJ4PSIzNS41NTU2IiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8Y2xpcFBhdGggaWQ9ImNsaXAxXzcwMzdfMTAzIj4KPHJlY3Qgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxMjAiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MCA0MCkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K";
|
|
5
|
+
var XverseConnector = class extends BaseConnector {
|
|
6
|
+
constructor() {
|
|
7
|
+
super(...arguments);
|
|
8
|
+
this.id = "xverse";
|
|
9
|
+
this.name = "Xverse Wallet";
|
|
10
|
+
this.icon = XVERSE_ICON;
|
|
11
|
+
this._paymentAddress = null;
|
|
12
|
+
this._ordinalsAddress = null;
|
|
13
|
+
this._network = "mainnet";
|
|
14
|
+
this._accounts = [];
|
|
15
|
+
this._removeAccountChangeListener = null;
|
|
16
|
+
this._removeNetworkChangeListener = null;
|
|
17
|
+
this._removeDisconnectedListener = null;
|
|
18
|
+
}
|
|
19
|
+
getProvider() {
|
|
20
|
+
if (typeof window === "undefined")
|
|
21
|
+
return void 0;
|
|
22
|
+
return window.XverseProviders?.BitcoinProvider;
|
|
23
|
+
}
|
|
24
|
+
async connect(network = "mainnet") {
|
|
25
|
+
const provider = this.getProvider();
|
|
26
|
+
if (!provider) {
|
|
27
|
+
this.handleError(new Error("Xverse Wallet is not installed"));
|
|
28
|
+
}
|
|
29
|
+
try {
|
|
30
|
+
this._network = network;
|
|
31
|
+
const permissionResponse = await provider.request("wallet_requestPermissions", void 0);
|
|
32
|
+
if (permissionResponse.error) {
|
|
33
|
+
throw new Error(permissionResponse.error.message);
|
|
34
|
+
}
|
|
35
|
+
const response = await provider.request("getAddresses", {
|
|
36
|
+
purposes: ["payment" /* Payment */, "ordinals" /* Ordinals */],
|
|
37
|
+
message: "Connect to application"
|
|
38
|
+
});
|
|
39
|
+
if (response.error) {
|
|
40
|
+
throw response.error;
|
|
41
|
+
}
|
|
42
|
+
const addresses = response.result.addresses;
|
|
43
|
+
this._accounts = addresses;
|
|
44
|
+
const paymentAddr = addresses.find((a) => a.purpose === "payment" /* Payment */);
|
|
45
|
+
const ordinalsAddr = addresses.find((a) => a.purpose === "ordinals" /* Ordinals */);
|
|
46
|
+
if (paymentAddr) {
|
|
47
|
+
this._paymentAddress = {
|
|
48
|
+
address: paymentAddr.address,
|
|
49
|
+
publicKey: paymentAddr.publicKey,
|
|
50
|
+
type: this.inferAddressType(paymentAddr.address)
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
if (ordinalsAddr) {
|
|
54
|
+
this._ordinalsAddress = {
|
|
55
|
+
address: ordinalsAddr.address,
|
|
56
|
+
publicKey: ordinalsAddr.publicKey,
|
|
57
|
+
type: this.inferAddressType(ordinalsAddr.address)
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
await this.checkAndSwitchNetwork(network);
|
|
61
|
+
this.setupEventListeners();
|
|
62
|
+
if (!this._paymentAddress) {
|
|
63
|
+
throw new Error("No payment address found");
|
|
64
|
+
}
|
|
65
|
+
return this._paymentAddress;
|
|
66
|
+
} catch (error) {
|
|
67
|
+
this.handleError(error);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
async checkAndSwitchNetwork(network) {
|
|
71
|
+
const provider = this.getProvider();
|
|
72
|
+
if (!provider)
|
|
73
|
+
return;
|
|
74
|
+
if (network === "testnet4") {
|
|
75
|
+
try {
|
|
76
|
+
const currentNetwork = await provider.request("wallet_getNetwork", null);
|
|
77
|
+
if (currentNetwork?.result?.bitcoin?.name !== "Testnet4") {
|
|
78
|
+
await provider.request("wallet_changeNetwork", { name: "Testnet4" });
|
|
79
|
+
}
|
|
80
|
+
} catch {
|
|
81
|
+
}
|
|
82
|
+
} else if (network === "testnet") {
|
|
83
|
+
try {
|
|
84
|
+
const currentNetwork = await provider.request("wallet_getNetwork", null);
|
|
85
|
+
if (currentNetwork?.result?.bitcoin?.name !== "Testnet") {
|
|
86
|
+
await provider.request("wallet_changeNetwork", { name: "Testnet" });
|
|
87
|
+
}
|
|
88
|
+
} catch {
|
|
89
|
+
}
|
|
90
|
+
} else if (network === "mainnet") {
|
|
91
|
+
try {
|
|
92
|
+
const currentNetwork = await provider.request("wallet_getNetwork", null);
|
|
93
|
+
if (currentNetwork?.result?.bitcoin?.name !== "Mainnet") {
|
|
94
|
+
await provider.request("wallet_changeNetwork", { name: "Mainnet" });
|
|
95
|
+
}
|
|
96
|
+
} catch {
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
setupEventListeners() {
|
|
101
|
+
const provider = this.getProvider();
|
|
102
|
+
if (!provider || typeof provider.addListener !== "function")
|
|
103
|
+
return;
|
|
104
|
+
this.removeEventListeners();
|
|
105
|
+
this._removeAccountChangeListener = provider.addListener("accountChange", async () => {
|
|
106
|
+
await this.handleAccountChange();
|
|
107
|
+
});
|
|
108
|
+
this._removeNetworkChangeListener = provider.addListener("networkChange", async (event) => {
|
|
109
|
+
await this.handleNetworkChange(event);
|
|
110
|
+
});
|
|
111
|
+
this._removeDisconnectedListener = provider.addListener("accountDisconnected", () => {
|
|
112
|
+
this.emitAccountsChanged([]);
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
async handleAccountChange() {
|
|
116
|
+
const provider = this.getProvider();
|
|
117
|
+
if (!provider)
|
|
118
|
+
return;
|
|
119
|
+
try {
|
|
120
|
+
const response = await provider.request("getAddresses", {
|
|
121
|
+
purposes: ["payment" /* Payment */, "ordinals" /* Ordinals */]
|
|
122
|
+
});
|
|
123
|
+
if (!response.error && response.result?.addresses?.length) {
|
|
124
|
+
this._accounts = response.result.addresses;
|
|
125
|
+
const paymentAddr = response.result.addresses.find((a) => a.purpose === "payment" /* Payment */);
|
|
126
|
+
if (paymentAddr) {
|
|
127
|
+
this._paymentAddress = {
|
|
128
|
+
address: paymentAddr.address,
|
|
129
|
+
publicKey: paymentAddr.publicKey,
|
|
130
|
+
type: this.inferAddressType(paymentAddr.address)
|
|
131
|
+
};
|
|
132
|
+
const accounts = response.result.addresses.map((addr) => ({
|
|
133
|
+
address: addr.address,
|
|
134
|
+
publicKey: addr.publicKey,
|
|
135
|
+
type: this.inferAddressType(addr.address)
|
|
136
|
+
}));
|
|
137
|
+
this.emitAccountsChanged(accounts);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
} catch (error) {
|
|
141
|
+
console.error("Error handling account change:", error);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async handleNetworkChange(event) {
|
|
145
|
+
if (!event.network)
|
|
146
|
+
return;
|
|
147
|
+
const networkMap = {
|
|
148
|
+
"Mainnet": "mainnet",
|
|
149
|
+
"Testnet": "testnet",
|
|
150
|
+
"Testnet4": "testnet4",
|
|
151
|
+
"Signet": "signet"
|
|
152
|
+
};
|
|
153
|
+
const mappedNetwork = networkMap[event.network] || "mainnet";
|
|
154
|
+
if (mappedNetwork !== this._network) {
|
|
155
|
+
this._network = mappedNetwork;
|
|
156
|
+
this.emitNetworkChanged(mappedNetwork);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
removeEventListeners() {
|
|
160
|
+
this._removeAccountChangeListener?.();
|
|
161
|
+
this._removeAccountChangeListener = null;
|
|
162
|
+
this._removeNetworkChangeListener?.();
|
|
163
|
+
this._removeNetworkChangeListener = null;
|
|
164
|
+
this._removeDisconnectedListener?.();
|
|
165
|
+
this._removeDisconnectedListener = null;
|
|
166
|
+
}
|
|
167
|
+
async disconnect() {
|
|
168
|
+
const provider = this.getProvider();
|
|
169
|
+
try {
|
|
170
|
+
if (provider) {
|
|
171
|
+
await provider.request("wallet_renouncePermissions", void 0);
|
|
172
|
+
}
|
|
173
|
+
} catch {
|
|
174
|
+
} finally {
|
|
175
|
+
this.removeEventListeners();
|
|
176
|
+
this._paymentAddress = null;
|
|
177
|
+
this._ordinalsAddress = null;
|
|
178
|
+
this._accounts = [];
|
|
179
|
+
this.cleanup();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
async getAccounts() {
|
|
183
|
+
const accounts = [];
|
|
184
|
+
if (this._paymentAddress)
|
|
185
|
+
accounts.push(this._paymentAddress);
|
|
186
|
+
if (this._ordinalsAddress)
|
|
187
|
+
accounts.push(this._ordinalsAddress);
|
|
188
|
+
return accounts;
|
|
189
|
+
}
|
|
190
|
+
async signMessage(message) {
|
|
191
|
+
const provider = this.getProvider();
|
|
192
|
+
if (!provider) {
|
|
193
|
+
throw new Error("Xverse Wallet is not installed");
|
|
194
|
+
}
|
|
195
|
+
if (!this._paymentAddress) {
|
|
196
|
+
throw new Error("Not connected");
|
|
197
|
+
}
|
|
198
|
+
try {
|
|
199
|
+
const response = await provider.request("signMessage", {
|
|
200
|
+
address: this._paymentAddress.address,
|
|
201
|
+
message
|
|
202
|
+
});
|
|
203
|
+
if (response.error) {
|
|
204
|
+
throw response.error;
|
|
205
|
+
}
|
|
206
|
+
return response.result.signature;
|
|
207
|
+
} catch (error) {
|
|
208
|
+
this.handleError(error);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async signPsbt(psbtHex, options) {
|
|
212
|
+
const provider = this.getProvider();
|
|
213
|
+
if (!provider) {
|
|
214
|
+
throw new Error("Xverse Wallet is not installed");
|
|
215
|
+
}
|
|
216
|
+
if (!this._paymentAddress) {
|
|
217
|
+
throw new Error("Not connected");
|
|
218
|
+
}
|
|
219
|
+
try {
|
|
220
|
+
const psbtBase64 = Buffer.from(psbtHex, "hex").toString("base64");
|
|
221
|
+
const signInputs = {};
|
|
222
|
+
const allAddresses = this._accounts.map((a) => a.address);
|
|
223
|
+
if (options?.toSignInputs && options.toSignInputs.length > 0) {
|
|
224
|
+
for (const input of options.toSignInputs) {
|
|
225
|
+
const addr = input.address && allAddresses.includes(input.address) ? input.address : this._paymentAddress.address;
|
|
226
|
+
if (!signInputs[addr]) {
|
|
227
|
+
signInputs[addr] = [];
|
|
228
|
+
}
|
|
229
|
+
signInputs[addr].push(input.index);
|
|
230
|
+
}
|
|
231
|
+
if (Object.keys(signInputs).length === 0) {
|
|
232
|
+
signInputs[this._paymentAddress.address] = options.toSignInputs.map((i) => i.index);
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
signInputs[this._paymentAddress.address] = [0];
|
|
236
|
+
}
|
|
237
|
+
const response = await provider.request("signPsbt", {
|
|
238
|
+
psbt: psbtBase64,
|
|
239
|
+
signInputs,
|
|
240
|
+
broadcast: options?.broadcast ?? false,
|
|
241
|
+
allowedSignHash: options?.toSignInputs?.[0]?.sighashTypes?.[0]
|
|
242
|
+
});
|
|
243
|
+
if (response.error) {
|
|
244
|
+
throw response.error;
|
|
245
|
+
}
|
|
246
|
+
if (response.result.txid) {
|
|
247
|
+
return response.result.txid;
|
|
248
|
+
}
|
|
249
|
+
return Buffer.from(response.result.psbt, "base64").toString("hex");
|
|
250
|
+
} catch (error) {
|
|
251
|
+
this.handleError(error);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
async sendTransaction(to, satoshis) {
|
|
255
|
+
const provider = this.getProvider();
|
|
256
|
+
if (!provider) {
|
|
257
|
+
throw new Error("Xverse Wallet is not installed");
|
|
258
|
+
}
|
|
259
|
+
if (!this._paymentAddress) {
|
|
260
|
+
throw new Error("Not connected");
|
|
261
|
+
}
|
|
262
|
+
try {
|
|
263
|
+
const response = await provider.request("sendTransfer", {
|
|
264
|
+
recipients: [
|
|
265
|
+
{
|
|
266
|
+
address: to,
|
|
267
|
+
amount: satoshis
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
});
|
|
271
|
+
if (response.error) {
|
|
272
|
+
throw response.error;
|
|
273
|
+
}
|
|
274
|
+
if (!response.result.txid) {
|
|
275
|
+
throw new Error("No transaction ID received");
|
|
276
|
+
}
|
|
277
|
+
return response.result.txid;
|
|
278
|
+
} catch (error) {
|
|
279
|
+
this.handleError(error);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async getNetwork() {
|
|
283
|
+
return this._network;
|
|
284
|
+
}
|
|
285
|
+
async switchNetwork(network) {
|
|
286
|
+
await this.checkAndSwitchNetwork(network);
|
|
287
|
+
this._network = network;
|
|
288
|
+
this.emitNetworkChanged(network);
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* Get the ordinals address (if available)
|
|
292
|
+
*/
|
|
293
|
+
getOrdinalsAddress() {
|
|
294
|
+
return this._ordinalsAddress;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get the payment address
|
|
298
|
+
*/
|
|
299
|
+
getPaymentAddress() {
|
|
300
|
+
return this._paymentAddress;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Get all connected addresses (for multi-address support)
|
|
304
|
+
*/
|
|
305
|
+
getAllAddresses() {
|
|
306
|
+
return this._accounts.map((acc) => acc.address);
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Switch to a specific address within the connected accounts
|
|
310
|
+
*/
|
|
311
|
+
switchWalletAddress(address) {
|
|
312
|
+
const account = this._accounts.find((a) => a.address === address);
|
|
313
|
+
if (account) {
|
|
314
|
+
if (account.purpose === "payment" /* Payment */) {
|
|
315
|
+
this._paymentAddress = {
|
|
316
|
+
address: account.address,
|
|
317
|
+
publicKey: account.publicKey,
|
|
318
|
+
type: this.inferAddressType(account.address)
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
return true;
|
|
322
|
+
}
|
|
323
|
+
return false;
|
|
324
|
+
}
|
|
325
|
+
};
|
|
326
|
+
|
|
327
|
+
export { XverseConnector };
|
|
328
|
+
//# sourceMappingURL=out.js.map
|
|
329
|
+
//# sourceMappingURL=chunk-RLZEG6KL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/xverse/XverseConnector.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 * Address purpose enum for Xverse\n */\nenum AddressPurpose {\n Payment = 'payment',\n Ordinals = 'ordinals',\n}\n\n/**\n * Xverse address response\n */\ninterface AddressResponse {\n address: string;\n publicKey: string;\n purpose: AddressPurpose;\n}\n\n/**\n * Xverse Provider request/response types\n */\ninterface XverseRequestResponse<T> {\n result: T;\n error?: { message: string };\n}\n\ninterface GetAddressesResult {\n addresses: AddressResponse[];\n}\n\ninterface SignMessageResult {\n signature: string;\n}\n\ninterface SignPsbtResult {\n psbt: string;\n txid?: string;\n}\n\ninterface SendTransferResult {\n txid: string;\n}\n\ninterface NetworkResult {\n bitcoin?: { name: string };\n}\n\ninterface XverseEventData {\n network?: string;\n}\n\n/**\n * Xverse Bitcoin Provider interface\n */\ninterface XverseBitcoinProvider {\n request<T>(method: string, params: unknown): Promise<XverseRequestResponse<T>>;\n addListener(event: string, callback: (data: XverseEventData) => void): () => void;\n}\n\n// Extend window type\ndeclare global {\n interface Window {\n XverseProviders?: {\n BitcoinProvider?: XverseBitcoinProvider;\n };\n }\n}\n\n// Xverse wallet icon\nconst XVERSE_ICON =\n 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF83MDM3XzEwMykiPgo8cGF0aCBkPSJNMjAwIDBIMFYyMDBIMjAwVjBaIiBmaWxsPSJ1cmwoI3BhaW50MF9saW5lYXJfNzAzN18xMDMpIi8+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMV83MDM3XzEwMykiPgo8cGF0aCBkPSJNMTU5LjM2NyAxNTcuNDQ1VjEzNS43MThDMTU5LjM2NyAxMzQuODU2IDE1OS4wMjUgMTM0LjAzNCAxNTguNDE0IDEzMy40MjRMNjUuOTY2NCA0MC45NzU2QzY1LjM1NTkgNDAuMzY1MSA2NC41MzQyIDQwLjAyMjggNjMuNjcyNiA0MC4wMjI4SDQxLjk0NTZDNDAuODczIDQwLjAyMjggNDAgNDAuODk1NyA0MCA0MS45Njg0VjYyLjE1NDlDNDAgNjMuMDE2NSA0MC4zNDIzIDYzLjgzOCA0MC45NTI4IDY0LjQ0ODZMNzQuMTM2OCA5Ny42MzI0Qzc0Ljg5NTYgOTguMzkxNiA3NC44OTU2IDk5LjYyNCA3NC4xMzY4IDEwMC4zODNMNDAuNTcwNiAxMzMuOTQ5QzQwLjIwNTQgMTM0LjMxNCA0MCAxMzQuODEgNDAgMTM1LjMyNFYxNTcuNDQ1QzQwIDE1OC41MTcgNDAuODczIDE1OS4zOTEgNDEuOTQ1NiAxNTkuMzkxSDc4LjI1MDVDNzkuMzIzMiAxNTkuMzkxIDgwLjE5NiAxNTguNTE3IDgwLjE5NiAxNTcuNDQ1VjE0NC40MTNDODAuMTk2IDE0My45IDgwLjQwMTYgMTQzLjQwMyA4MC43NjY4IDE0My4wMzhMOTguNzczNiAxMjUuMDMxQzk5LjUzMjQgMTI0LjI3MiAxMDAuNzY1IDEyNC4yNzIgMTAxLjUyNCAxMjUuMDMxTDEzNC45MzYgMTU4LjQ0NEMxMzUuNTQ2IDE1OS4wNTQgMTM2LjM2OCAxNTkuMzk2IDEzNy4yMyAxNTkuMzk2SDE1Ny40MTZDMTU4LjQ4OSAxNTkuMzk2IDE1OS4zNjIgMTU4LjUyMyAxNTkuMzYyIDE1Ny40NTFMMTU5LjM2NyAxNTcuNDQ1WiIgZmlsbD0id2hpdGUiLz4KPHBhdGggZD0iTTExMC45MzggNjguNzk2SDEyOS4xMjJDMTMwLjIgNjguNzk2IDEzMS4wNzkgNjkuNjc0NyAxMzEuMDc5IDcwLjc1MzFWODguOTM2OEMxMzEuMDc5IDkwLjY4MjggMTMzLjE5IDkxLjU1NiAxMzQuNDIyIDkwLjMxNzZMMTU5LjM2NyA2NS4zMzI4QzE1OS43MzIgNjQuOTY3NiAxNTkuOTM4IDY0LjQ3MTMgMTU5LjkzOCA2My45NTJWNDIuMDcwOUMxNTkuOTM4IDQwLjk5MjUgMTU5LjA2NCA0MC4xMTM5IDE1Ny45ODEgNDAuMTEzOUwxMzUuNzc0IDQwLjA4NTRDMTM1LjI1NiA0MC4wODU0IDEzNC43NTkgNDAuMjkwOCAxMzQuMzg4IDQwLjY1NTlMMTA5LjU1MiA2NS40NTI2QzEwOC4zMTkgNjYuNjg1IDEwOS4xOTIgNjguNzk2IDExMC45MzIgNjguNzk2SDExMC45MzhaIiBmaWxsPSIjRUU3QTMwIi8+CjwvZz4KPC9nPgo8ZGVmcz4KPGxpbmVhckdyYWRpZW50IGlkPSJwYWludDBfbGluZWFyXzcwMzdfMTAzIiB4MT0iMTAwIiB5MT0iMCIgeDI9IjEwMCIgeTI9IjIwMCIgZ3JhZGllbnRVbml0cz0idXNlclNwYWNlT25Vc2UiPgo8c3RvcCBzdG9wLWNvbG9yPSIjMEYwRjBGIi8+CjxzdG9wIG9mZnNldD0iMSIgc3RvcC1jb2xvcj0iIzE4MTgxOCIvPgo8L2xpbmVhckdyYWRpZW50Pgo8Y2xpcFBhdGggaWQ9ImNsaXAwXzcwMzdfMTAzIj4KPHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHJ4PSIzNS41NTU2IiBmaWxsPSJ3aGl0ZSIvPgo8L2NsaXBQYXRoPgo8Y2xpcFBhdGggaWQ9ImNsaXAxXzcwMzdfMTAzIj4KPHJlY3Qgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxMjAiIGZpbGw9IndoaXRlIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSg0MCA0MCkiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K';\n\n/**\n * Xverse Wallet Connector\n * Uses the native Xverse Provider API\n *\n * @see https://docs.xverse.app/\n */\nexport class XverseConnector extends BaseConnector {\n readonly id = 'xverse';\n readonly name = 'Xverse Wallet';\n readonly icon = XVERSE_ICON;\n\n private _paymentAddress: WalletAccount | null = null;\n private _ordinalsAddress: WalletAccount | null = null;\n private _network: BitcoinNetwork = 'mainnet';\n private _accounts: AddressResponse[] = [];\n private _removeAccountChangeListener: (() => void) | null = null;\n private _removeNetworkChangeListener: (() => void) | null = null;\n private _removeDisconnectedListener: (() => void) | null = null;\n\n protected getProvider(): XverseBitcoinProvider | undefined {\n if (typeof window === 'undefined') return undefined;\n return window.XverseProviders?.BitcoinProvider;\n }\n\n async connect(network: BitcoinNetwork = 'mainnet'): Promise<WalletAccount> {\n const provider = this.getProvider();\n if (!provider) {\n this.handleError(new Error('Xverse Wallet is not installed'));\n }\n\n try {\n this._network = network;\n\n // Request permissions first\n const permissionResponse = await provider!.request<unknown>('wallet_requestPermissions', undefined);\n if (permissionResponse.error) {\n throw new Error(permissionResponse.error.message);\n }\n\n // Get addresses\n const response = await provider!.request<GetAddressesResult>('getAddresses', {\n purposes: [AddressPurpose.Payment, AddressPurpose.Ordinals],\n message: 'Connect to application',\n });\n\n if (response.error) {\n throw response.error;\n }\n\n const addresses = response.result.addresses;\n this._accounts = addresses;\n\n const paymentAddr = addresses.find((a) => a.purpose === AddressPurpose.Payment);\n const ordinalsAddr = addresses.find((a) => a.purpose === AddressPurpose.Ordinals);\n\n if (paymentAddr) {\n this._paymentAddress = {\n address: paymentAddr.address,\n publicKey: paymentAddr.publicKey,\n type: this.inferAddressType(paymentAddr.address),\n };\n }\n\n if (ordinalsAddr) {\n this._ordinalsAddress = {\n address: ordinalsAddr.address,\n publicKey: ordinalsAddr.publicKey,\n type: this.inferAddressType(ordinalsAddr.address),\n };\n }\n\n // Check and switch network if needed\n await this.checkAndSwitchNetwork(network);\n\n // Setup event listeners\n this.setupEventListeners();\n\n if (!this._paymentAddress) {\n throw new Error('No payment address found');\n }\n\n return this._paymentAddress;\n } catch (error) {\n this.handleError(error);\n }\n }\n\n private async checkAndSwitchNetwork(network: BitcoinNetwork): Promise<void> {\n const provider = this.getProvider();\n if (!provider) return;\n\n // For testnet4, we need to switch to Testnet4 network in Xverse\n if (network === 'testnet4') {\n try {\n const currentNetwork = await provider.request<NetworkResult>('wallet_getNetwork', null);\n if (currentNetwork?.result?.bitcoin?.name !== 'Testnet4') {\n await provider.request<unknown>('wallet_changeNetwork', { name: 'Testnet4' });\n }\n } catch {\n // Network switch may not be supported, continue anyway\n }\n } else if (network === 'testnet') {\n try {\n const currentNetwork = await provider.request<NetworkResult>('wallet_getNetwork', null);\n if (currentNetwork?.result?.bitcoin?.name !== 'Testnet') {\n await provider.request<unknown>('wallet_changeNetwork', { name: 'Testnet' });\n }\n } catch {\n // Network switch may not be supported\n }\n } else if (network === 'mainnet') {\n try {\n const currentNetwork = await provider.request<NetworkResult>('wallet_getNetwork', null);\n if (currentNetwork?.result?.bitcoin?.name !== 'Mainnet') {\n await provider.request<unknown>('wallet_changeNetwork', { name: 'Mainnet' });\n }\n } catch {\n // Network switch may not be supported\n }\n }\n }\n\n private setupEventListeners(): void {\n const provider = this.getProvider();\n if (!provider || typeof provider.addListener !== 'function') return;\n\n // Remove existing listeners\n this.removeEventListeners();\n\n // Account change listener\n this._removeAccountChangeListener = provider.addListener('accountChange', async () => {\n await this.handleAccountChange();\n });\n\n // Network change listener\n this._removeNetworkChangeListener = provider.addListener('networkChange', async (event) => {\n await this.handleNetworkChange(event);\n });\n\n // Disconnected listener\n this._removeDisconnectedListener = provider.addListener('accountDisconnected', () => {\n this.emitAccountsChanged([]);\n });\n }\n\n private async handleAccountChange(): Promise<void> {\n const provider = this.getProvider();\n if (!provider) return;\n\n try {\n const response = await provider.request<GetAddressesResult>('getAddresses', {\n purposes: [AddressPurpose.Payment, AddressPurpose.Ordinals],\n });\n\n if (!response.error && response.result?.addresses?.length) {\n this._accounts = response.result.addresses;\n const paymentAddr = response.result.addresses.find((a) => a.purpose === AddressPurpose.Payment);\n\n if (paymentAddr) {\n this._paymentAddress = {\n address: paymentAddr.address,\n publicKey: paymentAddr.publicKey,\n type: this.inferAddressType(paymentAddr.address),\n };\n\n const accounts: WalletAccount[] = response.result.addresses.map((addr) => ({\n address: addr.address,\n publicKey: addr.publicKey,\n type: this.inferAddressType(addr.address),\n }));\n\n this.emitAccountsChanged(accounts);\n }\n }\n } catch (error) {\n console.error('Error handling account change:', error);\n }\n }\n\n private async handleNetworkChange(event: XverseEventData): Promise<void> {\n if (!event.network) return;\n\n const networkMap: Record<string, BitcoinNetwork> = {\n 'Mainnet': 'mainnet',\n 'Testnet': 'testnet',\n 'Testnet4': 'testnet4',\n 'Signet': 'signet',\n };\n\n const mappedNetwork = networkMap[event.network] || 'mainnet';\n if (mappedNetwork !== this._network) {\n this._network = mappedNetwork;\n this.emitNetworkChanged(mappedNetwork);\n }\n }\n\n private removeEventListeners(): void {\n this._removeAccountChangeListener?.();\n this._removeAccountChangeListener = null;\n\n this._removeNetworkChangeListener?.();\n this._removeNetworkChangeListener = null;\n\n this._removeDisconnectedListener?.();\n this._removeDisconnectedListener = null;\n }\n\n async disconnect(): Promise<void> {\n const provider = this.getProvider();\n\n try {\n if (provider) {\n await provider.request<unknown>('wallet_renouncePermissions', undefined);\n }\n } catch {\n // Ignore disconnect errors\n } finally {\n this.removeEventListeners();\n this._paymentAddress = null;\n this._ordinalsAddress = null;\n this._accounts = [];\n this.cleanup();\n }\n }\n\n async getAccounts(): Promise<WalletAccount[]> {\n const accounts: WalletAccount[] = [];\n if (this._paymentAddress) accounts.push(this._paymentAddress);\n if (this._ordinalsAddress) accounts.push(this._ordinalsAddress);\n return accounts;\n }\n\n async signMessage(message: string): Promise<string> {\n const provider = this.getProvider();\n if (!provider) {\n throw new Error('Xverse Wallet is not installed');\n }\n if (!this._paymentAddress) {\n throw new Error('Not connected');\n }\n\n try {\n const response = await provider.request<SignMessageResult>('signMessage', {\n address: this._paymentAddress.address,\n message,\n });\n\n if (response.error) {\n throw response.error;\n }\n\n return response.result.signature;\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string> {\n const provider = this.getProvider();\n if (!provider) {\n throw new Error('Xverse Wallet is not installed');\n }\n\n if (!this._paymentAddress) {\n throw new Error('Not connected');\n }\n\n try {\n // Convert hex to base64 for Xverse\n const psbtBase64 = Buffer.from(psbtHex, 'hex').toString('base64');\n\n // Build signInputs map\n const signInputs: Record<string, number[]> = {};\n const allAddresses = this._accounts.map((a) => a.address);\n\n if (options?.toSignInputs && options.toSignInputs.length > 0) {\n for (const input of options.toSignInputs) {\n const addr = input.address && allAddresses.includes(input.address)\n ? input.address\n : this._paymentAddress.address;\n\n if (!signInputs[addr]) {\n signInputs[addr] = [];\n }\n signInputs[addr]!.push(input.index);\n }\n\n // If no matching addresses found, use payment address\n if (Object.keys(signInputs).length === 0) {\n signInputs[this._paymentAddress.address] = options.toSignInputs.map((i) => i.index);\n }\n } else {\n // Default: sign all inputs with payment address\n signInputs[this._paymentAddress.address] = [0];\n }\n\n const response = await provider.request<SignPsbtResult>('signPsbt', {\n psbt: psbtBase64,\n signInputs,\n broadcast: options?.broadcast ?? false,\n allowedSignHash: options?.toSignInputs?.[0]?.sighashTypes?.[0],\n });\n if (response.error) {\n throw response.error;\n }\n\n // Return txid if broadcast, otherwise return signed psbt as hex\n if (response.result.txid) {\n return response.result.txid;\n }\n\n // Convert base64 back to hex\n return Buffer.from(response.result.psbt, 'base64').toString('hex');\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async sendTransaction(to: string, satoshis: number): Promise<string> {\n const provider = this.getProvider();\n if (!provider) {\n throw new Error('Xverse Wallet is not installed');\n }\n\n if (!this._paymentAddress) {\n throw new Error('Not connected');\n }\n\n try {\n const response = await provider.request<SendTransferResult>('sendTransfer', {\n recipients: [\n {\n address: to,\n amount: satoshis,\n },\n ],\n });\n\n if (response.error) {\n throw response.error;\n }\n\n if (!response.result.txid) {\n throw new Error('No transaction ID received');\n }\n\n return response.result.txid;\n } catch (error) {\n this.handleError(error);\n }\n }\n\n async getNetwork(): Promise<BitcoinNetwork> {\n return this._network;\n }\n\n async switchNetwork(network: BitcoinNetwork): Promise<void> {\n await this.checkAndSwitchNetwork(network);\n this._network = network;\n this.emitNetworkChanged(network);\n }\n\n /**\n * Get the ordinals address (if available)\n */\n getOrdinalsAddress(): WalletAccount | null {\n return this._ordinalsAddress;\n }\n\n /**\n * Get the payment address\n */\n getPaymentAddress(): WalletAccount | null {\n return this._paymentAddress;\n }\n\n /**\n * Get all connected addresses (for multi-address support)\n */\n getAllAddresses(): string[] {\n return this._accounts.map((acc) => acc.address);\n }\n\n /**\n * Switch to a specific address within the connected accounts\n */\n switchWalletAddress(address: string): boolean {\n const account = this._accounts.find((a) => a.address === address);\n if (account) {\n if (account.purpose === AddressPurpose.Payment) {\n this._paymentAddress = {\n address: account.address,\n publicKey: account.publicKey,\n type: this.inferAddressType(account.address),\n };\n }\n return true;\n }\n return false;\n }\n}\n"]}
|