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