@ledgerhq/coin-solana 0.37.0 → 0.38.0-nightly.20251126160702

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 (156) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/lib/bridge/bridge.d.ts +2 -4
  3. package/lib/bridge/bridge.d.ts.map +1 -1
  4. package/lib/bridge/bridge.js +16 -16
  5. package/lib/bridge/bridge.js.map +1 -1
  6. package/lib/bridge/js.d.ts +1 -2
  7. package/lib/bridge/js.d.ts.map +1 -1
  8. package/lib/bridge/js.js +9 -11
  9. package/lib/bridge/js.js.map +1 -1
  10. package/lib/cli-transaction.js +2 -2
  11. package/lib/cli-transaction.js.map +1 -1
  12. package/lib/config.d.ts +0 -1
  13. package/lib/config.d.ts.map +1 -1
  14. package/lib/config.js.map +1 -1
  15. package/lib/helpers/token.js +2 -2
  16. package/lib/helpers/token.js.map +1 -1
  17. package/lib/network/chain/index.d.ts.map +1 -1
  18. package/lib/network/chain/index.js +29 -38
  19. package/lib/network/chain/index.js.map +1 -1
  20. package/lib/network/chain/web3.d.ts.map +1 -1
  21. package/lib/network/chain/web3.js +9 -5
  22. package/lib/network/chain/web3.js.map +1 -1
  23. package/lib/network/index.d.ts +0 -2
  24. package/lib/network/index.d.ts.map +1 -1
  25. package/lib/network/index.js +1 -5
  26. package/lib/network/index.js.map +1 -1
  27. package/lib/network/nft/index.js +3 -3
  28. package/lib/network/nft/index.js.map +1 -1
  29. package/lib/preload-data.d.ts.map +1 -1
  30. package/lib/preload-data.js +0 -1
  31. package/lib/preload-data.js.map +1 -1
  32. package/lib/preload.d.ts +2 -6
  33. package/lib/preload.d.ts.map +1 -1
  34. package/lib/preload.js +2 -107
  35. package/lib/preload.js.map +1 -1
  36. package/lib/prepareTransaction.js +2 -2
  37. package/lib/prepareTransaction.js.map +1 -1
  38. package/lib/signOperation.d.ts +1 -1
  39. package/lib/signOperation.d.ts.map +1 -1
  40. package/lib/signOperation.js +1 -1
  41. package/lib/signOperation.js.map +1 -1
  42. package/lib/synchronization.d.ts.map +1 -1
  43. package/lib/synchronization.js +11 -7
  44. package/lib/synchronization.js.map +1 -1
  45. package/lib/transaction.js +2 -2
  46. package/lib/transaction.js.map +1 -1
  47. package/lib/types.d.ts +0 -2
  48. package/lib/types.d.ts.map +1 -1
  49. package/lib-es/bridge/bridge.d.ts +2 -4
  50. package/lib-es/bridge/bridge.d.ts.map +1 -1
  51. package/lib-es/bridge/bridge.js +17 -17
  52. package/lib-es/bridge/bridge.js.map +1 -1
  53. package/lib-es/bridge/js.d.ts +1 -2
  54. package/lib-es/bridge/js.d.ts.map +1 -1
  55. package/lib-es/bridge/js.js +10 -12
  56. package/lib-es/bridge/js.js.map +1 -1
  57. package/lib-es/cli-transaction.js +1 -1
  58. package/lib-es/cli-transaction.js.map +1 -1
  59. package/lib-es/config.d.ts +0 -1
  60. package/lib-es/config.d.ts.map +1 -1
  61. package/lib-es/config.js.map +1 -1
  62. package/lib-es/helpers/token.js +1 -1
  63. package/lib-es/helpers/token.js.map +1 -1
  64. package/lib-es/network/chain/index.d.ts.map +1 -1
  65. package/lib-es/network/chain/index.js +29 -38
  66. package/lib-es/network/chain/index.js.map +1 -1
  67. package/lib-es/network/chain/web3.d.ts.map +1 -1
  68. package/lib-es/network/chain/web3.js +9 -5
  69. package/lib-es/network/chain/web3.js.map +1 -1
  70. package/lib-es/network/index.d.ts +0 -2
  71. package/lib-es/network/index.d.ts.map +1 -1
  72. package/lib-es/network/index.js +0 -2
  73. package/lib-es/network/index.js.map +1 -1
  74. package/lib-es/network/nft/index.js +1 -1
  75. package/lib-es/network/nft/index.js.map +1 -1
  76. package/lib-es/preload-data.d.ts.map +1 -1
  77. package/lib-es/preload-data.js +0 -1
  78. package/lib-es/preload-data.js.map +1 -1
  79. package/lib-es/preload.d.ts +2 -6
  80. package/lib-es/preload.d.ts.map +1 -1
  81. package/lib-es/preload.js +2 -81
  82. package/lib-es/preload.js.map +1 -1
  83. package/lib-es/prepareTransaction.js +1 -1
  84. package/lib-es/prepareTransaction.js.map +1 -1
  85. package/lib-es/signOperation.d.ts +1 -1
  86. package/lib-es/signOperation.d.ts.map +1 -1
  87. package/lib-es/signOperation.js +1 -1
  88. package/lib-es/signOperation.js.map +1 -1
  89. package/lib-es/synchronization.d.ts.map +1 -1
  90. package/lib-es/synchronization.js +10 -6
  91. package/lib-es/synchronization.js.map +1 -1
  92. package/lib-es/transaction.js +1 -1
  93. package/lib-es/transaction.js.map +1 -1
  94. package/lib-es/types.d.ts +0 -2
  95. package/lib-es/types.d.ts.map +1 -1
  96. package/package.json +6 -8
  97. package/src/__tests__/getTransactions.test.ts +81 -0
  98. package/src/__tests__/unit/hw-signMessage.unit.test.ts +0 -1
  99. package/src/bridge/bridge.ts +27 -35
  100. package/src/bridge/js.ts +9 -29
  101. package/src/cli-transaction.ts +1 -1
  102. package/src/config.ts +0 -1
  103. package/src/helpers/token.ts +1 -1
  104. package/src/network/chain/index.ts +29 -38
  105. package/src/network/chain/web3.integration.test.ts +21 -1
  106. package/src/network/chain/web3.ts +11 -5
  107. package/src/network/index.ts +0 -2
  108. package/src/network/nft/index.ts +1 -1
  109. package/src/preload-data.ts +0 -1
  110. package/src/preload.test.ts +121 -12
  111. package/src/preload.ts +2 -111
  112. package/src/prepareTransaction.ts +1 -1
  113. package/src/signOperation.test.ts +2 -2
  114. package/src/signOperation.ts +2 -2
  115. package/src/synchronization.ts +10 -6
  116. package/src/tests/tokens-bridge.unit.test.ts +11 -16
  117. package/src/transaction.ts +1 -1
  118. package/src/types.ts +0 -2
  119. package/lib/cryptoAssetsStore.d.ts +0 -5
  120. package/lib/cryptoAssetsStore.d.ts.map +0 -1
  121. package/lib/cryptoAssetsStore.js +0 -17
  122. package/lib/cryptoAssetsStore.js.map +0 -1
  123. package/lib/network/cached.d.ts +0 -3
  124. package/lib/network/cached.d.ts.map +0 -1
  125. package/lib/network/cached.js +0 -56
  126. package/lib/network/cached.js.map +0 -1
  127. package/lib/network/queued.d.ts +0 -3
  128. package/lib/network/queued.d.ts.map +0 -1
  129. package/lib/network/queued.js +0 -27
  130. package/lib/network/queued.js.map +0 -1
  131. package/lib/network/traced.d.ts +0 -3
  132. package/lib/network/traced.d.ts.map +0 -1
  133. package/lib/network/traced.js +0 -80
  134. package/lib/network/traced.js.map +0 -1
  135. package/lib-es/cryptoAssetsStore.d.ts +0 -5
  136. package/lib-es/cryptoAssetsStore.d.ts.map +0 -1
  137. package/lib-es/cryptoAssetsStore.js +0 -12
  138. package/lib-es/cryptoAssetsStore.js.map +0 -1
  139. package/lib-es/network/cached.d.ts +0 -3
  140. package/lib-es/network/cached.d.ts.map +0 -1
  141. package/lib-es/network/cached.js +0 -49
  142. package/lib-es/network/cached.js.map +0 -1
  143. package/lib-es/network/queued.d.ts +0 -3
  144. package/lib-es/network/queued.d.ts.map +0 -1
  145. package/lib-es/network/queued.js +0 -23
  146. package/lib-es/network/queued.js.map +0 -1
  147. package/lib-es/network/traced.d.ts +0 -3
  148. package/lib-es/network/traced.d.ts.map +0 -1
  149. package/lib-es/network/traced.js +0 -76
  150. package/lib-es/network/traced.js.map +0 -1
  151. package/src/cryptoAssetsStore.test.ts +0 -19
  152. package/src/cryptoAssetsStore.ts +0 -16
  153. package/src/network/cached.ts +0 -111
  154. package/src/network/queued.ts +0 -25
  155. package/src/network/traced.ts +0 -89
  156. package/src/tests/preload.unit.test.ts +0 -182
@@ -1,3 +0,0 @@
1
- import { ChainAPI } from "./chain";
2
- export declare function queued(api: ChainAPI, delayBetweenRuns?: number): ChainAPI;
3
- //# sourceMappingURL=queued.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"queued.d.ts","sourceRoot":"","sources":["../../src/network/queued.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,wBAAgB,MAAM,CAAC,GAAG,EAAE,QAAQ,EAAE,gBAAgB,SAAM,GAAG,QAAQ,CAqBtE"}
@@ -1,23 +0,0 @@
1
- import { asyncQueue } from "../utils";
2
- export function queued(api, delayBetweenRuns = 100) {
3
- const q = asyncQueue({
4
- delayBetweenRuns,
5
- });
6
- const proxy = new Proxy(api, {
7
- get(target, propKey, receiver) {
8
- const targetValue = Reflect.get(target, propKey, receiver);
9
- if (typeof targetValue === "function") {
10
- return function (...args) {
11
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
12
- // @ts-ignore: TS-2683
13
- return q.submit(() => targetValue.apply(this, args));
14
- };
15
- }
16
- else {
17
- return targetValue;
18
- }
19
- },
20
- });
21
- return proxy;
22
- }
23
- //# sourceMappingURL=queued.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"queued.js","sourceRoot":"","sources":["../../src/network/queued.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAGtC,MAAM,UAAU,MAAM,CAAC,GAAa,EAAE,gBAAgB,GAAG,GAAG;IAC1D,MAAM,CAAC,GAAG,UAAU,CAAC;QACnB,gBAAgB;KACjB,CAAC,CAAC;IAEH,MAAM,KAAK,GAAa,IAAI,KAAK,CAAC,GAAG,EAAE;QACrC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ;YAC3B,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC3D,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;gBACtC,OAAO,UAAU,GAAG,IAAe;oBACjC,6DAA6D;oBAC7D,sBAAsB;oBACtB,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC;gBACvD,CAAC,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACN,OAAO,WAAW,CAAC;YACrB,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,3 +0,0 @@
1
- import { ChainAPI } from "./chain";
2
- export declare function traced(api: ChainAPI): ChainAPI;
3
- //# sourceMappingURL=traced.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"traced.d.ts","sourceRoot":"","sources":["../../src/network/traced.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,wBAAgB,MAAM,CAAC,GAAG,EAAE,QAAQ,GAAG,QAAQ,CA0E9C"}
@@ -1,76 +0,0 @@
1
- import { log } from "@ledgerhq/logs";
2
- import { getEnv } from "@ledgerhq/live-env";
3
- export function traced(api) {
4
- const state = {
5
- reqId: 0,
6
- reqStartTime: new Map(),
7
- };
8
- const startReqTrace = () => {
9
- state.reqId += 1;
10
- state.reqStartTime.set(state.reqId, Date.now());
11
- return state.reqId;
12
- };
13
- const stopReqTrace = (reqId) => {
14
- const reqStartTime = state.reqStartTime.get(reqId);
15
- if (reqStartTime === undefined) {
16
- log("warn", `request start time not found for request id <${reqId}>`);
17
- return {
18
- duration: 0,
19
- };
20
- }
21
- state.reqStartTime.delete(reqId);
22
- return {
23
- duration: Date.now() - reqStartTime,
24
- };
25
- };
26
- const proxy = new Proxy(api, {
27
- get(target, propKey, receiver) {
28
- if (typeof propKey === "symbol") {
29
- throw new Error("symbols not supported");
30
- }
31
- const targetValue = Reflect.get(target, propKey, receiver);
32
- if (typeof targetValue === "function") {
33
- return function (...args) {
34
- const reqId = startReqTrace();
35
- log("network", formatMsg({ reqId, msg: `calling <${propKey}>` }), {
36
- args,
37
- });
38
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
39
- // @ts-ignore: TS-2683
40
- const result = targetValue.apply(this, args);
41
- if (result instanceof Promise) {
42
- return result
43
- .then(answer => {
44
- const { duration } = stopReqTrace(reqId);
45
- log("network-success", formatMsg({ reqId, msg: "success", duration }), getEnv("DEBUG_HTTP_RESPONSE") ? { answer } : undefined);
46
- return answer;
47
- })
48
- .catch(error => {
49
- const { duration } = stopReqTrace(reqId);
50
- log("network-error", formatMsg({ reqId, msg: "error", duration }), { error });
51
- throw error;
52
- });
53
- }
54
- else {
55
- const { duration } = stopReqTrace(reqId);
56
- log("info", formatMsg({ reqId, msg: "sync result", duration }), getEnv("DEBUG_HTTP_RESPONSE") ? { result } : undefined);
57
- return result;
58
- }
59
- };
60
- }
61
- else {
62
- return targetValue;
63
- }
64
- },
65
- });
66
- return proxy;
67
- }
68
- function formatMsg({ reqId, msg, duration }) {
69
- const parts = [
70
- `solana req id: ${reqId}`,
71
- msg ?? "",
72
- duration === undefined ? "" : `took ${duration.toFixed(0)}ms`,
73
- ];
74
- return parts.join(", ");
75
- }
76
- //# sourceMappingURL=traced.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"traced.js","sourceRoot":"","sources":["../../src/network/traced.ts"],"names":[],"mappings":"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"}
@@ -1,19 +0,0 @@
1
- import { CryptoAssetsStore } from "@ledgerhq/types-live";
2
- import {
3
- CRYPTO_ASSETS_STORE_NO_SET_ERROR_MESSAGE,
4
- getCryptoAssetsStore,
5
- setCryptoAssetsStoreGetter,
6
- } from "./cryptoAssetsStore";
7
-
8
- describe("cryptoAssetsStore", () => {
9
- it("should throw an error when CryptoAssetsStoreGetter is not set", () => {
10
- expect(() => getCryptoAssetsStore()).toThrow(CRYPTO_ASSETS_STORE_NO_SET_ERROR_MESSAGE);
11
- });
12
-
13
- it("should return the CryptoAssetsStoreGetter set", () => {
14
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
15
- const store = {} as CryptoAssetsStore;
16
- setCryptoAssetsStoreGetter(() => store);
17
- expect(getCryptoAssetsStore()).toEqual(store);
18
- });
19
- });
@@ -1,16 +0,0 @@
1
- import { CryptoAssetsStore, CryptoAssetsStoreGetter } from "@ledgerhq/types-live";
2
-
3
- export const CRYPTO_ASSETS_STORE_NO_SET_ERROR_MESSAGE =
4
- "CryptoAssetsStore is not set. Please call setCryptoAssetsStore first on coin solana";
5
-
6
- let getStore: CryptoAssetsStoreGetter;
7
- export function setCryptoAssetsStoreGetter(cryptoAssetsStoreGetter: CryptoAssetsStoreGetter): void {
8
- getStore = cryptoAssetsStoreGetter;
9
- }
10
-
11
- export function getCryptoAssetsStore(): CryptoAssetsStore {
12
- if (!getStore) {
13
- throw new Error(CRYPTO_ASSETS_STORE_NO_SET_ERROR_MESSAGE);
14
- }
15
- return getStore();
16
- }
@@ -1,111 +0,0 @@
1
- import { makeLRUCache, minutes, seconds } from "@ledgerhq/live-network/cache";
2
- import { PublicKey, TransactionInstruction, TransactionMessage } from "@solana/web3.js";
3
- import hash from "object-hash";
4
- import { ChainAPI } from "./chain";
5
-
6
- const cacheKeyAddress = (address: string) => address;
7
- const cacheKeyEmpty = () => "" as const;
8
- const cacheKeyAssocTokenAccAddress = (owner: string, mint: string) => `${owner}:${mint}`;
9
- const cacheKeyMinimumBalanceForRentExemption = (dataLengt: number) => dataLengt.toString();
10
-
11
- const cacheKeyTransactions = (signatures: string[]) => hash([...signatures].sort());
12
- const cacheKeyAddresses = (addresses: string[]) => hash([...addresses].sort());
13
- const cacheKeyInstructions = (ixs: TransactionInstruction[], payer: PublicKey) => {
14
- return hash(
15
- new TransactionMessage({
16
- instructions: ixs,
17
- payerKey: payer,
18
- recentBlockhash: payer.toString(),
19
- })
20
- .compileToLegacyMessage()
21
- .serialize(),
22
- );
23
- };
24
-
25
- const cacheKeyByArgs = (...args: unknown[]) => hash(args);
26
-
27
- export function cached(api: ChainAPI): ChainAPI {
28
- return {
29
- findAssocTokenAccAddress: makeLRUCache(
30
- api.findAssocTokenAccAddress,
31
- cacheKeyAssocTokenAccAddress,
32
- minutes(1000),
33
- ),
34
-
35
- getAccountInfo: makeLRUCache(api.getAccountInfo, cacheKeyAddress, seconds(30)),
36
-
37
- getMultipleAccounts: makeLRUCache(api.getMultipleAccounts, cacheKeyAddresses, seconds(30)),
38
-
39
- getAssocTokenAccMinNativeBalance: makeLRUCache(
40
- api.getAssocTokenAccMinNativeBalance,
41
- cacheKeyEmpty,
42
- minutes(5),
43
- ),
44
-
45
- getBalance: makeLRUCache(api.getBalance, cacheKeyAddress, seconds(30)),
46
-
47
- getBalanceAndContext: makeLRUCache(api.getBalanceAndContext, cacheKeyAddress, seconds(30)),
48
-
49
- getParsedTransactions: makeLRUCache(
50
- api.getParsedTransactions,
51
- cacheKeyTransactions,
52
- seconds(30),
53
- ),
54
-
55
- getParsedTokenAccountsByOwner: makeLRUCache(
56
- api.getParsedTokenAccountsByOwner,
57
- cacheKeyAddress,
58
- minutes(1),
59
- ),
60
-
61
- getParsedToken2022AccountsByOwner: makeLRUCache(
62
- api.getParsedToken2022AccountsByOwner,
63
- cacheKeyAddress,
64
- minutes(1),
65
- ),
66
-
67
- // cached by default in api
68
- getStakeAccountsByStakeAuth: api.getStakeAccountsByStakeAuth,
69
- getStakeAccountsByWithdrawAuth: api.getStakeAccountsByWithdrawAuth,
70
-
71
- getInflationReward: makeLRUCache(api.getInflationReward, cacheKeyByArgs, minutes(5)),
72
-
73
- getVoteAccounts: makeLRUCache(api.getVoteAccounts, cacheKeyEmpty, minutes(1)),
74
-
75
- getLatestBlockhash: makeLRUCache(api.getLatestBlockhash, cacheKeyEmpty, seconds(15)),
76
-
77
- getFeeForMessage: makeLRUCache(
78
- api.getFeeForMessage,
79
- msg => msg.serialize().toString(),
80
- minutes(1),
81
- ),
82
-
83
- getSignaturesForAddress: makeLRUCache(api.getSignaturesForAddress, cacheKeyByArgs, seconds(30)),
84
-
85
- getMinimumBalanceForRentExemption: makeLRUCache(
86
- api.getMinimumBalanceForRentExemption,
87
- cacheKeyMinimumBalanceForRentExemption,
88
- minutes(5),
89
- ),
90
-
91
- // do not cache
92
- sendRawTransaction: api.sendRawTransaction,
93
-
94
- getEpochInfo: makeLRUCache(api.getEpochInfo, cacheKeyEmpty, minutes(1)),
95
-
96
- getRecentPrioritizationFees: makeLRUCache(
97
- api.getRecentPrioritizationFees,
98
- cacheKeyByArgs,
99
- seconds(30),
100
- ),
101
-
102
- getSimulationComputeUnits: makeLRUCache(
103
- api.getSimulationComputeUnits,
104
- cacheKeyInstructions,
105
- seconds(30),
106
- ),
107
-
108
- config: api.config,
109
- connection: api.connection,
110
- };
111
- }
@@ -1,25 +0,0 @@
1
- import { asyncQueue } from "../utils";
2
- import { ChainAPI } from "./chain";
3
-
4
- export function queued(api: ChainAPI, delayBetweenRuns = 100): ChainAPI {
5
- const q = asyncQueue({
6
- delayBetweenRuns,
7
- });
8
-
9
- const proxy: ChainAPI = new Proxy(api, {
10
- get(target, propKey, receiver) {
11
- const targetValue = Reflect.get(target, propKey, receiver);
12
- if (typeof targetValue === "function") {
13
- return function (...args: unknown[]) {
14
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
15
- // @ts-ignore: TS-2683
16
- return q.submit(() => targetValue.apply(this, args));
17
- };
18
- } else {
19
- return targetValue;
20
- }
21
- },
22
- });
23
-
24
- return proxy;
25
- }
@@ -1,89 +0,0 @@
1
- import { log } from "@ledgerhq/logs";
2
- import { getEnv } from "@ledgerhq/live-env";
3
- import { ChainAPI } from "./chain";
4
-
5
- export function traced(api: ChainAPI): ChainAPI {
6
- const state = {
7
- reqId: 0,
8
- reqStartTime: new Map<number, number>(),
9
- };
10
-
11
- const startReqTrace = () => {
12
- state.reqId += 1;
13
- state.reqStartTime.set(state.reqId, Date.now());
14
- return state.reqId;
15
- };
16
-
17
- const stopReqTrace = (reqId: number) => {
18
- const reqStartTime = state.reqStartTime.get(reqId);
19
- if (reqStartTime === undefined) {
20
- log("warn", `request start time not found for request id <${reqId}>`);
21
- return {
22
- duration: 0,
23
- };
24
- }
25
- state.reqStartTime.delete(reqId);
26
- return {
27
- duration: Date.now() - reqStartTime,
28
- };
29
- };
30
-
31
- const proxy: ChainAPI = new Proxy(api, {
32
- get(target, propKey, receiver) {
33
- if (typeof propKey === "symbol") {
34
- throw new Error("symbols not supported");
35
- }
36
- const targetValue = Reflect.get(target, propKey, receiver);
37
- if (typeof targetValue === "function") {
38
- return function (...args: unknown[]) {
39
- const reqId = startReqTrace();
40
- log("network", formatMsg({ reqId, msg: `calling <${propKey}>` }), {
41
- args,
42
- });
43
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
44
- // @ts-ignore: TS-2683
45
- const result = targetValue.apply(this, args);
46
- if (result instanceof Promise) {
47
- return result
48
- .then(answer => {
49
- const { duration } = stopReqTrace(reqId);
50
- log(
51
- "network-success",
52
- formatMsg({ reqId, msg: "success", duration }),
53
- getEnv("DEBUG_HTTP_RESPONSE") ? { answer } : undefined,
54
- );
55
- return answer;
56
- })
57
- .catch(error => {
58
- const { duration } = stopReqTrace(reqId);
59
- log("network-error", formatMsg({ reqId, msg: "error", duration }), { error });
60
- throw error;
61
- });
62
- } else {
63
- const { duration } = stopReqTrace(reqId);
64
- log(
65
- "info",
66
- formatMsg({ reqId, msg: "sync result", duration }),
67
- getEnv("DEBUG_HTTP_RESPONSE") ? { result } : undefined,
68
- );
69
- return result;
70
- }
71
- };
72
- } else {
73
- return targetValue;
74
- }
75
- },
76
- });
77
-
78
- return proxy;
79
- }
80
-
81
- function formatMsg({ reqId, msg, duration }: { reqId: number; msg?: string; duration?: number }) {
82
- const parts = [
83
- `solana req id: ${reqId}`,
84
- msg ?? "",
85
- duration === undefined ? "" : `took ${duration.toFixed(0)}ms`,
86
- ];
87
-
88
- return parts.join(", ");
89
- }
@@ -1,182 +0,0 @@
1
- jest.useFakeTimers();
2
-
3
- import { jlpDefinition, soEthDefinition, graphitDefinition } from "./preload.fixtures";
4
- import axios, { AxiosResponse } from "axios";
5
- import {
6
- convertSplTokens,
7
- __clearAllLists,
8
- addTokens,
9
- } from "@ledgerhq/cryptoassets/legacy/legacy-utils";
10
- import { fetchSPLTokens, hydrate, preloadWithAPI } from "../preload";
11
- import { __resetCALHash, getCALHash, setCALHash } from "../logic";
12
- import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
13
- import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets";
14
- import { ChainAPI } from "../network";
15
-
16
- jest.mock("axios");
17
- const mockedAxios = jest.mocked(axios);
18
- mockedAxios.AxiosError = jest.requireActual("axios").AxiosError;
19
-
20
- jest.mock("@ledgerhq/cryptoassets/legacy/legacy-utils", () => {
21
- const actual = jest.requireActual("@ledgerhq/cryptoassets/legacy/legacy-utils");
22
- return {
23
- ...actual,
24
- addTokens: jest.fn(),
25
- };
26
- });
27
-
28
- jest.mock("@ledgerhq/cryptoassets/data/spl", () => ({
29
- __esModule: true, // Ensures the mock is treated as an ES module
30
- default: [jlpDefinition, soEthDefinition], // Mocked as an array
31
-
32
- get hash() {
33
- return "initialStateSolana"; // Mocked hash value
34
- },
35
- }));
36
- const mockCurrency: CryptoCurrency = getCryptoCurrencyById("solana");
37
-
38
- const mockAPI = {
39
- getVoteAccounts: jest.fn(),
40
- } as unknown as ChainAPI;
41
-
42
- const mockGetAPI = jest.fn(() => Promise.resolve(mockAPI));
43
- jest.mock("../network/validator-app", () => ({
44
- getValidators: jest.fn(() => [{ commission: 50 }, { commission: 90 }, { commission: 110 }]),
45
- }));
46
-
47
- describe("Solana Family", () => {
48
- beforeEach(() => {
49
- __clearAllLists();
50
- mockedAxios.get.mockImplementation(async (url, { params, headers } = {}) => {
51
- if (url !== "https://crypto-assets-service.api.ledger.com/v1/tokens")
52
- throw new Error("UNEXPECTED URL");
53
-
54
- if (params.blockchain_name === "solana") {
55
- if (headers?.["If-None-Match"] === "newStateSolana")
56
- throw new axios.AxiosError("", "", undefined, undefined, {
57
- status: 304,
58
- } as AxiosResponse);
59
-
60
- return {
61
- data: [jlpDefinition, soEthDefinition].map(tokenDef => ({
62
- network: tokenDef[1],
63
- id: tokenDef[0],
64
- ticker: tokenDef[3],
65
- decimals: tokenDef[5],
66
- name: tokenDef[2],
67
- contract_address: tokenDef[4],
68
- })),
69
- headers: { ["etag"]: "newStateSolana" },
70
- };
71
- }
72
- });
73
- });
74
-
75
- afterEach(() => {
76
- jest.restoreAllMocks();
77
- __resetCALHash();
78
- });
79
-
80
- describe("fetchSPLTokens", () => {
81
- beforeEach(() => {
82
- jest.mocked(addTokens).mockClear();
83
- });
84
- it("should return the embedded tokens if there is no update on remote and tokens are not loaded", async () => {
85
- mockedAxios.get.mockImplementationOnce((url, { headers } = {}) => {
86
- if (headers?.["If-None-Match"] === "initialStateSolana")
87
- throw new axios.AxiosError("", "", undefined, undefined, {
88
- status: 304,
89
- } as AxiosResponse);
90
- throw new Error("unexpected");
91
- });
92
-
93
- expect(getCALHash(mockCurrency)).toBe("");
94
- const tokens = await fetchSPLTokens(mockCurrency);
95
- expect(tokens).toEqual([jlpDefinition, soEthDefinition]);
96
- expect(getCALHash(mockCurrency)).toBe("initialStateSolana");
97
- });
98
-
99
- it("should return nothing if loaded tokens are up to date with remote already", async () => {
100
- setCALHash(mockCurrency, "newStateSolana");
101
-
102
- const tokens = await fetchSPLTokens(mockCurrency);
103
- expect(tokens).toEqual(null);
104
- expect(getCALHash(mockCurrency)).toBe("newStateSolana");
105
- });
106
-
107
- it("should return the content of the remote CAL", async () => {
108
- setCALHash(mockCurrency, "initialStateSolana");
109
-
110
- const tokens = await fetchSPLTokens(mockCurrency);
111
- expect(tokens).toEqual([jlpDefinition, soEthDefinition]);
112
- expect(getCALHash(mockCurrency)).toBe("newStateSolana");
113
- });
114
-
115
- it("should return nothing and maintain the saved CAL hash if the CAL service is down", async () => {
116
- mockedAxios.get.mockImplementation(() => {
117
- throw new Error();
118
- });
119
-
120
- setCALHash(mockCurrency, "anything");
121
- const tokens = await fetchSPLTokens(mockCurrency);
122
- expect(tokens).toEqual(null);
123
- expect(getCALHash(mockCurrency)).toBe("anything");
124
- });
125
- });
126
-
127
- describe("preloadWithAPI", () => {
128
- beforeEach(() => {
129
- jest.mocked(addTokens).mockClear();
130
- });
131
-
132
- it("should return void when fetch is hitting cache", async () => {
133
- setCALHash(mockCurrency, "newStateSolana");
134
- const data = await preloadWithAPI(mockCurrency, mockGetAPI);
135
- expect(data.splTokens).toEqual(null);
136
- expect(addTokens).not.toHaveBeenCalled();
137
- });
138
-
139
- it("should return and register the new SPL tokens", async () => {
140
- setCALHash(mockCurrency, "initialStateSolana");
141
- const data = await preloadWithAPI(mockCurrency, mockGetAPI);
142
- expect(data.splTokens).toEqual([jlpDefinition, soEthDefinition]);
143
- expect(addTokens).toHaveBeenCalledTimes(1);
144
- expect(addTokens).toHaveBeenCalledWith([
145
- convertSplTokens(jlpDefinition),
146
- convertSplTokens(soEthDefinition),
147
- ]);
148
- });
149
- });
150
-
151
- describe("hydrate", () => {
152
- beforeEach(() => {
153
- jest.mocked(addTokens).mockClear();
154
- });
155
-
156
- it("should not do anything", async () => {
157
- hydrate(undefined, mockCurrency);
158
- expect(addTokens).toHaveBeenCalledTimes(0);
159
- });
160
-
161
- it("should register SPL tokens from embedded with null", async () => {
162
- hydrate(
163
- { version: "1", validators: [], validatorsWithMeta: [], splTokens: null },
164
- mockCurrency,
165
- );
166
-
167
- expect(addTokens).toHaveBeenCalledWith([
168
- convertSplTokens(jlpDefinition),
169
- convertSplTokens(soEthDefinition),
170
- ]);
171
- });
172
-
173
- it("should register SPL tokens", async () => {
174
- hydrate(
175
- { version: "1", validators: [], validatorsWithMeta: [], splTokens: [graphitDefinition] },
176
- mockCurrency,
177
- );
178
-
179
- expect(addTokens).toHaveBeenCalledWith([convertSplTokens(graphitDefinition)]);
180
- });
181
- });
182
- });