@dynamic-labs/bitcoin 3.0.0-alpha.64 → 3.0.0-alpha.65

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.
@@ -1,32 +1,49 @@
1
1
  'use client'
2
2
  import { __awaiter } from '../../../_virtual/_tslib.js';
3
3
  import { Psbt } from 'bitcoinjs-lib';
4
- import { BitcoinNetworkType, getAddress, AddressPurpose, signMessage, sendBtcTransaction, signTransaction, signMultipleTransactions } from 'sats-connect';
4
+ import { BitcoinNetworkType, request, AddressPurpose, signMultipleTransactions } from 'sats-connect';
5
5
  import { isMobile, template } from '@dynamic-labs/utils';
6
6
  import { findWalletBookWallet } from '@dynamic-labs/wallet-book';
7
- import { SATSCONNECT_FEATURE } from '../../const.js';
8
- import '@dynamic-labs/wallet-connector-core';
9
- import { BitcoinWalletConnector } from '../BitcoinWalletConnector.js';
7
+ import { logger } from '@dynamic-labs/wallet-connector-core';
10
8
  import { convertNetworkTypeForPsbt } from '../../utils/psbt/bitcoinNetworkTypeToNetworks.js';
9
+ import { BitcoinWalletConnector } from '../BitcoinWalletConnector.js';
11
10
  import { createSignPsbtOptionsForSatsConnect } from '../../utils/psbt/createSignPsbtOptions.js';
12
- import { supportsSatsConnect } from '../../utils/supportsSatsConnect.js';
13
11
 
14
12
  class BitcoinSatsConnectConnector extends BitcoinWalletConnector {
15
13
  constructor(opts) {
16
14
  super(opts);
17
15
  this.currentNetwork = BitcoinNetworkType.Mainnet;
18
16
  }
19
- getAddress() {
17
+ getGenericUserCancelledError() {
18
+ const error = new Error();
19
+ error.code = '-32000'; // error code for user cancelled
20
+ return error;
21
+ }
22
+ getAddresses() {
20
23
  return __awaiter(this, void 0, void 0, function* () {
21
24
  var _a;
22
- // xverse doesn't support wallet standard, so we won't have a wallet object,
23
- // but it's already the default provider for sats-connect, so it's ok
24
- // for getProvider in getAddress to return undefined
25
- // if we're not using xverse, we need to check if there is a wallet and
26
- // that it has the satsconnect feature to return the correct provider to use
27
- if (!supportsSatsConnect(this)) {
28
- return;
25
+ const getAddressResponse = yield request('getAddresses', {
26
+ purposes: [AddressPurpose.Payment, AddressPurpose.Ordinals],
27
+ });
28
+ if (getAddressResponse.status !== 'success') {
29
+ throw getAddressResponse.error;
29
30
  }
31
+ const { addresses } = getAddressResponse.result;
32
+ const ordinalsAccount = addresses === null || addresses === void 0 ? void 0 : addresses.find((address) => address.purpose === AddressPurpose.Ordinals);
33
+ const paymentAccount = addresses === null || addresses === void 0 ? void 0 : addresses.find((address) => address.purpose === AddressPurpose.Payment);
34
+ const mainAddress = (_a = ordinalsAccount === null || ordinalsAccount === void 0 ? void 0 : ordinalsAccount.address) !== null && _a !== void 0 ? _a : paymentAccount === null || paymentAccount === void 0 ? void 0 : paymentAccount.address;
35
+ yield this.setConnectedAccountWithAddresses({
36
+ active: true,
37
+ mainAddress,
38
+ ordinalsAddress: ordinalsAccount,
39
+ paymentAddress: paymentAccount,
40
+ });
41
+ return mainAddress;
42
+ });
43
+ }
44
+ getAddress() {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ var _a;
30
47
  const wallet = findWalletBookWallet(this.walletBook, this.key);
31
48
  const inAppBrowserUrl = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.mobile) === null || _a === void 0 ? void 0 : _a.inAppBrowser;
32
49
  if (isMobile() &&
@@ -40,154 +57,87 @@ class BitcoinSatsConnectConnector extends BitcoinWalletConnector {
40
57
  window.location.href = deepLink;
41
58
  return;
42
59
  }
43
- return new Promise((resolve, reject) => {
44
- getAddress({
45
- getProvider: () => __awaiter(this, void 0, void 0, function* () {
46
- var _a, _b;
47
- return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
48
- }),
49
- onCancel: () => {
50
- const error = new Error();
51
- error.code = '-32000'; // error code for user cancelled
52
- reject(error);
53
- },
54
- onFinish: (response) => __awaiter(this, void 0, void 0, function* () {
55
- var _c;
56
- const { addresses } = response;
57
- const ordinalsAccount = addresses === null || addresses === void 0 ? void 0 : addresses.find((address) => address.purpose === AddressPurpose.Ordinals);
58
- const paymentAccount = addresses === null || addresses === void 0 ? void 0 : addresses.find((address) => address.purpose === AddressPurpose.Payment);
59
- const mainAddress = (_c = ordinalsAccount === null || ordinalsAccount === void 0 ? void 0 : ordinalsAccount.address) !== null && _c !== void 0 ? _c : paymentAccount === null || paymentAccount === void 0 ? void 0 : paymentAccount.address;
60
- yield this.setConnectedAccountWithAddresses({
61
- active: true,
62
- mainAddress,
63
- ordinalsAddress: ordinalsAccount,
64
- paymentAddress: paymentAccount,
65
- });
66
- resolve(mainAddress);
67
- }),
68
- payload: {
69
- message: 'Address for receiving Ordinals and payments',
70
- network: {
71
- type: this.currentNetwork,
72
- },
73
- purposes: [AddressPurpose.Ordinals, AddressPurpose.Payment],
74
- },
75
- });
76
- });
77
- });
78
- }
79
- signMessageWithAddress(messageToSign, address) {
80
- return __awaiter(this, void 0, void 0, function* () {
81
- if (!supportsSatsConnect(this)) {
82
- return;
60
+ try {
61
+ // requesting permissions on initial connect will avoid connection prompt for other requests
62
+ const permissionResponse = yield request('wallet_requestPermissions', undefined);
63
+ if (permissionResponse.status !== 'success') {
64
+ throw permissionResponse.error;
65
+ }
66
+ const address = yield this.getAddresses();
67
+ return address;
68
+ }
69
+ catch (_) {
70
+ const error = this.getGenericUserCancelledError();
71
+ throw error;
83
72
  }
84
- return new Promise((resolve, reject) => {
85
- signMessage({
86
- getProvider: () => __awaiter(this, void 0, void 0, function* () {
87
- var _a, _b;
88
- return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
89
- }),
90
- onCancel: () => {
91
- const error = new Error();
92
- error.code = '-32000'; // error code for user cancelled
93
- reject(error);
94
- },
95
- onFinish: (response) => __awaiter(this, void 0, void 0, function* () {
96
- if (this.isHardwareWalletEnabled) {
97
- return resolve(JSON.stringify({
98
- signedTransaction: {
99
- data: response,
100
- },
101
- }));
102
- }
103
- resolve(response);
104
- }),
105
- payload: {
106
- address,
107
- message: messageToSign,
108
- network: {
109
- type: this.currentNetwork,
110
- },
111
- },
112
- });
113
- });
114
73
  });
115
74
  }
116
- signMessage(messageToSign) {
75
+ signMessage(messageToSign, withAddress) {
117
76
  return __awaiter(this, void 0, void 0, function* () {
118
- const [walletAddress] = yield this.getConnectedAccounts();
119
- if (!walletAddress) {
120
- return;
77
+ try {
78
+ const response = yield request('signMessage', {
79
+ address: withAddress,
80
+ message: messageToSign,
81
+ });
82
+ if (response.status !== 'success') {
83
+ throw response.error;
84
+ }
85
+ if (this.isHardwareWalletEnabled) {
86
+ return JSON.stringify({
87
+ signedTransaction: {
88
+ data: response.result.signature,
89
+ },
90
+ });
91
+ }
92
+ return response.result.signature;
93
+ }
94
+ catch (_) {
95
+ const error = this.getGenericUserCancelledError();
96
+ throw error;
121
97
  }
122
- return this.signMessageWithAddress(messageToSign, walletAddress);
123
98
  });
124
99
  }
125
100
  sendBitcoin(transaction) {
126
101
  return __awaiter(this, void 0, void 0, function* () {
127
- var _a;
128
- const mainAddress = yield this.getAddress();
129
- const senderAddress = (_a = (yield this.getAdditionalAddresses(mainAddress)).find((address) => address.type === 'payment')) === null || _a === void 0 ? void 0 : _a.address;
130
- if (!senderAddress || !supportsSatsConnect(this)) {
131
- return;
132
- }
133
- return new Promise((resolve, reject) => {
134
- sendBtcTransaction({
135
- getProvider: () => __awaiter(this, void 0, void 0, function* () {
136
- var _a, _b;
137
- return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
138
- }),
139
- onCancel: () => {
140
- const error = new Error();
141
- error.code = '-32000'; // error code for user cancelled
142
- reject(error);
143
- },
144
- onFinish: (response) => {
145
- resolve(response);
146
- },
147
- payload: {
148
- network: {
149
- type: this.currentNetwork,
102
+ try {
103
+ const response = yield request('sendTransfer', {
104
+ recipients: [
105
+ {
106
+ address: transaction.recipientAddress,
107
+ amount: Number(transaction.amount),
150
108
  },
151
- recipients: [
152
- {
153
- address: transaction.recipientAddress,
154
- amountSats: transaction.amount,
155
- },
156
- ],
157
- senderAddress,
158
- },
109
+ ],
159
110
  });
160
- });
111
+ if (response.status !== 'success') {
112
+ throw response.error;
113
+ }
114
+ return response.result.txid;
115
+ }
116
+ catch (_) {
117
+ const error = this.getGenericUserCancelledError();
118
+ throw error;
119
+ }
161
120
  });
162
121
  }
163
122
  signTransaction(params) {
164
123
  return __awaiter(this, void 0, void 0, function* () {
165
- const { message, psbtBase64, broadcast, inputsToSign } = params;
166
- return new Promise((resolve, reject) => {
167
- signTransaction({
168
- getProvider: () => __awaiter(this, void 0, void 0, function* () {
169
- var _a, _b;
170
- return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
171
- }),
172
- onCancel: () => {
173
- const error = new Error();
174
- error.code = '-32000'; // error code for user cancelled
175
- reject(error);
176
- },
177
- onFinish: (response) => {
178
- resolve(response);
179
- },
180
- payload: {
181
- broadcast,
182
- inputsToSign,
183
- message: message || 'Sign Transaction',
184
- network: {
185
- type: this.currentNetwork,
186
- },
187
- psbtBase64,
188
- },
124
+ const { allowedSignHash, psbtBase64, broadcast, inputsToSign } = params;
125
+ try {
126
+ const response = yield request('signPsbt', {
127
+ allowedSignHash,
128
+ broadcast,
129
+ psbt: psbtBase64,
130
+ signInputs: Object.fromEntries(inputsToSign.map((input) => [input.address, input.signingIndexes])),
189
131
  });
190
- });
132
+ if (response.status !== 'success') {
133
+ throw response.error;
134
+ }
135
+ return { psbtBase64: response.result.psbt, txId: response.result.txid };
136
+ }
137
+ catch (_) {
138
+ const error = this.getGenericUserCancelledError();
139
+ throw error;
140
+ }
191
141
  });
192
142
  }
193
143
  signTransactions(transactions) {
@@ -195,13 +145,8 @@ class BitcoinSatsConnectConnector extends BitcoinWalletConnector {
195
145
  const { message, psbts, network } = transactions;
196
146
  return new Promise((resolve, reject) => {
197
147
  signMultipleTransactions({
198
- getProvider: () => __awaiter(this, void 0, void 0, function* () {
199
- var _a, _b;
200
- return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
201
- }),
202
148
  onCancel: () => {
203
- const error = new Error();
204
- error.code = '-32000'; // error code for user cancelled
149
+ const error = this.getGenericUserCancelledError();
205
150
  reject(error);
206
151
  },
207
152
  onFinish: (response) => {
@@ -261,6 +206,16 @@ class BitcoinSatsConnectConnector extends BitcoinWalletConnector {
261
206
  return (_a = signedPsbts === null || signedPsbts === void 0 ? void 0 : signedPsbts.map((signedPsbts) => signedPsbts.psbtBase64)) !== null && _a !== void 0 ? _a : [];
262
207
  });
263
208
  }
209
+ validateActiveWallet(expectedAddress) {
210
+ return __awaiter(this, void 0, void 0, function* () {
211
+ // TODO: this is a workaround to avoid extra connecting prompt for xverse
212
+ // we should revisit it once xverse releases a new version with bug fixes
213
+ logger.debug('validateActiveWallet - skipping validation for xverse', {
214
+ expectedAddress,
215
+ });
216
+ return;
217
+ });
218
+ }
264
219
  }
265
220
 
266
221
  export { BitcoinSatsConnectConnector };
@@ -0,0 +1,212 @@
1
+ 'use client'
2
+ 'use strict';
3
+
4
+ Object.defineProperty(exports, '__esModule', { value: true });
5
+
6
+ var _tslib = require('../../../_virtual/_tslib.cjs');
7
+ var satsConnect = require('sats-connect');
8
+ var utils = require('@dynamic-labs/utils');
9
+ var walletBook = require('@dynamic-labs/wallet-book');
10
+ var _const = require('../../const.cjs');
11
+ require('bitcoinjs-lib');
12
+ require('@dynamic-labs/wallet-connector-core');
13
+ require('@dynamic-labs/sdk-api-core');
14
+ require('@wallet-standard/app');
15
+ var BitcoinSatsConnectConnector = require('../BitcoinSatsConnectConnector/BitcoinSatsConnectConnector.cjs');
16
+ var supportsSatsConnect = require('../../utils/supportsSatsConnect.cjs');
17
+
18
+ class BitcoinSatsConnectLegacyConnector extends BitcoinSatsConnectConnector.BitcoinSatsConnectConnector {
19
+ getAddress() {
20
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
21
+ var _a;
22
+ // xverse doesn't support wallet standard, so we won't have a wallet object,
23
+ // but it's already the default provider for sats-connect, so it's ok
24
+ // for getProvider in getAddress to return undefined
25
+ // if we're not using xverse, we need to check if there is a wallet and
26
+ // that it has the satsconnect feature to return the correct provider to use
27
+ if (!supportsSatsConnect.supportsSatsConnect(this)) {
28
+ return;
29
+ }
30
+ const wallet = walletBook.findWalletBookWallet(this.walletBook, this.key);
31
+ const inAppBrowserUrl = (_a = wallet === null || wallet === void 0 ? void 0 : wallet.mobile) === null || _a === void 0 ? void 0 : _a.inAppBrowser;
32
+ if (utils.isMobile() &&
33
+ !this.isInstalledOnBrowser() &&
34
+ inAppBrowserUrl &&
35
+ this.mobileExperience === 'in-app-browser') {
36
+ const inAppBrowserTemplate = utils.template(inAppBrowserUrl);
37
+ const deepLink = inAppBrowserTemplate({
38
+ encodedDappURI: encodeURIComponent(window.location.toString()),
39
+ });
40
+ window.location.href = deepLink;
41
+ return;
42
+ }
43
+ return new Promise((resolve, reject) => {
44
+ satsConnect.getAddress({
45
+ getProvider: () => _tslib.__awaiter(this, void 0, void 0, function* () {
46
+ var _a, _b;
47
+ return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[_const.SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
48
+ }),
49
+ onCancel: () => {
50
+ const error = new Error();
51
+ error.code = '-32000'; // error code for user cancelled
52
+ reject(error);
53
+ },
54
+ onFinish: (response) => _tslib.__awaiter(this, void 0, void 0, function* () {
55
+ var _c;
56
+ const { addresses } = response;
57
+ const ordinalsAccount = addresses === null || addresses === void 0 ? void 0 : addresses.find((address) => address.purpose === satsConnect.AddressPurpose.Ordinals);
58
+ const paymentAccount = addresses === null || addresses === void 0 ? void 0 : addresses.find((address) => address.purpose === satsConnect.AddressPurpose.Payment);
59
+ const mainAddress = (_c = ordinalsAccount === null || ordinalsAccount === void 0 ? void 0 : ordinalsAccount.address) !== null && _c !== void 0 ? _c : paymentAccount === null || paymentAccount === void 0 ? void 0 : paymentAccount.address;
60
+ yield this.setConnectedAccountWithAddresses({
61
+ active: true,
62
+ mainAddress,
63
+ ordinalsAddress: ordinalsAccount,
64
+ paymentAddress: paymentAccount,
65
+ });
66
+ resolve(mainAddress);
67
+ }),
68
+ payload: {
69
+ message: 'Address for receiving Ordinals and payments',
70
+ network: {
71
+ type: this.currentNetwork,
72
+ },
73
+ purposes: [satsConnect.AddressPurpose.Ordinals, satsConnect.AddressPurpose.Payment],
74
+ },
75
+ });
76
+ });
77
+ });
78
+ }
79
+ signMessage(messageToSign, withAddress) {
80
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
81
+ if (!supportsSatsConnect.supportsSatsConnect(this)) {
82
+ return;
83
+ }
84
+ return new Promise((resolve, reject) => {
85
+ satsConnect.signMessage({
86
+ getProvider: () => _tslib.__awaiter(this, void 0, void 0, function* () {
87
+ var _a, _b;
88
+ return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[_const.SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
89
+ }),
90
+ onCancel: () => {
91
+ const error = new Error();
92
+ error.code = '-32000'; // error code for user cancelled
93
+ reject(error);
94
+ },
95
+ onFinish: (response) => _tslib.__awaiter(this, void 0, void 0, function* () {
96
+ if (this.isHardwareWalletEnabled) {
97
+ return resolve(JSON.stringify({
98
+ signedTransaction: {
99
+ data: response,
100
+ },
101
+ }));
102
+ }
103
+ resolve(response);
104
+ }),
105
+ payload: {
106
+ address: withAddress,
107
+ message: messageToSign,
108
+ network: {
109
+ type: this.currentNetwork,
110
+ },
111
+ },
112
+ });
113
+ });
114
+ });
115
+ }
116
+ sendBitcoin(transaction) {
117
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
118
+ var _a;
119
+ const mainAddress = yield this.getAddress();
120
+ const senderAddress = (_a = (yield this.getAdditionalAddresses(mainAddress)).find((address) => address.type === 'payment')) === null || _a === void 0 ? void 0 : _a.address;
121
+ if (!senderAddress || !supportsSatsConnect.supportsSatsConnect(this)) {
122
+ return;
123
+ }
124
+ return new Promise((resolve, reject) => {
125
+ satsConnect.sendBtcTransaction({
126
+ getProvider: () => _tslib.__awaiter(this, void 0, void 0, function* () {
127
+ var _a, _b;
128
+ return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[_const.SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
129
+ }),
130
+ onCancel: () => {
131
+ const error = new Error();
132
+ error.code = '-32000'; // error code for user cancelled
133
+ reject(error);
134
+ },
135
+ onFinish: (response) => {
136
+ resolve(response);
137
+ },
138
+ payload: {
139
+ network: {
140
+ type: this.currentNetwork,
141
+ },
142
+ recipients: [
143
+ {
144
+ address: transaction.recipientAddress,
145
+ amountSats: transaction.amount,
146
+ },
147
+ ],
148
+ senderAddress,
149
+ },
150
+ });
151
+ });
152
+ });
153
+ }
154
+ signTransaction(params) {
155
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
156
+ const { message, psbtBase64, broadcast, inputsToSign } = params;
157
+ return new Promise((resolve, reject) => {
158
+ satsConnect.signTransaction({
159
+ getProvider: () => _tslib.__awaiter(this, void 0, void 0, function* () {
160
+ var _a, _b;
161
+ return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[_const.SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
162
+ }),
163
+ onCancel: () => {
164
+ const error = new Error();
165
+ error.code = '-32000'; // error code for user cancelled
166
+ reject(error);
167
+ },
168
+ onFinish: (response) => {
169
+ resolve(response);
170
+ },
171
+ payload: {
172
+ broadcast,
173
+ inputsToSign,
174
+ message: message || 'Sign Transaction',
175
+ network: {
176
+ type: this.currentNetwork,
177
+ },
178
+ psbtBase64,
179
+ },
180
+ });
181
+ });
182
+ });
183
+ }
184
+ signTransactions(transactions) {
185
+ return _tslib.__awaiter(this, void 0, void 0, function* () {
186
+ const { message, psbts, network } = transactions;
187
+ return new Promise((resolve, reject) => {
188
+ satsConnect.signMultipleTransactions({
189
+ getProvider: () => _tslib.__awaiter(this, void 0, void 0, function* () {
190
+ var _a, _b;
191
+ return (_b = (_a = this.wallet) === null || _a === void 0 ? void 0 : _a.features[_const.SATSCONNECT_FEATURE]) === null || _b === void 0 ? void 0 : _b.provider;
192
+ }),
193
+ onCancel: () => {
194
+ const error = new Error();
195
+ error.code = '-32000'; // error code for user cancelled
196
+ reject(error);
197
+ },
198
+ onFinish: (response) => {
199
+ resolve(response);
200
+ },
201
+ payload: {
202
+ message: message || 'Sign Transaction',
203
+ network,
204
+ psbts,
205
+ },
206
+ });
207
+ });
208
+ });
209
+ }
210
+ }
211
+
212
+ exports.BitcoinSatsConnectLegacyConnector = BitcoinSatsConnectLegacyConnector;
@@ -0,0 +1,10 @@
1
+ import { SignMultipleTransactionsPayload, SignTransactionResponse } from 'sats-connect';
2
+ import { BitcoinTransaction, SatsConnectSignTransactionInput } from '../../types';
3
+ import { BitcoinSatsConnectConnector } from '../BitcoinSatsConnectConnector';
4
+ export declare abstract class BitcoinSatsConnectLegacyConnector extends BitcoinSatsConnectConnector {
5
+ getAddress(): Promise<string | undefined>;
6
+ signMessage(messageToSign: string, withAddress: string): Promise<string | undefined>;
7
+ sendBitcoin(transaction: BitcoinTransaction): Promise<string | undefined>;
8
+ signTransaction(params: SatsConnectSignTransactionInput): Promise<SignTransactionResponse | undefined>;
9
+ signTransactions(transactions: SignMultipleTransactionsPayload): Promise<SignTransactionResponse[] | undefined>;
10
+ }