@trezor/connect 9.0.2 → 9.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/lib/api/authorizeCoinJoin.js +6 -2
- package/lib/api/bitcoin/TransactionComposer.js +2 -1
- package/lib/api/bitcoin/enhanceSignTx.js +1 -1
- package/lib/api/bitcoin/inputs.js +3 -2
- package/lib/api/bitcoin/outputs.js +2 -4
- package/lib/api/bitcoin/refTx.js +3 -3
- package/lib/api/bitcoin/signtxVerify.d.ts +3 -3
- package/lib/api/bitcoin/signtxVerify.js +16 -15
- package/lib/api/blockchainDisconnect.js +1 -1
- package/lib/api/blockchainSetCustomBackend.js +1 -1
- package/lib/api/cardano/cardanoAuxiliaryData.d.ts +1 -1
- package/lib/api/cardano/cardanoAuxiliaryData.js +38 -16
- package/lib/api/cardanoSignTransaction.d.ts +1 -0
- package/lib/api/cardanoSignTransaction.js +23 -3
- package/lib/api/getAddress.d.ts +2 -1
- package/lib/api/getAddress.js +12 -1
- package/lib/api/getOwnershipProof.d.ts +1 -5
- package/lib/api/getOwnershipProof.js +5 -3
- package/lib/api/getPublicKey.d.ts +1 -0
- package/lib/api/getPublicKey.js +22 -7
- package/lib/api/index.d.ts +2 -0
- package/lib/api/index.js +5 -1
- package/lib/api/setBusy.d.ts +7 -0
- package/lib/api/setBusy.js +27 -0
- package/lib/api/signTransaction.d.ts +2 -1
- package/lib/api/signTransaction.js +24 -5
- package/lib/api/unlockPath.d.ts +10 -0
- package/lib/api/unlockPath.js +35 -0
- package/lib/backend/BackendManager.d.ts +21 -0
- package/lib/backend/BackendManager.js +91 -0
- package/lib/backend/Blockchain.d.ts +72 -0
- package/lib/backend/Blockchain.js +204 -0
- package/lib/backend/BlockchainLink.d.ts +6 -71
- package/lib/backend/BlockchainLink.js +12 -288
- package/lib/constants/cardano.d.ts +3 -1
- package/lib/constants/cardano.js +3 -1
- package/lib/core/AbstractMethod.d.ts +1 -0
- package/lib/core/index.d.ts +1 -1
- package/lib/core/index.js +1 -1
- package/lib/core/method.d.ts +1 -1
- package/lib/data/config.js +2 -2
- package/lib/data/version.d.ts +1 -1
- package/lib/data/version.js +1 -1
- package/lib/device/Device.d.ts +1 -1
- package/lib/device/Device.js +8 -2
- package/lib/device/DeviceCommands.d.ts +8 -2
- package/lib/device/DeviceCommands.js +48 -25
- package/lib/factory.js +2 -0
- package/lib/types/api/authorizeCoinJoin.d.ts +1 -0
- package/lib/types/api/bitcoin/index.d.ts +5 -0
- package/lib/types/api/cardano/index.d.ts +13 -10
- package/lib/types/api/eos/index.d.ts +0 -4
- package/lib/types/api/eosGetPublicKey.d.ts +4 -4
- package/lib/types/api/getAddress.d.ts +1 -0
- package/lib/types/api/getPublicKey.d.ts +5 -0
- package/lib/types/api/index.d.ts +4 -0
- package/lib/types/api/setBusy.d.ts +4 -0
- package/lib/types/api/setBusy.js +3 -0
- package/lib/types/api/unlockPath.d.ts +8 -0
- package/lib/types/api/unlockPath.js +3 -0
- package/lib/utils/pathUtils.d.ts +2 -3
- package/lib/utils/pathUtils.js +42 -15
- package/package.json +19 -7
- package/lib/api/bitcoin/__fixtures__/inputs.d.ts +0 -112
- package/lib/api/bitcoin/__fixtures__/inputs.js +0 -102
- package/lib/api/bitcoin/__fixtures__/signtxVerify.d.ts +0 -147
- package/lib/api/bitcoin/__fixtures__/signtxVerify.js +0 -216
- package/lib/api/common/__fixtures__/paramsValidator.d.ts +0 -596
- package/lib/api/common/__fixtures__/paramsValidator.js +0 -355
- package/lib/api/ethereum/__fixtures__/ethereumSignTypedData.d.ts +0 -225
- package/lib/api/ethereum/__fixtures__/ethereumSignTypedData.js +0 -341
- package/lib/utils/__fixtures__/accountUtils.d.ts +0 -4
- package/lib/utils/__fixtures__/accountUtils.js +0 -32
- package/lib/utils/__fixtures__/addressUtils.d.ts +0 -10
- package/lib/utils/__fixtures__/addressUtils.js +0 -214
- package/lib/utils/__fixtures__/ethereumUtils.d.ts +0 -3
- package/lib/utils/__fixtures__/ethereumUtils.js +0 -20
- package/lib/utils/__fixtures__/formatUtils.d.ts +0 -3
- package/lib/utils/__fixtures__/formatUtils.js +0 -15
- package/lib/utils/__fixtures__/hdnodeUtils.d.ts +0 -186
- package/lib/utils/__fixtures__/hdnodeUtils.js +0 -206
- package/lib/utils/bufferUtils.d.ts +0 -3
- package/lib/utils/bufferUtils.js +0 -11
package/lib/api/index.js
CHANGED
|
@@ -4,7 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.requestLogin = exports.recoveryDevice = exports.rebootToBootloader = exports.pushTransaction = exports.nemSignTransaction = exports.nemGetAddress = exports.getSettings = exports.getPublicKey = exports.getOwnershipProof = exports.getOwnershipId = exports.getFirmwareHash = exports.getFeatures = exports.getDeviceState = exports.getCoinInfo = exports.getAddress = exports.getAccountInfo = exports.firmwareUpdate = exports.ethereumVerifyMessage = exports.ethereumSignTypedData = exports.ethereumSignTransaction = exports.ethereumSignMessage = exports.ethereumGetPublicKey = exports.ethereumGetAddress = exports.eosSignTransaction = exports.eosGetPublicKey = exports.composeTransaction = exports.cipherKeyValue = exports.changePin = exports.cardanoSignTransaction = exports.cardanoGetPublicKey = exports.cardanoGetNativeScriptHash = exports.cardanoGetAddress = exports.blockchainUnsubscribeFiatRates = exports.blockchainUnsubscribe = exports.blockchainSubscribeFiatRates = exports.blockchainSubscribe = exports.blockchainSetCustomBackend = exports.blockchainGetTransactions = exports.blockchainGetFiatRatesForTimestamps = exports.blockchainGetCurrentFiatRates = exports.blockchainGetAccountBalanceHistory = exports.blockchainEstimateFee = exports.blockchainDisconnect = exports.binanceSignTransaction = exports.binanceGetPublicKey = exports.binanceGetAddress = exports.backupDevice = exports.authorizeCoinJoin = exports.applySettings = exports.applyFlags = void 0;
|
|
7
|
-
exports.checkFirmwareAuthenticity = exports.wipeDevice = exports.verifyMessage = exports.tezosSignTransaction = exports.tezosGetPublicKey = exports.tezosGetAddress = exports.stellarSignTransaction = exports.stellarGetAddress = exports.signTransaction = exports.signMessage = exports.setProxy = exports.rippleSignTransaction = exports.rippleGetAddress = exports.resetDevice = void 0;
|
|
7
|
+
exports.checkFirmwareAuthenticity = exports.wipeDevice = exports.verifyMessage = exports.unlockPath = exports.tezosSignTransaction = exports.tezosGetPublicKey = exports.tezosGetAddress = exports.stellarSignTransaction = exports.stellarGetAddress = exports.signTransaction = exports.signMessage = exports.setProxy = exports.setBusy = exports.rippleSignTransaction = exports.rippleGetAddress = exports.resetDevice = void 0;
|
|
8
8
|
var applyFlags_1 = require("./applyFlags");
|
|
9
9
|
Object.defineProperty(exports, "applyFlags", { enumerable: true, get: function () { return __importDefault(applyFlags_1).default; } });
|
|
10
10
|
var applySettings_1 = require("./applySettings");
|
|
@@ -111,6 +111,8 @@ var rippleGetAddress_1 = require("./rippleGetAddress");
|
|
|
111
111
|
Object.defineProperty(exports, "rippleGetAddress", { enumerable: true, get: function () { return __importDefault(rippleGetAddress_1).default; } });
|
|
112
112
|
var rippleSignTransaction_1 = require("./rippleSignTransaction");
|
|
113
113
|
Object.defineProperty(exports, "rippleSignTransaction", { enumerable: true, get: function () { return __importDefault(rippleSignTransaction_1).default; } });
|
|
114
|
+
var setBusy_1 = require("./setBusy");
|
|
115
|
+
Object.defineProperty(exports, "setBusy", { enumerable: true, get: function () { return __importDefault(setBusy_1).default; } });
|
|
114
116
|
var setProxy_1 = require("./setProxy");
|
|
115
117
|
Object.defineProperty(exports, "setProxy", { enumerable: true, get: function () { return __importDefault(setProxy_1).default; } });
|
|
116
118
|
var signMessage_1 = require("./signMessage");
|
|
@@ -127,6 +129,8 @@ var tezosGetPublicKey_1 = require("./tezosGetPublicKey");
|
|
|
127
129
|
Object.defineProperty(exports, "tezosGetPublicKey", { enumerable: true, get: function () { return __importDefault(tezosGetPublicKey_1).default; } });
|
|
128
130
|
var tezosSignTransaction_1 = require("./tezosSignTransaction");
|
|
129
131
|
Object.defineProperty(exports, "tezosSignTransaction", { enumerable: true, get: function () { return __importDefault(tezosSignTransaction_1).default; } });
|
|
132
|
+
var unlockPath_1 = require("./unlockPath");
|
|
133
|
+
Object.defineProperty(exports, "unlockPath", { enumerable: true, get: function () { return __importDefault(unlockPath_1).default; } });
|
|
130
134
|
var verifyMessage_1 = require("./verifyMessage");
|
|
131
135
|
Object.defineProperty(exports, "verifyMessage", { enumerable: true, get: function () { return __importDefault(verifyMessage_1).default; } });
|
|
132
136
|
var wipeDevice_1 = require("./wipeDevice");
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { AbstractMethod } from '../core/AbstractMethod';
|
|
2
|
+
import { PROTO } from '../constants';
|
|
3
|
+
export default class SetBusy extends AbstractMethod<'setBusy', PROTO.SetBusy> {
|
|
4
|
+
init(): void;
|
|
5
|
+
run(): Promise<PROTO.Success>;
|
|
6
|
+
}
|
|
7
|
+
//# sourceMappingURL=setBusy.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const AbstractMethod_1 = require("../core/AbstractMethod");
|
|
4
|
+
const paramsValidator_1 = require("./common/paramsValidator");
|
|
5
|
+
class SetBusy extends AbstractMethod_1.AbstractMethod {
|
|
6
|
+
init() {
|
|
7
|
+
this.useDeviceState = false;
|
|
8
|
+
this.requiredPermissions = ['management'];
|
|
9
|
+
this.keepSession = true;
|
|
10
|
+
const { payload } = this;
|
|
11
|
+
(0, paramsValidator_1.validateParams)(payload, [{ name: 'expiry_ms', type: 'number' }]);
|
|
12
|
+
this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, null, {
|
|
13
|
+
1: { min: '0', max: '0' },
|
|
14
|
+
2: { min: '2.5.3', max: '0' },
|
|
15
|
+
});
|
|
16
|
+
this.params = {
|
|
17
|
+
expiry_ms: payload.expiry_ms,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
async run() {
|
|
21
|
+
const cmd = this.device.getCommands();
|
|
22
|
+
const { message } = await cmd.typedCall('SetBusy', 'Success', this.params);
|
|
23
|
+
return message;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
exports.default = SetBusy;
|
|
27
|
+
//# sourceMappingURL=setBusy.js.map
|
|
@@ -6,12 +6,13 @@ declare type Params = {
|
|
|
6
6
|
inputs: PROTO.TxInputType[];
|
|
7
7
|
outputs: PROTO.TxOutputType[];
|
|
8
8
|
paymentRequests: PROTO.TxAckPaymentRequest[];
|
|
9
|
+
coinjoinRequest?: PROTO.CoinJoinRequest;
|
|
9
10
|
refTxs?: RefTransaction[];
|
|
10
11
|
addresses?: AccountAddresses;
|
|
11
12
|
options: TransactionOptions;
|
|
12
13
|
coinInfo: BitcoinNetworkInfo;
|
|
13
14
|
push: boolean;
|
|
14
|
-
|
|
15
|
+
unlockPath?: PROTO.UnlockPath;
|
|
15
16
|
};
|
|
16
17
|
export default class SignTransaction extends AbstractMethod<'signTransaction', Params> {
|
|
17
18
|
init(): void;
|
|
@@ -19,6 +19,7 @@ class SignTransaction extends AbstractMethod_1.AbstractMethod {
|
|
|
19
19
|
{ name: 'inputs', type: 'array', required: true },
|
|
20
20
|
{ name: 'outputs', type: 'array', required: true },
|
|
21
21
|
{ name: 'paymentRequests', type: 'array', allowEmpty: true },
|
|
22
|
+
{ name: 'coinjoinRequest', type: 'object' },
|
|
22
23
|
{ name: 'refTxs', type: 'array', allowEmpty: true },
|
|
23
24
|
{ name: 'account', type: 'object' },
|
|
24
25
|
{ name: 'locktime', type: 'number' },
|
|
@@ -32,12 +33,21 @@ class SignTransaction extends AbstractMethod_1.AbstractMethod {
|
|
|
32
33
|
{ name: 'push', type: 'boolean' },
|
|
33
34
|
{ name: 'preauthorized', type: 'boolean' },
|
|
34
35
|
{ name: 'amountUnit', type: ['number', 'string'] },
|
|
36
|
+
{ name: 'unlockPath', type: 'object' },
|
|
37
|
+
{ name: 'serialize', type: 'boolean' },
|
|
35
38
|
]);
|
|
39
|
+
if (payload.unlockPath) {
|
|
40
|
+
(0, paramsValidator_1.validateParams)(payload.unlockPath, [
|
|
41
|
+
{ name: 'address_n', required: true, type: 'array' },
|
|
42
|
+
{ name: 'mac', required: true, type: 'string' },
|
|
43
|
+
]);
|
|
44
|
+
}
|
|
36
45
|
const coinInfo = (0, coinInfo_1.getBitcoinNetwork)(payload.coin);
|
|
37
46
|
if (!coinInfo) {
|
|
38
47
|
throw constants_1.ERRORS.TypedError('Method_UnknownCoin');
|
|
39
48
|
}
|
|
40
49
|
this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, coinInfo, this.firmwareRange);
|
|
50
|
+
this.preauthorized = payload.preauthorized;
|
|
41
51
|
this.info = (0, pathUtils_1.getLabel)('Sign #NETWORK transaction', coinInfo);
|
|
42
52
|
const inputs = (0, bitcoin_1.validateTrezorInputs)(payload.inputs, coinInfo);
|
|
43
53
|
const outputs = (0, bitcoin_1.validateTrezorOutputs)(payload.outputs, coinInfo);
|
|
@@ -66,10 +76,12 @@ class SignTransaction extends AbstractMethod_1.AbstractMethod {
|
|
|
66
76
|
branch_id: payload.branchId,
|
|
67
77
|
decred_staking_ticket: payload.decredStakingTicket,
|
|
68
78
|
amount_unit: payload.amountUnit,
|
|
79
|
+
serialize: payload.serialize,
|
|
80
|
+
coinjoin_request: payload.coinjoinRequest,
|
|
69
81
|
},
|
|
70
82
|
coinInfo,
|
|
71
83
|
push: typeof payload.push === 'boolean' ? payload.push : false,
|
|
72
|
-
|
|
84
|
+
unlockPath: payload.unlockPath,
|
|
73
85
|
};
|
|
74
86
|
this.params.options = (0, bitcoin_1.enhanceSignTx)(this.params.options, coinInfo);
|
|
75
87
|
}
|
|
@@ -95,9 +107,10 @@ class SignTransaction extends AbstractMethod_1.AbstractMethod {
|
|
|
95
107
|
if (!accountPath || !accountPath.address_n) {
|
|
96
108
|
throw constants_1.ERRORS.TypedError('Runtime', 'Account not found');
|
|
97
109
|
}
|
|
110
|
+
const address_n = accountPath.address_n.slice(0, 3);
|
|
98
111
|
const node = await device
|
|
99
112
|
.getCommands()
|
|
100
|
-
.getHDNode(
|
|
113
|
+
.getHDNode({ address_n }, { coinInfo: params.coinInfo });
|
|
101
114
|
const account = await blockchain.getAccountInfo({
|
|
102
115
|
descriptor: node.xpubSegwit || node.xpub,
|
|
103
116
|
details: 'tokens',
|
|
@@ -112,8 +125,11 @@ class SignTransaction extends AbstractMethod_1.AbstractMethod {
|
|
|
112
125
|
else {
|
|
113
126
|
refTxs = params.refTxs;
|
|
114
127
|
}
|
|
115
|
-
if (
|
|
116
|
-
await device.getCommands().
|
|
128
|
+
if (this.preauthorized) {
|
|
129
|
+
await device.getCommands().preauthorize(true);
|
|
130
|
+
}
|
|
131
|
+
else if (params.unlockPath) {
|
|
132
|
+
await device.getCommands().unlockPath(params.unlockPath);
|
|
117
133
|
}
|
|
118
134
|
const signTxMethod = !useLegacySignProcess ? bitcoin_1.signTx : bitcoin_1.signTxLegacy;
|
|
119
135
|
const response = await signTxMethod({
|
|
@@ -121,11 +137,14 @@ class SignTransaction extends AbstractMethod_1.AbstractMethod {
|
|
|
121
137
|
refTxs,
|
|
122
138
|
typedCall: device.getCommands().typedCall.bind(device.getCommands()),
|
|
123
139
|
});
|
|
140
|
+
if (!response.serializedTx) {
|
|
141
|
+
return response;
|
|
142
|
+
}
|
|
124
143
|
if (params.options.decred_staking_ticket) {
|
|
125
144
|
await (0, bitcoin_1.verifyTicketTx)(device.getCommands().getHDNode.bind(device.getCommands()), params.inputs, params.outputs, response.serializedTx, params.coinInfo);
|
|
126
145
|
}
|
|
127
146
|
else {
|
|
128
|
-
const bitcoinTx = await (0, bitcoin_1.verifyTx)(device.getCommands().getHDNode.bind(device.getCommands()), params.inputs, params.outputs, response.serializedTx, params.coinInfo);
|
|
147
|
+
const bitcoinTx = await (0, bitcoin_1.verifyTx)(device.getCommands().getHDNode.bind(device.getCommands()), params.inputs, params.outputs, response.serializedTx, params.coinInfo, params.unlockPath);
|
|
129
148
|
if (bitcoinTx.hasWitnesses()) {
|
|
130
149
|
response.witnesses = bitcoinTx.ins.map((_, i) => { var _a; return (_a = bitcoinTx.getWitness(i)) === null || _a === void 0 ? void 0 : _a.toString('hex'); });
|
|
131
150
|
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { AbstractMethod } from '../core/AbstractMethod';
|
|
2
|
+
import { PROTO } from '../constants';
|
|
3
|
+
export default class UnlockPath extends AbstractMethod<'unlockPath', PROTO.UnlockPath> {
|
|
4
|
+
init(): void;
|
|
5
|
+
run(): Promise<{
|
|
6
|
+
address_n: number[];
|
|
7
|
+
mac: string | undefined;
|
|
8
|
+
}>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=unlockPath.d.ts.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const AbstractMethod_1 = require("../core/AbstractMethod");
|
|
4
|
+
const pathUtils_1 = require("../utils/pathUtils");
|
|
5
|
+
const paramsValidator_1 = require("./common/paramsValidator");
|
|
6
|
+
class UnlockPath extends AbstractMethod_1.AbstractMethod {
|
|
7
|
+
init() {
|
|
8
|
+
this.requiredPermissions = ['read'];
|
|
9
|
+
this.skipFinalReload = true;
|
|
10
|
+
this.firmwareRange = (0, paramsValidator_1.getFirmwareRange)(this.name, null, {
|
|
11
|
+
1: { min: '0', max: '0' },
|
|
12
|
+
2: { min: '2.5.3', max: '0' },
|
|
13
|
+
});
|
|
14
|
+
const { payload } = this;
|
|
15
|
+
(0, paramsValidator_1.validateParams)(payload, [
|
|
16
|
+
{ name: 'path', required: true },
|
|
17
|
+
{ name: 'mac', type: 'string' },
|
|
18
|
+
]);
|
|
19
|
+
const path = (0, pathUtils_1.validatePath)(payload.path, 1);
|
|
20
|
+
this.params = {
|
|
21
|
+
address_n: path,
|
|
22
|
+
mac: payload.mac,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
async run() {
|
|
26
|
+
const cmd = this.device.getCommands();
|
|
27
|
+
const { message } = await cmd.unlockPath(this.params);
|
|
28
|
+
return {
|
|
29
|
+
address_n: this.params.address_n,
|
|
30
|
+
mac: message.mac,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.default = UnlockPath;
|
|
35
|
+
//# sourceMappingURL=unlockPath.js.map
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Blockchain, BlockchainOptions } from './Blockchain';
|
|
2
|
+
import type { CoinInfo, BlockchainLink } from '../types';
|
|
3
|
+
declare type CoinShortcut = CoinInfo['shortcut'];
|
|
4
|
+
export declare class BackendManager {
|
|
5
|
+
private readonly instances;
|
|
6
|
+
private readonly custom;
|
|
7
|
+
private readonly preferred;
|
|
8
|
+
get(shortcut: CoinShortcut): Blockchain | null;
|
|
9
|
+
remove(shortcut: CoinShortcut): void;
|
|
10
|
+
getOrConnect(coinInfo: CoinInfo, postMessage: BlockchainOptions['postMessage']): Promise<Blockchain>;
|
|
11
|
+
dispose(): void;
|
|
12
|
+
reconnectAll(): Promise<Blockchain[]>;
|
|
13
|
+
isSupported(coinInfo: CoinInfo): void;
|
|
14
|
+
setCustom(shortcut: CoinShortcut, blockchainLink: BlockchainLink): void;
|
|
15
|
+
removeCustom(shortcut: CoinShortcut): void;
|
|
16
|
+
private setPreferred;
|
|
17
|
+
private removePreferred;
|
|
18
|
+
private patchCoinInfo;
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=BackendManager.d.ts.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BackendManager = void 0;
|
|
4
|
+
const config_1 = require("../data/config");
|
|
5
|
+
const DataManager_1 = require("../data/DataManager");
|
|
6
|
+
const constants_1 = require("../constants");
|
|
7
|
+
const Blockchain_1 = require("./Blockchain");
|
|
8
|
+
class BackendManager {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.instances = {};
|
|
11
|
+
this.custom = {};
|
|
12
|
+
this.preferred = {};
|
|
13
|
+
}
|
|
14
|
+
get(shortcut) {
|
|
15
|
+
var _a;
|
|
16
|
+
return (_a = this.instances[shortcut]) !== null && _a !== void 0 ? _a : null;
|
|
17
|
+
}
|
|
18
|
+
remove(shortcut) {
|
|
19
|
+
delete this.instances[shortcut];
|
|
20
|
+
}
|
|
21
|
+
async getOrConnect(coinInfo, postMessage) {
|
|
22
|
+
let backend = this.get(coinInfo.shortcut);
|
|
23
|
+
if (!backend) {
|
|
24
|
+
backend = new Blockchain_1.Blockchain({
|
|
25
|
+
coinInfo: this.patchCoinInfo(coinInfo),
|
|
26
|
+
postMessage,
|
|
27
|
+
debug: DataManager_1.DataManager.getSettings('debug'),
|
|
28
|
+
proxy: DataManager_1.DataManager.getSettings('proxy'),
|
|
29
|
+
onionDomains: DataManager_1.DataManager.getSettings('useOnionLinks') && !this.custom[coinInfo.shortcut]
|
|
30
|
+
? config_1.config.onionDomains
|
|
31
|
+
: undefined,
|
|
32
|
+
onConnected: url => this.setPreferred(coinInfo.shortcut, url),
|
|
33
|
+
onDisconnected: () => this.remove(coinInfo.shortcut),
|
|
34
|
+
});
|
|
35
|
+
this.instances[coinInfo.shortcut] = backend;
|
|
36
|
+
try {
|
|
37
|
+
await backend.init();
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
this.remove(coinInfo.shortcut);
|
|
41
|
+
this.removePreferred(coinInfo.shortcut);
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return backend;
|
|
46
|
+
}
|
|
47
|
+
dispose() {
|
|
48
|
+
Object.values(this.instances).forEach(i => i.disconnect());
|
|
49
|
+
}
|
|
50
|
+
reconnectAll() {
|
|
51
|
+
const params = Object.values(this.instances).map(i => [i.coinInfo, i.postMessage]);
|
|
52
|
+
Object.values(this.instances).forEach(i => i.disconnect());
|
|
53
|
+
return Promise.all(params.map(p => this.getOrConnect(...p)));
|
|
54
|
+
}
|
|
55
|
+
isSupported(coinInfo) {
|
|
56
|
+
const info = this.custom[coinInfo.shortcut] || coinInfo.blockchainLink;
|
|
57
|
+
if (!info) {
|
|
58
|
+
throw constants_1.ERRORS.TypedError('Backend_NotSupported');
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
setCustom(shortcut, blockchainLink) {
|
|
62
|
+
this.removePreferred(shortcut);
|
|
63
|
+
this.custom[shortcut] = blockchainLink;
|
|
64
|
+
}
|
|
65
|
+
removeCustom(shortcut) {
|
|
66
|
+
this.removePreferred(shortcut);
|
|
67
|
+
delete this.custom[shortcut];
|
|
68
|
+
}
|
|
69
|
+
setPreferred(shortcut, url) {
|
|
70
|
+
this.preferred[shortcut] = url;
|
|
71
|
+
}
|
|
72
|
+
removePreferred(shortcut) {
|
|
73
|
+
delete this.preferred[shortcut];
|
|
74
|
+
}
|
|
75
|
+
patchCoinInfo(coinInfo) {
|
|
76
|
+
var _a, _b;
|
|
77
|
+
const custom = this.custom[coinInfo.shortcut];
|
|
78
|
+
const preferred = this.preferred[coinInfo.shortcut];
|
|
79
|
+
const url = preferred ? [preferred] : (_a = custom === null || custom === void 0 ? void 0 : custom.url) !== null && _a !== void 0 ? _a : (_b = coinInfo.blockchainLink) === null || _b === void 0 ? void 0 : _b.url;
|
|
80
|
+
return {
|
|
81
|
+
...coinInfo,
|
|
82
|
+
blockchainLink: {
|
|
83
|
+
...coinInfo.blockchainLink,
|
|
84
|
+
...custom,
|
|
85
|
+
url,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
exports.BackendManager = BackendManager;
|
|
91
|
+
//# sourceMappingURL=BackendManager.js.map
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import BlockchainLink, { ServerInfo, SubscriptionAccountInfo, BlockchainLinkParams, BlockchainLinkResponse } from '@trezor/blockchain-link';
|
|
2
|
+
import { ERRORS } from '../constants';
|
|
3
|
+
import type { CoinInfo, Proxy } from '../types';
|
|
4
|
+
import type { CoreMessage } from '../events';
|
|
5
|
+
export declare type BlockchainOptions = {
|
|
6
|
+
coinInfo: CoinInfo;
|
|
7
|
+
postMessage: (message: CoreMessage) => void;
|
|
8
|
+
proxy?: Proxy;
|
|
9
|
+
onionDomains?: {
|
|
10
|
+
[domain: string]: string;
|
|
11
|
+
};
|
|
12
|
+
debug?: boolean;
|
|
13
|
+
onConnected?: (url: string) => void;
|
|
14
|
+
onDisconnected?: () => void;
|
|
15
|
+
};
|
|
16
|
+
export declare class Blockchain {
|
|
17
|
+
link: BlockchainLink;
|
|
18
|
+
serverInfo?: ServerInfo;
|
|
19
|
+
coinInfo: BlockchainOptions['coinInfo'];
|
|
20
|
+
onionDomains: {
|
|
21
|
+
[onion: string]: string;
|
|
22
|
+
};
|
|
23
|
+
postMessage: BlockchainOptions['postMessage'];
|
|
24
|
+
feeForBlock: BlockchainLinkResponse<'estimateFee'>;
|
|
25
|
+
feeTimestamp: number;
|
|
26
|
+
private onConnected;
|
|
27
|
+
private onDisconnected;
|
|
28
|
+
constructor(options: BlockchainOptions);
|
|
29
|
+
onError(error: ERRORS.TrezorError): void;
|
|
30
|
+
init(): Promise<void>;
|
|
31
|
+
getTransactions(txs: string[]): Promise<import("@trezor/blockchain-link").TypedRawTransaction[]>;
|
|
32
|
+
getCurrentFiatRates(params: {
|
|
33
|
+
currencies?: string[];
|
|
34
|
+
}): Promise<{
|
|
35
|
+
ts: number;
|
|
36
|
+
rates: import("@trezor/blockchain-link").FiatRates;
|
|
37
|
+
}>;
|
|
38
|
+
getFiatRatesForTimestamps(params: {
|
|
39
|
+
timestamps: number[];
|
|
40
|
+
}): Promise<{
|
|
41
|
+
tickers: {
|
|
42
|
+
ts: number;
|
|
43
|
+
rates: import("@trezor/blockchain-link").FiatRates;
|
|
44
|
+
}[];
|
|
45
|
+
}>;
|
|
46
|
+
getAccountBalanceHistory(params: BlockchainLinkParams<'getAccountBalanceHistory'>): Promise<import("@trezor/blockchain-link").AccountBalanceHistory[]>;
|
|
47
|
+
getNetworkInfo(): Promise<ServerInfo>;
|
|
48
|
+
getAccountInfo(request: BlockchainLinkParams<'getAccountInfo'>): Promise<import("@trezor/blockchain-link").AccountInfo>;
|
|
49
|
+
getAccountUtxo(descriptor: string): Promise<import("@trezor/blockchain-link").Utxo[]>;
|
|
50
|
+
estimateFee(request: {
|
|
51
|
+
blocks?: number[];
|
|
52
|
+
}): Promise<{
|
|
53
|
+
feePerUnit: string;
|
|
54
|
+
feePerTx?: string | undefined;
|
|
55
|
+
feeLimit?: string | undefined;
|
|
56
|
+
}[]>;
|
|
57
|
+
subscribe(accounts?: SubscriptionAccountInfo[]): Promise<{
|
|
58
|
+
subscribed: boolean;
|
|
59
|
+
}>;
|
|
60
|
+
subscribeFiatRates(_currency?: string): Promise<{
|
|
61
|
+
subscribed: boolean;
|
|
62
|
+
}>;
|
|
63
|
+
unsubscribe(accounts?: SubscriptionAccountInfo[]): Promise<{
|
|
64
|
+
subscribed: boolean;
|
|
65
|
+
}>;
|
|
66
|
+
unsubscribeFiatRates(): Promise<{
|
|
67
|
+
subscribed: boolean;
|
|
68
|
+
}>;
|
|
69
|
+
pushTransaction(tx: string): Promise<string>;
|
|
70
|
+
disconnect(): void;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=Blockchain.d.ts.map
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Blockchain = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const blockchain_link_1 = tslib_1.__importDefault(require("@trezor/blockchain-link"));
|
|
6
|
+
const events_1 = require("../events");
|
|
7
|
+
const constants_1 = require("../constants");
|
|
8
|
+
const urlUtils_1 = require("../utils/urlUtils");
|
|
9
|
+
const workers_1 = require("../workers/workers");
|
|
10
|
+
const getWorker = (type) => {
|
|
11
|
+
switch (type) {
|
|
12
|
+
case 'blockbook':
|
|
13
|
+
return workers_1.BlockbookWorker;
|
|
14
|
+
case 'ripple':
|
|
15
|
+
return workers_1.RippleWorker;
|
|
16
|
+
case 'blockfrost':
|
|
17
|
+
return workers_1.BlockfrostWorker;
|
|
18
|
+
case 'electrum':
|
|
19
|
+
return workers_1.ElectrumWorker;
|
|
20
|
+
default:
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
class Blockchain {
|
|
25
|
+
constructor(options) {
|
|
26
|
+
this.feeForBlock = [];
|
|
27
|
+
this.feeTimestamp = 0;
|
|
28
|
+
this.coinInfo = options.coinInfo;
|
|
29
|
+
this.postMessage = options.postMessage;
|
|
30
|
+
this.onConnected = options.onConnected;
|
|
31
|
+
this.onDisconnected = options.onDisconnected;
|
|
32
|
+
const { blockchainLink } = options.coinInfo;
|
|
33
|
+
if (!blockchainLink) {
|
|
34
|
+
throw constants_1.ERRORS.TypedError('Backend_NotSupported');
|
|
35
|
+
}
|
|
36
|
+
const worker = getWorker(blockchainLink.type);
|
|
37
|
+
if (!worker) {
|
|
38
|
+
throw constants_1.ERRORS.TypedError('Backend_WorkerMissing', `BlockchainLink worker not found ${blockchainLink.type}`);
|
|
39
|
+
}
|
|
40
|
+
const { onionDomains } = options;
|
|
41
|
+
this.onionDomains = onionDomains
|
|
42
|
+
? blockchainLink.url.reduce((a, url) => {
|
|
43
|
+
const onion = (0, urlUtils_1.getOnionDomain)(url, onionDomains);
|
|
44
|
+
if (onion !== url) {
|
|
45
|
+
a[onion] = url;
|
|
46
|
+
}
|
|
47
|
+
return a;
|
|
48
|
+
}, {})
|
|
49
|
+
: {};
|
|
50
|
+
const server = Object.keys(this.onionDomains).length
|
|
51
|
+
? Object.keys(this.onionDomains)
|
|
52
|
+
: blockchainLink.url;
|
|
53
|
+
this.link = new blockchain_link_1.default({
|
|
54
|
+
name: this.coinInfo.shortcut,
|
|
55
|
+
worker,
|
|
56
|
+
server,
|
|
57
|
+
debug: options.debug,
|
|
58
|
+
proxy: options.proxy,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
onError(error) {
|
|
62
|
+
var _a;
|
|
63
|
+
this.link.dispose();
|
|
64
|
+
this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.ERROR, {
|
|
65
|
+
coin: this.coinInfo,
|
|
66
|
+
error: error.message,
|
|
67
|
+
code: error.code,
|
|
68
|
+
}));
|
|
69
|
+
(_a = this.onDisconnected) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
70
|
+
}
|
|
71
|
+
async init() {
|
|
72
|
+
this.link.on('connected', async () => {
|
|
73
|
+
var _a;
|
|
74
|
+
const info = await this.link.getInfo();
|
|
75
|
+
this.serverInfo = info;
|
|
76
|
+
const shortcut = this.coinInfo.shortcut === 'tXRP' ? 'XRP' : this.coinInfo.shortcut;
|
|
77
|
+
if (info.shortcut.toLowerCase() !== shortcut.toLowerCase()) {
|
|
78
|
+
this.onError(constants_1.ERRORS.TypedError('Backend_Invalid'));
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const cleanUrl = this.onionDomains[info.url];
|
|
82
|
+
(_a = this.onConnected) === null || _a === void 0 ? void 0 : _a.call(this, cleanUrl || info.url);
|
|
83
|
+
this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.CONNECT, {
|
|
84
|
+
coin: this.coinInfo,
|
|
85
|
+
...info,
|
|
86
|
+
cleanUrl,
|
|
87
|
+
}));
|
|
88
|
+
});
|
|
89
|
+
this.link.on('disconnected', () => {
|
|
90
|
+
this.onError(constants_1.ERRORS.TypedError('Backend_Disconnected'));
|
|
91
|
+
});
|
|
92
|
+
this.link.on('error', error => {
|
|
93
|
+
this.onError(constants_1.ERRORS.TypedError('Backend_Error', error.message));
|
|
94
|
+
});
|
|
95
|
+
try {
|
|
96
|
+
await this.link.connect();
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
this.onError(constants_1.ERRORS.TypedError('Backend_Error', error.message));
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
getTransactions(txs) {
|
|
104
|
+
return Promise.all(txs.map(id => this.link.getTransaction(id)));
|
|
105
|
+
}
|
|
106
|
+
getCurrentFiatRates(params) {
|
|
107
|
+
return this.link.getCurrentFiatRates(params);
|
|
108
|
+
}
|
|
109
|
+
getFiatRatesForTimestamps(params) {
|
|
110
|
+
return this.link.getFiatRatesForTimestamps(params);
|
|
111
|
+
}
|
|
112
|
+
getAccountBalanceHistory(params) {
|
|
113
|
+
return this.link.getAccountBalanceHistory(params);
|
|
114
|
+
}
|
|
115
|
+
getNetworkInfo() {
|
|
116
|
+
return this.link.getInfo();
|
|
117
|
+
}
|
|
118
|
+
getAccountInfo(request) {
|
|
119
|
+
return this.link.getAccountInfo(request);
|
|
120
|
+
}
|
|
121
|
+
getAccountUtxo(descriptor) {
|
|
122
|
+
return this.link.getAccountUtxo(descriptor);
|
|
123
|
+
}
|
|
124
|
+
async estimateFee(request) {
|
|
125
|
+
const { blocks } = request;
|
|
126
|
+
if (blocks) {
|
|
127
|
+
const now = Date.now();
|
|
128
|
+
const outdated = now - this.feeTimestamp > 20 * 60 * 1000;
|
|
129
|
+
const unknownBlocks = blocks.filter(() => typeof this.feeForBlock !== 'string');
|
|
130
|
+
if (!outdated && unknownBlocks.length < 1) {
|
|
131
|
+
}
|
|
132
|
+
const fees = await this.link.estimateFee(request);
|
|
133
|
+
blocks.forEach((block, index) => {
|
|
134
|
+
this.feeForBlock[block] = fees[index];
|
|
135
|
+
});
|
|
136
|
+
this.feeTimestamp = now;
|
|
137
|
+
return fees;
|
|
138
|
+
}
|
|
139
|
+
return this.link.estimateFee(request);
|
|
140
|
+
}
|
|
141
|
+
async subscribe(accounts) {
|
|
142
|
+
if (this.link.listenerCount('block') === 0) {
|
|
143
|
+
this.link.on('block', block => {
|
|
144
|
+
this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.BLOCK, {
|
|
145
|
+
coin: this.coinInfo,
|
|
146
|
+
...block,
|
|
147
|
+
}));
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (this.link.listenerCount('notification') === 0) {
|
|
151
|
+
this.link.on('notification', notification => {
|
|
152
|
+
this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.NOTIFICATION, {
|
|
153
|
+
coin: this.coinInfo,
|
|
154
|
+
notification,
|
|
155
|
+
}));
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
const blockSubscription = await this.link.subscribe({ type: 'block' });
|
|
159
|
+
if (!accounts) {
|
|
160
|
+
return blockSubscription;
|
|
161
|
+
}
|
|
162
|
+
return this.link.subscribe({
|
|
163
|
+
type: 'accounts',
|
|
164
|
+
accounts,
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
subscribeFiatRates(_currency) {
|
|
168
|
+
if (this.link.listenerCount('fiatRates') === 0) {
|
|
169
|
+
this.link.on('fiatRates', ({ rates }) => {
|
|
170
|
+
this.postMessage((0, events_1.createBlockchainMessage)(events_1.BLOCKCHAIN.FIAT_RATES_UPDATE, {
|
|
171
|
+
coin: this.coinInfo,
|
|
172
|
+
rates,
|
|
173
|
+
}));
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
return this.link.subscribe({
|
|
177
|
+
type: 'fiatRates',
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
async unsubscribe(accounts) {
|
|
181
|
+
if (!accounts) {
|
|
182
|
+
this.link.removeAllListeners('block');
|
|
183
|
+
this.link.removeAllListeners('fiatRates');
|
|
184
|
+
this.link.removeAllListeners('notification');
|
|
185
|
+
await this.link.unsubscribe({ type: 'fiatRates' });
|
|
186
|
+
return this.link.unsubscribe({ type: 'block' });
|
|
187
|
+
}
|
|
188
|
+
return this.link.unsubscribe({ type: 'accounts', accounts });
|
|
189
|
+
}
|
|
190
|
+
unsubscribeFiatRates() {
|
|
191
|
+
this.link.removeAllListeners('fiatRates');
|
|
192
|
+
return this.link.unsubscribe({ type: 'fiatRates' });
|
|
193
|
+
}
|
|
194
|
+
pushTransaction(tx) {
|
|
195
|
+
return this.link.pushTransaction(tx);
|
|
196
|
+
}
|
|
197
|
+
disconnect() {
|
|
198
|
+
this.link.removeAllListeners();
|
|
199
|
+
this.link.disconnect();
|
|
200
|
+
this.onError(constants_1.ERRORS.TypedError('Backend_Disconnected'));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
exports.Blockchain = Blockchain;
|
|
204
|
+
//# sourceMappingURL=Blockchain.js.map
|