@subwallet/extension-base 1.3.41-0 → 1.3.42-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/background/KoniTypes.d.ts +121 -4
- package/background/KoniTypes.js +18 -0
- package/background/errors/BitcoinProviderError.d.ts +6 -0
- package/background/errors/BitcoinProviderError.js +47 -0
- package/cjs/background/KoniTypes.js +20 -1
- package/cjs/background/errors/BitcoinProviderError.js +54 -0
- package/cjs/constants/bitcoin.js +22 -0
- package/cjs/constants/index.js +16 -1
- package/cjs/core/logic-validation/recipientAddress.js +9 -0
- package/cjs/core/logic-validation/transfer.js +25 -5
- package/cjs/core/types.js +1 -0
- package/cjs/core/utils.js +15 -1
- package/cjs/koni/background/handlers/Extension.js +59 -3
- package/cjs/koni/background/handlers/State.js +52 -11
- package/cjs/packageInfo.js +1 -1
- package/cjs/services/balance-service/helpers/subscribe/bitcoin.js +94 -0
- package/cjs/services/balance-service/helpers/subscribe/index.js +19 -7
- package/cjs/services/balance-service/index.js +32 -4
- package/cjs/services/balance-service/transfer/bitcoin-transfer.js +119 -0
- package/cjs/services/balance-service/transfer/token.js +2 -0
- package/cjs/services/base/types.js +2 -0
- package/cjs/services/chain-service/constants.js +14 -3
- package/cjs/services/chain-service/handler/bitcoin/BitcoinApi.js +105 -0
- package/cjs/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +78 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +371 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +19 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +368 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +302 -0
- package/cjs/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
- package/cjs/services/chain-service/index.js +27 -3
- package/cjs/services/chain-service/utils/index.js +57 -4
- package/cjs/services/chain-service/utils/patch.js +1 -1
- package/cjs/services/event-service/index.js +4 -0
- package/cjs/services/fee-service/service.js +8 -3
- package/cjs/services/hiro-service/index.js +96 -0
- package/cjs/services/hiro-service/utils/index.js +85 -0
- package/cjs/services/history-service/bitcoin-history.js +58 -0
- package/cjs/services/history-service/helpers/recoverHistoryStatus.js +96 -4
- package/cjs/services/history-service/index.js +41 -3
- package/cjs/services/keyring-service/context/handlers/Derive.js +1 -1
- package/cjs/services/keyring-service/context/handlers/Migration.js +2 -2
- package/cjs/services/keyring-service/context/handlers/Mnemonic.js +4 -3
- package/cjs/services/migration-service/scripts/MigrateNewUnifiedAccount.js +29 -0
- package/cjs/services/migration-service/scripts/index.js +3 -1
- package/cjs/services/request-service/handler/BitcoinRequestHandler.js +440 -0
- package/cjs/services/request-service/index.js +29 -3
- package/cjs/services/rune-service/index.js +105 -0
- package/cjs/services/transaction-service/helpers/index.js +7 -1
- package/cjs/services/transaction-service/index.js +136 -15
- package/cjs/services/transaction-service/utils.js +6 -3
- package/cjs/strategy/api-request-strategy/context/base.js +31 -0
- package/cjs/strategy/api-request-strategy/index.js +90 -0
- package/cjs/strategy/api-request-strategy/types.js +1 -0
- package/cjs/strategy/api-request-strategy/utils/index.js +33 -0
- package/cjs/types/account/info/keyring.js +1 -1
- package/cjs/types/bitcoin.js +24 -0
- package/cjs/types/fee/bitcoin.js +1 -0
- package/cjs/types/fee/index.js +11 -0
- package/cjs/types/index.js +11 -0
- package/cjs/utils/account/analyze.js +3 -3
- package/cjs/utils/account/common.js +16 -6
- package/cjs/utils/account/derive/info/solo.js +68 -19
- package/cjs/utils/account/derive/info/unified.js +2 -0
- package/cjs/utils/account/derive/validate.js +70 -2
- package/cjs/utils/account/transform.js +11 -5
- package/cjs/utils/bitcoin/common.js +98 -0
- package/cjs/utils/bitcoin/fee.js +21 -0
- package/cjs/utils/bitcoin/index.js +38 -0
- package/cjs/utils/bitcoin/utxo-management.js +281 -0
- package/cjs/utils/fee/transfer.js +48 -0
- package/cjs/utils/index.js +15 -1
- package/constants/bitcoin.d.ts +3 -0
- package/constants/bitcoin.js +13 -0
- package/constants/index.d.ts +2 -0
- package/constants/index.js +3 -1
- package/core/logic-validation/recipientAddress.js +10 -1
- package/core/logic-validation/transfer.d.ts +2 -2
- package/core/logic-validation/transfer.js +27 -7
- package/core/types.d.ts +1 -0
- package/core/types.js +1 -0
- package/core/utils.d.ts +1 -0
- package/core/utils.js +15 -2
- package/koni/background/handlers/Extension.d.ts +2 -0
- package/koni/background/handlers/Extension.js +58 -4
- package/koni/background/handlers/State.d.ts +7 -3
- package/koni/background/handlers/State.js +52 -12
- package/package.json +144 -8
- package/packageInfo.js +1 -1
- package/services/balance-service/helpers/subscribe/bitcoin.d.ts +2 -0
- package/services/balance-service/helpers/subscribe/bitcoin.js +87 -0
- package/services/balance-service/helpers/subscribe/index.d.ts +2 -2
- package/services/balance-service/helpers/subscribe/index.js +20 -8
- package/services/balance-service/index.d.ts +2 -0
- package/services/balance-service/index.js +32 -4
- package/services/balance-service/transfer/bitcoin-transfer.d.ts +14 -0
- package/services/balance-service/transfer/bitcoin-transfer.js +112 -0
- package/services/balance-service/transfer/token.js +2 -0
- package/services/base/types.d.ts +2 -0
- package/services/base/types.js +2 -0
- package/services/chain-service/constants.d.ts +6 -0
- package/services/chain-service/constants.js +8 -2
- package/services/chain-service/handler/bitcoin/BitcoinApi.d.ts +31 -0
- package/services/chain-service/handler/bitcoin/BitcoinApi.js +98 -0
- package/services/chain-service/handler/bitcoin/BitcoinChainHandler.d.ts +16 -0
- package/services/chain-service/handler/bitcoin/BitcoinChainHandler.js +70 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.d.ts +28 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/blockstream-testnet-strategy.js +362 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.d.ts +2 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/index.js +5 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.d.ts +28 -0
- package/services/chain-service/handler/bitcoin/strategy/BlockStreamTestnet/mempool-testnet-strategy.js +359 -0
- package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.d.ts +28 -0
- package/services/chain-service/handler/bitcoin/strategy/SubWalletMainnet/index.js +293 -0
- package/services/chain-service/handler/bitcoin/strategy/types.d.ts +291 -0
- package/services/chain-service/handler/bitcoin/strategy/types.js +1 -0
- package/services/chain-service/index.d.ts +3 -0
- package/services/chain-service/index.js +31 -5
- package/services/chain-service/types.d.ts +20 -0
- package/services/chain-service/utils/index.d.ts +4 -0
- package/services/chain-service/utils/index.js +50 -4
- package/services/chain-service/utils/patch.js +1 -1
- package/services/event-service/index.d.ts +3 -0
- package/services/event-service/index.js +4 -0
- package/services/event-service/types.d.ts +3 -0
- package/services/fee-service/service.js +8 -3
- package/services/hiro-service/index.d.ts +17 -0
- package/services/hiro-service/index.js +88 -0
- package/services/hiro-service/utils/index.d.ts +6 -0
- package/services/hiro-service/utils/index.js +72 -0
- package/services/history-service/bitcoin-history.d.ts +4 -0
- package/services/history-service/bitcoin-history.js +52 -0
- package/services/history-service/helpers/recoverHistoryStatus.d.ts +3 -1
- package/services/history-service/helpers/recoverHistoryStatus.js +96 -4
- package/services/history-service/index.d.ts +1 -0
- package/services/history-service/index.js +42 -4
- package/services/keyring-service/context/handlers/Derive.js +2 -2
- package/services/keyring-service/context/handlers/Migration.js +2 -2
- package/services/keyring-service/context/handlers/Mnemonic.js +4 -3
- package/services/migration-service/scripts/MigrateNewUnifiedAccount.d.ts +4 -0
- package/services/migration-service/scripts/MigrateNewUnifiedAccount.js +21 -0
- package/services/migration-service/scripts/index.js +3 -1
- package/services/request-service/handler/BitcoinRequestHandler.d.ts +23 -0
- package/services/request-service/handler/BitcoinRequestHandler.js +427 -0
- package/services/request-service/index.d.ts +9 -2
- package/services/request-service/index.js +25 -3
- package/services/rune-service/index.d.ts +17 -0
- package/services/rune-service/index.js +97 -0
- package/services/transaction-service/helpers/index.d.ts +3 -1
- package/services/transaction-service/helpers/index.js +5 -0
- package/services/transaction-service/index.d.ts +3 -5
- package/services/transaction-service/index.js +135 -16
- package/services/transaction-service/types.d.ts +12 -2
- package/services/transaction-service/utils.js +7 -4
- package/strategy/api-request-strategy/context/base.d.ts +15 -0
- package/strategy/api-request-strategy/context/base.js +24 -0
- package/strategy/api-request-strategy/index.d.ts +15 -0
- package/strategy/api-request-strategy/index.js +83 -0
- package/strategy/api-request-strategy/types.d.ts +22 -0
- package/strategy/api-request-strategy/types.js +1 -0
- package/strategy/api-request-strategy/utils/index.d.ts +2 -0
- package/strategy/api-request-strategy/utils/index.js +23 -0
- package/types/account/info/keyring.d.ts +1 -1
- package/types/account/info/keyring.js +1 -1
- package/types/balance/index.d.ts +4 -1
- package/types/balance/transfer.d.ts +17 -0
- package/types/bitcoin.d.ts +93 -0
- package/types/bitcoin.js +17 -0
- package/types/fee/base.d.ts +4 -1
- package/types/fee/bitcoin.d.ts +18 -0
- package/types/fee/bitcoin.js +1 -0
- package/types/fee/index.d.ts +1 -0
- package/types/fee/index.js +2 -1
- package/types/fee/subscription.d.ts +4 -3
- package/types/index.d.ts +1 -0
- package/types/index.js +1 -0
- package/utils/account/analyze.js +4 -4
- package/utils/account/common.d.ts +7 -8
- package/utils/account/common.js +16 -6
- package/utils/account/derive/info/solo.js +70 -21
- package/utils/account/derive/info/unified.js +2 -0
- package/utils/account/derive/validate.d.ts +1 -0
- package/utils/account/derive/validate.js +68 -1
- package/utils/account/transform.d.ts +1 -1
- package/utils/account/transform.js +11 -5
- package/utils/bitcoin/common.d.ts +22 -0
- package/utils/bitcoin/common.js +88 -0
- package/utils/bitcoin/fee.d.ts +2 -0
- package/utils/bitcoin/fee.js +14 -0
- package/utils/bitcoin/index.d.ts +3 -0
- package/utils/bitcoin/index.js +6 -0
- package/utils/bitcoin/utxo-management.d.ts +33 -0
- package/utils/bitcoin/utxo-management.js +266 -0
- package/utils/fee/transfer.d.ts +3 -1
- package/utils/fee/transfer.js +47 -1
- package/utils/index.d.ts +1 -0
- package/utils/index.js +6 -3
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { BitcoinProviderError } from '@subwallet/extension-base/background/errors/BitcoinProviderError';
|
|
5
|
+
import { TransactionError } from '@subwallet/extension-base/background/errors/TransactionError';
|
|
6
|
+
import { BitcoinProviderErrorType } from '@subwallet/extension-base/background/KoniTypes';
|
|
7
|
+
import { createBitcoinTransaction } from '@subwallet/extension-base/services/balance-service/transfer/bitcoin-transfer';
|
|
8
|
+
import { BasicTxErrorType } from '@subwallet/extension-base/types';
|
|
9
|
+
import { createPromiseHandler } from '@subwallet/extension-base/utils';
|
|
10
|
+
import { getId } from '@subwallet/extension-base/utils/getId';
|
|
11
|
+
import { isInternalRequest } from '@subwallet/extension-base/utils/request';
|
|
12
|
+
import keyring from '@subwallet/ui-keyring';
|
|
13
|
+
import { Psbt } from 'bitcoinjs-lib';
|
|
14
|
+
import * as bitcoin from 'bitcoinjs-lib';
|
|
15
|
+
import { t } from 'i18next';
|
|
16
|
+
import { BehaviorSubject } from 'rxjs';
|
|
17
|
+
import { isArray, logger as createLogger } from '@polkadot/util';
|
|
18
|
+
export default class BitcoinRequestHandler {
|
|
19
|
+
#requestService;
|
|
20
|
+
#chainService;
|
|
21
|
+
#transactionService;
|
|
22
|
+
#feeService;
|
|
23
|
+
#logger;
|
|
24
|
+
confirmationsQueueSubjectBitcoin = new BehaviorSubject({
|
|
25
|
+
bitcoinSignatureRequest: {},
|
|
26
|
+
bitcoinSendTransactionRequest: {},
|
|
27
|
+
bitcoinWatchTransactionRequest: {},
|
|
28
|
+
bitcoinSendTransactionRequestAfterConfirmation: {},
|
|
29
|
+
bitcoinSignPsbtRequest: {}
|
|
30
|
+
});
|
|
31
|
+
confirmationsPromiseMap = {};
|
|
32
|
+
constructor(requestService, chainService, feeService, transactionService) {
|
|
33
|
+
this.#requestService = requestService;
|
|
34
|
+
this.#chainService = chainService;
|
|
35
|
+
this.#feeService = feeService;
|
|
36
|
+
this.#transactionService = transactionService;
|
|
37
|
+
this.#logger = createLogger('BitcoinRequestHandler');
|
|
38
|
+
}
|
|
39
|
+
get numBitcoinRequests() {
|
|
40
|
+
let count = 0;
|
|
41
|
+
Object.values(this.confirmationsQueueSubjectBitcoin.getValue()).forEach(x => {
|
|
42
|
+
count += Object.keys(x).length;
|
|
43
|
+
});
|
|
44
|
+
return count;
|
|
45
|
+
}
|
|
46
|
+
getConfirmationsQueueSubjectBitcoin() {
|
|
47
|
+
return this.confirmationsQueueSubjectBitcoin;
|
|
48
|
+
}
|
|
49
|
+
async addConfirmationBitcoin(id, url, type, payload, options = {}, validator) {
|
|
50
|
+
const confirmations = this.confirmationsQueueSubjectBitcoin.getValue();
|
|
51
|
+
const confirmationType = confirmations[type];
|
|
52
|
+
const payloadJson = JSON.stringify(payload);
|
|
53
|
+
const isInternal = isInternalRequest(url);
|
|
54
|
+
if (['bitcoinSignatureRequest', 'bitcoinSendTransactionRequest', 'bitcoinSendTransactionRequestAfterConfirmation'].includes(type)) {
|
|
55
|
+
const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
|
|
56
|
+
if (isAlwaysRequired) {
|
|
57
|
+
this.#requestService.keyringService.lock();
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Check duplicate request
|
|
62
|
+
const duplicated = Object.values(confirmationType).find(c => c.url === url && c.payloadJson === payloadJson);
|
|
63
|
+
if (duplicated) {
|
|
64
|
+
throw new Error('Duplicate request');
|
|
65
|
+
}
|
|
66
|
+
confirmationType[id] = {
|
|
67
|
+
id,
|
|
68
|
+
url,
|
|
69
|
+
isInternal,
|
|
70
|
+
payload,
|
|
71
|
+
payloadJson,
|
|
72
|
+
...options
|
|
73
|
+
};
|
|
74
|
+
const promise = new Promise((resolve, reject) => {
|
|
75
|
+
this.confirmationsPromiseMap[id] = {
|
|
76
|
+
validator: validator,
|
|
77
|
+
resolver: {
|
|
78
|
+
resolve: resolve,
|
|
79
|
+
reject: reject
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
});
|
|
83
|
+
this.confirmationsQueueSubjectBitcoin.next(confirmations);
|
|
84
|
+
if (!isInternal) {
|
|
85
|
+
this.#requestService.popupOpen();
|
|
86
|
+
}
|
|
87
|
+
this.#requestService.updateIconV2();
|
|
88
|
+
return promise;
|
|
89
|
+
}
|
|
90
|
+
updateConfirmationBitcoin(id, type, payload, options = {}, validator) {
|
|
91
|
+
const confirmations = this.confirmationsQueueSubjectBitcoin.getValue();
|
|
92
|
+
const confirmationType = confirmations[type];
|
|
93
|
+
|
|
94
|
+
// Check duplicate request
|
|
95
|
+
const exists = confirmationType[id];
|
|
96
|
+
if (!exists) {
|
|
97
|
+
throw new Error('Request does not exist');
|
|
98
|
+
}
|
|
99
|
+
const payloadJson = JSON.stringify(payload);
|
|
100
|
+
confirmationType[id] = {
|
|
101
|
+
...exists,
|
|
102
|
+
payload,
|
|
103
|
+
payloadJson,
|
|
104
|
+
...options
|
|
105
|
+
};
|
|
106
|
+
if (validator) {
|
|
107
|
+
this.confirmationsPromiseMap[id].validator = validator;
|
|
108
|
+
}
|
|
109
|
+
this.confirmationsQueueSubjectBitcoin.next(confirmations);
|
|
110
|
+
}
|
|
111
|
+
signMessageBitcoin(confirmation) {
|
|
112
|
+
const {
|
|
113
|
+
account,
|
|
114
|
+
payload
|
|
115
|
+
} = confirmation.payload;
|
|
116
|
+
const address = account.address;
|
|
117
|
+
const pair = keyring.getPair(address);
|
|
118
|
+
if (pair.isLocked) {
|
|
119
|
+
keyring.unlockPair(pair.address);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Check if payload is a string
|
|
123
|
+
if (typeof payload === 'string') {
|
|
124
|
+
// Assume BitcoinSigner is an instance that implements the BitcoinSigner interface
|
|
125
|
+
return {
|
|
126
|
+
signature: pair.bitcoin.signMessage(payload),
|
|
127
|
+
message: payload,
|
|
128
|
+
address
|
|
129
|
+
}; // Assuming compressed = false
|
|
130
|
+
} else if (payload instanceof Uint8Array) {
|
|
131
|
+
// Check if payload is a byte array (Uint8Array)
|
|
132
|
+
// Convert Uint8Array to string
|
|
133
|
+
const payloadString = Buffer.from(payload).toString('hex');
|
|
134
|
+
|
|
135
|
+
// Assume BitcoinSigner is an instance that implements the BitcoinSigner interface
|
|
136
|
+
return {
|
|
137
|
+
signature: pair.bitcoin.signMessage(payloadString),
|
|
138
|
+
message: payload.toString(),
|
|
139
|
+
address
|
|
140
|
+
}; // Assuming compressed = false
|
|
141
|
+
} else {
|
|
142
|
+
// Handle the case where payload is invalid
|
|
143
|
+
throw new Error('Invalid payload type');
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
signTransactionBitcoin(request) {
|
|
147
|
+
// Extract necessary information from the BitcoinSendTransactionRequest
|
|
148
|
+
const {
|
|
149
|
+
account,
|
|
150
|
+
hashPayload
|
|
151
|
+
} = request.payload;
|
|
152
|
+
const address = account.address;
|
|
153
|
+
const pair = keyring.getPair(address);
|
|
154
|
+
|
|
155
|
+
// Unlock the pair if it is locked
|
|
156
|
+
if (pair.isLocked) {
|
|
157
|
+
keyring.unlockPair(pair.address);
|
|
158
|
+
}
|
|
159
|
+
const psbt = Psbt.fromHex(hashPayload);
|
|
160
|
+
|
|
161
|
+
// Finalize all inputs in the Psbt
|
|
162
|
+
// Sign the Psbt using the pair's bitcoin object
|
|
163
|
+
const signedTransaction = pair.bitcoin.signTransaction(psbt, psbt.txInputs.map((v, i) => i));
|
|
164
|
+
signedTransaction.finalizeAllInputs();
|
|
165
|
+
return signedTransaction.extractTransaction().toHex();
|
|
166
|
+
}
|
|
167
|
+
async signTransactionBitcoinWithPayload(request) {
|
|
168
|
+
const transaction = this.#transactionService.getTransaction(request.id);
|
|
169
|
+
const {
|
|
170
|
+
chain,
|
|
171
|
+
emitterTransaction,
|
|
172
|
+
feeCustom,
|
|
173
|
+
feeOption,
|
|
174
|
+
id
|
|
175
|
+
} = transaction;
|
|
176
|
+
const {
|
|
177
|
+
from,
|
|
178
|
+
to,
|
|
179
|
+
value
|
|
180
|
+
} = transaction.data;
|
|
181
|
+
if (!emitterTransaction) {
|
|
182
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.INTERNAL_ERROR);
|
|
183
|
+
}
|
|
184
|
+
const chainInfo = this.#chainService.getChainInfoByKey(chain);
|
|
185
|
+
const bitcoinApi = this.#chainService.getBitcoinApi(chain);
|
|
186
|
+
const eventData = {
|
|
187
|
+
id,
|
|
188
|
+
errors: [],
|
|
189
|
+
warnings: [],
|
|
190
|
+
extrinsicHash: id
|
|
191
|
+
};
|
|
192
|
+
const network = chainInfo.isTestnet ? bitcoin.networks.testnet : bitcoin.networks.bitcoin;
|
|
193
|
+
const feeInfo = await this.#feeService.subscribeChainFee(getId(), chain, 'bitcoin');
|
|
194
|
+
const [psbt] = await createBitcoinTransaction({
|
|
195
|
+
bitcoinApi,
|
|
196
|
+
chain,
|
|
197
|
+
from,
|
|
198
|
+
feeCustom,
|
|
199
|
+
feeOption,
|
|
200
|
+
feeInfo,
|
|
201
|
+
to,
|
|
202
|
+
transferAll: false,
|
|
203
|
+
value: value || '0',
|
|
204
|
+
network
|
|
205
|
+
});
|
|
206
|
+
const pair = keyring.getPair(from);
|
|
207
|
+
|
|
208
|
+
// Unlock the pair if it is locked
|
|
209
|
+
if (pair.isLocked) {
|
|
210
|
+
keyring.unlockPair(pair.address);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Finalize all inputs in the Psbt
|
|
214
|
+
|
|
215
|
+
// Sign the Psbt using the pair's bitcoin object
|
|
216
|
+
const signedTransaction = pair.bitcoin.signTransaction(psbt, psbt.txInputs.map((v, i) => i));
|
|
217
|
+
signedTransaction.finalizeAllInputs();
|
|
218
|
+
const signature = signedTransaction.extractTransaction().toHex();
|
|
219
|
+
this.#transactionService.emitterEventTransaction(emitterTransaction, eventData, chainInfo.slug, signature);
|
|
220
|
+
const {
|
|
221
|
+
promise,
|
|
222
|
+
reject,
|
|
223
|
+
resolve
|
|
224
|
+
} = createPromiseHandler();
|
|
225
|
+
emitterTransaction.on('extrinsicHash', data => {
|
|
226
|
+
if (!data.extrinsicHash) {
|
|
227
|
+
reject(BitcoinProviderErrorType.INTERNAL_ERROR);
|
|
228
|
+
} else {
|
|
229
|
+
resolve(data.extrinsicHash);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
emitterTransaction.on('error', error => {
|
|
233
|
+
reject(error);
|
|
234
|
+
});
|
|
235
|
+
return promise;
|
|
236
|
+
}
|
|
237
|
+
async signPsbt(request) {
|
|
238
|
+
// Extract necessary information from the BitcoinSendTransactionRequest
|
|
239
|
+
const {
|
|
240
|
+
account,
|
|
241
|
+
payload
|
|
242
|
+
} = request.payload;
|
|
243
|
+
const {
|
|
244
|
+
allowedSighash,
|
|
245
|
+
broadcast,
|
|
246
|
+
psbt,
|
|
247
|
+
signAtIndex
|
|
248
|
+
} = payload;
|
|
249
|
+
const transaction = this.#transactionService.getTransaction(request.id);
|
|
250
|
+
let eventData = {
|
|
251
|
+
id: request.id,
|
|
252
|
+
errors: [],
|
|
253
|
+
warnings: [],
|
|
254
|
+
extrinsicHash: request.id
|
|
255
|
+
};
|
|
256
|
+
|
|
257
|
+
// todo: validate type of the account
|
|
258
|
+
|
|
259
|
+
if (Object.keys(account).length === 0) {
|
|
260
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.INVALID_PARAMS, 'Please connect to Wallet to try this request');
|
|
261
|
+
}
|
|
262
|
+
const pair = keyring.getPair(account.address);
|
|
263
|
+
|
|
264
|
+
// Unlock the pair if it is locked
|
|
265
|
+
if (pair.isLocked) {
|
|
266
|
+
keyring.unlockPair(pair.address);
|
|
267
|
+
}
|
|
268
|
+
const signAtIndexGenerate = signAtIndex ? isArray(signAtIndex) ? signAtIndex : [signAtIndex] : [...Array(psbt.inputCount)].map((_, i) => i);
|
|
269
|
+
let psptSignedTransaction = null;
|
|
270
|
+
|
|
271
|
+
// Sign the Psbt using the pair's bitcoin object
|
|
272
|
+
try {
|
|
273
|
+
psptSignedTransaction = pair.bitcoin.signTransaction(psbt, signAtIndexGenerate, allowedSighash);
|
|
274
|
+
} catch (e) {
|
|
275
|
+
if (transaction) {
|
|
276
|
+
var _transaction$emitterT;
|
|
277
|
+
(_transaction$emitterT = transaction.emitterTransaction) === null || _transaction$emitterT === void 0 ? void 0 : _transaction$emitterT.emit('error', {
|
|
278
|
+
...eventData,
|
|
279
|
+
errors: [new TransactionError(BasicTxErrorType.INVALID_PARAMS, e.message)],
|
|
280
|
+
id: transaction.id,
|
|
281
|
+
extrinsicHash: transaction.id
|
|
282
|
+
});
|
|
283
|
+
}
|
|
284
|
+
throw new Error(e.message);
|
|
285
|
+
}
|
|
286
|
+
if (!psptSignedTransaction) {
|
|
287
|
+
throw new Error('Unable to sign');
|
|
288
|
+
}
|
|
289
|
+
if (!broadcast) {
|
|
290
|
+
for (const index of signAtIndexGenerate) {
|
|
291
|
+
psptSignedTransaction.finalizeInput(index);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
psbt: psptSignedTransaction.toHex()
|
|
295
|
+
};
|
|
296
|
+
}
|
|
297
|
+
if (!transaction) {
|
|
298
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.INTERNAL_ERROR);
|
|
299
|
+
}
|
|
300
|
+
const {
|
|
301
|
+
chain,
|
|
302
|
+
emitterTransaction,
|
|
303
|
+
id
|
|
304
|
+
} = transaction;
|
|
305
|
+
eventData = {
|
|
306
|
+
id,
|
|
307
|
+
errors: [],
|
|
308
|
+
warnings: [],
|
|
309
|
+
extrinsicHash: id
|
|
310
|
+
};
|
|
311
|
+
if (!emitterTransaction) {
|
|
312
|
+
throw new BitcoinProviderError(BitcoinProviderErrorType.INTERNAL_ERROR);
|
|
313
|
+
}
|
|
314
|
+
const chainInfo = this.#chainService.getChainInfoByKey(chain);
|
|
315
|
+
try {
|
|
316
|
+
psptSignedTransaction.finalizeAllInputs();
|
|
317
|
+
} catch (e) {
|
|
318
|
+
emitterTransaction.emit('error', {
|
|
319
|
+
...eventData,
|
|
320
|
+
errors: [new TransactionError(BasicTxErrorType.INVALID_PARAMS, e.message)]
|
|
321
|
+
});
|
|
322
|
+
throw new Error(e.message);
|
|
323
|
+
}
|
|
324
|
+
const hexTransaction = psptSignedTransaction.extractTransaction().toHex();
|
|
325
|
+
this.#transactionService.emitterEventTransaction(emitterTransaction, eventData, chainInfo.slug, hexTransaction);
|
|
326
|
+
const {
|
|
327
|
+
promise,
|
|
328
|
+
reject,
|
|
329
|
+
resolve
|
|
330
|
+
} = createPromiseHandler();
|
|
331
|
+
emitterTransaction.on('extrinsicHash', data => {
|
|
332
|
+
if (!data.extrinsicHash || !psptSignedTransaction) {
|
|
333
|
+
reject(BitcoinProviderErrorType.INTERNAL_ERROR);
|
|
334
|
+
} else {
|
|
335
|
+
var _psptSignedTransactio;
|
|
336
|
+
resolve({
|
|
337
|
+
psbt: (_psptSignedTransactio = psptSignedTransaction) === null || _psptSignedTransactio === void 0 ? void 0 : _psptSignedTransactio.toHex(),
|
|
338
|
+
txid: data.extrinsicHash
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
});
|
|
342
|
+
emitterTransaction.on('error', error => {
|
|
343
|
+
reject(error);
|
|
344
|
+
});
|
|
345
|
+
return promise;
|
|
346
|
+
}
|
|
347
|
+
async decorateResultBitcoin(t, request, result) {
|
|
348
|
+
if (t === 'bitcoinSignatureRequest') {
|
|
349
|
+
result.payload = this.signMessageBitcoin(request);
|
|
350
|
+
} else if (t === 'bitcoinSendTransactionRequest') {
|
|
351
|
+
result.payload = this.signTransactionBitcoin(request);
|
|
352
|
+
} else if (t === 'bitcoinSignPsbtRequest') {
|
|
353
|
+
result.payload = await this.signPsbt(request);
|
|
354
|
+
} else if (t === 'bitcoinSendTransactionRequestAfterConfirmation') {
|
|
355
|
+
result.payload = await this.signTransactionBitcoinWithPayload(request);
|
|
356
|
+
}
|
|
357
|
+
if (t === 'bitcoinSignatureRequest' || t === 'bitcoinSendTransactionRequest' || t === 'bitcoinSignPsbtRequest' || t === 'bitcoinSendTransactionRequestAfterConfirmation') {
|
|
358
|
+
const isAlwaysRequired = await this.#requestService.settingService.isAlwaysRequired;
|
|
359
|
+
if (isAlwaysRequired) {
|
|
360
|
+
this.#requestService.keyringService.lock();
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
async completeConfirmationBitcoin(request) {
|
|
365
|
+
const confirmations = this.confirmationsQueueSubjectBitcoin.getValue();
|
|
366
|
+
for (const ct in request) {
|
|
367
|
+
const type = ct;
|
|
368
|
+
const result = request[type];
|
|
369
|
+
const {
|
|
370
|
+
id,
|
|
371
|
+
isApproved
|
|
372
|
+
} = result;
|
|
373
|
+
const {
|
|
374
|
+
resolver,
|
|
375
|
+
validator
|
|
376
|
+
} = this.confirmationsPromiseMap[id];
|
|
377
|
+
const confirmation = confirmations[type][id];
|
|
378
|
+
if (!resolver || !confirmation) {
|
|
379
|
+
this.#logger.error(t('Unable to proceed. Please try again'), type, id);
|
|
380
|
+
throw new Error('Unable to proceed. Please try again');
|
|
381
|
+
}
|
|
382
|
+
if (isApproved) {
|
|
383
|
+
try {
|
|
384
|
+
// Fill signature for some special type
|
|
385
|
+
await this.decorateResultBitcoin(type, confirmation, result);
|
|
386
|
+
const error = validator && validator(result);
|
|
387
|
+
if (error) {
|
|
388
|
+
resolver.reject(error);
|
|
389
|
+
}
|
|
390
|
+
} catch (e) {
|
|
391
|
+
resolver.reject(e);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
// Delete confirmations from queue
|
|
396
|
+
delete this.confirmationsPromiseMap[id];
|
|
397
|
+
delete confirmations[type][id];
|
|
398
|
+
this.confirmationsQueueSubjectBitcoin.next(confirmations);
|
|
399
|
+
|
|
400
|
+
// Update icon, and close queue
|
|
401
|
+
this.#requestService.updateIconV2(this.#requestService.numAllRequests === 0);
|
|
402
|
+
resolver.resolve(result);
|
|
403
|
+
}
|
|
404
|
+
return true;
|
|
405
|
+
}
|
|
406
|
+
resetWallet() {
|
|
407
|
+
const confirmations = this.confirmationsQueueSubjectBitcoin.getValue();
|
|
408
|
+
for (const [type, requests] of Object.entries(confirmations)) {
|
|
409
|
+
for (const confirmation of Object.values(requests)) {
|
|
410
|
+
const {
|
|
411
|
+
id
|
|
412
|
+
} = confirmation;
|
|
413
|
+
const {
|
|
414
|
+
resolver
|
|
415
|
+
} = this.confirmationsPromiseMap[id];
|
|
416
|
+
if (!resolver || !confirmation) {
|
|
417
|
+
console.error('Not found confirmation', type, id);
|
|
418
|
+
} else {
|
|
419
|
+
resolver.reject(new Error('Reset wallet'));
|
|
420
|
+
}
|
|
421
|
+
delete this.confirmationsPromiseMap[id];
|
|
422
|
+
delete confirmations[type][id];
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
this.confirmationsQueueSubjectBitcoin.next(confirmations);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { AuthRequestV2, ConfirmationDefinitions, ConfirmationDefinitionsCardano, ConfirmationDefinitionsTon, ConfirmationsQueue, ConfirmationsQueueCardano, ConfirmationsQueueItemOptions, ConfirmationsQueueTon, ConfirmationType, ConfirmationTypeCardano, ConfirmationTypeTon, RequestConfirmationComplete, RequestConfirmationCompleteCardano, RequestConfirmationCompleteTon } from '@subwallet/extension-base/background/KoniTypes';
|
|
1
|
+
import { AuthRequestV2, ConfirmationDefinitions, ConfirmationDefinitionsBitcoin, ConfirmationDefinitionsCardano, ConfirmationDefinitionsTon, ConfirmationsQueue, ConfirmationsQueueBitcoin, ConfirmationsQueueCardano, ConfirmationsQueueItemOptions, ConfirmationsQueueTon, ConfirmationType, ConfirmationTypeBitcoin, ConfirmationTypeCardano, ConfirmationTypeTon, RequestConfirmationComplete, RequestConfirmationCompleteBitcoin, RequestConfirmationCompleteCardano, RequestConfirmationCompleteTon } from '@subwallet/extension-base/background/KoniTypes';
|
|
2
2
|
import { AccountAuthType, AuthorizeRequest, MetadataRequest, RequestAuthorizeTab, RequestSign, ResponseSigning, SigningRequest } from '@subwallet/extension-base/background/types';
|
|
3
3
|
import { ChainService } from '@subwallet/extension-base/services/chain-service';
|
|
4
|
+
import FeeService from '@subwallet/extension-base/services/fee-service/service';
|
|
4
5
|
import { KeyringService } from '@subwallet/extension-base/services/keyring-service';
|
|
5
6
|
import SettingService from '@subwallet/extension-base/services/setting-service/SettingService';
|
|
7
|
+
import TransactionService from '@subwallet/extension-base/services/transaction-service';
|
|
6
8
|
import { WalletConnectNotSupportRequest, WalletConnectSessionRequest } from '@subwallet/extension-base/services/wallet-connect-service/types';
|
|
7
9
|
import { MetadataDef } from '@subwallet/extension-inject/types';
|
|
8
10
|
import { BehaviorSubject } from 'rxjs';
|
|
@@ -12,7 +14,7 @@ export default class RequestService {
|
|
|
12
14
|
#private;
|
|
13
15
|
readonly settingService: SettingService;
|
|
14
16
|
readonly keyringService: KeyringService;
|
|
15
|
-
constructor(chainService: ChainService, settingService: SettingService, keyringService: KeyringService);
|
|
17
|
+
constructor(chainService: ChainService, settingService: SettingService, keyringService: KeyringService, feeService: FeeService, transactionService: TransactionService);
|
|
16
18
|
get numAllRequests(): number;
|
|
17
19
|
updateIconV2(shouldClose?: boolean): void;
|
|
18
20
|
getAddressList(value?: boolean): Record<string, boolean>;
|
|
@@ -48,6 +50,7 @@ export default class RequestService {
|
|
|
48
50
|
get numEvmRequests(): number;
|
|
49
51
|
get numTonRequests(): number;
|
|
50
52
|
get numCardanoRequests(): number;
|
|
53
|
+
get numBitcoinRequests(): number;
|
|
51
54
|
get confirmationsQueueSubject(): BehaviorSubject<ConfirmationsQueue>;
|
|
52
55
|
get confirmationsQueueSubjectTon(): BehaviorSubject<ConfirmationsQueueTon>;
|
|
53
56
|
get confirmationsQueueSubjectCardano(): BehaviorSubject<ConfirmationsQueueCardano>;
|
|
@@ -60,6 +63,10 @@ export default class RequestService {
|
|
|
60
63
|
completeConfirmationTon(request: RequestConfirmationCompleteTon): Promise<boolean>;
|
|
61
64
|
completeConfirmationCardano(request: RequestConfirmationCompleteCardano): Promise<boolean>;
|
|
62
65
|
updateConfirmation<CT extends ConfirmationType>(id: string, type: CT, payload: ConfirmationDefinitions[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitions[CT][1]) => Error | undefined): void;
|
|
66
|
+
get confirmationsQueueSubjectBitcoin(): BehaviorSubject<ConfirmationsQueueBitcoin>;
|
|
67
|
+
addConfirmationBitcoin<CT extends ConfirmationTypeBitcoin>(id: string, url: string, type: CT, payload: ConfirmationDefinitionsBitcoin[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitionsBitcoin[CT][1]) => Error | undefined): Promise<ConfirmationDefinitionsBitcoin[CT][1]>;
|
|
68
|
+
completeConfirmationBitcoin(request: RequestConfirmationCompleteBitcoin): Promise<boolean>;
|
|
69
|
+
updateConfirmationBitcoin<CT extends ConfirmationTypeBitcoin>(id: string, type: CT, payload: ConfirmationDefinitionsBitcoin[CT][0]['payload'], options?: ConfirmationsQueueItemOptions, validator?: (input: ConfirmationDefinitionsBitcoin[CT][1]) => Error | undefined): void;
|
|
63
70
|
getConnectWCRequest(id: string): import("@subwallet/extension-base/services/wallet-connect-service/types").RequestWalletConnectSession;
|
|
64
71
|
get connectWCSubject(): BehaviorSubject<WalletConnectSessionRequest[]>;
|
|
65
72
|
get allConnectWCRequests(): WalletConnectSessionRequest[];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
|
|
4
|
+
import BitcoinRequestHandler from '@subwallet/extension-base/services/request-service/handler/BitcoinRequestHandler';
|
|
4
5
|
import CardanoRequestHandler from '@subwallet/extension-base/services/request-service/handler/CardanoRequestHandler';
|
|
5
6
|
import TonRequestHandler from "./handler/TonRequestHandler.js";
|
|
6
7
|
import { AuthRequestHandler, ConnectWCRequestHandler, EvmRequestHandler, MetadataRequestHandler, NotSupportWCRequestHandler, PopupHandler, SubstrateRequestHandler } from "./handler/index.js";
|
|
@@ -12,13 +13,14 @@ export default class RequestService {
|
|
|
12
13
|
#authRequestHandler;
|
|
13
14
|
#substrateRequestHandler;
|
|
14
15
|
#evmRequestHandler;
|
|
16
|
+
#bitcoinRequestHandler;
|
|
15
17
|
#tonRequestHandler;
|
|
16
18
|
#cardanoRequestHandler;
|
|
17
19
|
#connectWCRequestHandler;
|
|
18
20
|
#notSupportWCRequestHandler;
|
|
19
21
|
|
|
20
22
|
// Common
|
|
21
|
-
constructor(chainService, settingService, keyringService) {
|
|
23
|
+
constructor(chainService, settingService, keyringService, feeService, transactionService) {
|
|
22
24
|
this.#chainService = chainService;
|
|
23
25
|
this.settingService = settingService;
|
|
24
26
|
this.keyringService = keyringService;
|
|
@@ -29,6 +31,7 @@ export default class RequestService {
|
|
|
29
31
|
this.#evmRequestHandler = new EvmRequestHandler(this);
|
|
30
32
|
this.#tonRequestHandler = new TonRequestHandler(this);
|
|
31
33
|
this.#cardanoRequestHandler = new CardanoRequestHandler(this);
|
|
34
|
+
this.#bitcoinRequestHandler = new BitcoinRequestHandler(this, this.#chainService, feeService, transactionService);
|
|
32
35
|
this.#connectWCRequestHandler = new ConnectWCRequestHandler(this);
|
|
33
36
|
this.#notSupportWCRequestHandler = new NotSupportWCRequestHandler(this);
|
|
34
37
|
|
|
@@ -36,7 +39,7 @@ export default class RequestService {
|
|
|
36
39
|
this.updateIconV2();
|
|
37
40
|
}
|
|
38
41
|
get numAllRequests() {
|
|
39
|
-
return this.allSubstrateRequests.length + this.numEvmRequests + this.numTonRequests + this.numCardanoRequests;
|
|
42
|
+
return this.allSubstrateRequests.length + this.numEvmRequests + this.numTonRequests + this.numCardanoRequests + this.numBitcoinRequests;
|
|
40
43
|
}
|
|
41
44
|
updateIconV2(shouldClose) {
|
|
42
45
|
this.#popupHandler.updateIconV2(shouldClose);
|
|
@@ -148,6 +151,9 @@ export default class RequestService {
|
|
|
148
151
|
get numCardanoRequests() {
|
|
149
152
|
return this.#cardanoRequestHandler.numCardanoRequests;
|
|
150
153
|
}
|
|
154
|
+
get numBitcoinRequests() {
|
|
155
|
+
return this.#bitcoinRequestHandler.numBitcoinRequests;
|
|
156
|
+
}
|
|
151
157
|
get confirmationsQueueSubject() {
|
|
152
158
|
return this.#evmRequestHandler.getConfirmationsQueueSubject();
|
|
153
159
|
}
|
|
@@ -185,6 +191,21 @@ export default class RequestService {
|
|
|
185
191
|
return this.#evmRequestHandler.updateConfirmation(id, type, payload, options, validator);
|
|
186
192
|
}
|
|
187
193
|
|
|
194
|
+
// Bitcoin requests
|
|
195
|
+
|
|
196
|
+
get confirmationsQueueSubjectBitcoin() {
|
|
197
|
+
return this.#bitcoinRequestHandler.getConfirmationsQueueSubjectBitcoin();
|
|
198
|
+
}
|
|
199
|
+
addConfirmationBitcoin(id, url, type, payload, options = {}, validator) {
|
|
200
|
+
return this.#bitcoinRequestHandler.addConfirmationBitcoin(id, url, type, payload, options, validator);
|
|
201
|
+
}
|
|
202
|
+
async completeConfirmationBitcoin(request) {
|
|
203
|
+
return await this.#bitcoinRequestHandler.completeConfirmationBitcoin(request);
|
|
204
|
+
}
|
|
205
|
+
updateConfirmationBitcoin(id, type, payload, options = {}, validator) {
|
|
206
|
+
return this.#bitcoinRequestHandler.updateConfirmationBitcoin(id, type, payload, options, validator);
|
|
207
|
+
}
|
|
208
|
+
|
|
188
209
|
// WalletConnect Connect requests
|
|
189
210
|
getConnectWCRequest(id) {
|
|
190
211
|
return this.#connectWCRequestHandler.getConnectWCRequest(id);
|
|
@@ -221,7 +242,7 @@ export default class RequestService {
|
|
|
221
242
|
|
|
222
243
|
// General methods
|
|
223
244
|
get numRequests() {
|
|
224
|
-
return this.numMetaRequests + this.numAuthRequests + this.numSubstrateRequests + this.numEvmRequests + this.numConnectWCRequests + this.numNotSupportWCRequests + this.numTonRequests + this.numCardanoRequests;
|
|
245
|
+
return this.numMetaRequests + this.numAuthRequests + this.numSubstrateRequests + this.numEvmRequests + this.numConnectWCRequests + this.numNotSupportWCRequests + this.numTonRequests + this.numCardanoRequests + this.numBitcoinRequests;
|
|
225
246
|
}
|
|
226
247
|
resetWallet() {
|
|
227
248
|
this.#authRequestHandler.resetWallet();
|
|
@@ -229,6 +250,7 @@ export default class RequestService {
|
|
|
229
250
|
this.#evmRequestHandler.resetWallet();
|
|
230
251
|
this.#tonRequestHandler.resetWallet();
|
|
231
252
|
this.#cardanoRequestHandler.resetWallet();
|
|
253
|
+
this.#bitcoinRequestHandler.resetWallet();
|
|
232
254
|
this.#metadataRequestHandler.resetWallet();
|
|
233
255
|
this.#connectWCRequestHandler.resetWallet();
|
|
234
256
|
this.#notSupportWCRequestHandler.resetWallet();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RuneMetadata, RunesCollectionInfoResponse, RunesInfoByAddressFetchedData, RuneTxsResponse, RuneUtxoResponse } from '@subwallet/extension-base/services/chain-service/handler/bitcoin/strategy/types';
|
|
2
|
+
import { BaseApiRequestStrategy } from '@subwallet/extension-base/strategy/api-request-strategy';
|
|
3
|
+
export declare class RunesService extends BaseApiRequestStrategy {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
private constructor();
|
|
6
|
+
private headers;
|
|
7
|
+
isRateLimited(): boolean;
|
|
8
|
+
getUrl(path: string): string;
|
|
9
|
+
getAddressRunesInfo(address: string, params: Record<string, string>): Promise<RunesInfoByAddressFetchedData>;
|
|
10
|
+
getRuneCollectionsByBatch(params: Record<string, string>): Promise<RunesCollectionInfoResponse>;
|
|
11
|
+
getAddressRuneTxs(address: string, params: Record<string, string>): Promise<RuneTxsResponse>;
|
|
12
|
+
getRuneMetadata(runeid: string): Promise<RuneMetadata>;
|
|
13
|
+
getAddressRuneUtxos(address: string): Promise<RuneUtxoResponse>;
|
|
14
|
+
private static mainnet;
|
|
15
|
+
private static testnet;
|
|
16
|
+
static getInstance(isTestnet?: boolean): RunesService;
|
|
17
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
|
|
4
|
+
import { SWError } from '@subwallet/extension-base/background/errors/SWError';
|
|
5
|
+
import { _BTC_SERVICE_TOKEN } from '@subwallet/extension-base/services/chain-service/constants';
|
|
6
|
+
import { BaseApiRequestStrategy } from '@subwallet/extension-base/strategy/api-request-strategy';
|
|
7
|
+
import { BaseApiRequestContext } from '@subwallet/extension-base/strategy/api-request-strategy/context/base';
|
|
8
|
+
import { getRequest } from '@subwallet/extension-base/strategy/api-request-strategy/utils';
|
|
9
|
+
const BITCOIN_API_URL = 'https://btc-api.koni.studio';
|
|
10
|
+
const BITCOIN_API_URL_TEST = 'https://api-testnet.openbit.app';
|
|
11
|
+
export class RunesService extends BaseApiRequestStrategy {
|
|
12
|
+
constructor(url) {
|
|
13
|
+
const context = new BaseApiRequestContext();
|
|
14
|
+
super(context);
|
|
15
|
+
this.baseUrl = url;
|
|
16
|
+
}
|
|
17
|
+
headers = {
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
Authorization: `Bearer ${_BTC_SERVICE_TOKEN}`
|
|
20
|
+
};
|
|
21
|
+
isRateLimited() {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
getUrl(path) {
|
|
25
|
+
return `${this.baseUrl}/${path}`;
|
|
26
|
+
}
|
|
27
|
+
getAddressRunesInfo(address, params) {
|
|
28
|
+
return this.addRequest(async () => {
|
|
29
|
+
const _rs = await getRequest(this.getUrl(`rune/address/${address}`), params, this.headers);
|
|
30
|
+
const rs = await _rs.json();
|
|
31
|
+
if (rs.status_code !== 200) {
|
|
32
|
+
throw new SWError('RuneScanService.getAddressRunesInfo', rs.message);
|
|
33
|
+
}
|
|
34
|
+
return rs.result;
|
|
35
|
+
}, 1);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// * Deprecated
|
|
39
|
+
getRuneCollectionsByBatch(params) {
|
|
40
|
+
return this.addRequest(async () => {
|
|
41
|
+
const url = this.getUrl('rune');
|
|
42
|
+
const rs = await getRequest(url, params);
|
|
43
|
+
if (rs.status !== 200) {
|
|
44
|
+
throw new SWError('RuneScanService.getRuneCollectionsByBatch', await rs.text());
|
|
45
|
+
}
|
|
46
|
+
return await rs.json();
|
|
47
|
+
}, 1);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// * Deprecated
|
|
51
|
+
getAddressRuneTxs(address, params) {
|
|
52
|
+
return this.addRequest(async () => {
|
|
53
|
+
const url = this.getUrl(`address/${address}/txs`);
|
|
54
|
+
const rs = await getRequest(url, params);
|
|
55
|
+
if (rs.status !== 200) {
|
|
56
|
+
throw new SWError('RuneScanService.getAddressRuneTxs', await rs.text());
|
|
57
|
+
}
|
|
58
|
+
return await rs.json();
|
|
59
|
+
}, 0);
|
|
60
|
+
}
|
|
61
|
+
getRuneMetadata(runeid) {
|
|
62
|
+
return this.addRequest(async () => {
|
|
63
|
+
const _rs = await getRequest(this.getUrl(`rune/metadata/${runeid}`), undefined, this.headers);
|
|
64
|
+
const rs = await _rs.json();
|
|
65
|
+
if (rs.status_code !== 200) {
|
|
66
|
+
throw new SWError('RuneScanService.getRuneMetadata', rs.message);
|
|
67
|
+
}
|
|
68
|
+
return rs.result;
|
|
69
|
+
}, 0);
|
|
70
|
+
}
|
|
71
|
+
getAddressRuneUtxos(address) {
|
|
72
|
+
return this.addRequest(async () => {
|
|
73
|
+
const _rs = await getRequest(this.getUrl(`rune/address/${address}/rune/utxo`), undefined, this.headers);
|
|
74
|
+
const rs = await _rs.json();
|
|
75
|
+
if (rs.status_code !== 200) {
|
|
76
|
+
throw new SWError('RuneScanService.getAddressRuneUtxos', rs.message);
|
|
77
|
+
}
|
|
78
|
+
return rs.result;
|
|
79
|
+
}, 0);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Singleton
|
|
83
|
+
|
|
84
|
+
static getInstance(isTestnet = false) {
|
|
85
|
+
if (isTestnet) {
|
|
86
|
+
if (!RunesService.testnet) {
|
|
87
|
+
RunesService.testnet = new RunesService(BITCOIN_API_URL_TEST);
|
|
88
|
+
}
|
|
89
|
+
return RunesService.testnet;
|
|
90
|
+
} else {
|
|
91
|
+
if (!RunesService.mainnet) {
|
|
92
|
+
RunesService.mainnet = new RunesService(BITCOIN_API_URL);
|
|
93
|
+
}
|
|
94
|
+
return RunesService.mainnet;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { _ChainInfo } from '@subwallet/chain-list/types';
|
|
2
2
|
import { CardanoTransactionConfig } from '@subwallet/extension-base/services/balance-service/transfer/cardano-transfer';
|
|
3
3
|
import { TonTransactionConfig } from '@subwallet/extension-base/services/balance-service/transfer/ton-transfer';
|
|
4
|
-
import { SWTransactionBase } from '@subwallet/extension-base/services/transaction-service/types';
|
|
4
|
+
import { SWTransaction, SWTransactionBase } from '@subwallet/extension-base/services/transaction-service/types';
|
|
5
|
+
import { Psbt } from 'bitcoinjs-lib';
|
|
5
6
|
import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
|
|
6
7
|
export declare const getTransactionId: (chainType: string, chain: string, isInternal: boolean, isWalletConnect?: boolean) => string;
|
|
7
8
|
export declare const getValidationId: (chainType: string, chain: string) => string;
|
|
8
9
|
export declare const isSubstrateTransaction: (tx: SWTransactionBase['transaction']) => tx is SubmittableExtrinsic;
|
|
9
10
|
export declare const isTonTransaction: (tx: SWTransactionBase['transaction']) => tx is TonTransactionConfig;
|
|
10
11
|
export declare const isCardanoTransaction: (tx: SWTransactionBase['transaction']) => tx is CardanoTransactionConfig;
|
|
12
|
+
export declare const isBitcoinTransaction: (tx: SWTransaction['transaction']) => tx is Psbt;
|
|
11
13
|
export declare const getBaseTransactionInfo: (transaction: SWTransactionBase, chainInfoMap: Record<string, _ChainInfo>) => string;
|