@ledgerhq/coin-hedera 1.6.6 → 1.6.7-nightly.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/lib/api/mirror.d.ts +15 -3
- package/lib/api/mirror.d.ts.map +1 -1
- package/lib/api/mirror.js +24 -8
- package/lib/api/mirror.js.map +1 -1
- package/lib/api/mirror.test.d.ts +2 -0
- package/lib/api/mirror.test.d.ts.map +1 -0
- package/lib/api/mirror.test.js +60 -0
- package/lib/api/mirror.test.js.map +1 -0
- package/lib/bridge/synchronisation.js +3 -3
- package/lib/bridge/synchronisation.js.map +1 -1
- package/lib-es/api/mirror.d.ts +15 -3
- package/lib-es/api/mirror.d.ts.map +1 -1
- package/lib-es/api/mirror.js +22 -7
- package/lib-es/api/mirror.js.map +1 -1
- package/lib-es/api/mirror.test.d.ts +2 -0
- package/lib-es/api/mirror.test.d.ts.map +1 -0
- package/lib-es/api/mirror.test.js +55 -0
- package/lib-es/api/mirror.test.js.map +1 -0
- package/lib-es/bridge/synchronisation.js +3 -3
- package/lib-es/bridge/synchronisation.js.map +1 -1
- package/package.json +6 -6
- package/src/api/mirror.test.ts +76 -0
- package/src/api/mirror.ts +36 -17
- package/src/bridge/synchronisation.ts +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ledgerhq/coin-hedera
|
|
2
2
|
|
|
3
|
+
## 1.6.7-nightly.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#10211](https://github.com/LedgerHQ/ledger-live/pull/10211) [`3ebfb21`](https://github.com/LedgerHQ/ledger-live/commit/3ebfb21cc0861cd69b7f4117b7d1f3c7c6a38acd) Thanks [@md-blockydevs](https://github.com/md-blockydevs)! - fix slow "add account" flow with Hedera
|
|
8
|
+
|
|
3
9
|
## 1.6.6
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
package/lib/api/mirror.d.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { AccountId } from "@hashgraph/sdk";
|
|
2
2
|
import { Operation } from "@ledgerhq/types-live";
|
|
3
3
|
import BigNumber from "bignumber.js";
|
|
4
|
-
|
|
4
|
+
interface HederaMirrorAccount {
|
|
5
5
|
accountId: AccountId;
|
|
6
6
|
balance: BigNumber;
|
|
7
7
|
}
|
|
8
|
-
export declare function getAccountsForPublicKey(publicKey: string): Promise<
|
|
9
|
-
|
|
8
|
+
export declare function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorAccount[]>;
|
|
9
|
+
interface HederaMirrorTransfer {
|
|
10
|
+
account: string;
|
|
11
|
+
amount: number;
|
|
12
|
+
}
|
|
13
|
+
interface HederaMirrorTransaction {
|
|
14
|
+
transfers: HederaMirrorTransfer[];
|
|
15
|
+
charged_tx_fee: string;
|
|
16
|
+
transaction_hash: string;
|
|
17
|
+
consensus_timestamp: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function getAccountTransactions(address: string, since: string | null): Promise<HederaMirrorTransaction[]>;
|
|
20
|
+
export declare function getOperationsForAccount(ledgerAccountId: string, address: string, latestOperationTimestamp: string | null): Promise<Operation[]>;
|
|
21
|
+
export {};
|
|
10
22
|
//# sourceMappingURL=mirror.d.ts.map
|
package/lib/api/mirror.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mirror.d.ts","sourceRoot":"","sources":["../../src/api/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAiB,MAAM,sBAAsB,CAAC;AAChE,OAAO,SAAS,MAAM,cAAc,CAAC;AAerC,
|
|
1
|
+
{"version":3,"file":"mirror.d.ts","sourceRoot":"","sources":["../../src/api/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAiB,MAAM,sBAAsB,CAAC;AAChE,OAAO,SAAS,MAAM,cAAc,CAAC;AAerC,UAAU,mBAAmB;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,SAAS,CAAC;CACpB;AAED,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqB/F;AAED,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,uBAAuB;IAC/B,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAuBpC;AAED,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACf,wBAAwB,EAAE,MAAM,GAAG,IAAI,GACtC,OAAO,CAAC,SAAS,EAAE,CAAC,CA0EtB"}
|
package/lib/api/mirror.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getOperationsForAccount = exports.getAccountsForPublicKey = void 0;
|
|
6
|
+
exports.getOperationsForAccount = exports.getAccountTransactions = exports.getAccountsForPublicKey = void 0;
|
|
7
7
|
const sdk_1 = require("@hashgraph/sdk");
|
|
8
8
|
const network_1 = __importDefault(require("@ledgerhq/live-network/network"));
|
|
9
9
|
const bignumber_js_1 = __importDefault(require("bignumber.js"));
|
|
@@ -40,15 +40,31 @@ async function getAccountsForPublicKey(publicKey) {
|
|
|
40
40
|
return accounts;
|
|
41
41
|
}
|
|
42
42
|
exports.getAccountsForPublicKey = getAccountsForPublicKey;
|
|
43
|
+
async function getAccountTransactions(address, since) {
|
|
44
|
+
const transactions = [];
|
|
45
|
+
const params = new URLSearchParams({
|
|
46
|
+
"account.id": address,
|
|
47
|
+
order: "desc",
|
|
48
|
+
limit: "100",
|
|
49
|
+
});
|
|
50
|
+
if (since) {
|
|
51
|
+
params.append("timestamp", `gt:${since}`);
|
|
52
|
+
}
|
|
53
|
+
let nextUrl = `/api/v1/transactions?${params.toString()}`;
|
|
54
|
+
while (nextUrl) {
|
|
55
|
+
const res = await fetch(nextUrl);
|
|
56
|
+
const newTransactions = res.data.transactions;
|
|
57
|
+
if (newTransactions.length === 0)
|
|
58
|
+
break;
|
|
59
|
+
transactions.push(...newTransactions);
|
|
60
|
+
nextUrl = res.data.links.next;
|
|
61
|
+
}
|
|
62
|
+
return transactions;
|
|
63
|
+
}
|
|
64
|
+
exports.getAccountTransactions = getAccountTransactions;
|
|
43
65
|
async function getOperationsForAccount(ledgerAccountId, address, latestOperationTimestamp) {
|
|
66
|
+
const rawOperations = await getAccountTransactions(address, latestOperationTimestamp);
|
|
44
67
|
const operations = [];
|
|
45
|
-
let r = await fetch(`/api/v1/transactions?account.id=${address}×tamp=gt:${latestOperationTimestamp}`);
|
|
46
|
-
const rawOperations = r.data.transactions;
|
|
47
|
-
while (r.data.links.next) {
|
|
48
|
-
r = await fetch(r.data.links.next);
|
|
49
|
-
const newOperations = r.data.transactions;
|
|
50
|
-
rawOperations.push(...newOperations);
|
|
51
|
-
}
|
|
52
68
|
for (const raw of rawOperations) {
|
|
53
69
|
const { consensus_timestamp } = raw;
|
|
54
70
|
const timestamp = new Date(parseInt(consensus_timestamp.split(".")[0], 10) * 1000);
|
package/lib/api/mirror.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/api/mirror.ts"],"names":[],"mappings":";;;;;;AAAA,wCAA2C;AAC3C,6EAAqD;AAErD,gEAAqC;AACrC,iDAA4C;AAC5C,kEAAuE;AACvE,uCAA8C;AAC9C,2CAAwD;AAExD,MAAM,eAAe,GAAG,GAAW,EAAE,CAAC,IAAA,iBAAM,EAAC,mBAAmB,CAAC,CAAC;AAElE,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE;IAC7B,OAAO,IAAA,iBAAO,EAAC;QACb,MAAM,EAAE,KAAK;QACb,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,IAAI,EAAE;KACnC,CAAC,CAAC;AACL,CAAC,CAAC;AAOK,KAAK,UAAU,uBAAuB,CAAC,SAAiB;IAC7D,IAAI,CAAC,CAAC;IACN,IAAI,CAAC;QACH,CAAC,GAAG,MAAM,KAAK,CAAC,sCAAsC,SAAS,gBAAgB,CAAC,CAAC;IACnF,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc;YAAE,OAAO,EAAE,CAAC;QACzC,MAAM,CAAC,CAAC;IACV,CAAC;IACD,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IACpC,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/api/mirror.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror.test.d.ts","sourceRoot":"","sources":["../../src/api/mirror.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const network_1 = __importDefault(require("@ledgerhq/live-network/network"));
|
|
7
|
+
const mirror_1 = require("./mirror");
|
|
8
|
+
jest.mock("@ledgerhq/live-network/network");
|
|
9
|
+
const mockedNetwork = jest.mocked(network_1.default);
|
|
10
|
+
const makeMockResponse = (data) => ({
|
|
11
|
+
data,
|
|
12
|
+
status: 200,
|
|
13
|
+
statusText: "OK",
|
|
14
|
+
headers: {},
|
|
15
|
+
config: {
|
|
16
|
+
headers: {},
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
describe("getAccountTransactions", () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
jest.clearAllMocks();
|
|
22
|
+
});
|
|
23
|
+
it("should include 'account.id', 'limit=100' and 'order=desc' query params", async () => {
|
|
24
|
+
mockedNetwork.mockResolvedValueOnce(makeMockResponse({ transactions: [], links: { next: null } }));
|
|
25
|
+
await (0, mirror_1.getAccountTransactions)("0.0.1234", null);
|
|
26
|
+
const calledUrl = mockedNetwork.mock.calls[0][0].url;
|
|
27
|
+
expect(calledUrl).toContain("account.id=0.0.1234");
|
|
28
|
+
expect(calledUrl).toContain("limit=100");
|
|
29
|
+
expect(calledUrl).toContain("order=desc");
|
|
30
|
+
});
|
|
31
|
+
it("should break early if no transactions are returned", async () => {
|
|
32
|
+
mockedNetwork.mockResolvedValueOnce(makeMockResponse({
|
|
33
|
+
transactions: [],
|
|
34
|
+
links: { next: "/next-1" },
|
|
35
|
+
}));
|
|
36
|
+
const result = await (0, mirror_1.getAccountTransactions)("0.0.1234", null);
|
|
37
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(1);
|
|
38
|
+
expect(result).toEqual([]);
|
|
39
|
+
});
|
|
40
|
+
it("should keep fetching if links.next is present and new transactions are returned", async () => {
|
|
41
|
+
mockedNetwork
|
|
42
|
+
.mockResolvedValueOnce(makeMockResponse({
|
|
43
|
+
transactions: [{ consensus_timestamp: "1" }],
|
|
44
|
+
links: { next: "/next-1" },
|
|
45
|
+
}))
|
|
46
|
+
.mockResolvedValueOnce(makeMockResponse({
|
|
47
|
+
transactions: [{ consensus_timestamp: "2" }],
|
|
48
|
+
links: { next: "/next-2" },
|
|
49
|
+
}))
|
|
50
|
+
.mockResolvedValueOnce(makeMockResponse({
|
|
51
|
+
transactions: [],
|
|
52
|
+
links: { next: "/next-3" },
|
|
53
|
+
}));
|
|
54
|
+
const result = await (0, mirror_1.getAccountTransactions)("0.0.1234", null);
|
|
55
|
+
expect(result).toHaveLength(2);
|
|
56
|
+
expect(result.map(tx => tx.consensus_timestamp)).toEqual(["1", "2"]);
|
|
57
|
+
expect(mockedNetwork).toHaveBeenCalledTimes(3);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
//# 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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"}
|
|
@@ -26,10 +26,10 @@ const getAccountShape = async (info) => {
|
|
|
26
26
|
// grab latest operation's consensus timestamp for incremental sync
|
|
27
27
|
const oldOperations = initialAccount?.operations ?? [];
|
|
28
28
|
const latestOperationTimestamp = oldOperations[0]
|
|
29
|
-
? Math.floor(oldOperations[0].date.getTime() / 1000)
|
|
30
|
-
:
|
|
29
|
+
? new bignumber_js_1.BigNumber(Math.floor(oldOperations[0].date.getTime() / 1000))
|
|
30
|
+
: null;
|
|
31
31
|
// merge new operations w/ previously synced ones
|
|
32
|
-
const newOperations = await (0, mirror_1.getOperationsForAccount)(liveAccountId, address,
|
|
32
|
+
const newOperations = await (0, mirror_1.getOperationsForAccount)(liveAccountId, address, latestOperationTimestamp ? latestOperationTimestamp.toString() : null);
|
|
33
33
|
const operations = (0, jsHelpers_1.mergeOps)(oldOperations, newOperations);
|
|
34
34
|
return {
|
|
35
35
|
id: liveAccountId,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"synchronisation.js","sourceRoot":"","sources":["../../src/bridge/synchronisation.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAkC;AAClC,oEAI6C;AAC7C,+CAAyC;AAEzC,0CAAiF;AACjF,yEAImD;AACnD,8DAAmE;AACnE,4CAAmD;AAE5C,MAAM,eAAe,GAA6B,KAAK,EAC5D,IAAS,EACkB,EAAE;IAC7B,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAEnE,IAAA,mBAAS,EAAC,OAAO,EAAE,+BAA+B,CAAC,CAAC;IAEpD,MAAM,aAAa,GAAG,IAAA,yBAAe,EAAC;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,IAAA,2BAAiB,EAAC,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
|
|
1
|
+
{"version":3,"file":"synchronisation.js","sourceRoot":"","sources":["../../src/bridge/synchronisation.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAkC;AAClC,oEAI6C;AAC7C,+CAAyC;AAEzC,0CAAiF;AACjF,yEAImD;AACnD,8DAAmE;AACnE,4CAAmD;AAE5C,MAAM,eAAe,GAA6B,KAAK,EAC5D,IAAS,EACkB,EAAE;IAC7B,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,IAAI,CAAC;IAEnE,IAAA,mBAAS,EAAC,OAAO,EAAE,+BAA+B,CAAC,CAAC;IAEpD,MAAM,aAAa,GAAG,IAAA,yBAAe,EAAC;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,IAAA,2BAAiB,EAAC,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,wBAAS,CAAC,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;QACnE,CAAC,CAAC,IAAI,CAAC;IAET,iDAAiD;IACjD,MAAM,aAAa,GAAG,MAAM,IAAA,gCAAuB,EACjD,aAAa,EACb,OAAO,EACP,wBAAwB,CAAC,CAAC,CAAC,wBAAwB,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,CACtE,CAAC;IACF,MAAM,UAAU,GAAG,IAAA,oBAAQ,EAAC,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;AA1CW,QAAA,eAAe,mBA0C1B;AAEK,MAAM,kBAAkB,GAAyB,KAAK,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE;IACvF,MAAM,QAAQ,GAAG,MAAM,IAAA,gCAAuB,EAAC,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,IAAA,gCAAmB,EAAC;YAC3C,cAAc;YACd,QAAQ;SACT,CAAC,CAAC;QACH,MAAM,gBAAgB,GAAG,IAAA,gCAAmB,EAAC,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;AApBW,QAAA,kBAAkB,sBAoB7B"}
|
package/lib-es/api/mirror.d.ts
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
1
|
import { AccountId } from "@hashgraph/sdk";
|
|
2
2
|
import { Operation } from "@ledgerhq/types-live";
|
|
3
3
|
import BigNumber from "bignumber.js";
|
|
4
|
-
|
|
4
|
+
interface HederaMirrorAccount {
|
|
5
5
|
accountId: AccountId;
|
|
6
6
|
balance: BigNumber;
|
|
7
7
|
}
|
|
8
|
-
export declare function getAccountsForPublicKey(publicKey: string): Promise<
|
|
9
|
-
|
|
8
|
+
export declare function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorAccount[]>;
|
|
9
|
+
interface HederaMirrorTransfer {
|
|
10
|
+
account: string;
|
|
11
|
+
amount: number;
|
|
12
|
+
}
|
|
13
|
+
interface HederaMirrorTransaction {
|
|
14
|
+
transfers: HederaMirrorTransfer[];
|
|
15
|
+
charged_tx_fee: string;
|
|
16
|
+
transaction_hash: string;
|
|
17
|
+
consensus_timestamp: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function getAccountTransactions(address: string, since: string | null): Promise<HederaMirrorTransaction[]>;
|
|
20
|
+
export declare function getOperationsForAccount(ledgerAccountId: string, address: string, latestOperationTimestamp: string | null): Promise<Operation[]>;
|
|
21
|
+
export {};
|
|
10
22
|
//# sourceMappingURL=mirror.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mirror.d.ts","sourceRoot":"","sources":["../../src/api/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAiB,MAAM,sBAAsB,CAAC;AAChE,OAAO,SAAS,MAAM,cAAc,CAAC;AAerC,
|
|
1
|
+
{"version":3,"file":"mirror.d.ts","sourceRoot":"","sources":["../../src/api/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAiB,MAAM,sBAAsB,CAAC;AAChE,OAAO,SAAS,MAAM,cAAc,CAAC;AAerC,UAAU,mBAAmB;IAC3B,SAAS,EAAE,SAAS,CAAC;IACrB,OAAO,EAAE,SAAS,CAAC;CACpB;AAED,wBAAsB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAqB/F;AAED,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,uBAAuB;IAC/B,SAAS,EAAE,oBAAoB,EAAE,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,GAAG,IAAI,GACnB,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAuBpC;AAED,wBAAsB,uBAAuB,CAC3C,eAAe,EAAE,MAAM,EACvB,OAAO,EAAE,MAAM,EACf,wBAAwB,EAAE,MAAM,GAAG,IAAI,GACtC,OAAO,CAAC,SAAS,EAAE,CAAC,CA0EtB"}
|
package/lib-es/api/mirror.js
CHANGED
|
@@ -33,15 +33,30 @@ export async function getAccountsForPublicKey(publicKey) {
|
|
|
33
33
|
}
|
|
34
34
|
return accounts;
|
|
35
35
|
}
|
|
36
|
+
export async function getAccountTransactions(address, since) {
|
|
37
|
+
const transactions = [];
|
|
38
|
+
const params = new URLSearchParams({
|
|
39
|
+
"account.id": address,
|
|
40
|
+
order: "desc",
|
|
41
|
+
limit: "100",
|
|
42
|
+
});
|
|
43
|
+
if (since) {
|
|
44
|
+
params.append("timestamp", `gt:${since}`);
|
|
45
|
+
}
|
|
46
|
+
let nextUrl = `/api/v1/transactions?${params.toString()}`;
|
|
47
|
+
while (nextUrl) {
|
|
48
|
+
const res = await fetch(nextUrl);
|
|
49
|
+
const newTransactions = res.data.transactions;
|
|
50
|
+
if (newTransactions.length === 0)
|
|
51
|
+
break;
|
|
52
|
+
transactions.push(...newTransactions);
|
|
53
|
+
nextUrl = res.data.links.next;
|
|
54
|
+
}
|
|
55
|
+
return transactions;
|
|
56
|
+
}
|
|
36
57
|
export async function getOperationsForAccount(ledgerAccountId, address, latestOperationTimestamp) {
|
|
58
|
+
const rawOperations = await getAccountTransactions(address, latestOperationTimestamp);
|
|
37
59
|
const operations = [];
|
|
38
|
-
let r = await fetch(`/api/v1/transactions?account.id=${address}×tamp=gt:${latestOperationTimestamp}`);
|
|
39
|
-
const rawOperations = r.data.transactions;
|
|
40
|
-
while (r.data.links.next) {
|
|
41
|
-
r = await fetch(r.data.links.next);
|
|
42
|
-
const newOperations = r.data.transactions;
|
|
43
|
-
rawOperations.push(...newOperations);
|
|
44
|
-
}
|
|
45
60
|
for (const raw of rawOperations) {
|
|
46
61
|
const { consensus_timestamp } = raw;
|
|
47
62
|
const timestamp = new Date(parseInt(consensus_timestamp.split(".")[0], 10) * 1000);
|
package/lib-es/api/mirror.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/api/mirror.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,OAAO,MAAM,gCAAgC,CAAC;AAErD,OAAO,SAAS,MAAM,cAAc,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAExD,MAAM,eAAe,GAAG,GAAW,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;AAElE,MAAM,KAAK,GAAG,CAAC,IAAY,EAAE,EAAE;IAC7B,OAAO,OAAO,CAAC;QACb,MAAM,EAAE,KAAK;QACb,GAAG,EAAE,GAAG,eAAe,EAAE,GAAG,IAAI,EAAE;KACnC,CAAC,CAAC;AACL,CAAC,CAAC;AAOF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,SAAiB;IAC7D,IAAI,CAAC,CAAC;IACN,IAAI,CAAC;QACH,CAAC,GAAG,MAAM,KAAK,CAAC,sCAAsC,SAAS,gBAAgB,CAAC,CAAC;IACnF,CAAC;IAAC,OAAO,CAAM,EAAE,CAAC;QAChB,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc;YAAE,OAAO,EAAE,CAAC;QACzC,MAAM,CAAC,CAAC;IACV,CAAC;IACD,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IACpC,MAAM,QAAQ,
|
|
1
|
+
{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/api/mirror.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mirror.test.d.ts","sourceRoot":"","sources":["../../src/api/mirror.test.ts"],"names":[],"mappings":""}
|
|
@@ -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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"}
|
|
@@ -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
|
-
:
|
|
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,
|
|
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
|
|
1
|
+
{"version":3,"file":"synchronisation.js","sourceRoot":"","sources":["../../src/bridge/synchronisation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ledgerhq/coin-hedera",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.7-nightly.0",
|
|
4
4
|
"description": "Ledger Hedera Coin integration",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Ledger",
|
|
@@ -83,12 +83,12 @@
|
|
|
83
83
|
"rxjs": "^7.8.1",
|
|
84
84
|
"@ledgerhq/coin-framework": "^5.0.2",
|
|
85
85
|
"@ledgerhq/cryptoassets": "^13.17.0",
|
|
86
|
-
"@ledgerhq/devices": "8.4.
|
|
87
|
-
"@ledgerhq/errors": "^6.
|
|
86
|
+
"@ledgerhq/devices": "8.4.5-nightly.2",
|
|
87
|
+
"@ledgerhq/errors": "^6.21.0-nightly.0",
|
|
88
88
|
"@ledgerhq/live-countervalues": "^0.5.6",
|
|
89
|
-
"@ledgerhq/live-env": "^2.
|
|
90
|
-
"@ledgerhq/live-network": "^2.0.
|
|
91
|
-
"@ledgerhq/types-live": "^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",
|
|
@@ -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
|
@@ -16,12 +16,12 @@ const fetch = (path: string) => {
|
|
|
16
16
|
});
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
interface HederaMirrorAccount {
|
|
20
20
|
accountId: AccountId;
|
|
21
21
|
balance: BigNumber;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
export async function getAccountsForPublicKey(publicKey: string): Promise<
|
|
24
|
+
export async function getAccountsForPublicKey(publicKey: string): Promise<HederaMirrorAccount[]> {
|
|
25
25
|
let r;
|
|
26
26
|
try {
|
|
27
27
|
r = await fetch(`/api/v1/accounts?account.publicKey=${publicKey}&balance=false`);
|
|
@@ -30,7 +30,7 @@ export async function getAccountsForPublicKey(publicKey: string): Promise<Accoun
|
|
|
30
30
|
throw e;
|
|
31
31
|
}
|
|
32
32
|
const rawAccounts = r.data.accounts;
|
|
33
|
-
const accounts:
|
|
33
|
+
const accounts: HederaMirrorAccount[] = [];
|
|
34
34
|
|
|
35
35
|
for (const raw of rawAccounts) {
|
|
36
36
|
const accountBalance = await getAccountBalance(raw.account);
|
|
@@ -44,6 +44,11 @@ export async function getAccountsForPublicKey(publicKey: string): Promise<Accoun
|
|
|
44
44
|
return accounts;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
interface HederaMirrorTransfer {
|
|
48
|
+
account: string;
|
|
49
|
+
amount: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
47
52
|
interface HederaMirrorTransaction {
|
|
48
53
|
transfers: HederaMirrorTransfer[];
|
|
49
54
|
charged_tx_fee: string;
|
|
@@ -51,27 +56,41 @@ interface HederaMirrorTransaction {
|
|
|
51
56
|
consensus_timestamp: string;
|
|
52
57
|
}
|
|
53
58
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
59
|
+
export async function getAccountTransactions(
|
|
60
|
+
address: string,
|
|
61
|
+
since: string | null,
|
|
62
|
+
): Promise<HederaMirrorTransaction[]> {
|
|
63
|
+
const transactions: HederaMirrorTransaction[] = [];
|
|
64
|
+
const params = new URLSearchParams({
|
|
65
|
+
"account.id": address,
|
|
66
|
+
order: "desc",
|
|
67
|
+
limit: "100",
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
if (since) {
|
|
71
|
+
params.append("timestamp", `gt:${since}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let nextUrl = `/api/v1/transactions?${params.toString()}`;
|
|
75
|
+
|
|
76
|
+
while (nextUrl) {
|
|
77
|
+
const res = await fetch(nextUrl);
|
|
78
|
+
const newTransactions = res.data.transactions as HederaMirrorTransaction[];
|
|
79
|
+
if (newTransactions.length === 0) break;
|
|
80
|
+
transactions.push(...newTransactions);
|
|
81
|
+
nextUrl = res.data.links.next;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return transactions;
|
|
57
85
|
}
|
|
58
86
|
|
|
59
87
|
export async function getOperationsForAccount(
|
|
60
88
|
ledgerAccountId: string,
|
|
61
89
|
address: string,
|
|
62
|
-
latestOperationTimestamp: string,
|
|
90
|
+
latestOperationTimestamp: string | null,
|
|
63
91
|
): Promise<Operation[]> {
|
|
92
|
+
const rawOperations = await getAccountTransactions(address, latestOperationTimestamp);
|
|
64
93
|
const operations: Operation[] = [];
|
|
65
|
-
let r = await fetch(
|
|
66
|
-
`/api/v1/transactions?account.id=${address}×tamp=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
94
|
|
|
76
95
|
for (const raw of rawOperations) {
|
|
77
96
|
const { consensus_timestamp } = raw;
|
|
@@ -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
|
-
:
|
|
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
|
-
|
|
46
|
+
latestOperationTimestamp ? latestOperationTimestamp.toString() : null,
|
|
47
47
|
);
|
|
48
48
|
const operations = mergeOps(oldOperations, newOperations);
|
|
49
49
|
|