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