@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.cjs
CHANGED
|
@@ -44,8 +44,10 @@ __export(index_exports, {
|
|
|
44
44
|
BitcoinLocks: () => BitcoinLocks,
|
|
45
45
|
BlockWatch: () => BlockWatch,
|
|
46
46
|
CohortBidder: () => CohortBidder,
|
|
47
|
+
ExtrinsicError: () => ExtrinsicError2,
|
|
47
48
|
JsonExt: () => JsonExt,
|
|
48
49
|
Keyring: () => import_api.Keyring,
|
|
50
|
+
MICROGONS_PER_ARGON: () => MICROGONS_PER_ARGON,
|
|
49
51
|
MiningBids: () => MiningBids,
|
|
50
52
|
MiningRotations: () => MiningRotations,
|
|
51
53
|
TxSubmitter: () => TxSubmitter,
|
|
@@ -57,6 +59,7 @@ __export(index_exports, {
|
|
|
57
59
|
convertPermillToBigNumber: () => convertPermillToBigNumber,
|
|
58
60
|
createKeyringPair: () => createKeyringPair,
|
|
59
61
|
decodeAddress: () => import_util_crypto.decodeAddress,
|
|
62
|
+
dispatchErrorToExtrinsicError: () => dispatchErrorToExtrinsicError,
|
|
60
63
|
dispatchErrorToString: () => dispatchErrorToString,
|
|
61
64
|
eventDataToJson: () => eventDataToJson,
|
|
62
65
|
filterUndefined: () => filterUndefined,
|
|
@@ -155,119 +158,6 @@ var WageProtector = class _WageProtector {
|
|
|
155
158
|
}
|
|
156
159
|
};
|
|
157
160
|
|
|
158
|
-
// src/utils.ts
|
|
159
|
-
var BN = __toESM(require("bignumber.js"), 1);
|
|
160
|
-
var { ROUND_FLOOR } = BN;
|
|
161
|
-
function formatArgons(x) {
|
|
162
|
-
const isNegative = x < 0;
|
|
163
|
-
let format = (0, BN.default)(x.toString()).abs().div(1e6).toFormat(2, ROUND_FLOOR);
|
|
164
|
-
if (format.endsWith(".00")) {
|
|
165
|
-
format = format.slice(0, -3);
|
|
166
|
-
}
|
|
167
|
-
return `${isNegative ? "-" : ""}\u20B3${format}`;
|
|
168
|
-
}
|
|
169
|
-
function formatPercent(x) {
|
|
170
|
-
if (!x) return "na";
|
|
171
|
-
return `${x.times(100).decimalPlaces(3)}%`;
|
|
172
|
-
}
|
|
173
|
-
function filterUndefined(obj) {
|
|
174
|
-
return Object.fromEntries(
|
|
175
|
-
Object.entries(obj).filter(
|
|
176
|
-
([_, value]) => value !== void 0 && value !== null
|
|
177
|
-
)
|
|
178
|
-
);
|
|
179
|
-
}
|
|
180
|
-
async function gettersToObject(obj) {
|
|
181
|
-
if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
|
|
182
|
-
const keys = [];
|
|
183
|
-
for (const key in obj) {
|
|
184
|
-
keys.push(key);
|
|
185
|
-
}
|
|
186
|
-
if (Symbol.iterator in obj) {
|
|
187
|
-
const iterableToArray = [];
|
|
188
|
-
for (const item of obj) {
|
|
189
|
-
iterableToArray.push(await gettersToObject(item));
|
|
190
|
-
}
|
|
191
|
-
return iterableToArray;
|
|
192
|
-
}
|
|
193
|
-
const result = {};
|
|
194
|
-
for (const key of keys) {
|
|
195
|
-
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
196
|
-
if (descriptor && typeof descriptor.value === "function") {
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
const value = descriptor && descriptor.get ? descriptor.get.call(obj) : obj[key];
|
|
200
|
-
if (typeof value === "function") continue;
|
|
201
|
-
result[key] = await gettersToObject(value);
|
|
202
|
-
}
|
|
203
|
-
return result;
|
|
204
|
-
}
|
|
205
|
-
function convertFixedU128ToBigNumber(fixedU128) {
|
|
206
|
-
const decimalFactor = new BN.default(10).pow(new BN.default(18));
|
|
207
|
-
const rawValue = new BN.default(fixedU128.toString());
|
|
208
|
-
return rawValue.div(decimalFactor);
|
|
209
|
-
}
|
|
210
|
-
function convertPermillToBigNumber(permill) {
|
|
211
|
-
const decimalFactor = new BN.default(1e6);
|
|
212
|
-
const rawValue = new BN.default(permill.toString());
|
|
213
|
-
return rawValue.div(decimalFactor);
|
|
214
|
-
}
|
|
215
|
-
function eventDataToJson(event) {
|
|
216
|
-
const obj = {};
|
|
217
|
-
event.data.forEach((data, index) => {
|
|
218
|
-
const name = event.data.names?.[index];
|
|
219
|
-
obj[name ?? `${index}`] = data.toJSON();
|
|
220
|
-
});
|
|
221
|
-
return obj;
|
|
222
|
-
}
|
|
223
|
-
function dispatchErrorToString(client, error) {
|
|
224
|
-
let message = error.toString();
|
|
225
|
-
if (error.isModule) {
|
|
226
|
-
const decoded = client.registry.findMetaError(error.asModule);
|
|
227
|
-
const { docs, name, section } = decoded;
|
|
228
|
-
message = `${section}.${name}: ${docs.join(" ")}`;
|
|
229
|
-
}
|
|
230
|
-
return message;
|
|
231
|
-
}
|
|
232
|
-
function checkForExtrinsicSuccess(events, client) {
|
|
233
|
-
return new Promise((resolve, reject) => {
|
|
234
|
-
for (const { event } of events) {
|
|
235
|
-
if (client.events.system.ExtrinsicSuccess.is(event)) {
|
|
236
|
-
resolve();
|
|
237
|
-
} else if (client.events.system.ExtrinsicFailed.is(event)) {
|
|
238
|
-
const [dispatchError] = event.data;
|
|
239
|
-
let errorInfo = dispatchError.toString();
|
|
240
|
-
if (dispatchError.isModule) {
|
|
241
|
-
const decoded = client.registry.findMetaError(dispatchError.asModule);
|
|
242
|
-
errorInfo = `${decoded.section}.${decoded.name}`;
|
|
243
|
-
}
|
|
244
|
-
reject(
|
|
245
|
-
new Error(
|
|
246
|
-
`${event.section}.${event.method}:: ExtrinsicFailed:: ${errorInfo}`
|
|
247
|
-
)
|
|
248
|
-
);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
});
|
|
252
|
-
}
|
|
253
|
-
var JsonExt = class {
|
|
254
|
-
static stringify(obj, space) {
|
|
255
|
-
return JSON.stringify(
|
|
256
|
-
obj,
|
|
257
|
-
(_, v) => typeof v === "bigint" ? `${v}n` : v,
|
|
258
|
-
space
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
static parse(str) {
|
|
262
|
-
return JSON.parse(str, (_, v) => {
|
|
263
|
-
if (typeof v === "string" && v.endsWith("n")) {
|
|
264
|
-
return BigInt(v.slice(0, -1));
|
|
265
|
-
}
|
|
266
|
-
return v;
|
|
267
|
-
});
|
|
268
|
-
}
|
|
269
|
-
};
|
|
270
|
-
|
|
271
161
|
// src/TxSubmitter.ts
|
|
272
162
|
function logExtrinsicResult(result) {
|
|
273
163
|
if (process.env.DEBUG) {
|
|
@@ -399,13 +289,12 @@ var TxResult = class {
|
|
|
399
289
|
}
|
|
400
290
|
}
|
|
401
291
|
if (encounteredError) {
|
|
402
|
-
const error =
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
this.reject(new Error(`Transaction failed: ${error}`));
|
|
292
|
+
const error = dispatchErrorToExtrinsicError(
|
|
293
|
+
this.client,
|
|
294
|
+
encounteredError,
|
|
295
|
+
batchErrorIndex
|
|
296
|
+
);
|
|
297
|
+
this.reject(error);
|
|
409
298
|
} else {
|
|
410
299
|
this.inBlockResolve(status.asInBlock.toU8a());
|
|
411
300
|
}
|
|
@@ -420,6 +309,147 @@ var TxResult = class {
|
|
|
420
309
|
}
|
|
421
310
|
};
|
|
422
311
|
|
|
312
|
+
// src/utils.ts
|
|
313
|
+
var BN = __toESM(require("bignumber.js"), 1);
|
|
314
|
+
var { ROUND_FLOOR } = BN;
|
|
315
|
+
var MICROGONS_PER_ARGON = 1e6;
|
|
316
|
+
function formatArgons(x) {
|
|
317
|
+
if (x === void 0 || x === null) return "na";
|
|
318
|
+
const isNegative = x < 0;
|
|
319
|
+
let format = (0, BN.default)(x.toString()).abs().div(MICROGONS_PER_ARGON).toFormat(2, ROUND_FLOOR);
|
|
320
|
+
if (format.endsWith(".00")) {
|
|
321
|
+
format = format.slice(0, -3);
|
|
322
|
+
}
|
|
323
|
+
return `${isNegative ? "-" : ""}\u20B3${format}`;
|
|
324
|
+
}
|
|
325
|
+
function formatPercent(x) {
|
|
326
|
+
if (!x) return "na";
|
|
327
|
+
return `${x.times(100).decimalPlaces(3)}%`;
|
|
328
|
+
}
|
|
329
|
+
function filterUndefined(obj) {
|
|
330
|
+
return Object.fromEntries(
|
|
331
|
+
Object.entries(obj).filter(
|
|
332
|
+
([_, value]) => value !== void 0 && value !== null
|
|
333
|
+
)
|
|
334
|
+
);
|
|
335
|
+
}
|
|
336
|
+
async function gettersToObject(obj) {
|
|
337
|
+
if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
|
|
338
|
+
const keys = [];
|
|
339
|
+
for (const key in obj) {
|
|
340
|
+
keys.push(key);
|
|
341
|
+
}
|
|
342
|
+
if (Symbol.iterator in obj) {
|
|
343
|
+
const iterableToArray = [];
|
|
344
|
+
for (const item of obj) {
|
|
345
|
+
iterableToArray.push(await gettersToObject(item));
|
|
346
|
+
}
|
|
347
|
+
return iterableToArray;
|
|
348
|
+
}
|
|
349
|
+
const result = {};
|
|
350
|
+
for (const key of keys) {
|
|
351
|
+
const descriptor = Object.getOwnPropertyDescriptor(obj, key);
|
|
352
|
+
if (descriptor && typeof descriptor.value === "function") {
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
const value = descriptor && descriptor.get ? descriptor.get.call(obj) : obj[key];
|
|
356
|
+
if (typeof value === "function") continue;
|
|
357
|
+
result[key] = await gettersToObject(value);
|
|
358
|
+
}
|
|
359
|
+
return result;
|
|
360
|
+
}
|
|
361
|
+
function convertFixedU128ToBigNumber(fixedU128) {
|
|
362
|
+
const decimalFactor = new BN.default(10).pow(new BN.default(18));
|
|
363
|
+
const rawValue = new BN.default(fixedU128.toString());
|
|
364
|
+
return rawValue.div(decimalFactor);
|
|
365
|
+
}
|
|
366
|
+
function convertPermillToBigNumber(permill) {
|
|
367
|
+
const decimalFactor = new BN.default(1e6);
|
|
368
|
+
const rawValue = new BN.default(permill.toString());
|
|
369
|
+
return rawValue.div(decimalFactor);
|
|
370
|
+
}
|
|
371
|
+
function eventDataToJson(event) {
|
|
372
|
+
const obj = {};
|
|
373
|
+
event.data.forEach((data, index) => {
|
|
374
|
+
const name = event.data.names?.[index];
|
|
375
|
+
obj[name ?? `${index}`] = data.toJSON();
|
|
376
|
+
});
|
|
377
|
+
return obj;
|
|
378
|
+
}
|
|
379
|
+
function dispatchErrorToString(client, error) {
|
|
380
|
+
let message = error.toString();
|
|
381
|
+
if (error.isModule) {
|
|
382
|
+
const decoded = client.registry.findMetaError(error.asModule);
|
|
383
|
+
const { docs, name, section } = decoded;
|
|
384
|
+
message = `${section}.${name}: ${docs.join(" ")}`;
|
|
385
|
+
}
|
|
386
|
+
return message;
|
|
387
|
+
}
|
|
388
|
+
var ExtrinsicError2 = class extends Error {
|
|
389
|
+
constructor(errorCode, details, batchInterruptedIndex) {
|
|
390
|
+
super(errorCode);
|
|
391
|
+
this.errorCode = errorCode;
|
|
392
|
+
this.details = details;
|
|
393
|
+
this.batchInterruptedIndex = batchInterruptedIndex;
|
|
394
|
+
}
|
|
395
|
+
toString() {
|
|
396
|
+
if (this.batchInterruptedIndex !== void 0) {
|
|
397
|
+
return `${this.errorCode} ${this.details ?? ""} (Batch interrupted at index ${this.batchInterruptedIndex})`;
|
|
398
|
+
}
|
|
399
|
+
return `${this.errorCode} ${this.details ?? ""}`;
|
|
400
|
+
}
|
|
401
|
+
};
|
|
402
|
+
function dispatchErrorToExtrinsicError(client, error, batchInterruptedIndex) {
|
|
403
|
+
if (error.isModule) {
|
|
404
|
+
const decoded = client.registry.findMetaError(error.asModule);
|
|
405
|
+
const { docs, name, section } = decoded;
|
|
406
|
+
return new ExtrinsicError2(
|
|
407
|
+
`${section}.${name}`,
|
|
408
|
+
docs.join(" "),
|
|
409
|
+
batchInterruptedIndex
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
return new ExtrinsicError2(error.toString(), void 0, batchInterruptedIndex);
|
|
413
|
+
}
|
|
414
|
+
function checkForExtrinsicSuccess(events, client) {
|
|
415
|
+
return new Promise((resolve, reject) => {
|
|
416
|
+
for (const { event } of events) {
|
|
417
|
+
if (client.events.system.ExtrinsicSuccess.is(event)) {
|
|
418
|
+
resolve();
|
|
419
|
+
} else if (client.events.system.ExtrinsicFailed.is(event)) {
|
|
420
|
+
const [dispatchError] = event.data;
|
|
421
|
+
let errorInfo = dispatchError.toString();
|
|
422
|
+
if (dispatchError.isModule) {
|
|
423
|
+
const decoded = client.registry.findMetaError(dispatchError.asModule);
|
|
424
|
+
errorInfo = `${decoded.section}.${decoded.name}`;
|
|
425
|
+
}
|
|
426
|
+
reject(
|
|
427
|
+
new Error(
|
|
428
|
+
`${event.section}.${event.method}:: ExtrinsicFailed:: ${errorInfo}`
|
|
429
|
+
)
|
|
430
|
+
);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
var JsonExt = class {
|
|
436
|
+
static stringify(obj, space) {
|
|
437
|
+
return JSON.stringify(
|
|
438
|
+
obj,
|
|
439
|
+
(_, v) => typeof v === "bigint" ? `${v}n` : v,
|
|
440
|
+
space
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
static parse(str) {
|
|
444
|
+
return JSON.parse(str, (_, v) => {
|
|
445
|
+
if (typeof v === "string" && v.endsWith("n")) {
|
|
446
|
+
return BigInt(v.slice(0, -1));
|
|
447
|
+
}
|
|
448
|
+
return v;
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
};
|
|
452
|
+
|
|
423
453
|
// src/AccountRegistry.ts
|
|
424
454
|
var AccountRegistry = class _AccountRegistry {
|
|
425
455
|
namedAccounts = /* @__PURE__ */ new Map();
|
|
@@ -652,7 +682,7 @@ var MiningRotations = class {
|
|
|
652
682
|
const slot1StartTick = this.genesisTick + this.miningConfig.slotBiddingStartAfterTicks + ticksBetweenSlots;
|
|
653
683
|
if (tick < slot1StartTick) return 0;
|
|
654
684
|
const ticksSinceSlot1 = tick - slot1StartTick;
|
|
655
|
-
return Math.floor(ticksSinceSlot1 / ticksBetweenSlots);
|
|
685
|
+
return Math.floor(ticksSinceSlot1 / ticksBetweenSlots) + 1;
|
|
656
686
|
}
|
|
657
687
|
async getForHeader(client, header) {
|
|
658
688
|
if (header.number.toNumber() === 0) return 0;
|
|
@@ -832,6 +862,14 @@ var Accountset = class {
|
|
|
832
862
|
);
|
|
833
863
|
}
|
|
834
864
|
}
|
|
865
|
+
async submitterBalance(blockHash) {
|
|
866
|
+
const client = await this.client;
|
|
867
|
+
const api = blockHash ? await client.at(blockHash) : client;
|
|
868
|
+
const accountData = await api.query.system.account(
|
|
869
|
+
this.txSubmitterPair.address
|
|
870
|
+
);
|
|
871
|
+
return accountData.data.free.toBigInt();
|
|
872
|
+
}
|
|
835
873
|
async balance(blockHash) {
|
|
836
874
|
const client = await this.client;
|
|
837
875
|
const api = blockHash ? await client.at(blockHash) : client;
|
|
@@ -1094,18 +1132,18 @@ var Accountset = class {
|
|
|
1094
1132
|
return new TxSubmitter(client, tx, this.txSubmitterPair);
|
|
1095
1133
|
}
|
|
1096
1134
|
/**
|
|
1097
|
-
* Create
|
|
1135
|
+
* Create but don't submit a mining bid transaction.
|
|
1136
|
+
* @param options
|
|
1098
1137
|
*/
|
|
1099
|
-
async
|
|
1100
|
-
const accounts = this.getAccountsInRange(options.subaccountRange);
|
|
1138
|
+
async createMiningBidTx(options) {
|
|
1101
1139
|
const client = await this.client;
|
|
1102
|
-
|
|
1140
|
+
const { bidAmount, subaccounts, sendRewardsToSeed } = options;
|
|
1103
1141
|
const batch = client.tx.utility.batch(
|
|
1104
|
-
|
|
1142
|
+
subaccounts.map((x) => {
|
|
1105
1143
|
const keys = this.keys();
|
|
1106
|
-
const rewards =
|
|
1144
|
+
const rewards = sendRewardsToSeed ? { Account: this.seedAddress } : { Owner: null };
|
|
1107
1145
|
return client.tx.miningSlot.bid(
|
|
1108
|
-
|
|
1146
|
+
bidAmount,
|
|
1109
1147
|
rewards,
|
|
1110
1148
|
{
|
|
1111
1149
|
grandpa: keys.gran.rawPublicKey,
|
|
@@ -1119,7 +1157,19 @@ var Accountset = class {
|
|
|
1119
1157
|
if (this.isProxy) {
|
|
1120
1158
|
tx = client.tx.proxy.proxy(this.seedAddress, "MiningBid", batch);
|
|
1121
1159
|
}
|
|
1122
|
-
|
|
1160
|
+
return new TxSubmitter(client, tx, this.txSubmitterPair);
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Create a mining bid. This will create a bid for each account in the given range from the seed account as funding.
|
|
1164
|
+
*/
|
|
1165
|
+
async createMiningBids(options) {
|
|
1166
|
+
const accounts = this.getAccountsInRange(options.subaccountRange);
|
|
1167
|
+
const client = await this.client;
|
|
1168
|
+
const submitter = await this.createMiningBidTx({
|
|
1169
|
+
...options,
|
|
1170
|
+
subaccounts: accounts
|
|
1171
|
+
});
|
|
1172
|
+
const { tip = 0n } = options;
|
|
1123
1173
|
const txFee = await submitter.feeEstimate(tip);
|
|
1124
1174
|
let minBalance = options.bidAmount * BigInt(accounts.length);
|
|
1125
1175
|
let totalFees = tip + 1n + txFee;
|
|
@@ -1563,27 +1613,24 @@ var VaultMonitor = class {
|
|
|
1563
1613
|
}
|
|
1564
1614
|
};
|
|
1565
1615
|
|
|
1566
|
-
// src/
|
|
1567
|
-
var
|
|
1568
|
-
constructor(
|
|
1569
|
-
this.accountset = accountset;
|
|
1616
|
+
// src/CohortBidderHistory.ts
|
|
1617
|
+
var CohortBidderHistory = class _CohortBidderHistory {
|
|
1618
|
+
constructor(cohortId, subaccounts) {
|
|
1570
1619
|
this.cohortId = cohortId;
|
|
1571
1620
|
this.subaccounts = subaccounts;
|
|
1572
|
-
this.
|
|
1621
|
+
this.maxSeatsInPlay = this.subaccounts.length;
|
|
1573
1622
|
this.subaccounts.forEach((x) => {
|
|
1574
|
-
this.
|
|
1623
|
+
this.myAddresses.add(x.address);
|
|
1575
1624
|
});
|
|
1576
1625
|
}
|
|
1577
|
-
|
|
1578
|
-
return this.accountset.client;
|
|
1579
|
-
}
|
|
1626
|
+
bidHistory = [];
|
|
1580
1627
|
stats = {
|
|
1581
1628
|
// number of seats won
|
|
1582
|
-
|
|
1629
|
+
seatsWon: 0,
|
|
1583
1630
|
// sum of argons bid in successful bids
|
|
1584
1631
|
totalArgonsBid: 0n,
|
|
1585
1632
|
// total number of bids placed (includes 1 per seat)
|
|
1586
|
-
|
|
1633
|
+
bidsAttempted: 0,
|
|
1587
1634
|
// fees including the tip
|
|
1588
1635
|
fees: 0n,
|
|
1589
1636
|
// Max bid per seat
|
|
@@ -1595,16 +1642,157 @@ var CohortBidder = class _CohortBidder {
|
|
|
1595
1642
|
// The cohort expected argons per block
|
|
1596
1643
|
cohortArgonsPerBlock: 0n,
|
|
1597
1644
|
// The last block that bids are synced to
|
|
1598
|
-
|
|
1645
|
+
lastBlockNumber: 0
|
|
1599
1646
|
};
|
|
1647
|
+
lastBids = [];
|
|
1648
|
+
myAddresses = /* @__PURE__ */ new Set();
|
|
1649
|
+
maxSeatsInPlay = 0;
|
|
1650
|
+
async init(client) {
|
|
1651
|
+
if (!this.stats.argonotsPerSeat) {
|
|
1652
|
+
const startingStats = await _CohortBidderHistory.getStartingData(client);
|
|
1653
|
+
Object.assign(this.stats, startingStats);
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
maybeReducingSeats(maxSeats, reason, historyEntry) {
|
|
1657
|
+
if (this.maxSeatsInPlay > maxSeats) {
|
|
1658
|
+
historyEntry.maxSeatsReductionReason = reason;
|
|
1659
|
+
}
|
|
1660
|
+
this.maxSeatsInPlay = maxSeats;
|
|
1661
|
+
historyEntry.maxSeatsInPlay = maxSeats;
|
|
1662
|
+
}
|
|
1663
|
+
trackChange(next, blockNumber, tick, isLastEntry = false) {
|
|
1664
|
+
let winningBids = 0;
|
|
1665
|
+
let totalArgonsBid = 0n;
|
|
1666
|
+
const nextEntrants = [];
|
|
1667
|
+
for (const x of next) {
|
|
1668
|
+
const bid = x.bid.toBigInt();
|
|
1669
|
+
const address = x.accountId.toHuman();
|
|
1670
|
+
nextEntrants.push({ address, bid });
|
|
1671
|
+
if (this.myAddresses.has(address)) {
|
|
1672
|
+
winningBids++;
|
|
1673
|
+
totalArgonsBid += bid;
|
|
1674
|
+
}
|
|
1675
|
+
}
|
|
1676
|
+
this.stats.seatsWon = winningBids;
|
|
1677
|
+
this.stats.totalArgonsBid = totalArgonsBid;
|
|
1678
|
+
this.stats.lastBlockNumber = Math.max(
|
|
1679
|
+
blockNumber,
|
|
1680
|
+
this.stats.lastBlockNumber
|
|
1681
|
+
);
|
|
1682
|
+
const historyEntry = {
|
|
1683
|
+
cohortId: this.cohortId,
|
|
1684
|
+
blockNumber,
|
|
1685
|
+
tick,
|
|
1686
|
+
bidChanges: [],
|
|
1687
|
+
winningSeats: winningBids,
|
|
1688
|
+
maxSeatsInPlay: this.maxSeatsInPlay
|
|
1689
|
+
};
|
|
1690
|
+
const hasDiffs = JsonExt.stringify(nextEntrants) !== JsonExt.stringify(this.lastBids);
|
|
1691
|
+
if (!isLastEntry || hasDiffs) {
|
|
1692
|
+
this.bidHistory.unshift(historyEntry);
|
|
1693
|
+
}
|
|
1694
|
+
if (hasDiffs) {
|
|
1695
|
+
nextEntrants.forEach(({ address, bid }, i) => {
|
|
1696
|
+
const prevBidIndex = this.lastBids.findIndex(
|
|
1697
|
+
(y) => y.address === address
|
|
1698
|
+
);
|
|
1699
|
+
const entry = {
|
|
1700
|
+
address,
|
|
1701
|
+
bidAmount: bid,
|
|
1702
|
+
bidPosition: i,
|
|
1703
|
+
prevPosition: prevBidIndex === -1 ? null : prevBidIndex
|
|
1704
|
+
};
|
|
1705
|
+
if (prevBidIndex !== -1) {
|
|
1706
|
+
const prevBidAmount = this.lastBids[prevBidIndex].bid;
|
|
1707
|
+
if (prevBidAmount !== bid) {
|
|
1708
|
+
entry.prevBidAmount = prevBidAmount;
|
|
1709
|
+
}
|
|
1710
|
+
}
|
|
1711
|
+
historyEntry.bidChanges.push(entry);
|
|
1712
|
+
});
|
|
1713
|
+
this.lastBids.forEach(({ address, bid }, i) => {
|
|
1714
|
+
const nextBid = nextEntrants.some((y) => y.address === address);
|
|
1715
|
+
if (!nextBid) {
|
|
1716
|
+
historyEntry.bidChanges.push({
|
|
1717
|
+
address,
|
|
1718
|
+
bidAmount: bid,
|
|
1719
|
+
bidPosition: null,
|
|
1720
|
+
prevPosition: i
|
|
1721
|
+
});
|
|
1722
|
+
}
|
|
1723
|
+
});
|
|
1724
|
+
this.lastBids = nextEntrants;
|
|
1725
|
+
}
|
|
1726
|
+
return historyEntry;
|
|
1727
|
+
}
|
|
1728
|
+
onBidResult(historyEntry, param) {
|
|
1729
|
+
const {
|
|
1730
|
+
txFeePlusTip,
|
|
1731
|
+
bidPerSeat,
|
|
1732
|
+
bidsAttempted,
|
|
1733
|
+
successfulBids,
|
|
1734
|
+
blockNumber,
|
|
1735
|
+
bidError
|
|
1736
|
+
} = param;
|
|
1737
|
+
this.stats.fees += txFeePlusTip;
|
|
1738
|
+
this.stats.bidsAttempted += bidsAttempted;
|
|
1739
|
+
if (bidPerSeat > this.stats.maxBidPerSeat) {
|
|
1740
|
+
this.stats.maxBidPerSeat = bidPerSeat;
|
|
1741
|
+
}
|
|
1742
|
+
if (blockNumber !== void 0) {
|
|
1743
|
+
this.stats.lastBlockNumber = Math.max(
|
|
1744
|
+
blockNumber,
|
|
1745
|
+
this.stats.lastBlockNumber
|
|
1746
|
+
);
|
|
1747
|
+
}
|
|
1748
|
+
historyEntry.myBidsPlaced.failureReason = bidError;
|
|
1749
|
+
historyEntry.myBidsPlaced.successfulBids = successfulBids;
|
|
1750
|
+
historyEntry.myBidsPlaced.txFeePlusTip = txFeePlusTip;
|
|
1751
|
+
}
|
|
1752
|
+
static async getStartingData(api) {
|
|
1753
|
+
const argonotPrice = await api.query.priceIndex.current();
|
|
1754
|
+
let argonotUsdPrice = 0;
|
|
1755
|
+
if (argonotPrice.isSome) {
|
|
1756
|
+
argonotUsdPrice = convertFixedU128ToBigNumber(
|
|
1757
|
+
argonotPrice.unwrap().argonotUsdPrice.toBigInt()
|
|
1758
|
+
).toNumber();
|
|
1759
|
+
}
|
|
1760
|
+
const argonotsPerSeat = await api.query.miningSlot.argonotsPerMiningSeat().then((x) => x.toBigInt());
|
|
1761
|
+
const cohortArgonsPerBlock = await api.query.blockRewards.argonsPerBlock().then((x) => x.toBigInt());
|
|
1762
|
+
return { argonotsPerSeat, argonotUsdPrice, cohortArgonsPerBlock };
|
|
1763
|
+
}
|
|
1764
|
+
};
|
|
1765
|
+
|
|
1766
|
+
// src/CohortBidder.ts
|
|
1767
|
+
var CohortBidder = class {
|
|
1768
|
+
constructor(accountset, cohortId, subaccounts, options) {
|
|
1769
|
+
this.accountset = accountset;
|
|
1770
|
+
this.cohortId = cohortId;
|
|
1771
|
+
this.subaccounts = subaccounts;
|
|
1772
|
+
this.options = options;
|
|
1773
|
+
this.history = new CohortBidderHistory(cohortId, subaccounts);
|
|
1774
|
+
this.subaccounts.forEach((x) => {
|
|
1775
|
+
this.myAddresses.add(x.address);
|
|
1776
|
+
});
|
|
1777
|
+
}
|
|
1778
|
+
get client() {
|
|
1779
|
+
return this.accountset.client;
|
|
1780
|
+
}
|
|
1781
|
+
get stats() {
|
|
1782
|
+
return this.history.stats;
|
|
1783
|
+
}
|
|
1784
|
+
get bidHistory() {
|
|
1785
|
+
return this.history.bidHistory;
|
|
1786
|
+
}
|
|
1600
1787
|
unsubscribe;
|
|
1601
1788
|
pendingRequest;
|
|
1602
1789
|
retryTimeout;
|
|
1603
1790
|
isStopped = false;
|
|
1604
1791
|
needsRebid = false;
|
|
1605
1792
|
lastBidTime = 0;
|
|
1793
|
+
history;
|
|
1606
1794
|
millisPerTick;
|
|
1607
|
-
|
|
1795
|
+
myAddresses = /* @__PURE__ */ new Set();
|
|
1608
1796
|
async stop() {
|
|
1609
1797
|
if (this.isStopped) return this.stats;
|
|
1610
1798
|
this.isStopped = true;
|
|
@@ -1614,70 +1802,59 @@ var CohortBidder = class _CohortBidder {
|
|
|
1614
1802
|
this.unsubscribe();
|
|
1615
1803
|
}
|
|
1616
1804
|
const client = await this.client;
|
|
1617
|
-
const [
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1805
|
+
const [nextCohortId, isBiddingOpen] = await client.queryMulti([
|
|
1806
|
+
client.query.miningSlot.nextCohortId,
|
|
1807
|
+
client.query.miningSlot.isNextSlotBiddingOpen
|
|
1808
|
+
]);
|
|
1809
|
+
if (nextCohortId.toNumber() === this.cohortId && isBiddingOpen.isTrue) {
|
|
1810
|
+
console.log("Bidding is still open, waiting for it to close");
|
|
1811
|
+
await new Promise(async (resolve) => {
|
|
1812
|
+
const unsub = await client.query.miningSlot.isNextSlotBiddingOpen(
|
|
1813
|
+
(isOpen) => {
|
|
1814
|
+
if (isOpen.isFalse) {
|
|
1815
|
+
unsub();
|
|
1816
|
+
resolve();
|
|
1817
|
+
}
|
|
1629
1818
|
}
|
|
1630
|
-
|
|
1631
|
-
);
|
|
1632
|
-
});
|
|
1633
|
-
void await this.pendingRequest;
|
|
1634
|
-
if (nextCohortId.toNumber() === this.cohortId) {
|
|
1635
|
-
console.log("Bidder updating stats with bid queue");
|
|
1636
|
-
this.updateStats(nextCohort);
|
|
1637
|
-
} else {
|
|
1638
|
-
const bestBlock = await client.rpc.chain.getBlockHash();
|
|
1639
|
-
const api = await client.at(bestBlock);
|
|
1640
|
-
const wonIndices = await api.query.miningSlot.accountIndexLookup.multi([...this.allAddresses]).then((x) => x.filter((x2) => x2.isSome).map((x2) => x2.value));
|
|
1641
|
-
const wonSeats = await api.query.miningSlot.activeMinersByIndex.multi(wonIndices).then(
|
|
1642
|
-
(x) => x.filter(
|
|
1643
|
-
(x2) => x2.isSome && x2.value.cohortId.toNumber() === this.cohortId
|
|
1644
|
-
).map((x2) => x2.value)
|
|
1645
|
-
);
|
|
1646
|
-
console.log("Bidder updating stats with finalized cohort");
|
|
1647
|
-
this.updateStats(wonSeats);
|
|
1819
|
+
);
|
|
1820
|
+
});
|
|
1648
1821
|
}
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1822
|
+
void await this.pendingRequest;
|
|
1823
|
+
let header = await client.rpc.chain.getHeader();
|
|
1824
|
+
while (true) {
|
|
1825
|
+
const api2 = await client.at(header.hash);
|
|
1826
|
+
const cohortId = await api2.query.miningSlot.nextCohortId();
|
|
1827
|
+
if (cohortId.toNumber() === this.cohortId) {
|
|
1828
|
+
break;
|
|
1829
|
+
}
|
|
1830
|
+
header = await client.rpc.chain.getHeader(header.parentHash);
|
|
1831
|
+
}
|
|
1832
|
+
const api = await client.at(header.hash);
|
|
1833
|
+
const tick = await api.query.ticks.currentTick().then((x) => x.toNumber());
|
|
1834
|
+
const cohort = await api.query.miningSlot.nextSlotCohort();
|
|
1835
|
+
this.history.trackChange(cohort, header.number.toNumber(), tick, true);
|
|
1836
|
+
console.log("Bidder stopped", {
|
|
1837
|
+
cohortId: this.cohortId,
|
|
1838
|
+
blockNumber: header.number.toNumber(),
|
|
1839
|
+
tick,
|
|
1840
|
+
cohort: cohort.map((x) => ({
|
|
1841
|
+
address: x.accountId.toHuman(),
|
|
1842
|
+
bid: x.bid.toBigInt()
|
|
1843
|
+
}))
|
|
1844
|
+
});
|
|
1653
1845
|
return this.stats;
|
|
1654
1846
|
}
|
|
1655
|
-
static async getStartingData(api) {
|
|
1656
|
-
const argonotPrice = await api.query.priceIndex.current();
|
|
1657
|
-
let argonotUsdPrice = 0;
|
|
1658
|
-
if (argonotPrice.isSome) {
|
|
1659
|
-
argonotUsdPrice = convertFixedU128ToBigNumber(
|
|
1660
|
-
argonotPrice.unwrap().argonotUsdPrice.toBigInt()
|
|
1661
|
-
).toNumber();
|
|
1662
|
-
}
|
|
1663
|
-
const argonotsPerSeat = await api.query.miningSlot.argonotsPerMiningSeat().then((x) => x.toBigInt());
|
|
1664
|
-
const cohortArgonsPerBlock = await api.query.blockRewards.argonsPerBlock().then((x) => x.toBigInt());
|
|
1665
|
-
return { argonotsPerSeat, argonotUsdPrice, cohortArgonsPerBlock };
|
|
1666
|
-
}
|
|
1667
1847
|
async start() {
|
|
1668
1848
|
console.log(`Starting cohort ${this.cohortId} bidder`, {
|
|
1669
1849
|
maxBid: formatArgons(this.options.maxBid),
|
|
1670
1850
|
minBid: formatArgons(this.options.minBid),
|
|
1671
1851
|
bidIncrement: formatArgons(this.options.bidIncrement),
|
|
1672
|
-
|
|
1852
|
+
maxBudget: formatArgons(this.options.maxBudget),
|
|
1673
1853
|
bidDelay: this.options.bidDelay,
|
|
1674
1854
|
subaccounts: this.subaccounts
|
|
1675
1855
|
});
|
|
1676
1856
|
const client = await this.client;
|
|
1677
|
-
|
|
1678
|
-
const startingStats = await _CohortBidder.getStartingData(client);
|
|
1679
|
-
Object.assign(this.stats, startingStats);
|
|
1680
|
-
}
|
|
1857
|
+
await this.history.init(client);
|
|
1681
1858
|
this.millisPerTick ??= await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber());
|
|
1682
1859
|
this.unsubscribe = await client.queryMulti(
|
|
1683
1860
|
[
|
|
@@ -1691,24 +1868,27 @@ var CohortBidder = class _CohortBidder {
|
|
|
1691
1868
|
}
|
|
1692
1869
|
);
|
|
1693
1870
|
}
|
|
1694
|
-
updateStats(next) {
|
|
1695
|
-
let seats = 0;
|
|
1696
|
-
let totalArgonsBid = 0n;
|
|
1697
|
-
for (const x of next) {
|
|
1698
|
-
if (this.allAddresses.has(x.accountId.toHuman())) {
|
|
1699
|
-
seats++;
|
|
1700
|
-
totalArgonsBid += x.bid.toBigInt();
|
|
1701
|
-
}
|
|
1702
|
-
}
|
|
1703
|
-
this.stats.seats = seats;
|
|
1704
|
-
this.stats.totalArgonsBid = totalArgonsBid;
|
|
1705
|
-
}
|
|
1706
1871
|
async checkSeats(next) {
|
|
1707
|
-
if (this.isStopped
|
|
1872
|
+
if (this.isStopped) return;
|
|
1873
|
+
clearTimeout(this.retryTimeout);
|
|
1874
|
+
const client = await this.client;
|
|
1875
|
+
const bestBlock = await client.rpc.chain.getBlockHash();
|
|
1876
|
+
const api = await client.at(bestBlock);
|
|
1877
|
+
const blockNumber = await api.query.system.number().then((x) => x.toNumber());
|
|
1878
|
+
if (this.bidHistory[0]?.blockNumber >= blockNumber) {
|
|
1879
|
+
return;
|
|
1880
|
+
}
|
|
1881
|
+
const tick = await api.query.ticks.currentTick().then((x) => x.toNumber());
|
|
1882
|
+
const historyEntry = this.history.trackChange(next, blockNumber, tick);
|
|
1883
|
+
if (this.pendingRequest) return;
|
|
1708
1884
|
const ticksSinceLastBid = Math.floor(
|
|
1709
1885
|
(Date.now() - this.lastBidTime) / this.millisPerTick
|
|
1710
1886
|
);
|
|
1711
1887
|
if (ticksSinceLastBid < this.options.bidDelay) {
|
|
1888
|
+
this.retryTimeout = setTimeout(
|
|
1889
|
+
() => void this.checkCurrentSeats(),
|
|
1890
|
+
this.millisPerTick
|
|
1891
|
+
);
|
|
1712
1892
|
return;
|
|
1713
1893
|
}
|
|
1714
1894
|
console.log(
|
|
@@ -1716,12 +1896,19 @@ var CohortBidder = class _CohortBidder {
|
|
|
1716
1896
|
this.cohortId,
|
|
1717
1897
|
this.subaccounts.map((x) => x.index)
|
|
1718
1898
|
);
|
|
1719
|
-
|
|
1720
|
-
this.needsRebid = this.subaccounts.
|
|
1721
|
-
(x) => !next.some((y) => y.accountId.toHuman() === x.address)
|
|
1722
|
-
);
|
|
1899
|
+
const winningBids = historyEntry.winningSeats;
|
|
1900
|
+
this.needsRebid = winningBids < this.subaccounts.length;
|
|
1723
1901
|
if (!this.needsRebid) return;
|
|
1724
|
-
const
|
|
1902
|
+
const winningAddresses = new Set(next.map((x) => x.accountId.toHuman()));
|
|
1903
|
+
let lowestBid = -this.options.bidIncrement;
|
|
1904
|
+
if (next.length) {
|
|
1905
|
+
for (let i = next.length - 1; i >= 0; i--) {
|
|
1906
|
+
if (!this.myAddresses.has(next[i].accountId.toHuman())) {
|
|
1907
|
+
lowestBid = next.at(i).bid.toBigInt();
|
|
1908
|
+
break;
|
|
1909
|
+
}
|
|
1910
|
+
}
|
|
1911
|
+
}
|
|
1725
1912
|
const MIN_INCREMENT = 10000n;
|
|
1726
1913
|
let nextBid = lowestBid + this.options.bidIncrement;
|
|
1727
1914
|
if (nextBid < this.options.minBid) {
|
|
@@ -1729,83 +1916,119 @@ var CohortBidder = class _CohortBidder {
|
|
|
1729
1916
|
}
|
|
1730
1917
|
if (nextBid > this.options.maxBid) {
|
|
1731
1918
|
nextBid = this.options.maxBid;
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1919
|
+
}
|
|
1920
|
+
const fakeTx = await this.accountset.createMiningBidTx({
|
|
1921
|
+
subaccounts: this.subaccounts,
|
|
1922
|
+
bidAmount: nextBid,
|
|
1923
|
+
sendRewardsToSeed: true
|
|
1924
|
+
});
|
|
1925
|
+
let availableBalanceForBids = await api.query.system.account(this.accountset.txSubmitterPair.address).then((x) => x.data.free.toBigInt());
|
|
1926
|
+
for (const bid of next) {
|
|
1927
|
+
if (this.myAddresses.has(bid.accountId.toHuman())) {
|
|
1928
|
+
availableBalanceForBids += bid.bid.toBigInt();
|
|
1742
1929
|
}
|
|
1743
1930
|
}
|
|
1931
|
+
const tip = this.options.tipPerTransaction ?? 0n;
|
|
1932
|
+
const feeEstimate = await fakeTx.feeEstimate(tip);
|
|
1933
|
+
const feePlusTip = feeEstimate + tip;
|
|
1934
|
+
let budgetForSeats = this.options.maxBudget - feePlusTip;
|
|
1935
|
+
if (budgetForSeats > availableBalanceForBids) {
|
|
1936
|
+
budgetForSeats = availableBalanceForBids - feePlusTip;
|
|
1937
|
+
}
|
|
1744
1938
|
if (nextBid < lowestBid) {
|
|
1745
1939
|
console.log(
|
|
1746
1940
|
`Can't bid ${formatArgons(nextBid)}. Current lowest bid is ${formatArgons(
|
|
1747
1941
|
lowestBid
|
|
1748
1942
|
)}.`
|
|
1749
1943
|
);
|
|
1944
|
+
this.history.maybeReducingSeats(
|
|
1945
|
+
winningBids,
|
|
1946
|
+
"MaxBidTooLow" /* MaxBidTooLow */,
|
|
1947
|
+
historyEntry
|
|
1948
|
+
);
|
|
1750
1949
|
return;
|
|
1751
1950
|
}
|
|
1752
|
-
|
|
1753
|
-
if (seatsInBudget <= 0) {
|
|
1951
|
+
if (nextBid - lowestBid < MIN_INCREMENT) {
|
|
1754
1952
|
console.log(
|
|
1755
|
-
`Can't
|
|
1953
|
+
`Can't make any more bids for ${this.cohortId} with given constraints.`,
|
|
1954
|
+
{
|
|
1955
|
+
lowestCurrentBid: formatArgons(lowestBid),
|
|
1956
|
+
nextAttemptedBid: formatArgons(nextBid),
|
|
1957
|
+
maxBid: formatArgons(this.options.maxBid)
|
|
1958
|
+
}
|
|
1959
|
+
);
|
|
1960
|
+
this.history.maybeReducingSeats(
|
|
1961
|
+
winningBids,
|
|
1962
|
+
"MaxBidTooLow" /* MaxBidTooLow */,
|
|
1963
|
+
historyEntry
|
|
1756
1964
|
);
|
|
1757
1965
|
return;
|
|
1758
1966
|
}
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
if (
|
|
1769
|
-
if (!
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
}
|
|
1773
|
-
const removedIndices = this.subaccounts.filter((x) => !toKeep.some((y) => y.index === x.index)).map((x) => x.index);
|
|
1774
|
-
this.subaccounts = toKeep;
|
|
1775
|
-
console.log("Had to remove some subaccounts to fit in budget:", {
|
|
1776
|
-
removedIndices,
|
|
1777
|
-
seatsInBudget,
|
|
1778
|
-
budget: formatArgons(this.options.maxBalance)
|
|
1967
|
+
const seatsInBudget = nextBid === 0n ? this.subaccounts.length : Number(budgetForSeats / nextBid);
|
|
1968
|
+
let accountsToUse = [...this.subaccounts];
|
|
1969
|
+
if (accountsToUse.length > seatsInBudget) {
|
|
1970
|
+
const reason = availableBalanceForBids - feePlusTip < nextBid * BigInt(seatsInBudget) ? "InsufficientFunds" /* InsufficientFunds */ : "MaxBudgetTooLow" /* MaxBudgetTooLow */;
|
|
1971
|
+
this.history.maybeReducingSeats(seatsInBudget, reason, historyEntry);
|
|
1972
|
+
accountsToUse.sort((a, b) => {
|
|
1973
|
+
const isWinningA = winningAddresses.has(a.address);
|
|
1974
|
+
const isWinningB = winningAddresses.has(b.address);
|
|
1975
|
+
if (isWinningA && !isWinningB) return -1;
|
|
1976
|
+
if (!isWinningA && isWinningB) return 1;
|
|
1977
|
+
if (a.isRebid && !b.isRebid) return -1;
|
|
1978
|
+
if (!a.isRebid && b.isRebid) return 1;
|
|
1979
|
+
return a.index - b.index;
|
|
1779
1980
|
});
|
|
1981
|
+
accountsToUse.length = seatsInBudget;
|
|
1982
|
+
}
|
|
1983
|
+
if (accountsToUse.length > winningBids) {
|
|
1984
|
+
historyEntry.myBidsPlaced = {
|
|
1985
|
+
bids: accountsToUse.length,
|
|
1986
|
+
bidPerSeat: nextBid,
|
|
1987
|
+
txFeePlusTip: feePlusTip,
|
|
1988
|
+
successfulBids: 0
|
|
1989
|
+
};
|
|
1990
|
+
this.pendingRequest = this.bid(nextBid, accountsToUse, historyEntry);
|
|
1991
|
+
} else if (historyEntry.bidChanges.length === 0) {
|
|
1992
|
+
this.history.bidHistory.shift();
|
|
1780
1993
|
}
|
|
1781
|
-
this.pendingRequest = this.bid(
|
|
1782
|
-
nextBid,
|
|
1783
|
-
this.subaccounts.map((x) => x.index)
|
|
1784
|
-
);
|
|
1785
1994
|
this.needsRebid = false;
|
|
1786
1995
|
}
|
|
1787
|
-
async bid(bidPerSeat,
|
|
1788
|
-
if (!subaccountRange.length) return;
|
|
1996
|
+
async bid(bidPerSeat, subaccounts, historyEntry) {
|
|
1789
1997
|
const prevLastBidTime = this.lastBidTime;
|
|
1790
1998
|
try {
|
|
1791
1999
|
this.lastBidTime = Date.now();
|
|
1792
|
-
const
|
|
1793
|
-
|
|
2000
|
+
const submitter = await this.accountset.createMiningBidTx({
|
|
2001
|
+
subaccounts,
|
|
1794
2002
|
bidAmount: bidPerSeat,
|
|
1795
2003
|
sendRewardsToSeed: true
|
|
1796
2004
|
});
|
|
1797
|
-
|
|
2005
|
+
const tip = this.options.tipPerTransaction ?? 0n;
|
|
2006
|
+
const txResult = await submitter.submit({
|
|
2007
|
+
tip,
|
|
2008
|
+
useLatestNonce: true
|
|
2009
|
+
});
|
|
2010
|
+
const bidError = await txResult.inBlockPromise.then(() => void 0).catch((x) => x);
|
|
2011
|
+
let blockNumber;
|
|
2012
|
+
if (txResult.includedInBlock) {
|
|
1798
2013
|
const client = await this.client;
|
|
1799
|
-
const api = await client.at(
|
|
1800
|
-
|
|
2014
|
+
const api = await client.at(txResult.includedInBlock);
|
|
2015
|
+
blockNumber = await api.query.system.number().then((x) => x.toNumber());
|
|
1801
2016
|
}
|
|
1802
|
-
|
|
1803
|
-
this.
|
|
1804
|
-
|
|
1805
|
-
|
|
1806
|
-
|
|
1807
|
-
|
|
1808
|
-
|
|
2017
|
+
const successfulBids = txResult.batchInterruptedIndex ?? subaccounts.length;
|
|
2018
|
+
this.history.onBidResult(historyEntry, {
|
|
2019
|
+
blockNumber,
|
|
2020
|
+
successfulBids,
|
|
2021
|
+
bidPerSeat,
|
|
2022
|
+
txFeePlusTip: txResult.finalFee ?? 0n,
|
|
2023
|
+
bidsAttempted: subaccounts.length,
|
|
2024
|
+
bidError
|
|
2025
|
+
});
|
|
2026
|
+
console.log("Done creating bids for cohort", {
|
|
2027
|
+
successfulBids,
|
|
2028
|
+
bidPerSeat,
|
|
2029
|
+
blockNumber
|
|
2030
|
+
});
|
|
2031
|
+
if (bidError) throw bidError;
|
|
1809
2032
|
} catch (err) {
|
|
1810
2033
|
this.lastBidTime = prevLastBidTime;
|
|
1811
2034
|
console.error(`Error bidding for cohort ${this.cohortId}:`, err);
|
|
@@ -2483,8 +2706,8 @@ function vaultCli() {
|
|
|
2483
2706
|
).action(async ({ tip, argons, vaultId, ratio }) => {
|
|
2484
2707
|
const accountset = await accountsetFromCli(program2);
|
|
2485
2708
|
const client = await accountset.client;
|
|
2486
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2487
|
-
const microgons = BigInt(argons *
|
|
2709
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2710
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2488
2711
|
const rawVault = (await client.query.vaults.vaultsById(vaultId)).unwrap();
|
|
2489
2712
|
if (rawVault.operatorAccountId.toHuman() !== accountset.seedAddress) {
|
|
2490
2713
|
console.error("Vault does not belong to this account");
|
|
@@ -2544,8 +2767,8 @@ function vaultCli() {
|
|
|
2544
2767
|
}
|
|
2545
2768
|
const accountset = await accountsetFromCli(program2);
|
|
2546
2769
|
const client = await accountset.client;
|
|
2547
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2548
|
-
const microgons = BigInt(argons *
|
|
2770
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2771
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2549
2772
|
const bitcoinLocks = new BitcoinLocks(Promise.resolve(client));
|
|
2550
2773
|
const existentialDeposit = client.consts.balances.existentialDeposit.toBigInt();
|
|
2551
2774
|
const tickDuration = (await client.query.ticks.genesisTicker()).tickDurationMillis.toNumber();
|
|
@@ -2750,7 +2973,7 @@ function miningCli() {
|
|
|
2750
2973
|
const balance = await accountset.balance();
|
|
2751
2974
|
const feeWiggleRoom = BigInt(25e3);
|
|
2752
2975
|
const amountAvailable = balance - feeWiggleRoom;
|
|
2753
|
-
let maxBidAmount = maxBid ? BigInt(maxBid *
|
|
2976
|
+
let maxBidAmount = maxBid ? BigInt(maxBid * MICROGONS_PER_ARGON) : void 0;
|
|
2754
2977
|
let maxBalanceToUse = amountAvailable;
|
|
2755
2978
|
if (maxBalance !== void 0) {
|
|
2756
2979
|
if (maxBalance.endsWith("%")) {
|
|
@@ -2762,7 +2985,7 @@ function miningCli() {
|
|
|
2762
2985
|
maxBalanceToUse = amountToBid;
|
|
2763
2986
|
} else {
|
|
2764
2987
|
maxBalanceToUse = BigInt(
|
|
2765
|
-
Math.floor(parseFloat(maxBalance) *
|
|
2988
|
+
Math.floor(parseFloat(maxBalance) * MICROGONS_PER_ARGON)
|
|
2766
2989
|
);
|
|
2767
2990
|
}
|
|
2768
2991
|
maxBidAmount ??= maxBalanceToUse / BigInt(seatsToWin);
|
|
@@ -2784,9 +3007,11 @@ function miningCli() {
|
|
|
2784
3007
|
subaccountRange,
|
|
2785
3008
|
{
|
|
2786
3009
|
maxBid: maxBidAmount,
|
|
2787
|
-
minBid: BigInt((minBid ?? 0) *
|
|
2788
|
-
bidIncrement: BigInt(
|
|
2789
|
-
|
|
3010
|
+
minBid: BigInt((minBid ?? 0) * MICROGONS_PER_ARGON),
|
|
3011
|
+
bidIncrement: BigInt(
|
|
3012
|
+
Math.floor(bidIncrement * MICROGONS_PER_ARGON)
|
|
3013
|
+
),
|
|
3014
|
+
maxBudget: maxBalanceToUse,
|
|
2790
3015
|
bidDelay
|
|
2791
3016
|
}
|
|
2792
3017
|
);
|
|
@@ -2818,7 +3043,10 @@ function miningCli() {
|
|
|
2818
3043
|
);
|
|
2819
3044
|
const tx = client.tx.utility.batchAll([
|
|
2820
3045
|
client.tx.proxy.addProxy(address, "MiningBid", 0),
|
|
2821
|
-
client.tx.balances.transferAllowDeath(
|
|
3046
|
+
client.tx.balances.transferAllowDeath(
|
|
3047
|
+
address,
|
|
3048
|
+
BigInt(feeArgons * MICROGONS_PER_ARGON)
|
|
3049
|
+
)
|
|
2822
3050
|
]);
|
|
2823
3051
|
let keypair;
|
|
2824
3052
|
try {
|
|
@@ -2867,8 +3095,8 @@ function liquidityCli() {
|
|
|
2867
3095
|
parseFloat
|
|
2868
3096
|
).action(async ({ tip, argons, vaultId }) => {
|
|
2869
3097
|
const accountset = await accountsetFromCli(program2);
|
|
2870
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
2871
|
-
const microgons = BigInt(argons *
|
|
3098
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
3099
|
+
const microgons = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2872
3100
|
const bidPool = new BidPool(
|
|
2873
3101
|
accountset.client,
|
|
2874
3102
|
accountset.txSubmitterPair
|
|
@@ -2893,7 +3121,7 @@ function liquidityCli() {
|
|
|
2893
3121
|
"The tip to include with the transaction",
|
|
2894
3122
|
parseFloat
|
|
2895
3123
|
).action(async ({ maxArgons, minPctSharing, tip }) => {
|
|
2896
|
-
const maxAmountPerSlot = BigInt(maxArgons *
|
|
3124
|
+
const maxAmountPerSlot = BigInt(maxArgons * MICROGONS_PER_ARGON);
|
|
2897
3125
|
const accountset = await accountsetFromCli(program2);
|
|
2898
3126
|
const vaults = new VaultMonitor(
|
|
2899
3127
|
accountset,
|
|
@@ -2906,7 +3134,7 @@ function liquidityCli() {
|
|
|
2906
3134
|
accountset.client,
|
|
2907
3135
|
accountset.txSubmitterPair
|
|
2908
3136
|
);
|
|
2909
|
-
const resolvedTip = tip ? BigInt(tip *
|
|
3137
|
+
const resolvedTip = tip ? BigInt(tip * MICROGONS_PER_ARGON) : 0n;
|
|
2910
3138
|
console.log("Waiting for liquidity pool space...");
|
|
2911
3139
|
vaults.events.on(
|
|
2912
3140
|
"liquidity-pool-space-above",
|
|
@@ -2945,7 +3173,7 @@ function bitcoinCli() {
|
|
|
2945
3173
|
).description("Watch for bitcoin space available").action(async ({ argons }) => {
|
|
2946
3174
|
const accountset = await accountsetFromCli(program2);
|
|
2947
3175
|
const bot = new VaultMonitor(accountset, {
|
|
2948
|
-
bitcoinSpaceAvailable: argons ? BigInt(argons *
|
|
3176
|
+
bitcoinSpaceAvailable: argons ? BigInt(argons * MICROGONS_PER_ARGON) : 1n
|
|
2949
3177
|
});
|
|
2950
3178
|
bot.events.on("bitcoin-space-above", async (vaultId, amount) => {
|
|
2951
3179
|
const vault = bot.vaultsById[vaultId];
|
|
@@ -2974,13 +3202,13 @@ function bitcoinCli() {
|
|
|
2974
3202
|
parseFloat,
|
|
2975
3203
|
0
|
|
2976
3204
|
).action(async ({ argons, bitcoinXpub, maxLockFee, tip }) => {
|
|
2977
|
-
const amountToLock = BigInt(argons *
|
|
3205
|
+
const amountToLock = BigInt(argons * MICROGONS_PER_ARGON);
|
|
2978
3206
|
const accountset = await accountsetFromCli(program2);
|
|
2979
3207
|
await BitcoinLocks.waitForSpace(accountset, {
|
|
2980
3208
|
argonAmount: amountToLock,
|
|
2981
3209
|
bitcoinXpub,
|
|
2982
|
-
maxLockFee: maxLockFee !== void 0 ? BigInt(maxLockFee *
|
|
2983
|
-
tip: BigInt(tip *
|
|
3210
|
+
maxLockFee: maxLockFee !== void 0 ? BigInt(maxLockFee * MICROGONS_PER_ARGON) : void 0,
|
|
3211
|
+
tip: BigInt(tip * MICROGONS_PER_ARGON)
|
|
2984
3212
|
}).then(({ vaultId, satoshis, txFee, btcFee }) => {
|
|
2985
3213
|
console.log(
|
|
2986
3214
|
`Locked ${satoshis} satoshis in vault ${vaultId}. Tx fee=${formatArgons(
|
|
@@ -3005,8 +3233,13 @@ async function keyringFromFile(opts) {
|
|
|
3005
3233
|
}
|
|
3006
3234
|
const path = opts.filePath.replace("~", os.homedir());
|
|
3007
3235
|
const json = JSON.parse(await readFile(path, "utf-8"));
|
|
3236
|
+
let passphrase = opts.passphrase;
|
|
3237
|
+
if (opts.passphraseFile) {
|
|
3238
|
+
const passphrasePath = opts.passphraseFile.replace("~", os.homedir());
|
|
3239
|
+
passphrase = await readFile(passphrasePath, "utf-8");
|
|
3240
|
+
}
|
|
3008
3241
|
const mainAccount = new import_api.Keyring().createFromJson(json);
|
|
3009
|
-
mainAccount.decodePkcs8(
|
|
3242
|
+
mainAccount.decodePkcs8(passphrase);
|
|
3010
3243
|
return mainAccount;
|
|
3011
3244
|
}
|
|
3012
3245
|
async function saveKeyringPair(opts) {
|
|
@@ -3041,6 +3274,11 @@ function buildCli() {
|
|
|
3041
3274
|
"--account-passphrase <password>",
|
|
3042
3275
|
"The password for your seed file"
|
|
3043
3276
|
).env("ACCOUNT_PASSPHRASE")
|
|
3277
|
+
).addOption(
|
|
3278
|
+
new import_extra_typings6.Option(
|
|
3279
|
+
"--account-passphrase-file <path>",
|
|
3280
|
+
"The path to a password for your seed file"
|
|
3281
|
+
)
|
|
3044
3282
|
).addOption(
|
|
3045
3283
|
new import_extra_typings6.Option(
|
|
3046
3284
|
"-s, --subaccounts <range>",
|
|
@@ -3057,7 +3295,8 @@ async function accountsetFromCli(program2, proxyForAddress) {
|
|
|
3057
3295
|
if (opts.accountFilePath) {
|
|
3058
3296
|
keypair = await keyringFromFile({
|
|
3059
3297
|
filePath: opts.accountFilePath,
|
|
3060
|
-
passphrase: opts.accountPassphrase
|
|
3298
|
+
passphrase: opts.accountPassphrase,
|
|
3299
|
+
passphraseFile: opts.accountPassphraseFile
|
|
3061
3300
|
});
|
|
3062
3301
|
}
|
|
3063
3302
|
if (!keypair) {
|