Skip to content
This repository has been archived by the owner on Jul 15, 2022. It is now read-only.

Commit

Permalink
added LL platform types and logic (#1166)
Browse files Browse the repository at this point in the history
* added ledgerLiveAPI hook

* added serializers, converters and platform types

* fixed tx serializer

* fixed types

* added bitcoin tx

* feat(Platform): added SignedTransaction types

* added paraswap -> eth dep

Co-authored-by: Rémi Jarasson (Ext) <[email protected]>
  • Loading branch information
IAmMorrow and Rémi Jarasson (Ext) authored May 17, 2021
1 parent 6d84bbd commit c62f6c7
Show file tree
Hide file tree
Showing 8 changed files with 330 additions and 0 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"expect": "^26.6.2",
"invariant": "^2.2.2",
"isomorphic-ws": "^4.0.1",
"json-rpc-2.0": "^0.2.16",
"lodash": "^4.17.21",
"lru-cache": "5.1.1",
"numeral": "^2.0.6",
Expand Down
1 change: 1 addition & 0 deletions src/apps/polyfill.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ listCryptoCurrencies(true, true).forEach((a) => {
["ThunderCore", "Ethereum"],
["Volta", "Ethereum"],
["ZenCash", "Bitcoin"],
["Paraswap", "Ethereum"],
].forEach(([name, dep]) => declareDep(name, dep));

export const getDependencies = (appName: string): string[] =>
Expand Down
42 changes: 42 additions & 0 deletions src/platform/JSONRPCServer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// @flow
import { useEffect, useRef, useCallback } from "react";
import {
JSONRPCServer,
JSONRPCServerAndClient,
JSONRPCClient,
} from "json-rpc-2.0";

type LedgerLiveAPIHandlers = {};

type SendFunc = (request: any) => void;

export const useJSONRPCServer = (
handlers: LedgerLiveAPIHandlers,
send: SendFunc
) => {
const serverRef: { current: null | typeof JSONRPCServerAndClient } = useRef(
null
);

useEffect(() => {
const server = new JSONRPCServerAndClient(
new JSONRPCServer(),
new JSONRPCClient(send)
);

const methodIds = Object.keys(handlers);
methodIds.forEach((methodId: string) => {
server.addMethod(methodId, handlers[methodId]);
});

serverRef.current = server;
}, [send, handlers]);

const receive = useCallback(async (request: any) => {
if (serverRef.current) {
await serverRef.current.receiveAndSend(request);
}
}, []);

return [receive];
};
35 changes: 35 additions & 0 deletions src/platform/converters.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// @flow

import type { Account, CryptoCurrency } from "../types";
import type { PlatformAccount, PlatformCurrency } from "./types";

export function accountToPlatformAccount(account: Account): PlatformAccount {
return {
id: account.id,
name: account.name,
address: account.freshAddress,
currency: account.currency.id,
balance: account.balance,
spendableBalance: account.spendableBalance,
blockHeight: account.blockHeight,
lastSyncDate: account.lastSyncDate,
};
}

export function currencyToPlatformCurrency(
currency: CryptoCurrency
): PlatformCurrency {
return {
type: currency.type,
id: currency.id,
ticker: currency.ticker,
name: currency.name,
family: currency.family,
color: currency.color,
units: currency.units.map((unit) => ({
name: unit.name,
code: unit.code,
magnitude: unit.magnitude,
})),
};
}
39 changes: 39 additions & 0 deletions src/platform/rawTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// @flow
import type { SignedOperationRaw } from "../types";

export type RawPlatformAccount = {
id: string,
name: string,
address: string,
currency: string,
balance: string,
spendableBalance: string,
blockHeight: number,
lastSyncDate: string,
};

export interface RawPlatformTransactionCommon {
amount: string;
recipient: string;
}

export interface RawPlatformEthereumTransaction
extends RawPlatformTransactionCommon {
family: "ethereum";
nonce: ?number;
data: ?string;
gasPrice: ?string;
gasLimit: ?string;
}

export interface RawPlatformBitcoinTransaction
extends RawPlatformTransactionCommon {
family: "bitcoin";
feePerByte: ?string;
}

export type RawPlatformTransaction =
| RawPlatformEthereumTransaction
| RawPlatformBitcoinTransaction;

export type RawPlatformSignedTransaction = SignedOperationRaw;
151 changes: 151 additions & 0 deletions src/platform/serializers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// @flow

import { fromSignedOperationRaw, toSignedOperationRaw } from "../transaction";

import type {
RawPlatformAccount,
RawPlatformTransaction,
RawPlatformEthereumTransaction,
RawPlatformBitcoinTransaction,
RawPlatformSignedTransaction,
} from "./rawTypes";
import type {
PlatformAccount,
PlatformTransaction,
PlatformEthereumTransaction,
PlatformBitcoinTransaction,
PlatformSignedTransaction,
} from "./types";

import { BigNumber } from "bignumber.js";

export function serializePlatformAccount(
account: PlatformAccount
): RawPlatformAccount {
return {
id: account.id,
name: account.name,
address: account.address,
currency: account.currency,
balance: account.balance.toString(),
spendableBalance: account.spendableBalance.toString(),
blockHeight: account.blockHeight,
lastSyncDate: account.lastSyncDate.toString(),
};
}

export function deserializePlatformAccount(
rawAccount: RawPlatformAccount
): PlatformAccount {
return {
id: rawAccount.id,
name: rawAccount.name,
address: rawAccount.address,
currency: rawAccount.currency,
balance: new BigNumber(rawAccount.balance),
spendableBalance: new BigNumber(rawAccount.spendableBalance),
blockHeight: rawAccount.blockHeight,
lastSyncDate: new Date(rawAccount.lastSyncDate),
};
}

export function serializePlatformEthereumTransaction(
transaction: PlatformEthereumTransaction
): RawPlatformEthereumTransaction {
return {
family: transaction.family,
amount: transaction.amount.toString(),
recipient: transaction.recipient,
nonce: transaction.nonce,
data: transaction.data ? transaction.data.toString() : undefined,
gasPrice: transaction.gasPrice
? transaction.gasPrice.toString()
: undefined,
gasLimit: transaction.gasLimit
? transaction.gasLimit.toString()
: undefined,
};
}

export function deserializePlatformEthereumTransaction(
rawTransaction: RawPlatformEthereumTransaction
): PlatformEthereumTransaction {
return {
family: rawTransaction.family,
amount: new BigNumber(rawTransaction.amount),
recipient: rawTransaction.recipient,
nonce: rawTransaction.nonce,
data: rawTransaction.data ? Buffer.from(rawTransaction.data) : undefined,
gasPrice: rawTransaction.gasPrice
? new BigNumber(rawTransaction.gasPrice)
: undefined,
gasLimit: rawTransaction.gasLimit
? new BigNumber(rawTransaction.gasLimit)
: undefined,
};
}

export function serializePlatformBitcoinTransaction(
transaction: PlatformBitcoinTransaction
): RawPlatformBitcoinTransaction {
return {
family: transaction.family,
amount: transaction.amount.toString(),
recipient: transaction.recipient,
feePerByte: transaction.feePerByte
? transaction.feePerByte.toString()
: undefined,
};
}

export function deserializePlatformBitcoinTransaction(
rawTransaction: RawPlatformBitcoinTransaction
): PlatformBitcoinTransaction {
return {
family: rawTransaction.family,
amount: new BigNumber(rawTransaction.amount),
recipient: rawTransaction.recipient,
feePerByte: rawTransaction.feePerByte
? new BigNumber(rawTransaction.feePerByte)
: undefined,
};
}

export function serializePlatformTransaction(
transaction: PlatformTransaction
): RawPlatformTransaction {
switch (transaction.family) {
case "ethereum":
return serializePlatformEthereumTransaction(transaction);
case "bitcoin":
return serializePlatformBitcoinTransaction(transaction);
default:
throw new Error(`Can't serialize ${transaction.family} transactions`);
}
}

export function deserializePlatformTransaction(
rawTransaction: RawPlatformTransaction
): PlatformTransaction {
switch (rawTransaction.family) {
case "ethereum":
return deserializePlatformEthereumTransaction(rawTransaction);
case "bitcoin":
return deserializePlatformBitcoinTransaction(rawTransaction);
default:
throw new Error(`Can't deserialize transaction: family not supported`);
}
}

export function serializePlatformSignedTransaction(
signedTransaction: PlatformSignedTransaction
): RawPlatformSignedTransaction {
return toSignedOperationRaw(signedTransaction, true);
}

export function deserializePlatformSignedTransaction(
rawSignedTransaction: RawPlatformSignedTransaction,
accountId: string
): PlatformSignedTransaction {
return fromSignedOperationRaw(rawSignedTransaction, accountId);
}
56 changes: 56 additions & 0 deletions src/platform/types.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// @flow

import type { BigNumber } from "bignumber.js";

import type { SignedOperation } from "../types";

export type PlatformAccount = {
id: string,
name: string,
address: string,
currency: string,
balance: BigNumber,
spendableBalance: BigNumber,
blockHeight: number,
lastSyncDate: Date,
};

export type PlatformUnit = {
name: string,
code: string,
magnitude: number,
};

export type PlatformCurrency = {
type: string,
color: string,
ticker: string,
id: string,
name: string,
family: string,
units: PlatformUnit[],
};

export interface PlatformTransactionCommon {
amount: BigNumber;
recipient: string;
}

export interface PlatformEthereumTransaction extends PlatformTransactionCommon {
family: "ethereum";
nonce: ?number;
data: ?Buffer;
gasPrice: ?BigNumber;
gasLimit: ?BigNumber;
}

export interface PlatformBitcoinTransaction extends PlatformTransactionCommon {
family: "bitcoin";
feePerByte: ?BigNumber;
}

export type PlatformTransaction =
| PlatformEthereumTransaction
| PlatformBitcoinTransaction;

export type PlatformSignedTransaction = SignedOperation;
5 changes: 5 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5392,6 +5392,11 @@ json-parse-even-better-errors@^2.3.0:
resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==

json-rpc-2.0@^0.2.16:
version "0.2.16"
resolved "https://registry.yarnpkg.com/json-rpc-2.0/-/json-rpc-2.0-0.2.16.tgz#8ee70443f09abc26a9d339f382c930f3d84cf635"
integrity sha512-nXKBcNZxkoeyKpotT/T3tciv+e7EQb13nuDRLD2tff8Vs39VpPTOvL0BOXM3mN5QE10BlVEq5LDSV344m4zpeg==

json-schema-traverse@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660"
Expand Down

1 comment on commit c62f6c7

@vercel
Copy link

@vercel vercel bot commented on c62f6c7 May 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Successfully deployed to the following URLs:

Please sign in to comment.