@ledgerhq/coin-sui 0.12.0 → 0.12.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 +7 -0
- package/lib/api/index.integration.test.js +9 -2
- package/lib/api/index.integration.test.js.map +1 -1
- package/lib/api/index.test.js +2 -2
- package/lib/api/index.test.js.map +1 -1
- package/lib/logic/listOperations.d.ts +1 -3
- package/lib/logic/listOperations.d.ts.map +1 -1
- package/lib/logic/listOperations.js +3 -3
- package/lib/logic/listOperations.js.map +1 -1
- package/lib/logic/listOperations.test.js +43 -39
- package/lib/logic/listOperations.test.js.map +1 -1
- package/lib/network/index.d.ts +1 -1
- package/lib/network/sdk.d.ts +9 -5
- package/lib/network/sdk.d.ts.map +1 -1
- package/lib/network/sdk.js +54 -27
- package/lib/network/sdk.js.map +1 -1
- package/lib/network/sdk.test.js +272 -170
- package/lib/network/sdk.test.js.map +1 -1
- package/lib-es/api/index.integration.test.js +9 -2
- package/lib-es/api/index.integration.test.js.map +1 -1
- package/lib-es/api/index.test.js +2 -2
- package/lib-es/api/index.test.js.map +1 -1
- package/lib-es/logic/listOperations.d.ts +1 -3
- package/lib-es/logic/listOperations.d.ts.map +1 -1
- package/lib-es/logic/listOperations.js +4 -4
- package/lib-es/logic/listOperations.js.map +1 -1
- package/lib-es/logic/listOperations.test.js +44 -40
- package/lib-es/logic/listOperations.test.js.map +1 -1
- package/lib-es/network/index.d.ts +1 -1
- package/lib-es/network/sdk.d.ts +9 -5
- package/lib-es/network/sdk.d.ts.map +1 -1
- package/lib-es/network/sdk.js +54 -27
- package/lib-es/network/sdk.js.map +1 -1
- package/lib-es/network/sdk.test.js +272 -170
- package/lib-es/network/sdk.test.js.map +1 -1
- package/package.json +3 -3
- package/src/api/index.integration.test.ts +10 -2
- package/src/api/index.test.ts +2 -2
- package/src/logic/listOperations.test.ts +45 -41
- package/src/logic/listOperations.ts +4 -4
- package/src/network/sdk.test.ts +312 -207
- package/src/network/sdk.ts +70 -32
package/lib/network/sdk.test.js
CHANGED
|
@@ -443,6 +443,7 @@ describe("SDK Functions", () => {
|
|
|
443
443
|
expect(operation.asset).toEqual({ type: "token", assetReference: "0x123::test::TOKEN" });
|
|
444
444
|
expect(operation.memo).toBeUndefined();
|
|
445
445
|
expect(operation.details).toBeUndefined();
|
|
446
|
+
expect(operation.tx.block.hash).toBeUndefined();
|
|
446
447
|
expect(operation.tx).toMatchObject({
|
|
447
448
|
hash: "DhKLpX5kwuKuyRa71RGqpX5EY2M8Efw535ZVXYXsRiDt",
|
|
448
449
|
block: {},
|
|
@@ -902,6 +903,7 @@ describe("Staking Operations", () => {
|
|
|
902
903
|
expect(operation.recipients).toEqual([]);
|
|
903
904
|
expect(operation.value).toEqual(1000000000n); // The function returns minus of the balance change
|
|
904
905
|
expect(operation.asset).toEqual({ type: "native" });
|
|
906
|
+
expect(operation.tx.block.hash).toBeUndefined();
|
|
905
907
|
});
|
|
906
908
|
test("transactionToOp should map unstaking transaction correctly", () => {
|
|
907
909
|
const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
|
|
@@ -948,6 +950,7 @@ describe("Staking Operations", () => {
|
|
|
948
950
|
expect(operation.recipients).toEqual([]);
|
|
949
951
|
expect(operation.value).toEqual(0n);
|
|
950
952
|
expect(operation.asset).toEqual({ type: "native" });
|
|
953
|
+
expect(operation.tx.block.hash).toBeUndefined();
|
|
951
954
|
});
|
|
952
955
|
});
|
|
953
956
|
describe("Operation Extra Information", () => {
|
|
@@ -1015,8 +1018,8 @@ describe("loadOperations", () => {
|
|
|
1015
1018
|
order: "ascending",
|
|
1016
1019
|
operations: [],
|
|
1017
1020
|
});
|
|
1018
|
-
expect(result).toHaveLength(pageSize + 1);
|
|
1019
|
-
expect(result.map(tx => tx.digest)).toEqual([
|
|
1021
|
+
expect(result.operations).toHaveLength(pageSize + 1);
|
|
1022
|
+
expect(result.operations.map(tx => tx.digest)).toEqual([
|
|
1020
1023
|
...firstPage.map(tx => tx.digest),
|
|
1021
1024
|
`tx${pageSize + 1}`,
|
|
1022
1025
|
]);
|
|
@@ -1038,7 +1041,7 @@ describe("loadOperations", () => {
|
|
|
1038
1041
|
order: "ascending",
|
|
1039
1042
|
operations: [],
|
|
1040
1043
|
});
|
|
1041
|
-
expect(result).toHaveLength(sdk.TRANSACTIONS_LIMIT_PER_QUERY - 1);
|
|
1044
|
+
expect(result.operations).toHaveLength(sdk.TRANSACTIONS_LIMIT_PER_QUERY - 1);
|
|
1042
1045
|
expect(mockApi.queryTransactionBlocks).toHaveBeenCalledTimes(1);
|
|
1043
1046
|
});
|
|
1044
1047
|
it("should not exceed TRANSACTIONS_LIMIT", async () => {
|
|
@@ -1062,7 +1065,7 @@ describe("loadOperations", () => {
|
|
|
1062
1065
|
order: "ascending",
|
|
1063
1066
|
operations: [],
|
|
1064
1067
|
});
|
|
1065
|
-
expect(result).toHaveLength(sdk.TRANSACTIONS_LIMIT);
|
|
1068
|
+
expect(result.operations).toHaveLength(sdk.TRANSACTIONS_LIMIT);
|
|
1066
1069
|
expect(mockApi.queryTransactionBlocks).toHaveBeenCalledTimes(expectedCalls);
|
|
1067
1070
|
});
|
|
1068
1071
|
it("should retry without cursor when InvalidParams error occurs", async () => {
|
|
@@ -1086,7 +1089,7 @@ describe("loadOperations", () => {
|
|
|
1086
1089
|
cursor: "some-cursor",
|
|
1087
1090
|
}));
|
|
1088
1091
|
// Result should be empty array (no retry, just return operations)
|
|
1089
|
-
expect(result).toHaveLength(0);
|
|
1092
|
+
expect(result.operations).toHaveLength(0);
|
|
1090
1093
|
});
|
|
1091
1094
|
it("should should not retry after unexpected errors and return empty data", async () => {
|
|
1092
1095
|
mockApi.queryTransactionBlocks.mockRejectedValueOnce(new Error("unexpected"));
|
|
@@ -1097,7 +1100,7 @@ describe("loadOperations", () => {
|
|
|
1097
1100
|
order: "ascending",
|
|
1098
1101
|
operations: [],
|
|
1099
1102
|
});
|
|
1100
|
-
expect(result).toEqual([]);
|
|
1103
|
+
expect(result.operations).toEqual([]);
|
|
1101
1104
|
expect(mockApi.queryTransactionBlocks).toHaveBeenCalledTimes(1);
|
|
1102
1105
|
});
|
|
1103
1106
|
});
|
|
@@ -1168,18 +1171,24 @@ describe("getOperations filtering logic", () => {
|
|
|
1168
1171
|
// Mock loadOperations to return different data based on operation type
|
|
1169
1172
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1170
1173
|
if (type === "OUT") {
|
|
1171
|
-
return
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1174
|
+
return {
|
|
1175
|
+
operations: [
|
|
1176
|
+
createMockTransaction("sent1", "1000", mockAddr, []),
|
|
1177
|
+
createMockTransaction("sent2", "2000", mockAddr, []),
|
|
1178
|
+
],
|
|
1179
|
+
cursor: null,
|
|
1180
|
+
};
|
|
1175
1181
|
}
|
|
1176
1182
|
else if (type === "IN") {
|
|
1177
|
-
return
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1183
|
+
return {
|
|
1184
|
+
operations: [
|
|
1185
|
+
createMockTransaction("received1", "1500", otherAddr, [mockAddr]),
|
|
1186
|
+
createMockTransaction("received2", "2500", otherAddr, [mockAddr]),
|
|
1187
|
+
],
|
|
1188
|
+
cursor: null,
|
|
1189
|
+
};
|
|
1181
1190
|
}
|
|
1182
|
-
return [];
|
|
1191
|
+
return { operations: [], cursor: null };
|
|
1183
1192
|
});
|
|
1184
1193
|
});
|
|
1185
1194
|
afterEach(() => {
|
|
@@ -1202,15 +1211,21 @@ describe("getOperations filtering logic", () => {
|
|
|
1202
1211
|
// Mock to return enough sent operations to reach limit
|
|
1203
1212
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1204
1213
|
if (type === "OUT") {
|
|
1205
|
-
return
|
|
1214
|
+
return {
|
|
1215
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`sent${i + 1}`, String(1000 + i * 100), mockAddr, [])),
|
|
1216
|
+
cursor: null,
|
|
1217
|
+
};
|
|
1206
1218
|
}
|
|
1207
1219
|
else if (type === "IN") {
|
|
1208
|
-
return
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1220
|
+
return {
|
|
1221
|
+
operations: [
|
|
1222
|
+
createMockTransaction("received1", "500", otherAddr, [mockAddr]),
|
|
1223
|
+
createMockTransaction("received2", "1500", otherAddr, [mockAddr]),
|
|
1224
|
+
],
|
|
1225
|
+
cursor: null,
|
|
1226
|
+
};
|
|
1212
1227
|
}
|
|
1213
|
-
return [];
|
|
1228
|
+
return { operations: [], cursor: null };
|
|
1214
1229
|
});
|
|
1215
1230
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1216
1231
|
// Filter timestamp should be the maximum of the last timestamps from both arrays
|
|
@@ -1225,15 +1240,23 @@ describe("getOperations filtering logic", () => {
|
|
|
1225
1240
|
// Mock to return enough received operations to reach limit
|
|
1226
1241
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1227
1242
|
if (type === "OUT") {
|
|
1228
|
-
return
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1243
|
+
return {
|
|
1244
|
+
operations: [
|
|
1245
|
+
createMockTransaction("sent1", "500", mockAddr, []),
|
|
1246
|
+
createMockTransaction("sent2", "1500", mockAddr, []),
|
|
1247
|
+
],
|
|
1248
|
+
cursor: null,
|
|
1249
|
+
};
|
|
1232
1250
|
}
|
|
1233
1251
|
else if (type === "IN") {
|
|
1234
|
-
return
|
|
1252
|
+
return {
|
|
1253
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`received${i + 1}`, String(1000 + i * 100), otherAddr, [
|
|
1254
|
+
mockAddr,
|
|
1255
|
+
])),
|
|
1256
|
+
cursor: null,
|
|
1257
|
+
};
|
|
1235
1258
|
}
|
|
1236
|
-
return [];
|
|
1259
|
+
return { operations: [], cursor: null };
|
|
1237
1260
|
});
|
|
1238
1261
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1239
1262
|
// Filter timestamp should be the maximum of the last timestamps from both arrays
|
|
@@ -1248,12 +1271,20 @@ describe("getOperations filtering logic", () => {
|
|
|
1248
1271
|
// Mock to return enough operations to reach limit for both types
|
|
1249
1272
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1250
1273
|
if (type === "OUT") {
|
|
1251
|
-
return
|
|
1274
|
+
return {
|
|
1275
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`sent${i + 1}`, String(1000 + i * 100), mockAddr, [])),
|
|
1276
|
+
cursor: null,
|
|
1277
|
+
};
|
|
1252
1278
|
}
|
|
1253
1279
|
else if (type === "IN") {
|
|
1254
|
-
return
|
|
1280
|
+
return {
|
|
1281
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`received${i + 1}`, String(2000 + i * 100), otherAddr, [
|
|
1282
|
+
mockAddr,
|
|
1283
|
+
])),
|
|
1284
|
+
cursor: null,
|
|
1285
|
+
};
|
|
1255
1286
|
}
|
|
1256
|
-
return [];
|
|
1287
|
+
return { operations: [], cursor: null };
|
|
1257
1288
|
});
|
|
1258
1289
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1259
1290
|
// Filter timestamp should be the maximum of the last timestamps from both arrays
|
|
@@ -1268,21 +1299,27 @@ describe("getOperations filtering logic", () => {
|
|
|
1268
1299
|
// Mock to return operations with null timestamps and reach limit
|
|
1269
1300
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1270
1301
|
if (type === "OUT") {
|
|
1271
|
-
return
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1302
|
+
return {
|
|
1303
|
+
operations: [
|
|
1304
|
+
createMockTransaction("sent1", "1000", mockAddr, []),
|
|
1305
|
+
createMockTransaction("sent2", null, mockAddr, []),
|
|
1306
|
+
createMockTransaction("sent3", "3000", mockAddr, []),
|
|
1307
|
+
...Array.from({ length: sdk.TRANSACTIONS_LIMIT - 3 }, (_, i) => createMockTransaction(`sent${i + 4}`, String(4000 + i * 100), mockAddr, [])),
|
|
1308
|
+
],
|
|
1309
|
+
cursor: null,
|
|
1310
|
+
};
|
|
1277
1311
|
}
|
|
1278
1312
|
else if (type === "IN") {
|
|
1279
|
-
return
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1313
|
+
return {
|
|
1314
|
+
operations: [
|
|
1315
|
+
createMockTransaction("received1", null, otherAddr, [mockAddr]),
|
|
1316
|
+
createMockTransaction("received2", "2000", otherAddr, [mockAddr]),
|
|
1317
|
+
createMockTransaction("received3", "4000", otherAddr, [mockAddr]),
|
|
1318
|
+
],
|
|
1319
|
+
cursor: null,
|
|
1320
|
+
};
|
|
1284
1321
|
}
|
|
1285
|
-
return [];
|
|
1322
|
+
return { operations: [], cursor: null };
|
|
1286
1323
|
});
|
|
1287
1324
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1288
1325
|
// Filter timestamp should be the timestamp of the last sent operation (4000 + 296*100 = 33600)
|
|
@@ -1294,12 +1331,18 @@ describe("getOperations filtering logic", () => {
|
|
|
1294
1331
|
// Mock to return operations that reach limit
|
|
1295
1332
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1296
1333
|
if (type === "OUT") {
|
|
1297
|
-
return
|
|
1334
|
+
return {
|
|
1335
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`sent${i + 1}`, String(1000 + i * 10), mockAddr, [])),
|
|
1336
|
+
cursor: null,
|
|
1337
|
+
};
|
|
1298
1338
|
}
|
|
1299
1339
|
else if (type === "IN") {
|
|
1300
|
-
return
|
|
1340
|
+
return {
|
|
1341
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`received${i + 1}`, String(500 + i * 10), otherAddr, [mockAddr])),
|
|
1342
|
+
cursor: null,
|
|
1343
|
+
};
|
|
1301
1344
|
}
|
|
1302
|
-
return [];
|
|
1345
|
+
return { operations: [], cursor: null };
|
|
1303
1346
|
});
|
|
1304
1347
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1305
1348
|
// Should be sorted by timestamp in descending order
|
|
@@ -1309,7 +1352,7 @@ describe("getOperations filtering logic", () => {
|
|
|
1309
1352
|
test("should handle empty operations arrays", async () => {
|
|
1310
1353
|
// Mock to return empty arrays
|
|
1311
1354
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1312
|
-
return [];
|
|
1355
|
+
return { operations: [], cursor: null };
|
|
1313
1356
|
});
|
|
1314
1357
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1315
1358
|
expect(operations).toHaveLength(0);
|
|
@@ -1318,15 +1361,18 @@ describe("getOperations filtering logic", () => {
|
|
|
1318
1361
|
// Mock to return only OUT operations
|
|
1319
1362
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1320
1363
|
if (type === "OUT") {
|
|
1321
|
-
return
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1364
|
+
return {
|
|
1365
|
+
operations: [
|
|
1366
|
+
createMockTransaction("sent1", "1000", mockAddr, []),
|
|
1367
|
+
createMockTransaction("sent2", "2000", mockAddr, []),
|
|
1368
|
+
],
|
|
1369
|
+
cursor: null,
|
|
1370
|
+
};
|
|
1325
1371
|
}
|
|
1326
1372
|
else if (type === "IN") {
|
|
1327
|
-
return [];
|
|
1373
|
+
return { operations: [], cursor: null };
|
|
1328
1374
|
}
|
|
1329
|
-
return [];
|
|
1375
|
+
return { operations: [], cursor: null };
|
|
1330
1376
|
});
|
|
1331
1377
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1332
1378
|
expect(operations).toHaveLength(2);
|
|
@@ -1336,15 +1382,21 @@ describe("getOperations filtering logic", () => {
|
|
|
1336
1382
|
// Mock to return operations with same timestamps and reach limit
|
|
1337
1383
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1338
1384
|
if (type === "OUT") {
|
|
1339
|
-
return
|
|
1385
|
+
return {
|
|
1386
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`sent${i + 1}`, "1000", mockAddr, [])),
|
|
1387
|
+
cursor: null,
|
|
1388
|
+
};
|
|
1340
1389
|
}
|
|
1341
1390
|
else if (type === "IN") {
|
|
1342
|
-
return
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1391
|
+
return {
|
|
1392
|
+
operations: [
|
|
1393
|
+
createMockTransaction("received1", "1000", otherAddr, [mockAddr]),
|
|
1394
|
+
createMockTransaction("received2", "1000", otherAddr, [mockAddr]),
|
|
1395
|
+
],
|
|
1396
|
+
cursor: null,
|
|
1397
|
+
};
|
|
1346
1398
|
}
|
|
1347
|
-
return [];
|
|
1399
|
+
return { operations: [], cursor: null };
|
|
1348
1400
|
});
|
|
1349
1401
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1350
1402
|
// Filter timestamp should be 1000 (the common timestamp)
|
|
@@ -1400,189 +1452,239 @@ describe("filterOperations", () => {
|
|
|
1400
1452
|
});
|
|
1401
1453
|
describe("when cursor is provided", () => {
|
|
1402
1454
|
test("should not apply timestamp filtering", () => {
|
|
1403
|
-
const operationList1 =
|
|
1404
|
-
createMockTransaction("tx1", "1000"),
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
const operationList2 =
|
|
1408
|
-
createMockTransaction("tx3", "1500"),
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
const
|
|
1412
|
-
const result = sdk.filterOperations(operationList1, operationList2, cursor);
|
|
1455
|
+
const operationList1 = {
|
|
1456
|
+
operations: [createMockTransaction("tx1", "1000"), createMockTransaction("tx2", "2000")],
|
|
1457
|
+
cursor: null,
|
|
1458
|
+
};
|
|
1459
|
+
const operationList2 = {
|
|
1460
|
+
operations: [createMockTransaction("tx3", "1500"), createMockTransaction("tx4", "2500")],
|
|
1461
|
+
cursor: null,
|
|
1462
|
+
};
|
|
1463
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1413
1464
|
// Should return all operations sorted by timestamp in descending order
|
|
1414
|
-
expect(result).toHaveLength(4);
|
|
1415
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1465
|
+
expect(result.operations).toHaveLength(4);
|
|
1466
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1416
1467
|
});
|
|
1417
1468
|
test("should handle null cursor", () => {
|
|
1418
|
-
const operationList1 =
|
|
1419
|
-
createMockTransaction("tx1", "1000"),
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
const operationList2 =
|
|
1423
|
-
createMockTransaction("tx3", "1500"),
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
const result = sdk.filterOperations(operationList1, operationList2,
|
|
1469
|
+
const operationList1 = {
|
|
1470
|
+
operations: [createMockTransaction("tx1", "1000"), createMockTransaction("tx2", "2000")],
|
|
1471
|
+
cursor: null,
|
|
1472
|
+
};
|
|
1473
|
+
const operationList2 = {
|
|
1474
|
+
operations: [createMockTransaction("tx3", "1500"), createMockTransaction("tx4", "2500")],
|
|
1475
|
+
cursor: null,
|
|
1476
|
+
};
|
|
1477
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1427
1478
|
// Should return all operations sorted by timestamp in descending order
|
|
1428
|
-
expect(result).toHaveLength(4);
|
|
1429
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1479
|
+
expect(result.operations).toHaveLength(4);
|
|
1480
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1430
1481
|
});
|
|
1431
1482
|
test("should handle undefined cursor", () => {
|
|
1432
|
-
const operationList1 =
|
|
1433
|
-
createMockTransaction("tx1", "1000"),
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
const operationList2 =
|
|
1437
|
-
createMockTransaction("tx3", "1500"),
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
const result = sdk.filterOperations(operationList1, operationList2,
|
|
1483
|
+
const operationList1 = {
|
|
1484
|
+
operations: [createMockTransaction("tx1", "1000"), createMockTransaction("tx2", "2000")],
|
|
1485
|
+
cursor: null,
|
|
1486
|
+
};
|
|
1487
|
+
const operationList2 = {
|
|
1488
|
+
operations: [createMockTransaction("tx3", "1500"), createMockTransaction("tx4", "2500")],
|
|
1489
|
+
cursor: null,
|
|
1490
|
+
};
|
|
1491
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1441
1492
|
// Should return all operations sorted by timestamp in descending order
|
|
1442
|
-
expect(result).toHaveLength(4);
|
|
1443
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1493
|
+
expect(result.operations).toHaveLength(4);
|
|
1494
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1444
1495
|
});
|
|
1445
1496
|
});
|
|
1446
1497
|
describe("when cursor is not provided and operations reach limits", () => {
|
|
1447
1498
|
test("should apply timestamp filtering when both lists reach limit", () => {
|
|
1448
|
-
const operationList1 =
|
|
1449
|
-
|
|
1450
|
-
|
|
1499
|
+
const operationList1 = {
|
|
1500
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, String(1000 + i * 100))),
|
|
1501
|
+
cursor: null,
|
|
1502
|
+
};
|
|
1503
|
+
const operationList2 = {
|
|
1504
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx2_${i + 1}`, String(2000 + i * 100))),
|
|
1505
|
+
cursor: null,
|
|
1506
|
+
};
|
|
1507
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1451
1508
|
// Filter timestamp should be max of last timestamps:
|
|
1452
1509
|
// operationList1: 1000 + 299*100 = 30900
|
|
1453
1510
|
// operationList2: 2000 + 299*100 = 31900
|
|
1454
1511
|
// filter = max(30900, 31900) = 31900
|
|
1455
1512
|
// Only operations with timestamp >= 31900 should remain
|
|
1456
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 31900);
|
|
1513
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 31900);
|
|
1457
1514
|
expect(filteredOperations).toHaveLength(1);
|
|
1458
1515
|
expect(filteredOperations[0].digest).toBe("tx2_300");
|
|
1459
1516
|
});
|
|
1460
1517
|
test("should apply timestamp filtering when only first list reaches limit", () => {
|
|
1461
|
-
const operationList1 =
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1518
|
+
const operationList1 = {
|
|
1519
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, String(1000 + i * 100))),
|
|
1520
|
+
cursor: null,
|
|
1521
|
+
};
|
|
1522
|
+
const operationList2 = {
|
|
1523
|
+
operations: [createMockTransaction("tx2_1", "500"), createMockTransaction("tx2_2", "1500")],
|
|
1524
|
+
cursor: null,
|
|
1525
|
+
};
|
|
1526
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1467
1527
|
// Filter timestamp should be max of last timestamps:
|
|
1468
1528
|
// operationList1: 1000 + 299*100 = 30900
|
|
1469
1529
|
// operationList2: 1500
|
|
1470
1530
|
// filter = max(30900, 1500) = 30900
|
|
1471
1531
|
// Only operations with timestamp >= 30900 should remain
|
|
1472
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 30900);
|
|
1532
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 30900);
|
|
1473
1533
|
expect(filteredOperations).toHaveLength(1);
|
|
1474
1534
|
expect(filteredOperations[0].digest).toBe("tx1_300");
|
|
1475
1535
|
});
|
|
1476
1536
|
test("should apply timestamp filtering when only second list reaches limit", () => {
|
|
1477
|
-
const operationList1 =
|
|
1478
|
-
createMockTransaction("tx1_1", "500"),
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
const operationList2 =
|
|
1482
|
-
|
|
1537
|
+
const operationList1 = {
|
|
1538
|
+
operations: [createMockTransaction("tx1_1", "500"), createMockTransaction("tx1_2", "1500")],
|
|
1539
|
+
cursor: null,
|
|
1540
|
+
};
|
|
1541
|
+
const operationList2 = {
|
|
1542
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx2_${i + 1}`, String(2000 + i * 100))),
|
|
1543
|
+
cursor: null,
|
|
1544
|
+
};
|
|
1545
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1483
1546
|
// Filter timestamp should be max of last timestamps:
|
|
1484
1547
|
// operationList1: 1500
|
|
1485
1548
|
// operationList2: 2000 + 299*100 = 31900
|
|
1486
1549
|
// filter = max(1500, 31900) = 31900
|
|
1487
1550
|
// Only operations with timestamp >= 31900 should remain
|
|
1488
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 31900);
|
|
1551
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 31900);
|
|
1489
1552
|
expect(filteredOperations).toHaveLength(1);
|
|
1490
1553
|
expect(filteredOperations[0].digest).toBe("tx2_300");
|
|
1491
1554
|
});
|
|
1492
1555
|
});
|
|
1493
1556
|
describe("when cursor is not provided and operations don't reach limits", () => {
|
|
1494
1557
|
test("should not apply timestamp filtering when neither list reaches limit", () => {
|
|
1495
|
-
const operationList1 =
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1558
|
+
const operationList1 = {
|
|
1559
|
+
operations: [
|
|
1560
|
+
createMockTransaction("tx1_1", "1000"),
|
|
1561
|
+
createMockTransaction("tx1_2", "2000"),
|
|
1562
|
+
],
|
|
1563
|
+
cursor: null,
|
|
1564
|
+
};
|
|
1565
|
+
const operationList2 = {
|
|
1566
|
+
operations: [
|
|
1567
|
+
createMockTransaction("tx2_1", "1500"),
|
|
1568
|
+
createMockTransaction("tx2_2", "2500"),
|
|
1569
|
+
],
|
|
1570
|
+
cursor: null,
|
|
1571
|
+
};
|
|
1572
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1504
1573
|
// Should return all operations sorted by timestamp in descending order
|
|
1505
|
-
expect(result).toHaveLength(4);
|
|
1506
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx2_2", "tx1_2", "tx2_1", "tx1_1"]);
|
|
1574
|
+
expect(result.operations).toHaveLength(4);
|
|
1575
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx2_2", "tx1_2", "tx2_1", "tx1_1"]);
|
|
1507
1576
|
});
|
|
1508
1577
|
test("should apply timestamp filtering when only one list reaches limit", () => {
|
|
1509
|
-
const operationList1 =
|
|
1510
|
-
|
|
1511
|
-
|
|
1578
|
+
const operationList1 = {
|
|
1579
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, String(1000 + i * 100))),
|
|
1580
|
+
cursor: null,
|
|
1581
|
+
};
|
|
1582
|
+
const operationList2 = {
|
|
1583
|
+
operations: [createMockTransaction("tx2_1", "1500")],
|
|
1584
|
+
cursor: null,
|
|
1585
|
+
};
|
|
1586
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1512
1587
|
// Should apply timestamp filtering since one list reaches limit
|
|
1513
1588
|
// Filter timestamp should be the timestamp of the last operation in list1 (1000 + 299*100 = 30900)
|
|
1514
1589
|
// Only operations with timestamp >= 30900 should remain
|
|
1515
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 30900);
|
|
1590
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 30900);
|
|
1516
1591
|
expect(filteredOperations).toHaveLength(1);
|
|
1517
1592
|
expect(filteredOperations[0].digest).toBe("tx1_300");
|
|
1518
1593
|
});
|
|
1519
1594
|
});
|
|
1520
1595
|
describe("edge cases", () => {
|
|
1521
1596
|
test("should handle null/undefined timestampMs values", () => {
|
|
1522
|
-
const operationList1 =
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1597
|
+
const operationList1 = {
|
|
1598
|
+
operations: [
|
|
1599
|
+
createMockTransaction("tx1_1", "1000"),
|
|
1600
|
+
createMockTransaction("tx1_2", null),
|
|
1601
|
+
createMockTransaction("tx1_3", "3000"),
|
|
1602
|
+
...Array.from({ length: sdk.TRANSACTIONS_LIMIT - 3 }, (_, i) => createMockTransaction(`tx1_${i + 4}`, String(4000 + i * 100))),
|
|
1603
|
+
],
|
|
1604
|
+
cursor: null,
|
|
1605
|
+
};
|
|
1606
|
+
const operationList2 = {
|
|
1607
|
+
operations: [
|
|
1608
|
+
createMockTransaction("tx2_1", null),
|
|
1609
|
+
createMockTransaction("tx2_2", "2000"),
|
|
1610
|
+
createMockTransaction("tx2_3", "4000"),
|
|
1611
|
+
],
|
|
1612
|
+
cursor: null,
|
|
1613
|
+
};
|
|
1614
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1534
1615
|
// Filter timestamp should be the timestamp of the last operation in list1 (4000 + 296*100 = 33600)
|
|
1535
1616
|
// Only operations with timestamp >= 33600 should remain
|
|
1536
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 33600);
|
|
1617
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 33600);
|
|
1537
1618
|
expect(filteredOperations).toHaveLength(1);
|
|
1538
1619
|
expect(filteredOperations[0].digest).toBe("tx1_300");
|
|
1539
1620
|
});
|
|
1540
1621
|
test("should handle empty arrays", () => {
|
|
1541
|
-
const result = sdk.filterOperations([], [], null);
|
|
1542
|
-
expect(result).toHaveLength(0);
|
|
1622
|
+
const result = sdk.filterOperations({ operations: [], cursor: null }, { operations: [], cursor: null }, "ascending");
|
|
1623
|
+
expect(result.operations).toHaveLength(0);
|
|
1543
1624
|
});
|
|
1544
1625
|
test("should handle one empty array", () => {
|
|
1545
|
-
const operationList1 =
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1626
|
+
const operationList1 = {
|
|
1627
|
+
operations: [
|
|
1628
|
+
createMockTransaction("tx1_1", "1000"),
|
|
1629
|
+
createMockTransaction("tx1_2", "2000"),
|
|
1630
|
+
],
|
|
1631
|
+
cursor: null,
|
|
1632
|
+
};
|
|
1633
|
+
const operationList2 = {
|
|
1634
|
+
operations: [],
|
|
1635
|
+
cursor: null,
|
|
1636
|
+
};
|
|
1637
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1638
|
+
expect(result.operations).toHaveLength(2);
|
|
1639
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx1_2", "tx1_1"]);
|
|
1553
1640
|
});
|
|
1554
1641
|
test("should remove duplicate transactions by digest", () => {
|
|
1555
|
-
const operationList1 =
|
|
1556
|
-
createMockTransaction("tx1", "1000"),
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
const operationList2 =
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1642
|
+
const operationList1 = {
|
|
1643
|
+
operations: [createMockTransaction("tx1", "1000"), createMockTransaction("tx2", "2000")],
|
|
1644
|
+
cursor: null,
|
|
1645
|
+
};
|
|
1646
|
+
const operationList2 = {
|
|
1647
|
+
operations: [
|
|
1648
|
+
createMockTransaction("tx2", "2000"), // Duplicate digest
|
|
1649
|
+
createMockTransaction("tx3", "3000"),
|
|
1650
|
+
],
|
|
1651
|
+
cursor: null,
|
|
1652
|
+
};
|
|
1653
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1564
1654
|
// Should remove duplicate tx2
|
|
1565
|
-
expect(result).toHaveLength(3);
|
|
1566
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx3", "tx2", "tx1"]);
|
|
1655
|
+
expect(result.operations).toHaveLength(3);
|
|
1656
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx3", "tx2", "tx1"]);
|
|
1567
1657
|
});
|
|
1568
1658
|
test("should maintain chronological order after filtering", () => {
|
|
1569
|
-
const operationList1 =
|
|
1570
|
-
|
|
1571
|
-
|
|
1659
|
+
const operationList1 = {
|
|
1660
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, String(1000 + i * 10))),
|
|
1661
|
+
cursor: null,
|
|
1662
|
+
};
|
|
1663
|
+
const operationList2 = {
|
|
1664
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx2_${i + 1}`, String(500 + i * 10))),
|
|
1665
|
+
cursor: null,
|
|
1666
|
+
};
|
|
1667
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1572
1668
|
// Should be sorted by timestamp in descending order
|
|
1573
|
-
const timestamps = result.map(tx => Number(tx.timestampMs));
|
|
1669
|
+
const timestamps = result.operations.map(tx => Number(tx.timestampMs));
|
|
1574
1670
|
expect(timestamps).toEqual(timestamps.slice().sort((a, b) => b - a));
|
|
1575
1671
|
});
|
|
1576
1672
|
test("should handle operations with same timestamps", () => {
|
|
1577
|
-
const operationList1 =
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1673
|
+
const operationList1 = {
|
|
1674
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, "1000")),
|
|
1675
|
+
cursor: null,
|
|
1676
|
+
};
|
|
1677
|
+
const operationList2 = {
|
|
1678
|
+
operations: [
|
|
1679
|
+
createMockTransaction("tx2_1", "1000"),
|
|
1680
|
+
createMockTransaction("tx2_2", "1000"),
|
|
1681
|
+
],
|
|
1682
|
+
cursor: null,
|
|
1683
|
+
};
|
|
1684
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1583
1685
|
// Filter timestamp should be 1000 (the common timestamp)
|
|
1584
1686
|
// All operations have timestamp 1000, so all should pass the filter
|
|
1585
|
-
expect(result).toHaveLength(sdk.TRANSACTIONS_LIMIT + 2);
|
|
1687
|
+
expect(result.operations).toHaveLength(sdk.TRANSACTIONS_LIMIT + 2);
|
|
1586
1688
|
});
|
|
1587
1689
|
});
|
|
1588
1690
|
describe("conversion methods", () => {
|