@dynamic-labs/bitcoin 5.0.0-rc.0 → 5.0.0-rc.2
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/CHANGELOG.md +74 -1
- package/package.cjs +1 -1
- package/package.js +1 -1
- package/package.json +11 -11
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.cjs +131 -30
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.d.ts +87 -16
- package/src/connectors/DynamicWaasBitcoinConnector/DynamicWaasBitcoinConnector.js +131 -30
- package/src/utils/BitcoinUiTransaction/BitcoinUiTransaction.cjs +3 -0
- package/src/utils/BitcoinUiTransaction/BitcoinUiTransaction.d.ts +1 -0
- package/src/utils/BitcoinUiTransaction/BitcoinUiTransaction.js +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,78 @@
|
|
|
1
1
|
|
|
2
|
-
## [5.0.0-rc.
|
|
2
|
+
## [5.0.0-rc.2](https://github.com/dynamic-labs/dynamic-auth/compare/v5.0.0-rc.1...v5.0.0-rc.2) (2026-07-17)
|
|
3
|
+
|
|
4
|
+
## [5.0.0-rc.1](https://github.com/dynamic-labs/dynamic-auth/compare/v5.0.0-rc.0...v5.0.0-rc.1) (2026-07-17)
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
### ⚠ BREAKING CHANGES
|
|
8
|
+
|
|
9
|
+
* move legacy embedded wallet to waas upgrade flow to new legacy-embedded-wallet-migration package (#11841)
|
|
10
|
+
* drop default injection of legacy embedded wallet connectors (#11833)
|
|
11
|
+
* remove legacy embedded wallet support (#11979)
|
|
12
|
+
* throw when legacy embedded wallet is detected without migration provider (#11855)
|
|
13
|
+
* remove deprecated eclipse package (#11831)
|
|
14
|
+
* remove deprecated functions and props (#11832)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
### [4.92.4](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.3...v4.92.4) (2026-07-16)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Features
|
|
21
|
+
|
|
22
|
+
* **bitcoin:** per-network address switching and dust-limit send validation [v4] ([#11970](https://github.com/dynamic-labs/dynamic-auth/issues/11970)) ([76a4a9a](https://github.com/dynamic-labs/dynamic-auth/commit/76a4a9a5025d78798ebd1beffe6c0af59d2d029a)), closes [#11896](https://github.com/dynamic-labs/dynamic-auth/issues/11896) [#11800](https://github.com/dynamic-labs/dynamic-auth/issues/11800)
|
|
23
|
+
* **midnight:** per-network addresses in deposit and wallet info views [v4] ([#11949](https://github.com/dynamic-labs/dynamic-auth/issues/11949)) ([978446a](https://github.com/dynamic-labs/dynamic-auth/commit/978446aca8546eb038ba9ed3be0503d10594ee15))
|
|
24
|
+
* **midnight:** resolve wallet address per selected network [v4] ([#11948](https://github.com/dynamic-labs/dynamic-auth/issues/11948)) ([d6f858c](https://github.com/dynamic-labs/dynamic-auth/commit/d6f858c5e35defda7ed73cf97b3fdbe5ed9d131d))
|
|
25
|
+
* set useMetamaskSdk to true by default ([#11926](https://github.com/dynamic-labs/dynamic-auth/issues/11926)) ([75b5a4a](https://github.com/dynamic-labs/dynamic-auth/commit/75b5a4a0fe8b1a375afce145c0b8bdc3ce761117))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
### Bug Fixes
|
|
29
|
+
|
|
30
|
+
* **midnight:** align per-network code with the final main iteration [v4] ([#11971](https://github.com/dynamic-labs/dynamic-auth/issues/11971)) ([3ef3ba8](https://github.com/dynamic-labs/dynamic-auth/commit/3ef3ba8c090dfd9e4286b4e51bf350ea5e6feac7))
|
|
31
|
+
* settle social sign-in when captcha is backed out or oauth popup never responds (v4) ([#11956](https://github.com/dynamic-labs/dynamic-auth/issues/11956)) ([ad49477](https://github.com/dynamic-labs/dynamic-auth/commit/ad49477f2acf61a154bb79cbe26b24f803cdb0e2))
|
|
32
|
+
* validate that private key is not empty before upgrading to WaaS ([#11952](https://github.com/dynamic-labs/dynamic-auth/issues/11952)) ([21dfb83](https://github.com/dynamic-labs/dynamic-auth/commit/21dfb83cb29e42b335bc94a0cdd2062cf14a262a))
|
|
33
|
+
|
|
34
|
+
### [4.92.3](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.2...v4.92.3) (2026-07-10)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
### Bug Fixes
|
|
38
|
+
|
|
39
|
+
* **sdk-react-core:** fix deterministic 'Wallet not found' crash in embedded wallet export (v4) ([#11906](https://github.com/dynamic-labs/dynamic-auth/issues/11906)) ([913ef23](https://github.com/dynamic-labs/dynamic-auth/commit/913ef236b26245488e1cd5db7e874601b65ff0a2)), closes [#11905](https://github.com/dynamic-labs/dynamic-auth/issues/11905) [#11729](https://github.com/dynamic-labs/dynamic-auth/issues/11729)
|
|
40
|
+
|
|
41
|
+
### [4.92.2](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.1...v4.92.2) (2026-07-09)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
### Bug Fixes
|
|
45
|
+
|
|
46
|
+
* engage captcha during step-up OTP re-auth ([#11879](https://github.com/dynamic-labs/dynamic-auth/issues/11879)) ([585460a](https://github.com/dynamic-labs/dynamic-auth/commit/585460a8976803a8ed0aad16a4a00047bd6c115a))
|
|
47
|
+
* **waas:** gate v1 wallet upgrade on recovery for email-only wallets ([#11897](https://github.com/dynamic-labs/dynamic-auth/issues/11897)) ([5a6f0c6](https://github.com/dynamic-labs/dynamic-auth/commit/5a6f0c6bf3120e59cf502004d09fae56f193e977))
|
|
48
|
+
|
|
49
|
+
### [4.92.1](https://github.com/dynamic-labs/dynamic-auth/compare/v4.92.0...v4.92.1) (2026-07-09)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
### Bug Fixes
|
|
53
|
+
|
|
54
|
+
* **ethereum:** fire in-app-browser redirect on sign for injected EVM wallets that use in-app-browser experience ([#11888](https://github.com/dynamic-labs/dynamic-auth/issues/11888)) ([5116d91](https://github.com/dynamic-labs/dynamic-auth/commit/5116d91ab2c71000a490d72c5d278549d4d8ae9a))
|
|
55
|
+
* **sdk-react-core:** show clear message for Phantom redirect signing failures (v4 backport) ([#11886](https://github.com/dynamic-labs/dynamic-auth/issues/11886)) ([60ac897](https://github.com/dynamic-labs/dynamic-auth/commit/60ac897ba81f7758ccd7a05f97b619785e1f50a7))
|
|
56
|
+
* **social:** use redirect strategy for step-up OAuth on mobile [V4 backport] ([#11881](https://github.com/dynamic-labs/dynamic-auth/issues/11881)) ([42a202e](https://github.com/dynamic-labs/dynamic-auth/commit/42a202e6255de8db73df02eff37c0b10b24fef1a))
|
|
57
|
+
* **solana:** fire in-app-browser redirect on sign and wallet switch ([#11871](https://github.com/dynamic-labs/dynamic-auth/issues/11871)) ([4e2d6b7](https://github.com/dynamic-labs/dynamic-auth/commit/4e2d6b7ac8fdef5bf7c62b8a726ecaef1c6210ec))
|
|
58
|
+
* **solana:** resolve Phantom/Backpack provider collision and Backpack >=0.10.x connect hangs ([#11856](https://github.com/dynamic-labs/dynamic-auth/issues/11856)) ([#11882](https://github.com/dynamic-labs/dynamic-auth/issues/11882)) ([5784aff](https://github.com/dynamic-labs/dynamic-auth/commit/5784aff9641bbc85445fb466f3ab1d6a14331e73))
|
|
59
|
+
|
|
60
|
+
## [4.92.0](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.6...v4.92.0) (2026-07-08)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
### Features
|
|
64
|
+
|
|
65
|
+
* **captcha:** add Cloudflare Turnstile provider support alongside hCaptcha (v4) ([#11798](https://github.com/dynamic-labs/dynamic-auth/issues/11798)) ([114c770](https://github.com/dynamic-labs/dynamic-auth/commit/114c7702e900d8dedeebe7be867de35d11a93f31))
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
### Bug Fixes
|
|
69
|
+
|
|
70
|
+
* **ethereum-aa:** resolve kernel client config per wallet (v4) ([#11870](https://github.com/dynamic-labs/dynamic-auth/issues/11870)) ([1b66d79](https://github.com/dynamic-labs/dynamic-auth/commit/1b66d79b4a32b4b6de433b7536bc46e6719224c6))
|
|
71
|
+
* **iframe-setup:** block dangerous URL schemes and verify sender in OPEN_URL ([#11819](https://github.com/dynamic-labs/dynamic-auth/issues/11819)) ([329b27e](https://github.com/dynamic-labs/dynamic-auth/commit/329b27e9fac825916ab227ec8cf93dc343898923))
|
|
72
|
+
* improve social OAuth error messages ([#11837](https://github.com/dynamic-labs/dynamic-auth/issues/11837)) ([8e57c06](https://github.com/dynamic-labs/dynamic-auth/commit/8e57c067c5a89111a32a12fb82e190cf6c46ad67))
|
|
73
|
+
* **react-native-extension:** reject path traversal in downloadFile fileName ([#11816](https://github.com/dynamic-labs/dynamic-auth/issues/11816)) ([9367a56](https://github.com/dynamic-labs/dynamic-auth/commit/9367a56b6daa853d7f7e7f5534261bc68825b239))
|
|
74
|
+
* **sdk-react-core:** display exactly the bytes signed in personal_sign preview ([#11818](https://github.com/dynamic-labs/dynamic-auth/issues/11818)) ([30b9382](https://github.com/dynamic-labs/dynamic-auth/commit/30b93829122f00060cb484aef09a03294c03f651))
|
|
75
|
+
|
|
3
76
|
|
|
4
77
|
### [4.91.6](https://github.com/dynamic-labs/dynamic-auth/compare/v4.91.5...v4.91.6) (2026-07-03)
|
|
5
78
|
|
package/package.cjs
CHANGED
package/package.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dynamic-labs/bitcoin",
|
|
3
|
-
"version": "5.0.0-rc.
|
|
3
|
+
"version": "5.0.0-rc.2",
|
|
4
4
|
"description": "A React SDK for implementing wallet web3 authentication and authorization to your website.",
|
|
5
5
|
"author": "Dynamic Labs, Inc.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,24 +18,24 @@
|
|
|
18
18
|
},
|
|
19
19
|
"homepage": "https://www.dynamic.xyz/",
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@dynamic-labs-wallet/browser-wallet-client": "1.0.
|
|
22
|
-
"@dynamic-labs-wallet/forward-mpc-client": "0.
|
|
21
|
+
"@dynamic-labs-wallet/browser-wallet-client": "1.0.70",
|
|
22
|
+
"@dynamic-labs-wallet/forward-mpc-client": "1.0.1",
|
|
23
23
|
"@bitcoinerlab/secp256k1": "1.1.1",
|
|
24
24
|
"@btckit/types": "0.0.19",
|
|
25
|
-
"@dynamic-labs/sdk-api-core": "0.0.
|
|
25
|
+
"@dynamic-labs/sdk-api-core": "0.0.1082",
|
|
26
26
|
"@wallet-standard/app": "1.0.1",
|
|
27
27
|
"@wallet-standard/base": "1.0.1",
|
|
28
28
|
"bitcoinjs-lib": "6.1.5",
|
|
29
29
|
"ecpair": "2.1.0",
|
|
30
30
|
"sats-connect": "4.2.1",
|
|
31
31
|
"jsontokens": "4.0.1",
|
|
32
|
-
"@dynamic-labs/assert-package-version": "5.0.0-rc.
|
|
33
|
-
"@dynamic-labs/logger": "5.0.0-rc.
|
|
34
|
-
"@dynamic-labs/types": "5.0.0-rc.
|
|
35
|
-
"@dynamic-labs/utils": "5.0.0-rc.
|
|
36
|
-
"@dynamic-labs/waas": "5.0.0-rc.
|
|
37
|
-
"@dynamic-labs/wallet-book": "5.0.0-rc.
|
|
38
|
-
"@dynamic-labs/wallet-connector-core": "5.0.0-rc.
|
|
32
|
+
"@dynamic-labs/assert-package-version": "5.0.0-rc.2",
|
|
33
|
+
"@dynamic-labs/logger": "5.0.0-rc.2",
|
|
34
|
+
"@dynamic-labs/types": "5.0.0-rc.2",
|
|
35
|
+
"@dynamic-labs/utils": "5.0.0-rc.2",
|
|
36
|
+
"@dynamic-labs/waas": "5.0.0-rc.2",
|
|
37
|
+
"@dynamic-labs/wallet-book": "5.0.0-rc.2",
|
|
38
|
+
"@dynamic-labs/wallet-connector-core": "5.0.0-rc.2",
|
|
39
39
|
"eventemitter3": "5.0.1"
|
|
40
40
|
},
|
|
41
41
|
"peerDependencies": {}
|
|
@@ -21,6 +21,9 @@ var PsbtParser = require('../../utils/psbtParser/PsbtParser.cjs');
|
|
|
21
21
|
var BitcoinUiTransaction = require('../../utils/BitcoinUiTransaction/BitcoinUiTransaction.cjs');
|
|
22
22
|
|
|
23
23
|
const logger = new logger$1.Logger('DynamicWaasConnector');
|
|
24
|
+
/** Dynamic network ids for the Bitcoin networks (mirrors the networks catalog). */
|
|
25
|
+
const BITCOIN_MAINNET_NETWORK_ID = 1;
|
|
26
|
+
const BITCOIN_TESTNET_NETWORK_ID = 2;
|
|
24
27
|
/**
|
|
25
28
|
* Bitcoin connector for Dynamic WaaS (Wallet as a Service)
|
|
26
29
|
* Extends BitcoinWalletConnector with WaaS functionality for Bitcoin transactions
|
|
@@ -40,6 +43,12 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
40
43
|
this.overrideKey = 'dynamicwaas';
|
|
41
44
|
this.isEmbeddedWallet = true;
|
|
42
45
|
this.connectedChain = 'BTC';
|
|
46
|
+
/**
|
|
47
|
+
* The currently selected Bitcoin network id (1 = mainnet, 2 = testnet).
|
|
48
|
+
* One wallet (one key) exposes an address per network via network-tagged
|
|
49
|
+
* additional addresses; switching networks swaps the active address.
|
|
50
|
+
*/
|
|
51
|
+
this.activeNetworkId = BITCOIN_MAINNET_NETWORK_ID;
|
|
43
52
|
this.walletUiUtils = props.walletUiUtils;
|
|
44
53
|
this.mempoolApiService = new MempoolApiService.MempoolApiService();
|
|
45
54
|
this.psbtBuilderService = new PsbtBuilderService.PsbtBuilderService(this.mempoolApiService);
|
|
@@ -83,16 +92,15 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
83
92
|
getAddress() {
|
|
84
93
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
85
94
|
var _a;
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
throw new utils.DynamicError('No active wallet address found', 'no_active_wallet_address_found');
|
|
95
|
+
if (this.activeAccountAddress) {
|
|
96
|
+
return this.activeAccountAddress;
|
|
97
|
+
}
|
|
98
|
+
if ((_a = this.verifiedCredential) === null || _a === void 0 ? void 0 : _a.address) {
|
|
99
|
+
const { address } = this.verifiedCredential;
|
|
100
|
+
this.activeAccountAddress = address;
|
|
101
|
+
return address;
|
|
94
102
|
}
|
|
95
|
-
|
|
103
|
+
throw new utils.DynamicError('No active wallet address found', 'no_active_wallet_address_found');
|
|
96
104
|
});
|
|
97
105
|
}
|
|
98
106
|
/**
|
|
@@ -108,28 +116,113 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
108
116
|
});
|
|
109
117
|
}
|
|
110
118
|
/**
|
|
111
|
-
* Gets the current Bitcoin network
|
|
112
|
-
* Always returns Dynamic's networkId (1 for mainnet)
|
|
113
|
-
* @returns The Dynamic networkId (1) for Bitcoin mainnet
|
|
119
|
+
* Gets the current Bitcoin network id (1 mainnet, 2 testnet)
|
|
114
120
|
*/
|
|
115
121
|
getNetwork() {
|
|
116
122
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
117
|
-
return
|
|
123
|
+
return this.activeNetworkId;
|
|
118
124
|
});
|
|
119
125
|
}
|
|
120
126
|
/**
|
|
121
|
-
* Maps
|
|
122
|
-
*
|
|
123
|
-
*
|
|
127
|
+
* Maps the selected networkId to the BitcoinNetwork enum for internal WaaS
|
|
128
|
+
* API calls (signing) — balance/UTXO/broadcast are address-driven and follow
|
|
129
|
+
* the active address automatically.
|
|
124
130
|
*/
|
|
125
131
|
getBitcoinNetworkEnum() {
|
|
132
|
+
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
133
|
+
return (this.activeNetworkId === BITCOIN_TESTNET_NETWORK_ID
|
|
134
|
+
? 'testnet'
|
|
135
|
+
: 'mainnet');
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
supportsNetworkSwitching() {
|
|
139
|
+
return true;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Testnet when the testnet network (id 2) is selected — drives the widget's
|
|
143
|
+
* native-denominated balance display (testnet coins have no fiat price).
|
|
144
|
+
*/
|
|
145
|
+
isTestnet() {
|
|
146
|
+
return Promise.resolve(this.activeNetworkId === BITCOIN_TESTNET_NETWORK_ID);
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Balance follows the active (per-network) address: callers pass the
|
|
150
|
+
* wallet's static primary address, which is the mainnet encoding — on
|
|
151
|
+
* testnet the switched address must be queried instead (the mempool API
|
|
152
|
+
* routing is address-driven).
|
|
153
|
+
*/
|
|
154
|
+
getBalance(address) {
|
|
155
|
+
const _super = Object.create(null, {
|
|
156
|
+
getBalance: { get: () => super.getBalance }
|
|
157
|
+
});
|
|
126
158
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
127
159
|
var _a;
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
160
|
+
return _super.getBalance.call(this, (_a = this.activeAccountAddress) !== null && _a !== void 0 ? _a : address);
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Wallet identity: keyshares/wallet records are keyed by the wallet's
|
|
165
|
+
* primary (mainnet) address. On testnet the active address is the same
|
|
166
|
+
* wallet's per-network encoding — WaaS lookups (password, signing) must use
|
|
167
|
+
* the primary address (the same key signs both encodings).
|
|
168
|
+
*/
|
|
169
|
+
getWalletIdentityAddress() {
|
|
170
|
+
var _a, _b;
|
|
171
|
+
// The active address is a valid fallback only on mainnet, where it is
|
|
172
|
+
// the primary encoding; a switched-network encoding must never be used
|
|
173
|
+
// as the wallet identity.
|
|
174
|
+
const identity = (_b = (_a = this.verifiedCredential) === null || _a === void 0 ? void 0 : _a.address) !== null && _b !== void 0 ? _b : (this.activeNetworkId === BITCOIN_MAINNET_NETWORK_ID
|
|
175
|
+
? this.activeAccountAddress
|
|
176
|
+
: undefined);
|
|
177
|
+
if (!identity) {
|
|
178
|
+
throw new utils.DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
179
|
+
}
|
|
180
|
+
return identity;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Resolves the wallet's payment address for a network from the credential's
|
|
184
|
+
* network-tagged additional addresses. Mainnet falls back to the primary
|
|
185
|
+
* address (wallets created before per-network registration).
|
|
186
|
+
*/
|
|
187
|
+
getPaymentAddressForNetwork(network) {
|
|
188
|
+
var _a, _b, _c;
|
|
189
|
+
const tagged = (_b = (_a = this.verifiedCredential) === null || _a === void 0 ? void 0 : _a.walletAdditionalAddresses) === null || _b === void 0 ? void 0 : _b.find((addr) => addr.type === 'payment' &&
|
|
190
|
+
addr.network === network);
|
|
191
|
+
if (tagged === null || tagged === void 0 ? void 0 : tagged.address) {
|
|
192
|
+
return tagged.address;
|
|
193
|
+
}
|
|
194
|
+
if (network === 'mainnet') {
|
|
195
|
+
return (_c = this.verifiedCredential) === null || _c === void 0 ? void 0 : _c.address;
|
|
196
|
+
}
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Switches between Bitcoin mainnet (1) and testnet (2). Same key — the
|
|
201
|
+
* active address swaps to the network's encoding; mempool/PSBT/broadcast
|
|
202
|
+
* follow the address, signing follows getBitcoinNetworkEnum().
|
|
203
|
+
*/
|
|
204
|
+
switchNetwork(_a) {
|
|
205
|
+
return _tslib.__awaiter(this, arguments, void 0, function* ({ networkChainId, networkName, }) {
|
|
206
|
+
let targetId = BITCOIN_MAINNET_NETWORK_ID;
|
|
207
|
+
if (networkChainId) {
|
|
208
|
+
targetId = Number(networkChainId);
|
|
209
|
+
}
|
|
210
|
+
else if (networkName === null || networkName === void 0 ? void 0 : networkName.toLowerCase().includes('test')) {
|
|
211
|
+
targetId = BITCOIN_TESTNET_NETWORK_ID;
|
|
212
|
+
}
|
|
213
|
+
if (targetId !== BITCOIN_MAINNET_NETWORK_ID &&
|
|
214
|
+
targetId !== BITCOIN_TESTNET_NETWORK_ID) {
|
|
215
|
+
throw new utils.DynamicError(`Unsupported Bitcoin network chain id: ${String(networkChainId)}`, 'unsupported_network');
|
|
216
|
+
}
|
|
217
|
+
const network = targetId === BITCOIN_TESTNET_NETWORK_ID ? 'testnet' : 'mainnet';
|
|
218
|
+
const address = this.getPaymentAddressForNetwork(network);
|
|
219
|
+
if (!address) {
|
|
220
|
+
logger.error('[DynamicWaasBitcoinConnector] switchNetwork: no address for network', { network, targetId });
|
|
221
|
+
throw new utils.DynamicError(`No ${network} address available for this wallet`, 'no_address_for_network');
|
|
222
|
+
}
|
|
223
|
+
this.activeNetworkId = targetId;
|
|
224
|
+
this.activeAccountAddress = address;
|
|
225
|
+
this.emit('chainChange', { chain: targetId.toString() });
|
|
133
226
|
});
|
|
134
227
|
}
|
|
135
228
|
/**
|
|
@@ -147,7 +240,9 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
147
240
|
*/
|
|
148
241
|
getBlockExplorerUrlsForCurrentNetwork() {
|
|
149
242
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
150
|
-
return
|
|
243
|
+
return this.activeNetworkId === BITCOIN_TESTNET_NETWORK_ID
|
|
244
|
+
? ['https://mempool.space/testnet/']
|
|
245
|
+
: ['https://mempool.space/'];
|
|
151
246
|
});
|
|
152
247
|
}
|
|
153
248
|
/**
|
|
@@ -192,15 +287,16 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
192
287
|
const elevatedAccessToken = yield ((_c = this.getElevatedAccessToken) === null || _c === void 0 ? void 0 : _c.call(this, {
|
|
193
288
|
scope: sdkApiCore.TokenScope.Walletsign,
|
|
194
289
|
}));
|
|
290
|
+
const walletIdentityAddress = this.getWalletIdentityAddress();
|
|
195
291
|
const password = yield this.getPasswordIfNeeded({
|
|
196
|
-
accountAddress:
|
|
292
|
+
accountAddress: walletIdentityAddress,
|
|
197
293
|
});
|
|
198
294
|
const signedTransaction = yield walletClient.signTransaction({
|
|
199
295
|
authToken: (_d = this.getAuthToken) === null || _d === void 0 ? void 0 : _d.call(this),
|
|
200
296
|
elevatedAccessToken,
|
|
201
297
|
mfaToken,
|
|
202
298
|
password,
|
|
203
|
-
senderAddress:
|
|
299
|
+
senderAddress: walletIdentityAddress,
|
|
204
300
|
signedSessionId,
|
|
205
301
|
transaction: request.unsignedPsbtBase64,
|
|
206
302
|
});
|
|
@@ -338,7 +434,7 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
338
434
|
*/
|
|
339
435
|
validateActiveWallet(expectedAddress) {
|
|
340
436
|
return _tslib.__awaiter(this, void 0, void 0, function* () {
|
|
341
|
-
var _a;
|
|
437
|
+
var _a, _b, _c, _d;
|
|
342
438
|
const walletClient = yield this.getWaasWalletClient();
|
|
343
439
|
const targetWallet = yield walletClient.getWallet({
|
|
344
440
|
accountAddress: expectedAddress,
|
|
@@ -350,7 +446,11 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
350
446
|
throw new utils.DynamicError('Account not found', 'account_not_found');
|
|
351
447
|
}
|
|
352
448
|
const isWalletActive = walletConnectorCore.isSameAddress(targetWallet.accountAddress, this.activeAccountAddress || '', this.connectedChain);
|
|
353
|
-
|
|
449
|
+
// The active address may be a per-network encoding of this same wallet
|
|
450
|
+
// (one key, network-tagged additional addresses). Resetting it here would
|
|
451
|
+
// silently un-switch the selected network.
|
|
452
|
+
const isPerNetworkVariantOfWallet = (_d = (_c = (_b = this.verifiedCredential) === null || _b === void 0 ? void 0 : _b.walletAdditionalAddresses) === null || _c === void 0 ? void 0 : _c.some((addr) => addr.address === this.activeAccountAddress)) !== null && _d !== void 0 ? _d : false;
|
|
453
|
+
if (!isWalletActive && !isPerNetworkVariantOfWallet) {
|
|
354
454
|
this.activeAccountAddress = targetWallet.accountAddress;
|
|
355
455
|
}
|
|
356
456
|
});
|
|
@@ -381,12 +481,13 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
381
481
|
scope: sdkApiCore.TokenScope.Walletsign,
|
|
382
482
|
}));
|
|
383
483
|
const password = yield this.getPasswordIfNeeded({
|
|
384
|
-
accountAddress: this.
|
|
484
|
+
accountAddress: this.getWalletIdentityAddress(),
|
|
385
485
|
});
|
|
386
486
|
const messageString = typeof message === 'string' ? message : message.raw;
|
|
387
487
|
return walletClient.signMessage({
|
|
388
|
-
accountAddress: this.
|
|
488
|
+
accountAddress: this.getWalletIdentityAddress(),
|
|
389
489
|
authToken: (_e = this.getAuthToken) === null || _e === void 0 ? void 0 : _e.call(this),
|
|
490
|
+
bitcoinConfig: { network: yield this.getBitcoinNetworkEnum() },
|
|
390
491
|
context,
|
|
391
492
|
elevatedAccessToken,
|
|
392
493
|
message: messageString,
|
|
@@ -594,10 +695,10 @@ class DynamicWaasBitcoinConnector extends waas.withDynamicWaas(BitcoinWalletConn
|
|
|
594
695
|
scope: sdkApiCore.TokenScope.Walletsign,
|
|
595
696
|
}));
|
|
596
697
|
const password = yield this.getPasswordIfNeeded({
|
|
597
|
-
accountAddress: this.
|
|
698
|
+
accountAddress: this.getWalletIdentityAddress(),
|
|
598
699
|
});
|
|
599
700
|
return walletClient.signMessage({
|
|
600
|
-
accountAddress: this.
|
|
701
|
+
accountAddress: this.getWalletIdentityAddress(),
|
|
601
702
|
authToken: (_d = this.getAuthToken) === null || _d === void 0 ? void 0 : _d.call(this),
|
|
602
703
|
bitcoinConfig: {
|
|
603
704
|
network: yield this.getBitcoinNetworkEnum(),
|
|
@@ -22,12 +22,13 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
22
22
|
scope: TokenScope;
|
|
23
23
|
}) => Promise<string | undefined>) | undefined;
|
|
24
24
|
onUnauthorized?: (() => void | Promise<void>) | undefined;
|
|
25
|
+
/** Dynamic network ids for the Bitcoin networks (mirrors the networks catalog). */
|
|
25
26
|
environmentId?: string | undefined;
|
|
26
27
|
baseApiUrl?: string | undefined;
|
|
27
28
|
relayUrl?: string | undefined;
|
|
28
29
|
baseClientKeysharesRelayApiUrl?: string | undefined;
|
|
29
30
|
dynamicWaasClient: import("@dynamic-labs-wallet/browser-wallet-client").DynamicWalletClient | undefined;
|
|
30
|
-
revokeSignedSession: (() => void) | undefined;
|
|
31
|
+
revokeSignedSession: ((reason?: string | undefined) => void) | undefined;
|
|
31
32
|
chainName: string;
|
|
32
33
|
authMode: "cookie" | "header";
|
|
33
34
|
logger: Logger;
|
|
@@ -66,16 +67,31 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
66
67
|
getWaasWalletClient(traceContext?: import("dist/packages/waas/utils/instrumentation").TraceContext | undefined, { forceRebuild }?: {
|
|
67
68
|
forceRebuild?: boolean | undefined;
|
|
68
69
|
} | undefined): Promise<import("@dynamic-labs-wallet/browser-wallet-client").DynamicWalletClient>;
|
|
69
|
-
createWalletAccount({ thresholdSignatureScheme, password, bitcoinConfig, }?: {
|
|
70
|
+
createWalletAccount({ thresholdSignatureScheme, password, bitcoinConfig, businessAccountId, }?: {
|
|
70
71
|
thresholdSignatureScheme?: string | undefined;
|
|
71
72
|
password?: string | undefined;
|
|
72
73
|
bitcoinConfig?: BitcoinConfig | undefined;
|
|
74
|
+
businessAccountId?: string | undefined;
|
|
73
75
|
} | undefined): Promise<{
|
|
74
76
|
chainName: string;
|
|
75
77
|
accountAddress: string;
|
|
76
78
|
publicKeyHex: string;
|
|
77
79
|
rawPublicKey: string | Uint8Array | undefined;
|
|
78
80
|
}>;
|
|
81
|
+
addSignerViaReshare({ accountAddress, walletId, businessAccountId, targetSignerIdentity, signerType, password, }: {
|
|
82
|
+
accountAddress: string;
|
|
83
|
+
walletId?: string | undefined;
|
|
84
|
+
businessAccountId: string;
|
|
85
|
+
targetSignerIdentity: {
|
|
86
|
+
userId?: string | undefined;
|
|
87
|
+
identifier?: string | undefined;
|
|
88
|
+
identifierType?: string | undefined;
|
|
89
|
+
};
|
|
90
|
+
signerType?: "endUser" | "server" | undefined;
|
|
91
|
+
password?: string | undefined;
|
|
92
|
+
}): Promise<{
|
|
93
|
+
shareSetId: string;
|
|
94
|
+
}>;
|
|
79
95
|
importPrivateKey({ privateKey, thresholdSignatureScheme, publicAddressCheck, addressType, legacyWalletId, password, }: {
|
|
80
96
|
privateKey: string;
|
|
81
97
|
thresholdSignatureScheme?: string | undefined;
|
|
@@ -92,7 +108,7 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
92
108
|
expectedAddresses: Record<string, string>;
|
|
93
109
|
coinTypes?: Record<string, number> | undefined;
|
|
94
110
|
password?: string | undefined;
|
|
95
|
-
}): Promise<
|
|
111
|
+
}): Promise<Record<string, unknown>>;
|
|
96
112
|
exportPrivateKey({ accountAddress, displayContainer, password, }?: {
|
|
97
113
|
accountAddress?: string | undefined;
|
|
98
114
|
displayContainer?: HTMLIFrameElement | undefined;
|
|
@@ -105,6 +121,21 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
105
121
|
accountAddress: string;
|
|
106
122
|
password?: string | undefined;
|
|
107
123
|
}): Promise<void>;
|
|
124
|
+
runBackupLifecycle({ provider, accountAddress, password, performBackup, }: {
|
|
125
|
+
provider: string;
|
|
126
|
+
accountAddress: string;
|
|
127
|
+
password?: string | undefined;
|
|
128
|
+
performBackup: (prerequisites: {
|
|
129
|
+
walletClient: import("@dynamic-labs-wallet/browser-wallet-client").DynamicWalletClient;
|
|
130
|
+
resolvedPassword: string | undefined;
|
|
131
|
+
signedSessionId: string;
|
|
132
|
+
sessionPublicKey: string | undefined;
|
|
133
|
+
traceContext: {
|
|
134
|
+
traceId: string;
|
|
135
|
+
startTime: number;
|
|
136
|
+
};
|
|
137
|
+
}) => Promise<void>;
|
|
138
|
+
}): Promise<void>;
|
|
108
139
|
backupKeySharesToGoogleDrive({ accountAddress, password, googleDriveAccessToken, }: {
|
|
109
140
|
accountAddress: string;
|
|
110
141
|
password?: string | undefined;
|
|
@@ -113,7 +144,11 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
113
144
|
exportClientKeysharesFromGoogleDrive({ accountAddress, password, }: {
|
|
114
145
|
accountAddress: string;
|
|
115
146
|
password?: string | undefined;
|
|
116
|
-
}): Promise<void>;
|
|
147
|
+
}): Promise<void>; /**
|
|
148
|
+
* Resolves the wallet's payment address for a network from the credential's
|
|
149
|
+
* network-tagged additional addresses. Mainnet falls back to the primary
|
|
150
|
+
* address (wallets created before per-network registration).
|
|
151
|
+
*/
|
|
117
152
|
backupKeySharesToICloud({ accountAddress, password, }: {
|
|
118
153
|
accountAddress: string;
|
|
119
154
|
password?: string | undefined;
|
|
@@ -122,11 +157,7 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
122
157
|
displayContainer: HTMLElement;
|
|
123
158
|
}): Promise<void>;
|
|
124
159
|
hideICloudSignIn(): Promise<void>;
|
|
125
|
-
isICloudAuthenticated(): Promise<boolean>;
|
|
126
|
-
* Gets block explorer URLs for the current network
|
|
127
|
-
* Returns mempool.space for Bitcoin transactions
|
|
128
|
-
* @returns Array containing mempool.space URL
|
|
129
|
-
*/
|
|
160
|
+
isICloudAuthenticated(): Promise<boolean>;
|
|
130
161
|
refreshWalletAccountShares({ accountAddress, password, }: {
|
|
131
162
|
accountAddress: string;
|
|
132
163
|
password?: string | undefined;
|
|
@@ -149,8 +180,9 @@ declare const DynamicWaasBitcoinConnector_base: (abstract new (...args: any[]) =
|
|
|
149
180
|
accountAddress: string;
|
|
150
181
|
newPassword: string;
|
|
151
182
|
}): Promise<void>;
|
|
152
|
-
signRawMessage({ accountAddress, message, password, }: {
|
|
183
|
+
signRawMessage({ accountAddress, context, message, password, }: {
|
|
153
184
|
accountAddress: string;
|
|
185
|
+
context?: SignMessageContext | undefined;
|
|
154
186
|
message: string;
|
|
155
187
|
password?: string | undefined;
|
|
156
188
|
}): Promise<string>;
|
|
@@ -238,17 +270,56 @@ export declare class DynamicWaasBitcoinConnector extends DynamicWaasBitcoinConne
|
|
|
238
270
|
*/
|
|
239
271
|
getConnectedAccounts(): Promise<string[]>;
|
|
240
272
|
/**
|
|
241
|
-
*
|
|
242
|
-
*
|
|
243
|
-
*
|
|
273
|
+
* The currently selected Bitcoin network id (1 = mainnet, 2 = testnet).
|
|
274
|
+
* One wallet (one key) exposes an address per network via network-tagged
|
|
275
|
+
* additional addresses; switching networks swaps the active address.
|
|
276
|
+
*/
|
|
277
|
+
private activeNetworkId;
|
|
278
|
+
/**
|
|
279
|
+
* Gets the current Bitcoin network id (1 mainnet, 2 testnet)
|
|
244
280
|
*/
|
|
245
281
|
getNetwork(): Promise<number>;
|
|
246
282
|
/**
|
|
247
|
-
* Maps
|
|
248
|
-
*
|
|
249
|
-
*
|
|
283
|
+
* Maps the selected networkId to the BitcoinNetwork enum for internal WaaS
|
|
284
|
+
* API calls (signing) — balance/UTXO/broadcast are address-driven and follow
|
|
285
|
+
* the active address automatically.
|
|
250
286
|
*/
|
|
251
287
|
private getBitcoinNetworkEnum;
|
|
288
|
+
supportsNetworkSwitching(): boolean;
|
|
289
|
+
/**
|
|
290
|
+
* Testnet when the testnet network (id 2) is selected — drives the widget's
|
|
291
|
+
* native-denominated balance display (testnet coins have no fiat price).
|
|
292
|
+
*/
|
|
293
|
+
isTestnet(): Promise<boolean>;
|
|
294
|
+
/**
|
|
295
|
+
* Balance follows the active (per-network) address: callers pass the
|
|
296
|
+
* wallet's static primary address, which is the mainnet encoding — on
|
|
297
|
+
* testnet the switched address must be queried instead (the mempool API
|
|
298
|
+
* routing is address-driven).
|
|
299
|
+
*/
|
|
300
|
+
getBalance(address: string): Promise<string | undefined>;
|
|
301
|
+
/**
|
|
302
|
+
* Wallet identity: keyshares/wallet records are keyed by the wallet's
|
|
303
|
+
* primary (mainnet) address. On testnet the active address is the same
|
|
304
|
+
* wallet's per-network encoding — WaaS lookups (password, signing) must use
|
|
305
|
+
* the primary address (the same key signs both encodings).
|
|
306
|
+
*/
|
|
307
|
+
private getWalletIdentityAddress;
|
|
308
|
+
/**
|
|
309
|
+
* Resolves the wallet's payment address for a network from the credential's
|
|
310
|
+
* network-tagged additional addresses. Mainnet falls back to the primary
|
|
311
|
+
* address (wallets created before per-network registration).
|
|
312
|
+
*/
|
|
313
|
+
private getPaymentAddressForNetwork;
|
|
314
|
+
/**
|
|
315
|
+
* Switches between Bitcoin mainnet (1) and testnet (2). Same key — the
|
|
316
|
+
* active address swaps to the network's encoding; mempool/PSBT/broadcast
|
|
317
|
+
* follow the address, signing follows getBitcoinNetworkEnum().
|
|
318
|
+
*/
|
|
319
|
+
switchNetwork({ networkChainId, networkName, }: {
|
|
320
|
+
networkChainId?: number | string;
|
|
321
|
+
networkName?: string;
|
|
322
|
+
}): Promise<void>;
|
|
252
323
|
/**
|
|
253
324
|
* Get the enabled networks for Bitcoin
|
|
254
325
|
* Returns configured networks from props
|
|
@@ -17,6 +17,9 @@ import { PsbtParser } from '../../utils/psbtParser/PsbtParser.js';
|
|
|
17
17
|
import { BitcoinUiTransaction } from '../../utils/BitcoinUiTransaction/BitcoinUiTransaction.js';
|
|
18
18
|
|
|
19
19
|
const logger = new Logger('DynamicWaasConnector');
|
|
20
|
+
/** Dynamic network ids for the Bitcoin networks (mirrors the networks catalog). */
|
|
21
|
+
const BITCOIN_MAINNET_NETWORK_ID = 1;
|
|
22
|
+
const BITCOIN_TESTNET_NETWORK_ID = 2;
|
|
20
23
|
/**
|
|
21
24
|
* Bitcoin connector for Dynamic WaaS (Wallet as a Service)
|
|
22
25
|
* Extends BitcoinWalletConnector with WaaS functionality for Bitcoin transactions
|
|
@@ -36,6 +39,12 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
36
39
|
this.overrideKey = 'dynamicwaas';
|
|
37
40
|
this.isEmbeddedWallet = true;
|
|
38
41
|
this.connectedChain = 'BTC';
|
|
42
|
+
/**
|
|
43
|
+
* The currently selected Bitcoin network id (1 = mainnet, 2 = testnet).
|
|
44
|
+
* One wallet (one key) exposes an address per network via network-tagged
|
|
45
|
+
* additional addresses; switching networks swaps the active address.
|
|
46
|
+
*/
|
|
47
|
+
this.activeNetworkId = BITCOIN_MAINNET_NETWORK_ID;
|
|
39
48
|
this.walletUiUtils = props.walletUiUtils;
|
|
40
49
|
this.mempoolApiService = new MempoolApiService();
|
|
41
50
|
this.psbtBuilderService = new PsbtBuilderService(this.mempoolApiService);
|
|
@@ -79,16 +88,15 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
79
88
|
getAddress() {
|
|
80
89
|
return __awaiter(this, void 0, void 0, function* () {
|
|
81
90
|
var _a;
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
throw new DynamicError('No active wallet address found', 'no_active_wallet_address_found');
|
|
91
|
+
if (this.activeAccountAddress) {
|
|
92
|
+
return this.activeAccountAddress;
|
|
93
|
+
}
|
|
94
|
+
if ((_a = this.verifiedCredential) === null || _a === void 0 ? void 0 : _a.address) {
|
|
95
|
+
const { address } = this.verifiedCredential;
|
|
96
|
+
this.activeAccountAddress = address;
|
|
97
|
+
return address;
|
|
90
98
|
}
|
|
91
|
-
|
|
99
|
+
throw new DynamicError('No active wallet address found', 'no_active_wallet_address_found');
|
|
92
100
|
});
|
|
93
101
|
}
|
|
94
102
|
/**
|
|
@@ -104,28 +112,113 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
104
112
|
});
|
|
105
113
|
}
|
|
106
114
|
/**
|
|
107
|
-
* Gets the current Bitcoin network
|
|
108
|
-
* Always returns Dynamic's networkId (1 for mainnet)
|
|
109
|
-
* @returns The Dynamic networkId (1) for Bitcoin mainnet
|
|
115
|
+
* Gets the current Bitcoin network id (1 mainnet, 2 testnet)
|
|
110
116
|
*/
|
|
111
117
|
getNetwork() {
|
|
112
118
|
return __awaiter(this, void 0, void 0, function* () {
|
|
113
|
-
return
|
|
119
|
+
return this.activeNetworkId;
|
|
114
120
|
});
|
|
115
121
|
}
|
|
116
122
|
/**
|
|
117
|
-
* Maps
|
|
118
|
-
*
|
|
119
|
-
*
|
|
123
|
+
* Maps the selected networkId to the BitcoinNetwork enum for internal WaaS
|
|
124
|
+
* API calls (signing) — balance/UTXO/broadcast are address-driven and follow
|
|
125
|
+
* the active address automatically.
|
|
120
126
|
*/
|
|
121
127
|
getBitcoinNetworkEnum() {
|
|
128
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
129
|
+
return (this.activeNetworkId === BITCOIN_TESTNET_NETWORK_ID
|
|
130
|
+
? 'testnet'
|
|
131
|
+
: 'mainnet');
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
supportsNetworkSwitching() {
|
|
135
|
+
return true;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Testnet when the testnet network (id 2) is selected — drives the widget's
|
|
139
|
+
* native-denominated balance display (testnet coins have no fiat price).
|
|
140
|
+
*/
|
|
141
|
+
isTestnet() {
|
|
142
|
+
return Promise.resolve(this.activeNetworkId === BITCOIN_TESTNET_NETWORK_ID);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Balance follows the active (per-network) address: callers pass the
|
|
146
|
+
* wallet's static primary address, which is the mainnet encoding — on
|
|
147
|
+
* testnet the switched address must be queried instead (the mempool API
|
|
148
|
+
* routing is address-driven).
|
|
149
|
+
*/
|
|
150
|
+
getBalance(address) {
|
|
151
|
+
const _super = Object.create(null, {
|
|
152
|
+
getBalance: { get: () => super.getBalance }
|
|
153
|
+
});
|
|
122
154
|
return __awaiter(this, void 0, void 0, function* () {
|
|
123
155
|
var _a;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
156
|
+
return _super.getBalance.call(this, (_a = this.activeAccountAddress) !== null && _a !== void 0 ? _a : address);
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Wallet identity: keyshares/wallet records are keyed by the wallet's
|
|
161
|
+
* primary (mainnet) address. On testnet the active address is the same
|
|
162
|
+
* wallet's per-network encoding — WaaS lookups (password, signing) must use
|
|
163
|
+
* the primary address (the same key signs both encodings).
|
|
164
|
+
*/
|
|
165
|
+
getWalletIdentityAddress() {
|
|
166
|
+
var _a, _b;
|
|
167
|
+
// The active address is a valid fallback only on mainnet, where it is
|
|
168
|
+
// the primary encoding; a switched-network encoding must never be used
|
|
169
|
+
// as the wallet identity.
|
|
170
|
+
const identity = (_b = (_a = this.verifiedCredential) === null || _a === void 0 ? void 0 : _a.address) !== null && _b !== void 0 ? _b : (this.activeNetworkId === BITCOIN_MAINNET_NETWORK_ID
|
|
171
|
+
? this.activeAccountAddress
|
|
172
|
+
: undefined);
|
|
173
|
+
if (!identity) {
|
|
174
|
+
throw new DynamicError('Active account address is required', 'active_account_address_is_required');
|
|
175
|
+
}
|
|
176
|
+
return identity;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Resolves the wallet's payment address for a network from the credential's
|
|
180
|
+
* network-tagged additional addresses. Mainnet falls back to the primary
|
|
181
|
+
* address (wallets created before per-network registration).
|
|
182
|
+
*/
|
|
183
|
+
getPaymentAddressForNetwork(network) {
|
|
184
|
+
var _a, _b, _c;
|
|
185
|
+
const tagged = (_b = (_a = this.verifiedCredential) === null || _a === void 0 ? void 0 : _a.walletAdditionalAddresses) === null || _b === void 0 ? void 0 : _b.find((addr) => addr.type === 'payment' &&
|
|
186
|
+
addr.network === network);
|
|
187
|
+
if (tagged === null || tagged === void 0 ? void 0 : tagged.address) {
|
|
188
|
+
return tagged.address;
|
|
189
|
+
}
|
|
190
|
+
if (network === 'mainnet') {
|
|
191
|
+
return (_c = this.verifiedCredential) === null || _c === void 0 ? void 0 : _c.address;
|
|
192
|
+
}
|
|
193
|
+
return undefined;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Switches between Bitcoin mainnet (1) and testnet (2). Same key — the
|
|
197
|
+
* active address swaps to the network's encoding; mempool/PSBT/broadcast
|
|
198
|
+
* follow the address, signing follows getBitcoinNetworkEnum().
|
|
199
|
+
*/
|
|
200
|
+
switchNetwork(_a) {
|
|
201
|
+
return __awaiter(this, arguments, void 0, function* ({ networkChainId, networkName, }) {
|
|
202
|
+
let targetId = BITCOIN_MAINNET_NETWORK_ID;
|
|
203
|
+
if (networkChainId) {
|
|
204
|
+
targetId = Number(networkChainId);
|
|
205
|
+
}
|
|
206
|
+
else if (networkName === null || networkName === void 0 ? void 0 : networkName.toLowerCase().includes('test')) {
|
|
207
|
+
targetId = BITCOIN_TESTNET_NETWORK_ID;
|
|
208
|
+
}
|
|
209
|
+
if (targetId !== BITCOIN_MAINNET_NETWORK_ID &&
|
|
210
|
+
targetId !== BITCOIN_TESTNET_NETWORK_ID) {
|
|
211
|
+
throw new DynamicError(`Unsupported Bitcoin network chain id: ${String(networkChainId)}`, 'unsupported_network');
|
|
212
|
+
}
|
|
213
|
+
const network = targetId === BITCOIN_TESTNET_NETWORK_ID ? 'testnet' : 'mainnet';
|
|
214
|
+
const address = this.getPaymentAddressForNetwork(network);
|
|
215
|
+
if (!address) {
|
|
216
|
+
logger.error('[DynamicWaasBitcoinConnector] switchNetwork: no address for network', { network, targetId });
|
|
217
|
+
throw new DynamicError(`No ${network} address available for this wallet`, 'no_address_for_network');
|
|
218
|
+
}
|
|
219
|
+
this.activeNetworkId = targetId;
|
|
220
|
+
this.activeAccountAddress = address;
|
|
221
|
+
this.emit('chainChange', { chain: targetId.toString() });
|
|
129
222
|
});
|
|
130
223
|
}
|
|
131
224
|
/**
|
|
@@ -143,7 +236,9 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
143
236
|
*/
|
|
144
237
|
getBlockExplorerUrlsForCurrentNetwork() {
|
|
145
238
|
return __awaiter(this, void 0, void 0, function* () {
|
|
146
|
-
return
|
|
239
|
+
return this.activeNetworkId === BITCOIN_TESTNET_NETWORK_ID
|
|
240
|
+
? ['https://mempool.space/testnet/']
|
|
241
|
+
: ['https://mempool.space/'];
|
|
147
242
|
});
|
|
148
243
|
}
|
|
149
244
|
/**
|
|
@@ -188,15 +283,16 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
188
283
|
const elevatedAccessToken = yield ((_c = this.getElevatedAccessToken) === null || _c === void 0 ? void 0 : _c.call(this, {
|
|
189
284
|
scope: TokenScope.Walletsign,
|
|
190
285
|
}));
|
|
286
|
+
const walletIdentityAddress = this.getWalletIdentityAddress();
|
|
191
287
|
const password = yield this.getPasswordIfNeeded({
|
|
192
|
-
accountAddress:
|
|
288
|
+
accountAddress: walletIdentityAddress,
|
|
193
289
|
});
|
|
194
290
|
const signedTransaction = yield walletClient.signTransaction({
|
|
195
291
|
authToken: (_d = this.getAuthToken) === null || _d === void 0 ? void 0 : _d.call(this),
|
|
196
292
|
elevatedAccessToken,
|
|
197
293
|
mfaToken,
|
|
198
294
|
password,
|
|
199
|
-
senderAddress:
|
|
295
|
+
senderAddress: walletIdentityAddress,
|
|
200
296
|
signedSessionId,
|
|
201
297
|
transaction: request.unsignedPsbtBase64,
|
|
202
298
|
});
|
|
@@ -334,7 +430,7 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
334
430
|
*/
|
|
335
431
|
validateActiveWallet(expectedAddress) {
|
|
336
432
|
return __awaiter(this, void 0, void 0, function* () {
|
|
337
|
-
var _a;
|
|
433
|
+
var _a, _b, _c, _d;
|
|
338
434
|
const walletClient = yield this.getWaasWalletClient();
|
|
339
435
|
const targetWallet = yield walletClient.getWallet({
|
|
340
436
|
accountAddress: expectedAddress,
|
|
@@ -346,7 +442,11 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
346
442
|
throw new DynamicError('Account not found', 'account_not_found');
|
|
347
443
|
}
|
|
348
444
|
const isWalletActive = isSameAddress(targetWallet.accountAddress, this.activeAccountAddress || '', this.connectedChain);
|
|
349
|
-
|
|
445
|
+
// The active address may be a per-network encoding of this same wallet
|
|
446
|
+
// (one key, network-tagged additional addresses). Resetting it here would
|
|
447
|
+
// silently un-switch the selected network.
|
|
448
|
+
const isPerNetworkVariantOfWallet = (_d = (_c = (_b = this.verifiedCredential) === null || _b === void 0 ? void 0 : _b.walletAdditionalAddresses) === null || _c === void 0 ? void 0 : _c.some((addr) => addr.address === this.activeAccountAddress)) !== null && _d !== void 0 ? _d : false;
|
|
449
|
+
if (!isWalletActive && !isPerNetworkVariantOfWallet) {
|
|
350
450
|
this.activeAccountAddress = targetWallet.accountAddress;
|
|
351
451
|
}
|
|
352
452
|
});
|
|
@@ -377,12 +477,13 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
377
477
|
scope: TokenScope.Walletsign,
|
|
378
478
|
}));
|
|
379
479
|
const password = yield this.getPasswordIfNeeded({
|
|
380
|
-
accountAddress: this.
|
|
480
|
+
accountAddress: this.getWalletIdentityAddress(),
|
|
381
481
|
});
|
|
382
482
|
const messageString = typeof message === 'string' ? message : message.raw;
|
|
383
483
|
return walletClient.signMessage({
|
|
384
|
-
accountAddress: this.
|
|
484
|
+
accountAddress: this.getWalletIdentityAddress(),
|
|
385
485
|
authToken: (_e = this.getAuthToken) === null || _e === void 0 ? void 0 : _e.call(this),
|
|
486
|
+
bitcoinConfig: { network: yield this.getBitcoinNetworkEnum() },
|
|
386
487
|
context,
|
|
387
488
|
elevatedAccessToken,
|
|
388
489
|
message: messageString,
|
|
@@ -590,10 +691,10 @@ class DynamicWaasBitcoinConnector extends withDynamicWaas(BitcoinWalletConnector
|
|
|
590
691
|
scope: TokenScope.Walletsign,
|
|
591
692
|
}));
|
|
592
693
|
const password = yield this.getPasswordIfNeeded({
|
|
593
|
-
accountAddress: this.
|
|
694
|
+
accountAddress: this.getWalletIdentityAddress(),
|
|
594
695
|
});
|
|
595
696
|
return walletClient.signMessage({
|
|
596
|
-
accountAddress: this.
|
|
697
|
+
accountAddress: this.getWalletIdentityAddress(),
|
|
597
698
|
authToken: (_d = this.getAuthToken) === null || _d === void 0 ? void 0 : _d.call(this),
|
|
598
699
|
bitcoinConfig: {
|
|
599
700
|
network: yield this.getBitcoinNetworkEnum(),
|
|
@@ -13,6 +13,9 @@ class BitcoinUiTransaction {
|
|
|
13
13
|
this.data = undefined;
|
|
14
14
|
this.fee = { gas: undefined };
|
|
15
15
|
this.feePriority = 'medium';
|
|
16
|
+
// Outputs below the dust limit are unrelayable; PsbtBuilderService throws
|
|
17
|
+
// on them, so surface the floor to the send form instead.
|
|
18
|
+
this.minAmount = BigInt(_const.DUST_LIMIT);
|
|
16
19
|
/**
|
|
17
20
|
* Formats the value into a string for the UI for non-native tokens
|
|
18
21
|
* @param value - The value to format
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
import { __awaiter } from '../../../_virtual/_tslib.js';
|
|
3
3
|
import { formatNumberText } from '@dynamic-labs/utils';
|
|
4
|
-
import { SATOSHIS_PER_BTC } from '../../const.js';
|
|
4
|
+
import { DUST_LIMIT, SATOSHIS_PER_BTC } from '../../const.js';
|
|
5
5
|
|
|
6
6
|
class BitcoinUiTransaction {
|
|
7
7
|
constructor({ onSubmit, from, mempoolApiService, }) {
|
|
@@ -9,6 +9,9 @@ class BitcoinUiTransaction {
|
|
|
9
9
|
this.data = undefined;
|
|
10
10
|
this.fee = { gas: undefined };
|
|
11
11
|
this.feePriority = 'medium';
|
|
12
|
+
// Outputs below the dust limit are unrelayable; PsbtBuilderService throws
|
|
13
|
+
// on them, so surface the floor to the send form instead.
|
|
14
|
+
this.minAmount = BigInt(DUST_LIMIT);
|
|
12
15
|
/**
|
|
13
16
|
* Formats the value into a string for the UI for non-native tokens
|
|
14
17
|
* @param value - The value to format
|