@ledgerhq/coin-hedera 1.6.7-next.0 → 1.6.7-nightly.1

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 (66) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.unimportedrc.json +1 -0
  3. package/CHANGELOG.md +10 -10
  4. package/lib/api/mirror.d.ts +16 -3
  5. package/lib/api/mirror.d.ts.map +1 -1
  6. package/lib/api/mirror.js +29 -10
  7. package/lib/api/mirror.js.map +1 -1
  8. package/lib/api/mirror.test.d.ts +2 -0
  9. package/lib/api/mirror.test.d.ts.map +1 -0
  10. package/lib/api/mirror.test.js +60 -0
  11. package/lib/api/mirror.test.js.map +1 -0
  12. package/lib/bridge/broadcast.d.ts.map +1 -1
  13. package/lib/bridge/broadcast.js +7 -1
  14. package/lib/bridge/broadcast.js.map +1 -1
  15. package/lib/bridge/synchronisation.js +3 -3
  16. package/lib/bridge/synchronisation.js.map +1 -1
  17. package/lib/bridge/utils.d.ts +3 -2
  18. package/lib/bridge/utils.d.ts.map +1 -1
  19. package/lib/bridge/utils.js +10 -1
  20. package/lib/bridge/utils.js.map +1 -1
  21. package/lib/logic.d.ts +5 -0
  22. package/lib/logic.d.ts.map +1 -0
  23. package/lib/logic.js +9 -0
  24. package/lib/logic.js.map +1 -0
  25. package/lib/logic.test.d.ts +2 -0
  26. package/lib/logic.test.d.ts.map +1 -0
  27. package/lib/logic.test.js +54 -0
  28. package/lib/logic.test.js.map +1 -0
  29. package/lib/types/bridge.d.ts +1 -3
  30. package/lib/types/bridge.d.ts.map +1 -1
  31. package/lib-es/api/mirror.d.ts +16 -3
  32. package/lib-es/api/mirror.d.ts.map +1 -1
  33. package/lib-es/api/mirror.js +27 -9
  34. package/lib-es/api/mirror.js.map +1 -1
  35. package/lib-es/api/mirror.test.d.ts +2 -0
  36. package/lib-es/api/mirror.test.d.ts.map +1 -0
  37. package/lib-es/api/mirror.test.js +55 -0
  38. package/lib-es/api/mirror.test.js.map +1 -0
  39. package/lib-es/bridge/broadcast.d.ts.map +1 -1
  40. package/lib-es/bridge/broadcast.js +8 -2
  41. package/lib-es/bridge/broadcast.js.map +1 -1
  42. package/lib-es/bridge/synchronisation.js +3 -3
  43. package/lib-es/bridge/synchronisation.js.map +1 -1
  44. package/lib-es/bridge/utils.d.ts +3 -2
  45. package/lib-es/bridge/utils.d.ts.map +1 -1
  46. package/lib-es/bridge/utils.js +8 -0
  47. package/lib-es/bridge/utils.js.map +1 -1
  48. package/lib-es/logic.d.ts +5 -0
  49. package/lib-es/logic.d.ts.map +1 -0
  50. package/lib-es/logic.js +6 -0
  51. package/lib-es/logic.js.map +1 -0
  52. package/lib-es/logic.test.d.ts +2 -0
  53. package/lib-es/logic.test.d.ts.map +1 -0
  54. package/lib-es/logic.test.js +52 -0
  55. package/lib-es/logic.test.js.map +1 -0
  56. package/lib-es/types/bridge.d.ts +1 -3
  57. package/lib-es/types/bridge.d.ts.map +1 -1
  58. package/package.json +11 -10
  59. package/src/api/mirror.test.ts +76 -0
  60. package/src/api/mirror.ts +43 -19
  61. package/src/bridge/broadcast.ts +11 -4
  62. package/src/bridge/synchronisation.ts +3 -3
  63. package/src/bridge/utils.ts +14 -2
  64. package/src/logic.test.ts +58 -0
  65. package/src/logic.ts +15 -0
  66. package/src/types/bridge.ts +1 -4
@@ -0,0 +1,55 @@
1
+ import network from "@ledgerhq/live-network/network";
2
+ import { getAccountTransactions } from "./mirror";
3
+ jest.mock("@ledgerhq/live-network/network");
4
+ const mockedNetwork = jest.mocked(network);
5
+ const makeMockResponse = (data) => ({
6
+ data,
7
+ status: 200,
8
+ statusText: "OK",
9
+ headers: {},
10
+ config: {
11
+ headers: {},
12
+ },
13
+ });
14
+ describe("getAccountTransactions", () => {
15
+ beforeEach(() => {
16
+ jest.clearAllMocks();
17
+ });
18
+ it("should include 'account.id', 'limit=100' and 'order=desc' query params", async () => {
19
+ mockedNetwork.mockResolvedValueOnce(makeMockResponse({ transactions: [], links: { next: null } }));
20
+ await getAccountTransactions("0.0.1234", null);
21
+ const calledUrl = mockedNetwork.mock.calls[0][0].url;
22
+ expect(calledUrl).toContain("account.id=0.0.1234");
23
+ expect(calledUrl).toContain("limit=100");
24
+ expect(calledUrl).toContain("order=desc");
25
+ });
26
+ it("should break early if no transactions are returned", async () => {
27
+ mockedNetwork.mockResolvedValueOnce(makeMockResponse({
28
+ transactions: [],
29
+ links: { next: "/next-1" },
30
+ }));
31
+ const result = await getAccountTransactions("0.0.1234", null);
32
+ expect(mockedNetwork).toHaveBeenCalledTimes(1);
33
+ expect(result).toEqual([]);
34
+ });
35
+ it("should keep fetching if links.next is present and new transactions are returned", async () => {
36
+ mockedNetwork
37
+ .mockResolvedValueOnce(makeMockResponse({
38
+ transactions: [{ consensus_timestamp: "1" }],
39
+ links: { next: "/next-1" },
40
+ }))
41
+ .mockResolvedValueOnce(makeMockResponse({
42
+ transactions: [{ consensus_timestamp: "2" }],
43
+ links: { next: "/next-2" },
44
+ }))
45
+ .mockResolvedValueOnce(makeMockResponse({
46
+ transactions: [],
47
+ links: { next: "/next-3" },
48
+ }));
49
+ const result = await getAccountTransactions("0.0.1234", null);
50
+ expect(result).toHaveLength(2);
51
+ expect(result.map(tx => tx.consensus_timestamp)).toEqual(["1", "2"]);
52
+ expect(mockedNetwork).toHaveBeenCalledTimes(3);
53
+ });
54
+ });
55
+ //# sourceMappingURL=mirror.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mirror.test.js","sourceRoot":"","sources":["../../src/api/mirror.test.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/bridge/broadcast.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAGrD,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAGvC,eAAO,MAAM,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC,WAAW,CAY7D,CAAC"}
1
+ {"version":3,"file":"broadcast.d.ts","sourceRoot":"","sources":["../../src/bridge/broadcast.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAa,MAAM,sBAAsB,CAAC;AAGhE,OAAO,EAAwB,WAAW,EAAE,MAAM,UAAU,CAAC;AAG7D,eAAO,MAAM,SAAS,EAAE,aAAa,CAAC,WAAW,CAAC,CAAC,WAAW,CAmB7D,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { Transaction as HederaSDKTransaction } from "@hashgraph/sdk";
2
2
  import { patchOperationWithHash } from "@ledgerhq/coin-framework/operation";
3
- import { base64ToUrlSafeBase64 } from "./utils";
3
+ import { base64ToUrlSafeBase64, patchOperationWithExtra } from "./utils";
4
4
  import { broadcastTransaction } from "../api/network";
5
5
  export const broadcast = async ({ signedOperation }) => {
6
6
  const { signature, operation } = signedOperation;
@@ -9,6 +9,12 @@ export const broadcast = async ({ signedOperation }) => {
9
9
  const response = await broadcastTransaction(hederaTransaction);
10
10
  const base64Hash = Buffer.from(response.transactionHash).toString("base64");
11
11
  const base64HashUrlSafe = base64ToUrlSafeBase64(base64Hash);
12
- return patchOperationWithHash(operation, base64HashUrlSafe);
12
+ const extra = {
13
+ transactionId: response.transactionId.toString(),
14
+ };
15
+ let patchedOperation = operation;
16
+ patchedOperation = patchOperationWithHash(patchedOperation, base64HashUrlSafe);
17
+ patchedOperation = patchOperationWithExtra(patchedOperation, extra);
18
+ return patchedOperation;
13
19
  };
14
20
  //# sourceMappingURL=broadcast.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/bridge/broadcast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AAEhD,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,CAAC,MAAM,SAAS,GAA4C,KAAK,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE;IAC9F,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC;IAEjD,oFAAoF;IACpF,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE3F,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAE/D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5E,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAE5D,OAAO,sBAAsB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAC9D,CAAC,CAAC"}
1
+ {"version":3,"file":"broadcast.js","sourceRoot":"","sources":["../../src/bridge/broadcast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,IAAI,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAErE,OAAO,EAAE,sBAAsB,EAAE,MAAM,oCAAoC,CAAC;AAC5E,OAAO,EAAE,qBAAqB,EAAE,uBAAuB,EAAE,MAAM,SAAS,CAAC;AAEzE,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAEtD,MAAM,CAAC,MAAM,SAAS,GAA4C,KAAK,EAAE,EAAE,eAAe,EAAE,EAAE,EAAE;IAC9F,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,eAAe,CAAC;IAEjD,oFAAoF;IACpF,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC;IAE3F,MAAM,QAAQ,GAAG,MAAM,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;IAE/D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAC5E,MAAM,iBAAiB,GAAG,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC5D,MAAM,KAAK,GAAyB;QAClC,aAAa,EAAE,QAAQ,CAAC,aAAa,CAAC,QAAQ,EAAE;KACjD,CAAC;IAEF,IAAI,gBAAgB,GAAc,SAAS,CAAC;IAC5C,gBAAgB,GAAG,sBAAsB,CAAC,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;IAC/E,gBAAgB,GAAG,uBAAuB,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC;IAEpE,OAAO,gBAAgB,CAAC;AAC1B,CAAC,CAAC"}
@@ -20,10 +20,10 @@ export const getAccountShape = async (info) => {
20
20
  // grab latest operation's consensus timestamp for incremental sync
21
21
  const oldOperations = initialAccount?.operations ?? [];
22
22
  const latestOperationTimestamp = oldOperations[0]
23
- ? Math.floor(oldOperations[0].date.getTime() / 1000)
24
- : 0;
23
+ ? new BigNumber(Math.floor(oldOperations[0].date.getTime() / 1000))
24
+ : null;
25
25
  // merge new operations w/ previously synced ones
26
- const newOperations = await getOperationsForAccount(liveAccountId, address, new BigNumber(latestOperationTimestamp).toString());
26
+ const newOperations = await getOperationsForAccount(liveAccountId, address, latestOperationTimestamp ? latestOperationTimestamp.toString() : null);
27
27
  const operations = mergeOps(oldOperations, newOperations);
28
28
  return {
29
29
  id: liveAccountId,
@@ -1 +1 @@
1
- {"version":3,"file":"synchronisation.js","sourceRoot":"","sources":["../../src/bridge/synchronisation.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,WAAW,CAAC;AAClC,OAAO,EACL,mBAAmB,EAEnB,mBAAmB,GACpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,uBAAuB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AACjF,OAAO,EAGL,QAAQ,GACT,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,MAAM,CAAC,MAAM,eAAe,GAA6B,KAAK,EAC5D,IAAS,EACkB,EAAE;IAC7B,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAEnE,SAAS,CAAC,OAAO,EAAE,+BAA+B,CAAC,CAAC;IAEpD,MAAM,aAAa,GAAG,eAAe,CAAC;QACpC,IAAI,EAAE,IAAI;QACV,OAAO,EAAE,GAAG;QACZ,UAAU,EAAE,QAAQ,CAAC,EAAE;QACvB,aAAa,EAAE,OAAO;QACtB,cAAc;KACf,CAAC,CAAC;IAEH,8BAA8B;IAC9B,MAAM,cAAc,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;IAExD,mEAAmE;IACnE,MAAM,aAAa,GAAG,cAAc,EAAE,UAAU,IAAI,EAAE,CAAC;IACvD,MAAM,wBAAwB,GAAG,aAAa,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC;QACpD,CAAC,CAAC,CAAC,CAAC;IAEN,iDAAiD;IACjD,MAAM,aAAa,GAAG,MAAM,uBAAuB,CACjD,aAAa,EACb,OAAO,EACP,IAAI,SAAS,CAAC,wBAAwB,CAAC,CAAC,QAAQ,EAAE,CACnD,CAAC;IACF,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IAE1D,OAAO;QACL,EAAE,EAAE,aAAa;QACjB,YAAY,EAAE,OAAO;QACrB,OAAO,EAAE,cAAc,CAAC,OAAO;QAC/B,gBAAgB,EAAE,cAAc,CAAC,OAAO;QACxC,UAAU;QACV,wCAAwC;QACxC,iGAAiG;QACjG,WAAW,EAAE,EAAE;KAChB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAyB,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE;IACvF,MAAM,QAAQ,GAAG,MAAM,uBAAuB,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IACrE,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC;IAE5D,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE,KAAK,EAAE,EAAE,EAAE;QACnD,MAAM,gBAAgB,GAAG,mBAAmB,CAAC;YAC3C,cAAc;YACd,QAAQ;SACT,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,gBAAgB,EAAE,QAAQ,EAAE;YACvE,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;QACH,OAAO,SAAS,CAAC,KAAK,CAAC;YACrB,CAAC,CAAE;gBACC,OAAO,EAAE,SAAS,CAAC,KAAK,CAAC;gBACzB,SAAS,EAAE,SAAS,CAAC,KAAK,CAAC;gBAC3B,IAAI,EAAE,gBAAgB;aACZ;YACd,CAAC,CAAC,IAAI,CAAC;IACX,CAAC,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"synchronisation.js","sourceRoot":"","sources":["../../src/bridge/synchronisation.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import BigNumber from "bignumber.js";
2
- import type { Account } from "@ledgerhq/types-live";
3
- import type { Transaction } from "../types";
2
+ import type { Account, Operation } from "@ledgerhq/types-live";
3
+ import type { HederaOperationExtra, Transaction } from "../types";
4
4
  export declare const estimatedFeeSafetyRate = 2;
5
5
  export declare function getEstimatedFees(account: Account): Promise<BigNumber>;
6
6
  export declare function calculateAmount({ account, transaction, }: {
@@ -11,4 +11,5 @@ export declare function calculateAmount({ account, transaction, }: {
11
11
  totalSpent: BigNumber;
12
12
  }>;
13
13
  export declare function base64ToUrlSafeBase64(data: string): string;
14
+ export declare function patchOperationWithExtra(operation: Operation, extra: HederaOperationExtra): Operation;
14
15
  //# sourceMappingURL=utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/bridge/utils.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,cAAc,CAAC;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAIpD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAsB3E;AAED,wBAAsB,eAAe,CAAC,EACpC,OAAO,EACP,WAAW,GACZ,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;CAC1B,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,SAAS,CAAC;CACvB,CAAC,CASD;AAGD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D"}
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/bridge/utils.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,cAAc,CAAC;AACrC,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAI/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAElE,eAAO,MAAM,sBAAsB,IAAI,CAAC;AAExC,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,CAsB3E;AAED,wBAAsB,eAAe,CAAC,EACpC,OAAO,EACP,WAAW,GACZ,EAAE;IACD,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,WAAW,CAAC;CAC1B,GAAG,OAAO,CAAC;IACV,MAAM,EAAE,SAAS,CAAC;IAClB,UAAU,EAAE,SAAS,CAAC;CACvB,CAAC,CASD;AAGD,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,oBAAoB,GAC1B,SAAS,CAOX"}
@@ -41,4 +41,12 @@ export function base64ToUrlSafeBase64(data) {
41
41
  // Buffer.from(data, "base64").toString("base64url");
42
42
  return data.replace(/\//g, "_").replace(/\+/g, "-");
43
43
  }
44
+ export function patchOperationWithExtra(operation, extra) {
45
+ return {
46
+ ...operation,
47
+ extra,
48
+ subOperations: (operation.subOperations ?? []).map(op => ({ ...op, extra })),
49
+ nftOperations: (operation.nftOperations ?? []).map(op => ({ ...op, extra })),
50
+ };
51
+ }
44
52
  //# sourceMappingURL=utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/bridge/utils.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,cAAc,CAAC;AAErC,OAAO,MAAM,MAAM,wCAAwC,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAgB;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;YACpC;gBACE,IAAI,EAAE,OAAO,CAAC,QAAQ;gBACtB,EAAE,EAAE,uBAAuB,CAAC,KAAK,CAAC;gBAClC,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB;SACF,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACZ,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC;iBACxB,SAAS,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;iBACjC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC;iBAClC,YAAY,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QACD,oCAAoC;IACtC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,sDAAsD;IACtD,oEAAoE;IACpE,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAC,gCAAgC;AACvG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,OAAO,EACP,WAAW,GAIZ;IAIC,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY;QACrC,CAAC,CAAC,MAAM,oBAAoB,CAAC,EAAE,OAAO,EAAE,CAAC;QACzC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;IAEvB,OAAO;QACL,MAAM;QACN,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,8EAA8E;IAC9E,uDAAuD;IACvD,qDAAqD;IAErD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACtD,CAAC"}
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/bridge/utils.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,cAAc,CAAC;AAErC,OAAO,MAAM,MAAM,wCAAwC,CAAC;AAC5D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAG9D,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,OAAgB;IACrD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC;YACpC;gBACE,IAAI,EAAE,OAAO,CAAC,QAAQ;gBACtB,EAAE,EAAE,uBAAuB,CAAC,KAAK,CAAC;gBAClC,SAAS,EAAE,IAAI,IAAI,EAAE;aACtB;SACF,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YACZ,OAAO,IAAI,SAAS,CAAC,KAAK,CAAC;iBACxB,SAAS,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;iBACjC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC;iBAClC,YAAY,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC;QACD,oCAAoC;IACtC,CAAC;IAAC,MAAM,CAAC,CAAA,CAAC;IAEV,sDAAsD;IACtD,oEAAoE;IACpE,OAAO,IAAI,SAAS,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,sBAAsB,CAAC,CAAC,CAAC,gCAAgC;AACvG,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EACpC,OAAO,EACP,WAAW,GAIZ;IAIC,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY;QACrC,CAAC,CAAC,MAAM,oBAAoB,CAAC,EAAE,OAAO,EAAE,CAAC;QACzC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;IAEvB,OAAO;QACL,MAAM;QACN,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,gBAAgB,CAAC,OAAO,CAAC,CAAC;KACzD,CAAC;AACJ,CAAC;AAED,yGAAyG;AACzG,MAAM,UAAU,qBAAqB,CAAC,IAAY;IAChD,8EAA8E;IAC9E,uDAAuD;IACvD,qDAAqD;IAErD,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,uBAAuB,CACrC,SAAoB,EACpB,KAA2B;IAE3B,OAAO;QACL,GAAG,SAAS;QACZ,KAAK;QACL,aAAa,EAAE,CAAC,SAAS,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;QAC5E,aAAa,EAAE,CAAC,SAAS,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,CAAC;KAC7E,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import { ExplorerView } from "@ledgerhq/types-cryptoassets";
2
+ import { Operation } from "@ledgerhq/types-live";
3
+ declare const getTransactionExplorer: (explorerView: ExplorerView | null | undefined, operation: Operation) => string | undefined;
4
+ export { getTransactionExplorer };
5
+ //# sourceMappingURL=logic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logic.d.ts","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAIjD,QAAA,MAAM,sBAAsB,iBACZ,YAAY,GAAG,IAAI,GAAG,SAAS,aAClC,SAAS,KACnB,MAAM,GAAG,SAIX,CAAC;AAEF,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,6 @@
1
+ const getTransactionExplorer = (explorerView, operation) => {
2
+ const extra = operation.extra;
3
+ return explorerView?.tx?.replace("$hash", extra.consensusTimestamp ?? extra.transactionId ?? "0");
4
+ };
5
+ export { getTransactionExplorer };
6
+ //# sourceMappingURL=logic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logic.js","sourceRoot":"","sources":["../src/logic.ts"],"names":[],"mappings":"AAKA,MAAM,sBAAsB,GAAG,CAC7B,YAA6C,EAC7C,SAAoB,EACA,EAAE;IACtB,MAAM,KAAK,GAAG,SAAS,CAAC,KAA6B,CAAC;IAEtD,OAAO,YAAY,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,kBAAkB,IAAI,KAAK,CAAC,aAAa,IAAI,GAAG,CAAC,CAAC;AACpG,CAAC,CAAC;AAEF,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=logic.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logic.test.d.ts","sourceRoot":"","sources":["../src/logic.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,52 @@
1
+ import { BigNumber } from "bignumber.js";
2
+ import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets";
3
+ import { getTransactionExplorer } from "./logic";
4
+ describe("getTransactionExplorer", () => {
5
+ test("Tx explorer URL is converted from hash to consensus timestamp", async () => {
6
+ const explorerView = getCryptoCurrencyById("hedera").explorerViews[0];
7
+ expect(explorerView).toBeDefined();
8
+ expect(explorerView.tx).toBeDefined();
9
+ const mockOperation = {
10
+ extra: {
11
+ consensusTimestamp: "1.2.3.4",
12
+ },
13
+ id: "",
14
+ hash: "",
15
+ type: "IN",
16
+ value: new BigNumber(0),
17
+ fee: new BigNumber(0),
18
+ senders: [],
19
+ recipients: [],
20
+ blockHeight: undefined,
21
+ blockHash: undefined,
22
+ accountId: "",
23
+ date: new Date(),
24
+ };
25
+ const newUrl = getTransactionExplorer(explorerView, mockOperation);
26
+ expect(newUrl).toBe("https://hashscan.io/mainnet/transaction/1.2.3.4");
27
+ });
28
+ test("Tx explorer URL is based on transaction id if consensus timestamp is not available", async () => {
29
+ const explorerView = getCryptoCurrencyById("hedera").explorerViews[0];
30
+ expect(explorerView).toBeDefined();
31
+ expect(explorerView.tx).toBeDefined();
32
+ const mockOperation = {
33
+ extra: {
34
+ transactionId: "0.0.1234567-123-123",
35
+ },
36
+ id: "",
37
+ hash: "",
38
+ type: "IN",
39
+ value: new BigNumber(0),
40
+ fee: new BigNumber(0),
41
+ senders: [],
42
+ recipients: [],
43
+ blockHeight: undefined,
44
+ blockHash: undefined,
45
+ accountId: "",
46
+ date: new Date(),
47
+ };
48
+ const newUrl = getTransactionExplorer(explorerView, mockOperation);
49
+ expect(newUrl).toBe("https://hashscan.io/mainnet/transaction/0.0.1234567-123-123");
50
+ });
51
+ });
52
+ //# sourceMappingURL=logic.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logic.test.js","sourceRoot":"","sources":["../src/logic.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,sBAAsB,EAAE,MAAM,SAAS,CAAC;AAEjD,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,IAAI,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,YAAY,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAEtC,MAAM,aAAa,GAAc;YAC/B,KAAK,EAAE;gBACL,kBAAkB,EAAE,SAAS;aAC9B;YACD,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC;YACvB,GAAG,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC;YACrB,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,EAAE;YACd,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,EAAE;YACb,IAAI,EAAE,IAAI,IAAI,EAAE;SACjB,CAAC;QAEF,MAAM,MAAM,GAAG,sBAAsB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACnE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oFAAoF,EAAE,KAAK,IAAI,EAAE;QACpG,MAAM,YAAY,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;QACtE,MAAM,CAAC,YAAY,CAAC,CAAC,WAAW,EAAE,CAAC;QACnC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAEtC,MAAM,aAAa,GAAc;YAC/B,KAAK,EAAE;gBACL,aAAa,EAAE,qBAAqB;aACrC;YACD,EAAE,EAAE,EAAE;YACN,IAAI,EAAE,EAAE;YACR,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC;YACvB,GAAG,EAAE,IAAI,SAAS,CAAC,CAAC,CAAC;YACrB,OAAO,EAAE,EAAE;YACX,UAAU,EAAE,EAAE;YACd,WAAW,EAAE,SAAS;YACtB,SAAS,EAAE,SAAS;YACpB,SAAS,EAAE,EAAE;YACb,IAAI,EAAE,IAAI,IAAI,EAAE;SACjB,CAAC;QAEF,MAAM,MAAM,GAAG,sBAAsB,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;QACnE,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;IACrF,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -17,8 +17,6 @@ export type TransactionStatus = TransactionStatusCommon;
17
17
  export type TransactionStatusRaw = TransactionStatusCommonRaw;
18
18
  export type HederaOperationExtra = {
19
19
  consensusTimestamp?: string;
20
- };
21
- export type HederaOperationExtraRaw = {
22
- consensusTimestamp?: string;
20
+ transactionId?: string;
23
21
  };
24
22
  //# sourceMappingURL=bridge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/types/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG;IAClD,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAE9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG;IACpC,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B,CAAC"}
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../../src/types/bridge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,uBAAuB,EACvB,0BAA0B,EAC3B,MAAM,sBAAsB,CAAC;AAE9B,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,MAAM,EAAE,QAAQ,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG;IAC5C,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG,oBAAoB,GAAG;IAClD,MAAM,EAAE,QAAQ,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,uBAAuB,CAAC;AAExD,MAAM,MAAM,oBAAoB,GAAG,0BAA0B,CAAC;AAE9D,MAAM,MAAM,oBAAoB,GAAG;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/coin-hedera",
3
- "version": "1.6.7-next.0",
3
+ "version": "1.6.7-nightly.1",
4
4
  "description": "Ledger Hedera Coin integration",
5
5
  "keywords": [
6
6
  "Ledger",
@@ -81,14 +81,14 @@
81
81
  "invariant": "^2.2.2",
82
82
  "lodash": "^4.17.21",
83
83
  "rxjs": "^7.8.1",
84
- "@ledgerhq/coin-framework": "^5.1.0-next.0",
85
- "@ledgerhq/cryptoassets": "^13.18.0-next.0",
86
- "@ledgerhq/devices": "8.4.5-next.0",
87
- "@ledgerhq/errors": "^6.21.0-next.0",
88
- "@ledgerhq/live-countervalues": "^0.5.7-next.0",
89
- "@ledgerhq/live-env": "^2.9.0-next.0",
90
- "@ledgerhq/live-network": "^2.0.8-next.0",
91
- "@ledgerhq/types-live": "^6.71.0-next.0"
84
+ "@ledgerhq/coin-framework": "^5.0.2",
85
+ "@ledgerhq/cryptoassets": "^13.17.0",
86
+ "@ledgerhq/devices": "8.4.5-nightly.2",
87
+ "@ledgerhq/errors": "^6.21.0-nightly.0",
88
+ "@ledgerhq/live-countervalues": "^0.5.6",
89
+ "@ledgerhq/live-env": "^2.9.0-nightly.0",
90
+ "@ledgerhq/live-network": "^2.0.8-nightly.1",
91
+ "@ledgerhq/types-live": "^6.71.0-nightly.1"
92
92
  },
93
93
  "devDependencies": {
94
94
  "@types/invariant": "^2.2.2",
@@ -97,7 +97,8 @@
97
97
  "jest": "^29.7.0",
98
98
  "jest-sonar": "0.2.16",
99
99
  "ts-jest": "^29.1.1",
100
- "@ledgerhq/disable-network-setup": "^0.0.0"
100
+ "@ledgerhq/disable-network-setup": "^0.0.0",
101
+ "@ledgerhq/types-cryptoassets": "^7.23.0"
101
102
  },
102
103
  "scripts": {
103
104
  "clean": "rimraf lib lib-es",
@@ -0,0 +1,76 @@
1
+ import network from "@ledgerhq/live-network/network";
2
+ import { getAccountTransactions } from "./mirror";
3
+
4
+ jest.mock("@ledgerhq/live-network/network");
5
+ const mockedNetwork = jest.mocked(network);
6
+
7
+ const makeMockResponse = (data: any): Awaited<ReturnType<typeof network>> => ({
8
+ data,
9
+ status: 200,
10
+ statusText: "OK",
11
+ headers: {},
12
+ config: {
13
+ headers: {} as any,
14
+ },
15
+ });
16
+
17
+ describe("getAccountTransactions", () => {
18
+ beforeEach(() => {
19
+ jest.clearAllMocks();
20
+ });
21
+
22
+ it("should include 'account.id', 'limit=100' and 'order=desc' query params", async () => {
23
+ mockedNetwork.mockResolvedValueOnce(
24
+ makeMockResponse({ transactions: [], links: { next: null } }),
25
+ );
26
+
27
+ await getAccountTransactions("0.0.1234", null);
28
+
29
+ const calledUrl = mockedNetwork.mock.calls[0][0].url;
30
+ expect(calledUrl).toContain("account.id=0.0.1234");
31
+ expect(calledUrl).toContain("limit=100");
32
+ expect(calledUrl).toContain("order=desc");
33
+ });
34
+
35
+ it("should break early if no transactions are returned", async () => {
36
+ mockedNetwork.mockResolvedValueOnce(
37
+ makeMockResponse({
38
+ transactions: [],
39
+ links: { next: "/next-1" },
40
+ }),
41
+ );
42
+
43
+ const result = await getAccountTransactions("0.0.1234", null);
44
+
45
+ expect(mockedNetwork).toHaveBeenCalledTimes(1);
46
+ expect(result).toEqual([]);
47
+ });
48
+
49
+ it("should keep fetching if links.next is present and new transactions are returned", async () => {
50
+ mockedNetwork
51
+ .mockResolvedValueOnce(
52
+ makeMockResponse({
53
+ transactions: [{ consensus_timestamp: "1" }],
54
+ links: { next: "/next-1" },
55
+ }),
56
+ )
57
+ .mockResolvedValueOnce(
58
+ makeMockResponse({
59
+ transactions: [{ consensus_timestamp: "2" }],
60
+ links: { next: "/next-2" },
61
+ }),
62
+ )
63
+ .mockResolvedValueOnce(
64
+ makeMockResponse({
65
+ transactions: [],
66
+ links: { next: "/next-3" },
67
+ }),
68
+ );
69
+
70
+ const result = await getAccountTransactions("0.0.1234", null);
71
+
72
+ expect(result).toHaveLength(2);
73
+ expect(result.map(tx => tx.consensus_timestamp)).toEqual(["1", "2"]);
74
+ expect(mockedNetwork).toHaveBeenCalledTimes(3);
75
+ });
76
+ });
package/src/api/mirror.ts CHANGED
@@ -6,6 +6,7 @@ import { getEnv } from "@ledgerhq/live-env";
6
6
  import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
7
7
  import { getAccountBalance } from "./network";
8
8
  import { base64ToUrlSafeBase64 } from "../bridge/utils";
9
+ import { HederaOperationExtra } from "../types";
9
10
 
10
11
  const getMirrorApiUrl = (): string => getEnv("API_HEDERA_MIRROR");
11
12
 
@@ -16,12 +17,12 @@ const fetch = (path: string) => {
16
17
  });
17
18
  };
18
19
 
19
- export interface Account {
20
+ interface HederaMirrorAccount {
20
21
  accountId: AccountId;
21
22
  balance: BigNumber;
22
23
  }
23
24
 
24
- export async function getAccountsForPublicKey(publicKey: string): Promise<Account[]> {
25
+ export async function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorAccount[]> {
25
26
  let r;
26
27
  try {
27
28
  r = await fetch(`/api/v1/accounts?account.publicKey=${publicKey}&balance=false`);
@@ -30,7 +31,7 @@ export async function getAccountsForPublicKey(publicKey: string): Promise<Accoun
30
31
  throw e;
31
32
  }
32
33
  const rawAccounts = r.data.accounts;
33
- const accounts: Account[] = [];
34
+ const accounts: HederaMirrorAccount[] = [];
34
35
 
35
36
  for (const raw of rawAccounts) {
36
37
  const accountBalance = await getAccountBalance(raw.account);
@@ -44,37 +45,57 @@ export async function getAccountsForPublicKey(publicKey: string): Promise<Accoun
44
45
  return accounts;
45
46
  }
46
47
 
48
+ interface HederaMirrorTransfer {
49
+ account: string;
50
+ amount: number;
51
+ }
52
+
47
53
  interface HederaMirrorTransaction {
48
54
  transfers: HederaMirrorTransfer[];
49
55
  charged_tx_fee: string;
50
56
  transaction_hash: string;
51
57
  consensus_timestamp: string;
58
+ transaction_id: string;
52
59
  }
53
60
 
54
- interface HederaMirrorTransfer {
55
- account: string;
56
- amount: number;
61
+ export async function getAccountTransactions(
62
+ address: string,
63
+ since: string | null,
64
+ ): Promise<HederaMirrorTransaction[]> {
65
+ const transactions: HederaMirrorTransaction[] = [];
66
+ const params = new URLSearchParams({
67
+ "account.id": address,
68
+ order: "desc",
69
+ limit: "100",
70
+ });
71
+
72
+ if (since) {
73
+ params.append("timestamp", `gt:${since}`);
74
+ }
75
+
76
+ let nextUrl = `/api/v1/transactions?${params.toString()}`;
77
+
78
+ while (nextUrl) {
79
+ const res = await fetch(nextUrl);
80
+ const newTransactions = res.data.transactions as HederaMirrorTransaction[];
81
+ if (newTransactions.length === 0) break;
82
+ transactions.push(...newTransactions);
83
+ nextUrl = res.data.links.next;
84
+ }
85
+
86
+ return transactions;
57
87
  }
58
88
 
59
89
  export async function getOperationsForAccount(
60
90
  ledgerAccountId: string,
61
91
  address: string,
62
- latestOperationTimestamp: string,
92
+ latestOperationTimestamp: string | null,
63
93
  ): Promise<Operation[]> {
94
+ const rawOperations = await getAccountTransactions(address, latestOperationTimestamp);
64
95
  const operations: Operation[] = [];
65
- let r = await fetch(
66
- `/api/v1/transactions?account.id=${address}&timestamp=gt:${latestOperationTimestamp}`,
67
- );
68
- const rawOperations = r.data.transactions as HederaMirrorTransaction[];
69
-
70
- while (r.data.links.next) {
71
- r = await fetch(r.data.links.next);
72
- const newOperations = r.data.transactions as HederaMirrorTransaction[];
73
- rawOperations.push(...newOperations);
74
- }
75
96
 
76
97
  for (const raw of rawOperations) {
77
- const { consensus_timestamp } = raw;
98
+ const { consensus_timestamp, transaction_id } = raw;
78
99
  const timestamp = new Date(parseInt(consensus_timestamp.split(".")[0], 10) * 1000);
79
100
  const senders: string[] = [];
80
101
  const recipients: string[] = [];
@@ -131,7 +152,10 @@ export async function getOperationsForAccount(
131
152
  // Set a value just so that it's considered confirmed according to isConfirmedOperation
132
153
  blockHeight: 5,
133
154
  blockHash: null,
134
- extra: { consensusTimestamp: consensus_timestamp },
155
+ extra: {
156
+ consensusTimestamp: consensus_timestamp,
157
+ transactionId: transaction_id,
158
+ } satisfies HederaOperationExtra,
135
159
  fee,
136
160
  hash,
137
161
  recipients,
@@ -1,8 +1,8 @@
1
1
  import { Transaction as HederaSDKTransaction } from "@hashgraph/sdk";
2
- import { AccountBridge } from "@ledgerhq/types-live";
2
+ import { AccountBridge, Operation } from "@ledgerhq/types-live";
3
3
  import { patchOperationWithHash } from "@ledgerhq/coin-framework/operation";
4
- import { base64ToUrlSafeBase64 } from "./utils";
5
- import { Transaction } from "../types";
4
+ import { base64ToUrlSafeBase64, patchOperationWithExtra } from "./utils";
5
+ import { HederaOperationExtra, Transaction } from "../types";
6
6
  import { broadcastTransaction } from "../api/network";
7
7
 
8
8
  export const broadcast: AccountBridge<Transaction>["broadcast"] = async ({ signedOperation }) => {
@@ -15,6 +15,13 @@ export const broadcast: AccountBridge<Transaction>["broadcast"] = async ({ signe
15
15
 
16
16
  const base64Hash = Buffer.from(response.transactionHash).toString("base64");
17
17
  const base64HashUrlSafe = base64ToUrlSafeBase64(base64Hash);
18
+ const extra: HederaOperationExtra = {
19
+ transactionId: response.transactionId.toString(),
20
+ };
18
21
 
19
- return patchOperationWithHash(operation, base64HashUrlSafe);
22
+ let patchedOperation: Operation = operation;
23
+ patchedOperation = patchOperationWithHash(patchedOperation, base64HashUrlSafe);
24
+ patchedOperation = patchOperationWithExtra(patchedOperation, extra);
25
+
26
+ return patchedOperation;
20
27
  };
@@ -36,14 +36,14 @@ export const getAccountShape: GetAccountShape<Account> = async (
36
36
  // grab latest operation's consensus timestamp for incremental sync
37
37
  const oldOperations = initialAccount?.operations ?? [];
38
38
  const latestOperationTimestamp = oldOperations[0]
39
- ? Math.floor(oldOperations[0].date.getTime() / 1000)
40
- : 0;
39
+ ? new BigNumber(Math.floor(oldOperations[0].date.getTime() / 1000))
40
+ : null;
41
41
 
42
42
  // merge new operations w/ previously synced ones
43
43
  const newOperations = await getOperationsForAccount(
44
44
  liveAccountId,
45
45
  address,
46
- new BigNumber(latestOperationTimestamp).toString(),
46
+ latestOperationTimestamp ? latestOperationTimestamp.toString() : null,
47
47
  );
48
48
  const operations = mergeOps(oldOperations, newOperations);
49
49
 
@@ -1,9 +1,9 @@
1
1
  import BigNumber from "bignumber.js";
2
- import type { Account } from "@ledgerhq/types-live";
2
+ import type { Account, Operation } from "@ledgerhq/types-live";
3
3
  import cvsApi from "@ledgerhq/live-countervalues/api/index";
4
4
  import { getFiatCurrencyByTicker } from "@ledgerhq/cryptoassets";
5
5
  import { estimateMaxSpendable } from "./estimateMaxSpendable";
6
- import type { Transaction } from "../types";
6
+ import type { HederaOperationExtra, Transaction } from "../types";
7
7
 
8
8
  export const estimatedFeeSafetyRate = 2;
9
9
 
@@ -59,3 +59,15 @@ export function base64ToUrlSafeBase64(data: string): string {
59
59
 
60
60
  return data.replace(/\//g, "_").replace(/\+/g, "-");
61
61
  }
62
+
63
+ export function patchOperationWithExtra(
64
+ operation: Operation,
65
+ extra: HederaOperationExtra,
66
+ ): Operation {
67
+ return {
68
+ ...operation,
69
+ extra,
70
+ subOperations: (operation.subOperations ?? []).map(op => ({ ...op, extra })),
71
+ nftOperations: (operation.nftOperations ?? []).map(op => ({ ...op, extra })),
72
+ };
73
+ }