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