@argonprotocol/mainchain 1.1.0-rc.6 → 1.1.0-rc.8
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/README.md +89 -1
- package/lib/cli.cjs +521 -282
- package/lib/cli.cjs.map +1 -1
- package/lib/cli.js +521 -282
- package/lib/cli.js.map +1 -1
- package/lib/clis/index.cjs +521 -282
- package/lib/clis/index.cjs.map +1 -1
- package/lib/clis/index.d.cts +2 -0
- package/lib/clis/index.d.ts +2 -0
- package/lib/clis/index.js +521 -282
- package/lib/clis/index.js.map +1 -1
- package/lib/index.cjs +488 -262
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +305 -203
- package/lib/index.d.ts +305 -203
- package/lib/index.js +485 -262
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/lib/clis/index.cjs
CHANGED
|
@@ -60,8 +60,10 @@ __export(index_exports, {
|
|
|
60
60
|
BitcoinLocks: () => BitcoinLocks,
|
|
61
61
|
BlockWatch: () => BlockWatch,
|
|
62
62
|
CohortBidder: () => CohortBidder,
|
|
63
|
+
ExtrinsicError: () => ExtrinsicError2,
|
|
63
64
|
JsonExt: () => JsonExt,
|
|
64
65
|
Keyring: () => import_api.Keyring,
|
|
66
|
+
MICROGONS_PER_ARGON: () => MICROGONS_PER_ARGON,
|
|
65
67
|
MiningBids: () => MiningBids,
|
|
66
68
|
MiningRotations: () => MiningRotations,
|
|
67
69
|
TxSubmitter: () => TxSubmitter,
|
|
@@ -73,6 +75,7 @@ __export(index_exports, {
|
|
|
73
75
|
convertPermillToBigNumber: () => convertPermillToBigNumber,
|
|
74
76
|
createKeyringPair: () => createKeyringPair,
|
|
75
77
|
decodeAddress: () => import_util_crypto.decodeAddress,
|
|
78
|
+
dispatchErrorToExtrinsicError: () => dispatchErrorToExtrinsicError,
|
|
76
79
|
dispatchErrorToString: () => dispatchErrorToString,
|
|
77
80
|
eventDataToJson: () => eventDataToJson,
|
|
78
81
|
filterUndefined: () => filterUndefined,
|
|
@@ -171,119 +174,6 @@ var WageProtector = class _WageProtector {
|
|
|
171
174
|
}
|
|
172
175
|
};
|
|
173
176
|
|
|
174
|
-
// src/utils.ts
|
|
175
|
-
var BN = __toESM(require("bignumber.js"), 1);
|
|
176
|
-
var { ROUND_FLOOR } = BN;
|
|
177
|
-
function formatArgons(x) {
|
|
178
|
-
const isNegative = x < 0;
|
|
179
|
-
let format = (0, BN.default)(x.toString()).abs().div(1e6).toFormat(2, ROUND_FLOOR);
|
|
180
|
-
if (format.endsWith(".00")) {
|
|
181
|
-
format = format.slice(0, -3);
|
|
182
|
-
}
|
|
183
|
-
return `${isNegative ? "-" : ""}\u20B3${format}`;
|
|
184
|
-
}
|
|
185
|
-
function formatPercent(x) {
|
|
186
|
-
if (!x) return "na";
|
|
187
|
-
return `${x.times(100).decimalPlaces(3)}%`;
|
|
188
|
-
}
|
|
189
|
-
function filterUndefined(obj) {
|
|
190
|
-
return Object.fromEntries(
|
|
191
|
-
Object.entries(obj).filter(
|
|
192
|
-
([_, value]) => value !== void 0 && value !== null
|
|
193
|
-
)
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
async function gettersToObject(obj) {
|
|
197
|
-
if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
|
|
198
|
-
const keys = [];
|
|
199
|
-
for (const key in obj) {
|
|
200
|
-
keys.push(key);
|
|
201
|
-
}
|
|
202
|
-
if (Symbol.iterator in obj) {
|
|
203
|
-
const iterableToArray = [];
|
|
204
|
-
for (const item of obj) {
|
|
205
|
-
iterableToArray.push(await gettersToObject(item));
|
|
206
|
-
}
|
|
207
|
-
return iterableToArray;
|
|
208
|
-
}
|
|
209
|
-
const result = {};
|
|
210
|
-
for (const key of keys) {
|
|
211
|
-
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
212
|
-
if (descriptor && typeof descriptor.value === "function") {
|
|
213
|
-
continue;
|
|
214
|
-
}
|
|
215
|
-
const value = descriptor && descriptor.get ? descriptor.get.call(obj) : obj[key];
|
|
216
|
-
if (typeof value === "function") continue;
|
|
217
|
-
result[key] = await gettersToObject(value);
|
|
218
|
-
}
|
|
219
|
-
return result;
|
|
220
|
-
}
|
|
221
|
-
function convertFixedU128ToBigNumber(fixedU128) {
|
|
222
|
-
const decimalFactor = new BN.default(10).pow(new BN.default(18));
|
|
223
|
-
const rawValue = new BN.default(fixedU128.toString());
|
|
224
|
-
return rawValue.div(decimalFactor);
|
|
225
|
-
}
|
|
226
|
-
function convertPermillToBigNumber(permill) {
|
|
227
|
-
const decimalFactor = new BN.default(1e6);
|
|
228
|
-
const rawValue = new BN.default(permill.toString());
|
|
229
|
-
return rawValue.div(decimalFactor);
|
|
230
|
-
}
|
|
231
|
-
function eventDataToJson(event) {
|
|
232
|
-
const obj = {};
|
|
233
|
-
event.data.forEach((data, index) => {
|
|
234
|
-
const name = event.data.names?.[index];
|
|
235
|
-
obj[name ?? `${index}`] = data.toJSON();
|
|
236
|
-
});
|
|
237
|
-
return obj;
|
|
238
|
-
}
|
|
239
|
-
function dispatchErrorToString(client, error) {
|
|
240
|
-
let message = error.toString();
|
|
241
|
-
if (error.isModule) {
|
|
242
|
-
const decoded = client.registry.findMetaError(error.asModule);
|
|
243
|
-
const { docs, name, section } = decoded;
|
|
244
|
-
message = `${section}.${name}: ${docs.join(" ")}`;
|
|
245
|
-
}
|
|
246
|
-
return message;
|
|
247
|
-
}
|
|
248
|
-
function checkForExtrinsicSuccess(events, client) {
|
|
249
|
-
return new Promise((resolve, reject) => {
|
|
250
|
-
for (const { event } of events) {
|
|
251
|
-
if (client.events.system.ExtrinsicSuccess.is(event)) {
|
|
252
|
-
resolve();
|
|
253
|
-
} else if (client.events.system.ExtrinsicFailed.is(event)) {
|
|
254
|
-
const [dispatchError] = event.data;
|
|
255
|
-
let errorInfo = dispatchError.toString();
|
|
256
|
-
if (dispatchError.isModule) {
|
|
257
|
-
const decoded = client.registry.findMetaError(dispatchError.asModule);
|
|
258
|
-
errorInfo = `${decoded.section}.${decoded.name}`;
|
|
259
|
-
}
|
|
260
|
-
reject(
|
|
261
|
-
new Error(
|
|
262
|
-
`${event.section}.${event.method}:: ExtrinsicFailed:: ${errorInfo}`
|
|
263
|
-
)
|
|
264
|
-
);
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
var JsonExt = class {
|
|
270
|
-
static stringify(obj, space) {
|
|
271
|
-
return JSON.stringify(
|
|
272
|
-
obj,
|
|
273
|
-
(_, v) => typeof v === "bigint" ? `${v}n` : v,
|
|
274
|
-
space
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
|
-
static parse(str) {
|
|
278
|
-
return JSON.parse(str, (_, v) => {
|
|
279
|
-
if (typeof v === "string" && v.endsWith("n")) {
|
|
280
|
-
return BigInt(v.slice(0, -1));
|
|
281
|
-
}
|
|
282
|
-
return v;
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
};
|
|
286
|
-
|
|
287
177
|
// src/TxSubmitter.ts
|
|
288
178
|
function logExtrinsicResult(result) {
|
|
289
179
|
if (process.env.DEBUG) {
|
|
@@ -415,13 +305,12 @@ var TxResult = class {
|
|
|
415
305
|
}
|
|
416
306
|
}
|
|
417
307
|
if (encounteredError) {
|
|
418
|
-
const error =
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
this.reject(new Error(`Transaction failed: ${error}`));
|
|
308
|
+
const error = dispatchErrorToExtrinsicError(
|
|
309
|
+
this.client,
|
|
310
|
+
encounteredError,
|
|
311
|
+
batchErrorIndex
|
|
312
|
+
);
|
|
313
|
+
this.reject(error);
|
|
425
314
|
} else {
|
|
426
315
|
this.inBlockResolve(status.asInBlock.toU8a());
|
|
427
316
|
}
|
|
@@ -436,6 +325,147 @@ var TxResult = class {
|
|
|
436
325
|
}
|
|
437
326
|
};
|
|
438
327
|
|
|
328
|
+
// src/utils.ts
|
|
329
|
+
var BN = __toESM(require("bignumber.js"), 1);
|
|
330
|
+
var { ROUND_FLOOR } = BN;
|
|
331
|
+
var MICROGONS_PER_ARGON = 1e6;
|
|
332
|
+
function formatArgons(x) {
|
|
333
|
+
if (x === void 0 || x === null) return "na";
|
|
334
|
+
const isNegative = x < 0;
|
|
335
|
+
let format = (0, BN.default)(x.toString()).abs().div(MICROGONS_PER_ARGON).toFormat(2, ROUND_FLOOR);
|
|
336
|
+
if (format.endsWith(".00")) {
|
|
337
|
+
format = format.slice(0, -3);
|
|
338
|
+
}
|
|
339
|
+
return `${isNegative ? "-" : ""}\u20B3${format}`;
|
|
340
|
+
}
|
|
341
|
+
function formatPercent(x) {
|
|
342
|
+
if (!x) return "na";
|
|
343
|
+
return `${x.times(100).decimalPlaces(3)}%`;
|
|
344
|
+
}
|
|
345
|
+
function filterUndefined(obj) {
|
|
346
|
+
return Object.fromEntries(
|
|
347
|
+
Object.entries(obj).filter(
|
|
348
|
+
([_, value]) => value !== void 0 && value !== null
|
|
349
|
+
)
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
async function gettersToObject(obj) {
|
|
353
|
+
if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
|
|
354
|
+
const keys = [];
|
|
355
|
+
for (const key in obj) {
|
|
356
|
+
keys.push(key);
|
|
357
|
+
}
|
|
358
|
+
if (Symbol.iterator in obj) {
|
|
359
|
+
const iterableToArray = [];
|
|
360
|
+
for (const item of obj) {
|
|
361
|
+
iterableToArray.push(await gettersToObject(item));
|
|
362
|
+
}
|
|
363
|
+
return iterableToArray;
|
|
364
|
+
}
|
|
365
|
+
const result = {};
|
|
366
|
+
for (const key of keys) {
|
|
367
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
368
|
+
if (descriptor && typeof descriptor.value === "function") {
|
|
369
|
+
continue;
|
|
370
|
+
}
|
|
371
|
+
const value = descriptor && descriptor.get ? descriptor.get.call(obj) : obj[key];
|
|
372
|
+
if (typeof value === "function") continue;
|
|
373
|
+
result[key] = await gettersToObject(value);
|
|
374
|
+
}
|
|
375
|
+
return result;
|
|
376
|
+
}
|
|
377
|
+
function convertFixedU128ToBigNumber(fixedU128) {
|
|
378
|
+
const decimalFactor = new BN.default(10).pow(new BN.default(18));
|
|
379
|
+
const rawValue = new BN.default(fixedU128.toString());
|
|
380
|
+
return rawValue.div(decimalFactor);
|
|
381
|
+
}
|
|
382
|
+
function convertPermillToBigNumber(permill) {
|
|
383
|
+
const decimalFactor = new BN.default(1e6);
|
|
384
|
+
const rawValue = new BN.default(permill.toString());
|
|
385
|
+
return rawValue.div(decimalFactor);
|
|
386
|
+
}
|
|
387
|
+
function eventDataToJson(event) {
|
|
388
|
+
const obj = {};
|
|
389
|
+
event.data.forEach((data, index) => {
|
|
390
|
+
const name = event.data.names?.[index];
|
|
391
|
+
obj[name ?? `${index}`] = data.toJSON();
|
|
392
|
+
});
|
|
393
|
+
return obj;
|
|
394
|
+
}
|
|
395
|
+
function dispatchErrorToString(client, error) {
|
|
396
|
+
let message = error.toString();
|
|
397
|
+
if (error.isModule) {
|
|
398
|
+
const decoded = client.registry.findMetaError(error.asModule);
|
|
399
|
+
const { docs, name, section } = decoded;
|
|
400
|
+
message = `${section}.${name}: ${docs.join(" ")}`;
|
|
401
|
+
}
|
|
402
|
+
return message;
|
|
403
|
+
}
|
|
404
|
+
var ExtrinsicError2 = class extends Error {
|
|
405
|
+
constructor(errorCode, details, batchInterruptedIndex) {
|
|
406
|
+
super(errorCode);
|
|
407
|
+
this.errorCode = errorCode;
|
|
408
|
+
this.details = details;
|
|
409
|
+
this.batchInterruptedIndex = batchInterruptedIndex;
|
|
410
|
+
}
|
|
411
|
+
toString() {
|
|
412
|
+
if (this.batchInterruptedIndex !== void 0) {
|
|
413
|
+
return `${this.errorCode} ${this.details ?? ""} (Batch interrupted at index ${this.batchInterruptedIndex})`;
|
|
414
|
+
}
|
|
415
|
+
return `${this.errorCode} ${this.details ?? ""}`;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
function dispatchErrorToExtrinsicError(client, error, batchInterruptedIndex) {
|
|
419
|
+
if (error.isModule) {
|
|
420
|
+
const decoded = client.registry.findMetaError(error.asModule);
|
|
421
|
+
const { docs, name, section } = decoded;
|
|
422
|
+
return new ExtrinsicError2(
|
|
423
|
+
`${section}.${name}`,
|
|
424
|
+
docs.join(" "),
|
|
425
|
+
batchInterruptedIndex
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
return new ExtrinsicError2(error.toString(), void 0, batchInterruptedIndex);
|
|
429
|
+
}
|
|
430
|
+
function checkForExtrinsicSuccess(events, client) {
|
|
431
|
+
return new Promise((resolve, reject) => {
|
|
432
|
+
for (const { event } of events) {
|
|
433
|
+
if (client.events.system.ExtrinsicSuccess.is(event)) {
|
|
434
|
+
resolve();
|
|
435
|
+
} else if (client.events.system.ExtrinsicFailed.is(event)) {
|
|
436
|
+
const [dispatchError] = event.data;
|
|
437
|
+
let errorInfo = dispatchError.toString();
|
|
438
|
+
if (dispatchError.isModule) {
|
|
439
|
+
const decoded = client.registry.findMetaError(dispatchError.asModule);
|
|
440
|
+
errorInfo = `${decoded.section}.${decoded.name}`;
|
|
441
|
+
}
|
|
442
|
+
reject(
|
|
443
|
+
new Error(
|
|
444
|
+
`${event.section}.${event.method}:: ExtrinsicFailed:: ${errorInfo}`
|
|
445
|
+
)
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
var JsonExt = class {
|
|
452
|
+
static stringify(obj, space) {
|
|
453
|
+
return JSON.stringify(
|
|
454
|
+
obj,
|
|
455
|
+
(_, v) => typeof v === "bigint" ? `${v}n` : v,
|
|
456
|
+
space
|
|
457
|
+
);
|
|
458
|
+
}
|
|
459
|
+
static parse(str) {
|
|
460
|
+
return JSON.parse(str, (_, v) => {
|
|
461
|
+
if (typeof v === "string" && v.endsWith("n")) {
|
|
462
|
+
return BigInt(v.slice(0, -1));
|
|
463
|
+
}
|
|
464
|
+
return v;
|
|
465
|
+
});
|
|
466
|
+
}
|
|
467
|
+
};
|
|
468
|
+
|
|
439
469
|
// src/AccountRegistry.ts
|
|
440
470
|
var AccountRegistry = class _AccountRegistry {
|
|
441
471
|
namedAccounts = /* @__PURE__ */ new Map();
|
|
@@ -668,7 +698,7 @@ var MiningRotations = class {
|
|
|
668
698
|
const slot1StartTick = this.genesisTick + this.miningConfig.slotBiddingStartAfterTicks + ticksBetweenSlots;
|
|
669
699
|
if (tick < slot1StartTick) return 0;
|
|
670
700
|
const ticksSinceSlot1 = tick - slot1StartTick;
|
|
671
|
-
return Math.floor(ticksSinceSlot1 / ticksBetweenSlots);
|
|
701
|
+
return Math.floor(ticksSinceSlot1 / ticksBetweenSlots) + 1;
|
|
672
702
|
}
|
|
673
703
|
async getForHeader(client, header) {
|
|
674
704
|
if (header.number.toNumber() === 0) return 0;
|
|
@@ -848,6 +878,14 @@ var Accountset = class {
|
|
|
848
878
|
);
|
|
849
879
|
}
|
|
850
880
|
}
|
|
881
|
+
async submitterBalance(blockHash) {
|
|
882
|
+
const client = await this.client;
|
|
883
|
+
const api = blockHash ? await client.at(blockHash) : client;
|
|
884
|
+
const accountData = await api.query.system.account(
|
|
885
|
+
this.txSubmitterPair.address
|
|
886
|
+
);
|
|
887
|
+
return accountData.data.free.toBigInt();
|
|
888
|
+
}
|
|
851
889
|
async balance(blockHash) {
|
|
852
890
|
const client = await this.client;
|
|
853
891
|
const api = blockHash ? await client.at(blockHash) : client;
|
|
@@ -1110,18 +1148,18 @@ var Accountset = class {
|
|
|
1110
1148
|
return new TxSubmitter(client, tx, this.txSubmitterPair);
|
|
1111
1149
|
}
|
|
1112
1150
|
/**
|
|
1113
|
-
* Create
|
|
1151
|
+
* Create but don't submit a mining bid transaction.
|
|
1152
|
+
* @param options
|
|
1114
1153
|
*/
|
|
1115
|
-
async
|
|
1116
|
-
const accounts = this.getAccountsInRange(options.subaccountRange);
|
|
1154
|
+
async createMiningBidTx(options) {
|
|
1117
1155
|
const client = await this.client;
|
|
1118
|
-
|
|
1156
|
+
const { bidAmount, subaccounts, sendRewardsToSeed } = options;
|
|
1119
1157
|
const batch = client.tx.utility.batch(
|
|
1120
|
-
|
|
1158
|
+
subaccounts.map((x) => {
|
|
1121
1159
|
const keys = this.keys();
|
|
1122
|
-
const rewards =
|
|
1160
|
+
const rewards = sendRewardsToSeed ? { Account: this.seedAddress } : { Owner: null };
|
|
1123
1161
|
return client.tx.miningSlot.bid(
|
|
1124
|
-
|
|
1162
|
+
bidAmount,
|
|
1125
1163
|
rewards,
|
|
1126
1164
|
{
|
|
1127
1165
|
grandpa: keys.gran.rawPublicKey,
|
|
@@ -1135,7 +1173,19 @@ var Accountset = class {
|
|
|
1135
1173
|
if (this.isProxy) {
|
|
1136
1174
|
tx = client.tx.proxy.proxy(this.seedAddress, "MiningBid", batch);
|
|
1137
1175
|
}
|
|
1138
|
-
|
|
1176
|
+
return new TxSubmitter(client, tx, this.txSubmitterPair);
|
|
1177
|
+
}
|
|
1178
|
+
/**
|
|
1179
|
+
* Create a mining bid. This will create a bid for each account in the given range from the seed account as funding.
|
|
1180
|
+
*/
|
|
1181
|
+
async createMiningBids(options) {
|
|
1182
|
+
const accounts = this.getAccountsInRange(options.subaccountRange);
|
|
1183
|
+
const client = await this.client;
|
|
1184
|
+
const submitter = await this.createMiningBidTx({
|
|
1185
|
+
...options,
|
|
1186
|
+
subaccounts: accounts
|
|
1187
|
+
});
|
|
1188
|
+
const { tip = 0n } = options;
|
|
1139
1189
|
const txFee = await submitter.feeEstimate(tip);
|
|
1140
1190
|
let minBalance = options.bidAmount * BigInt(accounts.length);
|
|
1141
1191
|
let totalFees = tip + 1n + txFee;
|
|
@@ -1579,27 +1629,24 @@ var VaultMonitor = class {
|
|
|
1579
1629
|
}
|
|
1580
1630
|
};
|
|
1581
1631
|
|
|
1582
|
-
// src/
|
|
1583
|
-
var
|
|
1584
|
-
constructor(
|
|
1585
|
-
this.accountset = accountset;
|
|
1632
|
+
// src/CohortBidderHistory.ts
|
|
1633
|
+
var CohortBidderHistory = class _CohortBidderHistory {
|
|
1634
|
+
constructor(cohortId, subaccounts) {
|
|
1586
1635
|
this.cohortId = cohortId;
|
|
1587
1636
|
this.subaccounts = subaccounts;
|
|
1588
|
-
this.
|
|
1637
|
+
this.maxSeatsInPlay = this.subaccounts.length;
|
|
1589
1638
|
this.subaccounts.forEach((x) => {
|
|
1590
|
-
this.
|
|
1639
|
+
this.myAddresses.add(x.address);
|
|
1591
1640
|
});
|
|
1592
1641
|
}
|
|
1593
|
-
|
|
1594
|
-
return this.accountset.client;
|
|
1595
|
-
}
|
|
1642
|
+
bidHistory = [];
|
|
1596
1643
|
stats = {
|
|
1597
1644
|
// number of seats won
|
|
1598
|
-
|
|
1645
|
+
seatsWon: 0,
|
|
1599
1646
|
// sum of argons bid in successful bids
|
|
1600
1647
|
totalArgonsBid: 0n,
|
|
1601
1648
|
// total number of bids placed (includes 1 per seat)
|
|
1602
|
-
|
|
1649
|
+
bidsAttempted: 0,
|
|
1603
1650
|
// fees including the tip
|
|
1604
1651
|
fees: 0n,
|
|
1605
1652
|
// Max bid per seat
|
|
@@ -1611,16 +1658,157 @@ var CohortBidder = class _CohortBidder {
|
|
|
1611
1658
|
// The cohort expected argons per block
|
|
1612
1659
|
cohortArgonsPerBlock: 0n,
|
|
1613
1660
|
// The last block that bids are synced to
|
|
1614
|
-
|
|
1661
|
+
lastBlockNumber: 0
|
|
1615
1662
|
};
|
|
1663
|
+
lastBids = [];
|
|
1664
|
+
myAddresses = /* @__PURE__ */ new Set();
|
|
1665
|
+
maxSeatsInPlay = 0;
|
|
1666
|
+
async init(client) {
|
|
1667
|
+
if (!this.stats.argonotsPerSeat) {
|
|
1668
|
+
const startingStats = await _CohortBidderHistory.getStartingData(client);
|
|
1669
|
+
Object.assign(this.stats, startingStats);
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
maybeReducingSeats(maxSeats, reason, historyEntry) {
|
|
1673
|
+
if (this.maxSeatsInPlay > maxSeats) {
|
|
1674
|
+
historyEntry.maxSeatsReductionReason = reason;
|
|
1675
|
+
}
|
|
1676
|
+
this.maxSeatsInPlay = maxSeats;
|
|
1677
|
+
historyEntry.maxSeatsInPlay = maxSeats;
|
|
1678
|
+
}
|
|
1679
|
+
trackChange(next, blockNumber, tick, isLastEntry = false) {
|
|
1680
|
+
let winningBids = 0;
|
|
1681
|
+
let totalArgonsBid = 0n;
|
|
1682
|
+
const nextEntrants = [];
|
|
1683
|
+
for (const x of next) {
|
|
1684
|
+
const bid = x.bid.toBigInt();
|
|
1685
|
+
const address = x.accountId.toHuman();
|
|
1686
|
+
nextEntrants.push({ address, bid });
|
|
1687
|
+
if (this.myAddresses.has(address)) {
|
|
1688
|
+
winningBids++;
|
|
1689
|
+
totalArgonsBid += bid;
|
|
1690
|
+
}
|
|
1691
|
+
}
|
|
1692
|
+
this.stats.seatsWon = winningBids;
|
|
1693
|
+
this.stats.totalArgonsBid = totalArgonsBid;
|
|
1694
|
+
this.stats.lastBlockNumber = Math.max(
|
|
1695
|
+
blockNumber,
|
|
1696
|
+
this.stats.lastBlockNumber
|
|
1697
|
+
);
|
|
1698
|
+
const historyEntry = {
|
|
1699
|
+
cohortId: this.cohortId,
|
|
1700
|
+
blockNumber,
|
|
1701
|
+
tick,
|
|
1702
|
+
bidChanges: [],
|
|
1703
|
+
winningSeats: winningBids,
|
|
1704
|
+
maxSeatsInPlay: this.maxSeatsInPlay
|
|
1705
|
+
};
|
|
1706
|
+
const hasDiffs = JsonExt.stringify(nextEntrants) !== JsonExt.stringify(this.lastBids);
|
|
1707
|
+
if (!isLastEntry || hasDiffs) {
|
|
1708
|
+
this.bidHistory.unshift(historyEntry);
|
|
1709
|
+
}
|
|
1710
|
+
if (hasDiffs) {
|
|
1711
|
+
nextEntrants.forEach(({ address, bid }, i) => {
|
|
1712
|
+
const prevBidIndex = this.lastBids.findIndex(
|
|
1713
|
+
(y) => y.address === address
|
|
1714
|
+
);
|
|
1715
|
+
const entry = {
|
|
1716
|
+
address,
|
|
1717
|
+
bidAmount: bid,
|
|
1718
|
+
bidPosition: i,
|
|
1719
|
+
prevPosition: prevBidIndex === -1 ? null : prevBidIndex
|
|
1720
|
+
};
|
|
1721
|
+
if (prevBidIndex !== -1) {
|
|
1722
|
+
const prevBidAmount = this.lastBids[prevBidIndex].bid;
|
|
1723
|
+
if (prevBidAmount !== bid) {
|
|
1724
|
+
entry.prevBidAmount = prevBidAmount;
|
|
1725
|
+
}
|
|
1726
|
+
}
|
|
1727
|
+
historyEntry.bidChanges.push(entry);
|
|
1728
|
+
});
|
|
1729
|
+
this.lastBids.forEach(({ address, bid }, i) => {
|
|
1730
|
+
const nextBid = nextEntrants.some((y) => y.address === address);
|
|
1731
|
+
if (!nextBid) {
|
|
1732
|
+
historyEntry.bidChanges.push({
|
|
1733
|
+
address,
|
|
1734
|
+
bidAmount: bid,
|
|
1735
|
+
bidPosition: null,
|
|
1736
|
+
prevPosition: i
|
|
1737
|
+
});
|
|
1738
|
+
}
|
|
1739
|
+
});
|
|
1740
|
+
this.lastBids = nextEntrants;
|
|
1741
|
+
}
|
|
1742
|
+
return historyEntry;
|
|
1743
|
+
}
|
|
1744
|
+
onBidResult(historyEntry, param) {
|
|
1745
|
+
const {
|
|
1746
|
+
txFeePlusTip,
|
|
1747
|
+
bidPerSeat,
|
|
1748
|
+
bidsAttempted,
|
|
1749
|
+
successfulBids,
|
|
1750
|
+
blockNumber,
|
|
1751
|
+
bidError
|
|
1752
|
+
} = param;
|
|
1753
|
+
this.stats.fees += txFeePlusTip;
|
|
1754
|
+
this.stats.bidsAttempted += bidsAttempted;
|
|
1755
|
+
if (bidPerSeat > this.stats.maxBidPerSeat) {
|
|
1756
|
+
this.stats.maxBidPerSeat = bidPerSeat;
|
|
1757
|
+
}
|
|
1758
|
+
if (blockNumber !== void 0) {
|
|
1759
|
+
this.stats.lastBlockNumber = Math.max(
|
|
1760
|
+
blockNumber,
|
|
1761
|
+
this.stats.lastBlockNumber
|
|
1762
|
+
);
|
|
1763
|
+
}
|
|
1764
|
+
historyEntry.myBidsPlaced.failureReason = bidError;
|
|
1765
|
+
historyEntry.myBidsPlaced.successfulBids = successfulBids;
|
|
1766
|
+
historyEntry.myBidsPlaced.txFeePlusTip = txFeePlusTip;
|
|
1767
|
+
}
|
|
1768
|
+
static async getStartingData(api) {
|
|
1769
|
+
const argonotPrice = await api.query.priceIndex.current();
|
|
1770
|
+
let argonotUsdPrice = 0;
|
|
1771
|
+
if (argonotPrice.isSome) {
|
|
1772
|
+
argonotUsdPrice = convertFixedU128ToBigNumber(
|
|
1773
|
+
argonotPrice.unwrap().argonotUsdPrice.toBigInt()
|
|
1774
|
+
).toNumber();
|
|
1775
|
+
}
|
|
1776
|
+
const argonotsPerSeat = await api.query.miningSlot.argonotsPerMiningSeat().then((x) => x.toBigInt());
|
|
1777
|
+
const cohortArgonsPerBlock = await api.query.blockRewards.argonsPerBlock().then((x) => x.toBigInt());
|
|
1778
|
+
return { argonotsPerSeat, argonotUsdPrice, cohortArgonsPerBlock };
|
|
1779
|
+
}
|
|
1780
|
+
};
|
|
1781
|
+
|
|
1782
|
+
// src/CohortBidder.ts
|
|
1783
|
+
var CohortBidder = class {
|
|
1784
|
+
constructor(accountset, cohortId, subaccounts, options) {
|
|
1785
|
+
this.accountset = accountset;
|
|
1786
|
+
this.cohortId = cohortId;
|
|
1787
|
+
this.subaccounts = subaccounts;
|
|
1788
|
+
this.options = options;
|
|
1789
|
+
this.history = new CohortBidderHistory(cohortId, subaccounts);
|
|
1790
|
+
this.subaccounts.forEach((x) => {
|
|
1791
|
+
this.myAddresses.add(x.address);
|
|
1792
|
+
});
|
|
1793
|
+
}
|
|
1794
|
+
get client() {
|
|
1795
|
+
return this.accountset.client;
|
|
1796
|
+
}
|
|
1797
|
+
get stats() {
|
|
1798
|
+
return this.history.stats;
|
|
1799
|
+
}
|
|
1800
|
+
get bidHistory() {
|
|
1801
|
+
return this.history.bidHistory;
|
|
1802
|
+
}
|
|
1616
1803
|
unsubscribe;
|
|
1617
1804
|
pendingRequest;
|
|
1618
1805
|
retryTimeout;
|
|
1619
1806
|
isStopped = false;
|
|
1620
1807
|
needsRebid = false;
|
|
1621
1808
|
lastBidTime = 0;
|
|
1809
|
+
history;
|
|
1622
1810
|
millisPerTick;
|
|
1623
|
-
|
|
1811
|
+
myAddresses = /* @__PURE__ */ new Set();
|
|
1624
1812
|
async stop() {
|
|
1625
1813
|
if (this.isStopped) return this.stats;
|
|
1626
1814
|
this.isStopped = true;
|
|
@@ -1630,70 +1818,59 @@ var CohortBidder = class _CohortBidder {
|
|
|
1630
1818
|
this.unsubscribe();
|
|
1631
1819
|
}
|
|
1632
1820
|
const client = await this.client;
|
|
1633
|
-
const [
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1821
|
+
const [nextCohortId, isBiddingOpen] = await client.queryMulti([
|
|
1822
|
+
client.query.miningSlot.nextCohortId,
|
|
1823
|
+
client.query.miningSlot.isNextSlotBiddingOpen
|
|
1824
|
+
]);
|
|
1825
|
+
if (nextCohortId.toNumber() === this.cohortId && isBiddingOpen.isTrue) {
|
|
1826
|
+
console.log("Bidding is still open, waiting for it to close");
|
|
1827
|
+
await new Promise(async (resolve) => {
|
|
1828
|
+
const unsub = await client.query.miningSlot.isNextSlotBiddingOpen(
|
|
1829
|
+
(isOpen) => {
|
|
1830
|
+
if (isOpen.isFalse) {
|
|
1831
|
+
unsub();
|
|
1832
|
+
resolve();
|
|
1833
|
+
}
|
|
1645
1834
|
}
|
|
1646
|
-
|
|
1647
|
-
);
|
|
1648
|
-
});
|
|
1649
|
-
void await this.pendingRequest;
|
|
1650
|
-
if (nextCohortId.toNumber() === this.cohortId) {
|
|
1651
|
-
console.log("Bidder updating stats with bid queue");
|
|
1652
|
-
this.updateStats(nextCohort);
|
|
1653
|
-
} else {
|
|
1654
|
-
const bestBlock = await client.rpc.chain.getBlockHash();
|
|
1655
|
-
const api = await client.at(bestBlock);
|
|
1656
|
-
const wonIndices = await api.query.miningSlot.accountIndexLookup.multi([...this.allAddresses]).then((x) => x.filter((x2) => x2.isSome).map((x2) => x2.value));
|
|
1657
|
-
const wonSeats = await api.query.miningSlot.activeMinersByIndex.multi(wonIndices).then(
|
|
1658
|
-
(x) => x.filter(
|
|
1659
|
-
(x2) => x2.isSome && x2.value.cohortId.toNumber() === this.cohortId
|
|
1660
|
-
).map((x2) => x2.value)
|
|
1661
|
-
);
|
|
1662
|
-
console.log("Bidder updating stats with finalized cohort");
|
|
1663
|
-
this.updateStats(wonSeats);
|
|
1835
|
+
);
|
|
1836
|
+
});
|
|
1664
1837
|
}
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1838
|
+
void await this.pendingRequest;
|
|
1839
|
+
let header = await client.rpc.chain.getHeader();
|
|
1840
|
+
while (true) {
|
|
1841
|
+
const api2 = await client.at(header.hash);
|
|
1842
|
+
const cohortId = await api2.query.miningSlot.nextCohortId();
|
|
1843
|
+
if (cohortId.toNumber() === this.cohortId) {
|
|
1844
|
+
break;
|
|
1845
|
+
}
|
|
1846
|
+
header = await client.rpc.chain.getHeader(header.parentHash);
|
|
1847
|
+
}
|
|
1848
|
+
const api = await client.at(header.hash);
|
|
1849
|
+
const tick = await api.query.ticks.currentTick().then((x) => x.toNumber());
|
|
1850
|
+
const cohort = await api.query.miningSlot.nextSlotCohort();
|
|
1851
|
+
this.history.trackChange(cohort, header.number.toNumber(), tick, true);
|
|
1852
|
+
console.log("Bidder stopped", {
|
|
1853
|
+
cohortId: this.cohortId,
|
|
1854
|
+
blockNumber: header.number.toNumber(),
|
|
1855
|
+
tick,
|
|
1856
|
+
cohort: cohort.map((x) => ({
|
|
1857
|
+
address: x.accountId.toHuman(),
|
|
1858
|
+
bid: x.bid.toBigInt()
|
|
1859
|
+
}))
|
|
1860
|
+
});
|
|
1669
1861
|
return this.stats;
|
|
1670
1862
|
}
|
|
1671
|
-
static async getStartingData(api) {
|
|
1672
|
-
const argonotPrice = await api.query.priceIndex.current();
|
|
1673
|
-
let argonotUsdPrice = 0;
|
|
1674
|
-
if (argonotPrice.isSome) {
|
|
1675
|
-
argonotUsdPrice = convertFixedU128ToBigNumber(
|
|
1676
|
-
argonotPrice.unwrap().argonotUsdPrice.toBigInt()
|
|
1677
|
-
).toNumber();
|
|
1678
|
-
}
|
|
1679
|
-
const argonotsPerSeat = await api.query.miningSlot.argonotsPerMiningSeat().then((x) => x.toBigInt());
|
|
1680
|
-
const cohortArgonsPerBlock = await api.query.blockRewards.argonsPerBlock().then((x) => x.toBigInt());
|
|
1681
|
-
return { argonotsPerSeat, argonotUsdPrice, cohortArgonsPerBlock };
|
|
1682
|
-
}
|
|
1683
1863
|
async start() {
|
|
1684
1864
|
console.log(`Starting cohort ${this.cohortId} bidder`, {
|
|
1685
1865
|
maxBid: formatArgons(this.options.maxBid),
|
|
1686
1866
|
minBid: formatArgons(this.options.minBid),
|
|
1687
1867
|
bidIncrement: formatArgons(this.options.bidIncrement),
|
|
1688
|
-
|
|
1868
|
+
maxBudget: formatArgons(this.options.maxBudget),
|
|
1689
1869
|
bidDelay: this.options.bidDelay,
|
|
1690
1870
|
subaccounts: this.subaccounts
|
|
1691
1871
|
});
|
|
1692
1872
|
const client = await this.client;
|
|
1693
|
-
|
|
1694
|
-
const startingStats = await _CohortBidder.getStartingData(client);
|
|
1695
|
-
Object.assign(this.stats, startingStats);
|
|
1696
|
-
}
|
|
1873
|
+
await this.history.init(client);
|
|
1697
1874
|
this.millisPerTick ??= await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber());
|
|
1698
1875
|
this.unsubscribe = await client.queryMulti(
|
|
1699
1876
|
[
|
|
@@ -1707,24 +1884,27 @@ var CohortBidder = class _CohortBidder {
|
|
|
1707
1884
|
}
|
|
1708
1885
|
);
|
|
1709
1886
|
}
|
|
1710
|
-
updateStats(next) {
|
|
1711
|
-
let seats = 0;
|
|
1712
|
-
let totalArgonsBid = 0n;
|
|
1713
|
-
for (const x of next) {
|
|
1714
|
-
if (this.allAddresses.has(x.accountId.toHuman())) {
|
|
1715
|
-
seats++;
|
|
1716
|
-
totalArgonsBid += x.bid.toBigInt();
|
|
1717
|
-
}
|
|
1718
|
-
}
|
|
1719
|
-
this.stats.seats = seats;
|
|
1720
|
-
this.stats.totalArgonsBid = totalArgonsBid;
|
|
1721
|
-
}
|
|
1722
1887
|
async checkSeats(next) {
|
|
1723
|
-
if (this.isStopped
|
|
1888
|
+
if (this.isStopped) return;
|
|
1889
|
+
clearTimeout(this.retryTimeout);
|
|
1890
|
+
const client = await this.client;
|
|
1891
|
+
const bestBlock = await client.rpc.chain.getBlockHash();
|
|
1892
|
+
const api = await client.at(bestBlock);
|
|
1893
|
+
const blockNumber = await api.query.system.number().then((x) => x.toNumber());
|
|
1894
|
+
if (this.bidHistory[0]?.blockNumber >= blockNumber) {
|
|
1895
|
+
return;
|
|
1896
|
+
}
|
|
1897
|
+
const tick = await api.query.ticks.currentTick().then((x) => x.toNumber());
|
|
1898
|
+
const historyEntry = this.history.trackChange(next, blockNumber, tick);
|
|
1899
|
+
if (this.pendingRequest) return;
|
|
1724
1900
|
const ticksSinceLastBid = Math.floor(
|
|
1725
1901
|
(Date.now() - this.lastBidTime) / this.millisPerTick
|
|
1726
1902
|
);
|
|
1727
1903
|
if (ticksSinceLastBid < this.options.bidDelay) {
|
|
1904
|
+
this.retryTimeout = setTimeout(
|
|
1905
|
+
() => void this.checkCurrentSeats(),
|
|
1906
|
+
this.millisPerTick
|
|
1907
|
+
);
|
|
1728
1908
|
return;
|
|
1729
1909
|
}
|
|
1730
1910
|
console.log(
|
|
@@ -1732,12 +1912,19 @@ var CohortBidder = class _CohortBidder {
|
|
|
1732
1912
|
this.cohortId,
|
|
1733
1913
|
this.subaccounts.map((x) => x.index)
|
|
1734
1914
|
);
|
|
1735
|
-
|
|
1736
|
-
this.needsRebid = this.subaccounts.
|
|
1737
|
-
(x) => !next.some((y) => y.accountId.toHuman() === x.address)
|
|
1738
|
-
);
|
|
1915
|
+
const winningBids = historyEntry.winningSeats;
|
|
1916
|
+
this.needsRebid = winningBids < this.subaccounts.length;
|
|
1739
1917
|
if (!this.needsRebid) return;
|
|
1740
|
-
const
|
|
1918
|
+
const winningAddresses = new Set(next.map((x) => x.accountId.toHuman()));
|
|
1919
|
+
let lowestBid = -this.options.bidIncrement;
|
|
1920
|
+
if (next.length) {
|
|
1921
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
1922
|
+
if (!this.myAddresses.has(next[i].accountId.toHuman())) {
|
|
1923
|
+
lowestBid = next.at(i).bid.toBigInt();
|
|
1924
|
+
break;
|
|
1925
|
+
}
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1741
1928
|
const MIN_INCREMENT = 10000n;
|
|
1742
1929
|
let nextBid = lowestBid + this.options.bidIncrement;
|
|
1743
1930
|
if (nextBid < this.options.minBid) {
|
|
@@ -1745,83 +1932,119 @@ var CohortBidder = class _CohortBidder {
|
|
|
1745
1932
|
}
|
|
1746
1933
|
if (nextBid > this.options.maxBid) {
|
|
1747
1934
|
nextBid = this.options.maxBid;
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1935
|
+
}
|
|
1936
|
+
const fakeTx = await this.accountset.createMiningBidTx({
|
|
1937
|
+
subaccounts: this.subaccounts,
|
|
1938
|
+
bidAmount: nextBid,
|
|
1939
|
+
sendRewardsToSeed: true
|
|
1940
|
+
});
|
|
1941
|
+
let availableBalanceForBids = await api.query.system.account(this.accountset.txSubmitterPair.address).then((x) => x.data.free.toBigInt());
|
|
1942
|
+
for (const bid of next) {
|
|
1943
|
+
if (this.myAddresses.has(bid.accountId.toHuman())) {
|
|
1944
|
+
availableBalanceForBids += bid.bid.toBigInt();
|
|
1758
1945
|
}
|
|
1759
1946
|
}
|
|
1947
|
+
const tip = this.options.tipPerTransaction ?? 0n;
|
|
1948
|
+
const feeEstimate = await fakeTx.feeEstimate(tip);
|
|
1949
|
+
const feePlusTip = feeEstimate + tip;
|
|
1950
|
+
let budgetForSeats = this.options.maxBudget - feePlusTip;
|
|
1951
|
+
if (budgetForSeats > availableBalanceForBids) {
|
|
1952
|
+
budgetForSeats = availableBalanceForBids - feePlusTip;
|
|
1953
|
+
}
|
|
1760
1954
|
if (nextBid < lowestBid) {
|
|
1761
1955
|
console.log(
|
|
1762
1956
|
`Can't bid ${formatArgons(nextBid)}. Current lowest bid is ${formatArgons(
|
|
1763
1957
|
lowestBid
|
|
1764
1958
|
)}.`
|
|
1765
1959
|
);
|
|
1960
|
+
this.history.maybeReducingSeats(
|
|
1961
|
+
winningBids,
|
|
1962
|
+
"MaxBidTooLow" /* MaxBidTooLow */,
|
|
1963
|
+
historyEntry
|
|
1964
|
+
);
|
|
1766
1965
|
return;
|
|
1767
1966
|
}
|
|
1768
|
-
|
|
1769
|
-
if (seatsInBudget <= 0) {
|
|
1967
|
+
if (nextBid - lowestBid < MIN_INCREMENT) {
|
|
1770
1968
|
console.log(
|
|
1771
|
-
`Can't
|
|
1969
|
+
`Can't make any more bids for ${this.cohortId} with given constraints.`,
|
|
1970
|
+
{
|
|
1971
|
+
lowestCurrentBid: formatArgons(lowestBid),
|
|
1972
|
+
nextAttemptedBid: formatArgons(nextBid),
|
|
1973
|
+
maxBid: formatArgons(this.options.maxBid)
|
|
1974
|
+
}
|
|
1975
|
+
);
|
|
1976
|
+
this.history.maybeReducingSeats(
|
|
1977
|
+
winningBids,
|
|
1978
|
+
"MaxBidTooLow" /* MaxBidTooLow */,
|
|
1979
|
+
historyEntry
|
|
1772
1980
|
);
|
|
1773
1981
|
return;
|
|
1774
1982
|
}
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
if (
|
|
1785
|
-
if (!
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
}
|
|
1789
|
-
const removedIndices = this.subaccounts.filter((x) => !toKeep.some((y) => y.index === x.index)).map((x) => x.index);
|
|
1790
|
-
this.subaccounts = toKeep;
|
|
1791
|
-
console.log("Had to remove some subaccounts to fit in budget:", {
|
|
1792
|
-
removedIndices,
|
|
1793
|
-
seatsInBudget,
|
|
1794
|
-
budget: formatArgons(this.options.maxBalance)
|
|
1983
|
+
const seatsInBudget = nextBid === 0n ? this.subaccounts.length : Number(budgetForSeats / nextBid);
|
|
1984
|
+
let accountsToUse = [...this.subaccounts];
|
|
1985
|
+
if (accountsToUse.length > seatsInBudget) {
|
|
1986
|
+
const reason = availableBalanceForBids - feePlusTip < nextBid * BigInt(seatsInBudget) ? "InsufficientFunds" /* InsufficientFunds */ : "MaxBudgetTooLow" /* MaxBudgetTooLow */;
|
|
1987
|
+
this.history.maybeReducingSeats(seatsInBudget, reason, historyEntry);
|
|
1988
|
+
accountsToUse.sort((a, b) => {
|
|
1989
|
+
const isWinningA = winningAddresses.has(a.address);
|
|
1990
|
+
const isWinningB = winningAddresses.has(b.address);
|
|
1991
|
+
if (isWinningA && !isWinningB) return -1;
|
|
1992
|
+
if (!isWinningA && isWinningB) return 1;
|
|
1993
|
+
if (a.isRebid && !b.isRebid) return -1;
|
|
1994
|
+
if (!a.isRebid && b.isRebid) return 1;
|
|
1995
|
+
return a.index - b.index;
|
|
1795
1996
|
});
|
|
1997
|
+
accountsToUse.length = seatsInBudget;
|
|
1998
|
+
}
|
|
1999
|
+
if (accountsToUse.length > winningBids) {
|
|
2000
|
+
historyEntry.myBidsPlaced = {
|
|
2001
|
+
bids: accountsToUse.length,
|
|
2002
|
+
bidPerSeat: nextBid,
|
|
2003
|
+
txFeePlusTip: feePlusTip,
|
|
2004
|
+
successfulBids: 0
|
|
2005
|
+
};
|
|
2006
|
+
this.pendingRequest = this.bid(nextBid, accountsToUse, historyEntry);
|
|
2007
|
+
} else if (historyEntry.bidChanges.length === 0) {
|
|
2008
|
+
this.history.bidHistory.shift();
|
|
1796
2009
|
}
|
|
1797
|
-
this.pendingRequest = this.bid(
|
|
1798
|
-
nextBid,
|
|
1799
|
-
this.subaccounts.map((x) => x.index)
|
|
1800
|
-
);
|
|
1801
2010
|
this.needsRebid = false;
|
|
1802
2011
|
}
|
|
1803
|
-
async bid(bidPerSeat,
|
|
1804
|
-
if (!subaccountRange.length) return;
|
|
2012
|
+
async bid(bidPerSeat, subaccounts, historyEntry) {
|
|
1805
2013
|
const prevLastBidTime = this.lastBidTime;
|
|
1806
2014
|
try {
|
|
1807
2015
|
this.lastBidTime = Date.now();
|
|
1808
|
-
const
|
|
1809
|
-
|
|
2016
|
+
const submitter = await this.accountset.createMiningBidTx({
|
|
2017
|
+
subaccounts,
|
|
1810
2018
|
bidAmount: bidPerSeat,
|
|
1811
2019
|
sendRewardsToSeed: true
|
|
1812
2020
|
});
|
|
1813
|
-
|
|
2021
|
+
const tip = this.options.tipPerTransaction ?? 0n;
|
|
2022
|
+
const txResult = await submitter.submit({
|
|
2023
|
+
tip,
|
|
2024
|
+
useLatestNonce: true
|
|
2025
|
+
});
|
|
2026
|
+
const bidError = await txResult.inBlockPromise.then(() => void 0).catch((x) => x);
|
|
2027
|
+
let blockNumber;
|
|
2028
|
+
if (txResult.includedInBlock) {
|
|
1814
2029
|
const client = await this.client;
|
|
1815
|
-
const api = await client.at(
|
|
1816
|
-
|
|
2030
|
+
const api = await client.at(txResult.includedInBlock);
|
|
2031
|
+
blockNumber = await api.query.system.number().then((x) => x.toNumber());
|
|
1817
2032
|
}
|
|
1818
|
-
|
|
1819
|
-
this.
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
2033
|
+
const successfulBids = txResult.batchInterruptedIndex ?? subaccounts.length;
|
|
2034
|
+
this.history.onBidResult(historyEntry, {
|
|
2035
|
+
blockNumber,
|
|
2036
|
+
successfulBids,
|
|
2037
|
+
bidPerSeat,
|
|
2038
|
+
txFeePlusTip: txResult.finalFee ?? 0n,
|
|
2039
|
+
bidsAttempted: subaccounts.length,
|
|
2040
|
+
bidError
|
|
2041
|
+
});
|
|
2042
|
+
console.log("Done creating bids for cohort", {
|
|
2043
|
+
successfulBids,
|
|
2044
|
+
bidPerSeat,
|
|
2045
|
+
blockNumber
|
|
2046
|
+
});
|
|
2047
|
+
if (bidError) throw bidError;
|
|
1825
2048
|
} catch (err) {
|
|
1826
2049
|
this.lastBidTime = prevLastBidTime;
|
|
1827
2050
|
console.error(`Error bidding for cohort ${this.cohortId}:`, err);
|
|
@@ -2499,8 +2722,8 @@ function vaultCli() {
|
|
|
2499
2722
|
).action(async ({ tip, argons, vaultId, ratio }) => {
|
|
2500
2723
|
const accountset = await accountsetFromCli(program);
|
|
2501
2724
|
const client = await accountset.client;
|
|
2502
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2503
|
-
const microgons = BigInt(argons *
|
|
2725
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2726
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2504
2727
|
const rawVault = (await client.query.vaults.vaultsById(vaultId)).unwrap();
|
|
2505
2728
|
if (rawVault.operatorAccountId.toHuman() !== accountset.seedAddress) {
|
|
2506
2729
|
console.error("Vault does not belong to this account");
|
|
@@ -2560,8 +2783,8 @@ function vaultCli() {
|
|
|
2560
2783
|
}
|
|
2561
2784
|
const accountset = await accountsetFromCli(program);
|
|
2562
2785
|
const client = await accountset.client;
|
|
2563
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2564
|
-
const microgons = BigInt(argons *
|
|
2786
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2787
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2565
2788
|
const bitcoinLocks = new BitcoinLocks(Promise.resolve(client));
|
|
2566
2789
|
const existentialDeposit = client.consts.balances.existentialDeposit.toBigInt();
|
|
2567
2790
|
const tickDuration = (await client.query.ticks.genesisTicker()).tickDurationMillis.toNumber();
|
|
@@ -2766,7 +2989,7 @@ function miningCli() {
|
|
|
2766
2989
|
const balance = await accountset.balance();
|
|
2767
2990
|
const feeWiggleRoom = BigInt(25e3);
|
|
2768
2991
|
const amountAvailable = balance - feeWiggleRoom;
|
|
2769
|
-
let maxBidAmount = maxBid ? BigInt(maxBid *
|
|
2992
|
+
let maxBidAmount = maxBid ? BigInt(maxBid * MICROGONS_PER_ARGON) : void 0;
|
|
2770
2993
|
let maxBalanceToUse = amountAvailable;
|
|
2771
2994
|
if (maxBalance !== void 0) {
|
|
2772
2995
|
if (maxBalance.endsWith("%")) {
|
|
@@ -2778,7 +3001,7 @@ function miningCli() {
|
|
|
2778
3001
|
maxBalanceToUse = amountToBid;
|
|
2779
3002
|
} else {
|
|
2780
3003
|
maxBalanceToUse = BigInt(
|
|
2781
|
-
Math.floor(parseFloat(maxBalance) *
|
|
3004
|
+
Math.floor(parseFloat(maxBalance) * MICROGONS_PER_ARGON)
|
|
2782
3005
|
);
|
|
2783
3006
|
}
|
|
2784
3007
|
maxBidAmount ??= maxBalanceToUse / BigInt(seatsToWin);
|
|
@@ -2800,9 +3023,11 @@ function miningCli() {
|
|
|
2800
3023
|
subaccountRange,
|
|
2801
3024
|
{
|
|
2802
3025
|
maxBid: maxBidAmount,
|
|
2803
|
-
minBid: BigInt((minBid ?? 0) *
|
|
2804
|
-
bidIncrement: BigInt(
|
|
2805
|
-
|
|
3026
|
+
minBid: BigInt((minBid ?? 0) * MICROGONS_PER_ARGON),
|
|
3027
|
+
bidIncrement: BigInt(
|
|
3028
|
+
Math.floor(bidIncrement * MICROGONS_PER_ARGON)
|
|
3029
|
+
),
|
|
3030
|
+
maxBudget: maxBalanceToUse,
|
|
2806
3031
|
bidDelay
|
|
2807
3032
|
}
|
|
2808
3033
|
);
|
|
@@ -2834,7 +3059,10 @@ function miningCli() {
|
|
|
2834
3059
|
);
|
|
2835
3060
|
const tx = client.tx.utility.batchAll([
|
|
2836
3061
|
client.tx.proxy.addProxy(address, "MiningBid", 0),
|
|
2837
|
-
client.tx.balances.transferAllowDeath(
|
|
3062
|
+
client.tx.balances.transferAllowDeath(
|
|
3063
|
+
address,
|
|
3064
|
+
BigInt(feeArgons * MICROGONS_PER_ARGON)
|
|
3065
|
+
)
|
|
2838
3066
|
]);
|
|
2839
3067
|
let keypair;
|
|
2840
3068
|
try {
|
|
@@ -2883,8 +3111,8 @@ function liquidityCli() {
|
|
|
2883
3111
|
parseFloat
|
|
2884
3112
|
).action(async ({ tip, argons, vaultId }) => {
|
|
2885
3113
|
const accountset = await accountsetFromCli(program);
|
|
2886
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2887
|
-
const microgons = BigInt(argons *
|
|
3114
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
3115
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2888
3116
|
const bidPool = new BidPool(
|
|
2889
3117
|
accountset.client,
|
|
2890
3118
|
accountset.txSubmitterPair
|
|
@@ -2909,7 +3137,7 @@ function liquidityCli() {
|
|
|
2909
3137
|
"The tip to include with the transaction",
|
|
2910
3138
|
parseFloat
|
|
2911
3139
|
).action(async ({ maxArgons, minPctSharing, tip }) => {
|
|
2912
|
-
const maxAmountPerSlot = BigInt(maxArgons *
|
|
3140
|
+
const maxAmountPerSlot = BigInt(maxArgons * MICROGONS_PER_ARGON);
|
|
2913
3141
|
const accountset = await accountsetFromCli(program);
|
|
2914
3142
|
const vaults = new VaultMonitor(
|
|
2915
3143
|
accountset,
|
|
@@ -2922,7 +3150,7 @@ function liquidityCli() {
|
|
|
2922
3150
|
accountset.client,
|
|
2923
3151
|
accountset.txSubmitterPair
|
|
2924
3152
|
);
|
|
2925
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
3153
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2926
3154
|
console.log("Waiting for liquidity pool space...");
|
|
2927
3155
|
vaults.events.on(
|
|
2928
3156
|
"liquidity-pool-space-above",
|
|
@@ -2961,7 +3189,7 @@ function bitcoinCli() {
|
|
|
2961
3189
|
).description("Watch for bitcoin space available").action(async ({ argons }) => {
|
|
2962
3190
|
const accountset = await accountsetFromCli(program);
|
|
2963
3191
|
const bot = new VaultMonitor(accountset, {
|
|
2964
|
-
bitcoinSpaceAvailable: argons ? BigInt(argons *
|
|
3192
|
+
bitcoinSpaceAvailable: argons ? BigInt(argons * MICROGONS_PER_ARGON) : 1n
|
|
2965
3193
|
});
|
|
2966
3194
|
bot.events.on("bitcoin-space-above", async (vaultId, amount) => {
|
|
2967
3195
|
const vault = bot.vaultsById[vaultId];
|
|
@@ -2990,13 +3218,13 @@ function bitcoinCli() {
|
|
|
2990
3218
|
parseFloat,
|
|
2991
3219
|
0
|
|
2992
3220
|
).action(async ({ argons, bitcoinXpub, maxLockFee, tip }) => {
|
|
2993
|
-
const amountToLock = BigInt(argons *
|
|
3221
|
+
const amountToLock = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2994
3222
|
const accountset = await accountsetFromCli(program);
|
|
2995
3223
|
await BitcoinLocks.waitForSpace(accountset, {
|
|
2996
3224
|
argonAmount: amountToLock,
|
|
2997
3225
|
bitcoinXpub,
|
|
2998
|
-
maxLockFee: maxLockFee !== void 0 ? BigInt(maxLockFee *
|
|
2999
|
-
tip: BigInt(tip *
|
|
3226
|
+
maxLockFee: maxLockFee !== void 0 ? BigInt(maxLockFee * MICROGONS_PER_ARGON) : void 0,
|
|
3227
|
+
tip: BigInt(tip * MICROGONS_PER_ARGON)
|
|
3000
3228
|
}).then(({ vaultId, satoshis, txFee, btcFee }) => {
|
|
3001
3229
|
console.log(
|
|
3002
3230
|
`Locked ${satoshis} satoshis in vault ${vaultId}. Tx fee=${formatArgons(
|
|
@@ -3021,8 +3249,13 @@ async function keyringFromFile(opts) {
|
|
|
3021
3249
|
}
|
|
3022
3250
|
const path = opts.filePath.replace("~", os.homedir());
|
|
3023
3251
|
const json = JSON.parse(await readFile(path, "utf-8"));
|
|
3252
|
+
let passphrase = opts.passphrase;
|
|
3253
|
+
if (opts.passphraseFile) {
|
|
3254
|
+
const passphrasePath = opts.passphraseFile.replace("~", os.homedir());
|
|
3255
|
+
passphrase = await readFile(passphrasePath, "utf-8");
|
|
3256
|
+
}
|
|
3024
3257
|
const mainAccount = new import_api.Keyring().createFromJson(json);
|
|
3025
|
-
mainAccount.decodePkcs8(
|
|
3258
|
+
mainAccount.decodePkcs8(passphrase);
|
|
3026
3259
|
return mainAccount;
|
|
3027
3260
|
}
|
|
3028
3261
|
async function saveKeyringPair(opts) {
|
|
@@ -3057,6 +3290,11 @@ function buildCli() {
|
|
|
3057
3290
|
"--account-passphrase <password>",
|
|
3058
3291
|
"The password for your seed file"
|
|
3059
3292
|
).env("ACCOUNT_PASSPHRASE")
|
|
3293
|
+
).addOption(
|
|
3294
|
+
new import_extra_typings6.Option(
|
|
3295
|
+
"--account-passphrase-file <path>",
|
|
3296
|
+
"The path to a password for your seed file"
|
|
3297
|
+
)
|
|
3060
3298
|
).addOption(
|
|
3061
3299
|
new import_extra_typings6.Option(
|
|
3062
3300
|
"-s, --subaccounts <range>",
|
|
@@ -3073,7 +3311,8 @@ async function accountsetFromCli(program, proxyForAddress) {
|
|
|
3073
3311
|
if (opts.accountFilePath) {
|
|
3074
3312
|
keypair = await keyringFromFile({
|
|
3075
3313
|
filePath: opts.accountFilePath,
|
|
3076
|
-
passphrase: opts.accountPassphrase
|
|
3314
|
+
passphrase: opts.accountPassphrase,
|
|
3315
|
+
passphraseFile: opts.accountPassphraseFile
|
|
3077
3316
|
});
|
|
3078
3317
|
}
|
|
3079
3318
|
if (!keypair) {
|