bitcoin-wallet-connector 0.1.0 → 0.2.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 +24 -21
- package/lib/BitcoinConnectionProvider.d.ts +3 -3
- package/lib/BitcoinWalletConnector-BC92ulXx.js +2 -0
- package/lib/BitcoinWalletConnector-BC92ulXx.js.map +1 -0
- package/lib/{BitcoinWalletAdapterConnector-Bq835yj0.mjs → BitcoinWalletConnector-CS0BshOl.mjs} +11 -19
- package/lib/BitcoinWalletConnector-CS0BshOl.mjs.map +1 -0
- package/lib/{BitcoinWalletAdapterConnector.d.ts → BitcoinWalletConnector.d.ts} +4 -5
- package/lib/BitgetWalletAdapter.impl-D8kqiYDi.mjs +11 -0
- package/lib/BitgetWalletAdapter.impl-D8kqiYDi.mjs.map +1 -0
- package/lib/BitgetWalletAdapter.impl-DiyzNQ9d.js +2 -0
- package/lib/BitgetWalletAdapter.impl-DiyzNQ9d.js.map +1 -0
- package/lib/{LeatherWalletAdapter.impl-RUYx555r.mjs → LeatherWalletAdapter.impl-B1PoZS7z.mjs} +48 -37
- package/lib/LeatherWalletAdapter.impl-B1PoZS7z.mjs.map +1 -0
- package/lib/LeatherWalletAdapter.impl-BIWirus3.js +2 -0
- package/lib/LeatherWalletAdapter.impl-BIWirus3.js.map +1 -0
- package/lib/{MagicEdenWalletAdapter.impl-CrA6SGvG.mjs → MagicEdenWalletAdapter.impl-B3d5lbkD.mjs} +31 -20
- package/lib/MagicEdenWalletAdapter.impl-B3d5lbkD.mjs.map +1 -0
- package/lib/MagicEdenWalletAdapter.impl-DLBP3p4o.js +2 -0
- package/lib/MagicEdenWalletAdapter.impl-DLBP3p4o.js.map +1 -0
- package/lib/OkxWalletAdapter.impl-7cj96tmr.js +2 -0
- package/lib/OkxWalletAdapter.impl-7cj96tmr.js.map +1 -0
- package/lib/{OkxWalletAdapter.impl-BepoUL1B.mjs → OkxWalletAdapter.impl-nRgHsPTn.mjs} +13 -9
- package/lib/OkxWalletAdapter.impl-nRgHsPTn.mjs.map +1 -0
- package/lib/{UnisatCompatibleWalletAdapterImpl-M38FqkZI.mjs → UnisatCompatibleWalletAdapterImpl-8lRRF7Zj.mjs} +18 -10
- package/lib/UnisatCompatibleWalletAdapterImpl-8lRRF7Zj.mjs.map +1 -0
- package/lib/{UnisatCompatibleWalletAdapterImpl-Cq2Oqk1b.js → UnisatCompatibleWalletAdapterImpl-C-JWrc9s.js} +2 -2
- package/lib/UnisatCompatibleWalletAdapterImpl-C-JWrc9s.js.map +1 -0
- package/lib/UnisatWalletAdapter.impl-DXDfnHz_.js +2 -0
- package/lib/UnisatWalletAdapter.impl-DXDfnHz_.js.map +1 -0
- package/lib/UnisatWalletAdapter.impl-DvA33Ikj.mjs +19 -0
- package/lib/UnisatWalletAdapter.impl-DvA33Ikj.mjs.map +1 -0
- package/lib/WalletAdapters.types-CExaiK0o.js +2 -0
- package/lib/WalletAdapters.types-CExaiK0o.js.map +1 -0
- package/lib/WalletAdapters.types-DBvhI1hu.mjs +20 -0
- package/lib/WalletAdapters.types-DBvhI1hu.mjs.map +1 -0
- package/lib/WalletAdapters.types.d.ts +7 -12
- package/lib/{XverseCompatibleWalletAdapterImpl-Bf-BK5VK.js → XverseCompatibleWalletAdapterImpl-Dp_GUxQM.js} +2 -2
- package/lib/XverseCompatibleWalletAdapterImpl-Dp_GUxQM.js.map +1 -0
- package/lib/{XverseCompatibleWalletAdapterImpl-DXKnO_-V.mjs → XverseCompatibleWalletAdapterImpl-bgp9xDYH.mjs} +12 -8
- package/lib/XverseCompatibleWalletAdapterImpl-bgp9xDYH.mjs.map +1 -0
- package/lib/{XverseWalletAdapter.impl-CZO0RQva.mjs → XverseWalletAdapter.impl-BOpY4Vf8.mjs} +15 -15
- package/lib/XverseWalletAdapter.impl-BOpY4Vf8.mjs.map +1 -0
- package/lib/XverseWalletAdapter.impl-D0eOtEOa.js +2 -0
- package/lib/XverseWalletAdapter.impl-D0eOtEOa.js.map +1 -0
- package/lib/adapters/BitgetWalletAdapter.d.ts +6 -2
- package/lib/adapters/LeatherWalletAdapter.d.ts +4 -2
- package/lib/adapters/LeatherWalletAdapter.impl.d.ts +8 -1
- package/lib/adapters/MagicEdenWalletAdapter.d.ts +5 -2
- package/lib/adapters/MagicEdenWalletAdapter.impl.d.ts +1 -1
- package/lib/adapters/MockAddressWalletAdapter.d.ts +8 -32
- package/lib/adapters/OkxWalletAdapter.d.ts +3 -2
- package/lib/adapters/OkxWalletAdapter.impl.d.ts +5 -1
- package/lib/adapters/UnisatWalletAdapter.d.ts +3 -2
- package/lib/adapters/UnisatWalletAdapter.impl.d.ts +4 -0
- package/lib/adapters/XverseWalletAdapter.d.ts +3 -2
- package/lib/adapters/XverseWalletAdapter.impl.d.ts +1 -1
- package/lib/adapters/index.d.ts +6 -6
- package/lib/adapters.js +1 -1
- package/lib/adapters.mjs +8 -8
- package/lib/constants-B7qVf97f.mjs +5 -0
- package/lib/constants-B7qVf97f.mjs.map +1 -0
- package/lib/constants-Dr0_Mix2.js +2 -0
- package/lib/constants-Dr0_Mix2.js.map +1 -0
- package/lib/constants.d.ts +1 -0
- package/lib/{index-D7YwhNAG.mjs → index-DM4G-LJz.mjs} +639 -590
- package/lib/index-DM4G-LJz.mjs.map +1 -0
- package/lib/index-jRY8YhyK.js +2 -0
- package/lib/index-jRY8YhyK.js.map +1 -0
- package/lib/index.d.ts +1 -1
- package/lib/index.js +1 -1
- package/lib/index.mjs +13 -13
- package/lib/react.js +1 -1
- package/lib/react.js.map +1 -1
- package/lib/react.mjs +7 -7
- package/lib/react.mjs.map +1 -1
- package/lib/{transaction-CiLOYSE_.mjs → transaction-4ShhFCwN.mjs} +2 -2
- package/lib/{transaction-CiLOYSE_.mjs.map → transaction-4ShhFCwN.mjs.map} +1 -1
- package/lib/{transaction-CzdnbXSo.js → transaction-B6SlpRzN.js} +2 -2
- package/lib/{transaction-CzdnbXSo.js.map → transaction-B6SlpRzN.js.map} +1 -1
- package/lib/utils/UnisatCompatibleWalletAdapterImpl.d.ts +11 -3
- package/lib/utils/XverseCompatibleWalletAdapterImpl.d.ts +4 -0
- package/lib/utils/XverseCompatibleWalletAdapterImpl_legacy.d.ts +7 -2
- package/package.json +9 -10
- package/src/BitcoinConnectionProvider.stories.tsx +111 -43
- package/src/BitcoinConnectionProvider.tsx +5 -5
- package/src/{BitcoinWalletAdapterConnector.ts → BitcoinWalletConnector.ts} +18 -26
- package/src/WalletAdapters.types.ts +13 -22
- package/src/adapters/BitgetWalletAdapter.impl.ts +2 -1
- package/src/adapters/BitgetWalletAdapter.ts +9 -7
- package/src/adapters/LeatherWalletAdapter.impl.ts +23 -13
- package/src/adapters/LeatherWalletAdapter.ts +11 -8
- package/src/adapters/MagicEdenWalletAdapter.impl.ts +9 -8
- package/src/adapters/MagicEdenWalletAdapter.ts +17 -14
- package/src/adapters/MockAddressWalletAdapter.ts +61 -35
- package/src/adapters/OkxWalletAdapter.impl.ts +12 -7
- package/src/adapters/OkxWalletAdapter.ts +10 -7
- package/src/adapters/UnisatWalletAdapter.impl.ts +8 -2
- package/src/adapters/UnisatWalletAdapter.ts +9 -7
- package/src/adapters/XverseWalletAdapter.impl.ts +6 -6
- package/src/adapters/XverseWalletAdapter.ts +10 -7
- package/src/adapters/index.ts +6 -6
- package/src/constants.ts +1 -0
- package/src/index.ts +1 -1
- package/src/utils/UnisatCompatibleWalletAdapterImpl.ts +11 -2
- package/src/utils/XverseCompatibleWalletAdapterImpl.ts +4 -0
- package/src/utils/XverseCompatibleWalletAdapterImpl_legacy.ts +19 -7
- package/lib/BitcoinWalletAdapterConnector-Bq835yj0.mjs.map +0 -1
- package/lib/BitcoinWalletAdapterConnector-DMef0iHV.js +0 -2
- package/lib/BitcoinWalletAdapterConnector-DMef0iHV.js.map +0 -1
- package/lib/BitgetWalletAdapter.impl-C_HLO7Oi.mjs +0 -10
- package/lib/BitgetWalletAdapter.impl-C_HLO7Oi.mjs.map +0 -1
- package/lib/BitgetWalletAdapter.impl-CxnKMf7U.js +0 -2
- package/lib/BitgetWalletAdapter.impl-CxnKMf7U.js.map +0 -1
- package/lib/LeatherWalletAdapter.impl-B2QgX_tO.js +0 -2
- package/lib/LeatherWalletAdapter.impl-B2QgX_tO.js.map +0 -1
- package/lib/LeatherWalletAdapter.impl-RUYx555r.mjs.map +0 -1
- package/lib/MagicEdenWalletAdapter.impl-CrA6SGvG.mjs.map +0 -1
- package/lib/MagicEdenWalletAdapter.impl-Di3Nu2S5.js +0 -2
- package/lib/MagicEdenWalletAdapter.impl-Di3Nu2S5.js.map +0 -1
- package/lib/OkxWalletAdapter.impl-BepoUL1B.mjs.map +0 -1
- package/lib/OkxWalletAdapter.impl-C8kesjGu.js +0 -2
- package/lib/OkxWalletAdapter.impl-C8kesjGu.js.map +0 -1
- package/lib/UnisatCompatibleWalletAdapterImpl-Cq2Oqk1b.js.map +0 -1
- package/lib/UnisatCompatibleWalletAdapterImpl-M38FqkZI.mjs.map +0 -1
- package/lib/UnisatWalletAdapter.impl-CJB22se8.mjs +0 -14
- package/lib/UnisatWalletAdapter.impl-CJB22se8.mjs.map +0 -1
- package/lib/UnisatWalletAdapter.impl-EISvxdpc.js +0 -2
- package/lib/UnisatWalletAdapter.impl-EISvxdpc.js.map +0 -1
- package/lib/WalletAdapters.types-CnvOqHFH.mjs +0 -32
- package/lib/WalletAdapters.types-CnvOqHFH.mjs.map +0 -1
- package/lib/WalletAdapters.types-De_x1lzr.js +0 -2
- package/lib/WalletAdapters.types-De_x1lzr.js.map +0 -1
- package/lib/XverseCompatibleWalletAdapterImpl-Bf-BK5VK.js.map +0 -1
- package/lib/XverseCompatibleWalletAdapterImpl-DXKnO_-V.mjs.map +0 -1
- package/lib/XverseWalletAdapter.impl-CZO0RQva.mjs.map +0 -1
- package/lib/XverseWalletAdapter.impl-lJwMi-Iv.js +0 -2
- package/lib/XverseWalletAdapter.impl-lJwMi-Iv.js.map +0 -1
- package/lib/index-D7YwhNAG.mjs.map +0 -1
- package/lib/index-Zx0KcpYx.js +0 -2
- package/lib/index-Zx0KcpYx.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SignMessageResult, WalletAdapter, WalletAdapter_onAddressesChanged_callback, WalletAdapterAddress } from '../WalletAdapters.types';
|
|
1
|
+
import { SignMessageResult, WalletAdapter, WalletAdapter_onAddressesChanged_callback, WalletAdapterAddress, WalletAdapterSendBitcoinCapability } from '../WalletAdapters.types';
|
|
2
2
|
/**
|
|
3
3
|
* https://docs.unisat.io/dev-center/open-api-documentation/unisat-wallet#events
|
|
4
4
|
*/
|
|
@@ -69,13 +69,21 @@ export declare class UnisatCompatibleWalletAdapterImpl implements WalletAdapter
|
|
|
69
69
|
disconnect(): Promise<void>;
|
|
70
70
|
getAddresses(): Promise<UnisatCompatibleWalletAdapterAddresses>;
|
|
71
71
|
signMessage(address: string, message: string): Promise<SignMessageResult>;
|
|
72
|
-
sendBitcoinFeeRateCapability:
|
|
72
|
+
sendBitcoinFeeRateCapability: WalletAdapterSendBitcoinCapability;
|
|
73
73
|
sendBitcoin(fromAddress: string, receiverAddress: string, satoshiAmount: bigint, options?: {
|
|
74
74
|
feeRate?: number;
|
|
75
75
|
}): Promise<{
|
|
76
76
|
txid: string;
|
|
77
77
|
}>;
|
|
78
|
-
|
|
78
|
+
/**
|
|
79
|
+
* @internal
|
|
80
|
+
* @experimental
|
|
81
|
+
*/
|
|
82
|
+
sendInscriptionFeeRateCapability: "unavailable" | "available" | "required";
|
|
83
|
+
/**
|
|
84
|
+
* @internal
|
|
85
|
+
* @experimental
|
|
86
|
+
*/
|
|
79
87
|
sendInscription(fromAddress: string, receiverAddress: string, inscriptionId: string, options?: {
|
|
80
88
|
feeRate?: number;
|
|
81
89
|
}): Promise<{
|
|
@@ -26,6 +26,10 @@ export declare class XverseCompatibleWalletAdapterImpl implements WalletAdapter
|
|
|
26
26
|
sendBitcoin(fromAddress: string, receiverAddress: string, satoshiAmount: bigint): Promise<{
|
|
27
27
|
txid: string;
|
|
28
28
|
}>;
|
|
29
|
+
/**
|
|
30
|
+
* @internal
|
|
31
|
+
* @experimental
|
|
32
|
+
*/
|
|
29
33
|
sendInscriptionFeeRateCapability: "unavailable";
|
|
30
34
|
signAndFinalizePsbt(psbtHex: string, signIndices: [address: string, signIndex: number][]): Promise<{
|
|
31
35
|
signedPsbtHex: string;
|
|
@@ -10,18 +10,19 @@ export type XverseCompatibleWalletAdapterImplAddress = WalletAdapterAddress & {
|
|
|
10
10
|
};
|
|
11
11
|
export declare class XverseCompatibleWalletAdapterImpl_legacy implements WalletAdapter {
|
|
12
12
|
protected readonly network: WalletAdapterBitcoinNetwork;
|
|
13
|
-
protected readonly
|
|
13
|
+
protected readonly localStorageKeyPrefix: string;
|
|
14
14
|
protected readonly walletDisplayName: string;
|
|
15
15
|
protected readonly getProvider: XverseCompatibleWalletAdapterGetProviderFn;
|
|
16
16
|
protected readonly parseAddresses: XverseCompatibleWalletAdapterParsedAddressesFn;
|
|
17
17
|
constructor(info: {
|
|
18
18
|
network: WalletAdapterBitcoinNetwork;
|
|
19
|
-
|
|
19
|
+
localStorageKeyPrefix: string;
|
|
20
20
|
walletDisplayName: string;
|
|
21
21
|
getProvider: XverseCompatibleWalletAdapterGetProviderFn;
|
|
22
22
|
parseAddresses: XverseCompatibleWalletAdapterParsedAddressesFn;
|
|
23
23
|
});
|
|
24
24
|
private getSdk;
|
|
25
|
+
protected get connectAddresses_localStorageKey(): string;
|
|
25
26
|
protected retrieveConnectedAddress(): GetAddressResponse | undefined;
|
|
26
27
|
protected updateConnectedAddress(addresses: GetAddressResponse["addresses"]): Promise<void>;
|
|
27
28
|
connect(): Promise<void>;
|
|
@@ -33,6 +34,10 @@ export declare class XverseCompatibleWalletAdapterImpl_legacy implements WalletA
|
|
|
33
34
|
sendBitcoin(fromAddress: string, receiverAddress: string, satoshiAmount: bigint): Promise<{
|
|
34
35
|
txid: string;
|
|
35
36
|
}>;
|
|
37
|
+
/**
|
|
38
|
+
* @internal
|
|
39
|
+
* @experimental
|
|
40
|
+
*/
|
|
36
41
|
sendInscriptionFeeRateCapability: "unavailable";
|
|
37
42
|
signAndFinalizePsbt(psbtHex: string, signIndices: [address: string, signIndex: number][]): Promise<{
|
|
38
43
|
signedPsbtHex: string;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bitcoin-wallet-connector",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A Bitcoin wallet connector with various adapters.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/index.mjs",
|
|
@@ -26,14 +26,6 @@
|
|
|
26
26
|
"lib",
|
|
27
27
|
"src"
|
|
28
28
|
],
|
|
29
|
-
"scripts": {
|
|
30
|
-
"prepare": "pnpm run build",
|
|
31
|
-
"postinstall": "git-hook-pure install",
|
|
32
|
-
"build": "vite build",
|
|
33
|
-
"test": "vitest",
|
|
34
|
-
"storybook": "storybook dev -p 6006",
|
|
35
|
-
"build-storybook": "storybook build"
|
|
36
|
-
},
|
|
37
29
|
"devDependencies": {
|
|
38
30
|
"@commitlint/cli": "^20.3.0",
|
|
39
31
|
"@commitlint/config-conventional": "^20.3.0",
|
|
@@ -82,5 +74,12 @@
|
|
|
82
74
|
"sats-connect": {
|
|
83
75
|
"optional": true
|
|
84
76
|
}
|
|
77
|
+
},
|
|
78
|
+
"scripts": {
|
|
79
|
+
"postinstall": "git-hook-pure install",
|
|
80
|
+
"build": "vite build",
|
|
81
|
+
"test": "vitest",
|
|
82
|
+
"storybook": "storybook dev -p 6006",
|
|
83
|
+
"build-storybook": "storybook build"
|
|
85
84
|
}
|
|
86
|
-
}
|
|
85
|
+
}
|
|
@@ -1,30 +1,34 @@
|
|
|
1
1
|
import { Meta, StoryFn } from "@storybook/react-vite"
|
|
2
|
-
import React, { useState } from "react"
|
|
2
|
+
import React, { FC, useEffect, useState } from "react"
|
|
3
3
|
import {
|
|
4
4
|
BitcoinConnectionProvider,
|
|
5
5
|
useBitcoinConnectionContext,
|
|
6
6
|
WalletSession,
|
|
7
7
|
} from "./BitcoinConnectionProvider"
|
|
8
8
|
import {
|
|
9
|
+
WalletAdapter,
|
|
9
10
|
WalletAdapterAddress,
|
|
10
11
|
WalletAdapterBitcoinNetwork,
|
|
12
|
+
WalletAdapterFactory,
|
|
11
13
|
} from "./WalletAdapters.types"
|
|
12
14
|
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
UnisatWalletAdapterFactory,
|
|
16
|
+
XverseWalletAdapterFactory,
|
|
17
|
+
OkxWalletAdapterFactory,
|
|
18
|
+
LeatherWalletAdapterFactory,
|
|
19
|
+
BitgetWalletAdapterFactory,
|
|
18
20
|
MagicEdenWalletAdapterFactory,
|
|
19
21
|
} from "./adapters"
|
|
20
22
|
|
|
21
|
-
const adapterFactories = [
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
MagicEdenWalletAdapterFactory(
|
|
23
|
+
const adapterFactories: WalletAdapterFactory<WalletAdapter>[] = [
|
|
24
|
+
UnisatWalletAdapterFactory(),
|
|
25
|
+
XverseWalletAdapterFactory(),
|
|
26
|
+
OkxWalletAdapterFactory(),
|
|
27
|
+
LeatherWalletAdapterFactory(),
|
|
28
|
+
BitgetWalletAdapterFactory(),
|
|
29
|
+
MagicEdenWalletAdapterFactory({
|
|
30
|
+
network: WalletAdapterBitcoinNetwork.MAINNET,
|
|
31
|
+
}),
|
|
28
32
|
]
|
|
29
33
|
|
|
30
34
|
export default {
|
|
@@ -104,34 +108,49 @@ const WalletConnectionContent = (): React.ReactElement => {
|
|
|
104
108
|
<div style={{ marginBottom: "16px" }}>
|
|
105
109
|
<h3>Available Wallets ({ctx.availableAdapters.length})</h3>
|
|
106
110
|
<div style={{ display: "flex", flexWrap: "wrap", gap: "8px" }}>
|
|
107
|
-
{ctx.availableAdapters.map(([adapterId, adapter]) =>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
})
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
111
|
+
{ctx.availableAdapters.map(([adapterId, adapter]) => {
|
|
112
|
+
const factory = adapterFactories.find(
|
|
113
|
+
factory => factory.adapterId === adapterId,
|
|
114
|
+
)!
|
|
115
|
+
|
|
116
|
+
return (
|
|
117
|
+
<div
|
|
118
|
+
key={adapterId}
|
|
119
|
+
onClick={() => {
|
|
120
|
+
addDebugInfo(`Connecting to ${adapterId}...`)
|
|
121
|
+
ctx
|
|
122
|
+
.connect(adapterId, adapter)
|
|
123
|
+
.then(() => {
|
|
124
|
+
addDebugInfo(`Connected to ${adapterId}`)
|
|
125
|
+
})
|
|
126
|
+
.catch(err => {
|
|
127
|
+
addDebugInfo(`Failed to connect: ${err.message}`)
|
|
128
|
+
})
|
|
129
|
+
}}
|
|
130
|
+
style={{
|
|
131
|
+
display: "flex",
|
|
132
|
+
alignItems: "center",
|
|
133
|
+
justifyContent: "center",
|
|
134
|
+
padding: "8px 16px",
|
|
135
|
+
cursor: ctx.isConnectionInitializing
|
|
136
|
+
? "not-allowed"
|
|
137
|
+
: "pointer",
|
|
138
|
+
border: "1px solid #ccc",
|
|
139
|
+
borderRadius: "4px",
|
|
140
|
+
background: "#fff",
|
|
141
|
+
}}
|
|
142
|
+
>
|
|
143
|
+
{ctx.isConnectionInitializing ? (
|
|
144
|
+
"Connecting..."
|
|
145
|
+
) : (
|
|
146
|
+
<>
|
|
147
|
+
<WalletIcon adapterFactory={factory} />
|
|
148
|
+
<span>{factory.metadata.name}</span>
|
|
149
|
+
</>
|
|
150
|
+
)}
|
|
151
|
+
</div>
|
|
152
|
+
)
|
|
153
|
+
})}
|
|
135
154
|
</div>
|
|
136
155
|
</div>
|
|
137
156
|
|
|
@@ -248,7 +267,7 @@ const WalletConnectionContent = (): React.ReactElement => {
|
|
|
248
267
|
<h3>Registered Adapter Factories ({ctx.adapterFactories.length})</h3>
|
|
249
268
|
<ul>
|
|
250
269
|
{ctx.adapterFactories.map((factory, i) => (
|
|
251
|
-
<li key={i}>{factory.
|
|
270
|
+
<li key={i}>{factory.metadata.name}</li>
|
|
252
271
|
))}
|
|
253
272
|
</ul>
|
|
254
273
|
</div>
|
|
@@ -303,7 +322,6 @@ export const Default: StoryFn<typeof BitcoinConnectionProvider> = () => {
|
|
|
303
322
|
addEvent(`Addresses changed: ${addresses.length} addresses`)
|
|
304
323
|
}}
|
|
305
324
|
onWalletDisconnected={() => {
|
|
306
|
-
debugger
|
|
307
325
|
addEvent("Wallet disconnected")
|
|
308
326
|
}}
|
|
309
327
|
>
|
|
@@ -327,3 +345,53 @@ export const Default: StoryFn<typeof BitcoinConnectionProvider> = () => {
|
|
|
327
345
|
</BitcoinConnectionProvider>
|
|
328
346
|
)
|
|
329
347
|
}
|
|
348
|
+
|
|
349
|
+
const WalletIcon: FC<{
|
|
350
|
+
adapterFactory: WalletAdapterFactory<WalletAdapter>
|
|
351
|
+
}> = ({ adapterFactory }) => {
|
|
352
|
+
const [iconUrl, setIconUrl] = useState<null | string>(null)
|
|
353
|
+
|
|
354
|
+
useEffect(() => {
|
|
355
|
+
const abortController = new AbortController()
|
|
356
|
+
|
|
357
|
+
void adapterFactory.metadata
|
|
358
|
+
.iconUrl()
|
|
359
|
+
.then(url => {
|
|
360
|
+
if (abortController.signal.aborted) return
|
|
361
|
+
setIconUrl(url)
|
|
362
|
+
})
|
|
363
|
+
.catch(err => {
|
|
364
|
+
console.error(
|
|
365
|
+
"Failed to load icon for ",
|
|
366
|
+
adapterFactory.metadata.name,
|
|
367
|
+
err,
|
|
368
|
+
)
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
return () => {
|
|
372
|
+
abortController.abort()
|
|
373
|
+
}
|
|
374
|
+
}, [adapterFactory.metadata])
|
|
375
|
+
|
|
376
|
+
if (!iconUrl) {
|
|
377
|
+
return (
|
|
378
|
+
<div
|
|
379
|
+
style={{
|
|
380
|
+
width: "24px",
|
|
381
|
+
height: "24px",
|
|
382
|
+
marginRight: "8px",
|
|
383
|
+
borderRadius: "4px",
|
|
384
|
+
background: "#eaeaea",
|
|
385
|
+
}}
|
|
386
|
+
></div>
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
return (
|
|
391
|
+
<img
|
|
392
|
+
src={iconUrl}
|
|
393
|
+
alt={adapterFactory.metadata.name}
|
|
394
|
+
style={{ width: "24px", height: "24px", marginRight: "8px" }}
|
|
395
|
+
/>
|
|
396
|
+
)
|
|
397
|
+
}
|
|
@@ -9,11 +9,11 @@ import {
|
|
|
9
9
|
useRef,
|
|
10
10
|
useState,
|
|
11
11
|
} from "react"
|
|
12
|
-
import {
|
|
12
|
+
import { BitcoinWalletConnector } from "./BitcoinWalletConnector"
|
|
13
13
|
import {
|
|
14
14
|
WalletAdapter,
|
|
15
15
|
WalletAdapterAddress,
|
|
16
|
-
|
|
16
|
+
WalletAdapterFactory,
|
|
17
17
|
} from "./WalletAdapters.types"
|
|
18
18
|
|
|
19
19
|
export interface WalletSession {
|
|
@@ -30,7 +30,7 @@ export interface BitcoinConnectionContextValue {
|
|
|
30
30
|
disconnect: () => Promise<void>
|
|
31
31
|
|
|
32
32
|
// Wallet management (for UI)
|
|
33
|
-
adapterFactories:
|
|
33
|
+
adapterFactories: WalletAdapterFactory<WalletAdapter>[]
|
|
34
34
|
availableAdapters: (readonly [adapterId: string, adapter: WalletAdapter])[]
|
|
35
35
|
}
|
|
36
36
|
|
|
@@ -55,7 +55,7 @@ function useConnectorState<T>(
|
|
|
55
55
|
|
|
56
56
|
export const BitcoinConnectionProvider: FC<{
|
|
57
57
|
children: ReactNode
|
|
58
|
-
adapterFactories:
|
|
58
|
+
adapterFactories: WalletAdapterFactory<WalletAdapter>[]
|
|
59
59
|
onWalletConnected?: (session: WalletSession) => void
|
|
60
60
|
onWalletAddressesChanged?: (addresses: WalletAdapterAddress[]) => void
|
|
61
61
|
onWalletDisconnected?: () => void
|
|
@@ -71,7 +71,7 @@ export const BitcoinConnectionProvider: FC<{
|
|
|
71
71
|
const onWalletDisconnected = usePersistFn(props.onWalletDisconnected ?? noop)
|
|
72
72
|
|
|
73
73
|
const connector = useMemo(
|
|
74
|
-
() => new
|
|
74
|
+
() => new BitcoinWalletConnector(props.adapterFactories),
|
|
75
75
|
[props.adapterFactories],
|
|
76
76
|
)
|
|
77
77
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import { LOCAL_STORAGE_KEY_PREFIX } from "./constants"
|
|
1
2
|
import { AvailabilitySubscription } from "./utils/createAdapterAvailability"
|
|
2
|
-
import { BitcoinWalletAdapterError } from "./utils/error"
|
|
3
3
|
import { StateChannel, StateChannelListener } from "./utils/StateChannel"
|
|
4
4
|
import {
|
|
5
5
|
WalletAdapter,
|
|
6
|
+
WalletAdapterFactory,
|
|
6
7
|
WalletAdapterNotConnectedError,
|
|
7
|
-
WalletAdapterStatic,
|
|
8
8
|
} from "./WalletAdapters.types"
|
|
9
9
|
|
|
10
|
-
const
|
|
11
|
-
|
|
10
|
+
const localStorageKeyPrefix = `${LOCAL_STORAGE_KEY_PREFIX}:BitcoinWalletConnector`
|
|
11
|
+
const previousConnectWalletAdapterId_localStorageKey = `${localStorageKeyPrefix}:previousConnectWallet`
|
|
12
12
|
|
|
13
13
|
export interface ConnectInfo {
|
|
14
14
|
adapterId: string
|
|
@@ -17,16 +17,16 @@ export interface ConnectInfo {
|
|
|
17
17
|
|
|
18
18
|
export type AdapterEntry = readonly [string, WalletAdapter]
|
|
19
19
|
|
|
20
|
-
export class
|
|
20
|
+
export class BitcoinWalletConnector {
|
|
21
21
|
private availableAdaptersState = new StateChannel<AdapterEntry[]>([])
|
|
22
22
|
private connectedInfoState = new StateChannel<null | ConnectInfo>(null)
|
|
23
23
|
private autoConnectRunning = false
|
|
24
24
|
private availabilitySubscriptions: AvailabilitySubscription[] = []
|
|
25
25
|
private adapterOrder = new Map<string, number>()
|
|
26
26
|
|
|
27
|
-
constructor(private
|
|
27
|
+
constructor(private factories: WalletAdapterFactory<WalletAdapter>[]) {
|
|
28
28
|
this.adapterOrder = new Map(
|
|
29
|
-
|
|
29
|
+
factories.map((factory, index) => [factory.adapterId, index]),
|
|
30
30
|
)
|
|
31
31
|
this.initializeAdapterAvailability()
|
|
32
32
|
}
|
|
@@ -57,9 +57,9 @@ export class BitcoinWalletAdapterConnector {
|
|
|
57
57
|
}
|
|
58
58
|
|
|
59
59
|
private initializeAdapterAvailability(): void {
|
|
60
|
-
this.availabilitySubscriptions = this.
|
|
61
|
-
return
|
|
62
|
-
this.addOrUpdateAvailableAdapter(
|
|
60
|
+
this.availabilitySubscriptions = this.factories.map(factory => {
|
|
61
|
+
return factory.getAdapter().subscribe(adapter => {
|
|
62
|
+
this.addOrUpdateAvailableAdapter(factory.adapterId, adapter)
|
|
63
63
|
})
|
|
64
64
|
})
|
|
65
65
|
}
|
|
@@ -91,16 +91,9 @@ export class BitcoinWalletAdapterConnector {
|
|
|
91
91
|
async connect(adapterId: string, adapter: WalletAdapter): Promise<void> {
|
|
92
92
|
const finalAdapter = adapter
|
|
93
93
|
|
|
94
|
-
await finalAdapter.connect()
|
|
95
|
-
if (err instanceof BitcoinWalletAdapterError) {
|
|
96
|
-
alert(err.message)
|
|
97
|
-
return
|
|
98
|
-
}
|
|
99
|
-
throw err
|
|
100
|
-
})
|
|
101
|
-
|
|
94
|
+
await finalAdapter.connect()
|
|
102
95
|
localStorage.setItem(
|
|
103
|
-
|
|
96
|
+
previousConnectWalletAdapterId_localStorageKey,
|
|
104
97
|
adapterId,
|
|
105
98
|
)
|
|
106
99
|
|
|
@@ -110,13 +103,12 @@ export class BitcoinWalletAdapterConnector {
|
|
|
110
103
|
async disconnect(): Promise<void> {
|
|
111
104
|
const info = this.connectedInfoState.getValue()
|
|
112
105
|
if (info == null) return
|
|
113
|
-
|
|
106
|
+
|
|
107
|
+
await info.adapter.disconnect()
|
|
108
|
+
localStorage.removeItem(previousConnectWalletAdapterId_localStorageKey)
|
|
109
|
+
|
|
114
110
|
this.connectedInfoState.setValue(null)
|
|
115
111
|
}
|
|
116
|
-
private async disconnectAdapter(adapter: WalletAdapter): Promise<void> {
|
|
117
|
-
await adapter.disconnect()
|
|
118
|
-
localStorage.removeItem(previousConnectWalletAdapterIdLocalStorageKey)
|
|
119
|
-
}
|
|
120
112
|
|
|
121
113
|
private async autoConnect(): Promise<void> {
|
|
122
114
|
if (this.isConnected || this.autoConnectRunning) return
|
|
@@ -151,10 +143,10 @@ export class BitcoinWalletAdapterConnector {
|
|
|
151
143
|
|
|
152
144
|
private get previousConnectedWallet(): string | undefined {
|
|
153
145
|
const adapterId =
|
|
154
|
-
localStorage.getItem(
|
|
146
|
+
localStorage.getItem(previousConnectWalletAdapterId_localStorageKey) ||
|
|
155
147
|
undefined
|
|
156
148
|
|
|
157
|
-
if (this.
|
|
149
|
+
if (this.factories.some(factory => factory.adapterId === adapterId)) {
|
|
158
150
|
return adapterId
|
|
159
151
|
}
|
|
160
152
|
return undefined
|
|
@@ -84,12 +84,12 @@ export interface WalletAdapterAddress extends Partial<
|
|
|
84
84
|
|
|
85
85
|
export interface WalletAdapterMetadata {
|
|
86
86
|
name: string
|
|
87
|
-
iconUrl: Promise<string>
|
|
87
|
+
iconUrl: () => Promise<string>
|
|
88
88
|
websiteUrl: string
|
|
89
89
|
downloadUrl: string
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
export interface
|
|
92
|
+
export interface WalletAdapterFactory<T extends WalletAdapter> {
|
|
93
93
|
adapterId: string
|
|
94
94
|
metadata: WalletAdapterMetadata
|
|
95
95
|
getAdapter(): Availability<T>
|
|
@@ -111,34 +111,25 @@ export interface WalletAdapter {
|
|
|
111
111
|
|
|
112
112
|
signMessage(address: string, message: string): Promise<SignMessageResult>
|
|
113
113
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
114
|
+
signAndFinalizePsbt(
|
|
115
|
+
psbtHex: string,
|
|
116
|
+
signIndices: [address: string, signIndex: number][],
|
|
117
|
+
): Promise<{ signedPsbtHex: string }>
|
|
118
|
+
|
|
119
|
+
sendBitcoinFeeRateCapability: WalletAdapterSendBitcoinCapability
|
|
118
120
|
sendBitcoin(
|
|
119
121
|
fromAddress: string,
|
|
120
122
|
receiverAddress: string,
|
|
121
123
|
satoshiAmount: bigint,
|
|
122
124
|
options?: { feeRate?: number },
|
|
123
125
|
): Promise<{ txid: string }>
|
|
124
|
-
|
|
125
|
-
readonly sendInscriptionFeeRateCapability:
|
|
126
|
-
| "unavailable"
|
|
127
|
-
| "available"
|
|
128
|
-
| "required"
|
|
129
|
-
sendInscription?(
|
|
130
|
-
fromAddress: string,
|
|
131
|
-
receiverAddress: string,
|
|
132
|
-
inscriptionId: string,
|
|
133
|
-
options?: { feeRate?: number },
|
|
134
|
-
): Promise<{ txid: string }>
|
|
135
|
-
|
|
136
|
-
signAndFinalizePsbt(
|
|
137
|
-
psbtHex: string,
|
|
138
|
-
signIndices: [address: string, signIndex: number][],
|
|
139
|
-
): Promise<{ signedPsbtHex: string }>
|
|
140
126
|
}
|
|
141
127
|
|
|
128
|
+
export type WalletAdapterSendBitcoinCapability =
|
|
129
|
+
| "unavailable"
|
|
130
|
+
| "available"
|
|
131
|
+
| "required"
|
|
132
|
+
|
|
142
133
|
export class WalletAdapterErrorBase extends Error {
|
|
143
134
|
constructor(message: string) {
|
|
144
135
|
super(message)
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
UnisatCompatibleWalletAdapterImpl,
|
|
4
4
|
} from "../utils/UnisatCompatibleWalletAdapterImpl"
|
|
5
5
|
import { WalletAdapter } from "../WalletAdapters.types"
|
|
6
|
+
import { metadata } from "./BitgetWalletAdapter"
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Derivation path (BIP-44): m/44'/0'/0'/0/ address_index
|
|
@@ -17,6 +18,6 @@ export class BitgetWalletAdapterImpl
|
|
|
17
18
|
*
|
|
18
19
|
* https://web3.bitget.com/zh-CN/docs/provider-api/btc.html
|
|
19
20
|
*/
|
|
20
|
-
super(provider,
|
|
21
|
+
super(provider, metadata.name)
|
|
21
22
|
}
|
|
22
23
|
}
|
|
@@ -3,7 +3,7 @@ import type { UnisatCompatibleProviderAPI } from "../utils/UnisatCompatibleWalle
|
|
|
3
3
|
import type {
|
|
4
4
|
WalletAdapter,
|
|
5
5
|
WalletAdapterMetadata,
|
|
6
|
-
|
|
6
|
+
WalletAdapterFactory,
|
|
7
7
|
} from "../WalletAdapters.types"
|
|
8
8
|
|
|
9
9
|
/**
|
|
@@ -15,9 +15,9 @@ const adapterId = "bitget.bitcoin"
|
|
|
15
15
|
/**
|
|
16
16
|
* https://web3.bitget.com/en/docs/wallet/brand-assets.html
|
|
17
17
|
*/
|
|
18
|
-
const metadata: WalletAdapterMetadata = {
|
|
18
|
+
export const metadata: WalletAdapterMetadata = {
|
|
19
19
|
name: "Bitget",
|
|
20
|
-
iconUrl: import("../_/bitget.png").then(m => m.default),
|
|
20
|
+
iconUrl: () => import("../_/bitget.png").then(m => m.default),
|
|
21
21
|
websiteUrl: "https://web3.bitget.com/",
|
|
22
22
|
downloadUrl: "https://web3.bitget.com/en/wallet-download",
|
|
23
23
|
}
|
|
@@ -37,8 +37,10 @@ const availability = createAvailability<
|
|
|
37
37
|
},
|
|
38
38
|
})
|
|
39
39
|
|
|
40
|
-
export
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
export function BitgetWalletAdapterFactory(): WalletAdapterFactory<WalletAdapter> {
|
|
41
|
+
return {
|
|
42
|
+
adapterId,
|
|
43
|
+
metadata,
|
|
44
|
+
getAdapter: () => availability,
|
|
45
|
+
}
|
|
44
46
|
}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import type { RequestFn, RpcErrorBody, RpcErrorResponse } from "@leather.io/rpc"
|
|
2
2
|
import { hex } from "@scure/base"
|
|
3
|
+
import { LOCAL_STORAGE_KEY_PREFIX } from "../constants"
|
|
3
4
|
import {
|
|
4
5
|
addressToScriptPubKey,
|
|
5
6
|
getTapInternalKeyOf_P2TR_publicKey,
|
|
6
7
|
} from "../utils/bitcoinAddressHelpers"
|
|
7
8
|
import { getBitcoinNetwork } from "../utils/bitcoinNetworkHelpers"
|
|
8
|
-
import {
|
|
9
|
+
import { BitcoinWalletAdapterError, UserRejectError } from "../utils/error"
|
|
9
10
|
import {
|
|
10
11
|
SignMessageAlgorithm,
|
|
11
12
|
SignMessageResult,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
WalletAdapterBitcoinNetwork,
|
|
18
19
|
WalletAdapterNotConnectedError,
|
|
19
20
|
} from "../WalletAdapters.types"
|
|
21
|
+
import { adapterId, metadata } from "./LeatherWalletAdapter"
|
|
20
22
|
|
|
21
23
|
type GetAddressesResponseData = any
|
|
22
24
|
|
|
@@ -41,9 +43,8 @@ enum RpcErrorCode {
|
|
|
41
43
|
|
|
42
44
|
type Addresses = (WalletAdapterAddress & { publicKey: string })[]
|
|
43
45
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const localStorageKey = `app:${LEATHER_PROVIDER_ID}:`
|
|
46
|
+
const localStorageKeyPrefix = `${LOCAL_STORAGE_KEY_PREFIX}:${adapterId}`
|
|
47
|
+
const connectedAddress_localStorageKey = `${localStorageKeyPrefix}:connectedAddress`
|
|
47
48
|
|
|
48
49
|
/**
|
|
49
50
|
* Derivation path (BIP-84): m/84'/0'/ account_index '/0/0
|
|
@@ -51,11 +52,10 @@ const localStorageKey = `app:${LEATHER_PROVIDER_ID}:`
|
|
|
51
52
|
export class LeatherWalletAdapterImpl implements WalletAdapter {
|
|
52
53
|
constructor(private request: RequestFn) {}
|
|
53
54
|
|
|
54
|
-
private readonly walletDisplayName = "Leather"
|
|
55
|
-
|
|
56
55
|
private retrieveConnectedAddress(): GetAddressesResponseData | undefined {
|
|
57
56
|
let resp: GetAddressesResponseData | undefined
|
|
58
|
-
const stored =
|
|
57
|
+
const stored =
|
|
58
|
+
localStorage.getItem(connectedAddress_localStorageKey) || undefined
|
|
59
59
|
if (stored != null) {
|
|
60
60
|
try {
|
|
61
61
|
resp = JSON.parse(stored)
|
|
@@ -67,7 +67,7 @@ export class LeatherWalletAdapterImpl implements WalletAdapter {
|
|
|
67
67
|
throw new Error("Invalid stored addresses")
|
|
68
68
|
}
|
|
69
69
|
} catch {
|
|
70
|
-
localStorage.removeItem(
|
|
70
|
+
localStorage.removeItem(connectedAddress_localStorageKey)
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
return resp
|
|
@@ -81,12 +81,15 @@ export class LeatherWalletAdapterImpl implements WalletAdapter {
|
|
|
81
81
|
*/
|
|
82
82
|
this.request("getAddresses"),
|
|
83
83
|
)
|
|
84
|
-
localStorage.setItem(
|
|
84
|
+
localStorage.setItem(
|
|
85
|
+
connectedAddress_localStorageKey,
|
|
86
|
+
JSON.stringify(resp),
|
|
87
|
+
)
|
|
85
88
|
}
|
|
86
89
|
}
|
|
87
90
|
|
|
88
91
|
async disconnect(): Promise<void> {
|
|
89
|
-
localStorage.removeItem(
|
|
92
|
+
localStorage.removeItem(connectedAddress_localStorageKey)
|
|
90
93
|
return Promise.resolve()
|
|
91
94
|
}
|
|
92
95
|
|
|
@@ -94,7 +97,7 @@ export class LeatherWalletAdapterImpl implements WalletAdapter {
|
|
|
94
97
|
const resp = this.retrieveConnectedAddress()
|
|
95
98
|
|
|
96
99
|
if (resp == null) {
|
|
97
|
-
throw new WalletAdapterNotConnectedError(
|
|
100
|
+
throw new WalletAdapterNotConnectedError(metadata.name)
|
|
98
101
|
}
|
|
99
102
|
|
|
100
103
|
const addresses = resp.addresses.filter(
|
|
@@ -200,8 +203,15 @@ export class LeatherWalletAdapterImpl implements WalletAdapter {
|
|
|
200
203
|
return { txid: resp.txid }
|
|
201
204
|
}
|
|
202
205
|
|
|
206
|
+
/**
|
|
207
|
+
* @internal
|
|
208
|
+
* @experimental
|
|
209
|
+
*/
|
|
203
210
|
sendInscriptionFeeRateCapability = "available" as const
|
|
204
|
-
|
|
211
|
+
/**
|
|
212
|
+
* @internal
|
|
213
|
+
* @experimental
|
|
214
|
+
*/
|
|
205
215
|
async sendInscription(
|
|
206
216
|
fromAddress: string,
|
|
207
217
|
receiverAddress: string,
|
|
@@ -238,7 +248,7 @@ export class LeatherWalletAdapterImpl implements WalletAdapter {
|
|
|
238
248
|
account => account.address === signIndices[0]?.[0],
|
|
239
249
|
)
|
|
240
250
|
if (signingAccount == null) {
|
|
241
|
-
throw new WalletAdapterNotConnectedError(
|
|
251
|
+
throw new WalletAdapterNotConnectedError(metadata.name)
|
|
242
252
|
}
|
|
243
253
|
|
|
244
254
|
const resp: any = await handleRpcError(
|