Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LIVE-13681 chore: move stacks to its own module #8163

Open
wants to merge 51 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
51 commits
Select commit Hold shift + click to select a range
2e16e4f
chore: move to own module
Wozacosta Oct 22, 2024
6fab5ac
move to src
Wozacosta Oct 22, 2024
1b2b23e
config files for stacks module
Wozacosta Oct 22, 2024
7a66e1e
separate bridge test into dataset & test, fix package.json requires
Wozacosta Oct 23, 2024
b3d9e88
config files
Wozacosta Oct 23, 2024
83fd41e
devicetransactionconfig
Wozacosta Oct 23, 2024
d8408bb
bot specs + some imports fix
Wozacosta Oct 23, 2024
f368ec5
move c32check dep
Wozacosta Oct 23, 2024
12b8ed2
bot-deviceAction + pnpmlock
Wozacosta Oct 23, 2024
acd65de
some more import fixes + utils inlined
Wozacosta Oct 23, 2024
cf08bef
some more import fixes
Wozacosta Oct 23, 2024
0a23c28
some missing packages
Wozacosta Oct 23, 2024
a6f3a2e
critical coin-stacks in llc
Wozacosta Oct 23, 2024
f121fa7
resolver
Wozacosta Oct 23, 2024
4741e39
bridge + signer
Wozacosta Oct 23, 2024
cd6ee3a
signOperation
Wozacosta Oct 23, 2024
2f22217
signMessage
Wozacosta Oct 23, 2024
45f18d6
cli
Wozacosta Oct 23, 2024
a32b2f3
errors & types passthrough
Wozacosta Oct 23, 2024
d3ea9b4
fix types import
Wozacosta Oct 23, 2024
23375be
add stacks to sync-families-dispatch
Wozacosta Oct 23, 2024
3e2c02e
jest.config and tsconfig
Wozacosta Oct 23, 2024
6c7b90d
fix typos
Wozacosta Oct 23, 2024
d78de22
fix imports + types defined in package.json
Wozacosta Oct 23, 2024
a610a00
tsconfig es2021 + cli fix
Wozacosta Oct 23, 2024
cea05b1
major fixes following boilerplate
Wozacosta Oct 23, 2024
aafdd42
fix errors import
Wozacosta Oct 23, 2024
06649f4
fix errors import frontend
Wozacosta Oct 23, 2024
c7219f0
lint
Wozacosta Oct 23, 2024
467bc2a
lint #2
Wozacosta Oct 23, 2024
57b31ac
unimported
Wozacosta Oct 23, 2024
6594c3b
remove coin-stacks lld
Wozacosta Oct 23, 2024
323cf14
revert to original array access to stacksnetwork
Wozacosta Oct 24, 2024
8afe1b3
cleanup signer.ts
Wozacosta Oct 24, 2024
3d8ef47
add note about shared code utils
Wozacosta Oct 25, 2024
e2ec26d
revert coin-xrp newline in package.json
Wozacosta Oct 25, 2024
3c48a46
changeset
Wozacosta Oct 25, 2024
393c40a
follow boilerplate structure
Wozacosta Oct 25, 2024
7c21a61
fix api import
Wozacosta Oct 25, 2024
8afae50
lint
Wozacosta Oct 25, 2024
7af510b
missing sign message
Wozacosta Oct 28, 2024
d8b9684
rebase + regenerate pnpm-lock
Wozacosta Oct 29, 2024
000f340
test updated pnpm-lock #2
Wozacosta Oct 29, 2024
c803325
map hw-signmessage to file
Wozacosta Oct 29, 2024
23f20b6
sort imports
Wozacosta Oct 29, 2024
ff6f476
network index
Wozacosta Oct 29, 2024
f39e9ae
remove /
Wozacosta Oct 29, 2024
d0b7130
remove types-cryptoassets import
Wozacosta Oct 29, 2024
57ded9c
use dep types-cryptoassets
Wozacosta Oct 30, 2024
93995cf
lint
Wozacosta Oct 30, 2024
2c11c62
unused
Wozacosta Oct 30, 2024
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
7 changes: 7 additions & 0 deletions .changeset/ten-pigs-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"@ledgerhq/coin-stacks": patch
"live-mobile": patch
"@ledgerhq/live-common": patch
---

support: move stacks to its own coin module
1 change: 1 addition & 0 deletions apps/ledger-live-mobile/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
"@ledgerhq/coin-elrond": "workspace:^",
"@ledgerhq/coin-evm": "workspace:^",
"@ledgerhq/coin-framework": "workspace:^",
"@ledgerhq/coin-stacks": "workspace:^",
"@ledgerhq/devices": "workspace:*",
"@ledgerhq/domain-service": "workspace:^",
"@ledgerhq/errors": "workspace:^",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import invariant from "invariant";
import React from "react";
import { StyleSheet } from "react-native";
import type { Transaction } from "@ledgerhq/live-common/generated/types";
import { ExtraDeviceTransactionField } from "@ledgerhq/live-common/families/stacks/deviceTransactionConfig";
import { DeviceTransactionField } from "@ledgerhq/live-common/transaction/index";
import { ExtraDeviceTransactionField } from "@ledgerhq/coin-stacks/deviceTransactionConfig";
import LText from "~/components/LText";
import { DataRow } from "~/components/ValidateOnDeviceDataRow";

Expand Down
20 changes: 20 additions & 0 deletions libs/coin-modules/coin-stacks/.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",
},
};
31 changes: 31 additions & 0 deletions libs/coin-modules/coin-stacks/.unimportedrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"entry": [
"src/api/index.ts",
"src/bridge/index.ts",
"src/bridge/deviceTransactionConfig.ts",
"src/datasets/dataset-1.ts",
"src/signer/index.ts",
"src/test/index.ts",
"src/index.ts"
],
"ignorePatterns": [
"**/node_modules/**",
"**/*.fixture.ts",
"**/*.mock.ts",
"**/*.test.{js,jsx,ts,tsx}"
],
"ignoreUnresolved": [
"jest-get-type",
"jest-matcher-utils",
"jest-message-util"
],
"ignoreUnimported": [
"src/network/index.ts",
"src/signer/signMessage.ts"
],
"ignoreUnused": [
"@ledgerhq/types-cryptoassets",
"ripple-address-codec",
"ripple-binary-codec"
]
}
8 changes: 8 additions & 0 deletions libs/coin-modules/coin-stacks/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/", ".integration.test.ts"]
};
136 changes: 136 additions & 0 deletions libs/coin-modules/coin-stacks/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
{
"name": "@ledgerhq/coin-stacks",
"version": "0.1.0",
"description": "Ledger Stacks Coin integration",
"keywords": [
"Ledger",
"LedgerWallet",
"stacks",
"stx",
"Bitcoin layer2",
"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-stacks",
"publishConfig": {
"access": "public"
},
"typesVersions": {
"*": {
"lib/*": [
"lib/*"
],
"lib-es/*": [
"lib-es/*"
],
"deviceTransactionConfig": [
"lib/bridge/deviceTransactionConfig"
],
"specs": [
"lib/test/bot-specs"
],
"transaction": [
"lib/bridge/transaction"
],
"*": [
"lib/*"
]
}
},
"exports": {
"./lib/*": "./lib/*.js",
"./lib-es/*": "./lib-es/*.js",
"./api": {
"require": "./lib/api/index.js",
"default": "./lib-es/api/index.js"
},
"./deviceTransactionConfig": {
"require": "./lib/bridge/deviceTransactionConfig.js",
"default": "./lib-es/bridge/deviceTransactionConfig.js"
},
"./signer": {
"require": "./lib/signer/index.js",
"default": "./lib-es/signer/index.js"
},
"./hw-signMessage": {
"require": "./lib/signer/signMessage.js",
"default": "./lib-es/signer/signMessage.js"
},
"./specs": {
"require": "./lib/test/bot-specs.js",
"default": "./lib-es/test/bot-specs.js"
},
"./transaction": {
"require": "./lib/bridge/transaction.js",
"default": "./lib-es/bridge/transaction.js"
},
"./types": {
"require": "./lib/types/index.js",
"default": "./lib-es/types/index.js"
},
"./*": {
"require": "./lib/*.js",
"default": "./lib-es/*.js"
},
".": {
"require": "./lib/index.js",
"default": "./lib-es/index.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/logs": "workspace:^",
"@ledgerhq/types-cryptoassets": "workspace:^",
"@ledgerhq/types-live": "workspace:^",
"axios": "1.7.7",
"bignumber.js": "^9.1.2",
"c32check": "1.1.3",
"invariant": "^2.2.4",
"lodash": "^4.17.21",
"ripple-address-codec": "^5.0.0",
"ripple-binary-codec": "^1.3.0",
"rxjs": "^7.8.1",
"@stacks/network": "6.10.0",
"@stacks/transactions": "6.11.0",
"@zondax/ledger-stacks": "^1.0.2"
},
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@types/invariant": "^2.2.37",
"@types/jest": "^29.5.12",
"@types/lodash": "^4.14.191",
"dotenv": "^16.4.5",
"expect": "^27.4.6",
"jest": "^29.7.0",
"ripple-keypairs": "^2.0.0",
"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-stacks.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": "DOTENV_CONFIG_PATH=.env.integ.test jest --config=jest.integ.config.js",
"typecheck": "tsc --noEmit",
"unimported": "unimported"
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import invariant from "invariant";
import { AccountBridge } from "@ledgerhq/types-live";
import { patchOperationWithHash } from "@ledgerhq/coin-framework/operation";
import { StacksOperation, Transaction } from "./types";
import { getTxToBroadcast } from "./bridge/utils/misc";
import { broadcastTx } from "./bridge/utils/api";
import { AccountBridge } from "@ledgerhq/types-live";
import invariant from "invariant";
import { broadcastTx } from "../network/api";
import { StacksOperation, Transaction } from "../types";
import { getTxToBroadcast } from "./utils/misc";

export const broadcast: AccountBridge<Transaction>["broadcast"] = async ({
signedOperation: { operation, signature, rawData },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import BigNumber from "bignumber.js";
import { Account, OperationType } from "@ledgerhq/types-live";
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
import { StacksOperation, Transaction } from "./types";
import { getAddress } from "./bridge/utils/misc";
import { Account, OperationType } from "@ledgerhq/types-live";
import BigNumber from "bignumber.js";
import { StacksOperation, Transaction } from "../types";
import { getAddress } from "./utils/misc";

export const buildOptimisticOperation = (
account: Account,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { AccountBridge } from "@ledgerhq/types-live";
import { Transaction } from "./types";
import BigNumber from "bignumber.js";
import { AnchorMode } from "@stacks/transactions";
import BigNumber from "bignumber.js";
import { Transaction } from "../types";

export const createTransaction: AccountBridge<Transaction>["createTransaction"] = () => ({
family: "stacks",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { BigNumber } from "bignumber.js";
import type { CommonDeviceTransactionField } from "@ledgerhq/coin-framework/transaction/common";
import type { Account, AccountLike } from "@ledgerhq/types-live";
import type { DeviceTransactionField } from "../../transaction";
import type { Transaction, TransactionStatus } from "./types";
import { BigNumber } from "bignumber.js";
import type { Transaction, TransactionStatus } from "../types";

export type ExtraDeviceTransactionField =
| {
Expand All @@ -15,6 +15,8 @@ export type ExtraDeviceTransactionField =
value: BigNumber;
};

export type DeviceTransactionField = CommonDeviceTransactionField | ExtraDeviceTransactionField;

function getDeviceTransactionConfig(input: {
account: AccountLike;
parentAccount: Account | null | undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { getMainAccount } from "@ledgerhq/coin-framework/account/index";
import { getAbandonSeedAddress } from "@ledgerhq/cryptoassets/abandonseed";
import { AccountBridge } from "@ledgerhq/types-live";
import { StacksMainnet } from "@stacks/network";
import {
UnsignedTokenTransferOptions,
estimateTransaction,
makeUnsignedSTXTokenTransfer,
} from "@stacks/transactions";
import invariant from "invariant";
import BigNumber from "bignumber.js";
import { StacksMainnet } from "@stacks/network";
import { AccountBridge } from "@ledgerhq/types-live";
import { getMainAccount } from "@ledgerhq/coin-framework/account/index";
import { getAbandonSeedAddress } from "@ledgerhq/cryptoassets/abandonseed";
import invariant from "invariant";
import { StacksNetwork } from "../network/api.types";
import { Transaction } from "../types";
import { createTransaction } from "./createTransaction";
import { StacksNetwork } from "./bridge/utils/api.types";
import { Transaction } from "./types";

export const estimateMaxSpendable: AccountBridge<Transaction>["estimateMaxSpendable"] = async ({
account,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@ import {
NotEnoughBalance,
RecipientRequired,
} from "@ledgerhq/errors";
import BigNumber from "bignumber.js";
import { AccountBridge } from "@ledgerhq/types-live";
import { Transaction, TransactionStatus } from "./types";
import { validateAddress } from "./bridge/utils/addresses";
import { getAddress } from "./bridge/utils/misc";
import { StacksMemoTooLong } from "./errors";
import BigNumber from "bignumber.js";
import { StacksMemoTooLong } from "../errors";
import { Transaction, TransactionStatus } from "../types";
import { validateAddress } from "./utils/addresses";
import { getAddress } from "./utils/misc";

export const getTransactionStatus: AccountBridge<Transaction>["getTransactionStatus"] = async (
account,
Expand Down
64 changes: 64 additions & 0 deletions libs/coin-modules/coin-stacks/src/bridge/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import {
makeAccountBridgeReceive,
makeScanAccounts,
makeSync,
} from "@ledgerhq/coin-framework/bridge/jsHelpers";
import resolver from "../signer/index";
import getAddressWrapper from "@ledgerhq/coin-framework/bridge/getAddressWrapper";
import { SignerContext } from "@ledgerhq/coin-framework/signer";
import type { Account, AccountBridge, CurrencyBridge } from "@ledgerhq/types-live";
import { defaultUpdateTransaction } from "@ledgerhq/coin-framework/bridge/jsHelpers";
import type { Transaction, TransactionStatus, StacksSigner } from "../types";
import { getTransactionStatus } from "./getTransactionStatus";
import { estimateMaxSpendable } from "./estimateMaxSpendable";
import { prepareTransaction } from "./prepareTransaction";
import { createTransaction } from "./createTransaction";
import { getAccountShape } from "./synchronization";
import { buildSignOperation } from "./signOperation";
import { broadcast } from "./broadcast";

function buildCurrencyBridge(signerContext: SignerContext<StacksSigner>): CurrencyBridge {
const getAddress = resolver(signerContext);

const scanAccounts = makeScanAccounts({
getAccountShape,
getAddressFn: getAddressWrapper(getAddress),
});

return {
preload: () => Promise.resolve({}),
hydrate: () => {},
scanAccounts,
};
}

const sync = makeSync({ getAccountShape });

function buildAccountBridge(
signerContext: SignerContext<StacksSigner>,
): AccountBridge<Transaction, Account, TransactionStatus> {
const getAddress = resolver(signerContext);
const receive = makeAccountBridgeReceive(getAddressWrapper(getAddress));

const signOperation = buildSignOperation(signerContext);

return {
estimateMaxSpendable,
createTransaction,
updateTransaction: defaultUpdateTransaction,
getTransactionStatus,
prepareTransaction,
sync,
receive,
signOperation,
broadcast,
};
}

export function createBridges(signerContext: SignerContext<StacksSigner>) {
return {
currencyBridge: buildCurrencyBridge(signerContext),
accountBridge: buildAccountBridge(signerContext),
};
}
export { prepareTransaction, estimateMaxSpendable };
Loading
Loading