@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.
Files changed (84) hide show
  1. package/README.md +5 -5
  2. package/lib/api/authorizeCoinJoin.js +6 -2
  3. package/lib/api/bitcoin/TransactionComposer.js +2 -1
  4. package/lib/api/bitcoin/enhanceSignTx.js +1 -1
  5. package/lib/api/bitcoin/inputs.js +3 -2
  6. package/lib/api/bitcoin/outputs.js +2 -4
  7. package/lib/api/bitcoin/refTx.js +3 -3
  8. package/lib/api/bitcoin/signtxVerify.d.ts +3 -3
  9. package/lib/api/bitcoin/signtxVerify.js +16 -15
  10. package/lib/api/blockchainDisconnect.js +1 -1
  11. package/lib/api/blockchainSetCustomBackend.js +1 -1
  12. package/lib/api/cardano/cardanoAuxiliaryData.d.ts +1 -1
  13. package/lib/api/cardano/cardanoAuxiliaryData.js +38 -16
  14. package/lib/api/cardanoSignTransaction.d.ts +1 -0
  15. package/lib/api/cardanoSignTransaction.js +23 -3
  16. package/lib/api/getAddress.d.ts +2 -1
  17. package/lib/api/getAddress.js +12 -1
  18. package/lib/api/getOwnershipProof.d.ts +1 -5
  19. package/lib/api/getOwnershipProof.js +5 -3
  20. package/lib/api/getPublicKey.d.ts +1 -0
  21. package/lib/api/getPublicKey.js +22 -7
  22. package/lib/api/index.d.ts +2 -0
  23. package/lib/api/index.js +5 -1
  24. package/lib/api/setBusy.d.ts +7 -0
  25. package/lib/api/setBusy.js +27 -0
  26. package/lib/api/signTransaction.d.ts +2 -1
  27. package/lib/api/signTransaction.js +24 -5
  28. package/lib/api/unlockPath.d.ts +10 -0
  29. package/lib/api/unlockPath.js +35 -0
  30. package/lib/backend/BackendManager.d.ts +21 -0
  31. package/lib/backend/BackendManager.js +91 -0
  32. package/lib/backend/Blockchain.d.ts +72 -0
  33. package/lib/backend/Blockchain.js +204 -0
  34. package/lib/backend/BlockchainLink.d.ts +6 -71
  35. package/lib/backend/BlockchainLink.js +12 -288
  36. package/lib/constants/cardano.d.ts +3 -1
  37. package/lib/constants/cardano.js +3 -1
  38. package/lib/core/AbstractMethod.d.ts +1 -0
  39. package/lib/core/index.d.ts +1 -1
  40. package/lib/core/index.js +1 -1
  41. package/lib/core/method.d.ts +1 -1
  42. package/lib/data/config.js +2 -2
  43. package/lib/data/version.d.ts +1 -1
  44. package/lib/data/version.js +1 -1
  45. package/lib/device/Device.d.ts +1 -1
  46. package/lib/device/Device.js +8 -2
  47. package/lib/device/DeviceCommands.d.ts +8 -2
  48. package/lib/device/DeviceCommands.js +48 -25
  49. package/lib/factory.js +2 -0
  50. package/lib/types/api/authorizeCoinJoin.d.ts +1 -0
  51. package/lib/types/api/bitcoin/index.d.ts +5 -0
  52. package/lib/types/api/cardano/index.d.ts +13 -10
  53. package/lib/types/api/eos/index.d.ts +0 -4
  54. package/lib/types/api/eosGetPublicKey.d.ts +4 -4
  55. package/lib/types/api/getAddress.d.ts +1 -0
  56. package/lib/types/api/getPublicKey.d.ts +5 -0
  57. package/lib/types/api/index.d.ts +4 -0
  58. package/lib/types/api/setBusy.d.ts +4 -0
  59. package/lib/types/api/setBusy.js +3 -0
  60. package/lib/types/api/unlockPath.d.ts +8 -0
  61. package/lib/types/api/unlockPath.js +3 -0
  62. package/lib/utils/pathUtils.d.ts +2 -3
  63. package/lib/utils/pathUtils.js +42 -15
  64. package/package.json +19 -7
  65. package/lib/api/bitcoin/__fixtures__/inputs.d.ts +0 -112
  66. package/lib/api/bitcoin/__fixtures__/inputs.js +0 -102
  67. package/lib/api/bitcoin/__fixtures__/signtxVerify.d.ts +0 -147
  68. package/lib/api/bitcoin/__fixtures__/signtxVerify.js +0 -216
  69. package/lib/api/common/__fixtures__/paramsValidator.d.ts +0 -596
  70. package/lib/api/common/__fixtures__/paramsValidator.js +0 -355
  71. package/lib/api/ethereum/__fixtures__/ethereumSignTypedData.d.ts +0 -225
  72. package/lib/api/ethereum/__fixtures__/ethereumSignTypedData.js +0 -341
  73. package/lib/utils/__fixtures__/accountUtils.d.ts +0 -4
  74. package/lib/utils/__fixtures__/accountUtils.js +0 -32
  75. package/lib/utils/__fixtures__/addressUtils.d.ts +0 -10
  76. package/lib/utils/__fixtures__/addressUtils.js +0 -214
  77. package/lib/utils/__fixtures__/ethereumUtils.d.ts +0 -3
  78. package/lib/utils/__fixtures__/ethereumUtils.js +0 -20
  79. package/lib/utils/__fixtures__/formatUtils.d.ts +0 -3
  80. package/lib/utils/__fixtures__/formatUtils.js +0 -15
  81. package/lib/utils/__fixtures__/hdnodeUtils.d.ts +0 -186
  82. package/lib/utils/__fixtures__/hdnodeUtils.js +0 -206
  83. package/lib/utils/bufferUtils.d.ts +0 -3
  84. 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
- preauthorized?: boolean;
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
- preauthorized: payload.preauthorized,
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(accountPath.address_n.slice(0, 3), params.coinInfo);
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 (params.preauthorized) {
116
- await device.getCommands().typedCall('DoPreauthorized', 'PreauthorizedRequest', {});
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