@ledgerhq/coin-filecoin 1.14.1-nightly.20251113102200 → 1.15.0-nightly.20251115023630
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/.unimportedrc.json +2 -0
- package/CHANGELOG.md +11 -7
- package/lib/api/api.d.ts +5 -3
- package/lib/api/api.d.ts.map +1 -1
- package/lib/api/api.js +66 -21
- package/lib/api/api.js.map +1 -1
- package/lib/common-logic/index.d.ts +1 -1
- package/lib/common-logic/index.d.ts.map +1 -1
- package/lib/common-logic/index.js +1 -3
- package/lib/common-logic/index.js.map +1 -1
- package/lib/common-logic/utils.d.ts +0 -2
- package/lib/common-logic/utils.d.ts.map +1 -1
- package/lib/common-logic/utils.js +16 -68
- package/lib/common-logic/utils.js.map +1 -1
- package/lib/erc20/tokenAccounts.d.ts +2 -3
- package/lib/erc20/tokenAccounts.d.ts.map +1 -1
- package/lib/erc20/tokenAccounts.js +46 -32
- package/lib/erc20/tokenAccounts.js.map +1 -1
- package/lib/test/fixtures.d.ts +87 -0
- package/lib/test/fixtures.d.ts.map +1 -0
- package/lib/test/fixtures.js +311 -0
- package/lib/test/fixtures.js.map +1 -0
- package/lib/types/common.d.ts +22 -2
- package/lib/types/common.d.ts.map +1 -1
- package/lib-es/api/api.d.ts +5 -3
- package/lib-es/api/api.d.ts.map +1 -1
- package/lib-es/api/api.js +61 -18
- package/lib-es/api/api.js.map +1 -1
- package/lib-es/common-logic/index.d.ts +1 -1
- package/lib-es/common-logic/index.d.ts.map +1 -1
- package/lib-es/common-logic/index.js +1 -1
- package/lib-es/common-logic/index.js.map +1 -1
- package/lib-es/common-logic/utils.d.ts +0 -2
- package/lib-es/common-logic/utils.d.ts.map +1 -1
- package/lib-es/common-logic/utils.js +16 -66
- package/lib-es/common-logic/utils.js.map +1 -1
- package/lib-es/erc20/tokenAccounts.d.ts +2 -3
- package/lib-es/erc20/tokenAccounts.d.ts.map +1 -1
- package/lib-es/erc20/tokenAccounts.js +47 -33
- package/lib-es/erc20/tokenAccounts.js.map +1 -1
- package/lib-es/test/fixtures.d.ts +87 -0
- package/lib-es/test/fixtures.d.ts.map +1 -0
- package/lib-es/test/fixtures.js +297 -0
- package/lib-es/test/fixtures.js.map +1 -0
- package/lib-es/types/common.d.ts +22 -2
- package/lib-es/types/common.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/api/api.ts +107 -26
- package/src/api/api.unit.test.ts +217 -0
- package/src/common-logic/index.ts +0 -2
- package/src/common-logic/utils.ts +19 -90
- package/src/common-logic/utils.unit.test.ts +429 -0
- package/src/erc20/tokenAccounts.ts +59 -34
- package/src/erc20/tokenAccounts.unit.test.ts +73 -0
- package/src/test/fixtures.ts +342 -0
- package/src/types/common.ts +24 -2
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
import BigNumber from "bignumber.js";
|
|
2
|
+
import { Account, Operation, OperationType, TokenAccount } from "@ledgerhq/types-live";
|
|
3
|
+
import type { Transaction } from "../types/bridge";
|
|
4
|
+
import type {
|
|
5
|
+
TransactionResponse,
|
|
6
|
+
BalanceResponse,
|
|
7
|
+
EstimatedFeesResponse,
|
|
8
|
+
ERC20Transfer,
|
|
9
|
+
} from "../types/common";
|
|
10
|
+
import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
|
|
11
|
+
import { encodeAccountId } from "@ledgerhq/coin-framework/account/index";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Sample Filecoin addresses for testing
|
|
15
|
+
*/
|
|
16
|
+
export const TEST_ADDRESSES = {
|
|
17
|
+
// f1 address (SECP256K1)
|
|
18
|
+
F1_ADDRESS: "f1abjxfbp274xpdqcpuaykwkfb43omjotacm2p3za",
|
|
19
|
+
// f4 address (delegated)
|
|
20
|
+
F4_ADDRESS: "f410fkkld55ioe7qg24wvt7fu6pbknb56ht7ptloy",
|
|
21
|
+
// Another f1 address for recipient
|
|
22
|
+
RECIPIENT_F1: "f1z4nykg7q6q5qnxs7h4zknhlqbqhq5jxcqm5qw4y",
|
|
23
|
+
// Another f4 address for recipient
|
|
24
|
+
RECIPIENT_F4: "f410fagkr6pfqzd5q2kj42qrj54g3sxqjsrqn4fhoy",
|
|
25
|
+
// ERC20 contract address (f4)
|
|
26
|
+
ERC20_CONTRACT: "f410f3huuiyauahgjp7xjbvb7yfpuhvpyxvnqx3qy",
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Sample transaction hashes for testing
|
|
31
|
+
*/
|
|
32
|
+
export const TEST_TRANSACTION_HASHES = {
|
|
33
|
+
VALID: "bafy2bzacedpqzd6qm2r7nvxj5oetpqvhujwwmvkhz4u3xnfzdvwzxpjzuqhpa",
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Sample block heights for testing
|
|
38
|
+
*/
|
|
39
|
+
export const TEST_BLOCK_HEIGHTS = {
|
|
40
|
+
CURRENT: 3000000,
|
|
41
|
+
RECENT: 2999999,
|
|
42
|
+
OLD: 2500000,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Create a mock Filecoin account for testing
|
|
47
|
+
*
|
|
48
|
+
* @param options Optional parameters to override default values
|
|
49
|
+
* @returns A mock Filecoin account
|
|
50
|
+
*/
|
|
51
|
+
export const createMockAccount = (options?: Partial<Account>): Account => {
|
|
52
|
+
const seedIdentifier = options?.seedIdentifier || TEST_ADDRESSES.F1_ADDRESS;
|
|
53
|
+
|
|
54
|
+
// For Filecoin, we need to handle the currency ID appropriately
|
|
55
|
+
// Using a mock currency structure similar to what getCryptoCurrencyById would return
|
|
56
|
+
const mockCurrency = {
|
|
57
|
+
type: "CryptoCurrency" as const,
|
|
58
|
+
id: "filecoin",
|
|
59
|
+
coinType: 461,
|
|
60
|
+
name: "Filecoin",
|
|
61
|
+
managerAppName: "Filecoin",
|
|
62
|
+
ticker: "FIL",
|
|
63
|
+
scheme: "filecoin",
|
|
64
|
+
color: "#0090FF",
|
|
65
|
+
family: "filecoin" as const,
|
|
66
|
+
units: [
|
|
67
|
+
{
|
|
68
|
+
name: "FIL",
|
|
69
|
+
code: "FIL",
|
|
70
|
+
magnitude: 18,
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
name: "attoFIL",
|
|
74
|
+
code: "attoFIL",
|
|
75
|
+
magnitude: 0,
|
|
76
|
+
},
|
|
77
|
+
],
|
|
78
|
+
explorerViews: [
|
|
79
|
+
{
|
|
80
|
+
address: "https://filfox.info/en/address/$address",
|
|
81
|
+
tx: "https://filfox.info/en/message/$hash",
|
|
82
|
+
},
|
|
83
|
+
],
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const account: Account = {
|
|
87
|
+
type: "Account",
|
|
88
|
+
id:
|
|
89
|
+
options?.id ||
|
|
90
|
+
encodeAccountId({
|
|
91
|
+
type: "js",
|
|
92
|
+
version: "2",
|
|
93
|
+
currencyId: "filecoin",
|
|
94
|
+
xpubOrAddress: seedIdentifier,
|
|
95
|
+
derivationMode: "",
|
|
96
|
+
}),
|
|
97
|
+
seedIdentifier,
|
|
98
|
+
derivationMode: "",
|
|
99
|
+
index: options?.index || 0,
|
|
100
|
+
freshAddress: options?.freshAddress || seedIdentifier,
|
|
101
|
+
freshAddressPath: options?.freshAddressPath || "44'/461'/0'/0/0",
|
|
102
|
+
blockHeight: options?.blockHeight || TEST_BLOCK_HEIGHTS.CURRENT,
|
|
103
|
+
balance:
|
|
104
|
+
options?.balance instanceof BigNumber
|
|
105
|
+
? options.balance
|
|
106
|
+
: new BigNumber(options?.balance || "1000000000000000000"), // 1 FIL
|
|
107
|
+
spendableBalance:
|
|
108
|
+
options?.spendableBalance instanceof BigNumber
|
|
109
|
+
? options.spendableBalance
|
|
110
|
+
: new BigNumber(options?.spendableBalance || "1000000000000000000"), // 1 FIL
|
|
111
|
+
operations: options?.operations || [],
|
|
112
|
+
pendingOperations: options?.pendingOperations || [],
|
|
113
|
+
currency: options?.currency || (mockCurrency as any),
|
|
114
|
+
operationsCount: options?.operationsCount || 0,
|
|
115
|
+
subAccounts: options?.subAccounts || [],
|
|
116
|
+
swapHistory: [],
|
|
117
|
+
balanceHistoryCache: {
|
|
118
|
+
HOUR: { latestDate: null, balances: [] },
|
|
119
|
+
DAY: { latestDate: null, balances: [] },
|
|
120
|
+
WEEK: { latestDate: null, balances: [] },
|
|
121
|
+
},
|
|
122
|
+
creationDate: options?.creationDate || new Date(),
|
|
123
|
+
lastSyncDate: options?.lastSyncDate || new Date(),
|
|
124
|
+
nfts: options?.nfts || [],
|
|
125
|
+
used: true,
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
return { ...account, ...options };
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Create a mock Filecoin transaction for testing
|
|
133
|
+
*
|
|
134
|
+
* @param options Optional parameters to override default values
|
|
135
|
+
* @returns A mock Filecoin transaction
|
|
136
|
+
*/
|
|
137
|
+
export const createMockTransaction = (options?: Partial<Transaction>): Transaction => {
|
|
138
|
+
const transaction: Transaction = {
|
|
139
|
+
family: "filecoin",
|
|
140
|
+
amount:
|
|
141
|
+
options?.amount instanceof BigNumber
|
|
142
|
+
? options.amount
|
|
143
|
+
: new BigNumber(options?.amount || "100000000000000000"), // 0.1 FIL
|
|
144
|
+
recipient: options?.recipient || TEST_ADDRESSES.RECIPIENT_F1,
|
|
145
|
+
useAllAmount: options?.useAllAmount || false,
|
|
146
|
+
nonce: options?.nonce || 0,
|
|
147
|
+
method: options?.method || 0,
|
|
148
|
+
version: options?.version || 0,
|
|
149
|
+
params: options?.params,
|
|
150
|
+
gasLimit: options?.gasLimit || new BigNumber(1000000),
|
|
151
|
+
gasFeeCap: options?.gasFeeCap || new BigNumber("100000"),
|
|
152
|
+
gasPremium: options?.gasPremium || new BigNumber("100000"),
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
return { ...transaction, ...options };
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Create a mock Filecoin operation for testing
|
|
160
|
+
*
|
|
161
|
+
* @param account The account associated with the operation
|
|
162
|
+
* @param transaction The transaction details
|
|
163
|
+
* @param options Optional parameters to override default values
|
|
164
|
+
* @returns A mock Filecoin operation
|
|
165
|
+
*/
|
|
166
|
+
export const createMockOperation = (
|
|
167
|
+
account: Account,
|
|
168
|
+
transaction: Transaction,
|
|
169
|
+
options?: Partial<Operation>,
|
|
170
|
+
): Operation => {
|
|
171
|
+
const hash = options?.hash || TEST_TRANSACTION_HASHES.VALID;
|
|
172
|
+
const type = (options?.type as OperationType) || "OUT";
|
|
173
|
+
|
|
174
|
+
const fee = transaction.gasLimit.multipliedBy(transaction.gasFeeCap).plus(transaction.gasPremium);
|
|
175
|
+
|
|
176
|
+
const operation: Operation = {
|
|
177
|
+
id: options?.id || encodeOperationId(account.id, hash, type),
|
|
178
|
+
hash,
|
|
179
|
+
type,
|
|
180
|
+
senders: options?.senders || [account.freshAddress],
|
|
181
|
+
recipients: options?.recipients || [transaction.recipient],
|
|
182
|
+
accountId: account.id,
|
|
183
|
+
blockHash: options?.blockHash || null,
|
|
184
|
+
blockHeight: options?.blockHeight || null,
|
|
185
|
+
value: type === "OUT" ? transaction.amount.plus(fee) : transaction.amount,
|
|
186
|
+
fee,
|
|
187
|
+
date: options?.date || new Date(),
|
|
188
|
+
extra: options?.extra || {},
|
|
189
|
+
hasFailed: options?.hasFailed || false,
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
return { ...operation, ...options };
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Create a mock TokenAccount for testing ERC20 functionality
|
|
197
|
+
*
|
|
198
|
+
* @param parentAccount The parent Filecoin account
|
|
199
|
+
* @param options Optional parameters to override default values
|
|
200
|
+
* @returns A mock TokenAccount
|
|
201
|
+
*/
|
|
202
|
+
export const createMockTokenAccount = (
|
|
203
|
+
parentAccount: Account,
|
|
204
|
+
options?: Partial<TokenAccount>,
|
|
205
|
+
): TokenAccount => {
|
|
206
|
+
const tokenAccount: TokenAccount = {
|
|
207
|
+
type: "TokenAccount",
|
|
208
|
+
id: options?.id || `${parentAccount.id}+${TEST_ADDRESSES.ERC20_CONTRACT}`,
|
|
209
|
+
parentId: parentAccount.id,
|
|
210
|
+
token: options?.token || {
|
|
211
|
+
type: "TokenCurrency" as const,
|
|
212
|
+
id: `filecoin/erc20/test_token`,
|
|
213
|
+
contractAddress: TEST_ADDRESSES.ERC20_CONTRACT,
|
|
214
|
+
parentCurrency: parentAccount.currency,
|
|
215
|
+
tokenType: "erc20" as const,
|
|
216
|
+
name: "Test Token",
|
|
217
|
+
ticker: "TST",
|
|
218
|
+
units: [
|
|
219
|
+
{
|
|
220
|
+
name: "TST",
|
|
221
|
+
code: "TST",
|
|
222
|
+
magnitude: 18,
|
|
223
|
+
},
|
|
224
|
+
],
|
|
225
|
+
disableCountervalue: false,
|
|
226
|
+
},
|
|
227
|
+
balance:
|
|
228
|
+
options?.balance instanceof BigNumber
|
|
229
|
+
? options.balance
|
|
230
|
+
: new BigNumber(options?.balance || "1000000000000000000"), // 1 TST
|
|
231
|
+
spendableBalance:
|
|
232
|
+
options?.spendableBalance instanceof BigNumber
|
|
233
|
+
? options.spendableBalance
|
|
234
|
+
: new BigNumber(options?.spendableBalance || "1000000000000000000"),
|
|
235
|
+
creationDate: options?.creationDate || new Date(),
|
|
236
|
+
operationsCount: options?.operationsCount || 0,
|
|
237
|
+
operations: options?.operations || [],
|
|
238
|
+
pendingOperations: options?.pendingOperations || [],
|
|
239
|
+
swapHistory: options?.swapHistory || [],
|
|
240
|
+
balanceHistoryCache: options?.balanceHistoryCache || {
|
|
241
|
+
HOUR: { latestDate: null, balances: [] },
|
|
242
|
+
DAY: { latestDate: null, balances: [] },
|
|
243
|
+
WEEK: { latestDate: null, balances: [] },
|
|
244
|
+
},
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
return { ...tokenAccount, ...options };
|
|
248
|
+
};
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Create mock API response for balance
|
|
252
|
+
*
|
|
253
|
+
* @param options Optional parameters to override default values
|
|
254
|
+
* @returns A mock BalanceResponse
|
|
255
|
+
*/
|
|
256
|
+
export const createMockBalanceResponse = (options?: Partial<BalanceResponse>): BalanceResponse => {
|
|
257
|
+
return {
|
|
258
|
+
total_balance: options?.total_balance || "1000000000000000000",
|
|
259
|
+
spendable_balance: options?.spendable_balance || "1000000000000000000",
|
|
260
|
+
locked_balance: options?.locked_balance || "0",
|
|
261
|
+
};
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Create mock API response for transaction
|
|
266
|
+
*
|
|
267
|
+
* @param options Optional parameters to override default values
|
|
268
|
+
* @returns A mock TransactionResponse
|
|
269
|
+
*/
|
|
270
|
+
export const createMockTransactionResponse = (
|
|
271
|
+
options?: Partial<TransactionResponse>,
|
|
272
|
+
): TransactionResponse => {
|
|
273
|
+
return {
|
|
274
|
+
hash: options?.hash || TEST_TRANSACTION_HASHES.VALID,
|
|
275
|
+
to: options?.to || TEST_ADDRESSES.RECIPIENT_F1,
|
|
276
|
+
from: options?.from || TEST_ADDRESSES.F1_ADDRESS,
|
|
277
|
+
amount: options?.amount || "100000000000000000",
|
|
278
|
+
status: options?.status || "Ok",
|
|
279
|
+
type: options?.type || "transfer",
|
|
280
|
+
timestamp: options?.timestamp || Math.floor(Date.now() / 1000),
|
|
281
|
+
height: options?.height || TEST_BLOCK_HEIGHTS.CURRENT,
|
|
282
|
+
fee_data: options?.fee_data || {
|
|
283
|
+
MinerFee: {
|
|
284
|
+
MinerAddress: "f0123",
|
|
285
|
+
Amount: "50000",
|
|
286
|
+
},
|
|
287
|
+
OverEstimationBurnFee: {
|
|
288
|
+
BurnAddress: "f099",
|
|
289
|
+
Amount: "25000",
|
|
290
|
+
},
|
|
291
|
+
BurnFee: {
|
|
292
|
+
BurnAddress: "f099",
|
|
293
|
+
Amount: "25000",
|
|
294
|
+
},
|
|
295
|
+
TotalCost: "100000",
|
|
296
|
+
},
|
|
297
|
+
};
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
/**
|
|
301
|
+
* Create mock API response for estimated fees
|
|
302
|
+
*
|
|
303
|
+
* @param options Optional parameters to override default values
|
|
304
|
+
* @returns A mock EstimatedFeesResponse
|
|
305
|
+
*/
|
|
306
|
+
export const createMockEstimatedFeesResponse = (
|
|
307
|
+
options?: Partial<EstimatedFeesResponse>,
|
|
308
|
+
): EstimatedFeesResponse => {
|
|
309
|
+
return {
|
|
310
|
+
gas_limit: options?.gas_limit || 1000000,
|
|
311
|
+
gas_fee_cap: options?.gas_fee_cap || "100000",
|
|
312
|
+
gas_premium: options?.gas_premium || "100000",
|
|
313
|
+
nonce: options?.nonce || 0,
|
|
314
|
+
};
|
|
315
|
+
};
|
|
316
|
+
|
|
317
|
+
/**
|
|
318
|
+
* Create mock ERC20 transfer for testing token functionality
|
|
319
|
+
*
|
|
320
|
+
* @param options Optional parameters to override default values
|
|
321
|
+
* @returns A mock ERC20Transfer
|
|
322
|
+
*/
|
|
323
|
+
export const createMockERC20Transfer = (options?: Partial<ERC20Transfer>): ERC20Transfer => {
|
|
324
|
+
const transfer: ERC20Transfer = {
|
|
325
|
+
id: options?.id || "1",
|
|
326
|
+
height: options?.height || TEST_BLOCK_HEIGHTS.CURRENT,
|
|
327
|
+
type: options?.type || "erc20_transfer",
|
|
328
|
+
status: options?.status || "Ok",
|
|
329
|
+
to: options?.to || TEST_ADDRESSES.RECIPIENT_F4,
|
|
330
|
+
from: options?.from || TEST_ADDRESSES.F4_ADDRESS,
|
|
331
|
+
amount: options?.amount || "1000000000000000000",
|
|
332
|
+
contract_address: options?.contract_address || TEST_ADDRESSES.ERC20_CONTRACT,
|
|
333
|
+
timestamp: options?.timestamp || Math.floor(Date.now() / 1000),
|
|
334
|
+
tx_hash: options?.tx_hash || TEST_TRANSACTION_HASHES.VALID,
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
if (options?.tx_cid !== undefined) {
|
|
338
|
+
transfer.tx_cid = options.tx_cid;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
return transfer;
|
|
342
|
+
};
|
package/src/types/common.ts
CHANGED
|
@@ -21,20 +21,42 @@ export interface EstimatedFeesResponse {
|
|
|
21
21
|
nonce: number;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
export interface Metadata {
|
|
25
|
+
limit: number;
|
|
26
|
+
offset: number;
|
|
27
|
+
}
|
|
28
|
+
|
|
24
29
|
export interface TransactionsResponse {
|
|
25
30
|
txs: TransactionResponse[];
|
|
31
|
+
metadata: Metadata;
|
|
26
32
|
}
|
|
27
33
|
|
|
28
34
|
export interface TransactionResponse {
|
|
29
|
-
amount:
|
|
35
|
+
amount: string;
|
|
30
36
|
to: string;
|
|
31
37
|
from: string;
|
|
38
|
+
fee_data?: FeeData;
|
|
32
39
|
status: string;
|
|
33
40
|
type: string;
|
|
34
41
|
hash: string;
|
|
35
42
|
timestamp: number;
|
|
36
43
|
height: number;
|
|
37
|
-
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface FeeData {
|
|
47
|
+
MinerFee: {
|
|
48
|
+
MinerAddress: string;
|
|
49
|
+
Amount: string;
|
|
50
|
+
};
|
|
51
|
+
OverEstimationBurnFee: {
|
|
52
|
+
BurnAddress: string;
|
|
53
|
+
Amount: string;
|
|
54
|
+
};
|
|
55
|
+
BurnFee: {
|
|
56
|
+
BurnAddress: string;
|
|
57
|
+
Amount: string;
|
|
58
|
+
};
|
|
59
|
+
TotalCost: string;
|
|
38
60
|
}
|
|
39
61
|
|
|
40
62
|
export interface BalanceResponse {
|