@ledgerhq/coin-sui 0.12.0 → 0.13.0-nightly.1
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/api/index.d.ts +1 -1
- package/lib/api/index.d.ts.map +1 -1
- package/lib/api/index.integration.test.js +9 -2
- package/lib/api/index.integration.test.js.map +1 -1
- package/lib/api/index.js +1 -1
- package/lib/api/index.js.map +1 -1
- package/lib/api/index.test.js +3 -3
- package/lib/api/index.test.js.map +1 -1
- package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib/bridge/estimateMaxSpendable.js +9 -7
- package/lib/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib/bridge/estimateMaxSpendable.test.js +2 -2
- package/lib/bridge/estimateMaxSpendable.test.js.map +1 -1
- package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib/bridge/getTransactionStatus.js +4 -1
- package/lib/bridge/getTransactionStatus.js.map +1 -1
- package/lib/bridge/utils.d.ts.map +1 -1
- package/lib/bridge/utils.js +2 -2
- package/lib/bridge/utils.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.d.ts +1 -1
- package/lib-es/api/index.d.ts.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.js +1 -1
- package/lib-es/api/index.js.map +1 -1
- package/lib-es/api/index.test.js +3 -3
- package/lib-es/api/index.test.js.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.js +9 -7
- package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
- package/lib-es/bridge/estimateMaxSpendable.test.js +2 -2
- package/lib-es/bridge/estimateMaxSpendable.test.js.map +1 -1
- package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
- package/lib-es/bridge/getTransactionStatus.js +4 -1
- package/lib-es/bridge/getTransactionStatus.js.map +1 -1
- package/lib-es/bridge/utils.d.ts.map +1 -1
- package/lib-es/bridge/utils.js +2 -2
- package/lib-es/bridge/utils.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 +5 -5
- package/src/api/index.integration.test.ts +10 -2
- package/src/api/index.test.ts +3 -3
- package/src/api/index.ts +4 -3
- package/src/bridge/estimateMaxSpendable.test.ts +2 -2
- package/src/bridge/estimateMaxSpendable.ts +9 -8
- package/src/bridge/getTransactionStatus.ts +4 -2
- package/src/bridge/utils.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
|
@@ -415,6 +415,7 @@ describe("SDK Functions", () => {
|
|
|
415
415
|
expect(operation.asset).toEqual({ type: "token", assetReference: "0x123::test::TOKEN" });
|
|
416
416
|
expect(operation.memo).toBeUndefined();
|
|
417
417
|
expect(operation.details).toBeUndefined();
|
|
418
|
+
expect(operation.tx.block.hash).toBeUndefined();
|
|
418
419
|
expect(operation.tx).toMatchObject({
|
|
419
420
|
hash: "DhKLpX5kwuKuyRa71RGqpX5EY2M8Efw535ZVXYXsRiDt",
|
|
420
421
|
block: {},
|
|
@@ -874,6 +875,7 @@ describe("Staking Operations", () => {
|
|
|
874
875
|
expect(operation.recipients).toEqual([]);
|
|
875
876
|
expect(operation.value).toEqual(1000000000n); // The function returns minus of the balance change
|
|
876
877
|
expect(operation.asset).toEqual({ type: "native" });
|
|
878
|
+
expect(operation.tx.block.hash).toBeUndefined();
|
|
877
879
|
});
|
|
878
880
|
test("transactionToOp should map unstaking transaction correctly", () => {
|
|
879
881
|
const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
|
|
@@ -920,6 +922,7 @@ describe("Staking Operations", () => {
|
|
|
920
922
|
expect(operation.recipients).toEqual([]);
|
|
921
923
|
expect(operation.value).toEqual(0n);
|
|
922
924
|
expect(operation.asset).toEqual({ type: "native" });
|
|
925
|
+
expect(operation.tx.block.hash).toBeUndefined();
|
|
923
926
|
});
|
|
924
927
|
});
|
|
925
928
|
describe("Operation Extra Information", () => {
|
|
@@ -987,8 +990,8 @@ describe("loadOperations", () => {
|
|
|
987
990
|
order: "ascending",
|
|
988
991
|
operations: [],
|
|
989
992
|
});
|
|
990
|
-
expect(result).toHaveLength(pageSize + 1);
|
|
991
|
-
expect(result.map(tx => tx.digest)).toEqual([
|
|
993
|
+
expect(result.operations).toHaveLength(pageSize + 1);
|
|
994
|
+
expect(result.operations.map(tx => tx.digest)).toEqual([
|
|
992
995
|
...firstPage.map(tx => tx.digest),
|
|
993
996
|
`tx${pageSize + 1}`,
|
|
994
997
|
]);
|
|
@@ -1010,7 +1013,7 @@ describe("loadOperations", () => {
|
|
|
1010
1013
|
order: "ascending",
|
|
1011
1014
|
operations: [],
|
|
1012
1015
|
});
|
|
1013
|
-
expect(result).toHaveLength(sdk.TRANSACTIONS_LIMIT_PER_QUERY - 1);
|
|
1016
|
+
expect(result.operations).toHaveLength(sdk.TRANSACTIONS_LIMIT_PER_QUERY - 1);
|
|
1014
1017
|
expect(mockApi.queryTransactionBlocks).toHaveBeenCalledTimes(1);
|
|
1015
1018
|
});
|
|
1016
1019
|
it("should not exceed TRANSACTIONS_LIMIT", async () => {
|
|
@@ -1034,7 +1037,7 @@ describe("loadOperations", () => {
|
|
|
1034
1037
|
order: "ascending",
|
|
1035
1038
|
operations: [],
|
|
1036
1039
|
});
|
|
1037
|
-
expect(result).toHaveLength(sdk.TRANSACTIONS_LIMIT);
|
|
1040
|
+
expect(result.operations).toHaveLength(sdk.TRANSACTIONS_LIMIT);
|
|
1038
1041
|
expect(mockApi.queryTransactionBlocks).toHaveBeenCalledTimes(expectedCalls);
|
|
1039
1042
|
});
|
|
1040
1043
|
it("should retry without cursor when InvalidParams error occurs", async () => {
|
|
@@ -1058,7 +1061,7 @@ describe("loadOperations", () => {
|
|
|
1058
1061
|
cursor: "some-cursor",
|
|
1059
1062
|
}));
|
|
1060
1063
|
// Result should be empty array (no retry, just return operations)
|
|
1061
|
-
expect(result).toHaveLength(0);
|
|
1064
|
+
expect(result.operations).toHaveLength(0);
|
|
1062
1065
|
});
|
|
1063
1066
|
it("should should not retry after unexpected errors and return empty data", async () => {
|
|
1064
1067
|
mockApi.queryTransactionBlocks.mockRejectedValueOnce(new Error("unexpected"));
|
|
@@ -1069,7 +1072,7 @@ describe("loadOperations", () => {
|
|
|
1069
1072
|
order: "ascending",
|
|
1070
1073
|
operations: [],
|
|
1071
1074
|
});
|
|
1072
|
-
expect(result).toEqual([]);
|
|
1075
|
+
expect(result.operations).toEqual([]);
|
|
1073
1076
|
expect(mockApi.queryTransactionBlocks).toHaveBeenCalledTimes(1);
|
|
1074
1077
|
});
|
|
1075
1078
|
});
|
|
@@ -1140,18 +1143,24 @@ describe("getOperations filtering logic", () => {
|
|
|
1140
1143
|
// Mock loadOperations to return different data based on operation type
|
|
1141
1144
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1142
1145
|
if (type === "OUT") {
|
|
1143
|
-
return
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1146
|
+
return {
|
|
1147
|
+
operations: [
|
|
1148
|
+
createMockTransaction("sent1", "1000", mockAddr, []),
|
|
1149
|
+
createMockTransaction("sent2", "2000", mockAddr, []),
|
|
1150
|
+
],
|
|
1151
|
+
cursor: null,
|
|
1152
|
+
};
|
|
1147
1153
|
}
|
|
1148
1154
|
else if (type === "IN") {
|
|
1149
|
-
return
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1155
|
+
return {
|
|
1156
|
+
operations: [
|
|
1157
|
+
createMockTransaction("received1", "1500", otherAddr, [mockAddr]),
|
|
1158
|
+
createMockTransaction("received2", "2500", otherAddr, [mockAddr]),
|
|
1159
|
+
],
|
|
1160
|
+
cursor: null,
|
|
1161
|
+
};
|
|
1153
1162
|
}
|
|
1154
|
-
return [];
|
|
1163
|
+
return { operations: [], cursor: null };
|
|
1155
1164
|
});
|
|
1156
1165
|
});
|
|
1157
1166
|
afterEach(() => {
|
|
@@ -1174,15 +1183,21 @@ describe("getOperations filtering logic", () => {
|
|
|
1174
1183
|
// Mock to return enough sent operations to reach limit
|
|
1175
1184
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1176
1185
|
if (type === "OUT") {
|
|
1177
|
-
return
|
|
1186
|
+
return {
|
|
1187
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`sent${i + 1}`, String(1000 + i * 100), mockAddr, [])),
|
|
1188
|
+
cursor: null,
|
|
1189
|
+
};
|
|
1178
1190
|
}
|
|
1179
1191
|
else if (type === "IN") {
|
|
1180
|
-
return
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1192
|
+
return {
|
|
1193
|
+
operations: [
|
|
1194
|
+
createMockTransaction("received1", "500", otherAddr, [mockAddr]),
|
|
1195
|
+
createMockTransaction("received2", "1500", otherAddr, [mockAddr]),
|
|
1196
|
+
],
|
|
1197
|
+
cursor: null,
|
|
1198
|
+
};
|
|
1184
1199
|
}
|
|
1185
|
-
return [];
|
|
1200
|
+
return { operations: [], cursor: null };
|
|
1186
1201
|
});
|
|
1187
1202
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1188
1203
|
// Filter timestamp should be the maximum of the last timestamps from both arrays
|
|
@@ -1197,15 +1212,23 @@ describe("getOperations filtering logic", () => {
|
|
|
1197
1212
|
// Mock to return enough received operations to reach limit
|
|
1198
1213
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1199
1214
|
if (type === "OUT") {
|
|
1200
|
-
return
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1215
|
+
return {
|
|
1216
|
+
operations: [
|
|
1217
|
+
createMockTransaction("sent1", "500", mockAddr, []),
|
|
1218
|
+
createMockTransaction("sent2", "1500", mockAddr, []),
|
|
1219
|
+
],
|
|
1220
|
+
cursor: null,
|
|
1221
|
+
};
|
|
1204
1222
|
}
|
|
1205
1223
|
else if (type === "IN") {
|
|
1206
|
-
return
|
|
1224
|
+
return {
|
|
1225
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`received${i + 1}`, String(1000 + i * 100), otherAddr, [
|
|
1226
|
+
mockAddr,
|
|
1227
|
+
])),
|
|
1228
|
+
cursor: null,
|
|
1229
|
+
};
|
|
1207
1230
|
}
|
|
1208
|
-
return [];
|
|
1231
|
+
return { operations: [], cursor: null };
|
|
1209
1232
|
});
|
|
1210
1233
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1211
1234
|
// Filter timestamp should be the maximum of the last timestamps from both arrays
|
|
@@ -1220,12 +1243,20 @@ describe("getOperations filtering logic", () => {
|
|
|
1220
1243
|
// Mock to return enough operations to reach limit for both types
|
|
1221
1244
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1222
1245
|
if (type === "OUT") {
|
|
1223
|
-
return
|
|
1246
|
+
return {
|
|
1247
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`sent${i + 1}`, String(1000 + i * 100), mockAddr, [])),
|
|
1248
|
+
cursor: null,
|
|
1249
|
+
};
|
|
1224
1250
|
}
|
|
1225
1251
|
else if (type === "IN") {
|
|
1226
|
-
return
|
|
1252
|
+
return {
|
|
1253
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`received${i + 1}`, String(2000 + i * 100), otherAddr, [
|
|
1254
|
+
mockAddr,
|
|
1255
|
+
])),
|
|
1256
|
+
cursor: null,
|
|
1257
|
+
};
|
|
1227
1258
|
}
|
|
1228
|
-
return [];
|
|
1259
|
+
return { operations: [], cursor: null };
|
|
1229
1260
|
});
|
|
1230
1261
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1231
1262
|
// Filter timestamp should be the maximum of the last timestamps from both arrays
|
|
@@ -1240,21 +1271,27 @@ describe("getOperations filtering logic", () => {
|
|
|
1240
1271
|
// Mock to return operations with null timestamps and reach limit
|
|
1241
1272
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1242
1273
|
if (type === "OUT") {
|
|
1243
|
-
return
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1274
|
+
return {
|
|
1275
|
+
operations: [
|
|
1276
|
+
createMockTransaction("sent1", "1000", mockAddr, []),
|
|
1277
|
+
createMockTransaction("sent2", null, mockAddr, []),
|
|
1278
|
+
createMockTransaction("sent3", "3000", mockAddr, []),
|
|
1279
|
+
...Array.from({ length: sdk.TRANSACTIONS_LIMIT - 3 }, (_, i) => createMockTransaction(`sent${i + 4}`, String(4000 + i * 100), mockAddr, [])),
|
|
1280
|
+
],
|
|
1281
|
+
cursor: null,
|
|
1282
|
+
};
|
|
1249
1283
|
}
|
|
1250
1284
|
else if (type === "IN") {
|
|
1251
|
-
return
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1285
|
+
return {
|
|
1286
|
+
operations: [
|
|
1287
|
+
createMockTransaction("received1", null, otherAddr, [mockAddr]),
|
|
1288
|
+
createMockTransaction("received2", "2000", otherAddr, [mockAddr]),
|
|
1289
|
+
createMockTransaction("received3", "4000", otherAddr, [mockAddr]),
|
|
1290
|
+
],
|
|
1291
|
+
cursor: null,
|
|
1292
|
+
};
|
|
1256
1293
|
}
|
|
1257
|
-
return [];
|
|
1294
|
+
return { operations: [], cursor: null };
|
|
1258
1295
|
});
|
|
1259
1296
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1260
1297
|
// Filter timestamp should be the timestamp of the last sent operation (4000 + 296*100 = 33600)
|
|
@@ -1266,12 +1303,18 @@ describe("getOperations filtering logic", () => {
|
|
|
1266
1303
|
// Mock to return operations that reach limit
|
|
1267
1304
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1268
1305
|
if (type === "OUT") {
|
|
1269
|
-
return
|
|
1306
|
+
return {
|
|
1307
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`sent${i + 1}`, String(1000 + i * 10), mockAddr, [])),
|
|
1308
|
+
cursor: null,
|
|
1309
|
+
};
|
|
1270
1310
|
}
|
|
1271
1311
|
else if (type === "IN") {
|
|
1272
|
-
return
|
|
1312
|
+
return {
|
|
1313
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`received${i + 1}`, String(500 + i * 10), otherAddr, [mockAddr])),
|
|
1314
|
+
cursor: null,
|
|
1315
|
+
};
|
|
1273
1316
|
}
|
|
1274
|
-
return [];
|
|
1317
|
+
return { operations: [], cursor: null };
|
|
1275
1318
|
});
|
|
1276
1319
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1277
1320
|
// Should be sorted by timestamp in descending order
|
|
@@ -1281,7 +1324,7 @@ describe("getOperations filtering logic", () => {
|
|
|
1281
1324
|
test("should handle empty operations arrays", async () => {
|
|
1282
1325
|
// Mock to return empty arrays
|
|
1283
1326
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1284
|
-
return [];
|
|
1327
|
+
return { operations: [], cursor: null };
|
|
1285
1328
|
});
|
|
1286
1329
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1287
1330
|
expect(operations).toHaveLength(0);
|
|
@@ -1290,15 +1333,18 @@ describe("getOperations filtering logic", () => {
|
|
|
1290
1333
|
// Mock to return only OUT operations
|
|
1291
1334
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1292
1335
|
if (type === "OUT") {
|
|
1293
|
-
return
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1336
|
+
return {
|
|
1337
|
+
operations: [
|
|
1338
|
+
createMockTransaction("sent1", "1000", mockAddr, []),
|
|
1339
|
+
createMockTransaction("sent2", "2000", mockAddr, []),
|
|
1340
|
+
],
|
|
1341
|
+
cursor: null,
|
|
1342
|
+
};
|
|
1297
1343
|
}
|
|
1298
1344
|
else if (type === "IN") {
|
|
1299
|
-
return [];
|
|
1345
|
+
return { operations: [], cursor: null };
|
|
1300
1346
|
}
|
|
1301
|
-
return [];
|
|
1347
|
+
return { operations: [], cursor: null };
|
|
1302
1348
|
});
|
|
1303
1349
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1304
1350
|
expect(operations).toHaveLength(2);
|
|
@@ -1308,15 +1354,21 @@ describe("getOperations filtering logic", () => {
|
|
|
1308
1354
|
// Mock to return operations with same timestamps and reach limit
|
|
1309
1355
|
mockLoadOperations.mockImplementation(async ({ type, ..._params }) => {
|
|
1310
1356
|
if (type === "OUT") {
|
|
1311
|
-
return
|
|
1357
|
+
return {
|
|
1358
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`sent${i + 1}`, "1000", mockAddr, [])),
|
|
1359
|
+
cursor: null,
|
|
1360
|
+
};
|
|
1312
1361
|
}
|
|
1313
1362
|
else if (type === "IN") {
|
|
1314
|
-
return
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1363
|
+
return {
|
|
1364
|
+
operations: [
|
|
1365
|
+
createMockTransaction("received1", "1000", otherAddr, [mockAddr]),
|
|
1366
|
+
createMockTransaction("received2", "1000", otherAddr, [mockAddr]),
|
|
1367
|
+
],
|
|
1368
|
+
cursor: null,
|
|
1369
|
+
};
|
|
1318
1370
|
}
|
|
1319
|
-
return [];
|
|
1371
|
+
return { operations: [], cursor: null };
|
|
1320
1372
|
});
|
|
1321
1373
|
const operations = await sdk.getOperations(mockAccountId, mockAddr);
|
|
1322
1374
|
// Filter timestamp should be 1000 (the common timestamp)
|
|
@@ -1372,189 +1424,239 @@ describe("filterOperations", () => {
|
|
|
1372
1424
|
});
|
|
1373
1425
|
describe("when cursor is provided", () => {
|
|
1374
1426
|
test("should not apply timestamp filtering", () => {
|
|
1375
|
-
const operationList1 =
|
|
1376
|
-
createMockTransaction("tx1", "1000"),
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
const operationList2 =
|
|
1380
|
-
createMockTransaction("tx3", "1500"),
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
const
|
|
1384
|
-
const result = sdk.filterOperations(operationList1, operationList2, cursor);
|
|
1427
|
+
const operationList1 = {
|
|
1428
|
+
operations: [createMockTransaction("tx1", "1000"), createMockTransaction("tx2", "2000")],
|
|
1429
|
+
cursor: null,
|
|
1430
|
+
};
|
|
1431
|
+
const operationList2 = {
|
|
1432
|
+
operations: [createMockTransaction("tx3", "1500"), createMockTransaction("tx4", "2500")],
|
|
1433
|
+
cursor: null,
|
|
1434
|
+
};
|
|
1435
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1385
1436
|
// Should return all operations sorted by timestamp in descending order
|
|
1386
|
-
expect(result).toHaveLength(4);
|
|
1387
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1437
|
+
expect(result.operations).toHaveLength(4);
|
|
1438
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1388
1439
|
});
|
|
1389
1440
|
test("should handle null cursor", () => {
|
|
1390
|
-
const operationList1 =
|
|
1391
|
-
createMockTransaction("tx1", "1000"),
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
const operationList2 =
|
|
1395
|
-
createMockTransaction("tx3", "1500"),
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
const result = sdk.filterOperations(operationList1, operationList2,
|
|
1441
|
+
const operationList1 = {
|
|
1442
|
+
operations: [createMockTransaction("tx1", "1000"), createMockTransaction("tx2", "2000")],
|
|
1443
|
+
cursor: null,
|
|
1444
|
+
};
|
|
1445
|
+
const operationList2 = {
|
|
1446
|
+
operations: [createMockTransaction("tx3", "1500"), createMockTransaction("tx4", "2500")],
|
|
1447
|
+
cursor: null,
|
|
1448
|
+
};
|
|
1449
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1399
1450
|
// Should return all operations sorted by timestamp in descending order
|
|
1400
|
-
expect(result).toHaveLength(4);
|
|
1401
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1451
|
+
expect(result.operations).toHaveLength(4);
|
|
1452
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx4", "tx2", "tx3", "tx1"]);
|
|
1402
1453
|
});
|
|
1403
1454
|
test("should handle undefined cursor", () => {
|
|
1404
|
-
const operationList1 =
|
|
1405
|
-
createMockTransaction("tx1", "1000"),
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
const operationList2 =
|
|
1409
|
-
createMockTransaction("tx3", "1500"),
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
const result = sdk.filterOperations(operationList1, operationList2,
|
|
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
|
});
|
|
1418
1469
|
describe("when cursor is not provided and operations reach limits", () => {
|
|
1419
1470
|
test("should apply timestamp filtering when both lists reach limit", () => {
|
|
1420
|
-
const operationList1 =
|
|
1421
|
-
|
|
1422
|
-
|
|
1471
|
+
const operationList1 = {
|
|
1472
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, String(1000 + i * 100))),
|
|
1473
|
+
cursor: null,
|
|
1474
|
+
};
|
|
1475
|
+
const operationList2 = {
|
|
1476
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx2_${i + 1}`, String(2000 + i * 100))),
|
|
1477
|
+
cursor: null,
|
|
1478
|
+
};
|
|
1479
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1423
1480
|
// Filter timestamp should be max of last timestamps:
|
|
1424
1481
|
// operationList1: 1000 + 299*100 = 30900
|
|
1425
1482
|
// operationList2: 2000 + 299*100 = 31900
|
|
1426
1483
|
// filter = max(30900, 31900) = 31900
|
|
1427
1484
|
// Only operations with timestamp >= 31900 should remain
|
|
1428
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 31900);
|
|
1485
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 31900);
|
|
1429
1486
|
expect(filteredOperations).toHaveLength(1);
|
|
1430
1487
|
expect(filteredOperations[0].digest).toBe("tx2_300");
|
|
1431
1488
|
});
|
|
1432
1489
|
test("should apply timestamp filtering when only first list reaches limit", () => {
|
|
1433
|
-
const operationList1 =
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1490
|
+
const operationList1 = {
|
|
1491
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, String(1000 + i * 100))),
|
|
1492
|
+
cursor: null,
|
|
1493
|
+
};
|
|
1494
|
+
const operationList2 = {
|
|
1495
|
+
operations: [createMockTransaction("tx2_1", "500"), createMockTransaction("tx2_2", "1500")],
|
|
1496
|
+
cursor: null,
|
|
1497
|
+
};
|
|
1498
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1439
1499
|
// Filter timestamp should be max of last timestamps:
|
|
1440
1500
|
// operationList1: 1000 + 299*100 = 30900
|
|
1441
1501
|
// operationList2: 1500
|
|
1442
1502
|
// filter = max(30900, 1500) = 30900
|
|
1443
1503
|
// Only operations with timestamp >= 30900 should remain
|
|
1444
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 30900);
|
|
1504
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 30900);
|
|
1445
1505
|
expect(filteredOperations).toHaveLength(1);
|
|
1446
1506
|
expect(filteredOperations[0].digest).toBe("tx1_300");
|
|
1447
1507
|
});
|
|
1448
1508
|
test("should apply timestamp filtering when only second list reaches limit", () => {
|
|
1449
|
-
const operationList1 =
|
|
1450
|
-
createMockTransaction("tx1_1", "500"),
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
const operationList2 =
|
|
1454
|
-
|
|
1509
|
+
const operationList1 = {
|
|
1510
|
+
operations: [createMockTransaction("tx1_1", "500"), createMockTransaction("tx1_2", "1500")],
|
|
1511
|
+
cursor: null,
|
|
1512
|
+
};
|
|
1513
|
+
const operationList2 = {
|
|
1514
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx2_${i + 1}`, String(2000 + i * 100))),
|
|
1515
|
+
cursor: null,
|
|
1516
|
+
};
|
|
1517
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1455
1518
|
// Filter timestamp should be max of last timestamps:
|
|
1456
1519
|
// operationList1: 1500
|
|
1457
1520
|
// operationList2: 2000 + 299*100 = 31900
|
|
1458
1521
|
// filter = max(1500, 31900) = 31900
|
|
1459
1522
|
// Only operations with timestamp >= 31900 should remain
|
|
1460
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 31900);
|
|
1523
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 31900);
|
|
1461
1524
|
expect(filteredOperations).toHaveLength(1);
|
|
1462
1525
|
expect(filteredOperations[0].digest).toBe("tx2_300");
|
|
1463
1526
|
});
|
|
1464
1527
|
});
|
|
1465
1528
|
describe("when cursor is not provided and operations don't reach limits", () => {
|
|
1466
1529
|
test("should not apply timestamp filtering when neither list reaches limit", () => {
|
|
1467
|
-
const operationList1 =
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1530
|
+
const operationList1 = {
|
|
1531
|
+
operations: [
|
|
1532
|
+
createMockTransaction("tx1_1", "1000"),
|
|
1533
|
+
createMockTransaction("tx1_2", "2000"),
|
|
1534
|
+
],
|
|
1535
|
+
cursor: null,
|
|
1536
|
+
};
|
|
1537
|
+
const operationList2 = {
|
|
1538
|
+
operations: [
|
|
1539
|
+
createMockTransaction("tx2_1", "1500"),
|
|
1540
|
+
createMockTransaction("tx2_2", "2500"),
|
|
1541
|
+
],
|
|
1542
|
+
cursor: null,
|
|
1543
|
+
};
|
|
1544
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1476
1545
|
// Should return all operations sorted by timestamp in descending order
|
|
1477
|
-
expect(result).toHaveLength(4);
|
|
1478
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx2_2", "tx1_2", "tx2_1", "tx1_1"]);
|
|
1546
|
+
expect(result.operations).toHaveLength(4);
|
|
1547
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx2_2", "tx1_2", "tx2_1", "tx1_1"]);
|
|
1479
1548
|
});
|
|
1480
1549
|
test("should apply timestamp filtering when only one list reaches limit", () => {
|
|
1481
|
-
const operationList1 =
|
|
1482
|
-
|
|
1483
|
-
|
|
1550
|
+
const operationList1 = {
|
|
1551
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, String(1000 + i * 100))),
|
|
1552
|
+
cursor: null,
|
|
1553
|
+
};
|
|
1554
|
+
const operationList2 = {
|
|
1555
|
+
operations: [createMockTransaction("tx2_1", "1500")],
|
|
1556
|
+
cursor: null,
|
|
1557
|
+
};
|
|
1558
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1484
1559
|
// Should apply timestamp filtering since one list reaches limit
|
|
1485
1560
|
// Filter timestamp should be the timestamp of the last operation in list1 (1000 + 299*100 = 30900)
|
|
1486
1561
|
// Only operations with timestamp >= 30900 should remain
|
|
1487
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 30900);
|
|
1562
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 30900);
|
|
1488
1563
|
expect(filteredOperations).toHaveLength(1);
|
|
1489
1564
|
expect(filteredOperations[0].digest).toBe("tx1_300");
|
|
1490
1565
|
});
|
|
1491
1566
|
});
|
|
1492
1567
|
describe("edge cases", () => {
|
|
1493
1568
|
test("should handle null/undefined timestampMs values", () => {
|
|
1494
|
-
const operationList1 =
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1569
|
+
const operationList1 = {
|
|
1570
|
+
operations: [
|
|
1571
|
+
createMockTransaction("tx1_1", "1000"),
|
|
1572
|
+
createMockTransaction("tx1_2", null),
|
|
1573
|
+
createMockTransaction("tx1_3", "3000"),
|
|
1574
|
+
...Array.from({ length: sdk.TRANSACTIONS_LIMIT - 3 }, (_, i) => createMockTransaction(`tx1_${i + 4}`, String(4000 + i * 100))),
|
|
1575
|
+
],
|
|
1576
|
+
cursor: null,
|
|
1577
|
+
};
|
|
1578
|
+
const operationList2 = {
|
|
1579
|
+
operations: [
|
|
1580
|
+
createMockTransaction("tx2_1", null),
|
|
1581
|
+
createMockTransaction("tx2_2", "2000"),
|
|
1582
|
+
createMockTransaction("tx2_3", "4000"),
|
|
1583
|
+
],
|
|
1584
|
+
cursor: null,
|
|
1585
|
+
};
|
|
1586
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1506
1587
|
// Filter timestamp should be the timestamp of the last operation in list1 (4000 + 296*100 = 33600)
|
|
1507
1588
|
// Only operations with timestamp >= 33600 should remain
|
|
1508
|
-
const filteredOperations = result.filter(tx => Number(tx.timestampMs) >= 33600);
|
|
1589
|
+
const filteredOperations = result.operations.filter(tx => Number(tx.timestampMs) >= 33600);
|
|
1509
1590
|
expect(filteredOperations).toHaveLength(1);
|
|
1510
1591
|
expect(filteredOperations[0].digest).toBe("tx1_300");
|
|
1511
1592
|
});
|
|
1512
1593
|
test("should handle empty arrays", () => {
|
|
1513
|
-
const result = sdk.filterOperations([], [], null);
|
|
1514
|
-
expect(result).toHaveLength(0);
|
|
1594
|
+
const result = sdk.filterOperations({ operations: [], cursor: null }, { operations: [], cursor: null }, "ascending");
|
|
1595
|
+
expect(result.operations).toHaveLength(0);
|
|
1515
1596
|
});
|
|
1516
1597
|
test("should handle one empty array", () => {
|
|
1517
|
-
const operationList1 =
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1598
|
+
const operationList1 = {
|
|
1599
|
+
operations: [
|
|
1600
|
+
createMockTransaction("tx1_1", "1000"),
|
|
1601
|
+
createMockTransaction("tx1_2", "2000"),
|
|
1602
|
+
],
|
|
1603
|
+
cursor: null,
|
|
1604
|
+
};
|
|
1605
|
+
const operationList2 = {
|
|
1606
|
+
operations: [],
|
|
1607
|
+
cursor: null,
|
|
1608
|
+
};
|
|
1609
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1610
|
+
expect(result.operations).toHaveLength(2);
|
|
1611
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx1_2", "tx1_1"]);
|
|
1525
1612
|
});
|
|
1526
1613
|
test("should remove duplicate transactions by digest", () => {
|
|
1527
|
-
const operationList1 =
|
|
1528
|
-
createMockTransaction("tx1", "1000"),
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
const operationList2 =
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1614
|
+
const operationList1 = {
|
|
1615
|
+
operations: [createMockTransaction("tx1", "1000"), createMockTransaction("tx2", "2000")],
|
|
1616
|
+
cursor: null,
|
|
1617
|
+
};
|
|
1618
|
+
const operationList2 = {
|
|
1619
|
+
operations: [
|
|
1620
|
+
createMockTransaction("tx2", "2000"), // Duplicate digest
|
|
1621
|
+
createMockTransaction("tx3", "3000"),
|
|
1622
|
+
],
|
|
1623
|
+
cursor: null,
|
|
1624
|
+
};
|
|
1625
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1536
1626
|
// Should remove duplicate tx2
|
|
1537
|
-
expect(result).toHaveLength(3);
|
|
1538
|
-
expect(result.map(tx => tx.digest)).toEqual(["tx3", "tx2", "tx1"]);
|
|
1627
|
+
expect(result.operations).toHaveLength(3);
|
|
1628
|
+
expect(result.operations.map(tx => tx.digest)).toEqual(["tx3", "tx2", "tx1"]);
|
|
1539
1629
|
});
|
|
1540
1630
|
test("should maintain chronological order after filtering", () => {
|
|
1541
|
-
const operationList1 =
|
|
1542
|
-
|
|
1543
|
-
|
|
1631
|
+
const operationList1 = {
|
|
1632
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, String(1000 + i * 10))),
|
|
1633
|
+
cursor: null,
|
|
1634
|
+
};
|
|
1635
|
+
const operationList2 = {
|
|
1636
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx2_${i + 1}`, String(500 + i * 10))),
|
|
1637
|
+
cursor: null,
|
|
1638
|
+
};
|
|
1639
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1544
1640
|
// Should be sorted by timestamp in descending order
|
|
1545
|
-
const timestamps = result.map(tx => Number(tx.timestampMs));
|
|
1641
|
+
const timestamps = result.operations.map(tx => Number(tx.timestampMs));
|
|
1546
1642
|
expect(timestamps).toEqual(timestamps.slice().sort((a, b) => b - a));
|
|
1547
1643
|
});
|
|
1548
1644
|
test("should handle operations with same timestamps", () => {
|
|
1549
|
-
const operationList1 =
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1645
|
+
const operationList1 = {
|
|
1646
|
+
operations: Array.from({ length: sdk.TRANSACTIONS_LIMIT }, (_, i) => createMockTransaction(`tx1_${i + 1}`, "1000")),
|
|
1647
|
+
cursor: null,
|
|
1648
|
+
};
|
|
1649
|
+
const operationList2 = {
|
|
1650
|
+
operations: [
|
|
1651
|
+
createMockTransaction("tx2_1", "1000"),
|
|
1652
|
+
createMockTransaction("tx2_2", "1000"),
|
|
1653
|
+
],
|
|
1654
|
+
cursor: null,
|
|
1655
|
+
};
|
|
1656
|
+
const result = sdk.filterOperations(operationList1, operationList2, "ascending");
|
|
1555
1657
|
// Filter timestamp should be 1000 (the common timestamp)
|
|
1556
1658
|
// All operations have timestamp 1000, so all should pass the filter
|
|
1557
|
-
expect(result).toHaveLength(sdk.TRANSACTIONS_LIMIT + 2);
|
|
1659
|
+
expect(result.operations).toHaveLength(sdk.TRANSACTIONS_LIMIT + 2);
|
|
1558
1660
|
});
|
|
1559
1661
|
});
|
|
1560
1662
|
describe("conversion methods", () => {
|