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