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.
Files changed (142) hide show
  1. package/README.md +554 -0
  2. package/dist/base-IAFq7sd8.d.mts +53 -0
  3. package/dist/base-IAFq7sd8.d.ts +53 -0
  4. package/dist/binance/index.d.mts +81 -0
  5. package/dist/binance/index.d.ts +81 -0
  6. package/dist/binance/index.js +13 -0
  7. package/dist/binance/index.js.map +1 -0
  8. package/dist/binance/index.mjs +4 -0
  9. package/dist/binance/index.mjs.map +1 -0
  10. package/dist/bitget/index.d.mts +84 -0
  11. package/dist/bitget/index.d.ts +84 -0
  12. package/dist/bitget/index.js +13 -0
  13. package/dist/bitget/index.js.map +1 -0
  14. package/dist/bitget/index.mjs +4 -0
  15. package/dist/bitget/index.mjs.map +1 -0
  16. package/dist/chunk-5Z5Q2Y75.mjs +91 -0
  17. package/dist/chunk-5Z5Q2Y75.mjs.map +1 -0
  18. package/dist/chunk-7KK2LZLZ.mjs +208 -0
  19. package/dist/chunk-7KK2LZLZ.mjs.map +1 -0
  20. package/dist/chunk-AW2JZIHR.mjs +753 -0
  21. package/dist/chunk-AW2JZIHR.mjs.map +1 -0
  22. package/dist/chunk-EIJOSZXZ.js +331 -0
  23. package/dist/chunk-EIJOSZXZ.js.map +1 -0
  24. package/dist/chunk-EQHR7P7G.js +541 -0
  25. package/dist/chunk-EQHR7P7G.js.map +1 -0
  26. package/dist/chunk-EWRXLZO4.mjs +539 -0
  27. package/dist/chunk-EWRXLZO4.mjs.map +1 -0
  28. package/dist/chunk-FISNQZZ7.js +802 -0
  29. package/dist/chunk-FISNQZZ7.js.map +1 -0
  30. package/dist/chunk-HL4WDMGS.js +200 -0
  31. package/dist/chunk-HL4WDMGS.js.map +1 -0
  32. package/dist/chunk-IPYWR76I.js +314 -0
  33. package/dist/chunk-IPYWR76I.js.map +1 -0
  34. package/dist/chunk-JYYNWR5G.js +142 -0
  35. package/dist/chunk-JYYNWR5G.js.map +1 -0
  36. package/dist/chunk-LNKTYZJM.js +701 -0
  37. package/dist/chunk-LNKTYZJM.js.map +1 -0
  38. package/dist/chunk-LVZMONQL.mjs +699 -0
  39. package/dist/chunk-LVZMONQL.mjs.map +1 -0
  40. package/dist/chunk-MFXLQWOE.js +93 -0
  41. package/dist/chunk-MFXLQWOE.js.map +1 -0
  42. package/dist/chunk-NBIA4TTE.mjs +204 -0
  43. package/dist/chunk-NBIA4TTE.mjs.map +1 -0
  44. package/dist/chunk-O4DD2XJ2.js +206 -0
  45. package/dist/chunk-O4DD2XJ2.js.map +1 -0
  46. package/dist/chunk-P7HVBU2B.mjs +140 -0
  47. package/dist/chunk-P7HVBU2B.mjs.map +1 -0
  48. package/dist/chunk-Q7QVQYEB.js +210 -0
  49. package/dist/chunk-Q7QVQYEB.js.map +1 -0
  50. package/dist/chunk-RLZEG6KL.mjs +329 -0
  51. package/dist/chunk-RLZEG6KL.mjs.map +1 -0
  52. package/dist/chunk-SYLDBJ75.mjs +246 -0
  53. package/dist/chunk-SYLDBJ75.mjs.map +1 -0
  54. package/dist/chunk-TTEUU3CI.mjs +198 -0
  55. package/dist/chunk-TTEUU3CI.mjs.map +1 -0
  56. package/dist/chunk-V66BXDTR.mjs +292 -0
  57. package/dist/chunk-V66BXDTR.mjs.map +1 -0
  58. package/dist/chunk-X77ZT4OI.js +268 -0
  59. package/dist/chunk-X77ZT4OI.js.map +1 -0
  60. package/dist/imtoken/index.d.mts +116 -0
  61. package/dist/imtoken/index.d.ts +116 -0
  62. package/dist/imtoken/index.js +14 -0
  63. package/dist/imtoken/index.js.map +1 -0
  64. package/dist/imtoken/index.mjs +5 -0
  65. package/dist/imtoken/index.mjs.map +1 -0
  66. package/dist/index.d.mts +14 -0
  67. package/dist/index.d.ts +14 -0
  68. package/dist/index.js +170 -0
  69. package/dist/index.js.map +1 -0
  70. package/dist/index.mjs +13 -0
  71. package/dist/index.mjs.map +1 -0
  72. package/dist/ledger/index.d.mts +290 -0
  73. package/dist/ledger/index.d.ts +290 -0
  74. package/dist/ledger/index.js +14 -0
  75. package/dist/ledger/index.js.map +1 -0
  76. package/dist/ledger/index.mjs +5 -0
  77. package/dist/ledger/index.mjs.map +1 -0
  78. package/dist/okx/index.d.mts +88 -0
  79. package/dist/okx/index.d.ts +88 -0
  80. package/dist/okx/index.js +13 -0
  81. package/dist/okx/index.js.map +1 -0
  82. package/dist/okx/index.mjs +4 -0
  83. package/dist/okx/index.mjs.map +1 -0
  84. package/dist/phantom/index.d.mts +96 -0
  85. package/dist/phantom/index.d.ts +96 -0
  86. package/dist/phantom/index.js +14 -0
  87. package/dist/phantom/index.js.map +1 -0
  88. package/dist/phantom/index.mjs +5 -0
  89. package/dist/phantom/index.mjs.map +1 -0
  90. package/dist/psbt-builder-CFOs69Z5.d.mts +131 -0
  91. package/dist/psbt-builder-CFOs69Z5.d.ts +131 -0
  92. package/dist/trezor/index.d.mts +155 -0
  93. package/dist/trezor/index.d.ts +155 -0
  94. package/dist/trezor/index.js +14 -0
  95. package/dist/trezor/index.js.map +1 -0
  96. package/dist/trezor/index.mjs +5 -0
  97. package/dist/trezor/index.mjs.map +1 -0
  98. package/dist/unisat/index.d.mts +75 -0
  99. package/dist/unisat/index.d.ts +75 -0
  100. package/dist/unisat/index.js +13 -0
  101. package/dist/unisat/index.js.map +1 -0
  102. package/dist/unisat/index.mjs +4 -0
  103. package/dist/unisat/index.mjs.map +1 -0
  104. package/dist/utils/index.d.mts +398 -0
  105. package/dist/utils/index.d.ts +398 -0
  106. package/dist/utils/index.js +120 -0
  107. package/dist/utils/index.js.map +1 -0
  108. package/dist/utils/index.mjs +3 -0
  109. package/dist/utils/index.mjs.map +1 -0
  110. package/dist/xverse/index.d.mts +79 -0
  111. package/dist/xverse/index.d.ts +79 -0
  112. package/dist/xverse/index.js +13 -0
  113. package/dist/xverse/index.js.map +1 -0
  114. package/dist/xverse/index.mjs +4 -0
  115. package/dist/xverse/index.mjs.map +1 -0
  116. package/package.json +108 -0
  117. package/src/base.ts +132 -0
  118. package/src/binance/BinanceConnector.ts +307 -0
  119. package/src/binance/index.ts +1 -0
  120. package/src/bitget/BitgetConnector.ts +301 -0
  121. package/src/bitget/index.ts +1 -0
  122. package/src/imtoken/ImTokenConnector.ts +420 -0
  123. package/src/imtoken/index.ts +2 -0
  124. package/src/index.ts +78 -0
  125. package/src/ledger/LedgerConnector.ts +1019 -0
  126. package/src/ledger/index.ts +8 -0
  127. package/src/okx/OKXConnector.ts +230 -0
  128. package/src/okx/index.ts +1 -0
  129. package/src/phantom/PhantomConnector.ts +381 -0
  130. package/src/phantom/index.ts +2 -0
  131. package/src/trezor/TrezorConnector.ts +824 -0
  132. package/src/trezor/index.ts +6 -0
  133. package/src/unisat/UnisatConnector.ts +312 -0
  134. package/src/unisat/index.ts +1 -0
  135. package/src/utils/blockstream.ts +230 -0
  136. package/src/utils/btc-service.ts +364 -0
  137. package/src/utils/index.ts +56 -0
  138. package/src/utils/mempool.ts +232 -0
  139. package/src/utils/psbt-builder.ts +492 -0
  140. package/src/utils/types.ts +183 -0
  141. package/src/xverse/XverseConnector.ts +479 -0
  142. package/src/xverse/index.ts +1 -0
@@ -0,0 +1,301 @@
1
+ import type {
2
+ WalletAccount,
3
+ BitcoinNetwork,
4
+ SignPsbtOptions,
5
+ } from 'otx-btc-wallet-core';
6
+ import { BaseConnector } from '../base';
7
+
8
+ /**
9
+ * Bitget sign PSBT options
10
+ * @see https://web3.bitget.com/en/docs/connect/mainnet/btc/
11
+ */
12
+ interface BitgetSignPsbtOptions {
13
+ autoFinalized?: boolean;
14
+ toSignInputs?: Array<{
15
+ index: number;
16
+ address?: string;
17
+ publicKey?: string;
18
+ sighashTypes?: number[];
19
+ disableTweakSigner?: boolean;
20
+ }>;
21
+ }
22
+
23
+ /**
24
+ * Bitget Bitcoin provider interface
25
+ * Provider is accessible via window.bitkeep.unisat
26
+ * @see https://web3.bitget.com/en/docs/connect/mainnet/btc/
27
+ */
28
+ interface BitgetBitcoinProvider {
29
+ requestAccounts(): Promise<string[]>;
30
+ getAccounts(): Promise<string[]>;
31
+ getPublicKey(): Promise<string>;
32
+ getBalance(): Promise<{ confirmed: number; unconfirmed: number; total: number }>;
33
+ getNetwork(): Promise<string>;
34
+ switchNetwork(network: 'livenet' | 'testnet' | 'signet'): Promise<void>;
35
+ signMessage(msg: string, type?: 'ecdsa' | 'bip322-simple'): Promise<string>;
36
+ signPsbt(psbtHex: string, options?: BitgetSignPsbtOptions): Promise<string>;
37
+ signPsbts(psbtHexs: string[], options?: BitgetSignPsbtOptions[]): Promise<string[]>;
38
+ pushPsbt(psbtHex: string): Promise<string>;
39
+ sendBitcoin(toAddress: string, satoshis: number, options?: { feeRate?: number }): Promise<string>;
40
+ pushTx(options: { rawtx: string }): Promise<string>;
41
+ on(event: 'accountsChanged', callback: (accounts: string[]) => void): void;
42
+ on(event: 'networkChanged', callback: (network: string) => void): void;
43
+ removeListener(event: 'accountsChanged', callback: (accounts: string[]) => void): void;
44
+ removeListener(event: 'networkChanged', callback: (network: string) => void): void;
45
+ }
46
+
47
+ // Extend window type
48
+ declare global {
49
+ interface Window {
50
+ bitkeep?: {
51
+ unisat?: BitgetBitcoinProvider;
52
+ };
53
+ }
54
+ }
55
+
56
+ // Bitget wallet icon
57
+ const BITGET_ICON =
58
+ 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjAwIiBoZWlnaHQ9IjIwMCIgdmlld0JveD0iMCAwIDIwMCAyMDAiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF83MDM3Xzc2KSI+CjxtYXNrIGlkPSJtYXNrMF83MDM3Xzc2IiBzdHlsZT0ibWFzay10eXBlOmx1bWluYW5jZSIgbWFza1VuaXRzPSJ1c2VyU3BhY2VPblVzZSIgeD0iMCIgeT0iMCIgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiPgo8cGF0aCBkPSJNMjAwIDBIMFYyMDBIMjAwVjBaIiBmaWxsPSJ3aGl0ZSIvPgo8L21hc2s+CjxnIG1hc2s9InVybCgjbWFzazBfNzAzN183NikiPgo8cGF0aCBkPSJNMjAwIDEuNTI1ODhlLTA1SDAuMDAwMjQ0MTQxVjIwMEgyMDBWMS41MjU4OGUtMDVaIiBmaWxsPSIjNTRGRkY1Ii8+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIwX2ZfNzAzN183NikiPgo8cGF0aCBkPSJNMTAuNTMxOCAxNTUuMTU5Qy0yMi45MTIgMjQ5LjI1MSAxNTUuOTg2IDIyMi42NzYgMjQ5LjYxNSAxOTcuNjI3QzM0NS40NDEgMTY1LjgyNSAyNzkuMjA4IDI1LjY0NDUgMjEwLjQ4IDIyLjU0MkMxNDEuNzUyIDE5LjQzOTYgMjE5LjAwMiA4Ny4zNjEzIDE2MC42MjIgMTA2Ljc2MUMxMDIuMjQxIDEyNi4xNiA1Mi4zMzY4IDM3LjU0NCAxMC41MzE4IDE1NS4xNTlaIiBmaWxsPSJ3aGl0ZSIvPgo8L2c+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIxX2ZfNzAzN183NikiPgo8cGF0aCBkPSJNNjYuODA2MyAtMzUuNzk5NkM0OS4yNjI1IC04My43MzIgLTEzLjIxNzkgLTE4Ljc0NzEgLTQyLjI2NTIgMTkuNzM3Qy02OS45NzI2IDYxLjU5OTIgMi4zNTExMyA5Ny43NzQyIDMwLjcxOTQgNzguMTUzNUM1OS4wODc5IDU4LjUzMjggNi4wNzM4NiA1NC43MTUzIDIyLjk0NiAyOS4yMDEyQzM5LjgxOCAzLjY4NzM0IDg4LjczNTYgMjQuMTE2MSA2Ni44MDYzIC0zNS43OTk2WiIgZmlsbD0iIzAwRkZGMCIgZmlsbC1vcGFjaXR5PSIwLjY3Ii8+CjwvZz4KPGcgZmlsdGVyPSJ1cmwoI2ZpbHRlcjJfZl83MDM3Xzc2KSI+CjxwYXRoIGQ9Ik03NS4zNzQ4IDE3Ni4xMTFDNTEuNDQ1OSA5NS41OTU3IC01MS42MjYgMTM3Ljk5NyAtMTAwLjE3MSAxNjkuMjYzQy0xNDYuODY3IDIwNi4yODIgLTM1Ljk5MjcgMzEyLjc3MSAxMC4wNTY5IDMwNy4zMjRDNTYuMTA2NCAzMDEuODc3IC0yNi44ODM5IDI1NS41MTkgMS41NTI2MiAyMzIuOTQ1QzI5Ljk4OTIgMjEwLjM3MSAxMDUuMjg3IDI3Ni43NTYgNzUuMzc0OCAxNzYuMTExWiIgZmlsbD0iIzlEODFGRiIvPgo8L2c+CjxnIGZpbHRlcj0idXJsKCNmaWx0ZXIzX2ZfNzAzN183NikiPgo8cGF0aCBkPSJNMjIwLjQwNiAtODMuODY5NUMxNjguNzg3IC0xNDUuMzM3IDk0Ljg5MjggLTk0LjUwNzggNjQuMzk4MyAtNjEuNDA5OEMzNy43MTQyIC0yMy45NDExIDE3NS4yMTUgNDQuNzExNyAyMTMuMzc2IDMyLjk0NjRDMjUxLjUzOCAyMS4xODA5IDE2MS4zMzcgLTMuMTY0MzYgMTc3LjU3NiAtMjYuMDA2MkMxOTMuODE0IC00OC44NDggMjg0LjkzMSAtNy4wMzU2NiAyMjAuNDA2IC04My44Njk1WiIgZmlsbD0iIzREOTRGRiIvPgo8L2c+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNzIuODA0IDExOS40MDNIMTA2Ljc3Nkw2OC4xMzE4IDgwLjUwODZMMTA3LjI3MyA0MS42MTQ1TDExNy45MzQgMzEuMjVIODIuNjcxNkwzNy43NjI2IDc2LjM4ODdDMzUuNDk2MiA3OC42NjM3IDM1LjUwNzggODIuMzQ0OSAzNy43ODU5IDg0LjYwODZMNzIuODA0IDExOS40MDNaTTkzLjIyNjcgODAuNkg5Mi45NjUzTDkzLjIyMzkgODAuNTk3M0w5My4yMjY3IDgwLjZaTTkzLjIyNjcgODAuNkwxMzEuODY4IDExOS40OTFMOTIuNzI3MSAxNTguMzg2TDgyLjA2NjEgMTY4Ljc1SDExNy4zMjlMMTYyLjIzOCAxMjMuNjE0QzE2NC41MDQgMTIxLjMzOSAxNjQuNDkyIDExNy42NTggMTYyLjIxNCAxMTUuMzk1TDEyNy4xOTYgODAuNkg5My4yMjY3WiIgZmlsbD0iYmxhY2siLz4KPC9nPgo8L2c+CjxkZWZzPgo8ZmlsdGVyIGlkPSJmaWx0ZXIwX2ZfNzAzN183NiIgeD0iLTcwLjUwMDciIHk9Ii01NC40ODM5IiB3aWR0aD0iNDQ0Ljk2NyIgaGVpZ2h0PSIzNTIuNjgxIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjM4LjQ2MTUiIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl83MDM3Xzc2Ii8+CjwvZmlsdGVyPgo8ZmlsdGVyIGlkPSJmaWx0ZXIxX2ZfNzAzN183NiIgeD0iLTEyNS4zOTkiIHk9Ii0xMjkuNjc5IiB3aWR0aD0iMjc0LjY4NSIgaGVpZ2h0PSIyOTAuMjQxIiBmaWx0ZXJVbml0cz0idXNlclNwYWNlT25Vc2UiIGNvbG9yLWludGVycG9sYXRpb24tZmlsdGVycz0ic1JHQiI+CjxmZUZsb29kIGZsb29kLW9wYWNpdHk9IjAiIHJlc3VsdD0iQmFja2dyb3VuZEltYWdlRml4Ii8+CjxmZUJsZW5kIG1vZGU9Im5vcm1hbCIgaW49IlNvdXJjZUdyYXBoaWMiIGluMj0iQmFja2dyb3VuZEltYWdlRml4IiByZXN1bHQ9InNoYXBlIi8+CjxmZUdhdXNzaWFuQmx1ciBzdGREZXZpYXRpb249IjM4LjQ2MTUiIHJlc3VsdD0iZWZmZWN0MV9mb3JlZ3JvdW5kQmx1cl83MDM3Xzc2Ii8+CjwvZmlsdGVyPgo8ZmlsdGVyIGlkPSJmaWx0ZXIyX2ZfNzAzN183NiIgeD0iLTE4OC4zNDIiIHk9IjUyLjg0NTEiIHdpZHRoPSIzNDcuNTQiIGhlaWdodD0iMzMxLjYwMyIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIzOC40NjE1IiByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfNzAzN183NiIvPgo8L2ZpbHRlcj4KPGZpbHRlciBpZD0iZmlsdGVyM19mXzcwMzdfNzYiIHg9Ii0xNS45MzQ4IiB5PSItMTg5LjY1NiIgd2lkdGg9IjMzNi4wODYiIGhlaWdodD0iMzAwLjg2MyIgZmlsdGVyVW5pdHM9InVzZXJTcGFjZU9uVXNlIiBjb2xvci1pbnRlcnBvbGF0aW9uLWZpbHRlcnM9InNSR0IiPgo8ZmVGbG9vZCBmbG9vZC1vcGFjaXR5PSIwIiByZXN1bHQ9IkJhY2tncm91bmRJbWFnZUZpeCIvPgo8ZmVCbGVuZCBtb2RlPSJub3JtYWwiIGluPSJTb3VyY2VHcmFwaGljIiBpbjI9IkJhY2tncm91bmRJbWFnZUZpeCIgcmVzdWx0PSJzaGFwZSIvPgo8ZmVHYXVzc2lhbkJsdXIgc3RkRGV2aWF0aW9uPSIzOC40NjE1IiByZXN1bHQ9ImVmZmVjdDFfZm9yZWdyb3VuZEJsdXJfNzAzN183NiIvPgo8L2ZpbHRlcj4KPGNsaXBQYXRoIGlkPSJjbGlwMF83MDM3Xzc2Ij4KPHJlY3Qgd2lkdGg9IjIwMCIgaGVpZ2h0PSIyMDAiIHJ4PSIzMiIgZmlsbD0id2hpdGUiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K';
59
+
60
+ /**
61
+ * Bitget network type
62
+ */
63
+ type BitgetNetwork = 'livenet' | 'testnet' | 'signet';
64
+
65
+ /**
66
+ * Bitget Wallet Connector
67
+ *
68
+ * @see https://web3.bitget.com/en/docs/connect/mainnet/btc/
69
+ */
70
+ export class BitgetConnector extends BaseConnector {
71
+ readonly id = 'bitget';
72
+ readonly name = 'Bitget Wallet';
73
+ readonly icon = BITGET_ICON;
74
+
75
+ private _removeAccountChangeListener: (() => void) | null = null;
76
+ private _removeNetworkChangeListener: (() => void) | null = null;
77
+
78
+ protected getProvider(): BitgetBitcoinProvider | undefined {
79
+ if (typeof window === 'undefined') return undefined;
80
+ return window.bitkeep?.unisat;
81
+ }
82
+
83
+ async connect(network: BitcoinNetwork = 'mainnet'): Promise<WalletAccount> {
84
+ this.ensureInstalled();
85
+ const provider = this.getProvider()!;
86
+
87
+ try {
88
+ const accounts = await provider.requestAccounts();
89
+ if (!accounts || accounts.length === 0) {
90
+ throw new Error('No accounts found');
91
+ }
92
+
93
+ // Switch network if needed
94
+ await this.ensureNetwork(provider, network);
95
+
96
+ const publicKey = await provider.getPublicKey();
97
+
98
+ // Setup event listeners
99
+ this.setupEventListeners();
100
+
101
+ return {
102
+ address: accounts[0] ?? '',
103
+ publicKey,
104
+ type: this.inferAddressType(accounts[0] ?? ''),
105
+ };
106
+ } catch (error) {
107
+ this.handleError(error);
108
+ }
109
+ }
110
+
111
+ private async ensureNetwork(provider: BitgetBitcoinProvider, network: BitcoinNetwork): Promise<void> {
112
+ const currentNetwork = await provider.getNetwork();
113
+ const targetNetwork = this.mapToBitgetNetwork(network);
114
+
115
+ if (currentNetwork !== targetNetwork) {
116
+ await provider.switchNetwork(targetNetwork);
117
+ }
118
+ }
119
+
120
+ private setupEventListeners(): void {
121
+ const provider = this.getProvider();
122
+ if (!provider) return;
123
+
124
+ // Remove existing listeners
125
+ this.removeEventListeners();
126
+
127
+ // Account change listener
128
+ const handleAccountsChanged = (accounts: string[]) => {
129
+ if (!accounts || accounts.length === 0) {
130
+ this.emitAccountsChanged([]);
131
+ return;
132
+ }
133
+
134
+ provider.getPublicKey().then((publicKey) => {
135
+ const walletAccounts: WalletAccount[] = accounts.map((address) => ({
136
+ address,
137
+ publicKey,
138
+ type: this.inferAddressType(address),
139
+ }));
140
+ this.emitAccountsChanged(walletAccounts);
141
+ }).catch(() => {
142
+ this.emitAccountsChanged([]);
143
+ });
144
+ };
145
+
146
+ // Network change listener
147
+ const handleNetworkChanged = (network: string) => {
148
+ const btcNetwork = this.mapNetwork(network);
149
+ this.emitNetworkChanged(btcNetwork);
150
+ };
151
+
152
+ provider.on('accountsChanged', handleAccountsChanged);
153
+ provider.on('networkChanged', handleNetworkChanged);
154
+
155
+ this._removeAccountChangeListener = () => {
156
+ provider.removeListener('accountsChanged', handleAccountsChanged);
157
+ };
158
+ this._removeNetworkChangeListener = () => {
159
+ provider.removeListener('networkChanged', handleNetworkChanged);
160
+ };
161
+ }
162
+
163
+ private removeEventListeners(): void {
164
+ this._removeAccountChangeListener?.();
165
+ this._removeAccountChangeListener = null;
166
+
167
+ this._removeNetworkChangeListener?.();
168
+ this._removeNetworkChangeListener = null;
169
+ }
170
+
171
+ async disconnect(): Promise<void> {
172
+ this.removeEventListeners();
173
+ this.cleanup();
174
+ }
175
+
176
+ async getAccounts(): Promise<WalletAccount[]> {
177
+ this.ensureInstalled();
178
+ const provider = this.getProvider()!;
179
+
180
+ try {
181
+ const addresses = await provider.getAccounts();
182
+ const publicKey = await provider.getPublicKey();
183
+
184
+ return addresses.map((address) => ({
185
+ address,
186
+ publicKey,
187
+ type: this.inferAddressType(address),
188
+ }));
189
+ } catch (error) {
190
+ this.handleError(error);
191
+ }
192
+ }
193
+
194
+ async signMessage(message: string): Promise<string> {
195
+ this.ensureInstalled();
196
+ const provider = this.getProvider()!;
197
+
198
+ try {
199
+ return await provider.signMessage(message);
200
+ } catch (error) {
201
+ this.handleError(error);
202
+ }
203
+ }
204
+
205
+ async signPsbt(psbtHex: string, options?: SignPsbtOptions): Promise<string> {
206
+ this.ensureInstalled();
207
+ const provider = this.getProvider()!;
208
+
209
+ try {
210
+ // Bitget uses same API as Unisat - pass options directly if provided
211
+ return await provider.signPsbt(psbtHex, options);
212
+ } catch (error) {
213
+ this.handleError(error);
214
+ }
215
+ }
216
+
217
+ async signPsbts(psbtHexs: string[], options?: SignPsbtOptions): Promise<string[]> {
218
+ this.ensureInstalled();
219
+ const provider = this.getProvider()!;
220
+
221
+ try {
222
+ const bitgetOptions: BitgetSignPsbtOptions = {
223
+ autoFinalized: options?.autoFinalize ?? true,
224
+ };
225
+
226
+ if (options?.toSignInputs) {
227
+ bitgetOptions.toSignInputs = options.toSignInputs;
228
+ }
229
+
230
+ // Create options array for each PSBT
231
+ const optionsArray = psbtHexs.map(() => bitgetOptions);
232
+
233
+ return await provider.signPsbts(psbtHexs, optionsArray);
234
+ } catch (error) {
235
+ this.handleError(error);
236
+ }
237
+ }
238
+
239
+ async sendTransaction(to: string, satoshis: number): Promise<string> {
240
+ this.ensureInstalled();
241
+ const provider = this.getProvider()!;
242
+
243
+ try {
244
+ return await provider.sendBitcoin(to, satoshis);
245
+ } catch (error) {
246
+ this.handleError(error);
247
+ }
248
+ }
249
+
250
+ async getNetwork(): Promise<BitcoinNetwork> {
251
+ this.ensureInstalled();
252
+ const provider = this.getProvider()!;
253
+
254
+ try {
255
+ const network = await provider.getNetwork();
256
+ return this.mapNetwork(network);
257
+ } catch (error) {
258
+ this.handleError(error);
259
+ }
260
+ }
261
+
262
+ async switchNetwork(network: BitcoinNetwork): Promise<void> {
263
+ this.ensureInstalled();
264
+ const provider = this.getProvider()!;
265
+
266
+ try {
267
+ const bitgetNetwork = this.mapToBitgetNetwork(network);
268
+ await provider.switchNetwork(bitgetNetwork);
269
+ } catch (error) {
270
+ this.handleError(error);
271
+ }
272
+ }
273
+
274
+ private mapNetwork(network: string): BitcoinNetwork {
275
+ switch (network.toLowerCase()) {
276
+ case 'livenet':
277
+ case 'mainnet':
278
+ return 'mainnet';
279
+ case 'testnet':
280
+ return 'testnet';
281
+ case 'signet':
282
+ return 'signet';
283
+ default:
284
+ return 'mainnet';
285
+ }
286
+ }
287
+
288
+ private mapToBitgetNetwork(network: BitcoinNetwork): BitgetNetwork {
289
+ switch (network) {
290
+ case 'mainnet':
291
+ return 'livenet';
292
+ case 'testnet':
293
+ case 'testnet4':
294
+ return 'testnet';
295
+ case 'signet':
296
+ return 'signet';
297
+ default:
298
+ return 'livenet';
299
+ }
300
+ }
301
+ }
@@ -0,0 +1 @@
1
+ export { BitgetConnector } from './BitgetConnector';