Skip to content

Commit

Permalink
[Coin Tron] Modularization (#6941)
Browse files Browse the repository at this point in the history
* feat: create coin module

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: typecheck

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: test

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: unimported

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: add missing invariant import

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: react test

Signed-off-by: Stéphane Prohaszka <[email protected]>

* feat: add typing to network calls

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: lint and typecheck

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: erroneous import for bridge test

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: minimal fix for test

Signed-off-by: Stéphane Prohaszka <[email protected]>

* fix: handle malformed transaction and manage nextUrl for transaction

Signed-off-by: Stéphane Prohaszka <[email protected]>

---------

Signed-off-by: Stéphane Prohaszka <[email protected]>
  • Loading branch information
sprohaszka-ledger committed Jun 21, 2024
1 parent 02f6ec0 commit 2426fa5
Show file tree
Hide file tree
Showing 76 changed files with 8,104 additions and 2,900 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export type ExtraDeviceTransactionField = {
type: "polkadot.validators";
label: string;
};
type DeviceTransactionField = CommonDeviceTransactionField & ExtraDeviceTransactionField;
type DeviceTransactionField = CommonDeviceTransactionField | ExtraDeviceTransactionField;

const getSendFields = ({
transaction,
Expand Down
20 changes: 20 additions & 0 deletions libs/coin-modules/coin-tron/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
env: {
browser: true,
es6: true,
},
overrides: [
{
files: ["src/**/*.test.{ts,tsx}"],
env: {
"jest/globals": true,
},
plugins: ["jest"],
},
],
rules: {
"no-console": ["error", { allow: ["warn", "error"] }],
"@typescript-eslint/no-empty-function": "off",
"@typescript-eslint/no-explicit-any": "warn",
},
};
25 changes: 25 additions & 0 deletions libs/coin-modules/coin-tron/.unimportedrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"entry": [
"src/index.ts",
"src/bridge/index.ts",
"src/network/index.ts",
"src/signer/index.ts"
],
"ignoreUnimported": [
"src/bridge/deviceTransactionConfig.ts",
"src/bridge/transaction.ts",
"src/network/superRepresentativesData.mock.ts",
"src/test/bot-deviceActions.ts",
"src/test/bot-specs.ts",
"src/test/bridgeDatasetTest.ts",
"src/test/cli.ts",
"src/test/index.ts"
],
"ignorePatterns": ["**/node_modules/**", "**/*.fixture.ts", "**/*.mock.ts", "**/*.test.ts"],
"ignoreUnused": [
"@ledgerhq/devices",
"@ledgerhq/live-env",
"expect",
"invariant"
]
}
8 changes: 8 additions & 0 deletions libs/coin-modules/coin-tron/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */
module.exports = {
collectCoverageFrom: ["src/**/*.ts"],
coverageDirectory: "coverage",
preset: "ts-jest",
testEnvironment: "node",
testPathIgnorePatterns: ["lib/", "lib-es/", ".*\\.integ\\.test\\.[tj]s"],
};
7 changes: 7 additions & 0 deletions libs/coin-modules/coin-tron/jest.integ.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */
module.exports = {
preset: "ts-jest",
testEnvironment: "node",
testRegex: ".integ.test.ts$",
testPathIgnorePatterns: ["lib/", "lib-es/"],
};
133 changes: 133 additions & 0 deletions libs/coin-modules/coin-tron/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
{
"name": "@ledgerhq/coin-tron",
"version": "0.0.1",
"description": "Ledger Tron Coin integration",
"keywords": [
"Ledger",
"LedgerWallet",
"trx",
"Tron",
"Hardware Wallet"
],
"repository": {
"type": "git",
"url": "https://github.com/LedgerHQ/ledger-live.git"
},
"bugs": {
"url": "https://github.com/LedgerHQ/ledger-live/issues"
},
"homepage": "https://github.com/LedgerHQ/ledger-live/tree/develop/libs/coin-modules/coin-tron",
"publishConfig": {
"access": "public"
},
"typesVersions": {
"*": {
"lib/*": [
"lib/*"
],
"lib-es/*": [
"lib-es/*"
],
"bridge": [
"lib/bridge/index"
],
"deviceTransactionConfig": [
"lib/bridge/deviceTransactionConfig"
],
"network": [
"lib/network/index"
],
"specs": [
"lib/test/bot-specs"
],
"signer": [
"lib/signer/index"
],
"transaction": [
"lib/bridge/transaction"
],
"types": [
"lib/types/index"
],
"*": [
"lib/*"
]
}
},
"exports": {
"./lib/*": "./lib/*.js",
"./lib-es/*": "./lib-es/*.js",
"./bridge": {
"require": "./lib/bridge/index.js",
"default": "./lib-es/bridge/index.js"
},
"./deviceTransactionConfig": {
"require": "./lib/bridge/deviceTransactionConfig.js",
"default": "./lib-es/bridge/deviceTransactionConfig.js"
},
"./network": {
"require": "./lib/network/index.js",
"default": "./lib-es/network/index.js"
},
"./signer": {
"require": "./lib/signer/index.js",
"default": "./lib-es/signer/index.js"
},
"./specs": {
"require": "./lib/test/bot-specs.js",
"default": "./lib-es/bridge/transaction.js"
},
"./transaction": {
"require": "./lib/bridge/transaction.js",
"default": "./lib-es/bridge/transaction.js"
},
"./*": {
"require": "./lib/*.js",
"default": "./lib-es/*.js"
},
"./package.json": "./package.json"
},
"license": "Apache-2.0",
"dependencies": {
"@ledgerhq/coin-framework": "workspace:^",
"@ledgerhq/cryptoassets": "workspace:^",
"@ledgerhq/devices": "workspace:^",
"@ledgerhq/errors": "workspace:^",
"@ledgerhq/live-env": "workspace:^",
"@ledgerhq/live-network": "workspace:^",
"@ledgerhq/live-promise": "workspace:^",
"@ledgerhq/logs": "workspace:^",
"@ledgerhq/types-live": "workspace:^",
"bignumber.js": "^9.1.2",
"bs58check": "^2.1.2",
"expect": "^27.4.6",
"invariant": "^2.2.2",
"lodash": "^4.17.21",
"rxjs": "^7.8.1",
"tronweb": "^5.3.2"
},
"devDependencies": {
"@agrozyme/types-tronweb": "^5.3.2",
"@types/bs58check": "^2.1.0",
"@types/invariant": "^2.2.2",
"@types/jest": "^29.5.10",
"@types/lodash": "^4.14.191",
"jest": "^29.7.0",
"msw": "^2.0.11",
"ts-jest": "^29.1.1",
"typescript": "^5.4.5"
},
"scripts": {
"clean": "rimraf lib lib-es",
"build": "tsc && tsc -m ES6 --outDir lib-es",
"coverage": "jest --coverage --testPathIgnorePatterns='/bridge.integration.test.ts|node_modules|lib-es|lib/' --passWithNoTests && mv coverage/coverage-final.json coverage/coverage-tron.json",
"prewatch": "pnpm build",
"watch": "tsc --watch",
"doc": "documentation readme src/** --section=API --pe ts --re ts --re d.ts",
"lint": "eslint ./src --no-error-on-unmatched-pattern --ext .ts,.tsx --cache",
"lint:fix": "pnpm lint --fix",
"test": "jest",
"test-integ": "jest --config=jest.integ.config.js",
"unimported": "unimported"
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { AccountBridge } from "@ledgerhq/types-live";
import { broadcastTron } from "./api";
import { Transaction } from "./types";
import { Account, Operation, SignedOperation } from "@ledgerhq/types-live";
import { broadcastTron } from "../network";

export const broadcast: AccountBridge<Transaction>["broadcast"] = async ({
const broadcast = async ({
signedOperation: { signature, operation, rawData },
}) => {
}: {
account: Account;
signedOperation: SignedOperation;
}): Promise<Operation> => {
const transaction = {
raw_data: rawData,
txID: operation.hash,
Expand All @@ -18,3 +20,5 @@ export const broadcast: AccountBridge<Transaction>["broadcast"] = async ({

return operation;
};

export default broadcast;
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import get from "lodash/get";
import BigNumber from "bignumber.js";
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
import { TokenAccount } from "@ledgerhq/types-live";
import BigNumber from "bignumber.js";
import get from "lodash/get";
import { getOperationTypefromMode } from "../logic/utils";
import {
Transaction,
TronAccount,
TronOperation,
TronResource,
TrongridExtraTxInfo,
} from "./types";
import { encodeOperationId } from "../../operation";
import { getOperationTypefromMode } from "./utils";
} from "../types";

const getValue = (
account: TronAccount,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { AccountBridge } from "@ledgerhq/types-live";
import { Transaction } from "./types";
import BigNumber from "bignumber.js";
import { Transaction } from "../types";

export const createTransaction: AccountBridge<Transaction>["createTransaction"] = () => ({
const createTransaction = (): Transaction => ({
family: "tron",
amount: new BigNumber(0),
useAllAmount: false,
Expand All @@ -13,3 +12,5 @@ export const createTransaction: AccountBridge<Transaction>["createTransaction"]
resource: null,
votes: [],
});

export default createTransaction;
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { AccountLike, Account } from "@ledgerhq/types-live";
import type { Transaction, TransactionStatus } from "./types";
import { getMainAccount } from "../../account";
import type { DeviceTransactionField } from "../../transaction";
import { getMainAccount } from "@ledgerhq/coin-framework/account";
import type { CommonDeviceTransactionField } from "@ledgerhq/coin-framework/transaction/common";
import type { Transaction, TransactionStatus } from "../types";

export type ExtraDeviceTransactionField =
| {
Expand All @@ -14,6 +14,8 @@ export type ExtraDeviceTransactionField =
label: string;
};

type DeviceTransactionField = CommonDeviceTransactionField | ExtraDeviceTransactionField;

function getDeviceTransactionConfig({
transaction: { votes, resource, mode, recipient },
account,
Expand Down
32 changes: 32 additions & 0 deletions libs/coin-modules/coin-tron/src/bridge/estimateMaxSpendable.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import BigNumber from "bignumber.js";
import { getMainAccount } from "@ledgerhq/coin-framework/account";
import { AccountBridge } from "@ledgerhq/types-live";
import { fetchTronContract } from "../network";
import { Transaction, TronAccount } from "../types";
import createTransaction from "./createTransaction";
import getEstimatedFees from "./getEstimateFees";

const estimateMaxSpendable: AccountBridge<
Transaction,
TronAccount
>["estimateMaxSpendable"] = async ({ account, parentAccount, transaction }): Promise<BigNumber> => {
const mainAccount = getMainAccount(account, parentAccount);
const fees = await getEstimatedFees(
mainAccount,
{
...createTransaction(),
subAccountId: account.type === "Account" ? null : account.id,
...transaction,
recipient: transaction?.recipient || "0x0000000000000000000000000000000000000000",
amount: new BigNumber(0),
},
transaction && transaction.recipient
? (await fetchTronContract(transaction.recipient)) !== undefined
: false,
);
return account.type === "Account"
? BigNumber.max(0, account.spendableBalance.minus(fees))
: account.balance;
};

export default estimateMaxSpendable;
Loading

0 comments on commit 2426fa5

Please sign in to comment.