@ledgerhq/coin-canton 0.5.0 → 0.5.1-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 +12 -0
- package/lib/api/getBalance.integ.test.js +9 -5
- package/lib/api/getBalance.integ.test.js.map +1 -1
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.js +20 -25
- package/lib/api/index.js.map +1 -1
- package/lib/api/lastBlock.integ.test.js +1 -1
- package/lib/api/lastBlock.integ.test.js.map +1 -1
- package/lib/api/listOperations.integ.test.js +1 -1
- package/lib/api/listOperations.integ.test.js.map +1 -1
- package/lib/bridge/broadcast.d.ts.map +1 -1
- package/lib/bridge/broadcast.js +3 -2
- package/lib/bridge/broadcast.js.map +1 -1
- package/lib/bridge/broadcast.test.js +9 -0
- package/lib/bridge/broadcast.test.js.map +1 -1
- package/lib/bridge/createTransaction.js +1 -1
- package/lib/bridge/createTransaction.js.map +1 -1
- package/lib/bridge/getTransactionStatus.js +1 -1
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/index.d.ts.map +1 -1
- package/lib/bridge/index.js +3 -0
- package/lib/bridge/index.js.map +1 -1
- package/lib/bridge/onboard.d.ts +7 -5
- package/lib/bridge/onboard.d.ts.map +1 -1
- package/lib/bridge/onboard.integ.test.js +14 -11
- package/lib/bridge/onboard.integ.test.js.map +1 -1
- package/lib/bridge/onboard.js +110 -42
- package/lib/bridge/onboard.js.map +1 -1
- package/lib/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib/bridge/prepareTransaction.js +5 -7
- package/lib/bridge/prepareTransaction.js.map +1 -1
- package/lib/bridge/serialization.d.ts +4 -0
- package/lib/bridge/serialization.d.ts.map +1 -0
- package/lib/bridge/serialization.js +31 -0
- package/lib/bridge/serialization.js.map +1 -0
- package/lib/bridge/signOperation.d.ts.map +1 -1
- package/lib/bridge/signOperation.js +14 -11
- package/lib/bridge/signOperation.js.map +1 -1
- package/lib/bridge/sync.d.ts +2 -1
- package/lib/bridge/sync.d.ts.map +1 -1
- package/lib/bridge/sync.integ.test.d.ts +2 -0
- package/lib/bridge/sync.integ.test.d.ts.map +1 -0
- package/lib/bridge/sync.integ.test.js +175 -0
- package/lib/bridge/sync.integ.test.js.map +1 -0
- package/lib/bridge/sync.js +50 -27
- package/lib/bridge/sync.js.map +1 -1
- package/lib/bridge/updateTransaction.d.ts.map +1 -1
- package/lib/bridge/updateTransaction.js +0 -4
- package/lib/bridge/updateTransaction.js.map +1 -1
- package/lib/common-logic/account/getBalance.d.ts +2 -1
- package/lib/common-logic/account/getBalance.d.ts.map +1 -1
- package/lib/common-logic/account/getBalance.js +7 -7
- package/lib/common-logic/account/getBalance.js.map +1 -1
- package/lib/common-logic/account/getBalance.unit.test.js +6 -3
- package/lib/common-logic/account/getBalance.unit.test.js.map +1 -1
- package/lib/common-logic/history/lastBlock.d.ts +2 -1
- package/lib/common-logic/history/lastBlock.d.ts.map +1 -1
- package/lib/common-logic/history/lastBlock.js +3 -3
- package/lib/common-logic/history/lastBlock.js.map +1 -1
- package/lib/common-logic/history/lastBlock.test.js +5 -2
- package/lib/common-logic/history/lastBlock.test.js.map +1 -1
- package/lib/common-logic/history/listOperations.d.ts +2 -1
- package/lib/common-logic/history/listOperations.d.ts.map +1 -1
- package/lib/common-logic/history/listOperations.js +2 -2
- package/lib/common-logic/history/listOperations.js.map +1 -1
- package/lib/common-logic/transaction/broadcast.d.ts +2 -1
- package/lib/common-logic/transaction/broadcast.d.ts.map +1 -1
- package/lib/common-logic/transaction/broadcast.js +5 -4
- package/lib/common-logic/transaction/broadcast.js.map +1 -1
- package/lib/common-logic/transaction/broadcast.test.js +8 -5
- package/lib/common-logic/transaction/broadcast.test.js.map +1 -1
- package/lib/common-logic/transaction/combine.d.ts +1 -1
- package/lib/common-logic/transaction/combine.d.ts.map +1 -1
- package/lib/common-logic/transaction/combine.js +2 -3
- package/lib/common-logic/transaction/combine.js.map +1 -1
- package/lib/common-logic/transaction/combine.test.js +3 -13
- package/lib/common-logic/transaction/combine.test.js.map +1 -1
- package/lib/common-logic/transaction/craftTransaction.d.ts +8 -4
- package/lib/common-logic/transaction/craftTransaction.d.ts.map +1 -1
- package/lib/common-logic/transaction/craftTransaction.js +15 -12
- package/lib/common-logic/transaction/craftTransaction.js.map +1 -1
- package/lib/common-logic/transaction/estimateFees.d.ts +2 -1
- package/lib/common-logic/transaction/estimateFees.d.ts.map +1 -1
- package/lib/common-logic/transaction/estimateFees.js +7 -3
- package/lib/common-logic/transaction/estimateFees.js.map +1 -1
- package/lib/config.d.ts +1 -0
- package/lib/config.d.ts.map +1 -1
- package/lib/config.js.map +1 -1
- package/lib/network/gateway.d.ts +41 -17
- package/lib/network/gateway.d.ts.map +1 -1
- package/lib/network/gateway.integ.test.js +19 -15
- package/lib/network/gateway.integ.test.js.map +1 -1
- package/lib/network/gateway.js +74 -48
- package/lib/network/gateway.js.map +1 -1
- package/lib/network/node.d.ts +2 -2
- package/lib/network/node.d.ts.map +1 -1
- package/lib/network/node.js.map +1 -1
- package/lib/network/types.d.ts +1 -1
- package/lib/network/types.d.ts.map +1 -1
- package/lib/signer/getAddress.d.ts.map +1 -1
- package/lib/signer/getAddress.js +2 -2
- package/lib/signer/getAddress.js.map +1 -1
- package/lib/types/bridge.d.ts +18 -3
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib/types/index.d.ts +0 -10
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/onboard.d.ts +2 -0
- package/lib/types/onboard.d.ts.map +1 -1
- package/lib/types/onboard.js.map +1 -1
- package/lib/types/signer.d.ts +2 -1
- package/lib/types/signer.d.ts.map +1 -1
- package/lib-es/api/getBalance.integ.test.js +9 -5
- package/lib-es/api/getBalance.integ.test.js.map +1 -1
- package/lib-es/api/index.d.ts.map +1 -1
- package/lib-es/api/index.js +19 -24
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/lastBlock.integ.test.js +1 -1
- package/lib-es/api/lastBlock.integ.test.js.map +1 -1
- package/lib-es/api/listOperations.integ.test.js +1 -1
- package/lib-es/api/listOperations.integ.test.js.map +1 -1
- package/lib-es/bridge/broadcast.d.ts.map +1 -1
- package/lib-es/bridge/broadcast.js +3 -2
- package/lib-es/bridge/broadcast.js.map +1 -1
- package/lib-es/bridge/broadcast.test.js +9 -0
- package/lib-es/bridge/broadcast.test.js.map +1 -1
- package/lib-es/bridge/createTransaction.js +1 -1
- package/lib-es/bridge/createTransaction.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +1 -1
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/index.d.ts.map +1 -1
- package/lib-es/bridge/index.js +3 -0
- package/lib-es/bridge/index.js.map +1 -1
- package/lib-es/bridge/onboard.d.ts +7 -5
- package/lib-es/bridge/onboard.d.ts.map +1 -1
- package/lib-es/bridge/onboard.integ.test.js +14 -11
- package/lib-es/bridge/onboard.integ.test.js.map +1 -1
- package/lib-es/bridge/onboard.js +107 -42
- package/lib-es/bridge/onboard.js.map +1 -1
- package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
- package/lib-es/bridge/prepareTransaction.js +6 -8
- package/lib-es/bridge/prepareTransaction.js.map +1 -1
- package/lib-es/bridge/serialization.d.ts +4 -0
- package/lib-es/bridge/serialization.d.ts.map +1 -0
- package/lib-es/bridge/serialization.js +27 -0
- package/lib-es/bridge/serialization.js.map +1 -0
- package/lib-es/bridge/signOperation.d.ts.map +1 -1
- package/lib-es/bridge/signOperation.js +15 -12
- package/lib-es/bridge/signOperation.js.map +1 -1
- package/lib-es/bridge/sync.d.ts +2 -1
- package/lib-es/bridge/sync.d.ts.map +1 -1
- package/lib-es/bridge/sync.integ.test.d.ts +2 -0
- package/lib-es/bridge/sync.integ.test.d.ts.map +1 -0
- package/lib-es/bridge/sync.integ.test.js +137 -0
- package/lib-es/bridge/sync.integ.test.js.map +1 -0
- package/lib-es/bridge/sync.js +51 -28
- package/lib-es/bridge/sync.js.map +1 -1
- package/lib-es/bridge/updateTransaction.d.ts.map +1 -1
- package/lib-es/bridge/updateTransaction.js +0 -4
- package/lib-es/bridge/updateTransaction.js.map +1 -1
- package/lib-es/common-logic/account/getBalance.d.ts +2 -1
- package/lib-es/common-logic/account/getBalance.d.ts.map +1 -1
- package/lib-es/common-logic/account/getBalance.js +7 -7
- package/lib-es/common-logic/account/getBalance.js.map +1 -1
- package/lib-es/common-logic/account/getBalance.unit.test.js +6 -3
- package/lib-es/common-logic/account/getBalance.unit.test.js.map +1 -1
- package/lib-es/common-logic/history/lastBlock.d.ts +2 -1
- package/lib-es/common-logic/history/lastBlock.d.ts.map +1 -1
- package/lib-es/common-logic/history/lastBlock.js +3 -3
- package/lib-es/common-logic/history/lastBlock.js.map +1 -1
- package/lib-es/common-logic/history/lastBlock.test.js +5 -2
- package/lib-es/common-logic/history/lastBlock.test.js.map +1 -1
- package/lib-es/common-logic/history/listOperations.d.ts +2 -1
- package/lib-es/common-logic/history/listOperations.d.ts.map +1 -1
- package/lib-es/common-logic/history/listOperations.js +2 -2
- package/lib-es/common-logic/history/listOperations.js.map +1 -1
- package/lib-es/common-logic/transaction/broadcast.d.ts +2 -1
- package/lib-es/common-logic/transaction/broadcast.d.ts.map +1 -1
- package/lib-es/common-logic/transaction/broadcast.js +5 -4
- package/lib-es/common-logic/transaction/broadcast.js.map +1 -1
- package/lib-es/common-logic/transaction/broadcast.test.js +8 -5
- package/lib-es/common-logic/transaction/broadcast.test.js.map +1 -1
- package/lib-es/common-logic/transaction/combine.d.ts +1 -1
- package/lib-es/common-logic/transaction/combine.d.ts.map +1 -1
- package/lib-es/common-logic/transaction/combine.js +2 -3
- package/lib-es/common-logic/transaction/combine.js.map +1 -1
- package/lib-es/common-logic/transaction/combine.test.js +3 -13
- package/lib-es/common-logic/transaction/combine.test.js.map +1 -1
- package/lib-es/common-logic/transaction/craftTransaction.d.ts +8 -4
- package/lib-es/common-logic/transaction/craftTransaction.d.ts.map +1 -1
- package/lib-es/common-logic/transaction/craftTransaction.js +15 -12
- package/lib-es/common-logic/transaction/craftTransaction.js.map +1 -1
- package/lib-es/common-logic/transaction/estimateFees.d.ts +2 -1
- package/lib-es/common-logic/transaction/estimateFees.d.ts.map +1 -1
- package/lib-es/common-logic/transaction/estimateFees.js +4 -3
- package/lib-es/common-logic/transaction/estimateFees.js.map +1 -1
- package/lib-es/config.d.ts +1 -0
- package/lib-es/config.d.ts.map +1 -1
- package/lib-es/config.js.map +1 -1
- package/lib-es/network/gateway.d.ts +41 -17
- package/lib-es/network/gateway.d.ts.map +1 -1
- package/lib-es/network/gateway.integ.test.js +19 -15
- package/lib-es/network/gateway.integ.test.js.map +1 -1
- package/lib-es/network/gateway.js +73 -48
- package/lib-es/network/gateway.js.map +1 -1
- package/lib-es/network/node.d.ts +2 -2
- package/lib-es/network/node.d.ts.map +1 -1
- package/lib-es/network/node.js.map +1 -1
- package/lib-es/network/types.d.ts +1 -1
- package/lib-es/network/types.d.ts.map +1 -1
- package/lib-es/signer/getAddress.d.ts.map +1 -1
- package/lib-es/signer/getAddress.js +2 -2
- package/lib-es/signer/getAddress.js.map +1 -1
- package/lib-es/types/bridge.d.ts +18 -3
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/lib-es/types/index.d.ts +0 -10
- package/lib-es/types/index.d.ts.map +1 -1
- package/lib-es/types/onboard.d.ts +2 -0
- package/lib-es/types/onboard.d.ts.map +1 -1
- package/lib-es/types/onboard.js.map +1 -1
- package/lib-es/types/signer.d.ts +2 -1
- package/lib-es/types/signer.d.ts.map +1 -1
- package/package.json +8 -8
- package/src/api/getBalance.integ.test.ts +9 -6
- package/src/api/index.ts +22 -44
- package/src/api/lastBlock.integ.test.ts +1 -1
- package/src/api/listOperations.integ.test.ts +1 -1
- package/src/bridge/broadcast.test.ts +11 -0
- package/src/bridge/broadcast.ts +4 -2
- package/src/bridge/createTransaction.ts +1 -1
- package/src/bridge/getTransactionStatus.ts +1 -1
- package/src/bridge/index.ts +3 -0
- package/src/bridge/onboard.integ.test.ts +25 -13
- package/src/bridge/onboard.ts +143 -51
- package/src/bridge/prepareTransaction.ts +6 -15
- package/src/bridge/serialization.ts +36 -0
- package/src/bridge/signOperation.ts +26 -20
- package/src/bridge/sync.integ.test.ts +180 -0
- package/src/bridge/sync.ts +61 -33
- package/src/bridge/updateTransaction.ts +0 -5
- package/src/common-logic/account/getBalance.ts +12 -7
- package/src/common-logic/account/getBalance.unit.test.ts +8 -3
- package/src/common-logic/history/lastBlock.test.ts +7 -2
- package/src/common-logic/history/lastBlock.ts +5 -3
- package/src/common-logic/history/listOperations.ts +3 -2
- package/src/common-logic/transaction/broadcast.test.ts +10 -5
- package/src/common-logic/transaction/broadcast.ts +7 -3
- package/src/common-logic/transaction/combine.test.ts +3 -13
- package/src/common-logic/transaction/combine.ts +2 -4
- package/src/common-logic/transaction/craftTransaction.ts +30 -15
- package/src/common-logic/transaction/estimateFees.ts +8 -3
- package/src/config.ts +1 -0
- package/src/network/gateway.integ.test.ts +31 -12
- package/src/network/gateway.ts +141 -62
- package/src/network/node.ts +3 -3
- package/src/network/types.ts +1 -1
- package/src/signer/getAddress.ts +6 -4
- package/src/types/bridge.ts +21 -0
- package/src/types/index.ts +0 -11
- package/src/types/onboard.ts +3 -0
- package/src/types/signer.ts +2 -1
package/src/bridge/onboard.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import { Observable } from "rxjs";
|
|
2
2
|
import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
3
|
-
import {
|
|
3
|
+
import { emptyHistoryCache } from "@ledgerhq/coin-framework/account/index";
|
|
4
|
+
import { getDerivationModesForCurrency } from "@ledgerhq/coin-framework/derivation";
|
|
5
|
+
import { getAccountShape } from "./sync";
|
|
6
|
+
import { CantonAccount, CantonSigner } from "../types";
|
|
7
|
+
import type { Account, DerivationMode } from "@ledgerhq/types-live";
|
|
4
8
|
import {
|
|
5
9
|
prepareOnboarding,
|
|
6
10
|
submitOnboarding,
|
|
@@ -19,8 +23,10 @@ import {
|
|
|
19
23
|
CantonPreApprovalResult,
|
|
20
24
|
PrepareTransactionResponse,
|
|
21
25
|
} from "../types/onboard";
|
|
26
|
+
import resolver from "../signer";
|
|
27
|
+
import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
|
|
22
28
|
|
|
23
|
-
async function
|
|
29
|
+
async function _getKeypair(
|
|
24
30
|
signerContext: SignerContext<CantonSigner>,
|
|
25
31
|
deviceId: string,
|
|
26
32
|
derivationPath: string,
|
|
@@ -32,25 +38,27 @@ async function getKeypair(
|
|
|
32
38
|
}
|
|
33
39
|
|
|
34
40
|
export const isAccountOnboarded = async (
|
|
41
|
+
currency: CryptoCurrency,
|
|
35
42
|
publicKey: string,
|
|
36
|
-
): Promise<
|
|
43
|
+
): Promise<{ isOnboarded: boolean; party_id?: string }> => {
|
|
37
44
|
try {
|
|
38
|
-
const { party_id } = await getPartyByPubKey(publicKey);
|
|
45
|
+
const { party_id } = await getPartyByPubKey(currency, publicKey);
|
|
39
46
|
|
|
40
47
|
if (party_id) {
|
|
41
|
-
return { party_id };
|
|
48
|
+
return { isOnboarded: true, party_id };
|
|
42
49
|
} else {
|
|
43
|
-
return false;
|
|
50
|
+
return { isOnboarded: false };
|
|
44
51
|
}
|
|
45
52
|
} catch (err) {
|
|
46
53
|
log("[isAccountOnboarded] Error checking party status (likely not onboarded):", err);
|
|
47
|
-
return false;
|
|
54
|
+
return { isOnboarded: false };
|
|
48
55
|
}
|
|
49
56
|
};
|
|
50
57
|
|
|
51
58
|
export const buildOnboardAccount =
|
|
52
59
|
(signerContext: SignerContext<CantonSigner>) =>
|
|
53
60
|
(
|
|
61
|
+
currency: CryptoCurrency,
|
|
54
62
|
deviceId: string,
|
|
55
63
|
derivationPath: string,
|
|
56
64
|
): Observable<CantonOnboardProgress | CantonOnboardResult> =>
|
|
@@ -59,22 +67,36 @@ export const buildOnboardAccount =
|
|
|
59
67
|
observer.next({
|
|
60
68
|
status: OnboardStatus.INIT,
|
|
61
69
|
});
|
|
62
|
-
const
|
|
70
|
+
const derivationMode = getDerivationModesForCurrency(currency)[0];
|
|
71
|
+
const getAddress = resolver(signerContext);
|
|
72
|
+
const { address, publicKey } = await getAddress(deviceId, {
|
|
73
|
+
path: derivationPath,
|
|
74
|
+
currency,
|
|
75
|
+
derivationMode: derivationMode || "",
|
|
76
|
+
});
|
|
63
77
|
|
|
64
78
|
observer.next({
|
|
65
79
|
status: OnboardStatus.PREPARE,
|
|
66
80
|
});
|
|
67
81
|
|
|
68
|
-
const
|
|
69
|
-
if (
|
|
82
|
+
const { party_id: partyId } = await isAccountOnboarded(currency, publicKey);
|
|
83
|
+
if (partyId) {
|
|
84
|
+
const account = await createAccount({
|
|
85
|
+
address,
|
|
86
|
+
derivationPath,
|
|
87
|
+
partyId,
|
|
88
|
+
currency,
|
|
89
|
+
derivationMode,
|
|
90
|
+
});
|
|
70
91
|
observer.next({
|
|
71
|
-
partyId
|
|
92
|
+
partyId,
|
|
93
|
+
account,
|
|
72
94
|
});
|
|
73
95
|
observer.complete();
|
|
74
96
|
return;
|
|
75
97
|
}
|
|
76
98
|
|
|
77
|
-
const preparedTransaction = await prepareOnboarding(
|
|
99
|
+
const preparedTransaction = await prepareOnboarding(currency, publicKey, "ed25519");
|
|
78
100
|
|
|
79
101
|
observer.next({
|
|
80
102
|
status: OnboardStatus.SIGN,
|
|
@@ -89,26 +111,44 @@ export const buildOnboardAccount =
|
|
|
89
111
|
});
|
|
90
112
|
|
|
91
113
|
const result = await submitOnboarding(
|
|
92
|
-
|
|
114
|
+
currency,
|
|
115
|
+
{ public_key: publicKey, public_key_type: "ed25519" },
|
|
93
116
|
preparedTransaction,
|
|
94
117
|
signature,
|
|
95
|
-
).catch(err => {
|
|
118
|
+
).catch(async err => {
|
|
96
119
|
if (err.type === "PARTY_ALREADY_EXISTS") {
|
|
120
|
+
const account = await createAccount({
|
|
121
|
+
address,
|
|
122
|
+
derivationPath,
|
|
123
|
+
partyId: preparedTransaction.party_id,
|
|
124
|
+
currency,
|
|
125
|
+
derivationMode,
|
|
126
|
+
});
|
|
97
127
|
observer.next({
|
|
98
128
|
partyId: preparedTransaction.party_id,
|
|
129
|
+
account,
|
|
99
130
|
});
|
|
100
131
|
return observer.complete();
|
|
101
132
|
}
|
|
102
133
|
throw err;
|
|
103
134
|
});
|
|
104
135
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
136
|
+
if (result) {
|
|
137
|
+
observer.next({
|
|
138
|
+
status: OnboardStatus.SUCCESS,
|
|
139
|
+
});
|
|
140
|
+
const account = await createAccount({
|
|
141
|
+
address,
|
|
142
|
+
derivationPath,
|
|
143
|
+
partyId: result.party.party_id,
|
|
144
|
+
currency,
|
|
145
|
+
derivationMode,
|
|
146
|
+
});
|
|
147
|
+
observer.next({
|
|
148
|
+
partyId: result.party.party_id,
|
|
149
|
+
account,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
112
152
|
|
|
113
153
|
observer.complete();
|
|
114
154
|
}
|
|
@@ -125,6 +165,7 @@ export const buildOnboardAccount =
|
|
|
125
165
|
export const buildAuthorizePreapproval =
|
|
126
166
|
(signerContext: SignerContext<CantonSigner>) =>
|
|
127
167
|
(
|
|
168
|
+
currency: CryptoCurrency,
|
|
128
169
|
deviceId: string,
|
|
129
170
|
derivationPath: string,
|
|
130
171
|
partyId: string,
|
|
@@ -135,8 +176,10 @@ export const buildAuthorizePreapproval =
|
|
|
135
176
|
status: PreApprovalStatus.PREPARE,
|
|
136
177
|
});
|
|
137
178
|
|
|
138
|
-
const preparedTransaction: PrepareTransactionResponse =
|
|
139
|
-
|
|
179
|
+
const preparedTransaction: PrepareTransactionResponse = await preparePreApprovalTransaction(
|
|
180
|
+
currency,
|
|
181
|
+
partyId,
|
|
182
|
+
);
|
|
140
183
|
|
|
141
184
|
observer.next({
|
|
142
185
|
status: PreApprovalStatus.SIGN,
|
|
@@ -151,6 +194,7 @@ export const buildAuthorizePreapproval =
|
|
|
151
194
|
});
|
|
152
195
|
|
|
153
196
|
const { isApproved } = await submitPreApprovalTransaction(
|
|
197
|
+
currency,
|
|
154
198
|
partyId,
|
|
155
199
|
preparedTransaction,
|
|
156
200
|
signature,
|
|
@@ -164,38 +208,35 @@ export const buildAuthorizePreapproval =
|
|
|
164
208
|
isApproved,
|
|
165
209
|
});
|
|
166
210
|
|
|
167
|
-
// TODO: remove after demo
|
|
168
211
|
const handleTapRequest = async () => {
|
|
169
212
|
try {
|
|
170
|
-
|
|
171
|
-
status: PreApprovalStatus.PREPARE,
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
const { serialized, hash } = await prepareTapRequest({
|
|
175
|
-
partyId,
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
observer.next({
|
|
179
|
-
status: PreApprovalStatus.SIGN,
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
const signature = await signerContext(deviceId, signer =>
|
|
183
|
-
signer.signTransaction(derivationPath, hash),
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
observer.next({
|
|
187
|
-
status: PreApprovalStatus.SUBMIT,
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
await submitTapRequest({
|
|
213
|
+
const { serialized, hash } = await prepareTapRequest(currency, {
|
|
191
214
|
partyId,
|
|
192
|
-
serialized,
|
|
193
|
-
signature,
|
|
194
215
|
});
|
|
195
216
|
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
217
|
+
if (serialized && hash) {
|
|
218
|
+
observer.next({
|
|
219
|
+
status: PreApprovalStatus.SIGN,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
const signature = await signerContext(deviceId, signer =>
|
|
223
|
+
signer.signTransaction(derivationPath, hash),
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
observer.next({
|
|
227
|
+
status: PreApprovalStatus.SUBMIT,
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
await submitTapRequest(currency, {
|
|
231
|
+
partyId,
|
|
232
|
+
serialized,
|
|
233
|
+
signature,
|
|
234
|
+
});
|
|
235
|
+
|
|
236
|
+
observer.next({
|
|
237
|
+
status: PreApprovalStatus.SUCCESS,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
199
240
|
} catch (err) {
|
|
200
241
|
// Tap request failure should not break the pre-approval flow
|
|
201
242
|
}
|
|
@@ -214,7 +255,58 @@ export const buildAuthorizePreapproval =
|
|
|
214
255
|
);
|
|
215
256
|
});
|
|
216
257
|
|
|
217
|
-
const
|
|
258
|
+
const createAccount = async ({
|
|
259
|
+
address,
|
|
260
|
+
partyId,
|
|
261
|
+
derivationPath,
|
|
262
|
+
currency,
|
|
263
|
+
derivationMode,
|
|
264
|
+
index = 0,
|
|
265
|
+
}: {
|
|
266
|
+
address: string;
|
|
267
|
+
derivationPath: string;
|
|
268
|
+
partyId: string;
|
|
269
|
+
currency: CryptoCurrency;
|
|
270
|
+
derivationMode: DerivationMode;
|
|
271
|
+
index?: number;
|
|
272
|
+
}): Promise<Partial<Account>> => {
|
|
273
|
+
const accountShape = await getAccountShape(
|
|
274
|
+
{
|
|
275
|
+
address,
|
|
276
|
+
currency,
|
|
277
|
+
derivationMode,
|
|
278
|
+
derivationPath,
|
|
279
|
+
index,
|
|
280
|
+
rest: {
|
|
281
|
+
cantonResources: {
|
|
282
|
+
partyId,
|
|
283
|
+
},
|
|
284
|
+
},
|
|
285
|
+
},
|
|
286
|
+
{ paginationConfig: {} },
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
const account: Partial<CantonAccount> = {
|
|
290
|
+
...accountShape,
|
|
291
|
+
type: "Account",
|
|
292
|
+
xpub: partyId.replace(/:/g, "_"),
|
|
293
|
+
index,
|
|
294
|
+
// operations: [],
|
|
295
|
+
currency,
|
|
296
|
+
derivationMode,
|
|
297
|
+
lastSyncDate: new Date(),
|
|
298
|
+
pendingOperations: [],
|
|
299
|
+
seedIdentifier: address,
|
|
300
|
+
balanceHistoryCache: emptyHistoryCache,
|
|
301
|
+
cantonResources: {
|
|
302
|
+
partyId,
|
|
303
|
+
},
|
|
304
|
+
};
|
|
305
|
+
|
|
306
|
+
return account;
|
|
307
|
+
};
|
|
308
|
+
|
|
309
|
+
const log = (message: string, ...rest: unknown[]) => {
|
|
218
310
|
// eslint-disable-next-line no-console
|
|
219
311
|
console.log(message, ...rest);
|
|
220
312
|
};
|
|
@@ -1,25 +1,16 @@
|
|
|
1
1
|
import { AccountBridge } from "@ledgerhq/types-live";
|
|
2
2
|
import { Transaction } from "../types";
|
|
3
|
-
import {
|
|
4
|
-
import { getNextSequence } from "../network/node";
|
|
3
|
+
import { estimateFees } from "../common-logic";
|
|
5
4
|
import BigNumber from "bignumber.js";
|
|
5
|
+
import { updateTransaction } from "./updateTransaction";
|
|
6
6
|
|
|
7
7
|
export const prepareTransaction: AccountBridge<Transaction>["prepareTransaction"] = async (
|
|
8
8
|
account,
|
|
9
9
|
transaction,
|
|
10
10
|
) => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
{ address: account.freshAddress, nextSequenceNumber: seq },
|
|
15
|
-
{ amount: transaction.amount, recipient: transaction.recipient },
|
|
16
|
-
);
|
|
17
|
-
|
|
18
|
-
const fee = await estimateFees(craftedTransaction.serializedTransaction);
|
|
19
|
-
|
|
20
|
-
if (transaction.fee !== new BigNumber(fee.toString())) {
|
|
21
|
-
return { ...transaction, fee: new BigNumber(fee.toString()) };
|
|
11
|
+
let fee = transaction.fee;
|
|
12
|
+
if (!fee || fee.eq(0)) {
|
|
13
|
+
fee = BigNumber((await estimateFees(account.currency)).toString());
|
|
22
14
|
}
|
|
23
|
-
|
|
24
|
-
return transaction;
|
|
15
|
+
return updateTransaction(transaction, { fee });
|
|
25
16
|
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { Account, AccountRaw } from "@ledgerhq/types-live";
|
|
2
|
+
import type {
|
|
3
|
+
CantonAccount,
|
|
4
|
+
CantonAccountRaw,
|
|
5
|
+
CantonResources,
|
|
6
|
+
CantonResourcesRaw,
|
|
7
|
+
} from "../types";
|
|
8
|
+
|
|
9
|
+
function toResourcesRaw(r: CantonResources): CantonResourcesRaw {
|
|
10
|
+
const { partyId } = r;
|
|
11
|
+
return {
|
|
12
|
+
partyId,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
function fromResourcesRaw(r: CantonResourcesRaw): CantonResources {
|
|
16
|
+
const { partyId } = r;
|
|
17
|
+
return {
|
|
18
|
+
partyId,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function assignToAccountRaw(account: Account, accountRaw: AccountRaw): void {
|
|
23
|
+
const cantonAccount = account as CantonAccount;
|
|
24
|
+
const cantonAccountRaw = accountRaw as CantonAccountRaw;
|
|
25
|
+
if (cantonAccount.cantonResources) {
|
|
26
|
+
cantonAccountRaw.cantonResources = toResourcesRaw(cantonAccount.cantonResources);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function assignFromAccountRaw(accountRaw: AccountRaw, account: Account): void {
|
|
31
|
+
const cantonResourcesRaw = (accountRaw as CantonAccountRaw).cantonResources;
|
|
32
|
+
const cantonAccount = account as CantonAccount;
|
|
33
|
+
if (cantonResourcesRaw) {
|
|
34
|
+
cantonAccount.cantonResources = fromResourcesRaw(cantonResourcesRaw);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { Observable } from "rxjs";
|
|
2
|
+
import BigNumber from "bignumber.js";
|
|
2
3
|
import { FeeNotLoaded } from "@ledgerhq/errors";
|
|
3
4
|
import { AccountBridge, Operation } from "@ledgerhq/types-live";
|
|
4
5
|
import { SignerContext } from "@ledgerhq/coin-framework/signer";
|
|
5
6
|
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
6
|
-
import { combine, craftTransaction
|
|
7
|
-
import { Transaction, CantonSigner
|
|
7
|
+
import { combine, craftTransaction } from "../common-logic";
|
|
8
|
+
import { Transaction, CantonSigner } from "../types";
|
|
8
9
|
|
|
9
10
|
export const buildSignOperation =
|
|
10
11
|
(signerContext: SignerContext<CantonSigner>): AccountBridge<Transaction>["signOperation"] =>
|
|
@@ -20,30 +21,36 @@ export const buildSignOperation =
|
|
|
20
21
|
type: "device-signature-requested",
|
|
21
22
|
});
|
|
22
23
|
|
|
23
|
-
const nextSequenceNumber = await getNextValidSequence(account.freshAddress);
|
|
24
|
-
|
|
25
24
|
const signature = await signerContext(deviceId, async signer => {
|
|
26
25
|
const { freshAddressPath: derivationPath } = account;
|
|
27
|
-
const {
|
|
26
|
+
const partyId = (account as unknown as { cantonResources: { partyId: string } })
|
|
27
|
+
.cantonResources.partyId;
|
|
28
|
+
const params: {
|
|
29
|
+
recipient?: string;
|
|
30
|
+
amount: BigNumber;
|
|
31
|
+
tokenId: string;
|
|
32
|
+
expireInSeconds: number;
|
|
33
|
+
memo?: string;
|
|
34
|
+
} = {
|
|
35
|
+
recipient: transaction.recipient,
|
|
36
|
+
amount: transaction.amount,
|
|
37
|
+
expireInSeconds: 60 * 60,
|
|
38
|
+
tokenId: "Amulet",
|
|
39
|
+
};
|
|
40
|
+
if (transaction.memo) {
|
|
41
|
+
params.memo = transaction.memo;
|
|
42
|
+
}
|
|
28
43
|
|
|
29
|
-
const {
|
|
30
|
-
|
|
31
|
-
address: account.freshAddress,
|
|
32
|
-
publicKey,
|
|
33
|
-
},
|
|
44
|
+
const { hash, serializedTransaction } = await craftTransaction(
|
|
45
|
+
account.currency,
|
|
34
46
|
{
|
|
35
|
-
|
|
36
|
-
amount: transaction.amount,
|
|
37
|
-
fee: fee,
|
|
47
|
+
address: partyId,
|
|
38
48
|
},
|
|
49
|
+
params,
|
|
39
50
|
);
|
|
51
|
+
const transactionSignature = await signer.signTransaction(derivationPath, hash);
|
|
40
52
|
|
|
41
|
-
|
|
42
|
-
derivationPath,
|
|
43
|
-
serializedTransaction,
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
return combine(serializedTransaction, transactionSignature);
|
|
53
|
+
return combine(serializedTransaction, `${transactionSignature}__PARTY__${partyId}`);
|
|
47
54
|
});
|
|
48
55
|
|
|
49
56
|
o.next({
|
|
@@ -64,7 +71,6 @@ export const buildSignOperation =
|
|
|
64
71
|
senders: [account.freshAddress],
|
|
65
72
|
recipients: [transaction.recipient],
|
|
66
73
|
date: new Date(),
|
|
67
|
-
transactionSequenceNumber: nextSequenceNumber,
|
|
68
74
|
extra: {},
|
|
69
75
|
};
|
|
70
76
|
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { AccountShapeInfo } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
3
|
+
import {
|
|
4
|
+
getDerivationModesForCurrency,
|
|
5
|
+
getDerivationScheme,
|
|
6
|
+
runDerivationScheme,
|
|
7
|
+
} from "@ledgerhq/coin-framework/derivation";
|
|
8
|
+
import { getCryptoCurrencyById } from "@ledgerhq/cryptoassets/currencies";
|
|
9
|
+
import { Account, Operation } from "@ledgerhq/types-live";
|
|
10
|
+
import coinConfig from "../config";
|
|
11
|
+
import * as gateway from "../network/gateway";
|
|
12
|
+
import { getAccountShape } from "./sync";
|
|
13
|
+
|
|
14
|
+
const TEST_ADDRESS =
|
|
15
|
+
"b6400f93ea1c74aea86be39b0ccc846fc5de01f12b2ad0d7c31848d6fb6eb6d9::1220c81315e2bf2524a9141bcc6cbf19b61c151e0dcaa95343c0ccf53aed7415c4ec";
|
|
16
|
+
const currency = getCryptoCurrencyById("canton_network");
|
|
17
|
+
const derivationMode = getDerivationModesForCurrency(currency)[0];
|
|
18
|
+
const derivationPath = runDerivationScheme(
|
|
19
|
+
getDerivationScheme({ derivationMode, currency }),
|
|
20
|
+
currency,
|
|
21
|
+
{
|
|
22
|
+
account: 0,
|
|
23
|
+
},
|
|
24
|
+
);
|
|
25
|
+
const ACCOUNT_SHAPE_INFO: AccountShapeInfo = {
|
|
26
|
+
address: TEST_ADDRESS,
|
|
27
|
+
currency,
|
|
28
|
+
derivationMode,
|
|
29
|
+
derivationPath,
|
|
30
|
+
index: 0,
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
describe("sync (devnet)", () => {
|
|
34
|
+
beforeAll(async () => {
|
|
35
|
+
coinConfig.setCoinConfig(() => ({
|
|
36
|
+
gatewayUrl: "https://canton-gateway.api.live.ledger-test.com",
|
|
37
|
+
useGateway: true,
|
|
38
|
+
networkType: "devnet",
|
|
39
|
+
status: {
|
|
40
|
+
type: "active",
|
|
41
|
+
},
|
|
42
|
+
}));
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
describe("getAccountShape", () => {
|
|
46
|
+
it("should fetch account shape for a valid address", async () => {
|
|
47
|
+
const result = await getAccountShape(ACCOUNT_SHAPE_INFO, { paginationConfig: {} });
|
|
48
|
+
|
|
49
|
+
expect(result).toBeDefined();
|
|
50
|
+
expect(result.id).toBeDefined();
|
|
51
|
+
expect(result.xpub).toBe(TEST_ADDRESS.replace(/:/g, "_"));
|
|
52
|
+
expect(result.blockHeight).toBeGreaterThan(0);
|
|
53
|
+
expect(result.balance).toBeDefined();
|
|
54
|
+
expect(result.spendableBalance).toBeDefined();
|
|
55
|
+
expect(result.operations).toBeDefined();
|
|
56
|
+
expect(result.operationsCount).toBeGreaterThanOrEqual(0);
|
|
57
|
+
|
|
58
|
+
expect(result.balance).toBeInstanceOf(Object);
|
|
59
|
+
expect(result.balance?.toNumber).toBeDefined();
|
|
60
|
+
expect(result.spendableBalance).toBeInstanceOf(Object);
|
|
61
|
+
expect(result.spendableBalance?.toNumber).toBeDefined();
|
|
62
|
+
|
|
63
|
+
expect(result.spendableBalance?.toNumber()).toBeLessThanOrEqual(
|
|
64
|
+
result.balance?.toNumber() || 0,
|
|
65
|
+
);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
it("should handle address with colons correctly", async () => {
|
|
69
|
+
const result = await getAccountShape(ACCOUNT_SHAPE_INFO, { paginationConfig: {} });
|
|
70
|
+
|
|
71
|
+
expect(result.xpub).toBe(TEST_ADDRESS.replace(/:/g, "_"));
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
it("should merge operations correctly with initial account", async () => {
|
|
75
|
+
const operations: Operation[] = [
|
|
76
|
+
{
|
|
77
|
+
id: "test-op-1",
|
|
78
|
+
hash: "test-hash-1",
|
|
79
|
+
accountId: "test-account",
|
|
80
|
+
type: "OUT" as const,
|
|
81
|
+
value: new BigNumber(1000000),
|
|
82
|
+
fee: new BigNumber(100000),
|
|
83
|
+
blockHash: "block-hash-1",
|
|
84
|
+
blockHeight: 100,
|
|
85
|
+
senders: [TEST_ADDRESS],
|
|
86
|
+
recipients: ["recipient-1"],
|
|
87
|
+
date: new Date("2023-01-01"),
|
|
88
|
+
transactionSequenceNumber: 100,
|
|
89
|
+
extra: { uid: "uid-1" },
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
|
|
93
|
+
const result = await getAccountShape(
|
|
94
|
+
{
|
|
95
|
+
...ACCOUNT_SHAPE_INFO,
|
|
96
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
97
|
+
initialAccount: { operations } as Account,
|
|
98
|
+
},
|
|
99
|
+
{ paginationConfig: {} },
|
|
100
|
+
);
|
|
101
|
+
|
|
102
|
+
expect(result.operations).toBeDefined();
|
|
103
|
+
expect(result.operationsCount).toBeGreaterThanOrEqual(1);
|
|
104
|
+
const initialOp = result.operations?.find(op => op.id === "test-op-1");
|
|
105
|
+
expect(initialOp).toBeDefined();
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
it("should take locked balance into account when calculating spendable balance", async () => {
|
|
109
|
+
const mockGetBalance = jest.spyOn(gateway, "getBalance");
|
|
110
|
+
|
|
111
|
+
mockGetBalance.mockResolvedValue([
|
|
112
|
+
{
|
|
113
|
+
instrument_id: "Amulet",
|
|
114
|
+
amount: 1000000,
|
|
115
|
+
locked: true,
|
|
116
|
+
},
|
|
117
|
+
]);
|
|
118
|
+
|
|
119
|
+
const result = await getAccountShape(ACCOUNT_SHAPE_INFO, { paginationConfig: {} });
|
|
120
|
+
|
|
121
|
+
expect(result.balance?.toNumber()).toBe(1000000);
|
|
122
|
+
expect(result.spendableBalance?.toNumber()).toBe(0);
|
|
123
|
+
|
|
124
|
+
mockGetBalance.mockRestore();
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it("should call getOperations with correct cursor based with initial account", async () => {
|
|
128
|
+
const mockGetOperations = jest.spyOn(gateway, "getOperations");
|
|
129
|
+
const operation: Operation = {
|
|
130
|
+
id: "test-op-1",
|
|
131
|
+
hash: "test-hash-1",
|
|
132
|
+
accountId: "test-account",
|
|
133
|
+
type: "OUT" as const,
|
|
134
|
+
value: new BigNumber(1000000),
|
|
135
|
+
fee: new BigNumber(100000),
|
|
136
|
+
blockHash: "block-hash-1",
|
|
137
|
+
blockHeight: 100,
|
|
138
|
+
senders: [TEST_ADDRESS],
|
|
139
|
+
recipients: ["recipient-1"],
|
|
140
|
+
date: new Date("2023-01-01"),
|
|
141
|
+
transactionSequenceNumber: 100,
|
|
142
|
+
extra: { uid: "uid-1" },
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
146
|
+
const initialAccount = { operations: [operation] } as Account;
|
|
147
|
+
|
|
148
|
+
const result = await getAccountShape(
|
|
149
|
+
{
|
|
150
|
+
...ACCOUNT_SHAPE_INFO,
|
|
151
|
+
initialAccount,
|
|
152
|
+
},
|
|
153
|
+
{ paginationConfig: {} },
|
|
154
|
+
);
|
|
155
|
+
|
|
156
|
+
expect(mockGetOperations).toHaveBeenCalledWith(TEST_ADDRESS, {
|
|
157
|
+
cursor: (operation.blockHeight || 0) + 1,
|
|
158
|
+
limit: 100,
|
|
159
|
+
});
|
|
160
|
+
expect(result.operations).toBeDefined();
|
|
161
|
+
expect(result.operationsCount).toBeGreaterThan(1);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
it("should call getOperations with cursor 0 when no initial account", async () => {
|
|
165
|
+
const mockGetOperations = jest.spyOn(gateway, "getOperations");
|
|
166
|
+
|
|
167
|
+
const result = await getAccountShape(ACCOUNT_SHAPE_INFO, { paginationConfig: {} });
|
|
168
|
+
|
|
169
|
+
expect(result.operations).toBeDefined();
|
|
170
|
+
expect(result.operationsCount).toBeGreaterThanOrEqual(1);
|
|
171
|
+
|
|
172
|
+
expect(mockGetOperations).toHaveBeenCalledWith(TEST_ADDRESS, {
|
|
173
|
+
cursor: 0,
|
|
174
|
+
limit: 100,
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
mockGetOperations.mockRestore();
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
});
|