polycopy 0.2.8 → 0.3.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/dist/index.js +119 -64
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -869,24 +869,32 @@ class RelayClient extends EventEmitter__default.default {
|
|
|
869
869
|
}
|
|
870
870
|
makePostData() {
|
|
871
871
|
const total = this.pendingTransactions.length;
|
|
872
|
-
const transactions = this.pendingTransactions.sort((a, b) => a.
|
|
872
|
+
const transactions = this.pendingTransactions.sort((a, b) => a.execCount - b.execCount).splice(0, this.options.batchSize);
|
|
873
873
|
if (transactions.length === 0) return null;
|
|
874
874
|
const postTransactions = [];
|
|
875
|
-
const
|
|
875
|
+
const postEvent = {
|
|
876
876
|
redeem: [],
|
|
877
877
|
merge: []
|
|
878
878
|
};
|
|
879
|
-
for (const { type, conditionId, transaction } of transactions) {
|
|
880
|
-
|
|
879
|
+
for (const { type, conditionId, execCount, transaction } of transactions) {
|
|
880
|
+
postEvent[type].push({ conditionId, execCount, done: false });
|
|
881
881
|
postTransactions.push(transaction);
|
|
882
882
|
}
|
|
883
883
|
return {
|
|
884
884
|
total,
|
|
885
885
|
transactions,
|
|
886
|
-
|
|
886
|
+
postEvent,
|
|
887
887
|
postTransactions
|
|
888
888
|
};
|
|
889
889
|
}
|
|
890
|
+
logPostedEvent(type, postedEvent) {
|
|
891
|
+
const { success, failed } = postedEvent[type];
|
|
892
|
+
if (success.length + failed.length > 0) {
|
|
893
|
+
logger.info(
|
|
894
|
+
` - ${type}: [success: ${success.length} failed: ${failed.length} nextRetry: ${failed.filter(({ done }) => !done).length}]`
|
|
895
|
+
);
|
|
896
|
+
}
|
|
897
|
+
}
|
|
890
898
|
exec() {
|
|
891
899
|
if (this.postTimeout || this.pendingTransactions.length === 0 || this.resetsTime) {
|
|
892
900
|
return;
|
|
@@ -901,17 +909,17 @@ class RelayClient extends EventEmitter__default.default {
|
|
|
901
909
|
this.postTimeout = setTimeout(() => {
|
|
902
910
|
const postData = this.makePostData();
|
|
903
911
|
if (!postData) return;
|
|
904
|
-
const { total, transactions, postTransactions,
|
|
912
|
+
const { total, transactions, postTransactions, postEvent } = postData;
|
|
905
913
|
logger.info(
|
|
906
914
|
"RelayClient",
|
|
907
915
|
"post transactions:",
|
|
908
916
|
`${transactions.length}/${total}`
|
|
909
917
|
);
|
|
910
918
|
logger.info(` - pending: ${this.pendingTransactions.length}`);
|
|
911
|
-
this.emit("post",
|
|
919
|
+
this.emit("post", postEvent);
|
|
912
920
|
const onPosted = (txHash, error) => {
|
|
913
921
|
this.lastPostTime = Date.now();
|
|
914
|
-
const
|
|
922
|
+
const postedEvent = {
|
|
915
923
|
txHash,
|
|
916
924
|
error,
|
|
917
925
|
redeem: {
|
|
@@ -925,30 +933,37 @@ class RelayClient extends EventEmitter__default.default {
|
|
|
925
933
|
};
|
|
926
934
|
const resolveTx = txHash ? (pt) => {
|
|
927
935
|
pt.resolve(txHash);
|
|
928
|
-
const success =
|
|
929
|
-
success.push(
|
|
936
|
+
const success = postedEvent[pt.type].success;
|
|
937
|
+
success.push({
|
|
938
|
+
conditionId: pt.conditionId,
|
|
939
|
+
execCount: pt.execCount,
|
|
940
|
+
done: true
|
|
941
|
+
});
|
|
930
942
|
} : (pt) => {
|
|
931
|
-
|
|
943
|
+
let done;
|
|
944
|
+
if (pt.execCount >= this.options.maxRetry) {
|
|
932
945
|
pt.reject(error);
|
|
933
|
-
|
|
934
|
-
failed.push(pt.conditionId);
|
|
946
|
+
done = true;
|
|
935
947
|
} else {
|
|
936
948
|
this.pendingTransactions.push(pt);
|
|
949
|
+
done = false;
|
|
937
950
|
}
|
|
951
|
+
const failed = postedEvent[pt.type].failed;
|
|
952
|
+
failed.push({
|
|
953
|
+
conditionId: pt.conditionId,
|
|
954
|
+
execCount: pt.execCount,
|
|
955
|
+
done
|
|
956
|
+
});
|
|
938
957
|
};
|
|
939
958
|
for (const pt of transactions) {
|
|
940
|
-
pt.
|
|
959
|
+
pt.execCount++;
|
|
941
960
|
resolveTx(pt);
|
|
942
961
|
}
|
|
943
962
|
logger.info("RelayClient", "post transactions done:");
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
);
|
|
947
|
-
logger.info(
|
|
948
|
-
` - merge: [success: ${postedRet.merge.success.length} failed: ${postedRet.merge.failed.length}]`
|
|
949
|
-
);
|
|
963
|
+
this.logPostedEvent("redeem", postedEvent);
|
|
964
|
+
this.logPostedEvent("merge", postedEvent);
|
|
950
965
|
logger.info(` - pending: ${this.pendingTransactions.length}`);
|
|
951
|
-
this.emit("posted",
|
|
966
|
+
this.emit("posted", postedEvent);
|
|
952
967
|
};
|
|
953
968
|
this.post(postTransactions).then((txHash) => onPosted(txHash)).catch((e) => {
|
|
954
969
|
const requestLimit = this.testRequestLimit(e);
|
|
@@ -1051,7 +1066,7 @@ class RelayClient extends EventEmitter__default.default {
|
|
|
1051
1066
|
type,
|
|
1052
1067
|
conditionId,
|
|
1053
1068
|
transaction,
|
|
1054
|
-
|
|
1069
|
+
execCount: 0,
|
|
1055
1070
|
reject,
|
|
1056
1071
|
resolve
|
|
1057
1072
|
});
|
|
@@ -1261,11 +1276,12 @@ function listenEvent(e, eventName, callback) {
|
|
|
1261
1276
|
}
|
|
1262
1277
|
const DATA_API_HOST = "https://data-api.polymarket.com";
|
|
1263
1278
|
const AUTO_REDEEM_INTERVAL = 60 * 1e3;
|
|
1279
|
+
const TIMEOUT = 15 * 60 * 1e3;
|
|
1264
1280
|
class Redeemer extends EventEmitter__default.default {
|
|
1265
1281
|
options;
|
|
1266
1282
|
running = false;
|
|
1267
1283
|
timer;
|
|
1268
|
-
|
|
1284
|
+
records = /* @__PURE__ */ new Map();
|
|
1269
1285
|
unListenRelayClient;
|
|
1270
1286
|
constructor(options) {
|
|
1271
1287
|
super();
|
|
@@ -1274,25 +1290,31 @@ class Redeemer extends EventEmitter__default.default {
|
|
|
1274
1290
|
}
|
|
1275
1291
|
listenRelayClient() {
|
|
1276
1292
|
const { relayClient } = this.options;
|
|
1277
|
-
const unListenPost = listenEvent(relayClient, "post", ({ redeem }) => {
|
|
1278
|
-
logger.lines(
|
|
1279
|
-
`post redeem(待确认):`,
|
|
1280
|
-
...this.toMessages(this.mapSubmittedPositions(redeem))
|
|
1281
|
-
);
|
|
1282
|
-
});
|
|
1283
1293
|
const unListenPosted = listenEvent(
|
|
1284
1294
|
relayClient,
|
|
1285
1295
|
"posted",
|
|
1286
|
-
({ redeem, error }) => {
|
|
1287
|
-
const
|
|
1288
|
-
|
|
1296
|
+
({ txHash, redeem, error }) => {
|
|
1297
|
+
const pendingEvents = [...redeem.success];
|
|
1298
|
+
for (const r of redeem.failed) if (!r.done) pendingEvents.push(r);
|
|
1299
|
+
const pendingRecords = this.updateEventRecords(pendingEvents);
|
|
1300
|
+
if (pendingRecords.length > 0) {
|
|
1301
|
+
logger.lines(
|
|
1302
|
+
`🟡 redeem 待确认: ${pendingRecords.length} 个`,
|
|
1303
|
+
...this.toMessages(pendingRecords)
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
const failedRecords = this.updateEventRecords(
|
|
1307
|
+
redeem.failed.filter(({ done }) => done)
|
|
1308
|
+
);
|
|
1309
|
+
if (failedRecords.length > 0) {
|
|
1289
1310
|
const messages = [
|
|
1290
|
-
`🔴 redeem
|
|
1291
|
-
...this.toMessages(
|
|
1311
|
+
`🔴 redeem 失败(重试超限): ${failedRecords.length} 个`,
|
|
1312
|
+
...this.toMessages(failedRecords)
|
|
1292
1313
|
];
|
|
1293
|
-
logger.lines(...messages
|
|
1314
|
+
logger.lines(...messages);
|
|
1294
1315
|
telegramService.info(messages.join("\n"));
|
|
1295
1316
|
}
|
|
1317
|
+
logger.info("redeem 提交结果:", txHash || error);
|
|
1296
1318
|
}
|
|
1297
1319
|
);
|
|
1298
1320
|
const unListenRequestLimit = listenEvent(
|
|
@@ -1311,24 +1333,29 @@ class Redeemer extends EventEmitter__default.default {
|
|
|
1311
1333
|
telegramService.info("AutoRedeem 已重启");
|
|
1312
1334
|
});
|
|
1313
1335
|
return () => {
|
|
1314
|
-
unListenPost();
|
|
1315
1336
|
unListenPosted();
|
|
1316
1337
|
unListenRequestLimit();
|
|
1317
1338
|
unListenResets();
|
|
1318
1339
|
};
|
|
1319
1340
|
}
|
|
1320
|
-
|
|
1321
|
-
const
|
|
1322
|
-
for (const
|
|
1323
|
-
const
|
|
1324
|
-
if (
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
logger.error("no submitted failed position", cId);
|
|
1328
|
-
telegramService.error(`no submitted failed position: ${cId}`);
|
|
1341
|
+
updateEventRecords(events) {
|
|
1342
|
+
const records = [];
|
|
1343
|
+
for (const { conditionId, execCount } of events) {
|
|
1344
|
+
const record = this.getRecord(conditionId);
|
|
1345
|
+
if (record) {
|
|
1346
|
+
record.execCount = execCount;
|
|
1347
|
+
records.push(record);
|
|
1329
1348
|
}
|
|
1330
1349
|
}
|
|
1331
|
-
return
|
|
1350
|
+
return records;
|
|
1351
|
+
}
|
|
1352
|
+
getRecord(conditionId) {
|
|
1353
|
+
const record = this.records.get(conditionId);
|
|
1354
|
+
if (!record) {
|
|
1355
|
+
logger.error("no redeem record for", conditionId);
|
|
1356
|
+
telegramService.error(`no redeem record for: ${conditionId}`);
|
|
1357
|
+
}
|
|
1358
|
+
return record;
|
|
1332
1359
|
}
|
|
1333
1360
|
/**
|
|
1334
1361
|
* 获取可 Redeem 的仓位
|
|
@@ -1365,9 +1392,9 @@ class Redeemer extends EventEmitter__default.default {
|
|
|
1365
1392
|
}
|
|
1366
1393
|
return positions;
|
|
1367
1394
|
}
|
|
1368
|
-
toMessages(
|
|
1369
|
-
return
|
|
1370
|
-
(position) => ` - ${position.slug} ${position.outcome}: ${position.currentValue} USDC`
|
|
1395
|
+
toMessages(eventRecords) {
|
|
1396
|
+
return eventRecords.map(
|
|
1397
|
+
({ position, execCount, postSuccessTime }) => ` - ${position.slug} ${position.outcome}: ${position.currentValue} USDC (执行次数: ${execCount} ${postSuccessTime ? `确认时长: ${(Date.now() - postSuccessTime) / 1e3}s` : ""})`
|
|
1371
1398
|
);
|
|
1372
1399
|
}
|
|
1373
1400
|
async autoRedeem() {
|
|
@@ -1378,36 +1405,64 @@ class Redeemer extends EventEmitter__default.default {
|
|
|
1378
1405
|
logger.error("自动 redeem: 获取仓位失败", error);
|
|
1379
1406
|
return;
|
|
1380
1407
|
}
|
|
1408
|
+
const preSize = this.records.size;
|
|
1381
1409
|
for (const position of redeemablePositions) {
|
|
1382
1410
|
const conditionId = position.conditionId;
|
|
1383
|
-
|
|
1411
|
+
let record = this.records.get(conditionId);
|
|
1412
|
+
if (!record) {
|
|
1413
|
+
record = {
|
|
1414
|
+
position,
|
|
1415
|
+
execCount: 0,
|
|
1416
|
+
timeout: false
|
|
1417
|
+
};
|
|
1418
|
+
this.records.set(conditionId, record);
|
|
1384
1419
|
const relayClient = this.options.relayClient;
|
|
1385
|
-
relayClient.submitRedeem(conditionId).
|
|
1420
|
+
relayClient.submitRedeem(conditionId).then(() => {
|
|
1421
|
+
record.postSuccessTime = Date.now();
|
|
1422
|
+
}).catch((error) => {
|
|
1386
1423
|
if (relayClient.isSubmitError(error)) {
|
|
1387
|
-
logger.error("
|
|
1388
|
-
telegramService.error(`
|
|
1424
|
+
logger.error("Redeem 提交失败:", conditionId, error);
|
|
1425
|
+
telegramService.error(`Redeem 提交失败: ${conditionId}`);
|
|
1389
1426
|
}
|
|
1390
1427
|
});
|
|
1391
1428
|
}
|
|
1392
|
-
|
|
1429
|
+
record.position = position;
|
|
1393
1430
|
}
|
|
1394
|
-
const
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1431
|
+
const now = Date.now();
|
|
1432
|
+
const successRecords = [];
|
|
1433
|
+
const timeoutRecords = [];
|
|
1434
|
+
for (const [conditionId, record] of this.records.entries()) {
|
|
1435
|
+
if (redeemablePositions.some((p) => p.conditionId === conditionId)) {
|
|
1436
|
+
if (!record.timeout && record.postSuccessTime && now - record.postSuccessTime >= TIMEOUT) {
|
|
1437
|
+
record.timeout = true;
|
|
1438
|
+
timeoutRecords.push(record);
|
|
1439
|
+
}
|
|
1440
|
+
} else {
|
|
1441
|
+
successRecords.push(record);
|
|
1442
|
+
this.records.delete(conditionId);
|
|
1399
1443
|
}
|
|
1400
1444
|
}
|
|
1401
|
-
if (
|
|
1445
|
+
if (timeoutRecords.length > 0) {
|
|
1402
1446
|
const messages = [
|
|
1403
|
-
|
|
1404
|
-
...this.toMessages(
|
|
1447
|
+
`🔴 redeem 超时: ${timeoutRecords.length} 个`,
|
|
1448
|
+
...this.toMessages(timeoutRecords)
|
|
1405
1449
|
];
|
|
1406
1450
|
logger.lines(...messages);
|
|
1407
1451
|
telegramService.info(messages.join("\n"));
|
|
1408
1452
|
}
|
|
1409
|
-
|
|
1410
|
-
|
|
1453
|
+
if (successRecords.length > 0) {
|
|
1454
|
+
const messages = [
|
|
1455
|
+
`🟢 redeem 成功: ${successRecords.length} 个`,
|
|
1456
|
+
...this.toMessages(successRecords)
|
|
1457
|
+
];
|
|
1458
|
+
logger.lines(...messages);
|
|
1459
|
+
telegramService.info(messages.join("\n"));
|
|
1460
|
+
}
|
|
1461
|
+
const curSize = this.records.size;
|
|
1462
|
+
if (curSize !== preSize) {
|
|
1463
|
+
logger.info(`redeem 待确认总数: ${curSize} 个`);
|
|
1464
|
+
}
|
|
1465
|
+
if (successRecords.length > 0) this.emit("redeemed");
|
|
1411
1466
|
}
|
|
1412
1467
|
start() {
|
|
1413
1468
|
if (this.running) return;
|