Skip to content
This repository has been archived by the owner on Nov 23, 2023. It is now read-only.

Feature/custom backend #538

Merged
merged 5 commits into from
Mar 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 28 additions & 21 deletions src/js/backend/BlockchainLink.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@ import type {
GetAccountInfo,
BlockchainBlock,
BlockchainSubscribeAccount,
BlockchainTransactions,
BlockchainFiatRates,
BlockchainTimestampedFiatRates,
BlockchainAccountBalanceHistory,
BlockchainGetAccountBalanceHistory,
} from '../types';

Expand Down Expand Up @@ -108,32 +105,32 @@ export default class Blockchain {
}
}

async loadTransaction(id: string): Promise<BitcoinJsTransaction> {
async loadTransaction(id: string) {
const transaction = await this.link.getTransaction(id);
return BitcoinJsTransaction.fromHex(transaction.tx.hex, this.coinInfo.network);
}

async getTransactions(txs: string[]): Promise<BlockchainTransactions[]> {
async getTransactions(txs: string[]) {
return Promise.all(
txs.map(id => this.link.getTransaction(id))
);
}

async getReferencedTransactions(txs: string[]): Promise<BitcoinJsTransaction[]> {
async getReferencedTransactions(txs: string[]) {
return Promise.all(
txs.map(id => this.loadTransaction(id))
);
}

async getCurrentFiatRates(params: { currencies?: ?string[] }): Promise<BlockchainTimestampedFiatRates> {
async getCurrentFiatRates(params: { currencies?: ?string[] }) {
return this.link.getCurrentFiatRates(params);
}

async getFiatRatesForTimestamps(params: { timestamps?: ?number[] }): Promise<BlockchainTimestampedFiatRates[]> {
async getFiatRatesForTimestamps(params: { timestamps?: ?number[] }) {
return this.link.getFiatRatesForTimestamps(params);
}

async getAccountBalanceHistory(params: $Shape<BlockchainGetAccountBalanceHistory>): Promise<BlockchainAccountBalanceHistory[]> {
async getAccountBalanceHistory(params: $Shape<BlockchainGetAccountBalanceHistory>) {
return this.link.getAccountBalanceHistory(params);
}

Expand Down Expand Up @@ -170,7 +167,7 @@ export default class Blockchain {
return this.link.estimateFee(request);
}

async subscribe(accounts: BlockchainSubscribeAccount[]): Promise<{ subscribed: boolean }> {
async subscribe(accounts: BlockchainSubscribeAccount[]) {
// set block listener if it wasn't set before
if (this.link.listenerCount('block') === 0) {
this.link.on('block', (block: BlockchainBlock) => {
Expand Down Expand Up @@ -199,7 +196,7 @@ export default class Blockchain {
});
}

async subscribeFiatRates(currency?: string): Promise<{ subscribed: boolean }> {
async subscribeFiatRates(currency?: string) {
// set block listener if it wasn't set before
if (this.link.listenerCount('fiatRates') === 0) {
this.link.on('fiatRates', (res: {
Expand All @@ -217,7 +214,7 @@ export default class Blockchain {
});
}

async unsubscribe(accounts?: BlockchainSubscribeAccount[]): Promise<any> {
async unsubscribe(accounts?: BlockchainSubscribeAccount[]) {
if (!accounts) {
this.link.removeAllListeners('block');
this.link.removeAllListeners('fiatRates');
Expand All @@ -232,12 +229,12 @@ export default class Blockchain {
return this.link.unsubscribe({ type: 'accounts', accounts });
}

async unsubscribeFiatRates(): Promise<any> {
async unsubscribeFiatRates() {
this.link.removeAllListeners('fiatRates');
return this.link.unsubscribe({ type: 'fiatRates' });
}

async pushTransaction(tx: string): Promise<string> {
async pushTransaction(tx: string) {
return await this.link.pushTransaction(tx);
}

Expand All @@ -249,28 +246,38 @@ export default class Blockchain {
}

const instances: Blockchain[] = [];
const customBackends: { [coin: string]: CoinInfo } = {};

const remove = (backend: Blockchain): void => {
const index: number = instances.indexOf(backend);
export const remove = (backend: Blockchain) => {
const index = instances.indexOf(backend);
if (index >= 0) {
instances.splice(index, 1);
}
};

export const find = (name: string): ?Blockchain => {
for (let i: number = 0; i < instances.length; i++) {
export const find = (name: string) => {
for (let i = 0; i < instances.length; i++) {
if (instances[i].coinInfo.name === name) {
return instances[i];
}
}
return null;
};

export const initBlockchain = async (coinInfo: $ElementType<Options, 'coinInfo'>, postMessage: $ElementType<Options, 'postMessage'>) => {
let backend: ?Blockchain = find(coinInfo.name);
export const setCustomBackend = (coinInfo: CoinInfo, blockchainLink: $ElementType<CoinInfo, 'blockchainLink'>) => {
if (!blockchainLink) {
delete customBackends[coinInfo.shortcut];
} else {
customBackends[coinInfo.shortcut] = coinInfo;
customBackends[coinInfo.shortcut].blockchainLink = blockchainLink;
}
};

export const initBlockchain = async (coinInfo: CoinInfo, postMessage: $ElementType<Options, 'postMessage'>) => {
let backend = find(coinInfo.name);
if (!backend) {
backend = new Blockchain({
coinInfo,
coinInfo: customBackends[coinInfo.shortcut] || coinInfo,
postMessage,
});
try {
Expand Down
13 changes: 3 additions & 10 deletions src/js/core/methods/blockchain/BlockchainDisconnect.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,7 @@ export default class BlockchainDisconnect extends AbstractMethod {
{ name: 'coin', type: 'string', obligatory: true },
]);

let coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
coinInfo = getCoinInfo(payload.coin);
}

const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand All @@ -46,14 +42,11 @@ export default class BlockchainDisconnect extends AbstractMethod {
};
}

async run(): Promise<{ disconnected: true }> {
async run() {
const backend = await findBlockchainBackend(this.params.coinInfo.name);
if (backend) {
backend.disconnect();
}

return {
disconnected: true,
};
return { disconnected: true };
}
}
2 changes: 1 addition & 1 deletion src/js/core/methods/blockchain/BlockchainEstimateFee.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export default class BlockchainEstimateFee extends AbstractMethod {
]);
}
}
const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);

if (!coinInfo) {
throw NO_COIN_INFO;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class BlockchainGetAccountBalanceHistory extends AbstractMethod {
{ name: 'groupBy', type: 'number', obligatory: false },
]);

const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default class BlockchainGetCurrentFiatRates extends AbstractMethod {
{ name: 'coin', type: 'string', obligatory: true },
]);

const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default class BlockchainGetFiatRatesForTimestamps extends AbstractMethod
{ name: 'coin', type: 'string', obligatory: true },
]);

const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default class BlockchainGetTransactions extends AbstractMethod {
{ name: 'coin', type: 'string', obligatory: true },
]);

const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand Down
56 changes: 56 additions & 0 deletions src/js/core/methods/blockchain/BlockchainSetCustomBackend.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/* @flow */

import AbstractMethod from '../AbstractMethod';
import { validateParams } from '../helpers/paramsValidator';
import { NO_COIN_INFO } from '../../../constants/errors';

import { find as findBackend, remove as removeBackend, setCustomBackend, initBlockchain } from '../../../backend/BlockchainLink';
import { getCoinInfo } from '../../../data/CoinInfo';
import type { CoreMessage, CoinInfo } from '../../../types';

type Params = {
coinInfo: CoinInfo;
}

export default class BlockchainSetCustomBackend extends AbstractMethod {
params: Params;

constructor(message: CoreMessage) {
super(message);
this.requiredPermissions = [];
this.info = '';
this.useDevice = false;
this.useUi = false;

const { payload } = message;

// validate incoming parameters
validateParams(payload, [
{ name: 'coin', type: 'string', obligatory: true },
{ name: 'blockchainLink', type: 'object' },
]);

const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}

setCustomBackend(coinInfo, payload.blockchainLink);

this.params = {
coinInfo,
};
}

async run() {
const current = await findBackend(this.params.coinInfo.name);
if (current) {
await current.disconnect();
removeBackend(current);

await initBlockchain(this.params.coinInfo, this.postMessage);
}

return true;
}
}
4 changes: 2 additions & 2 deletions src/js/core/methods/blockchain/BlockchainSubscribe.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export default class BlockchainSubscribe extends AbstractMethod {
]);
});

const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand All @@ -49,7 +49,7 @@ export default class BlockchainSubscribe extends AbstractMethod {
};
}

async run(): Promise<{ subscribed: boolean }> {
async run() {
const backend = await initBlockchain(this.params.coinInfo, this.postMessage);
return backend.subscribe(this.params.accounts);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default class BlockchainSubscribeFiatRates extends AbstractMethod {
{ name: 'coin', type: 'string', obligatory: true },
]);

const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand All @@ -43,7 +43,7 @@ export default class BlockchainSubscribeFiatRates extends AbstractMethod {
};
}

async run(): Promise<{ subscribed: boolean }> {
async run() {
const backend = await initBlockchain(this.params.coinInfo, this.postMessage);
return backend.subscribeFiatRates(this.params.currency);
}
Expand Down
4 changes: 2 additions & 2 deletions src/js/core/methods/blockchain/BlockchainUnsubscribe.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export default class BlockchainUnsubscribe extends AbstractMethod {
});
}

const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand All @@ -51,7 +51,7 @@ export default class BlockchainUnsubscribe extends AbstractMethod {
};
}

async run(): Promise<any> {
async run() {
const backend = await initBlockchain(this.params.coinInfo, this.postMessage);
return backend.unsubscribe(this.params.accounts);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export default class BlockchainUnsubscribeFiatRates extends AbstractMethod {
{ name: 'coin', type: 'string', obligatory: true },
]);

const coinInfo: ?CoinInfo = getCoinInfo(payload.coin);
const coinInfo = getCoinInfo(payload.coin);
if (!coinInfo) {
throw NO_COIN_INFO;
}
Expand All @@ -40,7 +40,7 @@ export default class BlockchainUnsubscribeFiatRates extends AbstractMethod {
};
}

async run(): Promise<any> {
async run() {
const backend = await initBlockchain(this.params.coinInfo, this.postMessage);
return backend.unsubscribeFiatRates();
}
Expand Down
10 changes: 6 additions & 4 deletions src/js/core/methods/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@ import AbstractMethod from './AbstractMethod';

import BlockchainDisconnect from './blockchain/BlockchainDisconnect';
import BlockchainEstimateFee from './blockchain/BlockchainEstimateFee';
import BlockchainGetTransactions from './blockchain/BlockchainGetTransactions';
import BlockchainGetAccountBalanceHistory from './blockchain/BlockchainGetAccountBalanceHistory';
import BlockchainGetCurrentFiatRates from './blockchain/BlockchainGetCurrentFiatRates';
import BlockchainGetFiatRatesForTimestamps from './blockchain/BlockchainGetFiatRatesForTimestamps';
import BlockchainGetAccountBalanceHistory from './blockchain/BlockchainGetAccountBalanceHistory';
import BlockchainSubscribeFiatRates from './blockchain/BlockchainSubscribeFiatRates';
import BlockchainUnsubscribeFiatRates from './blockchain/BlockchainUnsubscribeFiatRates';
import BlockchainGetTransactions from './blockchain/BlockchainGetTransactions';
import BlockchainSetCustomBackend from './blockchain/BlockchainSetCustomBackend';
import BlockchainSubscribe from './blockchain/BlockchainSubscribe';
import BlockchainSubscribeFiatRates from './blockchain/BlockchainSubscribeFiatRates';
import BlockchainUnsubscribe from './blockchain/BlockchainUnsubscribe';
import BlockchainUnsubscribeFiatRates from './blockchain/BlockchainUnsubscribeFiatRates';
import CardanoGetAddress from './CardanoGetAddress';
import CardanoGetPublicKey from './CardanoGetPublicKey';
import CardanoSignTransaction from './CardanoSignTransaction';
Expand Down Expand Up @@ -74,6 +75,7 @@ const classes: { [k: string]: any } = {
'blockchainGetCurrentFiatRates': BlockchainGetCurrentFiatRates,
'blockchainGetFiatRatesForTimestamps': BlockchainGetFiatRatesForTimestamps,
'blockchainGetTransactions': BlockchainGetTransactions,
'blockchainSetCustomBackend': BlockchainSetCustomBackend,
'blockchainSubscribe': BlockchainSubscribe,
'blockchainSubscribeFiatRates': BlockchainSubscribeFiatRates,
'blockchainUnsubscribe': BlockchainUnsubscribe,
Expand Down
2 changes: 1 addition & 1 deletion src/js/data/CoinInfo.js
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ const parseBitcoinNetworksJson = (json: JSON) => {
const isBitcoin = shortcut === 'BTC' || shortcut === 'TEST';
const hasTimestamp = shortcut === 'CPC' || shortcut === 'PPC' || shortcut === 'tPPC';

const network: $ElementType<BitcoinNetworkInfo, 'network'> = {
const network = {
messagePrefix: coin.signed_message_header,
bech32: coin.bech32_prefix,
bip32: {
Expand Down
4 changes: 4 additions & 0 deletions src/js/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ const TrezorConnect: API = {
return call({ method: 'blockchainGetTransactions', ...params });
},

blockchainSetCustomBackend: params => {
return call({ method: 'blockchainSetCustomBackend', ...params });
},

blockchainSubscribe: params => {
return call({ method: 'blockchainSubscribe', ...params });
},
Expand Down
Loading