@ledgerhq/coin-canton 0.10.0 → 0.11.0-nightly.20251126023856
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 +17 -0
- package/lib/bridge/acceptOffer.d.ts +8 -0
- package/lib/bridge/acceptOffer.d.ts.map +1 -0
- package/lib/bridge/acceptOffer.js +18 -0
- package/lib/bridge/acceptOffer.js.map +1 -0
- 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/serialization.d.ts +2 -0
- package/lib/bridge/serialization.d.ts.map +1 -1
- package/lib/bridge/serialization.js +4 -1
- package/lib/bridge/serialization.js.map +1 -1
- package/lib/bridge/sync.d.ts.map +1 -1
- package/lib/bridge/sync.js +14 -4
- package/lib/bridge/sync.js.map +1 -1
- package/lib/helpers.d.ts +10 -0
- package/lib/helpers.d.ts.map +1 -0
- package/lib/helpers.js +26 -0
- package/lib/helpers.js.map +1 -0
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +5 -1
- package/lib/index.js.map +1 -1
- package/lib/network/gateway.d.ts +18 -0
- package/lib/network/gateway.d.ts.map +1 -1
- package/lib/network/gateway.js +26 -6
- package/lib/network/gateway.js.map +1 -1
- package/lib/types/bridge.d.ts +4 -0
- package/lib/types/bridge.d.ts.map +1 -1
- package/lib-es/bridge/acceptOffer.d.ts +8 -0
- package/lib-es/bridge/acceptOffer.d.ts.map +1 -0
- package/lib-es/bridge/acceptOffer.js +14 -0
- package/lib-es/bridge/acceptOffer.js.map +1 -0
- 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/serialization.d.ts +2 -0
- package/lib-es/bridge/serialization.d.ts.map +1 -1
- package/lib-es/bridge/serialization.js +4 -2
- package/lib-es/bridge/serialization.js.map +1 -1
- package/lib-es/bridge/sync.d.ts.map +1 -1
- package/lib-es/bridge/sync.js +16 -6
- package/lib-es/bridge/sync.js.map +1 -1
- package/lib-es/helpers.d.ts +10 -0
- package/lib-es/helpers.d.ts.map +1 -0
- package/lib-es/helpers.js +22 -0
- package/lib-es/helpers.js.map +1 -0
- package/lib-es/index.d.ts +2 -0
- package/lib-es/index.d.ts.map +1 -1
- package/lib-es/index.js +2 -0
- package/lib-es/index.js.map +1 -1
- package/lib-es/network/gateway.d.ts +18 -0
- package/lib-es/network/gateway.d.ts.map +1 -1
- package/lib-es/network/gateway.js +22 -6
- package/lib-es/network/gateway.js.map +1 -1
- package/lib-es/types/bridge.d.ts +4 -0
- package/lib-es/types/bridge.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/bridge/acceptOffer.test.ts +300 -0
- package/src/bridge/acceptOffer.ts +36 -0
- package/src/bridge/getTransactionStatus.test.ts +1 -0
- package/src/bridge/index.ts +3 -0
- package/src/bridge/serialization.ts +4 -2
- package/src/bridge/sync.ts +21 -6
- package/src/helpers.test.ts +361 -0
- package/src/helpers.ts +31 -0
- package/src/index.ts +2 -0
- package/src/network/gateway.ts +60 -6
- package/src/types/bridge.ts +15 -0
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { TokenAccount } from "@ledgerhq/types-live";
|
|
3
|
+
import { isAccountEmpty } from "./helpers";
|
|
4
|
+
import { CantonAccount } from "./types";
|
|
5
|
+
import { createMockAccount } from "./test/fixtures";
|
|
6
|
+
|
|
7
|
+
describe("isAccountEmpty", () => {
|
|
8
|
+
const createCantonAccount = (overrides: Partial<CantonAccount> = {}): CantonAccount => {
|
|
9
|
+
const baseAccount = createMockAccount(overrides);
|
|
10
|
+
return {
|
|
11
|
+
...baseAccount,
|
|
12
|
+
cantonResources: {
|
|
13
|
+
instrumentUtxoCounts: {},
|
|
14
|
+
pendingTransferProposals: [],
|
|
15
|
+
...overrides.cantonResources,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
describe("when account is not of type Account", () => {
|
|
21
|
+
it("should return false for TokenAccount", () => {
|
|
22
|
+
const tokenAccount: TokenAccount = {
|
|
23
|
+
type: "TokenAccount",
|
|
24
|
+
id: "token-account-id",
|
|
25
|
+
parentId: "parent-account-id",
|
|
26
|
+
token: {
|
|
27
|
+
type: "TokenCurrency",
|
|
28
|
+
id: "token-id",
|
|
29
|
+
contractAddress: "0x123",
|
|
30
|
+
name: "Test Token",
|
|
31
|
+
ticker: "TEST",
|
|
32
|
+
decimals: 18,
|
|
33
|
+
parentCurrency: {
|
|
34
|
+
id: "ethereum",
|
|
35
|
+
type: "CryptoCurrency",
|
|
36
|
+
name: "Ethereum",
|
|
37
|
+
ticker: "ETH",
|
|
38
|
+
family: "evm",
|
|
39
|
+
units: [],
|
|
40
|
+
explorerViews: [],
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
balance: new BigNumber(0),
|
|
44
|
+
spendableBalance: new BigNumber(0),
|
|
45
|
+
operationsCount: 0,
|
|
46
|
+
operations: [],
|
|
47
|
+
pendingOperations: [],
|
|
48
|
+
balanceHistoryCache: {
|
|
49
|
+
HOUR: { latestDate: null, balances: [] },
|
|
50
|
+
DAY: { latestDate: null, balances: [] },
|
|
51
|
+
WEEK: { latestDate: null, balances: [] },
|
|
52
|
+
},
|
|
53
|
+
swapHistory: [],
|
|
54
|
+
creationDate: new Date(),
|
|
55
|
+
balanceHistory: [],
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
expect(isAccountEmpty(tokenAccount)).toBe(false);
|
|
59
|
+
});
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe("when account is not a Canton account", () => {
|
|
63
|
+
it("should return false for non-Canton account", () => {
|
|
64
|
+
const nonCantonAccount = createMockAccount({
|
|
65
|
+
currency: {
|
|
66
|
+
...createMockAccount().currency,
|
|
67
|
+
family: "ethereum",
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
expect(isAccountEmpty(nonCantonAccount)).toBe(false);
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe("when account is a Canton account", () => {
|
|
76
|
+
it("should return true for empty account (zero operations, zero balance, no subAccounts, no pending proposals)", () => {
|
|
77
|
+
const emptyAccount = createCantonAccount({
|
|
78
|
+
operationsCount: 0,
|
|
79
|
+
balance: new BigNumber(0),
|
|
80
|
+
subAccounts: [],
|
|
81
|
+
cantonResources: {
|
|
82
|
+
instrumentUtxoCounts: {},
|
|
83
|
+
pendingTransferProposals: [],
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
expect(isAccountEmpty(emptyAccount)).toBe(true);
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
it("should return false when account has operations", () => {
|
|
91
|
+
const accountWithOperations = createCantonAccount({
|
|
92
|
+
operationsCount: 1,
|
|
93
|
+
balance: new BigNumber(0),
|
|
94
|
+
subAccounts: [],
|
|
95
|
+
cantonResources: {
|
|
96
|
+
instrumentUtxoCounts: {},
|
|
97
|
+
pendingTransferProposals: [],
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
expect(isAccountEmpty(accountWithOperations)).toBe(false);
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
it("should return false when account has non-zero balance", () => {
|
|
105
|
+
const accountWithBalance = createCantonAccount({
|
|
106
|
+
operationsCount: 0,
|
|
107
|
+
balance: new BigNumber(100),
|
|
108
|
+
subAccounts: [],
|
|
109
|
+
cantonResources: {
|
|
110
|
+
instrumentUtxoCounts: {},
|
|
111
|
+
pendingTransferProposals: [],
|
|
112
|
+
},
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
expect(isAccountEmpty(accountWithBalance)).toBe(false);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("should return false when account has subAccounts", () => {
|
|
119
|
+
const accountWithSubAccounts = createCantonAccount({
|
|
120
|
+
operationsCount: 0,
|
|
121
|
+
balance: new BigNumber(0),
|
|
122
|
+
subAccounts: [
|
|
123
|
+
{
|
|
124
|
+
type: "TokenAccount",
|
|
125
|
+
id: "token-account-id",
|
|
126
|
+
parentId: "parent-id",
|
|
127
|
+
token: {
|
|
128
|
+
type: "TokenCurrency",
|
|
129
|
+
id: "token-id",
|
|
130
|
+
contractAddress: "0x123",
|
|
131
|
+
name: "Test Token",
|
|
132
|
+
ticker: "TEST",
|
|
133
|
+
decimals: 18,
|
|
134
|
+
parentCurrency: createMockAccount().currency,
|
|
135
|
+
},
|
|
136
|
+
balance: new BigNumber(0),
|
|
137
|
+
spendableBalance: new BigNumber(0),
|
|
138
|
+
operationsCount: 0,
|
|
139
|
+
operations: [],
|
|
140
|
+
pendingOperations: [],
|
|
141
|
+
balanceHistoryCache: {
|
|
142
|
+
HOUR: { latestDate: null, balances: [] },
|
|
143
|
+
DAY: { latestDate: null, balances: [] },
|
|
144
|
+
WEEK: { latestDate: null, balances: [] },
|
|
145
|
+
},
|
|
146
|
+
swapHistory: [],
|
|
147
|
+
creationDate: new Date(),
|
|
148
|
+
balanceHistory: [],
|
|
149
|
+
},
|
|
150
|
+
],
|
|
151
|
+
cantonResources: {
|
|
152
|
+
instrumentUtxoCounts: {},
|
|
153
|
+
pendingTransferProposals: [],
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
expect(isAccountEmpty(accountWithSubAccounts)).toBe(false);
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("should return false when account has pending transfer proposals", () => {
|
|
161
|
+
const accountWithPendingProposals = createCantonAccount({
|
|
162
|
+
operationsCount: 0,
|
|
163
|
+
balance: new BigNumber(0),
|
|
164
|
+
subAccounts: [],
|
|
165
|
+
cantonResources: {
|
|
166
|
+
instrumentUtxoCounts: {},
|
|
167
|
+
pendingTransferProposals: [
|
|
168
|
+
{
|
|
169
|
+
contract_id: "contract-123",
|
|
170
|
+
sender: "sender-address",
|
|
171
|
+
receiver: "receiver-address",
|
|
172
|
+
instrument_id: "instrument-123",
|
|
173
|
+
amount: "100",
|
|
174
|
+
memo: "test memo",
|
|
175
|
+
expires_at_micros: Date.now() * 1000 + 86400000000,
|
|
176
|
+
},
|
|
177
|
+
],
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
expect(isAccountEmpty(accountWithPendingProposals)).toBe(false);
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
it("should return false when account has operations and balance", () => {
|
|
185
|
+
const accountWithBoth = createCantonAccount({
|
|
186
|
+
operationsCount: 5,
|
|
187
|
+
balance: new BigNumber(1000),
|
|
188
|
+
subAccounts: [],
|
|
189
|
+
cantonResources: {
|
|
190
|
+
instrumentUtxoCounts: {},
|
|
191
|
+
pendingTransferProposals: [],
|
|
192
|
+
},
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
expect(isAccountEmpty(accountWithBoth)).toBe(false);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("should return false when account has operations and subAccounts", () => {
|
|
199
|
+
const accountWithOperationsAndSubAccounts = createCantonAccount({
|
|
200
|
+
operationsCount: 2,
|
|
201
|
+
balance: new BigNumber(0),
|
|
202
|
+
subAccounts: [
|
|
203
|
+
{
|
|
204
|
+
type: "TokenAccount",
|
|
205
|
+
id: "token-account-id",
|
|
206
|
+
parentId: "parent-id",
|
|
207
|
+
token: {
|
|
208
|
+
type: "TokenCurrency",
|
|
209
|
+
id: "token-id",
|
|
210
|
+
contractAddress: "0x123",
|
|
211
|
+
name: "Test Token",
|
|
212
|
+
ticker: "TEST",
|
|
213
|
+
decimals: 18,
|
|
214
|
+
parentCurrency: createMockAccount().currency,
|
|
215
|
+
},
|
|
216
|
+
balance: new BigNumber(0),
|
|
217
|
+
spendableBalance: new BigNumber(0),
|
|
218
|
+
operationsCount: 0,
|
|
219
|
+
operations: [],
|
|
220
|
+
pendingOperations: [],
|
|
221
|
+
balanceHistoryCache: {
|
|
222
|
+
HOUR: { latestDate: null, balances: [] },
|
|
223
|
+
DAY: { latestDate: null, balances: [] },
|
|
224
|
+
WEEK: { latestDate: null, balances: [] },
|
|
225
|
+
},
|
|
226
|
+
swapHistory: [],
|
|
227
|
+
creationDate: new Date(),
|
|
228
|
+
balanceHistory: [],
|
|
229
|
+
},
|
|
230
|
+
],
|
|
231
|
+
cantonResources: {
|
|
232
|
+
instrumentUtxoCounts: {},
|
|
233
|
+
pendingTransferProposals: [],
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
expect(isAccountEmpty(accountWithOperationsAndSubAccounts)).toBe(false);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
it("should return false when account has balance and pending proposals", () => {
|
|
241
|
+
const accountWithBalanceAndProposals = createCantonAccount({
|
|
242
|
+
operationsCount: 0,
|
|
243
|
+
balance: new BigNumber(500),
|
|
244
|
+
subAccounts: [],
|
|
245
|
+
cantonResources: {
|
|
246
|
+
instrumentUtxoCounts: {},
|
|
247
|
+
pendingTransferProposals: [
|
|
248
|
+
{
|
|
249
|
+
contract_id: "contract-456",
|
|
250
|
+
sender: "sender-address",
|
|
251
|
+
receiver: "receiver-address",
|
|
252
|
+
instrument_id: "instrument-456",
|
|
253
|
+
amount: "50",
|
|
254
|
+
memo: "test memo",
|
|
255
|
+
expires_at_micros: Date.now() * 1000 + 86400000000, // 1 day from now
|
|
256
|
+
},
|
|
257
|
+
],
|
|
258
|
+
},
|
|
259
|
+
});
|
|
260
|
+
|
|
261
|
+
expect(isAccountEmpty(accountWithBalanceAndProposals)).toBe(false);
|
|
262
|
+
});
|
|
263
|
+
|
|
264
|
+
it("should return false when account has all non-empty indicators", () => {
|
|
265
|
+
const fullyUsedAccount = createCantonAccount({
|
|
266
|
+
operationsCount: 10,
|
|
267
|
+
balance: new BigNumber(10000),
|
|
268
|
+
subAccounts: [
|
|
269
|
+
{
|
|
270
|
+
type: "TokenAccount",
|
|
271
|
+
id: "token-account-id",
|
|
272
|
+
parentId: "parent-id",
|
|
273
|
+
token: {
|
|
274
|
+
type: "TokenCurrency",
|
|
275
|
+
id: "token-id",
|
|
276
|
+
contractAddress: "0x123",
|
|
277
|
+
name: "Test Token",
|
|
278
|
+
ticker: "TEST",
|
|
279
|
+
decimals: 18,
|
|
280
|
+
parentCurrency: createMockAccount().currency,
|
|
281
|
+
},
|
|
282
|
+
balance: new BigNumber(100),
|
|
283
|
+
spendableBalance: new BigNumber(100),
|
|
284
|
+
operationsCount: 5,
|
|
285
|
+
operations: [],
|
|
286
|
+
pendingOperations: [],
|
|
287
|
+
balanceHistoryCache: {
|
|
288
|
+
HOUR: { latestDate: null, balances: [] },
|
|
289
|
+
DAY: { latestDate: null, balances: [] },
|
|
290
|
+
WEEK: { latestDate: null, balances: [] },
|
|
291
|
+
},
|
|
292
|
+
swapHistory: [],
|
|
293
|
+
creationDate: new Date(),
|
|
294
|
+
balanceHistory: [],
|
|
295
|
+
},
|
|
296
|
+
],
|
|
297
|
+
cantonResources: {
|
|
298
|
+
instrumentUtxoCounts: {
|
|
299
|
+
"instrument-1": 5,
|
|
300
|
+
"instrument-2": 3,
|
|
301
|
+
},
|
|
302
|
+
pendingTransferProposals: [
|
|
303
|
+
{
|
|
304
|
+
contract_id: "contract-789",
|
|
305
|
+
sender: "sender-address",
|
|
306
|
+
receiver: "receiver-address",
|
|
307
|
+
instrument_id: "instrument-789",
|
|
308
|
+
amount: "200",
|
|
309
|
+
memo: "test memo",
|
|
310
|
+
expires_at_micros: Date.now() * 1000 + 86400000000, // 1 day from now
|
|
311
|
+
},
|
|
312
|
+
],
|
|
313
|
+
},
|
|
314
|
+
});
|
|
315
|
+
|
|
316
|
+
expect(isAccountEmpty(fullyUsedAccount)).toBe(false);
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it("should handle undefined subAccounts", () => {
|
|
320
|
+
const accountWithUndefinedSubAccounts = createCantonAccount({
|
|
321
|
+
operationsCount: 0,
|
|
322
|
+
balance: new BigNumber(0),
|
|
323
|
+
subAccounts: undefined,
|
|
324
|
+
cantonResources: {
|
|
325
|
+
instrumentUtxoCounts: {},
|
|
326
|
+
pendingTransferProposals: [],
|
|
327
|
+
},
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
expect(isAccountEmpty(accountWithUndefinedSubAccounts)).toBe(true);
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
it("should handle empty subAccounts array", () => {
|
|
334
|
+
const accountWithEmptySubAccounts = createCantonAccount({
|
|
335
|
+
operationsCount: 0,
|
|
336
|
+
balance: new BigNumber(0),
|
|
337
|
+
subAccounts: [],
|
|
338
|
+
cantonResources: {
|
|
339
|
+
instrumentUtxoCounts: {},
|
|
340
|
+
pendingTransferProposals: [],
|
|
341
|
+
},
|
|
342
|
+
});
|
|
343
|
+
|
|
344
|
+
expect(isAccountEmpty(accountWithEmptySubAccounts)).toBe(true);
|
|
345
|
+
});
|
|
346
|
+
|
|
347
|
+
it("should handle empty pendingTransferProposals array", () => {
|
|
348
|
+
const accountWithEmptyProposals = createCantonAccount({
|
|
349
|
+
operationsCount: 0,
|
|
350
|
+
balance: new BigNumber(0),
|
|
351
|
+
subAccounts: [],
|
|
352
|
+
cantonResources: {
|
|
353
|
+
instrumentUtxoCounts: {},
|
|
354
|
+
pendingTransferProposals: [],
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
expect(isAccountEmpty(accountWithEmptyProposals)).toBe(true);
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
package/src/helpers.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AccountLike } from "@ledgerhq/types-live";
|
|
2
|
+
import { isCantonAccount } from "./bridge/serialization";
|
|
3
|
+
import { CantonAccount } from "./types";
|
|
4
|
+
|
|
5
|
+
export function isCantonAccountEmpty(
|
|
6
|
+
account: Pick<CantonAccount, "operationsCount" | "balance" | "subAccounts" | "cantonResources">,
|
|
7
|
+
): boolean {
|
|
8
|
+
return (
|
|
9
|
+
account.operationsCount === 0 &&
|
|
10
|
+
account.balance.isZero() &&
|
|
11
|
+
!account.subAccounts?.length &&
|
|
12
|
+
!account.cantonResources?.pendingTransferProposals?.length
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Check if a Canton account is empty (has no operations, no balance, and no pending transfer proposals)
|
|
18
|
+
* @param account - The account to check (must be a Canton account)
|
|
19
|
+
* @returns true if the account is empty, false otherwise
|
|
20
|
+
*/
|
|
21
|
+
export function isAccountEmpty(account: AccountLike): boolean {
|
|
22
|
+
if (account.type !== "Account") {
|
|
23
|
+
return false;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (!isCantonAccount(account)) {
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return isCantonAccountEmpty(account);
|
|
31
|
+
}
|
package/src/index.ts
CHANGED
package/src/network/gateway.ts
CHANGED
|
@@ -58,6 +58,25 @@ export type PrepareTransferRequest = {
|
|
|
58
58
|
reason?: string;
|
|
59
59
|
};
|
|
60
60
|
|
|
61
|
+
export type PrepareTransferInstructionRequest = {
|
|
62
|
+
type:
|
|
63
|
+
| "accept-transfer-instruction"
|
|
64
|
+
| "reject-transfer-instruction"
|
|
65
|
+
| "withdraw-transfer-instruction";
|
|
66
|
+
contract_id: string;
|
|
67
|
+
reason?: string;
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export type TransferProposal = {
|
|
71
|
+
contract_id: string;
|
|
72
|
+
sender: string;
|
|
73
|
+
receiver: string;
|
|
74
|
+
amount: string;
|
|
75
|
+
instrument_id: string;
|
|
76
|
+
memo: string;
|
|
77
|
+
expires_at_micros: number;
|
|
78
|
+
};
|
|
79
|
+
|
|
61
80
|
type OnboardingSubmitRequest = {
|
|
62
81
|
prepare_request: OnboardingPrepareRequest;
|
|
63
82
|
prepare_response: OnboardingPrepareResponse;
|
|
@@ -380,6 +399,22 @@ export async function submit(
|
|
|
380
399
|
return data;
|
|
381
400
|
}
|
|
382
401
|
|
|
402
|
+
export async function prepare(
|
|
403
|
+
currency: CryptoCurrency,
|
|
404
|
+
partyId: string,
|
|
405
|
+
params: PrepareTransferRequest | PrepareTransferInstructionRequest,
|
|
406
|
+
) {
|
|
407
|
+
const { data } = await gatewayNetwork<
|
|
408
|
+
PrepareTransferResponse,
|
|
409
|
+
PrepareTransferRequest | PrepareTransferInstructionRequest
|
|
410
|
+
>({
|
|
411
|
+
method: "POST",
|
|
412
|
+
url: `${getGatewayUrl(currency)}/v1/node/${getNodeId(currency)}/party/${partyId}/transaction/prepare`,
|
|
413
|
+
data: params,
|
|
414
|
+
});
|
|
415
|
+
return data;
|
|
416
|
+
}
|
|
417
|
+
|
|
383
418
|
export async function getBalance(currency: CryptoCurrency, partyId: string) {
|
|
384
419
|
const { data } = await gatewayNetwork<GetBalanceResponse>({
|
|
385
420
|
method: "GET",
|
|
@@ -502,13 +537,15 @@ export async function prepareTransferRequest(
|
|
|
502
537
|
partyId: string,
|
|
503
538
|
params: PrepareTransferRequest,
|
|
504
539
|
) {
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
url: `${getGatewayUrl(currency)}/v1/node/${getNodeId(currency)}/party/${partyId}/transaction/prepare`,
|
|
508
|
-
data: params,
|
|
509
|
-
});
|
|
540
|
+
return prepare(currency, partyId, params);
|
|
541
|
+
}
|
|
510
542
|
|
|
511
|
-
|
|
543
|
+
export async function prepareTransferInstruction(
|
|
544
|
+
currency: CryptoCurrency,
|
|
545
|
+
partyId: string,
|
|
546
|
+
params: PrepareTransferInstructionRequest,
|
|
547
|
+
) {
|
|
548
|
+
return prepare(currency, partyId, params);
|
|
512
549
|
}
|
|
513
550
|
|
|
514
551
|
export async function getLedgerEnd(currency: CryptoCurrency): Promise<number> {
|
|
@@ -553,6 +590,15 @@ export async function submitPreApprovalTransaction(
|
|
|
553
590
|
} satisfies PreApprovalResult;
|
|
554
591
|
}
|
|
555
592
|
|
|
593
|
+
export async function submitTransferInstruction(
|
|
594
|
+
currency: CryptoCurrency,
|
|
595
|
+
partyId: string,
|
|
596
|
+
serialized: string,
|
|
597
|
+
signature: string,
|
|
598
|
+
) {
|
|
599
|
+
return submit(currency, partyId, serialized, signature);
|
|
600
|
+
}
|
|
601
|
+
|
|
556
602
|
type GetTransferPreApprovalResponse = {
|
|
557
603
|
contract_id: string;
|
|
558
604
|
receiver: string;
|
|
@@ -569,3 +615,11 @@ export async function getTransferPreApproval(currency: CryptoCurrency, partyId:
|
|
|
569
615
|
});
|
|
570
616
|
return data;
|
|
571
617
|
}
|
|
618
|
+
|
|
619
|
+
export async function getPendingTransferProposals(currency: CryptoCurrency, partyId: string) {
|
|
620
|
+
const { data } = await gatewayNetwork<TransferProposal[]>({
|
|
621
|
+
method: "GET",
|
|
622
|
+
url: `${getGatewayUrl(currency)}/v1/node/${getNodeId(currency)}/party/${partyId}/transfer-proposals?timestamp=${Date.now()}`,
|
|
623
|
+
});
|
|
624
|
+
return data;
|
|
625
|
+
}
|
package/src/types/bridge.ts
CHANGED
|
@@ -16,6 +16,7 @@ import type {
|
|
|
16
16
|
CantonAuthorizeProgress,
|
|
17
17
|
CantonAuthorizeResult,
|
|
18
18
|
} from "./onboard";
|
|
19
|
+
import type { TransferProposal } from "../network/gateway";
|
|
19
20
|
|
|
20
21
|
export interface CantonCurrencyBridge extends CurrencyBridge {
|
|
21
22
|
onboardAccount: (
|
|
@@ -29,6 +30,18 @@ export interface CantonCurrencyBridge extends CurrencyBridge {
|
|
|
29
30
|
creatableAccount: Account,
|
|
30
31
|
partyId: string,
|
|
31
32
|
) => Observable<CantonAuthorizeProgress | CantonAuthorizeResult>;
|
|
33
|
+
transferInstruction: (
|
|
34
|
+
currency: CryptoCurrency,
|
|
35
|
+
deviceId: string,
|
|
36
|
+
account: Account,
|
|
37
|
+
partyId: string,
|
|
38
|
+
contractId: string,
|
|
39
|
+
type:
|
|
40
|
+
| "accept-transfer-instruction"
|
|
41
|
+
| "reject-transfer-instruction"
|
|
42
|
+
| "withdraw-transfer-instruction",
|
|
43
|
+
reason?: string,
|
|
44
|
+
) => Promise<void>;
|
|
32
45
|
}
|
|
33
46
|
|
|
34
47
|
export type NetworkInfo = {
|
|
@@ -64,9 +77,11 @@ export type TransactionStatusRaw = TransactionStatusCommonRaw;
|
|
|
64
77
|
|
|
65
78
|
export type CantonResources = {
|
|
66
79
|
instrumentUtxoCounts: Record<string, number>;
|
|
80
|
+
pendingTransferProposals: TransferProposal[];
|
|
67
81
|
};
|
|
68
82
|
export type CantonResourcesRaw = {
|
|
69
83
|
instrumentUtxoCounts: Record<string, number>;
|
|
84
|
+
pendingTransferProposals: TransferProposal[];
|
|
70
85
|
};
|
|
71
86
|
|
|
72
87
|
export type CantonAccount = Account & {
|