@ledgerhq/coin-cosmos 0.21.0-nightly.20251210120335 → 0.21.0-nightly.20251212024049

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.
Files changed (109) hide show
  1. package/CHANGELOG.md +13 -11
  2. package/lib/bridge/index.d.ts.map +1 -1
  3. package/lib/bridge/index.js +2 -0
  4. package/lib/bridge/index.js.map +1 -1
  5. package/lib/bridge/index.test.d.ts +2 -0
  6. package/lib/bridge/index.test.d.ts.map +1 -0
  7. package/lib/bridge/index.test.js +68 -0
  8. package/lib/bridge/index.test.js.map +1 -0
  9. package/lib/buildTransaction.unit.test.d.ts +2 -0
  10. package/lib/buildTransaction.unit.test.d.ts.map +1 -0
  11. package/lib/buildTransaction.unit.test.js +736 -0
  12. package/lib/buildTransaction.unit.test.js.map +1 -0
  13. package/lib/chain/chain.unit.test.d.ts +2 -0
  14. package/lib/chain/chain.unit.test.d.ts.map +1 -0
  15. package/lib/chain/chain.unit.test.js +41 -0
  16. package/lib/chain/chain.unit.test.js.map +1 -0
  17. package/lib/helpers.unit.test.d.ts +2 -0
  18. package/lib/helpers.unit.test.d.ts.map +1 -0
  19. package/lib/helpers.unit.test.js +65 -0
  20. package/lib/helpers.unit.test.js.map +1 -0
  21. package/lib/mock.d.ts +5 -4
  22. package/lib/mock.d.ts.map +1 -1
  23. package/lib/mock.js +7 -0
  24. package/lib/mock.js.map +1 -1
  25. package/lib/network/Cosmos.unit.test.d.ts +2 -0
  26. package/lib/network/Cosmos.unit.test.d.ts.map +1 -0
  27. package/lib/network/Cosmos.unit.test.js +580 -0
  28. package/lib/network/Cosmos.unit.test.js.map +1 -0
  29. package/lib/prepareTransaction.unit.test.d.ts +2 -0
  30. package/lib/prepareTransaction.unit.test.d.ts.map +1 -0
  31. package/lib/prepareTransaction.unit.test.js +159 -0
  32. package/lib/prepareTransaction.unit.test.js.map +1 -0
  33. package/lib/synchronisation.integ.test.d.ts +2 -0
  34. package/lib/synchronisation.integ.test.d.ts.map +1 -0
  35. package/lib/synchronisation.integ.test.js +233 -0
  36. package/lib/synchronisation.integ.test.js.map +1 -0
  37. package/lib/synchronisation.test.d.ts +2 -0
  38. package/lib/synchronisation.test.d.ts.map +1 -0
  39. package/lib/synchronisation.test.js +65 -0
  40. package/lib/synchronisation.test.js.map +1 -0
  41. package/lib/synchronisation.unit.test.d.ts +2 -0
  42. package/lib/synchronisation.unit.test.d.ts.map +1 -0
  43. package/lib/synchronisation.unit.test.js +667 -0
  44. package/lib/synchronisation.unit.test.js.map +1 -0
  45. package/lib/validateAddress.d.ts +3 -0
  46. package/lib/validateAddress.d.ts.map +1 -0
  47. package/lib/validateAddress.js +52 -0
  48. package/lib/validateAddress.js.map +1 -0
  49. package/lib/validateAddress.test.d.ts +2 -0
  50. package/lib/validateAddress.test.d.ts.map +1 -0
  51. package/lib/validateAddress.test.js +125 -0
  52. package/lib/validateAddress.test.js.map +1 -0
  53. package/lib-es/bridge/index.d.ts.map +1 -1
  54. package/lib-es/bridge/index.js +2 -0
  55. package/lib-es/bridge/index.js.map +1 -1
  56. package/lib-es/bridge/index.test.d.ts +2 -0
  57. package/lib-es/bridge/index.test.d.ts.map +1 -0
  58. package/lib-es/bridge/index.test.js +66 -0
  59. package/lib-es/bridge/index.test.js.map +1 -0
  60. package/lib-es/buildTransaction.unit.test.d.ts +2 -0
  61. package/lib-es/buildTransaction.unit.test.d.ts.map +1 -0
  62. package/lib-es/buildTransaction.unit.test.js +731 -0
  63. package/lib-es/buildTransaction.unit.test.js.map +1 -0
  64. package/lib-es/chain/chain.unit.test.d.ts +2 -0
  65. package/lib-es/chain/chain.unit.test.d.ts.map +1 -0
  66. package/lib-es/chain/chain.unit.test.js +36 -0
  67. package/lib-es/chain/chain.unit.test.js.map +1 -0
  68. package/lib-es/helpers.unit.test.d.ts +2 -0
  69. package/lib-es/helpers.unit.test.d.ts.map +1 -0
  70. package/lib-es/helpers.unit.test.js +63 -0
  71. package/lib-es/helpers.unit.test.js.map +1 -0
  72. package/lib-es/mock.d.ts +5 -4
  73. package/lib-es/mock.d.ts.map +1 -1
  74. package/lib-es/mock.js +7 -0
  75. package/lib-es/mock.js.map +1 -1
  76. package/lib-es/network/Cosmos.unit.test.d.ts +2 -0
  77. package/lib-es/network/Cosmos.unit.test.d.ts.map +1 -0
  78. package/lib-es/network/Cosmos.unit.test.js +575 -0
  79. package/lib-es/network/Cosmos.unit.test.js.map +1 -0
  80. package/lib-es/prepareTransaction.unit.test.d.ts +2 -0
  81. package/lib-es/prepareTransaction.unit.test.d.ts.map +1 -0
  82. package/lib-es/prepareTransaction.unit.test.js +131 -0
  83. package/lib-es/prepareTransaction.unit.test.js.map +1 -0
  84. package/lib-es/synchronisation.integ.test.d.ts +2 -0
  85. package/lib-es/synchronisation.integ.test.d.ts.map +1 -0
  86. package/lib-es/synchronisation.integ.test.js +205 -0
  87. package/lib-es/synchronisation.integ.test.js.map +1 -0
  88. package/lib-es/synchronisation.test.d.ts +2 -0
  89. package/lib-es/synchronisation.test.d.ts.map +1 -0
  90. package/lib-es/synchronisation.test.js +60 -0
  91. package/lib-es/synchronisation.test.js.map +1 -0
  92. package/lib-es/synchronisation.unit.test.d.ts +2 -0
  93. package/lib-es/synchronisation.unit.test.d.ts.map +1 -0
  94. package/lib-es/synchronisation.unit.test.js +639 -0
  95. package/lib-es/synchronisation.unit.test.js.map +1 -0
  96. package/lib-es/validateAddress.d.ts +3 -0
  97. package/lib-es/validateAddress.d.ts.map +1 -0
  98. package/lib-es/validateAddress.js +22 -0
  99. package/lib-es/validateAddress.js.map +1 -0
  100. package/lib-es/validateAddress.test.d.ts +2 -0
  101. package/lib-es/validateAddress.test.d.ts.map +1 -0
  102. package/lib-es/validateAddress.test.js +97 -0
  103. package/lib-es/validateAddress.test.js.map +1 -0
  104. package/package.json +10 -10
  105. package/src/bridge/index.ts +2 -0
  106. package/src/mock.ts +21 -11
  107. package/src/validateAddress.test.ts +132 -0
  108. package/src/validateAddress.ts +27 -0
  109. package/tsconfig.json +8 -2
@@ -0,0 +1,22 @@
1
+ import * as bech32 from "bech32";
2
+ import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets";
3
+ import cryptoFactory from "./chain/chain";
4
+ export async function validateAddress(address, parameters) {
5
+ if (!parameters.currency) {
6
+ throw new Error("Missing currency parameter on address validation for Cosmos");
7
+ }
8
+ let isValid = true;
9
+ try {
10
+ bech32.decode(address);
11
+ }
12
+ catch {
13
+ isValid = false;
14
+ }
15
+ const currency = findCryptoCurrencyById(parameters.currency.name.toLowerCase());
16
+ let prefix = "";
17
+ if (currency) {
18
+ prefix = cryptoFactory(currency.id).prefix;
19
+ }
20
+ return isValid && address.startsWith(prefix);
21
+ }
22
+ //# sourceMappingURL=validateAddress.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateAddress.js","sourceRoot":"","sources":["../src/validateAddress.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAChE,OAAO,aAAa,MAAM,eAAe,CAAC;AAE1C,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,OAAe,EACf,UAAwD;IAExD,IAAI,CAAC,UAAU,CAAC,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACjF,CAAC;IAED,IAAI,OAAO,GAAG,IAAI,CAAC;IACnB,IAAI,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACzB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,KAAK,CAAC;IAClB,CAAC;IACD,MAAM,QAAQ,GAAG,sBAAsB,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAChF,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;IAC7C,CAAC;IAED,OAAO,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=validateAddress.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateAddress.test.d.ts","sourceRoot":"","sources":["../src/validateAddress.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,97 @@
1
+ import { validateAddress } from "./validateAddress";
2
+ import * as bech32 from "bech32";
3
+ import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets";
4
+ import cryptoFactory from "./chain/chain";
5
+ jest.mock("bech32");
6
+ jest.mock("@ledgerhq/cryptoassets");
7
+ jest.mock("./chain/chain");
8
+ describe("validateAddress", () => {
9
+ const mockedDecode = jest.mocked(bech32.decode);
10
+ const mockedFindCryptoCurrencyById = jest.mocked(findCryptoCurrencyById);
11
+ const mockedCryptoFactory = jest.mocked(cryptoFactory);
12
+ beforeEach(() => {
13
+ mockedDecode.mockClear();
14
+ mockedFindCryptoCurrencyById.mockClear();
15
+ mockedCryptoFactory.mockClear();
16
+ });
17
+ it("should throw an error when currency parameters is not provided", async () => {
18
+ try {
19
+ await validateAddress("some random address", {});
20
+ }
21
+ catch (error) {
22
+ expect(error).toBeInstanceOf(Error);
23
+ expect(error.message).toEqual("Missing currency parameter on address validation for Cosmos");
24
+ }
25
+ });
26
+ it.each([true, false])("should only decode address when currency config not found and return expected value (%s)", async (expectedValue) => {
27
+ if (!expectedValue) {
28
+ mockedDecode.mockImplementationOnce(_address => {
29
+ throw new Error("Mocked Error from unit test");
30
+ });
31
+ }
32
+ mockedFindCryptoCurrencyById.mockReturnValueOnce(undefined);
33
+ const address = "some random address";
34
+ const parameters = {
35
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
36
+ currency: {
37
+ name: "cosmos",
38
+ },
39
+ };
40
+ const result = await validateAddress(address, parameters);
41
+ expect(result).toEqual(expectedValue);
42
+ expect(mockedDecode).toHaveBeenCalledTimes(1);
43
+ expect(mockedDecode).toHaveBeenCalledWith(address);
44
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledTimes(1);
45
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledWith(parameters.currency.name);
46
+ });
47
+ it.each([true, false])("should decode address, check prefix from currency config and return expected value (%s)", async (expectedValue) => {
48
+ const address = "cosmos: some random address";
49
+ const parameters = {
50
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
51
+ currency: {
52
+ id: "cosmos id",
53
+ name: "cosmos name",
54
+ },
55
+ };
56
+ mockedFindCryptoCurrencyById.mockReturnValueOnce(parameters.currency);
57
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
58
+ mockedCryptoFactory.mockReturnValueOnce({
59
+ prefix: expectedValue ? "cosmos" : "other",
60
+ });
61
+ const result = await validateAddress(address, parameters);
62
+ expect(result).toEqual(expectedValue);
63
+ expect(mockedDecode).toHaveBeenCalledTimes(1);
64
+ expect(mockedDecode).toHaveBeenCalledWith(address);
65
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledTimes(1);
66
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledWith(parameters.currency.name);
67
+ expect(mockedCryptoFactory).toHaveBeenCalledTimes(1);
68
+ expect(mockedCryptoFactory).toHaveBeenCalledWith(parameters.currency.id);
69
+ });
70
+ it("should return false when decode and prefix check fail", async () => {
71
+ mockedDecode.mockImplementationOnce(_address => {
72
+ throw new Error("Mocked Error from unit tests");
73
+ });
74
+ const address = "cosmos: some random address";
75
+ const parameters = {
76
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
77
+ currency: {
78
+ id: "cosmos id",
79
+ name: "cosmos name",
80
+ },
81
+ };
82
+ mockedFindCryptoCurrencyById.mockReturnValueOnce(parameters.currency);
83
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
84
+ mockedCryptoFactory.mockReturnValueOnce({
85
+ prefix: "juno:",
86
+ });
87
+ const result = await validateAddress(address, parameters);
88
+ expect(result).toEqual(false);
89
+ expect(mockedDecode).toHaveBeenCalledTimes(1);
90
+ expect(mockedDecode).toHaveBeenCalledWith(address);
91
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledTimes(1);
92
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledWith(parameters.currency.name);
93
+ expect(mockedCryptoFactory).toHaveBeenCalledTimes(1);
94
+ expect(mockedCryptoFactory).toHaveBeenCalledWith(parameters.currency.id);
95
+ });
96
+ });
97
+ //# sourceMappingURL=validateAddress.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validateAddress.test.js","sourceRoot":"","sources":["../src/validateAddress.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/coin-cosmos",
3
- "version": "0.21.0-nightly.20251210120335",
3
+ "version": "0.21.0-nightly.20251212024049",
4
4
  "description": "Ledger Cosmos Coin integration",
5
5
  "keywords": [
6
6
  "Ledger",
@@ -59,16 +59,16 @@
59
59
  "prando": "^6.0.1",
60
60
  "rxjs": "7.8.2",
61
61
  "semver": "^7.1.3",
62
- "@ledgerhq/coin-framework": "^6.11.0-nightly.20251210120335",
63
- "@ledgerhq/cryptoassets": "^13.35.0-nightly.20251210120335",
64
- "@ledgerhq/devices": "8.8.0-nightly.20251210120335",
65
- "@ledgerhq/errors": "^6.28.0-nightly.20251210120335",
66
- "@ledgerhq/live-config": "^3.3.0-nightly.20251210120335",
67
- "@ledgerhq/live-env": "^2.23.0-nightly.20251210120335",
68
- "@ledgerhq/live-network": "^2.1.3-nightly.20251210120335",
62
+ "@ledgerhq/coin-framework": "^6.11.0-nightly.20251212024049",
63
+ "@ledgerhq/cryptoassets": "^13.35.0-nightly.20251212024049",
64
+ "@ledgerhq/devices": "8.8.0-nightly.20251212024049",
65
+ "@ledgerhq/errors": "^6.28.0-nightly.20251212024049",
66
+ "@ledgerhq/live-config": "^3.3.0-nightly.20251212024049",
67
+ "@ledgerhq/live-env": "^2.23.0-nightly.20251212024049",
68
+ "@ledgerhq/live-network": "^2.1.3-nightly.20251212024049",
69
69
  "@ledgerhq/logs": "^6.13.0",
70
- "@ledgerhq/types-cryptoassets": "^7.31.0-nightly.20251210120335",
71
- "@ledgerhq/types-live": "^6.91.0-nightly.20251210120335"
70
+ "@ledgerhq/types-cryptoassets": "^7.31.0-nightly.20251212024049",
71
+ "@ledgerhq/types-live": "^6.91.0-nightly.20251212024049"
72
72
  },
73
73
  "devDependencies": {
74
74
  "@types/invariant": "^2.2.2",
@@ -29,6 +29,7 @@ import type { CosmosAccount, CosmosOperation, Transaction, TransactionStatus } f
29
29
  import { CosmosSigner } from "../types/signer";
30
30
  import { updateTransaction } from "../updateTransaction";
31
31
  import { getPreloadStrategy, hydrate, preload } from "./preload";
32
+ import { validateAddress } from "../validateAddress";
32
33
 
33
34
  const sync = makeSync({ getAccountShape });
34
35
 
@@ -80,6 +81,7 @@ function buildAccountBridge(
80
81
  formatAccountSpecifics: formatters.formatAccountSpecifics,
81
82
  formatOperationSpecifics: formatters.formatOperationSpecifics,
82
83
  getSerializedAddressParameters,
84
+ validateAddress,
83
85
  };
84
86
  }
85
87
 
package/src/mock.ts CHANGED
@@ -1,15 +1,16 @@
1
1
  import { BigNumber } from "bignumber.js";
2
2
  import Prando from "prando";
3
3
  import { genAddress, genHex } from "@ledgerhq/coin-framework/mocks/helpers";
4
- import type { OperationType } from "@ledgerhq/types-live";
4
+ import type { Account, OperationType } from "@ledgerhq/types-live";
5
5
  import preloadedData from "./preloadedData.mock";
6
- import type {
7
- CosmosAccount,
8
- CosmosDelegation,
9
- CosmosOperation,
10
- CosmosRedelegation,
11
- CosmosResources,
12
- CosmosUnbonding,
6
+ import {
7
+ isCosmosAccount,
8
+ type CosmosAccount,
9
+ type CosmosDelegation,
10
+ type CosmosOperation,
11
+ type CosmosRedelegation,
12
+ type CosmosResources,
13
+ type CosmosUnbonding,
13
14
  } from "./types";
14
15
  const { validators } = preloadedData;
15
16
 
@@ -340,7 +341,10 @@ function genAccountEnhanceOperations(account: CosmosAccount, rng: Prando): Cosmo
340
341
  * @memberof cosmos/mock
341
342
  * @param {CosmosAccount} account
342
343
  */
343
- function postSyncAccount(account: CosmosAccount): CosmosAccount {
344
+ function postSyncAccount(account: Account): Account {
345
+ if (!isCosmosAccount(account)) {
346
+ throw new Error("postSyncAccount must be called with a CosmosAccount type parameter");
347
+ }
344
348
  const cosmosResources = account?.cosmosResources;
345
349
  const delegatedBalance = cosmosResources?.delegatedBalance ?? new BigNumber(0);
346
350
  const unbondingBalance = cosmosResources?.unbondingBalance ?? new BigNumber(0);
@@ -355,13 +359,19 @@ function postSyncAccount(account: CosmosAccount): CosmosAccount {
355
359
  * @param {CosmosAccount} account
356
360
  */
357
361
  function postScanAccount(
358
- account: CosmosAccount,
362
+ account: Account,
359
363
  {
360
364
  isEmpty,
361
365
  }: {
362
366
  isEmpty: boolean;
363
367
  },
364
- ): CosmosAccount {
368
+ ): Account {
369
+ if (!isCosmosAccount(account)) {
370
+ throw new Error(
371
+ "postScanAccount from cosmos must be used with a CosmosAccount type as parameter",
372
+ );
373
+ }
374
+
365
375
  if (isEmpty) {
366
376
  account.cosmosResources = {
367
377
  delegations: [],
@@ -0,0 +1,132 @@
1
+ import { validateAddress } from "./validateAddress";
2
+ import * as bech32 from "bech32";
3
+ import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets";
4
+ import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
5
+ import cryptoFactory from "./chain/chain";
6
+ import cosmosBase from "./chain/cosmosBase";
7
+
8
+ jest.mock("bech32");
9
+ jest.mock("@ledgerhq/cryptoassets");
10
+ jest.mock("./chain/chain");
11
+
12
+ describe("validateAddress", () => {
13
+ const mockedDecode = jest.mocked(bech32.decode);
14
+ const mockedFindCryptoCurrencyById = jest.mocked(findCryptoCurrencyById);
15
+ const mockedCryptoFactory = jest.mocked(cryptoFactory);
16
+
17
+ beforeEach(() => {
18
+ mockedDecode.mockClear();
19
+ mockedFindCryptoCurrencyById.mockClear();
20
+ mockedCryptoFactory.mockClear();
21
+ });
22
+
23
+ it("should throw an error when currency parameters is not provided", async () => {
24
+ try {
25
+ await validateAddress("some random address", {});
26
+ } catch (error) {
27
+ expect(error).toBeInstanceOf(Error);
28
+ expect((error as Error).message).toEqual(
29
+ "Missing currency parameter on address validation for Cosmos",
30
+ );
31
+ }
32
+ });
33
+
34
+ it.each([true, false])(
35
+ "should only decode address when currency config not found and return expected value (%s)",
36
+ async (expectedValue: boolean) => {
37
+ if (!expectedValue) {
38
+ mockedDecode.mockImplementationOnce(_address => {
39
+ throw new Error("Mocked Error from unit test");
40
+ });
41
+ }
42
+
43
+ mockedFindCryptoCurrencyById.mockReturnValueOnce(undefined);
44
+ const address = "some random address";
45
+ const parameters = {
46
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
47
+ currency: {
48
+ name: "cosmos",
49
+ } as CryptoCurrency,
50
+ };
51
+
52
+ const result = await validateAddress(address, parameters);
53
+
54
+ expect(result).toEqual(expectedValue);
55
+
56
+ expect(mockedDecode).toHaveBeenCalledTimes(1);
57
+ expect(mockedDecode).toHaveBeenCalledWith(address);
58
+
59
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledTimes(1);
60
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledWith(parameters.currency.name);
61
+ },
62
+ );
63
+
64
+ it.each([true, false])(
65
+ "should decode address, check prefix from currency config and return expected value (%s)",
66
+ async (expectedValue: boolean) => {
67
+ const address = "cosmos: some random address";
68
+ const parameters = {
69
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
70
+ currency: {
71
+ id: "cosmos id",
72
+ name: "cosmos name",
73
+ } as CryptoCurrency,
74
+ };
75
+
76
+ mockedFindCryptoCurrencyById.mockReturnValueOnce(parameters.currency);
77
+
78
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
79
+ mockedCryptoFactory.mockReturnValueOnce({
80
+ prefix: expectedValue ? "cosmos" : "other",
81
+ } as unknown as cosmosBase);
82
+
83
+ const result = await validateAddress(address, parameters);
84
+
85
+ expect(result).toEqual(expectedValue);
86
+
87
+ expect(mockedDecode).toHaveBeenCalledTimes(1);
88
+ expect(mockedDecode).toHaveBeenCalledWith(address);
89
+
90
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledTimes(1);
91
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledWith(parameters.currency.name);
92
+
93
+ expect(mockedCryptoFactory).toHaveBeenCalledTimes(1);
94
+ expect(mockedCryptoFactory).toHaveBeenCalledWith(parameters.currency.id);
95
+ },
96
+ );
97
+
98
+ it("should return false when decode and prefix check fail", async () => {
99
+ mockedDecode.mockImplementationOnce(_address => {
100
+ throw new Error("Mocked Error from unit tests");
101
+ });
102
+
103
+ const address = "cosmos: some random address";
104
+ const parameters = {
105
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
106
+ currency: {
107
+ id: "cosmos id",
108
+ name: "cosmos name",
109
+ } as CryptoCurrency,
110
+ };
111
+
112
+ mockedFindCryptoCurrencyById.mockReturnValueOnce(parameters.currency);
113
+
114
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
115
+ mockedCryptoFactory.mockReturnValueOnce({
116
+ prefix: "juno:",
117
+ } as unknown as cosmosBase);
118
+
119
+ const result = await validateAddress(address, parameters);
120
+
121
+ expect(result).toEqual(false);
122
+
123
+ expect(mockedDecode).toHaveBeenCalledTimes(1);
124
+ expect(mockedDecode).toHaveBeenCalledWith(address);
125
+
126
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledTimes(1);
127
+ expect(mockedFindCryptoCurrencyById).toHaveBeenCalledWith(parameters.currency.name);
128
+
129
+ expect(mockedCryptoFactory).toHaveBeenCalledTimes(1);
130
+ expect(mockedCryptoFactory).toHaveBeenCalledWith(parameters.currency.id);
131
+ });
132
+ });
@@ -0,0 +1,27 @@
1
+ import { AddressValidationCurrencyParameters } from "@ledgerhq/types-live";
2
+ import * as bech32 from "bech32";
3
+ import { findCryptoCurrencyById } from "@ledgerhq/cryptoassets";
4
+ import cryptoFactory from "./chain/chain";
5
+
6
+ export async function validateAddress(
7
+ address: string,
8
+ parameters: Partial<AddressValidationCurrencyParameters>,
9
+ ): Promise<boolean> {
10
+ if (!parameters.currency) {
11
+ throw new Error("Missing currency parameter on address validation for Cosmos");
12
+ }
13
+
14
+ let isValid = true;
15
+ try {
16
+ bech32.decode(address);
17
+ } catch {
18
+ isValid = false;
19
+ }
20
+ const currency = findCryptoCurrencyById(parameters.currency.name.toLowerCase());
21
+ let prefix = "";
22
+ if (currency) {
23
+ prefix = cryptoFactory(currency.id).prefix;
24
+ }
25
+
26
+ return isValid && address.startsWith(prefix);
27
+ }
package/tsconfig.json CHANGED
@@ -4,9 +4,15 @@
4
4
  "declaration": true,
5
5
  "declarationMap": true,
6
6
  "downlevelIteration": true,
7
- "lib": ["es2020", "dom"],
7
+ "lib": [
8
+ "es2020",
9
+ "dom"
10
+ ],
8
11
  "outDir": "lib",
9
12
  "exactOptionalPropertyTypes": true
10
13
  },
11
- "include": ["src/**/*"]
14
+ "include": [
15
+ "src/**/*"
16
+ ],
17
+ "exclude": []
12
18
  }