@ledgerhq/coin-hedera 1.12.0-nightly.2 → 1.12.0-nightly.4
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 +73 -11
- package/lib/api/network.d.ts +2 -6
- package/lib/api/network.d.ts.map +1 -1
- package/lib/api/network.js +4 -25
- package/lib/api/network.js.map +1 -1
- package/lib/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib/bridge/buildOptimisticOperation.js +6 -2
- package/lib/bridge/buildOptimisticOperation.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +10 -13
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/getTransactionStatus.test.js +24 -8
- package/lib/bridge/getTransactionStatus.test.js.map +1 -1
- package/lib/bridge/index.d.ts.map +1 -1
- package/lib/bridge/index.js +3 -0
- package/lib/bridge/index.js.map +1 -1
- package/lib/bridge/utils.d.ts +4 -0
- package/lib/bridge/utils.d.ts.map +1 -1
- package/lib/bridge/utils.integration.test.js +40 -0
- package/lib/bridge/utils.integration.test.js.map +1 -1
- package/lib/bridge/utils.js +41 -3
- package/lib/bridge/utils.js.map +1 -1
- package/lib/errors.d.ts +12 -0
- package/lib/errors.d.ts.map +1 -1
- package/lib/errors.js +5 -1
- package/lib/errors.js.map +1 -1
- package/lib-es/api/network.d.ts +2 -6
- package/lib-es/api/network.d.ts.map +1 -1
- package/lib-es/api/network.js +3 -24
- package/lib-es/api/network.js.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.d.ts.map +1 -1
- package/lib-es/bridge/buildOptimisticOperation.js +7 -3
- 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 +9 -12
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.test.js +21 -5
- package/lib-es/bridge/getTransactionStatus.test.js.map +1 -1
- package/lib-es/bridge/index.d.ts.map +1 -1
- package/lib-es/bridge/index.js +3 -0
- package/lib-es/bridge/index.js.map +1 -1
- package/lib-es/bridge/utils.d.ts +4 -0
- package/lib-es/bridge/utils.d.ts.map +1 -1
- package/lib-es/bridge/utils.integration.test.js +41 -1
- package/lib-es/bridge/utils.integration.test.js.map +1 -1
- package/lib-es/bridge/utils.js +40 -3
- package/lib-es/bridge/utils.js.map +1 -1
- package/lib-es/errors.d.ts +12 -0
- package/lib-es/errors.d.ts.map +1 -1
- package/lib-es/errors.js +4 -0
- package/lib-es/errors.js.map +1 -1
- package/package.json +10 -10
- package/src/api/network.ts +2 -35
- package/src/bridge/buildOptimisticOperation.ts +7 -3
- package/src/bridge/getTransactionStatus.test.ts +27 -5
- package/src/bridge/getTransactionStatus.ts +14 -13
- package/src/bridge/index.ts +3 -0
- package/src/bridge/utils.integration.test.ts +52 -0
- package/src/bridge/utils.ts +49 -2
- package/src/errors.ts +12 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
|
+
import { InvalidAddress } from "@ledgerhq/errors";
|
|
2
3
|
import cvsApi from "@ledgerhq/live-countervalues/api/index";
|
|
3
4
|
import { encodeTokenAccountId } from "@ledgerhq/coin-framework/account";
|
|
4
5
|
import { getMockedAccount, getMockedTokenAccount } from "../test/fixtures/account.fixture";
|
|
@@ -12,6 +13,7 @@ import {
|
|
|
12
13
|
getSubAccounts,
|
|
13
14
|
getSyncHash,
|
|
14
15
|
mergeSubAccounts,
|
|
16
|
+
safeParseAccountId,
|
|
15
17
|
patchOperationWithExtra,
|
|
16
18
|
prepareOperations,
|
|
17
19
|
} from "./utils";
|
|
@@ -23,6 +25,7 @@ import {
|
|
|
23
25
|
import { getMockedOperation } from "../test/fixtures/operation.fixture";
|
|
24
26
|
import { HederaOperationExtra } from "../types";
|
|
25
27
|
import { getAccount } from "../api/mirror";
|
|
28
|
+
import { HederaRecipientInvalidChecksum } from "../errors";
|
|
26
29
|
import { isValidExtra } from "../logic";
|
|
27
30
|
import { getMockedMirrorToken } from "../test/fixtures/mirror.fixture";
|
|
28
31
|
import { HEDERA_OPERATION_TYPES, HEDERA_TRANSACTION_KINDS } from "../constants";
|
|
@@ -539,5 +542,54 @@ describe("utils", () => {
|
|
|
539
542
|
const result = await checkAccountTokenAssociationStatus(accountId, tokenId);
|
|
540
543
|
expect(result).toBe(false);
|
|
541
544
|
});
|
|
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
|
+
});
|
|
542
594
|
});
|
|
543
595
|
});
|
package/src/bridge/utils.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
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";
|
|
4
6
|
import type { Account, Operation, TokenAccount } from "@ledgerhq/types-live";
|
|
5
7
|
import cvsApi from "@ledgerhq/live-countervalues/api/index";
|
|
6
8
|
import {
|
|
9
|
+
findCryptoCurrencyById,
|
|
7
10
|
findTokenByAddressInCurrency,
|
|
8
11
|
getFiatCurrencyByTicker,
|
|
9
12
|
listTokensForCryptoCurrency,
|
|
@@ -22,7 +25,9 @@ import { makeLRUCache, seconds } from "@ledgerhq/live-network/cache";
|
|
|
22
25
|
import { estimateMaxSpendable } from "./estimateMaxSpendable";
|
|
23
26
|
import type { HederaOperationExtra, Transaction } from "../types";
|
|
24
27
|
import { getAccount } from "../api/mirror";
|
|
28
|
+
import { getHederaClient } from "../api/network";
|
|
25
29
|
import type { HederaMirrorToken } from "../api/types";
|
|
30
|
+
import { HederaRecipientInvalidChecksum } from "../errors";
|
|
26
31
|
import { isTokenAssociateTransaction, isValidExtra } from "../logic";
|
|
27
32
|
import { BASE_USD_FEE_BY_OPERATION_TYPE, HEDERA_OPERATION_TYPES } from "../constants";
|
|
28
33
|
|
|
@@ -453,8 +458,15 @@ export function patchOperationWithExtra(
|
|
|
453
458
|
}
|
|
454
459
|
|
|
455
460
|
export const checkAccountTokenAssociationStatus = makeLRUCache(
|
|
456
|
-
async (
|
|
457
|
-
const
|
|
461
|
+
async (address: string, tokenId: string) => {
|
|
462
|
+
const [parsingError, parsingResult] = safeParseAccountId(address);
|
|
463
|
+
|
|
464
|
+
if (parsingError) {
|
|
465
|
+
throw parsingError;
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
const addressWithoutChecksum = parsingResult.accountId;
|
|
469
|
+
const mirrorAccount = await getAccount(addressWithoutChecksum);
|
|
458
470
|
|
|
459
471
|
// auto association is enabled
|
|
460
472
|
if (mirrorAccount.max_automatic_token_associations === -1) {
|
|
@@ -470,3 +482,38 @@ export const checkAccountTokenAssociationStatus = makeLRUCache(
|
|
|
470
482
|
(accountId, tokenId) => `${accountId}-${tokenId}`,
|
|
471
483
|
seconds(30),
|
|
472
484
|
);
|
|
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,3 +1,15 @@
|
|
|
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
|
+
);
|