@subwallet/extension-base 1.3.40-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/environment.js +4 -2
- 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 +96 -41
- 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/evm.js +6 -1
- 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/balance-service/transfer/xcm/index.js +15 -9
- package/cjs/services/balance-service/transfer/xcm/utils.js +12 -14
- package/cjs/services/base/types.js +2 -0
- package/cjs/services/chain-service/constants.js +18 -6
- package/cjs/services/chain-service/handler/CardanoApi.js +25 -35
- 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/earning-service/handlers/native-staking/tao.js +4 -38
- 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/swap-service/handler/chainflip-handler.js +29 -18
- package/cjs/services/swap-service/handler/kyber-handler.js +5 -9
- package/cjs/services/swap-service/handler/simpleswap-handler.js +4 -7
- package/cjs/services/swap-service/handler/uniswap-handler.js +5 -12
- package/cjs/services/swap-service/utils.js +46 -37
- 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/environment.js +19 -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/environment.js +30 -2
- 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/environment.d.ts +1 -0
- package/constants/environment.js +2 -1
- 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 +95 -42
- package/koni/background/handlers/State.d.ts +7 -3
- package/koni/background/handlers/State.js +52 -12
- package/package.json +149 -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/evm.js +6 -1
- 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/balance-service/transfer/xcm/index.js +15 -9
- package/services/balance-service/transfer/xcm/utils.d.ts +2 -0
- package/services/balance-service/transfer/xcm/utils.js +12 -14
- package/services/base/types.d.ts +2 -0
- package/services/base/types.js +2 -0
- package/services/chain-service/constants.d.ts +7 -0
- package/services/chain-service/constants.js +12 -5
- package/services/chain-service/handler/CardanoApi.d.ts +1 -5
- package/services/chain-service/handler/CardanoApi.js +26 -34
- 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/earning-service/handlers/native-staking/tao.d.ts +0 -11
- package/services/earning-service/handlers/native-staking/tao.js +4 -24
- 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/swap-service/handler/chainflip-handler.d.ts +0 -2
- package/services/swap-service/handler/chainflip-handler.js +25 -13
- package/services/swap-service/handler/kyber-handler.d.ts +0 -1
- package/services/swap-service/handler/kyber-handler.js +5 -8
- package/services/swap-service/handler/simpleswap-handler.d.ts +0 -1
- package/services/swap-service/handler/simpleswap-handler.js +4 -6
- package/services/swap-service/handler/uniswap-handler.js +6 -13
- package/services/swap-service/utils.d.ts +0 -13
- package/services/swap-service/utils.js +46 -34
- 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/environment.d.ts +9 -0
- package/types/environment.js +13 -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/environment.d.ts +2 -0
- package/utils/environment.js +27 -1
- 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,78 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.BitcoinChainHandler = void 0;
|
|
7
|
+
var _AbstractChainHandler = require("../AbstractChainHandler");
|
|
8
|
+
var _BitcoinApi = require("./BitcoinApi");
|
|
9
|
+
// Copyright 2019-2022 @subwallet/extension-base authors & contributors
|
|
10
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
11
|
+
|
|
12
|
+
class BitcoinChainHandler extends _AbstractChainHandler.AbstractChainHandler {
|
|
13
|
+
apiMap = {};
|
|
14
|
+
|
|
15
|
+
// eslint-disable-next-line no-useless-constructor
|
|
16
|
+
constructor(parent) {
|
|
17
|
+
super(parent);
|
|
18
|
+
}
|
|
19
|
+
getApiMap() {
|
|
20
|
+
return this.apiMap;
|
|
21
|
+
}
|
|
22
|
+
getApiByChain(chain) {
|
|
23
|
+
return this.apiMap[chain];
|
|
24
|
+
}
|
|
25
|
+
setApi(chainSlug, api) {
|
|
26
|
+
this.apiMap[chainSlug] = api;
|
|
27
|
+
}
|
|
28
|
+
async initApi(chainSlug, apiUrl) {
|
|
29
|
+
let {
|
|
30
|
+
onUpdateStatus,
|
|
31
|
+
providerName
|
|
32
|
+
} = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
|
33
|
+
const existed = this.getApiByChain(chainSlug);
|
|
34
|
+
if (existed) {
|
|
35
|
+
existed.connect();
|
|
36
|
+
if (apiUrl !== existed.apiUrl) {
|
|
37
|
+
existed.updateApiUrl(apiUrl).catch(console.error);
|
|
38
|
+
}
|
|
39
|
+
return existed;
|
|
40
|
+
}
|
|
41
|
+
const apiObject = new _BitcoinApi.BitcoinApi(chainSlug, apiUrl, {
|
|
42
|
+
providerName
|
|
43
|
+
});
|
|
44
|
+
apiObject.connectionStatusSubject.subscribe(this.handleConnection.bind(this, chainSlug));
|
|
45
|
+
apiObject.connectionStatusSubject.subscribe(onUpdateStatus);
|
|
46
|
+
return Promise.resolve(apiObject);
|
|
47
|
+
}
|
|
48
|
+
async recoverApi(chainSlug) {
|
|
49
|
+
const existed = this.getApiByChain(chainSlug);
|
|
50
|
+
if (existed && !existed.isApiReadyOnce) {
|
|
51
|
+
console.log(`Reconnect ${existed.providerName || existed.chainSlug} at ${existed.apiUrl}`);
|
|
52
|
+
return existed.recoverConnect();
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
destroyApi(chain) {
|
|
56
|
+
const api = this.getApiByChain(chain);
|
|
57
|
+
api === null || api === void 0 ? void 0 : api.destroy().catch(console.error);
|
|
58
|
+
}
|
|
59
|
+
async sleep() {
|
|
60
|
+
this.isSleeping = true;
|
|
61
|
+
this.cancelAllRecover();
|
|
62
|
+
await Promise.all(Object.values(this.getApiMap()).map(evmApi => {
|
|
63
|
+
return evmApi.disconnect().catch(console.error);
|
|
64
|
+
}));
|
|
65
|
+
return Promise.resolve();
|
|
66
|
+
}
|
|
67
|
+
wakeUp() {
|
|
68
|
+
var _this$parent;
|
|
69
|
+
this.isSleeping = false;
|
|
70
|
+
const activeChains = ((_this$parent = this.parent) === null || _this$parent === void 0 ? void 0 : _this$parent.getActiveChains()) || [];
|
|
71
|
+
for (const chain of activeChains) {
|
|
72
|
+
const api = this.getApiByChain(chain);
|
|
73
|
+
api === null || api === void 0 ? void 0 : api.connect();
|
|
74
|
+
}
|
|
75
|
+
return Promise.resolve();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
exports.BitcoinChainHandler = BitcoinChainHandler;
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
4
|
+
Object.defineProperty(exports, "__esModule", {
|
|
5
|
+
value: true
|
|
6
|
+
});
|
|
7
|
+
exports.BlockStreamTestnetRequestStrategy = void 0;
|
|
8
|
+
var _SWError = require("@subwallet/extension-base/background/errors/SWError");
|
|
9
|
+
var _hiroService = require("@subwallet/extension-base/services/hiro-service");
|
|
10
|
+
var _runeService = require("@subwallet/extension-base/services/rune-service");
|
|
11
|
+
var _apiRequestStrategy = require("@subwallet/extension-base/strategy/api-request-strategy");
|
|
12
|
+
var _base = require("@subwallet/extension-base/strategy/api-request-strategy/context/base");
|
|
13
|
+
var _utils = require("@subwallet/extension-base/strategy/api-request-strategy/utils");
|
|
14
|
+
var _bignumber = _interopRequireDefault(require("bignumber.js"));
|
|
15
|
+
var _eventemitter = _interopRequireDefault(require("eventemitter3"));
|
|
16
|
+
// Copyright 2019-2022 @subwallet/extension-base
|
|
17
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
18
|
+
|
|
19
|
+
class BlockStreamTestnetRequestStrategy extends _apiRequestStrategy.BaseApiRequestStrategy {
|
|
20
|
+
timePerBlock = 0; // in milliseconds
|
|
21
|
+
|
|
22
|
+
constructor(url) {
|
|
23
|
+
const context = new _base.BaseApiRequestContext();
|
|
24
|
+
super(context);
|
|
25
|
+
this.baseUrl = url;
|
|
26
|
+
this.isTestnet = url.includes('testnet');
|
|
27
|
+
}
|
|
28
|
+
headers = {
|
|
29
|
+
'Content-Type': 'application/json'
|
|
30
|
+
};
|
|
31
|
+
isRateLimited() {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
getUrl(path) {
|
|
35
|
+
return `${this.baseUrl}/${path}`;
|
|
36
|
+
}
|
|
37
|
+
getBlockTime() {
|
|
38
|
+
return this.addRequest(async () => {
|
|
39
|
+
const response = await (0, _utils.getRequest)(this.getUrl('blocks'), undefined, this.headers);
|
|
40
|
+
const blocks = await response.json();
|
|
41
|
+
if (!response.ok) {
|
|
42
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getBlockTime', 'Failed to fetch blocks');
|
|
43
|
+
}
|
|
44
|
+
const length = blocks.length;
|
|
45
|
+
const sortedBlocks = blocks.sort((a, b) => b.timestamp - a.timestamp);
|
|
46
|
+
const time = (sortedBlocks[0].timestamp - sortedBlocks[length - 1].timestamp) * 1000;
|
|
47
|
+
return time / length;
|
|
48
|
+
}, 0);
|
|
49
|
+
}
|
|
50
|
+
async computeBlockTime() {
|
|
51
|
+
let blockTime = this.timePerBlock;
|
|
52
|
+
if (blockTime > 0) {
|
|
53
|
+
return blockTime;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
blockTime = await this.getBlockTime();
|
|
57
|
+
this.timePerBlock = blockTime;
|
|
58
|
+
} catch (e) {
|
|
59
|
+
console.error('Failed to compute block time', e);
|
|
60
|
+
blockTime = (this.isTestnet ? 5 * 60 : 10 * 60) * 1000; // Default to 10 minutes if failed
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Cache block time in 60 seconds
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
this.timePerBlock = 0;
|
|
66
|
+
}, 60000);
|
|
67
|
+
return blockTime;
|
|
68
|
+
}
|
|
69
|
+
getAddressSummaryInfo(address) {
|
|
70
|
+
return this.addRequest(async () => {
|
|
71
|
+
const response = await (0, _utils.getRequest)(this.getUrl(`address/${address}`), undefined, this.headers);
|
|
72
|
+
if (!response.ok) {
|
|
73
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getAddressSummaryInfo', 'Failed to fetch address info');
|
|
74
|
+
}
|
|
75
|
+
const rsRaw = await response.json();
|
|
76
|
+
const chainBalance = rsRaw.chain_stats.funded_txo_sum - rsRaw.chain_stats.spent_txo_sum;
|
|
77
|
+
const pendingLocked = rsRaw.mempool_stats.spent_txo_sum; // Only consider spent UTXOs in mempool
|
|
78
|
+
const mempoolReceived = rsRaw.mempool_stats.funded_txo_sum; // Funds received in mempool (e.g., change)
|
|
79
|
+
const availableBalance = Math.max(0, chainBalance - pendingLocked + mempoolReceived); // Ensure balance is non-negative
|
|
80
|
+
|
|
81
|
+
const rs = {
|
|
82
|
+
address: rsRaw.address,
|
|
83
|
+
chain_stats: {
|
|
84
|
+
funded_txo_count: rsRaw.chain_stats.funded_txo_count,
|
|
85
|
+
funded_txo_sum: rsRaw.chain_stats.funded_txo_sum,
|
|
86
|
+
spent_txo_count: rsRaw.chain_stats.spent_txo_count,
|
|
87
|
+
spent_txo_sum: rsRaw.chain_stats.spent_txo_sum,
|
|
88
|
+
tx_count: rsRaw.chain_stats.tx_count
|
|
89
|
+
},
|
|
90
|
+
mempool_stats: {
|
|
91
|
+
funded_txo_count: rsRaw.mempool_stats.funded_txo_count,
|
|
92
|
+
funded_txo_sum: rsRaw.mempool_stats.funded_txo_sum,
|
|
93
|
+
spent_txo_count: rsRaw.mempool_stats.spent_txo_count,
|
|
94
|
+
spent_txo_sum: rsRaw.mempool_stats.spent_txo_sum,
|
|
95
|
+
tx_count: rsRaw.mempool_stats.tx_count
|
|
96
|
+
},
|
|
97
|
+
balance: availableBalance,
|
|
98
|
+
total_inscription: 0,
|
|
99
|
+
balance_rune: '0',
|
|
100
|
+
balance_inscription: '0'
|
|
101
|
+
};
|
|
102
|
+
return rs;
|
|
103
|
+
}, 0);
|
|
104
|
+
}
|
|
105
|
+
getAddressTransaction(address) {
|
|
106
|
+
let limit = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 100;
|
|
107
|
+
return this.addRequest(async () => {
|
|
108
|
+
const response = await (0, _utils.getRequest)(this.getUrl(`address/${address}/txs`), {
|
|
109
|
+
limit: `${limit}`
|
|
110
|
+
}, this.headers);
|
|
111
|
+
if (!response.ok) {
|
|
112
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getAddressTransaction', 'Failed to fetch transactions');
|
|
113
|
+
}
|
|
114
|
+
return await response.json();
|
|
115
|
+
}, 1);
|
|
116
|
+
}
|
|
117
|
+
getTransactionStatus(txHash) {
|
|
118
|
+
return this.addRequest(async () => {
|
|
119
|
+
const response = await (0, _utils.getRequest)(this.getUrl(`tx/${txHash}/status`), undefined, {});
|
|
120
|
+
if (!response.ok) {
|
|
121
|
+
const errorText = await response.text();
|
|
122
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getTransactionStatus', `Failed to fetch transaction status: ${errorText}`);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Blockstream API trả về object thô
|
|
126
|
+
const data = await response.json();
|
|
127
|
+
return {
|
|
128
|
+
confirmed: data.confirmed || false,
|
|
129
|
+
block_time: data.block_time || 0,
|
|
130
|
+
block_height: data.block_height,
|
|
131
|
+
block_hash: data.block_hash
|
|
132
|
+
};
|
|
133
|
+
}, 1);
|
|
134
|
+
}
|
|
135
|
+
getTransactionDetail(txHash) {
|
|
136
|
+
return this.addRequest(async () => {
|
|
137
|
+
const response = await (0, _utils.getRequest)(this.getUrl(`tx/${txHash}`), undefined, this.headers);
|
|
138
|
+
if (!response.ok) {
|
|
139
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getTransactionDetail', 'Failed to fetch transaction detail');
|
|
140
|
+
}
|
|
141
|
+
return await response.json();
|
|
142
|
+
}, 1);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// TODO: NOTE: Currently not in use. Recheck the response if you want to use it.
|
|
146
|
+
async getFeeRate() {
|
|
147
|
+
const blockTime = await this.computeBlockTime();
|
|
148
|
+
return await this.addRequest(async () => {
|
|
149
|
+
const response = await (0, _utils.getRequest)(this.getUrl('fee-estimates'), undefined, this.headers);
|
|
150
|
+
const estimates = await response.json();
|
|
151
|
+
if (!response.ok) {
|
|
152
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getFeeRate', 'Failed to fetch fee estimates');
|
|
153
|
+
}
|
|
154
|
+
const low = 6;
|
|
155
|
+
const average = 3;
|
|
156
|
+
const fast = 1;
|
|
157
|
+
const convertFee = fee => parseFloat(new _bignumber.default(fee).toFixed(2));
|
|
158
|
+
return {
|
|
159
|
+
type: 'bitcoin',
|
|
160
|
+
busyNetwork: false,
|
|
161
|
+
options: {
|
|
162
|
+
slow: {
|
|
163
|
+
feeRate: convertFee(estimates[low] || 10),
|
|
164
|
+
time: blockTime * low
|
|
165
|
+
},
|
|
166
|
+
average: {
|
|
167
|
+
feeRate: convertFee(estimates[average || 12]),
|
|
168
|
+
time: blockTime * average
|
|
169
|
+
},
|
|
170
|
+
fast: {
|
|
171
|
+
feeRate: convertFee(estimates[fast] || 15),
|
|
172
|
+
time: blockTime * fast
|
|
173
|
+
},
|
|
174
|
+
default: 'slow'
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
}, 0);
|
|
178
|
+
}
|
|
179
|
+
getRecommendedFeeRate() {
|
|
180
|
+
return this.addRequest(async () => {
|
|
181
|
+
const convertTimeMilisec = {
|
|
182
|
+
fastestFee: 10 * 60000,
|
|
183
|
+
halfHourFee: 30 * 60000,
|
|
184
|
+
hourFee: 60 * 60000
|
|
185
|
+
};
|
|
186
|
+
const defaultFeeInfo = {
|
|
187
|
+
type: 'bitcoin',
|
|
188
|
+
busyNetwork: false,
|
|
189
|
+
options: {
|
|
190
|
+
slow: {
|
|
191
|
+
feeRate: 1.5,
|
|
192
|
+
time: convertTimeMilisec.hourFee
|
|
193
|
+
},
|
|
194
|
+
average: {
|
|
195
|
+
feeRate: 1.5,
|
|
196
|
+
time: convertTimeMilisec.halfHourFee
|
|
197
|
+
},
|
|
198
|
+
fast: {
|
|
199
|
+
feeRate: 1.5,
|
|
200
|
+
time: convertTimeMilisec.fastestFee
|
|
201
|
+
},
|
|
202
|
+
default: 'slow'
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
try {
|
|
206
|
+
const response = await (0, _utils.getRequest)(this.getUrl('/fee-estimates'), undefined, this.headers);
|
|
207
|
+
if (!response.ok) {
|
|
208
|
+
console.warn(`Failed to fetch fee estimates: ${response.statusText}`);
|
|
209
|
+
return defaultFeeInfo;
|
|
210
|
+
}
|
|
211
|
+
const estimates = await response.json();
|
|
212
|
+
const convertFee = fee => {
|
|
213
|
+
const adjustedFee = parseInt(new _bignumber.default(fee).toFixed(), 10);
|
|
214
|
+
return Math.max(adjustedFee, 1.5);
|
|
215
|
+
};
|
|
216
|
+
return {
|
|
217
|
+
type: 'bitcoin',
|
|
218
|
+
busyNetwork: false,
|
|
219
|
+
options: {
|
|
220
|
+
slow: {
|
|
221
|
+
feeRate: convertFee(estimates['6'] || 1),
|
|
222
|
+
time: this.timePerBlock * 6
|
|
223
|
+
},
|
|
224
|
+
// 6 block
|
|
225
|
+
average: {
|
|
226
|
+
feeRate: convertFee(estimates['3'] || 1),
|
|
227
|
+
time: this.timePerBlock * 3
|
|
228
|
+
},
|
|
229
|
+
// 3 block
|
|
230
|
+
fast: {
|
|
231
|
+
feeRate: convertFee(estimates['1'] || 1),
|
|
232
|
+
time: this.timePerBlock
|
|
233
|
+
},
|
|
234
|
+
// 1 block
|
|
235
|
+
default: 'slow'
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
} catch {
|
|
239
|
+
return defaultFeeInfo;
|
|
240
|
+
}
|
|
241
|
+
}, 0);
|
|
242
|
+
}
|
|
243
|
+
getUtxos(address) {
|
|
244
|
+
return this.addRequest(async () => {
|
|
245
|
+
const response = await (0, _utils.getRequest)(this.getUrl(`address/${address}/utxo`), undefined, {});
|
|
246
|
+
const rs = await response.json();
|
|
247
|
+
if (!response.ok) {
|
|
248
|
+
const errorText = await response.text();
|
|
249
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getUtxos', `Failed to fetch UTXOs: ${errorText}`);
|
|
250
|
+
}
|
|
251
|
+
return rs.map(item => ({
|
|
252
|
+
txid: item.txid,
|
|
253
|
+
vout: item.vout,
|
|
254
|
+
value: item.value,
|
|
255
|
+
status: item.status
|
|
256
|
+
}));
|
|
257
|
+
}, 0);
|
|
258
|
+
}
|
|
259
|
+
sendRawTransaction(rawTransaction) {
|
|
260
|
+
const eventEmitter = new _eventemitter.default();
|
|
261
|
+
this.addRequest(async () => {
|
|
262
|
+
const response = await (0, _utils.postRequest)(this.getUrl('tx'), rawTransaction, {
|
|
263
|
+
'Content-Type': 'text/plain'
|
|
264
|
+
}, false);
|
|
265
|
+
if (!response.ok) {
|
|
266
|
+
const errorText = await response.text();
|
|
267
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.sendRawTransaction', `Failed to broadcast transaction: ${errorText}`);
|
|
268
|
+
}
|
|
269
|
+
return await response.text();
|
|
270
|
+
}, 0).then(extrinsicHash => {
|
|
271
|
+
eventEmitter.emit('extrinsicHash', extrinsicHash);
|
|
272
|
+
|
|
273
|
+
// Check transaction status
|
|
274
|
+
const interval = setInterval(() => {
|
|
275
|
+
this.getTransactionStatus(extrinsicHash).then(transactionStatus => {
|
|
276
|
+
if (transactionStatus.confirmed && transactionStatus.block_time > 0) {
|
|
277
|
+
clearInterval(interval);
|
|
278
|
+
eventEmitter.emit('success', transactionStatus);
|
|
279
|
+
}
|
|
280
|
+
}).catch(console.error);
|
|
281
|
+
}, 30000);
|
|
282
|
+
}).catch(error => {
|
|
283
|
+
eventEmitter.emit('error', error.message);
|
|
284
|
+
});
|
|
285
|
+
return eventEmitter;
|
|
286
|
+
}
|
|
287
|
+
simpleSendRawTransaction(rawTransaction) {
|
|
288
|
+
return this.addRequest(async () => {
|
|
289
|
+
const response = await (0, _utils.postRequest)(this.getUrl('tx'), rawTransaction, {
|
|
290
|
+
'Content-Type': 'text/plain'
|
|
291
|
+
}, false);
|
|
292
|
+
if (!response.ok) {
|
|
293
|
+
const errorText = await response.text();
|
|
294
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.simpleSendRawTransaction', `Failed to broadcast transaction: ${errorText}`);
|
|
295
|
+
}
|
|
296
|
+
return await response.text();
|
|
297
|
+
}, 0);
|
|
298
|
+
}
|
|
299
|
+
async getRunes(address) {
|
|
300
|
+
const runesFullList = [];
|
|
301
|
+
const pageSize = 60;
|
|
302
|
+
let offset = 0;
|
|
303
|
+
const runeService = _runeService.RunesService.getInstance(this.isTestnet);
|
|
304
|
+
try {
|
|
305
|
+
while (true) {
|
|
306
|
+
const response = await runeService.getAddressRunesInfo(address, {
|
|
307
|
+
limit: String(pageSize),
|
|
308
|
+
offset: String(offset)
|
|
309
|
+
});
|
|
310
|
+
const runes = response.runes;
|
|
311
|
+
if (runes.length !== 0) {
|
|
312
|
+
runesFullList.push(...runes);
|
|
313
|
+
offset += pageSize;
|
|
314
|
+
} else {
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return runesFullList;
|
|
319
|
+
} catch (error) {
|
|
320
|
+
console.error(`Failed to get ${address} balances`, error);
|
|
321
|
+
throw error;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
async getRuneUtxos(address) {
|
|
325
|
+
const runeService = _runeService.RunesService.getInstance(this.isTestnet);
|
|
326
|
+
try {
|
|
327
|
+
const responseRuneUtxos = await runeService.getAddressRuneUtxos(address);
|
|
328
|
+
return responseRuneUtxos.results;
|
|
329
|
+
} catch (error) {
|
|
330
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
331
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getRuneUtxos', `Failed to get ${address} rune utxos: ${errorMessage}`);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
async getAddressInscriptions(address) {
|
|
335
|
+
const inscriptionsFullList = [];
|
|
336
|
+
const pageSize = 60;
|
|
337
|
+
let offset = 0;
|
|
338
|
+
const hiroService = _hiroService.HiroService.getInstance(this.isTestnet);
|
|
339
|
+
try {
|
|
340
|
+
while (true) {
|
|
341
|
+
const response = await hiroService.getAddressInscriptionsInfo({
|
|
342
|
+
limit: String(pageSize),
|
|
343
|
+
offset: String(offset),
|
|
344
|
+
address: String(address)
|
|
345
|
+
});
|
|
346
|
+
const inscriptions = response.results;
|
|
347
|
+
if (inscriptions.length !== 0) {
|
|
348
|
+
inscriptionsFullList.push(...inscriptions);
|
|
349
|
+
offset += pageSize;
|
|
350
|
+
} else {
|
|
351
|
+
break;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
return inscriptionsFullList;
|
|
355
|
+
} catch (error) {
|
|
356
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
357
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getAddressInscriptions', `Failed to get ${address} inscriptions: ${errorMessage}`);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
getTxHex(txHash) {
|
|
361
|
+
return this.addRequest(async () => {
|
|
362
|
+
const response = await (0, _utils.getRequest)(this.getUrl(`tx/${txHash}/hex`), undefined, this.headers);
|
|
363
|
+
if (!response.ok) {
|
|
364
|
+
const errorText = await response.text();
|
|
365
|
+
throw new _SWError.SWError('BlockStreamTestnetRequestStrategy.getTxHex', `Failed to fetch transaction hex: ${errorText}`);
|
|
366
|
+
}
|
|
367
|
+
return await response.text();
|
|
368
|
+
}, 0);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
exports.BlockStreamTestnetRequestStrategy = BlockStreamTestnetRequestStrategy;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
Object.defineProperty(exports, "BlockStreamTestnetRequestStrategy", {
|
|
7
|
+
enumerable: true,
|
|
8
|
+
get: function () {
|
|
9
|
+
return _blockstreamTestnetStrategy.BlockStreamTestnetRequestStrategy;
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
Object.defineProperty(exports, "MempoolTestnetRequestStrategy", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
get: function () {
|
|
15
|
+
return _mempoolTestnetStrategy.MempoolTestnetRequestStrategy;
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
var _mempoolTestnetStrategy = require("./mempool-testnet-strategy");
|
|
19
|
+
var _blockstreamTestnetStrategy = require("./blockstream-testnet-strategy");
|