@ledgerhq/coin-canton 0.8.0-nightly.1 → 0.8.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/bridge/onboard.d.ts +2 -2
- package/lib/bridge/onboard.d.ts.map +1 -1
- package/lib/bridge/onboard.js +7 -4
- package/lib/bridge/onboard.js.map +1 -1
- package/lib/bridge/onboard.test.d.ts +2 -0
- package/lib/bridge/onboard.test.d.ts.map +1 -0
- package/lib/bridge/onboard.test.js +84 -0
- package/lib/bridge/onboard.test.js.map +1 -0
- package/lib/bridge/sync.d.ts.map +1 -1
- package/lib/bridge/sync.js +6 -2
- package/lib/bridge/sync.js.map +1 -1
- package/lib/bridge/sync.test.d.ts +2 -0
- package/lib/bridge/sync.test.d.ts.map +1 -0
- package/lib/bridge/sync.test.js +201 -0
- package/lib/bridge/sync.test.js.map +1 -0
- package/lib/network/gateway.d.ts +9 -0
- package/lib/network/gateway.d.ts.map +1 -1
- package/lib/network/gateway.js +8 -0
- package/lib/network/gateway.js.map +1 -1
- package/lib-es/bridge/onboard.d.ts +2 -2
- package/lib-es/bridge/onboard.d.ts.map +1 -1
- package/lib-es/bridge/onboard.js +8 -5
- package/lib-es/bridge/onboard.js.map +1 -1
- package/lib-es/bridge/onboard.test.d.ts +2 -0
- package/lib-es/bridge/onboard.test.d.ts.map +1 -0
- package/lib-es/bridge/onboard.test.js +49 -0
- package/lib-es/bridge/onboard.test.js.map +1 -0
- package/lib-es/bridge/sync.d.ts.map +1 -1
- package/lib-es/bridge/sync.js +6 -2
- package/lib-es/bridge/sync.js.map +1 -1
- package/lib-es/bridge/sync.test.d.ts +2 -0
- package/lib-es/bridge/sync.test.d.ts.map +1 -0
- package/lib-es/bridge/sync.test.js +163 -0
- package/lib-es/bridge/sync.test.js.map +1 -0
- package/lib-es/network/gateway.d.ts +9 -0
- package/lib-es/network/gateway.d.ts.map +1 -1
- package/lib-es/network/gateway.js +7 -0
- package/lib-es/network/gateway.js.map +1 -1
- package/package.json +4 -4
- package/src/bridge/onboard.test.ts +59 -0
- package/src/bridge/onboard.ts +10 -5
- package/src/bridge/sync.test.ts +185 -0
- package/src/bridge/sync.ts +8 -2
- package/src/network/gateway.ts +17 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { makeGetAccountShape } from "./sync";
|
|
2
|
+
import { OperationInfo } from "../network/gateway";
|
|
3
|
+
import * as gateway from "../network/gateway";
|
|
4
|
+
import * as onboard from "./onboard";
|
|
5
|
+
import * as config from "../config";
|
|
6
|
+
import resolver from "../signer";
|
|
7
|
+
import { AccountShapeInfo } from "@ledgerhq/coin-framework/bridge/jsHelpers";
|
|
8
|
+
import { Account } from "@ledgerhq/types-live";
|
|
9
|
+
import BigNumber from "bignumber.js";
|
|
10
|
+
|
|
11
|
+
jest.mock("../network/gateway");
|
|
12
|
+
jest.mock("../signer");
|
|
13
|
+
jest.mock("../config");
|
|
14
|
+
jest.mock("./onboard");
|
|
15
|
+
|
|
16
|
+
const mockedGetBalance = gateway.getBalance as jest.Mock;
|
|
17
|
+
const mockedGetLedgerEnd = gateway.getLedgerEnd as jest.Mock;
|
|
18
|
+
const mockedGetOperations = gateway.getOperations as jest.Mock;
|
|
19
|
+
const mockedResolver = resolver as jest.Mock;
|
|
20
|
+
const mockedIsOnboarded = onboard.isAccountOnboarded as jest.Mock;
|
|
21
|
+
const mockedIsAuthorized = onboard.isAccountAuthorized as jest.Mock;
|
|
22
|
+
const mockedCoinConfig = config.default.getCoinConfig as jest.Mock;
|
|
23
|
+
|
|
24
|
+
const sampleCurrency = {
|
|
25
|
+
id: "testcoin",
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
describe("makeGetAccountShape", () => {
|
|
29
|
+
const fakeSignerContext = {} as any;
|
|
30
|
+
|
|
31
|
+
const defaultInfo = {
|
|
32
|
+
address: "addr1",
|
|
33
|
+
currency: sampleCurrency,
|
|
34
|
+
derivationMode: "",
|
|
35
|
+
derivationPath: "44'/0'/0'/0/0",
|
|
36
|
+
deviceId: "fakeDevice",
|
|
37
|
+
initialAccount: undefined,
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
jest.clearAllMocks();
|
|
42
|
+
|
|
43
|
+
mockedResolver.mockReturnValue(async () => ({
|
|
44
|
+
publicKey: "FAKE_PUBLIC_KEY",
|
|
45
|
+
}));
|
|
46
|
+
|
|
47
|
+
mockedIsOnboarded.mockResolvedValue({
|
|
48
|
+
isOnboarded: true,
|
|
49
|
+
partyId: "party123",
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
mockedCoinConfig.mockReturnValue({
|
|
53
|
+
nativeInstrumentId: "Native",
|
|
54
|
+
minReserve: "0",
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
mockedIsAuthorized.mockResolvedValue(true);
|
|
58
|
+
mockedGetLedgerEnd.mockResolvedValue(12345);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
it("should return a valid account shape with correct balances and operations", async () => {
|
|
62
|
+
mockedGetBalance.mockResolvedValue([
|
|
63
|
+
{
|
|
64
|
+
instrument_id: "Native",
|
|
65
|
+
amount: "1000",
|
|
66
|
+
locked: false,
|
|
67
|
+
},
|
|
68
|
+
]);
|
|
69
|
+
mockedGetOperations.mockResolvedValue({
|
|
70
|
+
operations: [
|
|
71
|
+
{
|
|
72
|
+
transaction_hash: "tx1",
|
|
73
|
+
uid: "uid1",
|
|
74
|
+
type: "Send",
|
|
75
|
+
fee: { value: "5" },
|
|
76
|
+
transfers: [
|
|
77
|
+
{
|
|
78
|
+
value: "100",
|
|
79
|
+
details: {
|
|
80
|
+
metadata: {
|
|
81
|
+
reason: "test transfer",
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
transaction_timestamp: new Date().toISOString(),
|
|
87
|
+
senders: ["party123"],
|
|
88
|
+
recipients: ["party456"],
|
|
89
|
+
block: {
|
|
90
|
+
height: 1,
|
|
91
|
+
hash: "blockhash1",
|
|
92
|
+
},
|
|
93
|
+
} as OperationInfo,
|
|
94
|
+
],
|
|
95
|
+
});
|
|
96
|
+
const getAccountShape = makeGetAccountShape(fakeSignerContext);
|
|
97
|
+
const shape = await getAccountShape(defaultInfo as AccountShapeInfo<Account>, {
|
|
98
|
+
paginationConfig: {},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(shape).toHaveProperty("id");
|
|
102
|
+
expect(shape.balance).toEqual(BigNumber(1000));
|
|
103
|
+
expect(shape.operations?.length).toBe(1);
|
|
104
|
+
expect((shape.operations as any)[0].type).toBe("OUT");
|
|
105
|
+
expect((shape.operations as any)[0].value).toEqual(BigNumber(105)); // 100 + 5 fee
|
|
106
|
+
expect(shape.spendableBalance).toEqual(BigNumber(1000));
|
|
107
|
+
expect(shape.used).toBe(true);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it("should handle locked balances correctly", async () => {
|
|
111
|
+
mockedGetBalance.mockResolvedValue([
|
|
112
|
+
{
|
|
113
|
+
instrument_id: "LockedNative",
|
|
114
|
+
amount: "1000",
|
|
115
|
+
locked: true,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
instrument_id: "Native",
|
|
119
|
+
amount: "10",
|
|
120
|
+
locked: false,
|
|
121
|
+
},
|
|
122
|
+
]);
|
|
123
|
+
|
|
124
|
+
const getAccountShape = makeGetAccountShape(fakeSignerContext);
|
|
125
|
+
const shape = await getAccountShape(defaultInfo as AccountShapeInfo<Account>, {
|
|
126
|
+
paginationConfig: {},
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
expect(shape).toBeDefined();
|
|
130
|
+
expect(shape.balance).toEqual(BigNumber(1010));
|
|
131
|
+
expect(shape.spendableBalance).toEqual(BigNumber(10));
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("should handle empty balances correctly", async () => {
|
|
135
|
+
mockedGetBalance.mockResolvedValue([]);
|
|
136
|
+
|
|
137
|
+
const getAccountShape = makeGetAccountShape(fakeSignerContext);
|
|
138
|
+
const shape = await getAccountShape(defaultInfo as AccountShapeInfo<Account>, {
|
|
139
|
+
paginationConfig: {},
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
expect(shape).toBeDefined();
|
|
143
|
+
expect(shape.balance).toEqual(BigNumber(0));
|
|
144
|
+
expect(shape.spendableBalance).toEqual(BigNumber(0));
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
it("should default to FEES operation type when transferValue is 0", async () => {
|
|
148
|
+
mockedGetOperations.mockResolvedValue({
|
|
149
|
+
operations: [
|
|
150
|
+
{
|
|
151
|
+
transaction_hash: "tx2",
|
|
152
|
+
uid: "uid2",
|
|
153
|
+
type: "Send",
|
|
154
|
+
fee: { value: "3" },
|
|
155
|
+
transfers: [
|
|
156
|
+
{
|
|
157
|
+
value: "0",
|
|
158
|
+
details: {
|
|
159
|
+
metadata: {
|
|
160
|
+
reason: "fee only",
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
transaction_timestamp: new Date().toISOString(),
|
|
166
|
+
senders: ["party123"],
|
|
167
|
+
recipients: ["party456"],
|
|
168
|
+
block: {
|
|
169
|
+
height: 2,
|
|
170
|
+
hash: "blockhash2",
|
|
171
|
+
},
|
|
172
|
+
} as OperationInfo,
|
|
173
|
+
],
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const getAccountShape = makeGetAccountShape(fakeSignerContext);
|
|
177
|
+
const shape: any = await getAccountShape(defaultInfo as AccountShapeInfo<Account>, {
|
|
178
|
+
paginationConfig: {},
|
|
179
|
+
});
|
|
180
|
+
expect(shape).toBeDefined();
|
|
181
|
+
expect(shape.operations[0].type).toBe("FEES");
|
|
182
|
+
// In this case, value should equal the fee
|
|
183
|
+
expect(shape.operations[0].value).toEqual(BigNumber(3));
|
|
184
|
+
});
|
|
185
|
+
});
|
package/src/bridge/sync.ts
CHANGED
|
@@ -33,7 +33,13 @@ const txInfoToOperationAdapter =
|
|
|
33
33
|
} else if (txInfo.type === "Initialize") {
|
|
34
34
|
type = "PRE_APPROVAL";
|
|
35
35
|
}
|
|
36
|
-
|
|
36
|
+
let value = new BigNumber(transferValue);
|
|
37
|
+
|
|
38
|
+
if (type === "OUT" || type === "FEES") {
|
|
39
|
+
// We add fees when it's an outgoing transaction or a fees-only transaction
|
|
40
|
+
value = value.plus(fee);
|
|
41
|
+
}
|
|
42
|
+
|
|
37
43
|
const feeValue = new BigNumber(fee);
|
|
38
44
|
const memo = details.metadata.reason;
|
|
39
45
|
|
|
@@ -127,7 +133,7 @@ export function makeGetAccountShape(
|
|
|
127
133
|
operations = mergeOps(oldOperations, newOperations);
|
|
128
134
|
}
|
|
129
135
|
|
|
130
|
-
const isAuthorized = await isAccountAuthorized(
|
|
136
|
+
const isAuthorized = await isAccountAuthorized(currency, xpubOrAddress);
|
|
131
137
|
const used = isAuthorized && totalBalance.gt(0);
|
|
132
138
|
|
|
133
139
|
const blockHeight = await getLedgerEnd(currency);
|
package/src/network/gateway.ts
CHANGED
|
@@ -549,3 +549,20 @@ export async function submitPreApprovalTransaction(
|
|
|
549
549
|
updateId: data.update_id,
|
|
550
550
|
} satisfies PreApprovalResult;
|
|
551
551
|
}
|
|
552
|
+
|
|
553
|
+
type GetTransferPreApprovalResponse = {
|
|
554
|
+
contract_id: string;
|
|
555
|
+
receiver: string;
|
|
556
|
+
provider: string;
|
|
557
|
+
valid_from: string; // ISO 8601 date string
|
|
558
|
+
last_renewed_at: string; // ISO 8601 date
|
|
559
|
+
expires_at: string; // ISO 8601 date string
|
|
560
|
+
};
|
|
561
|
+
|
|
562
|
+
export async function getTransferPreApproval(currency: CryptoCurrency, partyId: string) {
|
|
563
|
+
const { data } = await gatewayNetwork<GetTransferPreApprovalResponse>({
|
|
564
|
+
method: "GET",
|
|
565
|
+
url: `${getGatewayUrl(currency)}/v1/node/${getNodeId(currency)}/party/${partyId}/transfer-preapproval`,
|
|
566
|
+
});
|
|
567
|
+
return data;
|
|
568
|
+
}
|