@ledgerhq/coin-hedera 1.12.0-nightly.7 → 1.12.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/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +26 -76
- package/lib/api/mirror.test.d.ts +2 -0
- package/lib/api/mirror.test.d.ts.map +1 -0
- package/lib/api/mirror.test.js +114 -0
- package/lib/api/mirror.test.js.map +1 -0
- package/lib/api/network.d.ts +6 -2
- package/lib/api/network.d.ts.map +1 -1
- package/lib/api/network.js +25 -4
- package/lib/api/network.js.map +1 -1
- package/lib/api/network.test.d.ts +2 -0
- package/lib/api/network.test.d.ts.map +1 -0
- package/lib/api/network.test.js +45 -0
- package/lib/api/network.test.js.map +1 -0
- package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib/bridge/buildOptimisticOperation.integration.test.d.ts +2 -0
- package/lib/bridge/buildOptimisticOperation.integration.test.d.ts.map +1 -0
- package/lib/bridge/buildOptimisticOperation.integration.test.js +82 -0
- package/lib/bridge/buildOptimisticOperation.integration.test.js.map +1 -0
- package/lib/bridge/buildOptimisticOperation.js +2 -6
- package/lib/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +13 -10
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/getTransactionStatus.test.d.ts +2 -0
- package/lib/bridge/getTransactionStatus.test.d.ts.map +1 -0
- package/lib/bridge/getTransactionStatus.test.js +176 -0
- package/lib/bridge/getTransactionStatus.test.js.map +1 -0
- package/lib/bridge/js-estimateMaxSpendable.integration.test.d.ts +2 -0
- package/lib/bridge/js-estimateMaxSpendable.integration.test.d.ts.map +1 -0
- package/lib/bridge/js-estimateMaxSpendable.integration.test.js +47 -0
- package/lib/bridge/js-estimateMaxSpendable.integration.test.js.map +1 -0
- package/lib/bridge/js-transaction.test.d.ts +2 -0
- package/lib/bridge/js-transaction.test.d.ts.map +1 -0
- package/lib/bridge/js-transaction.test.js +40 -0
- package/lib/bridge/js-transaction.test.js.map +1 -0
- package/lib/bridge/prepareTransaction.test.d.ts +2 -0
- package/lib/bridge/prepareTransaction.test.d.ts.map +1 -0
- package/lib/bridge/prepareTransaction.test.js +58 -0
- package/lib/bridge/prepareTransaction.test.js.map +1 -0
- package/lib/bridge/serialization.test.d.ts +2 -0
- package/lib/bridge/serialization.test.d.ts.map +1 -0
- package/lib/bridge/serialization.test.js +27 -0
- package/lib/bridge/serialization.test.js.map +1 -0
- package/lib/bridge/transaction.test.d.ts +2 -0
- package/lib/bridge/transaction.test.d.ts.map +1 -0
- package/lib/bridge/transaction.test.js +37 -0
- package/lib/bridge/transaction.test.js.map +1 -0
- package/lib/bridge/utils.d.ts +0 -4
- package/lib/bridge/utils.d.ts.map +1 -1
- package/lib/bridge/utils.integration.test.d.ts +2 -0
- package/lib/bridge/utils.integration.test.d.ts.map +1 -0
- package/lib/bridge/utils.integration.test.js +428 -0
- package/lib/bridge/utils.integration.test.js.map +1 -0
- package/lib/bridge/utils.js +3 -41
- package/lib/bridge/utils.js.map +1 -1
- package/lib/errors.d.ts +0 -12
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +1 -5
- package/lib/errors.js.map +1 -1
- package/lib/logic.test.d.ts +2 -0
- package/lib/logic.test.d.ts.map +1 -0
- package/lib/logic.test.js +111 -0
- package/lib/logic.test.js.map +1 -0
- package/lib-es/api/mirror.test.d.ts +2 -0
- package/lib-es/api/mirror.test.d.ts.map +1 -0
- package/lib-es/api/mirror.test.js +109 -0
- package/lib-es/api/mirror.test.js.map +1 -0
- package/lib-es/api/network.d.ts +6 -2
- package/lib-es/api/network.d.ts.map +1 -1
- package/lib-es/api/network.js +24 -3
- package/lib-es/api/network.js.map +1 -1
- package/lib-es/api/network.test.d.ts +2 -0
- package/lib-es/api/network.test.d.ts.map +1 -0
- package/lib-es/api/network.test.js +40 -0
- package/lib-es/api/network.test.js.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.integration.test.d.ts +2 -0
- package/lib-es/bridge/buildOptimisticOperation.integration.test.d.ts.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.integration.test.js +77 -0
- package/lib-es/bridge/buildOptimisticOperation.integration.test.js.map +1 -0
- package/lib-es/bridge/buildOptimisticOperation.js +3 -7
- package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +12 -9
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.test.d.ts +2 -0
- package/lib-es/bridge/getTransactionStatus.test.d.ts.map +1 -0
- package/lib-es/bridge/getTransactionStatus.test.js +148 -0
- package/lib-es/bridge/getTransactionStatus.test.js.map +1 -0
- package/lib-es/bridge/js-estimateMaxSpendable.integration.test.d.ts +2 -0
- package/lib-es/bridge/js-estimateMaxSpendable.integration.test.d.ts.map +1 -0
- package/lib-es/bridge/js-estimateMaxSpendable.integration.test.js +42 -0
- package/lib-es/bridge/js-estimateMaxSpendable.integration.test.js.map +1 -0
- package/lib-es/bridge/js-transaction.test.d.ts +2 -0
- package/lib-es/bridge/js-transaction.test.d.ts.map +1 -0
- package/lib-es/bridge/js-transaction.test.js +35 -0
- package/lib-es/bridge/js-transaction.test.js.map +1 -0
- package/lib-es/bridge/prepareTransaction.test.d.ts +2 -0
- package/lib-es/bridge/prepareTransaction.test.d.ts.map +1 -0
- package/lib-es/bridge/prepareTransaction.test.js +30 -0
- package/lib-es/bridge/prepareTransaction.test.js.map +1 -0
- package/lib-es/bridge/serialization.test.d.ts +2 -0
- package/lib-es/bridge/serialization.test.d.ts.map +1 -0
- package/lib-es/bridge/serialization.test.js +25 -0
- package/lib-es/bridge/serialization.test.js.map +1 -0
- package/lib-es/bridge/transaction.test.d.ts +2 -0
- package/lib-es/bridge/transaction.test.d.ts.map +1 -0
- package/lib-es/bridge/transaction.test.js +32 -0
- package/lib-es/bridge/transaction.test.js.map +1 -0
- package/lib-es/bridge/utils.d.ts +0 -4
- package/lib-es/bridge/utils.d.ts.map +1 -1
- package/lib-es/bridge/utils.integration.test.d.ts +2 -0
- package/lib-es/bridge/utils.integration.test.d.ts.map +1 -0
- package/lib-es/bridge/utils.integration.test.js +423 -0
- package/lib-es/bridge/utils.integration.test.js.map +1 -0
- package/lib-es/bridge/utils.js +3 -40
- package/lib-es/bridge/utils.js.map +1 -1
- package/lib-es/errors.d.ts +0 -12
- package/lib-es/errors.d.ts.map +1 -1
- package/lib-es/errors.js +0 -4
- package/lib-es/errors.js.map +1 -1
- package/lib-es/logic.test.d.ts +2 -0
- package/lib-es/logic.test.d.ts.map +1 -0
- package/lib-es/logic.test.js +109 -0
- package/lib-es/logic.test.js.map +1 -0
- package/package.json +10 -10
- package/src/api/network.ts +35 -2
- package/src/bridge/buildOptimisticOperation.ts +3 -7
- package/src/bridge/getTransactionStatus.test.ts +5 -27
- package/src/bridge/getTransactionStatus.ts +13 -14
- package/src/bridge/utils.integration.test.ts +0 -52
- package/src/bridge/utils.ts +2 -49
- package/src/errors.ts +0 -12
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets";
|
|
2
|
+
import { getTransactionExplorer, isAutoTokenAssociationEnabled, isTokenAssociateTransaction, isTokenAssociationRequired, isValidExtra, sendRecipientCanNext, } from "./logic";
|
|
3
|
+
import { getMockedAccount, getMockedTokenAccount } from "./test/fixtures/account.fixture";
|
|
4
|
+
import { getMockedOperation } from "./test/fixtures/operation.fixture";
|
|
5
|
+
import { getMockedTokenCurrency } from "./test/fixtures/currency.fixture";
|
|
6
|
+
import { HEDERA_TRANSACTION_KINDS } from "./constants";
|
|
7
|
+
describe("logic", () => {
|
|
8
|
+
describe("getTransactionExplorer", () => {
|
|
9
|
+
test("Tx explorer URL is converted from hash to consensus timestamp", async () => {
|
|
10
|
+
const explorerView = getCryptoCurrencyById("hedera").explorerViews[0];
|
|
11
|
+
expect(explorerView).toEqual({
|
|
12
|
+
tx: expect.any(String),
|
|
13
|
+
address: expect.any(String),
|
|
14
|
+
});
|
|
15
|
+
const mockedOperation = getMockedOperation({
|
|
16
|
+
extra: { consensusTimestamp: "1.2.3.4" },
|
|
17
|
+
});
|
|
18
|
+
const newUrl = getTransactionExplorer(explorerView, mockedOperation);
|
|
19
|
+
expect(newUrl).toBe("https://hashscan.io/mainnet/transaction/1.2.3.4");
|
|
20
|
+
});
|
|
21
|
+
test("Tx explorer URL is based on transaction id if consensus timestamp is not available", async () => {
|
|
22
|
+
const explorerView = getCryptoCurrencyById("hedera").explorerViews[0];
|
|
23
|
+
expect(explorerView).toEqual({
|
|
24
|
+
tx: expect.any(String),
|
|
25
|
+
address: expect.any(String),
|
|
26
|
+
});
|
|
27
|
+
const mockedOperation = getMockedOperation({
|
|
28
|
+
extra: { transactionId: "0.0.1234567-123-123" },
|
|
29
|
+
});
|
|
30
|
+
const newUrl = getTransactionExplorer(explorerView, mockedOperation);
|
|
31
|
+
expect(newUrl).toBe("https://hashscan.io/mainnet/transaction/0.0.1234567-123-123");
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
describe("isTokenAssociateTransaction", () => {
|
|
35
|
+
test("returns correct value based on tx.properties", () => {
|
|
36
|
+
expect(isTokenAssociateTransaction({
|
|
37
|
+
properties: { name: HEDERA_TRANSACTION_KINDS.TokenAssociate.name },
|
|
38
|
+
})).toBe(true);
|
|
39
|
+
expect(isTokenAssociateTransaction({
|
|
40
|
+
properties: { name: "transfer" },
|
|
41
|
+
})).toBe(false);
|
|
42
|
+
expect(isTokenAssociateTransaction({})).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
describe("isAutoTokenAssociationEnabled", () => {
|
|
46
|
+
test("returns value based on isAutoTokenAssociationEnabled flag", () => {
|
|
47
|
+
expect(isAutoTokenAssociationEnabled({
|
|
48
|
+
hederaResources: { isAutoTokenAssociationEnabled: true },
|
|
49
|
+
})).toBe(true);
|
|
50
|
+
expect(isAutoTokenAssociationEnabled({
|
|
51
|
+
hederaResources: { isAutoTokenAssociationEnabled: false },
|
|
52
|
+
})).toBe(false);
|
|
53
|
+
expect(isAutoTokenAssociationEnabled({})).toBe(false);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
describe("isTokenAssociationRequired", () => {
|
|
57
|
+
test("should return false if token is already associated (token account exists)", () => {
|
|
58
|
+
const mockedTokenCurrency = getMockedTokenCurrency();
|
|
59
|
+
const mockedTokenAccount = getMockedTokenAccount(mockedTokenCurrency);
|
|
60
|
+
const mockedAccount = getMockedAccount({ subAccounts: [mockedTokenAccount] });
|
|
61
|
+
expect(isTokenAssociationRequired(mockedAccount, mockedTokenCurrency)).toBe(false);
|
|
62
|
+
});
|
|
63
|
+
test("should return false if auto token associations are enabled", () => {
|
|
64
|
+
const mockedTokenCurrency = getMockedTokenCurrency();
|
|
65
|
+
const mockedAccount = getMockedAccount({
|
|
66
|
+
subAccounts: [],
|
|
67
|
+
hederaResources: {
|
|
68
|
+
maxAutomaticTokenAssociations: -1,
|
|
69
|
+
isAutoTokenAssociationEnabled: true,
|
|
70
|
+
},
|
|
71
|
+
});
|
|
72
|
+
expect(isTokenAssociationRequired(mockedAccount, mockedTokenCurrency)).toBe(false);
|
|
73
|
+
});
|
|
74
|
+
test("should return true if token is not associated and auto associations are disabled", () => {
|
|
75
|
+
const mockedTokenCurrency = getMockedTokenCurrency();
|
|
76
|
+
const mockedAccount = getMockedAccount({ subAccounts: [] });
|
|
77
|
+
expect(isTokenAssociationRequired(mockedAccount, mockedTokenCurrency)).toBe(true);
|
|
78
|
+
});
|
|
79
|
+
test("should return false if token is undefined", () => {
|
|
80
|
+
const mockedAccount = getMockedAccount({ subAccounts: [] });
|
|
81
|
+
expect(isTokenAssociationRequired(mockedAccount, undefined)).toBe(false);
|
|
82
|
+
});
|
|
83
|
+
test("should return false for legacy accounts without subAccounts or hederaResources", () => {
|
|
84
|
+
const mockedTokenCurrency = getMockedTokenCurrency();
|
|
85
|
+
const mockedAccount = getMockedAccount();
|
|
86
|
+
delete mockedAccount.subAccounts;
|
|
87
|
+
delete mockedAccount.hederaResources;
|
|
88
|
+
expect(isTokenAssociationRequired(mockedAccount, mockedTokenCurrency)).toBe(true);
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
describe("isValidExtra", () => {
|
|
92
|
+
test("returns true for object and false for invalid types", () => {
|
|
93
|
+
expect(isValidExtra({ some: "value" })).toBe(true);
|
|
94
|
+
expect(isValidExtra(null)).toBe(false);
|
|
95
|
+
expect(isValidExtra(undefined)).toBe(false);
|
|
96
|
+
expect(isValidExtra("string")).toBe(false);
|
|
97
|
+
expect(isValidExtra(123)).toBe(false);
|
|
98
|
+
expect(isValidExtra([])).toBe(false);
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
describe("sendRecipientCanNext", () => {
|
|
102
|
+
test("handles association warnings", () => {
|
|
103
|
+
expect(sendRecipientCanNext({ warnings: {} })).toBe(true);
|
|
104
|
+
expect(sendRecipientCanNext({ warnings: { missingAssociation: new Error() } })).toBe(false);
|
|
105
|
+
expect(sendRecipientCanNext({ warnings: { unverifiedAssociation: new Error() } })).toBe(false);
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
//# sourceMappingURL=logic.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logic.test.js","sourceRoot":"","sources":["../src/logic.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-hedera",
|
|
3
|
-
"version": "1.12.0
|
|
3
|
+
"version": "1.12.0",
|
|
4
4
|
"description": "Ledger Hedera Coin integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -82,14 +82,14 @@
|
|
|
82
82
|
"invariant": "^2.2.2",
|
|
83
83
|
"lodash": "^4.17.21",
|
|
84
84
|
"rxjs": "^7.8.1",
|
|
85
|
-
"@ledgerhq/coin-framework": "^6.7.0
|
|
86
|
-
"@ledgerhq/cryptoassets": "^13.31.0
|
|
87
|
-
"@ledgerhq/devices": "8.6.
|
|
88
|
-
"@ledgerhq/errors": "^6.
|
|
89
|
-
"@ledgerhq/live-countervalues": "^0.8.0
|
|
90
|
-
"@ledgerhq/live-env": "^2.19.0
|
|
91
|
-
"@ledgerhq/live-network": "^2.0.20
|
|
92
|
-
"@ledgerhq/types-live": "^6.87.0
|
|
85
|
+
"@ledgerhq/coin-framework": "^6.7.0",
|
|
86
|
+
"@ledgerhq/cryptoassets": "^13.31.0",
|
|
87
|
+
"@ledgerhq/devices": "8.6.1",
|
|
88
|
+
"@ledgerhq/errors": "^6.26.0",
|
|
89
|
+
"@ledgerhq/live-countervalues": "^0.8.0",
|
|
90
|
+
"@ledgerhq/live-env": "^2.19.0",
|
|
91
|
+
"@ledgerhq/live-network": "^2.0.20",
|
|
92
|
+
"@ledgerhq/types-live": "^6.87.0"
|
|
93
93
|
},
|
|
94
94
|
"devDependencies": {
|
|
95
95
|
"@types/imurmurhash": "^0.1.4",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"jest": "^29.7.0",
|
|
101
101
|
"ts-jest": "^29.1.1",
|
|
102
102
|
"@ledgerhq/disable-network-setup": "^0.0.0",
|
|
103
|
-
"@ledgerhq/types-cryptoassets": "^7.29.0
|
|
103
|
+
"@ledgerhq/types-cryptoassets": "^7.29.0"
|
|
104
104
|
},
|
|
105
105
|
"scripts": {
|
|
106
106
|
"clean": "rimraf lib lib-es",
|
package/src/api/network.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
1
2
|
import invariant from "invariant";
|
|
2
3
|
import type { Transaction as HederaTransaction, TransactionResponse } from "@hashgraph/sdk";
|
|
3
4
|
import {
|
|
@@ -6,15 +7,18 @@ import {
|
|
|
6
7
|
Hbar,
|
|
7
8
|
AccountId,
|
|
8
9
|
TransactionId,
|
|
10
|
+
AccountBalanceQuery,
|
|
11
|
+
HbarUnit,
|
|
9
12
|
TokenAssociateTransaction,
|
|
10
13
|
} from "@hashgraph/sdk";
|
|
11
14
|
import type { Account, TokenAccount } from "@ledgerhq/types-live";
|
|
12
15
|
import { findSubAccountById, isTokenAccount } from "@ledgerhq/coin-framework/account/helpers";
|
|
16
|
+
import { HederaAddAccountError } from "../errors";
|
|
13
17
|
import { Transaction } from "../types";
|
|
14
18
|
import { isTokenAssociateTransaction } from "../logic";
|
|
15
19
|
|
|
16
20
|
export function broadcastTransaction(transaction: HederaTransaction): Promise<TransactionResponse> {
|
|
17
|
-
return transaction.execute(
|
|
21
|
+
return transaction.execute(getClient());
|
|
18
22
|
}
|
|
19
23
|
|
|
20
24
|
// https://github.com/LedgerHQ/ledger-live/pull/72/commits/1e942687d4301660e43e0c4b5419fcfa2733b290
|
|
@@ -114,12 +118,41 @@ export async function buildUnsignedTransaction({
|
|
|
114
118
|
}
|
|
115
119
|
}
|
|
116
120
|
|
|
121
|
+
export interface AccountBalance {
|
|
122
|
+
balance: BigNumber;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export async function getAccountBalance(address: string): Promise<AccountBalance> {
|
|
126
|
+
const accountId = AccountId.fromString(address);
|
|
127
|
+
let accountBalance;
|
|
128
|
+
|
|
129
|
+
try {
|
|
130
|
+
accountBalance = await new AccountBalanceQuery({
|
|
131
|
+
accountId,
|
|
132
|
+
}).execute(getBalanceClient());
|
|
133
|
+
} catch {
|
|
134
|
+
throw new HederaAddAccountError();
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
return {
|
|
138
|
+
balance: accountBalance.hbars.to(HbarUnit.Tinybar),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
|
|
117
142
|
let _hederaClient: Client | null = null;
|
|
118
143
|
|
|
119
|
-
|
|
144
|
+
let _hederaBalanceClient: Client | null = null;
|
|
145
|
+
|
|
146
|
+
function getClient(): Client {
|
|
120
147
|
_hederaClient ??= Client.forMainnet().setMaxNodesPerTransaction(1);
|
|
121
148
|
|
|
122
149
|
//_hederaClient.setNetwork({ mainnet: "https://hedera.coin.ledger.com" });
|
|
123
150
|
|
|
124
151
|
return _hederaClient;
|
|
125
152
|
}
|
|
153
|
+
|
|
154
|
+
function getBalanceClient(): Client {
|
|
155
|
+
_hederaBalanceClient ??= Client.forMainnet();
|
|
156
|
+
|
|
157
|
+
return _hederaBalanceClient;
|
|
158
|
+
}
|
|
@@ -3,7 +3,7 @@ import type { Account, Operation, OperationType, TokenAccount } from "@ledgerhq/
|
|
|
3
3
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
4
4
|
import { findSubAccountById, isTokenAccount } from "@ledgerhq/coin-framework/account/helpers";
|
|
5
5
|
import type { HederaOperationExtra, Transaction } from "../types";
|
|
6
|
-
import { getEstimatedFees
|
|
6
|
+
import { getEstimatedFees } from "./utils";
|
|
7
7
|
import { isTokenAssociateTransaction } from "../logic";
|
|
8
8
|
import { HEDERA_OPERATION_TYPES } from "../constants";
|
|
9
9
|
|
|
@@ -55,8 +55,6 @@ const buildOptimisticCoinOperation = async ({
|
|
|
55
55
|
: await getEstimatedFees(account, HEDERA_OPERATION_TYPES.CryptoTransfer);
|
|
56
56
|
const value = transaction.amount;
|
|
57
57
|
const type: OperationType = transactionType ?? "OUT";
|
|
58
|
-
const [_, recipientAddress] = safeParseAccountId(transaction.recipient);
|
|
59
|
-
const recipientWithoutChecksum = recipientAddress?.accountId ?? transaction.recipient;
|
|
60
58
|
|
|
61
59
|
const operation: Operation = {
|
|
62
60
|
id: encodeOperationId(account.id, "", type),
|
|
@@ -67,7 +65,7 @@ const buildOptimisticCoinOperation = async ({
|
|
|
67
65
|
blockHash: null,
|
|
68
66
|
blockHeight: null,
|
|
69
67
|
senders: [account.freshAddress.toString()],
|
|
70
|
-
recipients: [
|
|
68
|
+
recipients: [transaction.recipient],
|
|
71
69
|
accountId: account.id,
|
|
72
70
|
date: new Date(),
|
|
73
71
|
extra: {},
|
|
@@ -88,8 +86,6 @@ const buildOptimisticTokenOperation = async ({
|
|
|
88
86
|
const estimatedFee = await getEstimatedFees(account, HEDERA_OPERATION_TYPES.TokenTransfer);
|
|
89
87
|
const value = transaction.amount;
|
|
90
88
|
const type: OperationType = "OUT";
|
|
91
|
-
const [_, recipientAddress] = safeParseAccountId(transaction.recipient);
|
|
92
|
-
const recipientWithoutChecksum = recipientAddress?.accountId ?? transaction.recipient;
|
|
93
89
|
|
|
94
90
|
const coinOperation = await buildOptimisticCoinOperation({
|
|
95
91
|
account,
|
|
@@ -113,7 +109,7 @@ const buildOptimisticTokenOperation = async ({
|
|
|
113
109
|
blockHash: null,
|
|
114
110
|
blockHeight: null,
|
|
115
111
|
senders: [account.freshAddress.toString()],
|
|
116
|
-
recipients: [
|
|
112
|
+
recipients: [transaction.recipient],
|
|
117
113
|
accountId: tokenAccount.id,
|
|
118
114
|
date: new Date(),
|
|
119
115
|
extra: {},
|
|
@@ -4,13 +4,10 @@ import {
|
|
|
4
4
|
InvalidAddressBecauseDestinationIsAlsoSource,
|
|
5
5
|
AmountRequired,
|
|
6
6
|
NotEnoughBalance,
|
|
7
|
-
} from "@ledgerhq/errors";
|
|
8
|
-
import {
|
|
9
|
-
HederaRecipientInvalidChecksum,
|
|
10
7
|
HederaInsufficientFundsForAssociation,
|
|
11
8
|
HederaRecipientTokenAssociationRequired,
|
|
12
9
|
HederaRecipientTokenAssociationUnverified,
|
|
13
|
-
} from "
|
|
10
|
+
} from "@ledgerhq/errors";
|
|
14
11
|
import { getMockedAccount, getMockedTokenAccount } from "../test/fixtures/account.fixture";
|
|
15
12
|
import { getMockedTokenCurrency } from "../test/fixtures/currency.fixture";
|
|
16
13
|
import { getMockedTransaction } from "../test/fixtures/transaction.fixture";
|
|
@@ -22,7 +19,7 @@ describe("getTransactionStatus", () => {
|
|
|
22
19
|
const mockedEstimatedFee = new BigNumber(1);
|
|
23
20
|
const mockedUsdRate = new BigNumber(1);
|
|
24
21
|
const validRecipientAddress = "0.0.1234567";
|
|
25
|
-
const
|
|
22
|
+
const invalidRecipientAddress = "invalid_address";
|
|
26
23
|
|
|
27
24
|
beforeEach(() => {
|
|
28
25
|
jest.clearAllMocks();
|
|
@@ -84,32 +81,13 @@ describe("getTransactionStatus", () => {
|
|
|
84
81
|
expect(result.estimatedFees).toEqual(mockedEstimatedFee);
|
|
85
82
|
});
|
|
86
83
|
|
|
87
|
-
test("recipient with checksum is supported", async () => {
|
|
88
|
-
const mockedAccount = getMockedAccount({ balance: new BigNumber(1000) });
|
|
89
|
-
const mockedTransaction = getMockedTransaction({
|
|
90
|
-
recipient: validRecipientAddressWithChecksum,
|
|
91
|
-
amount: new BigNumber(100),
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const result = await getTransactionStatus(mockedAccount, mockedTransaction);
|
|
95
|
-
|
|
96
|
-
expect(result.errors).toEqual({});
|
|
97
|
-
expect(result.warnings).toEqual({});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
84
|
test("adds error for invalid recipient address", async () => {
|
|
101
85
|
const mockedAccount = getMockedAccount();
|
|
86
|
+
const mockedTransaction = getMockedTransaction({ recipient: invalidRecipientAddress });
|
|
102
87
|
|
|
103
|
-
const
|
|
104
|
-
const txWithInvalidAddressChecksum = getMockedTransaction({ recipient: "0.0.9124531-invld" });
|
|
105
|
-
|
|
106
|
-
const [result1, result2] = await Promise.all([
|
|
107
|
-
getTransactionStatus(mockedAccount, txWithInvalidAddress),
|
|
108
|
-
getTransactionStatus(mockedAccount, txWithInvalidAddressChecksum),
|
|
109
|
-
]);
|
|
88
|
+
const result = await getTransactionStatus(mockedAccount, mockedTransaction);
|
|
110
89
|
|
|
111
|
-
expect(
|
|
112
|
-
expect(result2.errors.recipient).toBeInstanceOf(HederaRecipientInvalidChecksum);
|
|
90
|
+
expect(result.errors.recipient).toBeInstanceOf(InvalidAddress);
|
|
113
91
|
});
|
|
114
92
|
|
|
115
93
|
test("adds error for self transfers", async () => {
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
|
+
import { AccountId } from "@hashgraph/sdk";
|
|
2
3
|
import {
|
|
3
4
|
AmountRequired,
|
|
4
5
|
NotEnoughBalance,
|
|
6
|
+
InvalidAddress,
|
|
5
7
|
InvalidAddressBecauseDestinationIsAlsoSource,
|
|
6
8
|
RecipientRequired,
|
|
9
|
+
HederaInsufficientFundsForAssociation,
|
|
10
|
+
HederaRecipientTokenAssociationRequired,
|
|
11
|
+
HederaRecipientTokenAssociationUnverified,
|
|
7
12
|
} from "@ledgerhq/errors";
|
|
8
13
|
import type { Account, AccountBridge, TokenAccount } from "@ledgerhq/types-live";
|
|
9
14
|
import { findSubAccountById, isTokenAccount } from "@ledgerhq/coin-framework/account";
|
|
10
15
|
import { getEnv } from "@ledgerhq/live-env";
|
|
11
|
-
import {
|
|
12
|
-
HederaInsufficientFundsForAssociation,
|
|
13
|
-
HederaRecipientTokenAssociationRequired,
|
|
14
|
-
HederaRecipientTokenAssociationUnverified,
|
|
15
|
-
} from "../errors";
|
|
16
16
|
import { isTokenAssociateTransaction, isTokenAssociationRequired } from "../logic";
|
|
17
17
|
import type { TokenAssociateProperties, Transaction, TransactionStatus } from "../types";
|
|
18
18
|
import {
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
checkAccountTokenAssociationStatus,
|
|
21
21
|
getCurrencyToUSDRate,
|
|
22
22
|
getEstimatedFees,
|
|
23
|
-
safeParseAccountId,
|
|
24
23
|
} from "./utils";
|
|
25
24
|
import { HEDERA_OPERATION_TYPES } from "../constants";
|
|
26
25
|
|
|
@@ -32,16 +31,16 @@ function validateRecipient(account: Account, recipient: string): Error | null {
|
|
|
32
31
|
return new RecipientRequired();
|
|
33
32
|
}
|
|
34
33
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
if (parsingError) {
|
|
38
|
-
return parsingError;
|
|
34
|
+
if (account.freshAddress === recipient) {
|
|
35
|
+
return new InvalidAddressBecauseDestinationIsAlsoSource();
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
return new
|
|
38
|
+
try {
|
|
39
|
+
AccountId.fromString(recipient);
|
|
40
|
+
} catch (err) {
|
|
41
|
+
return new InvalidAddress("", {
|
|
42
|
+
currencyName: account.currency.name,
|
|
43
|
+
});
|
|
45
44
|
}
|
|
46
45
|
|
|
47
46
|
return null;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
|
-
import { InvalidAddress } from "@ledgerhq/errors";
|
|
3
2
|
import cvsApi from "@ledgerhq/live-countervalues/api/index";
|
|
4
3
|
import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account";
|
|
5
4
|
import { getMockedAccount, getMockedTokenAccount } from "../test/fixtures/account.fixture";
|
|
@@ -13,7 +12,6 @@ import {
|
|
|
13
12
|
getSubAccounts,
|
|
14
13
|
getSyncHash,
|
|
15
14
|
mergeSubAccounts,
|
|
16
|
-
safeParseAccountId,
|
|
17
15
|
patchOperationWithExtra,
|
|
18
16
|
prepareOperations,
|
|
19
17
|
} from "./utils";
|
|
@@ -25,7 +23,6 @@ import {
|
|
|
25
23
|
import { getMockedOperation } from "../test/fixtures/operation.fixture";
|
|
26
24
|
import { HederaOperationExtra } from "../types";
|
|
27
25
|
import { getAccount } from "../api/mirror";
|
|
28
|
-
import { HederaRecipientInvalidChecksum } from "../errors";
|
|
29
26
|
import { isValidExtra } from "../logic";
|
|
30
27
|
import { getMockedMirrorToken } from "../test/fixtures/mirror.fixture";
|
|
31
28
|
import { HEDERA_OPERATION_TYPES, HEDERA_TRANSACTION_KINDS } from "../constants";
|
|
@@ -542,54 +539,5 @@ describe("utils", () => {
|
|
|
542
539
|
const result = await checkAccountTokenAssociationStatus(accountId, tokenId);
|
|
543
540
|
expect(result).toBe(false);
|
|
544
541
|
});
|
|
545
|
-
|
|
546
|
-
test("supports addresses with checksum", async () => {
|
|
547
|
-
const addressWithChecksum = "0.0.9124531-xrxlv";
|
|
548
|
-
|
|
549
|
-
mockedGetAccount.mockResolvedValueOnce({
|
|
550
|
-
account: accountId,
|
|
551
|
-
max_automatic_token_associations: 0,
|
|
552
|
-
balance: {
|
|
553
|
-
balance: 1,
|
|
554
|
-
timestamp: "",
|
|
555
|
-
tokens: [{ token_id: "0.0.9999", balance: 1 }],
|
|
556
|
-
},
|
|
557
|
-
});
|
|
558
|
-
|
|
559
|
-
await checkAccountTokenAssociationStatus(addressWithChecksum, tokenId);
|
|
560
|
-
expect(mockedGetAccount).toHaveBeenCalledWith("0.0.9124531");
|
|
561
|
-
});
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
describe("safeParseAccountId", () => {
|
|
565
|
-
test("returns account id and no checksum for valid address without checksum", () => {
|
|
566
|
-
const [error, result] = safeParseAccountId("0.0.9124531");
|
|
567
|
-
|
|
568
|
-
expect(error).toBeNull();
|
|
569
|
-
expect(result?.accountId).toBe("0.0.9124531");
|
|
570
|
-
expect(result?.checksum).toBeNull();
|
|
571
|
-
});
|
|
572
|
-
|
|
573
|
-
test("returns account id and checksum for valid address with correct checksum", () => {
|
|
574
|
-
const [error, result] = safeParseAccountId("0.0.9124531-xrxlv");
|
|
575
|
-
|
|
576
|
-
expect(error).toBeNull();
|
|
577
|
-
expect(result?.accountId).toBe("0.0.9124531");
|
|
578
|
-
expect(result?.checksum).toBe("xrxlv");
|
|
579
|
-
});
|
|
580
|
-
|
|
581
|
-
test("returns error for valid address with incorrect checksum", () => {
|
|
582
|
-
const [error, accountId] = safeParseAccountId("0.0.9124531-invld");
|
|
583
|
-
|
|
584
|
-
expect(error).toBeInstanceOf(HederaRecipientInvalidChecksum);
|
|
585
|
-
expect(accountId).toBeNull();
|
|
586
|
-
});
|
|
587
|
-
|
|
588
|
-
test("returns error for invalid address format", () => {
|
|
589
|
-
const [error, accountId] = safeParseAccountId("not-a-valid-address");
|
|
590
|
-
|
|
591
|
-
expect(error).toBeInstanceOf(InvalidAddress);
|
|
592
|
-
expect(accountId).toBeNull();
|
|
593
|
-
});
|
|
594
542
|
});
|
|
595
543
|
});
|
package/src/bridge/utils.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
2
|
import murmurhash from "imurmurhash";
|
|
3
3
|
import invariant from "invariant";
|
|
4
|
-
import { AccountId } from "@hashgraph/sdk";
|
|
5
|
-
import { InvalidAddress } from "@ledgerhq/errors";
|
|
6
4
|
import type { Account, Operation, TokenAccount } from "@ledgerhq/types-live";
|
|
7
5
|
import cvsApi from "@ledgerhq/live-countervalues/api/index";
|
|
8
6
|
import {
|
|
9
|
-
findCryptoCurrencyById,
|
|
10
7
|
findTokenByAddressInCurrency,
|
|
11
8
|
getFiatCurrencyByTicker,
|
|
12
9
|
listTokensForCryptoCurrency,
|
|
@@ -25,9 +22,7 @@ import { makeLRUCache, seconds } from "@ledgerhq/live-network/cache";
|
|
|
25
22
|
import { estimateMaxSpendable } from "./estimateMaxSpendable";
|
|
26
23
|
import type { HederaOperationExtra, Transaction } from "../types";
|
|
27
24
|
import { getAccount } from "../api/mirror";
|
|
28
|
-
import { getHederaClient } from "../api/network";
|
|
29
25
|
import type { HederaMirrorToken } from "../api/types";
|
|
30
|
-
import { HederaRecipientInvalidChecksum } from "../errors";
|
|
31
26
|
import { isTokenAssociateTransaction, isValidExtra } from "../logic";
|
|
32
27
|
import { BASE_USD_FEE_BY_OPERATION_TYPE, HEDERA_OPERATION_TYPES } from "../constants";
|
|
33
28
|
|
|
@@ -458,15 +453,8 @@ export function patchOperationWithExtra(
|
|
|
458
453
|
}
|
|
459
454
|
|
|
460
455
|
export const checkAccountTokenAssociationStatus = makeLRUCache(
|
|
461
|
-
async (
|
|
462
|
-
const
|
|
463
|
-
|
|
464
|
-
if (parsingError) {
|
|
465
|
-
throw parsingError;
|
|
466
|
-
}
|
|
467
|
-
|
|
468
|
-
const addressWithoutChecksum = parsingResult.accountId;
|
|
469
|
-
const mirrorAccount = await getAccount(addressWithoutChecksum);
|
|
456
|
+
async (accountId: string, tokenId: string) => {
|
|
457
|
+
const mirrorAccount = await getAccount(accountId);
|
|
470
458
|
|
|
471
459
|
// auto association is enabled
|
|
472
460
|
if (mirrorAccount.max_automatic_token_associations === -1) {
|
|
@@ -482,38 +470,3 @@ export const checkAccountTokenAssociationStatus = makeLRUCache(
|
|
|
482
470
|
(accountId, tokenId) => `${accountId}-${tokenId}`,
|
|
483
471
|
seconds(30),
|
|
484
472
|
);
|
|
485
|
-
|
|
486
|
-
export const safeParseAccountId = (
|
|
487
|
-
address: string,
|
|
488
|
-
): [Error, null] | [null, { accountId: string; checksum: string | null }] => {
|
|
489
|
-
const currency = findCryptoCurrencyById("hedera");
|
|
490
|
-
const currencyName = currency?.name ?? "Hedera";
|
|
491
|
-
|
|
492
|
-
try {
|
|
493
|
-
const accountId = AccountId.fromString(address);
|
|
494
|
-
|
|
495
|
-
// verify checksum if present
|
|
496
|
-
// FIXME: migrate to EntityIdHelper methods once SDK is upgraded:
|
|
497
|
-
// https://github.com/hiero-ledger/hiero-sdk-js/blob/main/src/EntityIdHelper.js#L197
|
|
498
|
-
// https://github.com/hiero-ledger/hiero-sdk-js/blob/main/src/EntityIdHelper.js#L446
|
|
499
|
-
const checksum: string | null = address.split("-")[1] ?? null;
|
|
500
|
-
if (checksum) {
|
|
501
|
-
const client = getHederaClient();
|
|
502
|
-
const recipientWithChecksum = accountId.toStringWithChecksum(client);
|
|
503
|
-
const expectedChecksum = recipientWithChecksum.split("-")[1];
|
|
504
|
-
|
|
505
|
-
if (checksum !== expectedChecksum) {
|
|
506
|
-
return [new HederaRecipientInvalidChecksum(), null];
|
|
507
|
-
}
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
const result = {
|
|
511
|
-
accountId: accountId.toString(),
|
|
512
|
-
checksum,
|
|
513
|
-
};
|
|
514
|
-
|
|
515
|
-
return [null, result];
|
|
516
|
-
} catch (err) {
|
|
517
|
-
return [new InvalidAddress("", { currencyName }), null];
|
|
518
|
-
}
|
|
519
|
-
};
|
package/src/errors.ts
CHANGED
|
@@ -1,15 +1,3 @@
|
|
|
1
1
|
import { createCustomErrorClass } from "@ledgerhq/errors";
|
|
2
2
|
|
|
3
3
|
export const HederaAddAccountError = createCustomErrorClass("HederaAddAccountError");
|
|
4
|
-
export const HederaRecipientInvalidChecksum = createCustomErrorClass(
|
|
5
|
-
"HederaRecipientInvalidChecksum",
|
|
6
|
-
);
|
|
7
|
-
export const HederaInsufficientFundsForAssociation = createCustomErrorClass(
|
|
8
|
-
"HederaInsufficientFundsForAssociation",
|
|
9
|
-
);
|
|
10
|
-
export const HederaRecipientTokenAssociationRequired = createCustomErrorClass(
|
|
11
|
-
"HederaRecipientTokenAssociationRequired",
|
|
12
|
-
);
|
|
13
|
-
export const HederaRecipientTokenAssociationUnverified = createCustomErrorClass(
|
|
14
|
-
"HederaRecipientTokenAssociationUnverified",
|
|
15
|
-
);
|