@ledgerhq/coin-canton 0.7.0-nightly.1 → 0.7.0-nightly.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +23 -0
- package/lib/api/lastBlock.integ.test.js +0 -15
- package/lib/api/lastBlock.integ.test.js.map +1 -1
- package/lib/bridge/getTransactionStatus.test.d.ts +2 -0
- package/lib/bridge/getTransactionStatus.test.d.ts.map +1 -0
- package/lib/bridge/getTransactionStatus.test.js +365 -0
- package/lib/bridge/getTransactionStatus.test.js.map +1 -0
- package/lib/bridge/index.d.ts.map +1 -1
- package/lib/bridge/index.js +2 -5
- package/lib/bridge/index.js.map +1 -1
- package/lib/bridge/onboard.d.ts +11 -6
- package/lib/bridge/onboard.d.ts.map +1 -1
- package/lib/bridge/onboard.integ.test.js +49 -27
- package/lib/bridge/onboard.integ.test.js.map +1 -1
- package/lib/bridge/onboard.js +45 -152
- package/lib/bridge/onboard.js.map +1 -1
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +5 -5
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/sync.d.ts +3 -2
- package/lib/bridge/sync.d.ts.map +1 -1
- package/lib/bridge/sync.integ.test.js +31 -14
- package/lib/bridge/sync.integ.test.js.map +1 -1
- package/lib/bridge/sync.js +71 -57
- package/lib/bridge/sync.js.map +1 -1
- package/lib/common-logic/utils.d.ts.map +1 -1
- package/lib/common-logic/utils.js +3 -1
- package/lib/common-logic/utils.js.map +1 -1
- package/lib/common-logic/utils.test.d.ts +2 -0
- package/lib/common-logic/utils.test.d.ts.map +1 -0
- package/lib/common-logic/utils.test.js +104 -0
- package/lib/common-logic/utils.test.js.map +1 -0
- package/lib/config.d.ts +1 -1
- package/lib/config.d.ts.map +1 -1
- package/lib/network/gateway.d.ts +9 -9
- package/lib/network/gateway.d.ts.map +1 -1
- package/lib/network/gateway.integ.test.js +31 -17
- package/lib/network/gateway.integ.test.js.map +1 -1
- package/lib/network/gateway.js +33 -15
- package/lib/network/gateway.js.map +1 -1
- package/lib/types/bridge.d.ts +6 -16
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib/types/onboard.d.ts +5 -5
- package/lib/types/onboard.d.ts.map +1 -1
- package/lib/types/onboard.js +10 -10
- package/lib/types/onboard.js.map +1 -1
- package/lib-es/api/lastBlock.integ.test.js +0 -15
- package/lib-es/api/lastBlock.integ.test.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.test.d.ts +2 -0
- package/lib-es/bridge/getTransactionStatus.test.d.ts.map +1 -0
- package/lib-es/bridge/getTransactionStatus.test.js +360 -0
- package/lib-es/bridge/getTransactionStatus.test.js.map +1 -0
- package/lib-es/bridge/index.d.ts.map +1 -1
- package/lib-es/bridge/index.js +3 -6
- package/lib-es/bridge/index.js.map +1 -1
- package/lib-es/bridge/onboard.d.ts +11 -6
- package/lib-es/bridge/onboard.d.ts.map +1 -1
- package/lib-es/bridge/onboard.integ.test.js +37 -15
- package/lib-es/bridge/onboard.integ.test.js.map +1 -1
- package/lib-es/bridge/onboard.js +44 -152
- package/lib-es/bridge/onboard.js.map +1 -1
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +5 -5
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/sync.d.ts +3 -2
- package/lib-es/bridge/sync.d.ts.map +1 -1
- package/lib-es/bridge/sync.integ.test.js +26 -9
- package/lib-es/bridge/sync.integ.test.js.map +1 -1
- package/lib-es/bridge/sync.js +71 -56
- package/lib-es/bridge/sync.js.map +1 -1
- package/lib-es/common-logic/utils.d.ts.map +1 -1
- package/lib-es/common-logic/utils.js +3 -1
- package/lib-es/common-logic/utils.js.map +1 -1
- package/lib-es/common-logic/utils.test.d.ts +2 -0
- package/lib-es/common-logic/utils.test.d.ts.map +1 -0
- package/lib-es/common-logic/utils.test.js +99 -0
- package/lib-es/common-logic/utils.test.js.map +1 -0
- package/lib-es/config.d.ts +1 -1
- package/lib-es/config.d.ts.map +1 -1
- package/lib-es/network/gateway.d.ts +9 -9
- package/lib-es/network/gateway.d.ts.map +1 -1
- package/lib-es/network/gateway.integ.test.js +31 -17
- package/lib-es/network/gateway.integ.test.js.map +1 -1
- package/lib-es/network/gateway.js +33 -15
- package/lib-es/network/gateway.js.map +1 -1
- package/lib-es/types/bridge.d.ts +6 -16
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/lib-es/types/onboard.d.ts +5 -5
- package/lib-es/types/onboard.d.ts.map +1 -1
- package/lib-es/types/onboard.js +9 -9
- package/lib-es/types/onboard.js.map +1 -1
- package/package.json +5 -4
- package/src/api/lastBlock.integ.test.ts +0 -18
- package/src/bridge/getTransactionStatus.test.ts +446 -0
- package/src/bridge/index.ts +3 -6
- package/src/bridge/onboard.integ.test.ts +44 -31
- package/src/bridge/onboard.ts +61 -209
- package/src/bridge/signOperation.ts +5 -6
- package/src/bridge/sync.integ.test.ts +30 -10
- package/src/bridge/sync.ts +87 -72
- package/src/common-logic/utils.test.ts +108 -0
- package/src/common-logic/utils.ts +4 -1
- package/src/config.ts +1 -1
- package/src/network/gateway.integ.test.ts +48 -21
- package/src/network/gateway.ts +49 -34
- package/src/types/bridge.ts +8 -19
- package/src/types/onboard.ts +5 -5
- package/lib/bridge/serialization.d.ts +0 -4
- package/lib/bridge/serialization.d.ts.map +0 -1
- package/lib/bridge/serialization.js +0 -31
- package/lib/bridge/serialization.js.map +0 -1
- package/lib-es/bridge/serialization.d.ts +0 -4
- package/lib-es/bridge/serialization.d.ts.map +0 -1
- package/lib-es/bridge/serialization.js +0 -27
- package/lib-es/bridge/serialization.js.map +0 -1
- package/src/bridge/serialization.ts +0 -36
package/lib-es/bridge/onboard.js
CHANGED
|
@@ -1,151 +1,79 @@
|
|
|
1
1
|
import { Observable } from "rxjs";
|
|
2
|
-
import {
|
|
3
|
-
import { getDerivationModesForCurrency } from "@ledgerhq/coin-framework/derivation";
|
|
4
|
-
import { getAccountShape } from "./sync";
|
|
2
|
+
import { log } from "@ledgerhq/logs";
|
|
5
3
|
import { prepareOnboarding, submitOnboarding, getPartyByPubKey, preparePreApprovalTransaction, submitPreApprovalTransaction, prepareTapRequest, submitTapRequest, } from "../network/gateway";
|
|
6
|
-
import { OnboardStatus,
|
|
4
|
+
import { OnboardStatus, AuthorizeStatus, } from "../types/onboard";
|
|
7
5
|
import resolver from "../signer";
|
|
8
|
-
async function _getKeypair(signerContext, deviceId, derivationPath) {
|
|
9
|
-
return signerContext(deviceId, async (signer) => {
|
|
10
|
-
const { publicKey, address } = await signer.getAddress(derivationPath);
|
|
11
|
-
return { signer, publicKey: publicKey.replace("0x", ""), address };
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
6
|
export const isAccountOnboarded = async (currency, publicKey) => {
|
|
15
7
|
try {
|
|
16
8
|
const { party_id } = await getPartyByPubKey(currency, publicKey);
|
|
17
9
|
if (party_id) {
|
|
18
|
-
return { isOnboarded: true, party_id };
|
|
10
|
+
return { isOnboarded: true, partyId: party_id };
|
|
19
11
|
}
|
|
20
12
|
else {
|
|
21
13
|
return { isOnboarded: false };
|
|
22
14
|
}
|
|
23
15
|
}
|
|
24
16
|
catch (err) {
|
|
25
|
-
log("[isAccountOnboarded] Error checking party status (likely not onboarded):", err);
|
|
26
17
|
return { isOnboarded: false };
|
|
27
18
|
}
|
|
28
19
|
};
|
|
29
|
-
export const
|
|
20
|
+
export const isAccountAuthorized = async (operations, partyId) => {
|
|
21
|
+
// temporary solution to check if the account is authorized
|
|
22
|
+
return operations.some(operation => operation.senders.includes(partyId));
|
|
23
|
+
};
|
|
24
|
+
export const buildOnboardAccount = (signerContext) => (currency, deviceId, account) => new Observable(o => {
|
|
30
25
|
async function main() {
|
|
31
|
-
|
|
32
|
-
status: OnboardStatus.INIT,
|
|
33
|
-
});
|
|
34
|
-
const derivationMode = getDerivationModesForCurrency(currency)[0];
|
|
26
|
+
o.next({ status: OnboardStatus.INIT });
|
|
35
27
|
const getAddress = resolver(signerContext);
|
|
36
|
-
const {
|
|
37
|
-
path:
|
|
28
|
+
const { publicKey } = await getAddress(deviceId, {
|
|
29
|
+
path: account.freshAddressPath,
|
|
38
30
|
currency,
|
|
39
|
-
derivationMode: derivationMode
|
|
31
|
+
derivationMode: account.derivationMode,
|
|
40
32
|
});
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
const { party_id: partyId } = await isAccountOnboarded(currency, publicKey);
|
|
33
|
+
o.next({ status: OnboardStatus.PREPARE });
|
|
34
|
+
let { partyId } = await isAccountOnboarded(currency, publicKey);
|
|
45
35
|
if (partyId) {
|
|
46
|
-
|
|
47
|
-
address,
|
|
48
|
-
derivationPath,
|
|
49
|
-
partyId,
|
|
50
|
-
currency,
|
|
51
|
-
derivationMode,
|
|
52
|
-
});
|
|
53
|
-
observer.next({
|
|
54
|
-
partyId,
|
|
55
|
-
account,
|
|
56
|
-
});
|
|
57
|
-
observer.complete();
|
|
36
|
+
o.next({ partyId, account }); // success
|
|
58
37
|
return;
|
|
59
38
|
}
|
|
60
|
-
const preparedTransaction = await prepareOnboarding(currency, publicKey
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
});
|
|
68
|
-
const result = await submitOnboarding(currency, { public_key: publicKey, public_key_type: "ed25519" }, preparedTransaction, signature).catch(async (err) => {
|
|
69
|
-
if (err.type === "PARTY_ALREADY_EXISTS") {
|
|
70
|
-
const account = await createAccount({
|
|
71
|
-
address,
|
|
72
|
-
derivationPath,
|
|
73
|
-
partyId: preparedTransaction.party_id,
|
|
74
|
-
currency,
|
|
75
|
-
derivationMode,
|
|
76
|
-
});
|
|
77
|
-
observer.next({
|
|
78
|
-
partyId: preparedTransaction.party_id,
|
|
79
|
-
account,
|
|
80
|
-
});
|
|
81
|
-
return observer.complete();
|
|
82
|
-
}
|
|
83
|
-
throw err;
|
|
84
|
-
});
|
|
85
|
-
if (result) {
|
|
86
|
-
observer.next({
|
|
87
|
-
status: OnboardStatus.SUCCESS,
|
|
88
|
-
});
|
|
89
|
-
const account = await createAccount({
|
|
90
|
-
address,
|
|
91
|
-
derivationPath,
|
|
92
|
-
partyId: result.party.party_id,
|
|
93
|
-
currency,
|
|
94
|
-
derivationMode,
|
|
95
|
-
});
|
|
96
|
-
observer.next({
|
|
97
|
-
partyId: result.party.party_id,
|
|
98
|
-
account,
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
observer.complete();
|
|
39
|
+
const preparedTransaction = await prepareOnboarding(currency, publicKey);
|
|
40
|
+
partyId = preparedTransaction.party_id;
|
|
41
|
+
o.next({ status: OnboardStatus.SIGN });
|
|
42
|
+
const signature = await signerContext(deviceId, signer => signer.signTransaction(account.freshAddressPath, preparedTransaction.transactions.combined_hash));
|
|
43
|
+
o.next({ status: OnboardStatus.SUBMIT });
|
|
44
|
+
await submitOnboarding(currency, publicKey, preparedTransaction, signature);
|
|
45
|
+
o.next({ partyId, account }); // success
|
|
102
46
|
}
|
|
103
|
-
main().then(() =>
|
|
104
|
-
log("[
|
|
105
|
-
|
|
47
|
+
main().then(() => o.complete(), error => {
|
|
48
|
+
log("[canton:onboard] onboardAccount failed:", error);
|
|
49
|
+
o.error(error);
|
|
106
50
|
});
|
|
107
51
|
});
|
|
108
|
-
export const buildAuthorizePreapproval = (signerContext) => (currency, deviceId,
|
|
52
|
+
export const buildAuthorizePreapproval = (signerContext) => (currency, deviceId, account, partyId) => new Observable(o => {
|
|
109
53
|
async function main() {
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
status:
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
});
|
|
121
|
-
const { isApproved } = await submitPreApprovalTransaction(currency, partyId, preparedTransaction, signature);
|
|
122
|
-
observer.next({
|
|
123
|
-
status: PreApprovalStatus.SUCCESS,
|
|
124
|
-
});
|
|
125
|
-
observer.next({
|
|
126
|
-
isApproved,
|
|
127
|
-
});
|
|
54
|
+
o.next({ status: AuthorizeStatus.INIT });
|
|
55
|
+
const isAuthorized = await isAccountAuthorized(account.operations, partyId);
|
|
56
|
+
if (!isAuthorized) {
|
|
57
|
+
o.next({ status: AuthorizeStatus.PREPARE });
|
|
58
|
+
const preparedTransaction = await preparePreApprovalTransaction(currency, partyId);
|
|
59
|
+
o.next({ status: AuthorizeStatus.SIGN });
|
|
60
|
+
const signature = await signerContext(deviceId, signer => signer.signTransaction(account.freshAddressPath, preparedTransaction.hash));
|
|
61
|
+
o.next({ status: AuthorizeStatus.SUBMIT });
|
|
62
|
+
await submitPreApprovalTransaction(currency, partyId, preparedTransaction, signature);
|
|
63
|
+
}
|
|
64
|
+
o.next({ isApproved: true }); // success
|
|
128
65
|
const handleTapRequest = async () => {
|
|
129
66
|
try {
|
|
130
|
-
const { serialized, hash } = await prepareTapRequest(currency, {
|
|
131
|
-
partyId,
|
|
132
|
-
});
|
|
67
|
+
const { serialized, hash } = await prepareTapRequest(currency, { partyId });
|
|
133
68
|
if (serialized && hash) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
});
|
|
137
|
-
const signature = await signerContext(deviceId, signer => signer.signTransaction(derivationPath, hash));
|
|
138
|
-
observer.next({
|
|
139
|
-
status: PreApprovalStatus.SUBMIT,
|
|
140
|
-
});
|
|
69
|
+
o.next({ status: AuthorizeStatus.SIGN });
|
|
70
|
+
const signature = await signerContext(deviceId, signer => signer.signTransaction(account.freshAddressPath, hash));
|
|
71
|
+
o.next({ status: AuthorizeStatus.SUBMIT });
|
|
141
72
|
await submitTapRequest(currency, {
|
|
142
73
|
partyId,
|
|
143
74
|
serialized,
|
|
144
75
|
signature,
|
|
145
76
|
});
|
|
146
|
-
observer.next({
|
|
147
|
-
status: PreApprovalStatus.SUCCESS,
|
|
148
|
-
});
|
|
149
77
|
}
|
|
150
78
|
}
|
|
151
79
|
catch (err) {
|
|
@@ -153,46 +81,10 @@ export const buildAuthorizePreapproval = (signerContext) => (currency, deviceId,
|
|
|
153
81
|
}
|
|
154
82
|
};
|
|
155
83
|
await handleTapRequest();
|
|
156
|
-
observer.complete();
|
|
157
84
|
}
|
|
158
|
-
main().then(() =>
|
|
159
|
-
log("[
|
|
160
|
-
|
|
85
|
+
main().then(() => o.complete(), error => {
|
|
86
|
+
log("[canton:onboard] authorizePreapproval failed:", error);
|
|
87
|
+
o.error(error);
|
|
161
88
|
});
|
|
162
89
|
});
|
|
163
|
-
const createAccount = async ({ address, partyId, derivationPath, currency, derivationMode, index = 0, }) => {
|
|
164
|
-
const accountShape = await getAccountShape({
|
|
165
|
-
address,
|
|
166
|
-
currency,
|
|
167
|
-
derivationMode,
|
|
168
|
-
derivationPath,
|
|
169
|
-
index,
|
|
170
|
-
rest: {
|
|
171
|
-
cantonResources: {
|
|
172
|
-
partyId,
|
|
173
|
-
},
|
|
174
|
-
},
|
|
175
|
-
}, { paginationConfig: {} });
|
|
176
|
-
const account = {
|
|
177
|
-
...accountShape,
|
|
178
|
-
type: "Account",
|
|
179
|
-
xpub: partyId.replace(/:/g, "_"),
|
|
180
|
-
index,
|
|
181
|
-
// operations: [],
|
|
182
|
-
currency,
|
|
183
|
-
derivationMode,
|
|
184
|
-
lastSyncDate: new Date(),
|
|
185
|
-
pendingOperations: [],
|
|
186
|
-
seedIdentifier: address,
|
|
187
|
-
balanceHistoryCache: emptyHistoryCache,
|
|
188
|
-
cantonResources: {
|
|
189
|
-
partyId,
|
|
190
|
-
},
|
|
191
|
-
};
|
|
192
|
-
return account;
|
|
193
|
-
};
|
|
194
|
-
const log = (message, ...rest) => {
|
|
195
|
-
// eslint-disable-next-line no-console
|
|
196
|
-
console.log(message, ...rest);
|
|
197
|
-
};
|
|
198
90
|
//# sourceMappingURL=onboard.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/bridge/onboard.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../src/bridge/onboard.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signOperation.d.ts","sourceRoot":"","sources":["../../src/bridge/signOperation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAa,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"signOperation.d.ts","sourceRoot":"","sources":["../../src/bridge/signOperation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAa,MAAM,sBAAsB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAIhE,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAErD,eAAO,MAAM,kBAAkB,GAC5B,eAAe,aAAa,CAAC,YAAY,CAAC,KAAG,aAAa,CAAC,WAAW,CAAC,CAAC,eAAe,CAuFpF,CAAC"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Observable } from "rxjs";
|
|
2
2
|
import { FeeNotLoaded } from "@ledgerhq/errors";
|
|
3
3
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
4
|
+
import { decodeAccountId } from "@ledgerhq/coin-framework/account";
|
|
4
5
|
import { combine, craftTransaction } from "../common-logic";
|
|
5
6
|
export const buildSignOperation = (signerContext) => ({ account, deviceId, transaction }) => new Observable(o => {
|
|
6
7
|
async function main() {
|
|
@@ -13,9 +14,8 @@ export const buildSignOperation = (signerContext) => ({ account, deviceId, trans
|
|
|
13
14
|
type: "device-signature-requested",
|
|
14
15
|
});
|
|
15
16
|
const signature = await signerContext(deviceId, async (signer) => {
|
|
16
|
-
const { freshAddressPath: derivationPath } = account;
|
|
17
|
-
const
|
|
18
|
-
.cantonResources.partyId;
|
|
17
|
+
const { id, freshAddressPath: derivationPath, xpub } = account;
|
|
18
|
+
const address = xpub ?? decodeAccountId(id).xpubOrAddress;
|
|
19
19
|
const params = {
|
|
20
20
|
recipient: transaction.recipient,
|
|
21
21
|
amount: transaction.amount,
|
|
@@ -26,10 +26,10 @@ export const buildSignOperation = (signerContext) => ({ account, deviceId, trans
|
|
|
26
26
|
params.memo = transaction.memo;
|
|
27
27
|
}
|
|
28
28
|
const { hash, serializedTransaction } = await craftTransaction(account.currency, {
|
|
29
|
-
address
|
|
29
|
+
address,
|
|
30
30
|
}, params);
|
|
31
31
|
const transactionSignature = await signer.signTransaction(derivationPath, hash);
|
|
32
|
-
return combine(serializedTransaction, `${transactionSignature}__PARTY__${
|
|
32
|
+
return combine(serializedTransaction, `${transactionSignature}__PARTY__${address}`);
|
|
33
33
|
});
|
|
34
34
|
o.next({
|
|
35
35
|
type: "device-signature-granted",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signOperation.js","sourceRoot":"","sources":["../../src/bridge/signOperation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAG5D,MAAM,CAAC,MAAM,kBAAkB,GAC7B,CAAC,aAA0C,EAA+C,EAAE,CAC5F,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,EAAE,EAAE,CACrC,IAAI,UAAU,CAAC,CAAC,CAAC,EAAE;IACjB,KAAK,UAAU,IAAI;QACjB,MAAM,EAAE,GAAG,EAAE,GAAG,WAAW,CAAC;QAC5B,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,YAAY,EAAE,CAAC;QAEnC,IAAI,CAAC;YACH,8EAA8E;YAC9E,CAAC,CAAC,IAAI,CAAC;gBACL,IAAI,EAAE,4BAA4B;aACnC,CAAC,CAAC;YAEH,MAAM,SAAS,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;gBAC7D,MAAM,EAAE,gBAAgB,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"signOperation.js","sourceRoot":"","sources":["../../src/bridge/signOperation.ts"],"names":[],"mappings":"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"}
|
package/lib-es/bridge/sync.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { GetAccountShape } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
3
|
+
import { CantonAccount, CantonSigner } from "../types";
|
|
4
|
+
export declare function makeGetAccountShape(signerContext: SignerContext<CantonSigner>): GetAccountShape<CantonAccount>;
|
|
4
5
|
//# sourceMappingURL=sync.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/bridge/sync.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAY,MAAM,2CAA2C,CAAC;
|
|
1
|
+
{"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../src/bridge/sync.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,eAAe,EAAY,MAAM,2CAA2C,CAAC;AAEtF,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAIhE,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AA4DvD,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,aAAa,CAAC,YAAY,CAAC,GACzC,eAAe,CAAC,aAAa,CAAC,CAmFhC"}
|
|
@@ -3,20 +3,31 @@ import { getDerivationModesForCurrency, getDerivationScheme, runDerivationScheme
|
|
|
3
3
|
import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
|
|
4
4
|
import coinConfig from "../config";
|
|
5
5
|
import * as gateway from "../network/gateway";
|
|
6
|
-
import {
|
|
6
|
+
import { generateMockKeyPair, createMockSigner } from "../test/cantonTestUtils";
|
|
7
|
+
import { makeGetAccountShape } from "./sync";
|
|
7
8
|
const TEST_ADDRESS = "b6400f93ea1c74aea86be39b0ccc846fc5de01f12b2ad0d7c31848d6fb6eb6d9::1220c81315e2bf2524a9141bcc6cbf19b61c151e0dcaa95343c0ccf53aed7415c4ec";
|
|
8
9
|
const currency = getCryptoCurrencyById("canton_network");
|
|
9
10
|
const derivationMode = getDerivationModesForCurrency(currency)[0];
|
|
10
11
|
const derivationPath = runDerivationScheme(getDerivationScheme({ derivationMode, currency }), currency, {
|
|
11
12
|
account: 0,
|
|
12
13
|
});
|
|
14
|
+
const xpub = TEST_ADDRESS;
|
|
13
15
|
const ACCOUNT_SHAPE_INFO = {
|
|
14
16
|
address: TEST_ADDRESS,
|
|
15
17
|
currency,
|
|
16
18
|
derivationMode,
|
|
17
19
|
derivationPath,
|
|
18
20
|
index: 0,
|
|
21
|
+
initialAccount: {
|
|
22
|
+
xpub,
|
|
23
|
+
},
|
|
19
24
|
};
|
|
25
|
+
// Mock signer context for testing
|
|
26
|
+
const keyPair = generateMockKeyPair();
|
|
27
|
+
const mockSigner = createMockSigner(keyPair);
|
|
28
|
+
const mockSignerContext = jest.fn().mockImplementation((deviceId, callback) => {
|
|
29
|
+
return callback(mockSigner);
|
|
30
|
+
});
|
|
20
31
|
describe("sync (devnet)", () => {
|
|
21
32
|
beforeAll(async () => {
|
|
22
33
|
coinConfig.setCoinConfig(() => ({
|
|
@@ -29,12 +40,13 @@ describe("sync (devnet)", () => {
|
|
|
29
40
|
},
|
|
30
41
|
}));
|
|
31
42
|
});
|
|
32
|
-
describe("
|
|
43
|
+
describe("makeGetAccountShape", () => {
|
|
33
44
|
it("should fetch account shape for a valid address", async () => {
|
|
45
|
+
const getAccountShape = makeGetAccountShape(mockSignerContext);
|
|
34
46
|
const result = await getAccountShape(ACCOUNT_SHAPE_INFO, { paginationConfig: {} });
|
|
35
47
|
expect(result).toBeDefined();
|
|
36
48
|
expect(result.id).toBeDefined();
|
|
37
|
-
expect(result.xpub).toBe(TEST_ADDRESS
|
|
49
|
+
expect(result.xpub).toBe(TEST_ADDRESS);
|
|
38
50
|
expect(result.blockHeight).toBeGreaterThan(0);
|
|
39
51
|
expect(result.balance).toBeDefined();
|
|
40
52
|
expect(result.spendableBalance).toBeDefined();
|
|
@@ -47,10 +59,12 @@ describe("sync (devnet)", () => {
|
|
|
47
59
|
expect(result.spendableBalance?.toNumber()).toBeLessThanOrEqual(result.balance?.toNumber() || 0);
|
|
48
60
|
});
|
|
49
61
|
it("should handle address with colons correctly", async () => {
|
|
62
|
+
const getAccountShape = makeGetAccountShape(mockSignerContext);
|
|
50
63
|
const result = await getAccountShape(ACCOUNT_SHAPE_INFO, { paginationConfig: {} });
|
|
51
|
-
expect(result.xpub).
|
|
64
|
+
expect(result.xpub).toContain("::");
|
|
52
65
|
});
|
|
53
66
|
it("should merge operations correctly with initial account", async () => {
|
|
67
|
+
const getAccountShape = makeGetAccountShape(mockSignerContext);
|
|
54
68
|
const operations = [
|
|
55
69
|
{
|
|
56
70
|
id: "test-op-1",
|
|
@@ -71,7 +85,7 @@ describe("sync (devnet)", () => {
|
|
|
71
85
|
const result = await getAccountShape({
|
|
72
86
|
...ACCOUNT_SHAPE_INFO,
|
|
73
87
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
74
|
-
initialAccount: { operations },
|
|
88
|
+
initialAccount: { xpub, operations },
|
|
75
89
|
}, { paginationConfig: {} });
|
|
76
90
|
expect(result.operations).toBeDefined();
|
|
77
91
|
expect(result.operationsCount).toBeGreaterThanOrEqual(1);
|
|
@@ -87,12 +101,13 @@ describe("sync (devnet)", () => {
|
|
|
87
101
|
locked: true,
|
|
88
102
|
},
|
|
89
103
|
]);
|
|
104
|
+
const getAccountShape = makeGetAccountShape(mockSignerContext);
|
|
90
105
|
const result = await getAccountShape(ACCOUNT_SHAPE_INFO, { paginationConfig: {} });
|
|
91
106
|
expect(result.balance?.toNumber()).toBe(1000000);
|
|
92
107
|
expect(result.spendableBalance?.toNumber()).toBe(0);
|
|
93
108
|
mockGetBalance.mockRestore();
|
|
94
109
|
});
|
|
95
|
-
it("should call getOperations with correct cursor based
|
|
110
|
+
it("should call getOperations with correct cursor based on initial account", async () => {
|
|
96
111
|
const mockGetOperations = jest.spyOn(gateway, "getOperations");
|
|
97
112
|
const operation = {
|
|
98
113
|
id: "test-op-1",
|
|
@@ -110,12 +125,13 @@ describe("sync (devnet)", () => {
|
|
|
110
125
|
extra: { uid: "uid-1" },
|
|
111
126
|
};
|
|
112
127
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
113
|
-
const initialAccount = { operations: [operation] };
|
|
128
|
+
const initialAccount = { xpub, operations: [operation] };
|
|
129
|
+
const getAccountShape = makeGetAccountShape(mockSignerContext);
|
|
114
130
|
const result = await getAccountShape({
|
|
115
131
|
...ACCOUNT_SHAPE_INFO,
|
|
116
132
|
initialAccount,
|
|
117
133
|
}, { paginationConfig: {} });
|
|
118
|
-
expect(mockGetOperations).toHaveBeenCalledWith(TEST_ADDRESS, {
|
|
134
|
+
expect(mockGetOperations).toHaveBeenCalledWith(currency, TEST_ADDRESS, {
|
|
119
135
|
cursor: (operation.blockHeight || 0) + 1,
|
|
120
136
|
limit: 100,
|
|
121
137
|
});
|
|
@@ -124,10 +140,11 @@ describe("sync (devnet)", () => {
|
|
|
124
140
|
});
|
|
125
141
|
it("should call getOperations with cursor 0 when no initial account", async () => {
|
|
126
142
|
const mockGetOperations = jest.spyOn(gateway, "getOperations");
|
|
143
|
+
const getAccountShape = makeGetAccountShape(mockSignerContext);
|
|
127
144
|
const result = await getAccountShape(ACCOUNT_SHAPE_INFO, { paginationConfig: {} });
|
|
128
145
|
expect(result.operations).toBeDefined();
|
|
129
146
|
expect(result.operationsCount).toBeGreaterThanOrEqual(1);
|
|
130
|
-
expect(mockGetOperations).toHaveBeenCalledWith(TEST_ADDRESS, {
|
|
147
|
+
expect(mockGetOperations).toHaveBeenCalledWith(currency, TEST_ADDRESS, {
|
|
131
148
|
cursor: 0,
|
|
132
149
|
limit: 100,
|
|
133
150
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sync.integ.test.js","sourceRoot":"","sources":["../../src/bridge/sync.integ.test.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,cAAc,CAAC;AAErC,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,UAAU,MAAM,WAAW,CAAC;AACnC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"sync.integ.test.js","sourceRoot":"","sources":["../../src/bridge/sync.integ.test.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,cAAc,CAAC;AAErC,OAAO,EACL,6BAA6B,EAC7B,mBAAmB,EACnB,mBAAmB,GACpB,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAE1E,OAAO,UAAU,MAAM,WAAW,CAAC;AACnC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhF,OAAO,EAAE,mBAAmB,EAAE,MAAM,QAAQ,CAAC;AAE7C,MAAM,YAAY,GAChB,wIAAwI,CAAC;AAC3I,MAAM,QAAQ,GAAG,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;AACzD,MAAM,cAAc,GAAG,6BAA6B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,MAAM,cAAc,GAAG,mBAAmB,CACxC,mBAAmB,CAAC,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,EACjD,QAAQ,EACR;IACE,OAAO,EAAE,CAAC;CACX,CACF,CAAC;AACF,MAAM,IAAI,GAAG,YAAY,CAAC;AAC1B,MAAM,kBAAkB,GAAoC;IAC1D,OAAO,EAAE,YAAY;IACrB,QAAQ;IACR,cAAc;IACd,cAAc;IACd,KAAK,EAAE,CAAC;IACR,cAAc,EAAE;QACd,IAAI;KACY;CACnB,CAAC;AAEF,kCAAkC;AAClC,MAAM,OAAO,GAAG,mBAAmB,EAAE,CAAC;AACtC,MAAM,UAAU,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;AAC7C,MAAM,iBAAiB,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE;IAC5E,OAAO,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC9B,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,UAAU,CAAC,aAAa,CAAC,GAAG,EAAE,CAAC,CAAC;YAC9B,UAAU,EAAE,iDAAiD;YAC7D,UAAU,EAAE,IAAI;YAChB,WAAW,EAAE,QAAQ;YACrB,kBAAkB,EAAE,QAAQ;YAC5B,MAAM,EAAE;gBACN,IAAI,EAAE,QAAQ;aACf;SACF,CAAC,CAAC,CAAC;IACN,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;QACnC,EAAE,CAAC,gDAAgD,EAAE,KAAK,IAAI,EAAE;YAC9D,MAAM,eAAe,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,kBAAkB,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;YAEnF,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;YAC7B,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;YAChC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;YACrC,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,WAAW,EAAE,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAEzD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YAC9C,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;YACvD,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;YAExD,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,EAAE,CAAC,CAAC,mBAAmB,CAC7D,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,CAChC,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,6CAA6C,EAAE,KAAK,IAAI,EAAE;YAC3D,MAAM,eAAe,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,kBAAkB,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;YAEnF,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wDAAwD,EAAE,KAAK,IAAI,EAAE;YACtE,MAAM,eAAe,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;YAE/D,MAAM,UAAU,GAAgB;gBAC9B;oBACE,EAAE,EAAE,WAAW;oBACf,IAAI,EAAE,aAAa;oBACnB,SAAS,EAAE,cAAc;oBACzB,IAAI,EAAE,KAAc;oBACpB,KAAK,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC;oBAC7B,GAAG,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC;oBAC1B,SAAS,EAAE,cAAc;oBACzB,WAAW,EAAE,GAAG;oBAChB,OAAO,EAAE,CAAC,YAAY,CAAC;oBACvB,UAAU,EAAE,CAAC,aAAa,CAAC;oBAC3B,IAAI,EAAE,IAAI,IAAI,CAAC,YAAY,CAAC;oBAC5B,yBAAyB,EAAE,GAAG;oBAC9B,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;iBACxB;aACF,CAAC;YAEF,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC;gBACE,GAAG,kBAAkB;gBACrB,yEAAyE;gBACzE,cAAc,EAAE,EAAE,IAAI,EAAE,UAAU,EAAa;aAChD,EACD,EAAE,gBAAgB,EAAE,EAAE,EAAE,CACzB,CAAC;YAEF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YACzD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,EAAE,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,WAAW,CAAC,CAAC;YACvE,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,4EAA4E,EAAE,KAAK,IAAI,EAAE;YAC1F,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;YAEzD,cAAc,CAAC,iBAAiB,CAAC;gBAC/B;oBACE,aAAa,EAAE,QAAQ;oBACvB,MAAM,EAAE,OAAO;oBACf,MAAM,EAAE,IAAI;iBACb;aACF,CAAC,CAAC;YAEH,MAAM,eAAe,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,kBAAkB,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;YAEnF,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACjD,MAAM,CAAC,MAAM,CAAC,gBAAgB,EAAE,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAEpD,cAAc,CAAC,WAAW,EAAE,CAAC;QAC/B,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;YACtF,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YAC/D,MAAM,SAAS,GAAc;gBAC3B,EAAE,EAAE,WAAW;gBACf,IAAI,EAAE,aAAa;gBACnB,SAAS,EAAE,cAAc;gBACzB,IAAI,EAAE,KAAc;gBACpB,KAAK,EAAE,IAAI,SAAS,CAAC,OAAO,CAAC;gBAC7B,GAAG,EAAE,IAAI,SAAS,CAAC,MAAM,CAAC;gBAC1B,SAAS,EAAE,cAAc;gBACzB,WAAW,EAAE,GAAG;gBAChB,OAAO,EAAE,CAAC,YAAY,CAAC;gBACvB,UAAU,EAAE,CAAC,aAAa,CAAC;gBAC3B,IAAI,EAAE,IAAI,IAAI,CAAC,YAAY,CAAC;gBAC5B,yBAAyB,EAAE,GAAG;gBAC9B,KAAK,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;aACxB,CAAC;YAEF,yEAAyE;YACzE,MAAM,cAAc,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,SAAS,CAAC,EAAa,CAAC;YAEpE,MAAM,eAAe,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,eAAe,CAClC;gBACE,GAAG,kBAAkB;gBACrB,cAAc;aACf,EACD,EAAE,gBAAgB,EAAE,EAAE,EAAE,CACzB,CAAC;YAEF,MAAM,CAAC,iBAAiB,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE;gBACrE,MAAM,EAAE,CAAC,SAAS,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC;gBACxC,KAAK,EAAE,GAAG;aACX,CAAC,CAAC;YACH,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;YAC/E,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;YAE/D,MAAM,eAAe,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;YAC/D,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,kBAAkB,EAAE,EAAE,gBAAgB,EAAE,EAAE,EAAE,CAAC,CAAC;YAEnF,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,CAAC;YACxC,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;YAEzD,MAAM,CAAC,iBAAiB,CAAC,CAAC,oBAAoB,CAAC,QAAQ,EAAE,YAAY,EAAE;gBACrE,MAAM,EAAE,CAAC;gBACT,KAAK,EAAE,GAAG;aACX,CAAC,CAAC;YAEH,iBAAiB,CAAC,WAAW,EAAE,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
package/lib-es/bridge/sync.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import BigNumber from "bignumber.js";
|
|
2
|
-
import {
|
|
2
|
+
import { encodeAccountId } from "@ledgerhq/coin-framework/account/index";
|
|
3
3
|
import { mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
4
4
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
5
5
|
import { getBalance, getLedgerEnd, getOperations } from "../network/gateway";
|
|
6
6
|
import coinConfig from "../config";
|
|
7
|
+
import resolver from "../signer";
|
|
8
|
+
import { isAccountOnboarded, isAccountAuthorized } from "./onboard";
|
|
7
9
|
const txInfoToOperationAdapter = (accountId, partyId) => (txInfo) => {
|
|
8
10
|
const { transaction_hash, uid, block: { height, hash }, senders, recipients, transaction_timestamp, fee: { value: fee }, transfers: [{ value: transferValue, details }], } = txInfo;
|
|
9
11
|
let type = "UNKNOWN";
|
|
@@ -45,61 +47,74 @@ const txInfoToOperationAdapter = (accountId, partyId) => (txInfo) => {
|
|
|
45
47
|
const filterOperations = (transactions, accountId, partyId) => {
|
|
46
48
|
return transactions.map(txInfoToOperationAdapter(accountId, partyId));
|
|
47
49
|
};
|
|
48
|
-
export
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const reserveMin = coinConfig.getCoinConfig(currency).minReserve || 0;
|
|
72
|
-
const lockedAmount = balanceData.locked ? balance : new BigNumber(0);
|
|
73
|
-
const spendableBalance = BigNumber.max(0, balance.minus(lockedAmount).minus(BigNumber(reserveMin)));
|
|
74
|
-
let operations = [];
|
|
75
|
-
// Tx history fetching if xpubOrAddress is not empty
|
|
76
|
-
if (xpubOrAddress) {
|
|
77
|
-
const oldOperations = initialAccount?.operations || [];
|
|
78
|
-
const startAt = oldOperations.length ? (oldOperations[0].blockHeight || 0) + 1 : 0;
|
|
79
|
-
const transactionData = await getOperations(currency, partyId, {
|
|
80
|
-
cursor: startAt,
|
|
81
|
-
limit: 100,
|
|
50
|
+
export function makeGetAccountShape(signerContext) {
|
|
51
|
+
return async (info) => {
|
|
52
|
+
const { address, currency, derivationMode, derivationPath, initialAccount } = info;
|
|
53
|
+
let xpubOrAddress = initialAccount?.xpub || "";
|
|
54
|
+
if (!xpubOrAddress) {
|
|
55
|
+
const getAddress = resolver(signerContext);
|
|
56
|
+
const { publicKey } = await getAddress(info.deviceId || "", {
|
|
57
|
+
path: derivationPath,
|
|
58
|
+
currency: currency,
|
|
59
|
+
derivationMode: derivationMode,
|
|
60
|
+
verify: false,
|
|
61
|
+
});
|
|
62
|
+
const { isOnboarded, partyId } = await isAccountOnboarded(currency, publicKey);
|
|
63
|
+
if (isOnboarded && partyId) {
|
|
64
|
+
xpubOrAddress = partyId;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const accountId = encodeAccountId({
|
|
68
|
+
type: "js",
|
|
69
|
+
version: "2",
|
|
70
|
+
currencyId: currency.id,
|
|
71
|
+
xpubOrAddress: xpubOrAddress,
|
|
72
|
+
derivationMode,
|
|
82
73
|
});
|
|
83
|
-
const
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
balance
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
74
|
+
const { nativeInstrumentId } = coinConfig.getCoinConfig(currency);
|
|
75
|
+
const balances = xpubOrAddress ? await getBalance(currency, xpubOrAddress) : [];
|
|
76
|
+
const balanceData = balances.find(balance => balance.instrument_id.includes(nativeInstrumentId)) || {
|
|
77
|
+
instrument_id: nativeInstrumentId,
|
|
78
|
+
amount: 0,
|
|
79
|
+
locked: false,
|
|
80
|
+
};
|
|
81
|
+
const balance = new BigNumber(balanceData.amount);
|
|
82
|
+
const reserveMin = new BigNumber(coinConfig.getCoinConfig(currency).minReserve || 0);
|
|
83
|
+
const lockedAmount = balanceData.locked ? balance : new BigNumber(0);
|
|
84
|
+
const spendableBalance = BigNumber.max(0, balance.minus(lockedAmount).minus(reserveMin));
|
|
85
|
+
let operations = [];
|
|
86
|
+
if (xpubOrAddress) {
|
|
87
|
+
const oldOperations = initialAccount?.operations || [];
|
|
88
|
+
const startAt = oldOperations.length ? (oldOperations[0].blockHeight || 0) + 1 : 0;
|
|
89
|
+
const transactionData = await getOperations(currency, xpubOrAddress, {
|
|
90
|
+
cursor: startAt,
|
|
91
|
+
limit: 100,
|
|
92
|
+
});
|
|
93
|
+
const newOperations = filterOperations(transactionData.operations, accountId, xpubOrAddress);
|
|
94
|
+
operations = mergeOps(oldOperations, newOperations);
|
|
95
|
+
}
|
|
96
|
+
const isAuthorized = await isAccountAuthorized(operations, xpubOrAddress);
|
|
97
|
+
const used = isAuthorized && balance.gt(0);
|
|
98
|
+
const blockHeight = await getLedgerEnd(currency);
|
|
99
|
+
const creationDate = operations.length > 0
|
|
100
|
+
? new Date(Math.min(...operations.map(op => op.date.getTime())))
|
|
101
|
+
: new Date();
|
|
102
|
+
const shape = {
|
|
103
|
+
id: accountId,
|
|
104
|
+
type: "Account",
|
|
105
|
+
balance,
|
|
106
|
+
blockHeight,
|
|
107
|
+
creationDate,
|
|
108
|
+
lastSyncDate: new Date(),
|
|
109
|
+
freshAddress: address,
|
|
110
|
+
seedIdentifier: address,
|
|
111
|
+
operations,
|
|
112
|
+
operationsCount: operations.length,
|
|
113
|
+
spendableBalance,
|
|
114
|
+
xpub: xpubOrAddress,
|
|
115
|
+
used,
|
|
116
|
+
};
|
|
117
|
+
return shape;
|
|
102
118
|
};
|
|
103
|
-
|
|
104
|
-
};
|
|
119
|
+
}
|
|
105
120
|
//# sourceMappingURL=sync.js.map
|