@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/cli.js
CHANGED
|
@@ -33,8 +33,10 @@ __export(index_exports, {
|
|
|
33
33
|
BitcoinLocks: () => BitcoinLocks,
|
|
34
34
|
BlockWatch: () => BlockWatch,
|
|
35
35
|
CohortBidder: () => CohortBidder,
|
|
36
|
+
ExtrinsicError: () => ExtrinsicError2,
|
|
36
37
|
JsonExt: () => JsonExt,
|
|
37
38
|
Keyring: () => Keyring,
|
|
39
|
+
MICROGONS_PER_ARGON: () => MICROGONS_PER_ARGON,
|
|
38
40
|
MiningBids: () => MiningBids,
|
|
39
41
|
MiningRotations: () => MiningRotations,
|
|
40
42
|
TxSubmitter: () => TxSubmitter,
|
|
@@ -46,6 +48,7 @@ __export(index_exports, {
|
|
|
46
48
|
convertPermillToBigNumber: () => convertPermillToBigNumber,
|
|
47
49
|
createKeyringPair: () => createKeyringPair,
|
|
48
50
|
decodeAddress: () => decodeAddress,
|
|
51
|
+
dispatchErrorToExtrinsicError: () => dispatchErrorToExtrinsicError,
|
|
49
52
|
dispatchErrorToString: () => dispatchErrorToString,
|
|
50
53
|
eventDataToJson: () => eventDataToJson,
|
|
51
54
|
filterUndefined: () => filterUndefined,
|
|
@@ -149,119 +152,6 @@ var WageProtector = class _WageProtector {
|
|
|
149
152
|
}
|
|
150
153
|
};
|
|
151
154
|
|
|
152
|
-
// src/utils.ts
|
|
153
|
-
import BigNumber2, * as BN from "bignumber.js";
|
|
154
|
-
var { ROUND_FLOOR } = BN;
|
|
155
|
-
function formatArgons(x) {
|
|
156
|
-
const isNegative = x < 0;
|
|
157
|
-
let format = BigNumber2(x.toString()).abs().div(1e6).toFormat(2, ROUND_FLOOR);
|
|
158
|
-
if (format.endsWith(".00")) {
|
|
159
|
-
format = format.slice(0, -3);
|
|
160
|
-
}
|
|
161
|
-
return `${isNegative ? "-" : ""}\u20B3${format}`;
|
|
162
|
-
}
|
|
163
|
-
function formatPercent(x) {
|
|
164
|
-
if (!x) return "na";
|
|
165
|
-
return `${x.times(100).decimalPlaces(3)}%`;
|
|
166
|
-
}
|
|
167
|
-
function filterUndefined(obj) {
|
|
168
|
-
return Object.fromEntries(
|
|
169
|
-
Object.entries(obj).filter(
|
|
170
|
-
([_, value]) => value !== void 0 && value !== null
|
|
171
|
-
)
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
async function gettersToObject(obj) {
|
|
175
|
-
if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
|
|
176
|
-
const keys = [];
|
|
177
|
-
for (const key in obj) {
|
|
178
|
-
keys.push(key);
|
|
179
|
-
}
|
|
180
|
-
if (Symbol.iterator in obj) {
|
|
181
|
-
const iterableToArray = [];
|
|
182
|
-
for (const item of obj) {
|
|
183
|
-
iterableToArray.push(await gettersToObject(item));
|
|
184
|
-
}
|
|
185
|
-
return iterableToArray;
|
|
186
|
-
}
|
|
187
|
-
const result = {};
|
|
188
|
-
for (const key of keys) {
|
|
189
|
-
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
190
|
-
if (descriptor && typeof descriptor.value === "function") {
|
|
191
|
-
continue;
|
|
192
|
-
}
|
|
193
|
-
const value = descriptor && descriptor.get ? descriptor.get.call(obj) : obj[key];
|
|
194
|
-
if (typeof value === "function") continue;
|
|
195
|
-
result[key] = await gettersToObject(value);
|
|
196
|
-
}
|
|
197
|
-
return result;
|
|
198
|
-
}
|
|
199
|
-
function convertFixedU128ToBigNumber(fixedU128) {
|
|
200
|
-
const decimalFactor = new BigNumber2(10).pow(new BigNumber2(18));
|
|
201
|
-
const rawValue = new BigNumber2(fixedU128.toString());
|
|
202
|
-
return rawValue.div(decimalFactor);
|
|
203
|
-
}
|
|
204
|
-
function convertPermillToBigNumber(permill) {
|
|
205
|
-
const decimalFactor = new BigNumber2(1e6);
|
|
206
|
-
const rawValue = new BigNumber2(permill.toString());
|
|
207
|
-
return rawValue.div(decimalFactor);
|
|
208
|
-
}
|
|
209
|
-
function eventDataToJson(event) {
|
|
210
|
-
const obj = {};
|
|
211
|
-
event.data.forEach((data, index) => {
|
|
212
|
-
const name = event.data.names?.[index];
|
|
213
|
-
obj[name ?? `${index}`] = data.toJSON();
|
|
214
|
-
});
|
|
215
|
-
return obj;
|
|
216
|
-
}
|
|
217
|
-
function dispatchErrorToString(client, error) {
|
|
218
|
-
let message = error.toString();
|
|
219
|
-
if (error.isModule) {
|
|
220
|
-
const decoded = client.registry.findMetaError(error.asModule);
|
|
221
|
-
const { docs, name, section } = decoded;
|
|
222
|
-
message = `${section}.${name}: ${docs.join(" ")}`;
|
|
223
|
-
}
|
|
224
|
-
return message;
|
|
225
|
-
}
|
|
226
|
-
function checkForExtrinsicSuccess(events, client) {
|
|
227
|
-
return new Promise((resolve, reject) => {
|
|
228
|
-
for (const { event } of events) {
|
|
229
|
-
if (client.events.system.ExtrinsicSuccess.is(event)) {
|
|
230
|
-
resolve();
|
|
231
|
-
} else if (client.events.system.ExtrinsicFailed.is(event)) {
|
|
232
|
-
const [dispatchError] = event.data;
|
|
233
|
-
let errorInfo = dispatchError.toString();
|
|
234
|
-
if (dispatchError.isModule) {
|
|
235
|
-
const decoded = client.registry.findMetaError(dispatchError.asModule);
|
|
236
|
-
errorInfo = `${decoded.section}.${decoded.name}`;
|
|
237
|
-
}
|
|
238
|
-
reject(
|
|
239
|
-
new Error(
|
|
240
|
-
`${event.section}.${event.method}:: ExtrinsicFailed:: ${errorInfo}`
|
|
241
|
-
)
|
|
242
|
-
);
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
var JsonExt = class {
|
|
248
|
-
static stringify(obj, space) {
|
|
249
|
-
return JSON.stringify(
|
|
250
|
-
obj,
|
|
251
|
-
(_, v) => typeof v === "bigint" ? `${v}n` : v,
|
|
252
|
-
space
|
|
253
|
-
);
|
|
254
|
-
}
|
|
255
|
-
static parse(str) {
|
|
256
|
-
return JSON.parse(str, (_, v) => {
|
|
257
|
-
if (typeof v === "string" && v.endsWith("n")) {
|
|
258
|
-
return BigInt(v.slice(0, -1));
|
|
259
|
-
}
|
|
260
|
-
return v;
|
|
261
|
-
});
|
|
262
|
-
}
|
|
263
|
-
};
|
|
264
|
-
|
|
265
155
|
// src/TxSubmitter.ts
|
|
266
156
|
function logExtrinsicResult(result) {
|
|
267
157
|
if (process.env.DEBUG) {
|
|
@@ -393,13 +283,12 @@ var TxResult = class {
|
|
|
393
283
|
}
|
|
394
284
|
}
|
|
395
285
|
if (encounteredError) {
|
|
396
|
-
const error =
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
this.reject(new Error(`Transaction failed: ${error}`));
|
|
286
|
+
const error = dispatchErrorToExtrinsicError(
|
|
287
|
+
this.client,
|
|
288
|
+
encounteredError,
|
|
289
|
+
batchErrorIndex
|
|
290
|
+
);
|
|
291
|
+
this.reject(error);
|
|
403
292
|
} else {
|
|
404
293
|
this.inBlockResolve(status.asInBlock.toU8a());
|
|
405
294
|
}
|
|
@@ -414,6 +303,147 @@ var TxResult = class {
|
|
|
414
303
|
}
|
|
415
304
|
};
|
|
416
305
|
|
|
306
|
+
// src/utils.ts
|
|
307
|
+
import BigNumber2, * as BN from "bignumber.js";
|
|
308
|
+
var { ROUND_FLOOR } = BN;
|
|
309
|
+
var MICROGONS_PER_ARGON = 1e6;
|
|
310
|
+
function formatArgons(x) {
|
|
311
|
+
if (x === void 0 || x === null) return "na";
|
|
312
|
+
const isNegative = x < 0;
|
|
313
|
+
let format = BigNumber2(x.toString()).abs().div(MICROGONS_PER_ARGON).toFormat(2, ROUND_FLOOR);
|
|
314
|
+
if (format.endsWith(".00")) {
|
|
315
|
+
format = format.slice(0, -3);
|
|
316
|
+
}
|
|
317
|
+
return `${isNegative ? "-" : ""}\u20B3${format}`;
|
|
318
|
+
}
|
|
319
|
+
function formatPercent(x) {
|
|
320
|
+
if (!x) return "na";
|
|
321
|
+
return `${x.times(100).decimalPlaces(3)}%`;
|
|
322
|
+
}
|
|
323
|
+
function filterUndefined(obj) {
|
|
324
|
+
return Object.fromEntries(
|
|
325
|
+
Object.entries(obj).filter(
|
|
326
|
+
([_, value]) => value !== void 0 && value !== null
|
|
327
|
+
)
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
async function gettersToObject(obj) {
|
|
331
|
+
if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
|
|
332
|
+
const keys = [];
|
|
333
|
+
for (const key in obj) {
|
|
334
|
+
keys.push(key);
|
|
335
|
+
}
|
|
336
|
+
if (Symbol.iterator in obj) {
|
|
337
|
+
const iterableToArray = [];
|
|
338
|
+
for (const item of obj) {
|
|
339
|
+
iterableToArray.push(await gettersToObject(item));
|
|
340
|
+
}
|
|
341
|
+
return iterableToArray;
|
|
342
|
+
}
|
|
343
|
+
const result = {};
|
|
344
|
+
for (const key of keys) {
|
|
345
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
346
|
+
if (descriptor && typeof descriptor.value === "function") {
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
const value = descriptor && descriptor.get ? descriptor.get.call(obj) : obj[key];
|
|
350
|
+
if (typeof value === "function") continue;
|
|
351
|
+
result[key] = await gettersToObject(value);
|
|
352
|
+
}
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
function convertFixedU128ToBigNumber(fixedU128) {
|
|
356
|
+
const decimalFactor = new BigNumber2(10).pow(new BigNumber2(18));
|
|
357
|
+
const rawValue = new BigNumber2(fixedU128.toString());
|
|
358
|
+
return rawValue.div(decimalFactor);
|
|
359
|
+
}
|
|
360
|
+
function convertPermillToBigNumber(permill) {
|
|
361
|
+
const decimalFactor = new BigNumber2(1e6);
|
|
362
|
+
const rawValue = new BigNumber2(permill.toString());
|
|
363
|
+
return rawValue.div(decimalFactor);
|
|
364
|
+
}
|
|
365
|
+
function eventDataToJson(event) {
|
|
366
|
+
const obj = {};
|
|
367
|
+
event.data.forEach((data, index) => {
|
|
368
|
+
const name = event.data.names?.[index];
|
|
369
|
+
obj[name ?? `${index}`] = data.toJSON();
|
|
370
|
+
});
|
|
371
|
+
return obj;
|
|
372
|
+
}
|
|
373
|
+
function dispatchErrorToString(client, error) {
|
|
374
|
+
let message = error.toString();
|
|
375
|
+
if (error.isModule) {
|
|
376
|
+
const decoded = client.registry.findMetaError(error.asModule);
|
|
377
|
+
const { docs, name, section } = decoded;
|
|
378
|
+
message = `${section}.${name}: ${docs.join(" ")}`;
|
|
379
|
+
}
|
|
380
|
+
return message;
|
|
381
|
+
}
|
|
382
|
+
var ExtrinsicError2 = class extends Error {
|
|
383
|
+
constructor(errorCode, details, batchInterruptedIndex) {
|
|
384
|
+
super(errorCode);
|
|
385
|
+
this.errorCode = errorCode;
|
|
386
|
+
this.details = details;
|
|
387
|
+
this.batchInterruptedIndex = batchInterruptedIndex;
|
|
388
|
+
}
|
|
389
|
+
toString() {
|
|
390
|
+
if (this.batchInterruptedIndex !== void 0) {
|
|
391
|
+
return `${this.errorCode} ${this.details ?? ""} (Batch interrupted at index ${this.batchInterruptedIndex})`;
|
|
392
|
+
}
|
|
393
|
+
return `${this.errorCode} ${this.details ?? ""}`;
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
function dispatchErrorToExtrinsicError(client, error, batchInterruptedIndex) {
|
|
397
|
+
if (error.isModule) {
|
|
398
|
+
const decoded = client.registry.findMetaError(error.asModule);
|
|
399
|
+
const { docs, name, section } = decoded;
|
|
400
|
+
return new ExtrinsicError2(
|
|
401
|
+
`${section}.${name}`,
|
|
402
|
+
docs.join(" "),
|
|
403
|
+
batchInterruptedIndex
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
return new ExtrinsicError2(error.toString(), void 0, batchInterruptedIndex);
|
|
407
|
+
}
|
|
408
|
+
function checkForExtrinsicSuccess(events, client) {
|
|
409
|
+
return new Promise((resolve, reject) => {
|
|
410
|
+
for (const { event } of events) {
|
|
411
|
+
if (client.events.system.ExtrinsicSuccess.is(event)) {
|
|
412
|
+
resolve();
|
|
413
|
+
} else if (client.events.system.ExtrinsicFailed.is(event)) {
|
|
414
|
+
const [dispatchError] = event.data;
|
|
415
|
+
let errorInfo = dispatchError.toString();
|
|
416
|
+
if (dispatchError.isModule) {
|
|
417
|
+
const decoded = client.registry.findMetaError(dispatchError.asModule);
|
|
418
|
+
errorInfo = `${decoded.section}.${decoded.name}`;
|
|
419
|
+
}
|
|
420
|
+
reject(
|
|
421
|
+
new Error(
|
|
422
|
+
`${event.section}.${event.method}:: ExtrinsicFailed:: ${errorInfo}`
|
|
423
|
+
)
|
|
424
|
+
);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
});
|
|
428
|
+
}
|
|
429
|
+
var JsonExt = class {
|
|
430
|
+
static stringify(obj, space) {
|
|
431
|
+
return JSON.stringify(
|
|
432
|
+
obj,
|
|
433
|
+
(_, v) => typeof v === "bigint" ? `${v}n` : v,
|
|
434
|
+
space
|
|
435
|
+
);
|
|
436
|
+
}
|
|
437
|
+
static parse(str) {
|
|
438
|
+
return JSON.parse(str, (_, v) => {
|
|
439
|
+
if (typeof v === "string" && v.endsWith("n")) {
|
|
440
|
+
return BigInt(v.slice(0, -1));
|
|
441
|
+
}
|
|
442
|
+
return v;
|
|
443
|
+
});
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
|
|
417
447
|
// src/AccountRegistry.ts
|
|
418
448
|
var AccountRegistry = class _AccountRegistry {
|
|
419
449
|
namedAccounts = /* @__PURE__ */ new Map();
|
|
@@ -646,7 +676,7 @@ var MiningRotations = class {
|
|
|
646
676
|
const slot1StartTick = this.genesisTick + this.miningConfig.slotBiddingStartAfterTicks + ticksBetweenSlots;
|
|
647
677
|
if (tick < slot1StartTick) return 0;
|
|
648
678
|
const ticksSinceSlot1 = tick - slot1StartTick;
|
|
649
|
-
return Math.floor(ticksSinceSlot1 / ticksBetweenSlots);
|
|
679
|
+
return Math.floor(ticksSinceSlot1 / ticksBetweenSlots) + 1;
|
|
650
680
|
}
|
|
651
681
|
async getForHeader(client, header) {
|
|
652
682
|
if (header.number.toNumber() === 0) return 0;
|
|
@@ -826,6 +856,14 @@ var Accountset = class {
|
|
|
826
856
|
);
|
|
827
857
|
}
|
|
828
858
|
}
|
|
859
|
+
async submitterBalance(blockHash) {
|
|
860
|
+
const client = await this.client;
|
|
861
|
+
const api = blockHash ? await client.at(blockHash) : client;
|
|
862
|
+
const accountData = await api.query.system.account(
|
|
863
|
+
this.txSubmitterPair.address
|
|
864
|
+
);
|
|
865
|
+
return accountData.data.free.toBigInt();
|
|
866
|
+
}
|
|
829
867
|
async balance(blockHash) {
|
|
830
868
|
const client = await this.client;
|
|
831
869
|
const api = blockHash ? await client.at(blockHash) : client;
|
|
@@ -1088,18 +1126,18 @@ var Accountset = class {
|
|
|
1088
1126
|
return new TxSubmitter(client, tx, this.txSubmitterPair);
|
|
1089
1127
|
}
|
|
1090
1128
|
/**
|
|
1091
|
-
* Create
|
|
1129
|
+
* Create but don't submit a mining bid transaction.
|
|
1130
|
+
* @param options
|
|
1092
1131
|
*/
|
|
1093
|
-
async
|
|
1094
|
-
const accounts = this.getAccountsInRange(options.subaccountRange);
|
|
1132
|
+
async createMiningBidTx(options) {
|
|
1095
1133
|
const client = await this.client;
|
|
1096
|
-
|
|
1134
|
+
const { bidAmount, subaccounts, sendRewardsToSeed } = options;
|
|
1097
1135
|
const batch = client.tx.utility.batch(
|
|
1098
|
-
|
|
1136
|
+
subaccounts.map((x) => {
|
|
1099
1137
|
const keys = this.keys();
|
|
1100
|
-
const rewards =
|
|
1138
|
+
const rewards = sendRewardsToSeed ? { Account: this.seedAddress } : { Owner: null };
|
|
1101
1139
|
return client.tx.miningSlot.bid(
|
|
1102
|
-
|
|
1140
|
+
bidAmount,
|
|
1103
1141
|
rewards,
|
|
1104
1142
|
{
|
|
1105
1143
|
grandpa: keys.gran.rawPublicKey,
|
|
@@ -1113,7 +1151,19 @@ var Accountset = class {
|
|
|
1113
1151
|
if (this.isProxy) {
|
|
1114
1152
|
tx = client.tx.proxy.proxy(this.seedAddress, "MiningBid", batch);
|
|
1115
1153
|
}
|
|
1116
|
-
|
|
1154
|
+
return new TxSubmitter(client, tx, this.txSubmitterPair);
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* Create a mining bid. This will create a bid for each account in the given range from the seed account as funding.
|
|
1158
|
+
*/
|
|
1159
|
+
async createMiningBids(options) {
|
|
1160
|
+
const accounts = this.getAccountsInRange(options.subaccountRange);
|
|
1161
|
+
const client = await this.client;
|
|
1162
|
+
const submitter = await this.createMiningBidTx({
|
|
1163
|
+
...options,
|
|
1164
|
+
subaccounts: accounts
|
|
1165
|
+
});
|
|
1166
|
+
const { tip = 0n } = options;
|
|
1117
1167
|
const txFee = await submitter.feeEstimate(tip);
|
|
1118
1168
|
let minBalance = options.bidAmount * BigInt(accounts.length);
|
|
1119
1169
|
let totalFees = tip + 1n + txFee;
|
|
@@ -1557,27 +1607,24 @@ var VaultMonitor = class {
|
|
|
1557
1607
|
}
|
|
1558
1608
|
};
|
|
1559
1609
|
|
|
1560
|
-
// src/
|
|
1561
|
-
var
|
|
1562
|
-
constructor(
|
|
1563
|
-
this.accountset = accountset;
|
|
1610
|
+
// src/CohortBidderHistory.ts
|
|
1611
|
+
var CohortBidderHistory = class _CohortBidderHistory {
|
|
1612
|
+
constructor(cohortId, subaccounts) {
|
|
1564
1613
|
this.cohortId = cohortId;
|
|
1565
1614
|
this.subaccounts = subaccounts;
|
|
1566
|
-
this.
|
|
1615
|
+
this.maxSeatsInPlay = this.subaccounts.length;
|
|
1567
1616
|
this.subaccounts.forEach((x) => {
|
|
1568
|
-
this.
|
|
1617
|
+
this.myAddresses.add(x.address);
|
|
1569
1618
|
});
|
|
1570
1619
|
}
|
|
1571
|
-
|
|
1572
|
-
return this.accountset.client;
|
|
1573
|
-
}
|
|
1620
|
+
bidHistory = [];
|
|
1574
1621
|
stats = {
|
|
1575
1622
|
// number of seats won
|
|
1576
|
-
|
|
1623
|
+
seatsWon: 0,
|
|
1577
1624
|
// sum of argons bid in successful bids
|
|
1578
1625
|
totalArgonsBid: 0n,
|
|
1579
1626
|
// total number of bids placed (includes 1 per seat)
|
|
1580
|
-
|
|
1627
|
+
bidsAttempted: 0,
|
|
1581
1628
|
// fees including the tip
|
|
1582
1629
|
fees: 0n,
|
|
1583
1630
|
// Max bid per seat
|
|
@@ -1589,16 +1636,157 @@ var CohortBidder = class _CohortBidder {
|
|
|
1589
1636
|
// The cohort expected argons per block
|
|
1590
1637
|
cohortArgonsPerBlock: 0n,
|
|
1591
1638
|
// The last block that bids are synced to
|
|
1592
|
-
|
|
1639
|
+
lastBlockNumber: 0
|
|
1593
1640
|
};
|
|
1641
|
+
lastBids = [];
|
|
1642
|
+
myAddresses = /* @__PURE__ */ new Set();
|
|
1643
|
+
maxSeatsInPlay = 0;
|
|
1644
|
+
async init(client) {
|
|
1645
|
+
if (!this.stats.argonotsPerSeat) {
|
|
1646
|
+
const startingStats = await _CohortBidderHistory.getStartingData(client);
|
|
1647
|
+
Object.assign(this.stats, startingStats);
|
|
1648
|
+
}
|
|
1649
|
+
}
|
|
1650
|
+
maybeReducingSeats(maxSeats, reason, historyEntry) {
|
|
1651
|
+
if (this.maxSeatsInPlay > maxSeats) {
|
|
1652
|
+
historyEntry.maxSeatsReductionReason = reason;
|
|
1653
|
+
}
|
|
1654
|
+
this.maxSeatsInPlay = maxSeats;
|
|
1655
|
+
historyEntry.maxSeatsInPlay = maxSeats;
|
|
1656
|
+
}
|
|
1657
|
+
trackChange(next, blockNumber, tick, isLastEntry = false) {
|
|
1658
|
+
let winningBids = 0;
|
|
1659
|
+
let totalArgonsBid = 0n;
|
|
1660
|
+
const nextEntrants = [];
|
|
1661
|
+
for (const x of next) {
|
|
1662
|
+
const bid = x.bid.toBigInt();
|
|
1663
|
+
const address = x.accountId.toHuman();
|
|
1664
|
+
nextEntrants.push({ address, bid });
|
|
1665
|
+
if (this.myAddresses.has(address)) {
|
|
1666
|
+
winningBids++;
|
|
1667
|
+
totalArgonsBid += bid;
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
this.stats.seatsWon = winningBids;
|
|
1671
|
+
this.stats.totalArgonsBid = totalArgonsBid;
|
|
1672
|
+
this.stats.lastBlockNumber = Math.max(
|
|
1673
|
+
blockNumber,
|
|
1674
|
+
this.stats.lastBlockNumber
|
|
1675
|
+
);
|
|
1676
|
+
const historyEntry = {
|
|
1677
|
+
cohortId: this.cohortId,
|
|
1678
|
+
blockNumber,
|
|
1679
|
+
tick,
|
|
1680
|
+
bidChanges: [],
|
|
1681
|
+
winningSeats: winningBids,
|
|
1682
|
+
maxSeatsInPlay: this.maxSeatsInPlay
|
|
1683
|
+
};
|
|
1684
|
+
const hasDiffs = JsonExt.stringify(nextEntrants) !== JsonExt.stringify(this.lastBids);
|
|
1685
|
+
if (!isLastEntry || hasDiffs) {
|
|
1686
|
+
this.bidHistory.unshift(historyEntry);
|
|
1687
|
+
}
|
|
1688
|
+
if (hasDiffs) {
|
|
1689
|
+
nextEntrants.forEach(({ address, bid }, i) => {
|
|
1690
|
+
const prevBidIndex = this.lastBids.findIndex(
|
|
1691
|
+
(y) => y.address === address
|
|
1692
|
+
);
|
|
1693
|
+
const entry = {
|
|
1694
|
+
address,
|
|
1695
|
+
bidAmount: bid,
|
|
1696
|
+
bidPosition: i,
|
|
1697
|
+
prevPosition: prevBidIndex === -1 ? null : prevBidIndex
|
|
1698
|
+
};
|
|
1699
|
+
if (prevBidIndex !== -1) {
|
|
1700
|
+
const prevBidAmount = this.lastBids[prevBidIndex].bid;
|
|
1701
|
+
if (prevBidAmount !== bid) {
|
|
1702
|
+
entry.prevBidAmount = prevBidAmount;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
historyEntry.bidChanges.push(entry);
|
|
1706
|
+
});
|
|
1707
|
+
this.lastBids.forEach(({ address, bid }, i) => {
|
|
1708
|
+
const nextBid = nextEntrants.some((y) => y.address === address);
|
|
1709
|
+
if (!nextBid) {
|
|
1710
|
+
historyEntry.bidChanges.push({
|
|
1711
|
+
address,
|
|
1712
|
+
bidAmount: bid,
|
|
1713
|
+
bidPosition: null,
|
|
1714
|
+
prevPosition: i
|
|
1715
|
+
});
|
|
1716
|
+
}
|
|
1717
|
+
});
|
|
1718
|
+
this.lastBids = nextEntrants;
|
|
1719
|
+
}
|
|
1720
|
+
return historyEntry;
|
|
1721
|
+
}
|
|
1722
|
+
onBidResult(historyEntry, param) {
|
|
1723
|
+
const {
|
|
1724
|
+
txFeePlusTip,
|
|
1725
|
+
bidPerSeat,
|
|
1726
|
+
bidsAttempted,
|
|
1727
|
+
successfulBids,
|
|
1728
|
+
blockNumber,
|
|
1729
|
+
bidError
|
|
1730
|
+
} = param;
|
|
1731
|
+
this.stats.fees += txFeePlusTip;
|
|
1732
|
+
this.stats.bidsAttempted += bidsAttempted;
|
|
1733
|
+
if (bidPerSeat > this.stats.maxBidPerSeat) {
|
|
1734
|
+
this.stats.maxBidPerSeat = bidPerSeat;
|
|
1735
|
+
}
|
|
1736
|
+
if (blockNumber !== void 0) {
|
|
1737
|
+
this.stats.lastBlockNumber = Math.max(
|
|
1738
|
+
blockNumber,
|
|
1739
|
+
this.stats.lastBlockNumber
|
|
1740
|
+
);
|
|
1741
|
+
}
|
|
1742
|
+
historyEntry.myBidsPlaced.failureReason = bidError;
|
|
1743
|
+
historyEntry.myBidsPlaced.successfulBids = successfulBids;
|
|
1744
|
+
historyEntry.myBidsPlaced.txFeePlusTip = txFeePlusTip;
|
|
1745
|
+
}
|
|
1746
|
+
static async getStartingData(api) {
|
|
1747
|
+
const argonotPrice = await api.query.priceIndex.current();
|
|
1748
|
+
let argonotUsdPrice = 0;
|
|
1749
|
+
if (argonotPrice.isSome) {
|
|
1750
|
+
argonotUsdPrice = convertFixedU128ToBigNumber(
|
|
1751
|
+
argonotPrice.unwrap().argonotUsdPrice.toBigInt()
|
|
1752
|
+
).toNumber();
|
|
1753
|
+
}
|
|
1754
|
+
const argonotsPerSeat = await api.query.miningSlot.argonotsPerMiningSeat().then((x) => x.toBigInt());
|
|
1755
|
+
const cohortArgonsPerBlock = await api.query.blockRewards.argonsPerBlock().then((x) => x.toBigInt());
|
|
1756
|
+
return { argonotsPerSeat, argonotUsdPrice, cohortArgonsPerBlock };
|
|
1757
|
+
}
|
|
1758
|
+
};
|
|
1759
|
+
|
|
1760
|
+
// src/CohortBidder.ts
|
|
1761
|
+
var CohortBidder = class {
|
|
1762
|
+
constructor(accountset, cohortId, subaccounts, options) {
|
|
1763
|
+
this.accountset = accountset;
|
|
1764
|
+
this.cohortId = cohortId;
|
|
1765
|
+
this.subaccounts = subaccounts;
|
|
1766
|
+
this.options = options;
|
|
1767
|
+
this.history = new CohortBidderHistory(cohortId, subaccounts);
|
|
1768
|
+
this.subaccounts.forEach((x) => {
|
|
1769
|
+
this.myAddresses.add(x.address);
|
|
1770
|
+
});
|
|
1771
|
+
}
|
|
1772
|
+
get client() {
|
|
1773
|
+
return this.accountset.client;
|
|
1774
|
+
}
|
|
1775
|
+
get stats() {
|
|
1776
|
+
return this.history.stats;
|
|
1777
|
+
}
|
|
1778
|
+
get bidHistory() {
|
|
1779
|
+
return this.history.bidHistory;
|
|
1780
|
+
}
|
|
1594
1781
|
unsubscribe;
|
|
1595
1782
|
pendingRequest;
|
|
1596
1783
|
retryTimeout;
|
|
1597
1784
|
isStopped = false;
|
|
1598
1785
|
needsRebid = false;
|
|
1599
1786
|
lastBidTime = 0;
|
|
1787
|
+
history;
|
|
1600
1788
|
millisPerTick;
|
|
1601
|
-
|
|
1789
|
+
myAddresses = /* @__PURE__ */ new Set();
|
|
1602
1790
|
async stop() {
|
|
1603
1791
|
if (this.isStopped) return this.stats;
|
|
1604
1792
|
this.isStopped = true;
|
|
@@ -1608,70 +1796,59 @@ var CohortBidder = class _CohortBidder {
|
|
|
1608
1796
|
this.unsubscribe();
|
|
1609
1797
|
}
|
|
1610
1798
|
const client = await this.client;
|
|
1611
|
-
const [
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1799
|
+
const [nextCohortId, isBiddingOpen] = await client.queryMulti([
|
|
1800
|
+
client.query.miningSlot.nextCohortId,
|
|
1801
|
+
client.query.miningSlot.isNextSlotBiddingOpen
|
|
1802
|
+
]);
|
|
1803
|
+
if (nextCohortId.toNumber() === this.cohortId && isBiddingOpen.isTrue) {
|
|
1804
|
+
console.log("Bidding is still open, waiting for it to close");
|
|
1805
|
+
await new Promise(async (resolve) => {
|
|
1806
|
+
const unsub = await client.query.miningSlot.isNextSlotBiddingOpen(
|
|
1807
|
+
(isOpen) => {
|
|
1808
|
+
if (isOpen.isFalse) {
|
|
1809
|
+
unsub();
|
|
1810
|
+
resolve();
|
|
1811
|
+
}
|
|
1623
1812
|
}
|
|
1624
|
-
|
|
1625
|
-
);
|
|
1626
|
-
});
|
|
1627
|
-
void await this.pendingRequest;
|
|
1628
|
-
if (nextCohortId.toNumber() === this.cohortId) {
|
|
1629
|
-
console.log("Bidder updating stats with bid queue");
|
|
1630
|
-
this.updateStats(nextCohort);
|
|
1631
|
-
} else {
|
|
1632
|
-
const bestBlock = await client.rpc.chain.getBlockHash();
|
|
1633
|
-
const api = await client.at(bestBlock);
|
|
1634
|
-
const wonIndices = await api.query.miningSlot.accountIndexLookup.multi([...this.allAddresses]).then((x) => x.filter((x2) => x2.isSome).map((x2) => x2.value));
|
|
1635
|
-
const wonSeats = await api.query.miningSlot.activeMinersByIndex.multi(wonIndices).then(
|
|
1636
|
-
(x) => x.filter(
|
|
1637
|
-
(x2) => x2.isSome && x2.value.cohortId.toNumber() === this.cohortId
|
|
1638
|
-
).map((x2) => x2.value)
|
|
1639
|
-
);
|
|
1640
|
-
console.log("Bidder updating stats with finalized cohort");
|
|
1641
|
-
this.updateStats(wonSeats);
|
|
1813
|
+
);
|
|
1814
|
+
});
|
|
1642
1815
|
}
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1816
|
+
void await this.pendingRequest;
|
|
1817
|
+
let header = await client.rpc.chain.getHeader();
|
|
1818
|
+
while (true) {
|
|
1819
|
+
const api2 = await client.at(header.hash);
|
|
1820
|
+
const cohortId = await api2.query.miningSlot.nextCohortId();
|
|
1821
|
+
if (cohortId.toNumber() === this.cohortId) {
|
|
1822
|
+
break;
|
|
1823
|
+
}
|
|
1824
|
+
header = await client.rpc.chain.getHeader(header.parentHash);
|
|
1825
|
+
}
|
|
1826
|
+
const api = await client.at(header.hash);
|
|
1827
|
+
const tick = await api.query.ticks.currentTick().then((x) => x.toNumber());
|
|
1828
|
+
const cohort = await api.query.miningSlot.nextSlotCohort();
|
|
1829
|
+
this.history.trackChange(cohort, header.number.toNumber(), tick, true);
|
|
1830
|
+
console.log("Bidder stopped", {
|
|
1831
|
+
cohortId: this.cohortId,
|
|
1832
|
+
blockNumber: header.number.toNumber(),
|
|
1833
|
+
tick,
|
|
1834
|
+
cohort: cohort.map((x) => ({
|
|
1835
|
+
address: x.accountId.toHuman(),
|
|
1836
|
+
bid: x.bid.toBigInt()
|
|
1837
|
+
}))
|
|
1838
|
+
});
|
|
1647
1839
|
return this.stats;
|
|
1648
1840
|
}
|
|
1649
|
-
static async getStartingData(api) {
|
|
1650
|
-
const argonotPrice = await api.query.priceIndex.current();
|
|
1651
|
-
let argonotUsdPrice = 0;
|
|
1652
|
-
if (argonotPrice.isSome) {
|
|
1653
|
-
argonotUsdPrice = convertFixedU128ToBigNumber(
|
|
1654
|
-
argonotPrice.unwrap().argonotUsdPrice.toBigInt()
|
|
1655
|
-
).toNumber();
|
|
1656
|
-
}
|
|
1657
|
-
const argonotsPerSeat = await api.query.miningSlot.argonotsPerMiningSeat().then((x) => x.toBigInt());
|
|
1658
|
-
const cohortArgonsPerBlock = await api.query.blockRewards.argonsPerBlock().then((x) => x.toBigInt());
|
|
1659
|
-
return { argonotsPerSeat, argonotUsdPrice, cohortArgonsPerBlock };
|
|
1660
|
-
}
|
|
1661
1841
|
async start() {
|
|
1662
1842
|
console.log(`Starting cohort ${this.cohortId} bidder`, {
|
|
1663
1843
|
maxBid: formatArgons(this.options.maxBid),
|
|
1664
1844
|
minBid: formatArgons(this.options.minBid),
|
|
1665
1845
|
bidIncrement: formatArgons(this.options.bidIncrement),
|
|
1666
|
-
|
|
1846
|
+
maxBudget: formatArgons(this.options.maxBudget),
|
|
1667
1847
|
bidDelay: this.options.bidDelay,
|
|
1668
1848
|
subaccounts: this.subaccounts
|
|
1669
1849
|
});
|
|
1670
1850
|
const client = await this.client;
|
|
1671
|
-
|
|
1672
|
-
const startingStats = await _CohortBidder.getStartingData(client);
|
|
1673
|
-
Object.assign(this.stats, startingStats);
|
|
1674
|
-
}
|
|
1851
|
+
await this.history.init(client);
|
|
1675
1852
|
this.millisPerTick ??= await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber());
|
|
1676
1853
|
this.unsubscribe = await client.queryMulti(
|
|
1677
1854
|
[
|
|
@@ -1685,24 +1862,27 @@ var CohortBidder = class _CohortBidder {
|
|
|
1685
1862
|
}
|
|
1686
1863
|
);
|
|
1687
1864
|
}
|
|
1688
|
-
updateStats(next) {
|
|
1689
|
-
let seats = 0;
|
|
1690
|
-
let totalArgonsBid = 0n;
|
|
1691
|
-
for (const x of next) {
|
|
1692
|
-
if (this.allAddresses.has(x.accountId.toHuman())) {
|
|
1693
|
-
seats++;
|
|
1694
|
-
totalArgonsBid += x.bid.toBigInt();
|
|
1695
|
-
}
|
|
1696
|
-
}
|
|
1697
|
-
this.stats.seats = seats;
|
|
1698
|
-
this.stats.totalArgonsBid = totalArgonsBid;
|
|
1699
|
-
}
|
|
1700
1865
|
async checkSeats(next) {
|
|
1701
|
-
if (this.isStopped
|
|
1866
|
+
if (this.isStopped) return;
|
|
1867
|
+
clearTimeout(this.retryTimeout);
|
|
1868
|
+
const client = await this.client;
|
|
1869
|
+
const bestBlock = await client.rpc.chain.getBlockHash();
|
|
1870
|
+
const api = await client.at(bestBlock);
|
|
1871
|
+
const blockNumber = await api.query.system.number().then((x) => x.toNumber());
|
|
1872
|
+
if (this.bidHistory[0]?.blockNumber >= blockNumber) {
|
|
1873
|
+
return;
|
|
1874
|
+
}
|
|
1875
|
+
const tick = await api.query.ticks.currentTick().then((x) => x.toNumber());
|
|
1876
|
+
const historyEntry = this.history.trackChange(next, blockNumber, tick);
|
|
1877
|
+
if (this.pendingRequest) return;
|
|
1702
1878
|
const ticksSinceLastBid = Math.floor(
|
|
1703
1879
|
(Date.now() - this.lastBidTime) / this.millisPerTick
|
|
1704
1880
|
);
|
|
1705
1881
|
if (ticksSinceLastBid < this.options.bidDelay) {
|
|
1882
|
+
this.retryTimeout = setTimeout(
|
|
1883
|
+
() => void this.checkCurrentSeats(),
|
|
1884
|
+
this.millisPerTick
|
|
1885
|
+
);
|
|
1706
1886
|
return;
|
|
1707
1887
|
}
|
|
1708
1888
|
console.log(
|
|
@@ -1710,12 +1890,19 @@ var CohortBidder = class _CohortBidder {
|
|
|
1710
1890
|
this.cohortId,
|
|
1711
1891
|
this.subaccounts.map((x) => x.index)
|
|
1712
1892
|
);
|
|
1713
|
-
|
|
1714
|
-
this.needsRebid = this.subaccounts.
|
|
1715
|
-
(x) => !next.some((y) => y.accountId.toHuman() === x.address)
|
|
1716
|
-
);
|
|
1893
|
+
const winningBids = historyEntry.winningSeats;
|
|
1894
|
+
this.needsRebid = winningBids < this.subaccounts.length;
|
|
1717
1895
|
if (!this.needsRebid) return;
|
|
1718
|
-
const
|
|
1896
|
+
const winningAddresses = new Set(next.map((x) => x.accountId.toHuman()));
|
|
1897
|
+
let lowestBid = -this.options.bidIncrement;
|
|
1898
|
+
if (next.length) {
|
|
1899
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
1900
|
+
if (!this.myAddresses.has(next[i].accountId.toHuman())) {
|
|
1901
|
+
lowestBid = next.at(i).bid.toBigInt();
|
|
1902
|
+
break;
|
|
1903
|
+
}
|
|
1904
|
+
}
|
|
1905
|
+
}
|
|
1719
1906
|
const MIN_INCREMENT = 10000n;
|
|
1720
1907
|
let nextBid = lowestBid + this.options.bidIncrement;
|
|
1721
1908
|
if (nextBid < this.options.minBid) {
|
|
@@ -1723,83 +1910,119 @@ var CohortBidder = class _CohortBidder {
|
|
|
1723
1910
|
}
|
|
1724
1911
|
if (nextBid > this.options.maxBid) {
|
|
1725
1912
|
nextBid = this.options.maxBid;
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1913
|
+
}
|
|
1914
|
+
const fakeTx = await this.accountset.createMiningBidTx({
|
|
1915
|
+
subaccounts: this.subaccounts,
|
|
1916
|
+
bidAmount: nextBid,
|
|
1917
|
+
sendRewardsToSeed: true
|
|
1918
|
+
});
|
|
1919
|
+
let availableBalanceForBids = await api.query.system.account(this.accountset.txSubmitterPair.address).then((x) => x.data.free.toBigInt());
|
|
1920
|
+
for (const bid of next) {
|
|
1921
|
+
if (this.myAddresses.has(bid.accountId.toHuman())) {
|
|
1922
|
+
availableBalanceForBids += bid.bid.toBigInt();
|
|
1736
1923
|
}
|
|
1737
1924
|
}
|
|
1925
|
+
const tip = this.options.tipPerTransaction ?? 0n;
|
|
1926
|
+
const feeEstimate = await fakeTx.feeEstimate(tip);
|
|
1927
|
+
const feePlusTip = feeEstimate + tip;
|
|
1928
|
+
let budgetForSeats = this.options.maxBudget - feePlusTip;
|
|
1929
|
+
if (budgetForSeats > availableBalanceForBids) {
|
|
1930
|
+
budgetForSeats = availableBalanceForBids - feePlusTip;
|
|
1931
|
+
}
|
|
1738
1932
|
if (nextBid < lowestBid) {
|
|
1739
1933
|
console.log(
|
|
1740
1934
|
`Can't bid ${formatArgons(nextBid)}. Current lowest bid is ${formatArgons(
|
|
1741
1935
|
lowestBid
|
|
1742
1936
|
)}.`
|
|
1743
1937
|
);
|
|
1938
|
+
this.history.maybeReducingSeats(
|
|
1939
|
+
winningBids,
|
|
1940
|
+
"MaxBidTooLow" /* MaxBidTooLow */,
|
|
1941
|
+
historyEntry
|
|
1942
|
+
);
|
|
1744
1943
|
return;
|
|
1745
1944
|
}
|
|
1746
|
-
|
|
1747
|
-
if (seatsInBudget <= 0) {
|
|
1945
|
+
if (nextBid - lowestBid < MIN_INCREMENT) {
|
|
1748
1946
|
console.log(
|
|
1749
|
-
`Can't
|
|
1947
|
+
`Can't make any more bids for ${this.cohortId} with given constraints.`,
|
|
1948
|
+
{
|
|
1949
|
+
lowestCurrentBid: formatArgons(lowestBid),
|
|
1950
|
+
nextAttemptedBid: formatArgons(nextBid),
|
|
1951
|
+
maxBid: formatArgons(this.options.maxBid)
|
|
1952
|
+
}
|
|
1953
|
+
);
|
|
1954
|
+
this.history.maybeReducingSeats(
|
|
1955
|
+
winningBids,
|
|
1956
|
+
"MaxBidTooLow" /* MaxBidTooLow */,
|
|
1957
|
+
historyEntry
|
|
1750
1958
|
);
|
|
1751
1959
|
return;
|
|
1752
1960
|
}
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
if (
|
|
1763
|
-
if (!
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
}
|
|
1767
|
-
const removedIndices = this.subaccounts.filter((x) => !toKeep.some((y) => y.index === x.index)).map((x) => x.index);
|
|
1768
|
-
this.subaccounts = toKeep;
|
|
1769
|
-
console.log("Had to remove some subaccounts to fit in budget:", {
|
|
1770
|
-
removedIndices,
|
|
1771
|
-
seatsInBudget,
|
|
1772
|
-
budget: formatArgons(this.options.maxBalance)
|
|
1961
|
+
const seatsInBudget = nextBid === 0n ? this.subaccounts.length : Number(budgetForSeats / nextBid);
|
|
1962
|
+
let accountsToUse = [...this.subaccounts];
|
|
1963
|
+
if (accountsToUse.length > seatsInBudget) {
|
|
1964
|
+
const reason = availableBalanceForBids - feePlusTip < nextBid * BigInt(seatsInBudget) ? "InsufficientFunds" /* InsufficientFunds */ : "MaxBudgetTooLow" /* MaxBudgetTooLow */;
|
|
1965
|
+
this.history.maybeReducingSeats(seatsInBudget, reason, historyEntry);
|
|
1966
|
+
accountsToUse.sort((a, b) => {
|
|
1967
|
+
const isWinningA = winningAddresses.has(a.address);
|
|
1968
|
+
const isWinningB = winningAddresses.has(b.address);
|
|
1969
|
+
if (isWinningA && !isWinningB) return -1;
|
|
1970
|
+
if (!isWinningA && isWinningB) return 1;
|
|
1971
|
+
if (a.isRebid && !b.isRebid) return -1;
|
|
1972
|
+
if (!a.isRebid && b.isRebid) return 1;
|
|
1973
|
+
return a.index - b.index;
|
|
1773
1974
|
});
|
|
1975
|
+
accountsToUse.length = seatsInBudget;
|
|
1976
|
+
}
|
|
1977
|
+
if (accountsToUse.length > winningBids) {
|
|
1978
|
+
historyEntry.myBidsPlaced = {
|
|
1979
|
+
bids: accountsToUse.length,
|
|
1980
|
+
bidPerSeat: nextBid,
|
|
1981
|
+
txFeePlusTip: feePlusTip,
|
|
1982
|
+
successfulBids: 0
|
|
1983
|
+
};
|
|
1984
|
+
this.pendingRequest = this.bid(nextBid, accountsToUse, historyEntry);
|
|
1985
|
+
} else if (historyEntry.bidChanges.length === 0) {
|
|
1986
|
+
this.history.bidHistory.shift();
|
|
1774
1987
|
}
|
|
1775
|
-
this.pendingRequest = this.bid(
|
|
1776
|
-
nextBid,
|
|
1777
|
-
this.subaccounts.map((x) => x.index)
|
|
1778
|
-
);
|
|
1779
1988
|
this.needsRebid = false;
|
|
1780
1989
|
}
|
|
1781
|
-
async bid(bidPerSeat,
|
|
1782
|
-
if (!subaccountRange.length) return;
|
|
1990
|
+
async bid(bidPerSeat, subaccounts, historyEntry) {
|
|
1783
1991
|
const prevLastBidTime = this.lastBidTime;
|
|
1784
1992
|
try {
|
|
1785
1993
|
this.lastBidTime = Date.now();
|
|
1786
|
-
const
|
|
1787
|
-
|
|
1994
|
+
const submitter = await this.accountset.createMiningBidTx({
|
|
1995
|
+
subaccounts,
|
|
1788
1996
|
bidAmount: bidPerSeat,
|
|
1789
1997
|
sendRewardsToSeed: true
|
|
1790
1998
|
});
|
|
1791
|
-
|
|
1999
|
+
const tip = this.options.tipPerTransaction ?? 0n;
|
|
2000
|
+
const txResult = await submitter.submit({
|
|
2001
|
+
tip,
|
|
2002
|
+
useLatestNonce: true
|
|
2003
|
+
});
|
|
2004
|
+
const bidError = await txResult.inBlockPromise.then(() => void 0).catch((x) => x);
|
|
2005
|
+
let blockNumber;
|
|
2006
|
+
if (txResult.includedInBlock) {
|
|
1792
2007
|
const client = await this.client;
|
|
1793
|
-
const api = await client.at(
|
|
1794
|
-
|
|
2008
|
+
const api = await client.at(txResult.includedInBlock);
|
|
2009
|
+
blockNumber = await api.query.system.number().then((x) => x.toNumber());
|
|
1795
2010
|
}
|
|
1796
|
-
|
|
1797
|
-
this.
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
|
|
1802
|
-
|
|
2011
|
+
const successfulBids = txResult.batchInterruptedIndex ?? subaccounts.length;
|
|
2012
|
+
this.history.onBidResult(historyEntry, {
|
|
2013
|
+
blockNumber,
|
|
2014
|
+
successfulBids,
|
|
2015
|
+
bidPerSeat,
|
|
2016
|
+
txFeePlusTip: txResult.finalFee ?? 0n,
|
|
2017
|
+
bidsAttempted: subaccounts.length,
|
|
2018
|
+
bidError
|
|
2019
|
+
});
|
|
2020
|
+
console.log("Done creating bids for cohort", {
|
|
2021
|
+
successfulBids,
|
|
2022
|
+
bidPerSeat,
|
|
2023
|
+
blockNumber
|
|
2024
|
+
});
|
|
2025
|
+
if (bidError) throw bidError;
|
|
1803
2026
|
} catch (err) {
|
|
1804
2027
|
this.lastBidTime = prevLastBidTime;
|
|
1805
2028
|
console.error(`Error bidding for cohort ${this.cohortId}:`, err);
|
|
@@ -2479,8 +2702,8 @@ function vaultCli() {
|
|
|
2479
2702
|
).action(async ({ tip, argons, vaultId, ratio }) => {
|
|
2480
2703
|
const accountset = await accountsetFromCli(program2);
|
|
2481
2704
|
const client = await accountset.client;
|
|
2482
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2483
|
-
const microgons = BigInt(argons *
|
|
2705
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2706
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2484
2707
|
const rawVault = (await client.query.vaults.vaultsById(vaultId)).unwrap();
|
|
2485
2708
|
if (rawVault.operatorAccountId.toHuman() !== accountset.seedAddress) {
|
|
2486
2709
|
console.error("Vault does not belong to this account");
|
|
@@ -2540,8 +2763,8 @@ function vaultCli() {
|
|
|
2540
2763
|
}
|
|
2541
2764
|
const accountset = await accountsetFromCli(program2);
|
|
2542
2765
|
const client = await accountset.client;
|
|
2543
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2544
|
-
const microgons = BigInt(argons *
|
|
2766
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2767
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2545
2768
|
const bitcoinLocks = new BitcoinLocks(Promise.resolve(client));
|
|
2546
2769
|
const existentialDeposit = client.consts.balances.existentialDeposit.toBigInt();
|
|
2547
2770
|
const tickDuration = (await client.query.ticks.genesisTicker()).tickDurationMillis.toNumber();
|
|
@@ -2746,7 +2969,7 @@ function miningCli() {
|
|
|
2746
2969
|
const balance = await accountset.balance();
|
|
2747
2970
|
const feeWiggleRoom = BigInt(25e3);
|
|
2748
2971
|
const amountAvailable = balance - feeWiggleRoom;
|
|
2749
|
-
let maxBidAmount = maxBid ? BigInt(maxBid *
|
|
2972
|
+
let maxBidAmount = maxBid ? BigInt(maxBid * MICROGONS_PER_ARGON) : void 0;
|
|
2750
2973
|
let maxBalanceToUse = amountAvailable;
|
|
2751
2974
|
if (maxBalance !== void 0) {
|
|
2752
2975
|
if (maxBalance.endsWith("%")) {
|
|
@@ -2758,7 +2981,7 @@ function miningCli() {
|
|
|
2758
2981
|
maxBalanceToUse = amountToBid;
|
|
2759
2982
|
} else {
|
|
2760
2983
|
maxBalanceToUse = BigInt(
|
|
2761
|
-
Math.floor(parseFloat(maxBalance) *
|
|
2984
|
+
Math.floor(parseFloat(maxBalance) * MICROGONS_PER_ARGON)
|
|
2762
2985
|
);
|
|
2763
2986
|
}
|
|
2764
2987
|
maxBidAmount ??= maxBalanceToUse / BigInt(seatsToWin);
|
|
@@ -2780,9 +3003,11 @@ function miningCli() {
|
|
|
2780
3003
|
subaccountRange,
|
|
2781
3004
|
{
|
|
2782
3005
|
maxBid: maxBidAmount,
|
|
2783
|
-
minBid: BigInt((minBid ?? 0) *
|
|
2784
|
-
bidIncrement: BigInt(
|
|
2785
|
-
|
|
3006
|
+
minBid: BigInt((minBid ?? 0) * MICROGONS_PER_ARGON),
|
|
3007
|
+
bidIncrement: BigInt(
|
|
3008
|
+
Math.floor(bidIncrement * MICROGONS_PER_ARGON)
|
|
3009
|
+
),
|
|
3010
|
+
maxBudget: maxBalanceToUse,
|
|
2786
3011
|
bidDelay
|
|
2787
3012
|
}
|
|
2788
3013
|
);
|
|
@@ -2814,7 +3039,10 @@ function miningCli() {
|
|
|
2814
3039
|
);
|
|
2815
3040
|
const tx = client.tx.utility.batchAll([
|
|
2816
3041
|
client.tx.proxy.addProxy(address, "MiningBid", 0),
|
|
2817
|
-
client.tx.balances.transferAllowDeath(
|
|
3042
|
+
client.tx.balances.transferAllowDeath(
|
|
3043
|
+
address,
|
|
3044
|
+
BigInt(feeArgons * MICROGONS_PER_ARGON)
|
|
3045
|
+
)
|
|
2818
3046
|
]);
|
|
2819
3047
|
let keypair;
|
|
2820
3048
|
try {
|
|
@@ -2863,8 +3091,8 @@ function liquidityCli() {
|
|
|
2863
3091
|
parseFloat
|
|
2864
3092
|
).action(async ({ tip, argons, vaultId }) => {
|
|
2865
3093
|
const accountset = await accountsetFromCli(program2);
|
|
2866
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2867
|
-
const microgons = BigInt(argons *
|
|
3094
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
3095
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2868
3096
|
const bidPool = new BidPool(
|
|
2869
3097
|
accountset.client,
|
|
2870
3098
|
accountset.txSubmitterPair
|
|
@@ -2889,7 +3117,7 @@ function liquidityCli() {
|
|
|
2889
3117
|
"The tip to include with the transaction",
|
|
2890
3118
|
parseFloat
|
|
2891
3119
|
).action(async ({ maxArgons, minPctSharing, tip }) => {
|
|
2892
|
-
const maxAmountPerSlot = BigInt(maxArgons *
|
|
3120
|
+
const maxAmountPerSlot = BigInt(maxArgons * MICROGONS_PER_ARGON);
|
|
2893
3121
|
const accountset = await accountsetFromCli(program2);
|
|
2894
3122
|
const vaults = new VaultMonitor(
|
|
2895
3123
|
accountset,
|
|
@@ -2902,7 +3130,7 @@ function liquidityCli() {
|
|
|
2902
3130
|
accountset.client,
|
|
2903
3131
|
accountset.txSubmitterPair
|
|
2904
3132
|
);
|
|
2905
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
3133
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2906
3134
|
console.log("Waiting for liquidity pool space...");
|
|
2907
3135
|
vaults.events.on(
|
|
2908
3136
|
"liquidity-pool-space-above",
|
|
@@ -2941,7 +3169,7 @@ function bitcoinCli() {
|
|
|
2941
3169
|
).description("Watch for bitcoin space available").action(async ({ argons }) => {
|
|
2942
3170
|
const accountset = await accountsetFromCli(program2);
|
|
2943
3171
|
const bot = new VaultMonitor(accountset, {
|
|
2944
|
-
bitcoinSpaceAvailable: argons ? BigInt(argons *
|
|
3172
|
+
bitcoinSpaceAvailable: argons ? BigInt(argons * MICROGONS_PER_ARGON) : 1n
|
|
2945
3173
|
});
|
|
2946
3174
|
bot.events.on("bitcoin-space-above", async (vaultId, amount) => {
|
|
2947
3175
|
const vault = bot.vaultsById[vaultId];
|
|
@@ -2970,13 +3198,13 @@ function bitcoinCli() {
|
|
|
2970
3198
|
parseFloat,
|
|
2971
3199
|
0
|
|
2972
3200
|
).action(async ({ argons, bitcoinXpub, maxLockFee, tip }) => {
|
|
2973
|
-
const amountToLock = BigInt(argons *
|
|
3201
|
+
const amountToLock = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2974
3202
|
const accountset = await accountsetFromCli(program2);
|
|
2975
3203
|
await BitcoinLocks.waitForSpace(accountset, {
|
|
2976
3204
|
argonAmount: amountToLock,
|
|
2977
3205
|
bitcoinXpub,
|
|
2978
|
-
maxLockFee: maxLockFee !== void 0 ? BigInt(maxLockFee *
|
|
2979
|
-
tip: BigInt(tip *
|
|
3206
|
+
maxLockFee: maxLockFee !== void 0 ? BigInt(maxLockFee * MICROGONS_PER_ARGON) : void 0,
|
|
3207
|
+
tip: BigInt(tip * MICROGONS_PER_ARGON)
|
|
2980
3208
|
}).then(({ vaultId, satoshis, txFee, btcFee }) => {
|
|
2981
3209
|
console.log(
|
|
2982
3210
|
`Locked ${satoshis} satoshis in vault ${vaultId}. Tx fee=${formatArgons(
|
|
@@ -3001,8 +3229,13 @@ async function keyringFromFile(opts) {
|
|
|
3001
3229
|
}
|
|
3002
3230
|
const path = opts.filePath.replace("~", os.homedir());
|
|
3003
3231
|
const json = JSON.parse(await readFile(path, "utf-8"));
|
|
3232
|
+
let passphrase = opts.passphrase;
|
|
3233
|
+
if (opts.passphraseFile) {
|
|
3234
|
+
const passphrasePath = opts.passphraseFile.replace("~", os.homedir());
|
|
3235
|
+
passphrase = await readFile(passphrasePath, "utf-8");
|
|
3236
|
+
}
|
|
3004
3237
|
const mainAccount = new Keyring().createFromJson(json);
|
|
3005
|
-
mainAccount.decodePkcs8(
|
|
3238
|
+
mainAccount.decodePkcs8(passphrase);
|
|
3006
3239
|
return mainAccount;
|
|
3007
3240
|
}
|
|
3008
3241
|
async function saveKeyringPair(opts) {
|
|
@@ -3037,6 +3270,11 @@ function buildCli() {
|
|
|
3037
3270
|
"--account-passphrase <password>",
|
|
3038
3271
|
"The password for your seed file"
|
|
3039
3272
|
).env("ACCOUNT_PASSPHRASE")
|
|
3273
|
+
).addOption(
|
|
3274
|
+
new Option2(
|
|
3275
|
+
"--account-passphrase-file <path>",
|
|
3276
|
+
"The path to a password for your seed file"
|
|
3277
|
+
)
|
|
3040
3278
|
).addOption(
|
|
3041
3279
|
new Option2(
|
|
3042
3280
|
"-s, --subaccounts <range>",
|
|
@@ -3053,7 +3291,8 @@ async function accountsetFromCli(program2, proxyForAddress) {
|
|
|
3053
3291
|
if (opts.accountFilePath) {
|
|
3054
3292
|
keypair = await keyringFromFile({
|
|
3055
3293
|
filePath: opts.accountFilePath,
|
|
3056
|
-
passphrase: opts.accountPassphrase
|
|
3294
|
+
passphrase: opts.accountPassphrase,
|
|
3295
|
+
passphraseFile: opts.accountPassphraseFile
|
|
3057
3296
|
});
|
|
3058
3297
|
}
|
|
3059
3298
|
if (!keypair) {
|