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