@ledgerhq/coin-algorand 0.2.0-next.0

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.
package/.eslintrc.js ADDED
@@ -0,0 +1,57 @@
1
+ module.exports = {
2
+ parser: "@typescript-eslint/parser",
3
+ env: {
4
+ browser: true,
5
+ es6: true,
6
+ node: true,
7
+ jest: true,
8
+ },
9
+ extends: [
10
+ "eslint:recommended",
11
+ "plugin:@typescript-eslint/eslint-recommended",
12
+ "plugin:@typescript-eslint/recommended",
13
+ "prettier",
14
+ ],
15
+ globals: {
16
+ Atomics: "readonly",
17
+ SharedArrayBuffer: "readonly",
18
+ },
19
+ plugins: ["@typescript-eslint", "prettier"],
20
+ rules: {
21
+ "no-console": ["error", { allow: ["warn", "error"] }],
22
+ "linebreak-style": ["error", "unix"],
23
+ semi: ["error", "always"],
24
+ "no-unused-vars": "off",
25
+ "import/prefer-default-export": 0,
26
+ "no-plusplus": 0,
27
+ "no-underscore-dangle": 0,
28
+ "prefer-template": 0,
29
+ "no-await-in-loop": 0,
30
+ "no-restricted-syntax": 0,
31
+ "consistent-return": 0,
32
+ "no-lonely-if": 0,
33
+ "no-use-before-define": 0,
34
+ "no-nested-ternary": 0,
35
+ "import/no-cycle": 0,
36
+ "no-multi-assign": 0,
37
+ "guard-for-in": 0,
38
+ "no-continue": 0,
39
+ "lines-between-class-members": 0,
40
+ "prefer-destructuring": 0,
41
+ "prettier/prettier": "error",
42
+ "@typescript-eslint/no-use-before-define": "off",
43
+ "@typescript-eslint/no-unused-vars": ["error", { argsIgnorePattern: "^_" }],
44
+ "@typescript-eslint/no-empty-function": "off",
45
+ "@typescript-eslint/no-namespace": ["error", { allowDeclarations: true }],
46
+ "@typescript-eslint/no-explicit-any": 0,
47
+ "@typescript-eslint/ban-types": [
48
+ "error",
49
+ {
50
+ extendDefaults: true,
51
+ types: {
52
+ "{}": false,
53
+ },
54
+ },
55
+ ],
56
+ },
57
+ };
@@ -0,0 +1,4 @@
1
+
2
+ > @ledgerhq/coin-algorand@0.1.0 build /home/runner/work/ledger-live/ledger-live/libs/coin-algorand
3
+ > tsc && tsc -m ES6 --outDir lib-es
4
+
package/CHANGELOG.md ADDED
@@ -0,0 +1,18 @@
1
+ # @ledgerhq/coin-algorand
2
+
3
+ ## 0.2.0-next.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#3306](https://github.com/LedgerHQ/ledger-live/pull/3306) [`77f990e207`](https://github.com/LedgerHQ/ledger-live/commit/77f990e2075c7c9a4be69b364e3754b449c7a546) Thanks [@chabroA](https://github.com/chabroA)! - Move algorand coin logic in own package
8
+
9
+ ### Patch Changes
10
+
11
+ - Updated dependencies [[`77f990e207`](https://github.com/LedgerHQ/ledger-live/commit/77f990e2075c7c9a4be69b364e3754b449c7a546), [`817a8dd811`](https://github.com/LedgerHQ/ledger-live/commit/817a8dd8112ff7c4640852ab4e47ea0436df2ec1), [`77f990e207`](https://github.com/LedgerHQ/ledger-live/commit/77f990e2075c7c9a4be69b364e3754b449c7a546), [`22491091f7`](https://github.com/LedgerHQ/ledger-live/commit/22491091f7b4e06ee6a0cdf964498aa5b08d6eb0), [`745fbf2a54`](https://github.com/LedgerHQ/ledger-live/commit/745fbf2a54cdc34aea938d7fbe4c8b198dc36b54), [`7cf49e1919`](https://github.com/LedgerHQ/ledger-live/commit/7cf49e1919466836e9025693ed07b18ebf99041a)]:
12
+ - @ledgerhq/errors@6.12.6-next.0
13
+ - @ledgerhq/cryptoassets@9.6.0-next.0
14
+ - @ledgerhq/coin-framework@0.3.4-next.0
15
+ - @ledgerhq/live-env@0.3.0-next.0
16
+ - @ledgerhq/types-live@6.34.1-next.0
17
+ - @ledgerhq/devices@8.0.3-next.0
18
+ - @ledgerhq/hw-app-algorand@6.27.15-next.0
package/jest.config.js ADDED
@@ -0,0 +1,6 @@
1
+ /** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
2
+ module.exports = {
3
+ preset: "ts-jest",
4
+ testEnvironment: "node",
5
+ testPathIgnorePatterns: ["lib/", "lib-es/"],
6
+ };
package/package.json ADDED
@@ -0,0 +1,92 @@
1
+ {
2
+ "name": "@ledgerhq/coin-algorand",
3
+ "version": "0.2.0-next.0",
4
+ "description": "Ledger Algorand Coin integration",
5
+ "keywords": [
6
+ "Ledger",
7
+ "LedgerWallet",
8
+ "algo",
9
+ "Algorand",
10
+ "Hardware Wallet"
11
+ ],
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "https://github.com/LedgerHQ/ledger-live.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/LedgerHQ/ledger-live/issues"
18
+ },
19
+ "homepage": "https://github.com/LedgerHQ/ledger-live/tree/develop/libs/coin-algorand",
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "typesVersions": {
24
+ "*": {
25
+ "lib/*": [
26
+ "lib/*"
27
+ ],
28
+ "lib-es/*": [
29
+ "lib-es/*"
30
+ ],
31
+ "*": [
32
+ "lib/*"
33
+ ]
34
+ }
35
+ },
36
+ "exports": {
37
+ "./lib/*": "./lib/*.js",
38
+ "./lib-es/*": "./lib-es/*.js",
39
+ "./*": {
40
+ "require": "./lib/*.js",
41
+ "default": "./lib-es/*.js"
42
+ },
43
+ "./package.json": "./package.json"
44
+ },
45
+ "license": "Apache-2.0",
46
+ "dependencies": {
47
+ "algo-msgpack-with-bigint": "^2.1.1",
48
+ "algosdk": "1.13.0",
49
+ "bignumber.js": "^9.1.0",
50
+ "expect": "^27.4.6",
51
+ "invariant": "^2.2.2",
52
+ "lodash": "^4.17.21",
53
+ "prando": "^6.0.1",
54
+ "rxjs": "^6.6.7",
55
+ "@ledgerhq/coin-framework": "^0.3.4-next.0",
56
+ "@ledgerhq/cryptoassets": "^9.6.0-next.0",
57
+ "@ledgerhq/devices": "^8.0.3-next.0",
58
+ "@ledgerhq/errors": "^6.12.6-next.0",
59
+ "@ledgerhq/hw-app-algorand": "^6.27.15-next.0",
60
+ "@ledgerhq/live-env": "^0.3.0-next.0",
61
+ "@ledgerhq/live-promise": "^0.0.1",
62
+ "@ledgerhq/types-cryptoassets": "^7.2.0",
63
+ "@ledgerhq/types-live": "^6.34.1-next.0"
64
+ },
65
+ "devDependencies": {
66
+ "@types/invariant": "^2.2.2",
67
+ "@types/jest": "^29.2.4",
68
+ "@types/lodash": "^4.14.191",
69
+ "@typescript-eslint/eslint-plugin": "^5.46.1",
70
+ "@typescript-eslint/parser": "^5.46.1",
71
+ "eslint": "^7.32.0",
72
+ "eslint-config-prettier": "^8.3.0",
73
+ "eslint-config-typescript": "^3.0.0",
74
+ "eslint-formatter-pretty": "^3.0.1",
75
+ "eslint-plugin-prettier": "^3.4.0",
76
+ "eslint-plugin-typescript": "^0.14.0",
77
+ "jest": "^28.1.1",
78
+ "prettier": "^2.8.1",
79
+ "ts-jest": "^28.0.5",
80
+ "typescript": "^4.9.5"
81
+ },
82
+ "scripts": {
83
+ "clean": "rimraf lib lib-es",
84
+ "build": "tsc && tsc -m ES6 --outDir lib-es",
85
+ "prewatch": "pnpm build",
86
+ "watch": "tsc --watch",
87
+ "doc": "documentation readme src/** --section=API --pe ts --re ts --re d.ts",
88
+ "lint": "eslint ./src --no-error-on-unmatched-pattern --ext .ts,.tsx",
89
+ "lint:fix": "pnpm lint --fix",
90
+ "test": "jest"
91
+ }
92
+ }
package/src/account.ts ADDED
@@ -0,0 +1,76 @@
1
+ import { getAccountUnit } from "@ledgerhq/coin-framework/account/index";
2
+ import { formatCurrencyUnit } from "@ledgerhq/coin-framework/currencies/index";
3
+ import type { Unit } from "@ledgerhq/types-cryptoassets";
4
+ import type { Account, Operation } from "@ledgerhq/types-live";
5
+ import { BigNumber } from "bignumber.js";
6
+ import invariant from "invariant";
7
+ import type { AlgorandAccount, AlgorandResources } from "./types";
8
+
9
+ function formatOperationSpecifics(
10
+ op: Operation,
11
+ unit: Unit | null | undefined
12
+ ): string {
13
+ const { rewards } = op.extra;
14
+ return rewards
15
+ ? " REWARDS : " +
16
+ `${
17
+ unit
18
+ ? formatCurrencyUnit(unit, new BigNumber(rewards), {
19
+ showCode: true,
20
+ disableRounding: true,
21
+ }).padEnd(16)
22
+ : rewards
23
+ }`
24
+ : "";
25
+ }
26
+
27
+ function formatAccountSpecifics(account: Account): string {
28
+ const { algorandResources } = account as AlgorandAccount;
29
+ invariant(algorandResources, "algorand account expected");
30
+ const unit = getAccountUnit(account);
31
+ const formatConfig = {
32
+ disableRounding: true,
33
+ alwaysShowSign: false,
34
+ showCode: true,
35
+ };
36
+ let str = " ";
37
+ str +=
38
+ formatCurrencyUnit(unit, account.spendableBalance, formatConfig) +
39
+ " spendable. ";
40
+
41
+ if ((algorandResources as AlgorandResources).rewards.gt(0)) {
42
+ str +=
43
+ formatCurrencyUnit(
44
+ unit,
45
+ (algorandResources as AlgorandResources).rewards,
46
+ formatConfig
47
+ ) + " rewards. ";
48
+ }
49
+
50
+ return str;
51
+ }
52
+
53
+ export function fromOperationExtraRaw(
54
+ extra: Record<string, any> | null | undefined
55
+ ) {
56
+ if (extra && extra.rewards) {
57
+ return { ...extra, rewards: new BigNumber(extra.rewards) };
58
+ }
59
+
60
+ return extra;
61
+ }
62
+ export function toOperationExtraRaw(
63
+ extra: Record<string, any> | null | undefined
64
+ ) {
65
+ if (extra && extra.rewards) {
66
+ return { ...extra, rewards: extra.rewards.toString() };
67
+ }
68
+
69
+ return extra;
70
+ }
71
+ export default {
72
+ formatAccountSpecifics,
73
+ formatOperationSpecifics,
74
+ fromOperationExtraRaw,
75
+ toOperationExtraRaw,
76
+ };
@@ -0,0 +1,71 @@
1
+ import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
2
+ import { getEnv } from "@ledgerhq/live-env";
3
+ import { BigNumber } from "bignumber.js";
4
+ import {
5
+ AlgoAccount,
6
+ AlgoAsset,
7
+ AlgoTransactionBroadcastResponse,
8
+ AlgoTransactionParams,
9
+ } from "./algodv2.types";
10
+
11
+ const BASE_URL = getEnv("API_ALGORAND_BLOCKCHAIN_EXPLORER_API_ENDPOINT");
12
+ const NODE_URL = `${BASE_URL}/ps2/v2`;
13
+
14
+ const fullUrl = (route: string): string => `${NODE_URL}${route}`;
15
+
16
+ export const getAccount =
17
+ (network: NetworkRequestCall) =>
18
+ async (address: string): Promise<AlgoAccount> => {
19
+ const { data } = await network({
20
+ method: "GET",
21
+ url: fullUrl(`/accounts/${address}`),
22
+ });
23
+
24
+ const assets: AlgoAsset[] = data.assets
25
+ ? // FIXME: what is the type of `a`?
26
+ data.assets.map((a: any): AlgoAsset => {
27
+ return {
28
+ assetId: a["asset-id"].toString(),
29
+ balance: new BigNumber(a.amount),
30
+ };
31
+ })
32
+ : [];
33
+
34
+ return {
35
+ round: data.round,
36
+ address: data.address,
37
+ balance: new BigNumber(data.amount),
38
+ pendingRewards: new BigNumber(data["pending-rewards"]),
39
+ assets,
40
+ };
41
+ };
42
+
43
+ export const getTransactionParams =
44
+ (network: NetworkRequestCall) => async (): Promise<AlgoTransactionParams> => {
45
+ const { data } = await network({
46
+ method: "GET",
47
+ url: fullUrl(`/transactions/params`),
48
+ });
49
+
50
+ return {
51
+ fee: data["fee"],
52
+ minFee: data["min-fee"],
53
+ firstRound: data["first-round"] ?? 0,
54
+ lastRound: data["last-round"],
55
+ genesisID: data["genesis-id"],
56
+ genesisHash: data["genesis-hash"],
57
+ };
58
+ };
59
+
60
+ export const broadcastTransaction =
61
+ (network: NetworkRequestCall) =>
62
+ async (payload: Buffer): Promise<string> => {
63
+ const { data }: { data: AlgoTransactionBroadcastResponse } = await network({
64
+ method: "POST",
65
+ url: fullUrl(`/transactions`),
66
+ data: payload,
67
+ headers: { "Content-Type": "application/x-binary" },
68
+ });
69
+
70
+ return data.txId;
71
+ };
@@ -0,0 +1,27 @@
1
+ import { BigNumber } from "bignumber.js";
2
+
3
+ export interface AlgoAccount {
4
+ round: number;
5
+ address: string;
6
+ balance: BigNumber;
7
+ pendingRewards: BigNumber;
8
+ assets: AlgoAsset[];
9
+ }
10
+
11
+ export interface AlgoAsset {
12
+ assetId: string;
13
+ balance: BigNumber;
14
+ }
15
+
16
+ export interface AlgoTransactionParams {
17
+ fee: number;
18
+ minFee: number;
19
+ firstRound: number;
20
+ lastRound: number;
21
+ genesisHash: string;
22
+ genesisID: string;
23
+ }
24
+
25
+ export interface AlgoTransactionBroadcastResponse {
26
+ txId: string;
27
+ }
@@ -0,0 +1,41 @@
1
+ import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
2
+ import { AlgoAccount, AlgoTransactionParams } from "./algodv2.types";
3
+
4
+ import {
5
+ broadcastTransaction,
6
+ getAccount,
7
+ getTransactionParams,
8
+ } from "./algodv2";
9
+
10
+ import { getAccountTransactions } from "./indexer";
11
+ import { AlgoTransaction } from "./indexer.types";
12
+
13
+ export * from "./algodv2.types";
14
+ export * from "./indexer.types";
15
+
16
+ export class AlgorandAPI {
17
+ network: NetworkRequestCall;
18
+
19
+ constructor(network: NetworkRequestCall) {
20
+ this.network = network;
21
+ }
22
+
23
+ async getAccount(address: string): Promise<AlgoAccount> {
24
+ return getAccount(this.network)(address);
25
+ }
26
+
27
+ async getTransactionParams(): Promise<AlgoTransactionParams> {
28
+ return getTransactionParams(this.network)();
29
+ }
30
+
31
+ async broadcastTransaction(payload: Buffer): Promise<string> {
32
+ return broadcastTransaction(this.network)(payload);
33
+ }
34
+
35
+ async getAccountTransactions(
36
+ address: string,
37
+ startAt?: number
38
+ ): Promise<AlgoTransaction[]> {
39
+ return getAccountTransactions(this.network)(address, startAt);
40
+ }
41
+ }
@@ -0,0 +1,102 @@
1
+ import { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
2
+ import { getEnv } from "@ledgerhq/live-env";
3
+ import { BigNumber } from "bignumber.js";
4
+ import {
5
+ AlgoAssetTransferInfo,
6
+ AlgoPaymentInfo,
7
+ AlgoTransaction,
8
+ AlgoTransactionDetails,
9
+ } from "./indexer.types";
10
+
11
+ const LIMIT = 100; // Max nb of transactions per request
12
+
13
+ const BASE_URL = getEnv("API_ALGORAND_BLOCKCHAIN_EXPLORER_API_ENDPOINT");
14
+ const INDEXER_URL = `${BASE_URL}/idx2/v2`;
15
+
16
+ const fullUrl = (route: string): string =>
17
+ `${INDEXER_URL}${route}?limit=${LIMIT}`;
18
+
19
+ export const getAccountTransactions =
20
+ (network: NetworkRequestCall) =>
21
+ async (address: string, startAt?: number): Promise<AlgoTransaction[]> => {
22
+ const url = fullUrl(`/accounts/${address}/transactions`);
23
+
24
+ let nextToken: string | undefined;
25
+ let newRawTxs: any[] = [];
26
+ const mergedTxs: AlgoTransaction[] = [];
27
+ do {
28
+ let nextUrl: string = url;
29
+ if (startAt) {
30
+ nextUrl = nextUrl.concat(`&min-round=${startAt}`);
31
+ }
32
+ if (nextToken) {
33
+ nextUrl = nextUrl.concat(`&next=${nextToken}`);
34
+ }
35
+ const { data }: { data: { transactions: any[] } } = await network({
36
+ method: "GET",
37
+ url: nextUrl,
38
+ });
39
+
40
+ // FIXME: what is the correct type? Properly type response from api above (data)
41
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
42
+ // @ts-ignore
43
+ nextToken = data["next-token"];
44
+ newRawTxs = data.transactions;
45
+ newRawTxs.map(parseRawTransaction).forEach((tx) => mergedTxs.push(tx));
46
+ } while (newRawTxs.length >= LIMIT);
47
+
48
+ return mergedTxs;
49
+ };
50
+
51
+ const parseRawTransaction = (tx: any): AlgoTransaction => {
52
+ let details: AlgoTransactionDetails | undefined = undefined;
53
+ if (tx["tx-type"] === "pay") {
54
+ const info = tx["payment-transaction"];
55
+ const paymentInfo: AlgoPaymentInfo = {
56
+ amount: new BigNumber(info.amount),
57
+ recipientAddress: info.receiver,
58
+ closeAmount:
59
+ info["close-amount"] === undefined
60
+ ? undefined
61
+ : new BigNumber(info["close-amount"]),
62
+ closeToAddress: info["close-remainder-to"],
63
+ };
64
+ details = paymentInfo;
65
+ } else if (tx["tx-type"] === "axfer") {
66
+ const info = tx["asset-transfer-transaction"];
67
+ const assetTransferInfo: AlgoAssetTransferInfo = {
68
+ assetAmount: new BigNumber(info.amount),
69
+ assetId: info["asset-id"],
70
+ assetRecipientAddress: info.receiver,
71
+ assetSenderAddress: info.sender,
72
+ assetCloseAmount:
73
+ info["close-amount"] === undefined
74
+ ? undefined
75
+ : new BigNumber(info["close-amount"]),
76
+ assetCloseToAddress: tx["close-to"],
77
+ };
78
+ details = assetTransferInfo;
79
+ }
80
+
81
+ return {
82
+ id: tx.id,
83
+ timestamp: tx["round-time"],
84
+ round: tx["confirmed-round"],
85
+ senderAddress: tx.sender,
86
+ senderRewards: new BigNumber(tx["sender-rewards"]),
87
+ recipientRewards: new BigNumber(tx["receiver-rewards"]),
88
+ closeRewards:
89
+ tx["close-rewards"] === undefined
90
+ ? undefined
91
+ : new BigNumber(tx["close-rewards"]),
92
+ closeAmount:
93
+ tx["closing-amount"] === undefined
94
+ ? undefined
95
+ : new BigNumber(tx["closing-amount"]),
96
+ fee: new BigNumber(tx.fee),
97
+ note: tx.note,
98
+
99
+ type: tx["tx-type"],
100
+ details,
101
+ };
102
+ };
@@ -0,0 +1,41 @@
1
+ import { BigNumber } from "bignumber.js";
2
+
3
+ export type AlgoTransactionDetails = AlgoPaymentInfo | AlgoAssetTransferInfo;
4
+
5
+ // Define only types we explicitely support
6
+ export enum AlgoTransactionType {
7
+ PAYMENT = "pay",
8
+ ASSET_TRANSFER = "axfer",
9
+ }
10
+
11
+ export interface AlgoTransaction {
12
+ id: string;
13
+ timestamp: string; // 'round-time': 1597933539,
14
+ round: number; // 'confirmed-round': 8575676,
15
+ senderAddress: string; // sender: 'RGX5XA7DWZOZ5SLG4WQSNIFKIG4CNX4VOH23YCEX56523DQEAL3QL56XZM',
16
+ senderRewards: BigNumber; // 'sender-rewards': 0,
17
+ recipientRewards: BigNumber; //'receiver-rewards': 0,
18
+ closeRewards?: BigNumber; // 'close-rewards': 0,
19
+ closeAmount?: BigNumber; //'closing-amount': 0,
20
+ fee: BigNumber;
21
+ note: string;
22
+
23
+ type: string; // 'tx-type': 'pay'
24
+ details?: AlgoTransactionDetails;
25
+ }
26
+
27
+ export interface AlgoPaymentInfo {
28
+ amount: BigNumber;
29
+ recipientAddress: string; // receiver
30
+ closeAmount?: BigNumber; // close-amount
31
+ closeToAddress?: string; // close-remainder-to
32
+ }
33
+
34
+ export interface AlgoAssetTransferInfo {
35
+ assetId: string; // asset-id
36
+ assetAmount: BigNumber; // amount
37
+ assetRecipientAddress: string; // receiver
38
+ assetSenderAddress?: string; // sender
39
+ assetCloseAmount?: BigNumber; // close-amount
40
+ assetCloseToAddress?: string; // close-to
41
+ }
@@ -0,0 +1,92 @@
1
+ import getAddressWrapper from "@ledgerhq/coin-framework/bridge/getAddressWrapper";
2
+ import {
3
+ DeviceCommunication,
4
+ makeAccountBridgeReceive,
5
+ makeScanAccounts,
6
+ makeSync,
7
+ } from "@ledgerhq/coin-framework/bridge/jsHelpers";
8
+ import type { NetworkRequestCall } from "@ledgerhq/coin-framework/network";
9
+
10
+ import type { AccountBridge, CurrencyBridge } from "@ledgerhq/types-live";
11
+ import { AlgorandAPI } from "../api";
12
+ import getAddress from "../hw-getAddress";
13
+ import { initAccount } from "../initAccount";
14
+ import { broadcast } from "../js-broadcast";
15
+ import createTransaction from "../js-createTransaction";
16
+ import { estimateMaxSpendable } from "../js-estimateMaxSpendable";
17
+ import { getTransactionStatus } from "../js-getTransactionStatus";
18
+ import prepareTransaction from "../js-prepareTransaction";
19
+ import { buildSignOperation } from "../js-signOperation";
20
+ import { makeGetAccountShape } from "../js-synchronization";
21
+ import { assignFromAccountRaw, assignToAccountRaw } from "../serialization";
22
+ import type { Transaction } from "../types";
23
+
24
+ const updateTransaction = (t: Transaction, patch: Partial<Transaction>) => ({
25
+ ...t,
26
+ ...patch,
27
+ });
28
+
29
+ export function buildCurrencyBridge(
30
+ deviceCommunication: DeviceCommunication,
31
+ network: NetworkRequestCall
32
+ ): CurrencyBridge {
33
+ const algorandAPI = new AlgorandAPI(network);
34
+
35
+ const getAccountShape = makeGetAccountShape(algorandAPI);
36
+ const scanAccounts = makeScanAccounts({
37
+ getAccountShape,
38
+ deviceCommunication,
39
+ getAddressFn: getAddress,
40
+ });
41
+
42
+ return {
43
+ preload: async () => Promise.resolve({}),
44
+ hydrate: () => {},
45
+ scanAccounts,
46
+ };
47
+ }
48
+
49
+ export function buildAccountBridge(
50
+ deviceCommunication: DeviceCommunication,
51
+ network: NetworkRequestCall
52
+ ): AccountBridge<Transaction> {
53
+ const algorandAPI = new AlgorandAPI(network);
54
+
55
+ const receive = makeAccountBridgeReceive(
56
+ getAddressWrapper(getAddress),
57
+ deviceCommunication
58
+ );
59
+ const signOperation = buildSignOperation(deviceCommunication, algorandAPI);
60
+ const getAccountShape = makeGetAccountShape(algorandAPI);
61
+ const sync = makeSync({ getAccountShape });
62
+
63
+ return {
64
+ createTransaction,
65
+ updateTransaction,
66
+ prepareTransaction: prepareTransaction(algorandAPI),
67
+ getTransactionStatus: getTransactionStatus(algorandAPI),
68
+ sync,
69
+ receive,
70
+ assignToAccountRaw,
71
+ assignFromAccountRaw,
72
+ initAccount,
73
+ signOperation,
74
+ broadcast: broadcast(algorandAPI),
75
+ estimateMaxSpendable: estimateMaxSpendable(algorandAPI),
76
+ };
77
+ }
78
+
79
+ /**
80
+ * FIXME: an unsued cacheFn is passed to createBridges because of how the
81
+ * libs/ledger-live-common/scripts/sync-families-dispatch.mjs script works.
82
+ */
83
+ export function createBridges(
84
+ deviceCommunication: DeviceCommunication,
85
+ network: NetworkRequestCall,
86
+ _cacheFn: unknown
87
+ ) {
88
+ return {
89
+ currencyBridge: buildCurrencyBridge(deviceCommunication, network),
90
+ accountBridge: buildAccountBridge(deviceCommunication, network),
91
+ };
92
+ }