@argonprotocol/mainchain 1.3.6 → 1.3.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 +7 -190
- package/browser/index.d.ts +483 -1977
- package/browser/index.js +109 -1974
- package/browser/index.js.map +1 -1
- package/lib/index.cjs +1006 -68
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +483 -1977
- package/lib/index.d.ts +483 -1977
- package/lib/index.js +1018 -80
- package/lib/index.js.map +1 -1
- package/package.json +19 -27
- package/lib/chunk-FGSUNAT4.js +0 -2970
- package/lib/chunk-FGSUNAT4.js.map +0 -1
- package/lib/chunk-KMBXJV55.js +0 -743
- package/lib/chunk-KMBXJV55.js.map +0 -1
- package/lib/chunk-KYRBSY6G.cjs +0 -743
- package/lib/chunk-KYRBSY6G.cjs.map +0 -1
- package/lib/chunk-U6J3AWYW.cjs +0 -2970
- package/lib/chunk-U6J3AWYW.cjs.map +0 -1
- package/lib/cli.cjs +0 -19
- package/lib/cli.cjs.map +0 -1
- package/lib/cli.d.cts +0 -1
- package/lib/cli.d.ts +0 -1
- package/lib/cli.js +0 -19
- package/lib/cli.js.map +0 -1
- package/lib/clis/index.cjs +0 -30
- package/lib/clis/index.cjs.map +0 -1
- package/lib/clis/index.d.cts +0 -129
- package/lib/clis/index.d.ts +0 -129
- package/lib/clis/index.js +0 -30
- package/lib/clis/index.js.map +0 -1
package/browser/index.js
CHANGED
|
@@ -11,12 +11,11 @@ import { Keyring, HttpProvider, WsProvider, ApiPromise } from '@polkadot/api';
|
|
|
11
11
|
export { Keyring } from '@polkadot/api';
|
|
12
12
|
import { mnemonicGenerate, cryptoWaitReady } from '@polkadot/util-crypto';
|
|
13
13
|
export { decodeAddress, mnemonicGenerate } from '@polkadot/util-crypto';
|
|
14
|
-
import * as
|
|
15
|
-
import
|
|
16
|
-
import { u8aToHex, hexToU8a } from '@polkadot/util';
|
|
17
|
-
export { hexToU8a, u8aEq, u8aToHex } from '@polkadot/util';
|
|
18
|
-
import { printTable, Table } from 'console-table-printer';
|
|
14
|
+
import * as BigNumber2 from 'bignumber.js';
|
|
15
|
+
import BigNumber2__default from 'bignumber.js';
|
|
19
16
|
import bs58check from 'bs58check';
|
|
17
|
+
import { hexToU8a, u8aToHex } from '@polkadot/util';
|
|
18
|
+
export { hexToU8a, u8aEq, u8aToHex } from '@polkadot/util';
|
|
20
19
|
export { GenericAddress, GenericBlock, GenericEvent } from '@polkadot/types/generic';
|
|
21
20
|
export { BTreeMap, Bool, Bytes, Compact, Enum, Null, Option, Range, Result, Struct, Text, Tuple, U256, U8aFixed, Vec, bool, i128, u128, u16, u32, u64, u8 } from '@polkadot/types-codec';
|
|
22
21
|
|
|
@@ -79,33 +78,11 @@ var WageProtector = class _WageProtector {
|
|
|
79
78
|
}
|
|
80
79
|
};
|
|
81
80
|
|
|
82
|
-
// src/config.ts
|
|
83
|
-
var config = {};
|
|
84
|
-
function getEnvVar(key) {
|
|
85
|
-
if (typeof process !== "undefined" && process.env) {
|
|
86
|
-
return process.env[key];
|
|
87
|
-
}
|
|
88
|
-
return void 0;
|
|
89
|
-
}
|
|
90
|
-
function setConfig(newConfig) {
|
|
91
|
-
config = { ...config, ...newConfig };
|
|
92
|
-
}
|
|
93
|
-
function getConfig() {
|
|
94
|
-
return {
|
|
95
|
-
debug: config.debug ?? getEnvVar("DEBUG") === "true",
|
|
96
|
-
keysVersion: config.keysVersion ?? (getEnvVar("KEYS_VERSION") ? parseInt(getEnvVar("KEYS_VERSION")) : void 0),
|
|
97
|
-
keysMnemonic: config.keysMnemonic ?? getEnvVar("KEYS_MNEMONIC"),
|
|
98
|
-
subaccountRange: config.subaccountRange ?? getEnvVar("SUBACCOUNT_RANGE") ?? "0-9"
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
|
|
102
81
|
// src/TxSubmitter.ts
|
|
103
82
|
function logExtrinsicResult(result) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
console.debug('Transaction update: "%s"', status, json[status]);
|
|
108
|
-
}
|
|
83
|
+
const json = result.status.toJSON();
|
|
84
|
+
const status = Object.keys(json)[0];
|
|
85
|
+
console.debug('Transaction update: "%s"', status, json[status]);
|
|
109
86
|
}
|
|
110
87
|
var TxSubmitter = class {
|
|
111
88
|
constructor(client, tx, pair) {
|
|
@@ -137,7 +114,7 @@ var TxSubmitter = class {
|
|
|
137
114
|
const result = new TxResult(this.client, logResults);
|
|
138
115
|
result.txProgressCallback = options.txProgressCallback;
|
|
139
116
|
let toHuman = this.tx.toHuman().method;
|
|
140
|
-
|
|
117
|
+
const txString = [];
|
|
141
118
|
let api = formatCall(toHuman);
|
|
142
119
|
const args = [];
|
|
143
120
|
if (api === "proxy.proxy") {
|
|
@@ -201,10 +178,8 @@ var TxResult = class {
|
|
|
201
178
|
this.finalizedResolve = resolve;
|
|
202
179
|
this.finalizedReject = reject;
|
|
203
180
|
});
|
|
204
|
-
this.inBlockPromise.catch(() =>
|
|
205
|
-
|
|
206
|
-
this.finalizedPromise.catch(() => {
|
|
207
|
-
});
|
|
181
|
+
this.inBlockPromise.catch(() => null);
|
|
182
|
+
this.finalizedPromise.catch(() => null);
|
|
208
183
|
}
|
|
209
184
|
onResult(result) {
|
|
210
185
|
this.status = result.status;
|
|
@@ -254,26 +229,17 @@ var TxResult = class {
|
|
|
254
229
|
this.finalizedReject(error);
|
|
255
230
|
}
|
|
256
231
|
};
|
|
257
|
-
var { ROUND_FLOOR } =
|
|
232
|
+
var { ROUND_FLOOR } = BigNumber2;
|
|
258
233
|
var MICROGONS_PER_ARGON = 1e6;
|
|
259
234
|
function formatArgons(microgons) {
|
|
260
235
|
if (microgons === void 0 || microgons === null) return "na";
|
|
261
236
|
const isNegative = microgons < 0;
|
|
262
|
-
let format =
|
|
237
|
+
let format = BigNumber2__default(microgons.toString()).abs().div(MICROGONS_PER_ARGON).toFormat(2, ROUND_FLOOR);
|
|
263
238
|
if (format.endsWith(".00")) {
|
|
264
239
|
format = format.slice(0, -3);
|
|
265
240
|
}
|
|
266
241
|
return `${isNegative ? "-" : ""}\u20B3${format}`;
|
|
267
242
|
}
|
|
268
|
-
function formatPercent(x) {
|
|
269
|
-
if (!x) return "na";
|
|
270
|
-
return `${x.times(100).decimalPlaces(3)}%`;
|
|
271
|
-
}
|
|
272
|
-
function filterUndefined(obj) {
|
|
273
|
-
return Object.fromEntries(
|
|
274
|
-
Object.entries(obj).filter(([_, value]) => value !== void 0 && value !== null)
|
|
275
|
-
);
|
|
276
|
-
}
|
|
277
243
|
async function gettersToObject(obj) {
|
|
278
244
|
if (obj === null || obj === void 0 || typeof obj !== "object") return obj;
|
|
279
245
|
const keys = [];
|
|
@@ -299,36 +265,6 @@ async function gettersToObject(obj) {
|
|
|
299
265
|
}
|
|
300
266
|
return result;
|
|
301
267
|
}
|
|
302
|
-
function toFixedNumber(value, decimals) {
|
|
303
|
-
const factor = new BigNumber__default(10).pow(decimals);
|
|
304
|
-
const bn = new BigNumber__default(value);
|
|
305
|
-
const int = bn.times(factor).integerValue(BigNumber__default.ROUND_DOWN);
|
|
306
|
-
return BigInt(int.toFixed(0));
|
|
307
|
-
}
|
|
308
|
-
function convertNumberToFixedU128(value) {
|
|
309
|
-
return toFixedNumber(value, 18);
|
|
310
|
-
}
|
|
311
|
-
function convertFixedU128ToBigNumber(fixedU128) {
|
|
312
|
-
const decimalFactor = new BigNumber__default(10).pow(new BigNumber__default(18));
|
|
313
|
-
const rawValue = new BigNumber__default(fixedU128.toString());
|
|
314
|
-
return rawValue.div(decimalFactor);
|
|
315
|
-
}
|
|
316
|
-
function convertPermillToBigNumber(permill) {
|
|
317
|
-
const decimalFactor = new BigNumber__default(1e6);
|
|
318
|
-
const rawValue = new BigNumber__default(permill.toString());
|
|
319
|
-
return rawValue.div(decimalFactor);
|
|
320
|
-
}
|
|
321
|
-
function convertNumberToPermill(value) {
|
|
322
|
-
return toFixedNumber(value, 6);
|
|
323
|
-
}
|
|
324
|
-
function eventDataToJson(event) {
|
|
325
|
-
const obj = {};
|
|
326
|
-
event.data.forEach((data, index) => {
|
|
327
|
-
const name = event.data.names?.[index];
|
|
328
|
-
obj[name ?? `${index}`] = data.toJSON();
|
|
329
|
-
});
|
|
330
|
-
return obj;
|
|
331
|
-
}
|
|
332
268
|
function dispatchErrorToString(client, error) {
|
|
333
269
|
let message = error.toString();
|
|
334
270
|
if (error.isModule) {
|
|
@@ -377,79 +313,18 @@ function checkForExtrinsicSuccess(events, client) {
|
|
|
377
313
|
}
|
|
378
314
|
});
|
|
379
315
|
}
|
|
380
|
-
var JsonExt = class {
|
|
381
|
-
static stringify(obj, space) {
|
|
382
|
-
return JSON.stringify(
|
|
383
|
-
obj,
|
|
384
|
-
(_, v) => {
|
|
385
|
-
if (typeof v === "bigint") {
|
|
386
|
-
return `${v}n`;
|
|
387
|
-
}
|
|
388
|
-
if (v instanceof Uint8Array) {
|
|
389
|
-
return {
|
|
390
|
-
type: "Buffer",
|
|
391
|
-
data: Array.from(v)
|
|
392
|
-
// Convert Uint8Array to an array of numbers
|
|
393
|
-
};
|
|
394
|
-
}
|
|
395
|
-
return v;
|
|
396
|
-
},
|
|
397
|
-
space
|
|
398
|
-
);
|
|
399
|
-
}
|
|
400
|
-
static parse(str) {
|
|
401
|
-
return JSON.parse(str, (_, v) => {
|
|
402
|
-
if (typeof v === "string" && v.match(/^\d+n$/)) {
|
|
403
|
-
return BigInt(v.slice(0, -1));
|
|
404
|
-
}
|
|
405
|
-
if (typeof v === "object" && v !== null && v.type === "Buffer" && Array.isArray(v.data)) {
|
|
406
|
-
return Uint8Array.from(v.data);
|
|
407
|
-
}
|
|
408
|
-
return v;
|
|
409
|
-
});
|
|
410
|
-
}
|
|
411
|
-
};
|
|
412
|
-
function createNanoEvents() {
|
|
413
|
-
return new TypedEmitter();
|
|
414
|
-
}
|
|
415
|
-
var TypedEmitter = class {
|
|
416
|
-
constructor() {
|
|
417
|
-
__publicField(this, "events", {});
|
|
418
|
-
}
|
|
419
|
-
emit(event, ...args) {
|
|
420
|
-
for (const cb of this.events[event] || []) {
|
|
421
|
-
cb(...args);
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
on(event, cb) {
|
|
425
|
-
var _a;
|
|
426
|
-
((_a = this.events)[event] || (_a[event] = [])).push(cb);
|
|
427
|
-
return () => {
|
|
428
|
-
this.events[event] = this.events[event]?.filter((i) => cb !== i);
|
|
429
|
-
};
|
|
430
|
-
}
|
|
431
|
-
};
|
|
432
316
|
|
|
433
|
-
// src/
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
getName(address) {
|
|
443
|
-
return this.namedAccounts.get(address);
|
|
444
|
-
}
|
|
445
|
-
register(address, name) {
|
|
446
|
-
this.namedAccounts.set(address, name);
|
|
447
|
-
}
|
|
448
|
-
};
|
|
449
|
-
__publicField(_AccountRegistry, "factory", (name) => new _AccountRegistry(name));
|
|
450
|
-
var AccountRegistry = _AccountRegistry;
|
|
317
|
+
// src/keyringUtils.ts
|
|
318
|
+
function keyringFromSuri(suri, cryptoType = "sr25519") {
|
|
319
|
+
return new Keyring({ type: cryptoType }).createFromUri(suri);
|
|
320
|
+
}
|
|
321
|
+
function createKeyringPair(opts) {
|
|
322
|
+
const { cryptoType } = opts;
|
|
323
|
+
const seed = mnemonicGenerate();
|
|
324
|
+
return keyringFromSuri(seed, cryptoType);
|
|
325
|
+
}
|
|
451
326
|
|
|
452
|
-
// src/
|
|
327
|
+
// src/header.ts
|
|
453
328
|
function getTickFromHeader(client, header) {
|
|
454
329
|
for (const x of header.digest.logs) {
|
|
455
330
|
if (x.isPreRuntime) {
|
|
@@ -472,845 +347,7 @@ function getAuthorFromHeader(client, header) {
|
|
|
472
347
|
}
|
|
473
348
|
return void 0;
|
|
474
349
|
}
|
|
475
|
-
var
|
|
476
|
-
constructor(mainchain, options = {}) {
|
|
477
|
-
this.mainchain = mainchain;
|
|
478
|
-
this.options = options;
|
|
479
|
-
__publicField(this, "events", createNanoEvents());
|
|
480
|
-
__publicField(this, "locksById", {});
|
|
481
|
-
__publicField(this, "unsubscribe");
|
|
482
|
-
var _a, _b;
|
|
483
|
-
(_a = this.options).shouldLog ?? (_a.shouldLog = true);
|
|
484
|
-
(_b = this.options).finalizedBlocks ?? (_b.finalizedBlocks = false);
|
|
485
|
-
}
|
|
486
|
-
stop() {
|
|
487
|
-
if (this.unsubscribe) {
|
|
488
|
-
this.unsubscribe();
|
|
489
|
-
this.unsubscribe = void 0;
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
async start() {
|
|
493
|
-
await this.watchBlocks();
|
|
494
|
-
}
|
|
495
|
-
async watchBlocks() {
|
|
496
|
-
const client = await this.mainchain;
|
|
497
|
-
const onBlock = async (header) => {
|
|
498
|
-
try {
|
|
499
|
-
await this.processBlock(header);
|
|
500
|
-
} catch (e) {
|
|
501
|
-
console.error("Error processing block", e);
|
|
502
|
-
}
|
|
503
|
-
};
|
|
504
|
-
if (this.options.finalizedBlocks) {
|
|
505
|
-
this.unsubscribe = await client.rpc.chain.subscribeFinalizedHeads(onBlock);
|
|
506
|
-
} else {
|
|
507
|
-
this.unsubscribe = await client.rpc.chain.subscribeNewHeads(onBlock);
|
|
508
|
-
}
|
|
509
|
-
}
|
|
510
|
-
async processBlock(header) {
|
|
511
|
-
const client = await this.mainchain;
|
|
512
|
-
if (this.options.shouldLog) {
|
|
513
|
-
console.log(`-------------------------------------
|
|
514
|
-
BLOCK #${header.number}, ${header.hash.toHuman()}`);
|
|
515
|
-
}
|
|
516
|
-
const blockHash = header.hash;
|
|
517
|
-
const api = await client.at(blockHash);
|
|
518
|
-
const isBlockVote = await api.query.blockSeal.isBlockFromVoteSeal();
|
|
519
|
-
if (!isBlockVote) {
|
|
520
|
-
console.warn("> Compute reactivated!");
|
|
521
|
-
}
|
|
522
|
-
const events = await api.query.system.events();
|
|
523
|
-
const reloadVaults = /* @__PURE__ */ new Set();
|
|
524
|
-
let block = void 0;
|
|
525
|
-
for (const { event, phase } of events) {
|
|
526
|
-
const data = eventDataToJson(event);
|
|
527
|
-
if (data.vaultId) {
|
|
528
|
-
const vaultId = data.vaultId;
|
|
529
|
-
reloadVaults.add(vaultId);
|
|
530
|
-
}
|
|
531
|
-
let logEvent = false;
|
|
532
|
-
if (event.section === "liquidityPools") {
|
|
533
|
-
if (client.events.liquidityPools.BidPoolDistributed.is(event)) {
|
|
534
|
-
const { bidPoolBurned, bidPoolDistributed } = event.data;
|
|
535
|
-
data.burned = formatArgons(bidPoolBurned.toBigInt());
|
|
536
|
-
data.distributed = formatArgons(bidPoolDistributed.toBigInt());
|
|
537
|
-
logEvent = true;
|
|
538
|
-
} else if (client.events.liquidityPools.NextBidPoolCapitalLocked.is(event)) {
|
|
539
|
-
const { totalActivatedCapital } = event.data;
|
|
540
|
-
data.totalActivatedCapital = formatArgons(totalActivatedCapital.toBigInt());
|
|
541
|
-
logEvent = true;
|
|
542
|
-
}
|
|
543
|
-
} else if (event.section === "bitcoinLocks") {
|
|
544
|
-
if (client.events.bitcoinLocks.BitcoinLockCreated.is(event)) {
|
|
545
|
-
const { lockPrice, utxoId, accountId, vaultId } = event.data;
|
|
546
|
-
this.locksById[utxoId.toNumber()] = {
|
|
547
|
-
vaultId: vaultId.toNumber(),
|
|
548
|
-
lockPrice: lockPrice.toBigInt()
|
|
549
|
-
};
|
|
550
|
-
data.lockPrice = formatArgons(lockPrice.toBigInt());
|
|
551
|
-
data.accountId = accountId.toHuman();
|
|
552
|
-
reloadVaults.add(vaultId.toNumber());
|
|
553
|
-
}
|
|
554
|
-
logEvent = true;
|
|
555
|
-
} else if (event.section === "mint") {
|
|
556
|
-
logEvent = true;
|
|
557
|
-
if (client.events.mint.MiningMint.is(event)) {
|
|
558
|
-
const { amount } = event.data;
|
|
559
|
-
data.amount = formatArgons(amount.toBigInt());
|
|
560
|
-
}
|
|
561
|
-
} else if (event.section === "miningSlot") {
|
|
562
|
-
logEvent = true;
|
|
563
|
-
if (client.events.miningSlot.SlotBidderAdded.is(event)) {
|
|
564
|
-
data.amount = formatArgons(event.data.bidAmount.toBigInt());
|
|
565
|
-
this.events.emit("mining-bid", header, {
|
|
566
|
-
amount: event.data.bidAmount.toBigInt(),
|
|
567
|
-
accountId: event.data.accountId.toString()
|
|
568
|
-
});
|
|
569
|
-
} else if (client.events.miningSlot.SlotBidderDropped.is(event)) {
|
|
570
|
-
this.events.emit("mining-bid-ousted", header, {
|
|
571
|
-
accountId: event.data.accountId.toString(),
|
|
572
|
-
preservedArgonotHold: event.data.preservedArgonotHold.toPrimitive()
|
|
573
|
-
});
|
|
574
|
-
}
|
|
575
|
-
} else if (event.section === "bitcoinUtxos") {
|
|
576
|
-
logEvent = true;
|
|
577
|
-
if (client.events.bitcoinUtxos.UtxoVerified.is(event)) {
|
|
578
|
-
const { utxoId } = event.data;
|
|
579
|
-
const details = await this.getBitcoinLockDetails(utxoId.toNumber(), blockHash);
|
|
580
|
-
this.events.emit("bitcoin-verified", header, {
|
|
581
|
-
utxoId: utxoId.toNumber(),
|
|
582
|
-
vaultId: details.vaultId,
|
|
583
|
-
lockPrice: details.lockPrice
|
|
584
|
-
});
|
|
585
|
-
data.lockPrice = formatArgons(details.lockPrice);
|
|
586
|
-
reloadVaults.add(details.vaultId);
|
|
587
|
-
}
|
|
588
|
-
} else if (event.section === "system") {
|
|
589
|
-
if (client.events.system.ExtrinsicFailed.is(event)) {
|
|
590
|
-
const { dispatchError } = event.data;
|
|
591
|
-
if (dispatchError.isModule) {
|
|
592
|
-
const decoded = api.registry.findMetaError(dispatchError.asModule);
|
|
593
|
-
const { name, section } = decoded;
|
|
594
|
-
block ?? (block = await client.rpc.chain.getBlock(header.hash));
|
|
595
|
-
const extrinsicIndex = phase.asApplyExtrinsic.toNumber();
|
|
596
|
-
const ext = block.block.extrinsics[extrinsicIndex];
|
|
597
|
-
if (this.options.shouldLog) {
|
|
598
|
-
console.log(
|
|
599
|
-
`> [Failed Tx] ${section}.${name} -> ${ext.method.section}.${ext.method.method} (nonce=${ext.nonce})`,
|
|
600
|
-
ext.toHuman()?.method?.args
|
|
601
|
-
);
|
|
602
|
-
}
|
|
603
|
-
} else {
|
|
604
|
-
if (this.options.shouldLog) {
|
|
605
|
-
console.log(`x [Failed Tx] ${dispatchError.toJSON()}`);
|
|
606
|
-
}
|
|
607
|
-
}
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
if (this.options.shouldLog && logEvent) {
|
|
611
|
-
console.log(`> ${event.section}.${event.method}`, data);
|
|
612
|
-
}
|
|
613
|
-
this.events.emit("event", header, event);
|
|
614
|
-
}
|
|
615
|
-
if (reloadVaults.size) this.events.emit("vaults-updated", header, reloadVaults);
|
|
616
|
-
const tick = getTickFromHeader(client, header);
|
|
617
|
-
const author = getAuthorFromHeader(client, header);
|
|
618
|
-
this.events.emit(
|
|
619
|
-
"block",
|
|
620
|
-
header,
|
|
621
|
-
{ tick, author },
|
|
622
|
-
events.map((x) => x.event)
|
|
623
|
-
);
|
|
624
|
-
}
|
|
625
|
-
async getBitcoinLockDetails(utxoId, blockHash) {
|
|
626
|
-
const client = await this.mainchain;
|
|
627
|
-
const api = await client.at(blockHash);
|
|
628
|
-
if (!this.locksById[utxoId]) {
|
|
629
|
-
const lock = await api.query.bitcoinLocks.locksByUtxoId(utxoId);
|
|
630
|
-
this.locksById[utxoId] = {
|
|
631
|
-
vaultId: lock.value.vaultId.toNumber(),
|
|
632
|
-
lockPrice: lock.value.lockPrice.toBigInt()
|
|
633
|
-
};
|
|
634
|
-
}
|
|
635
|
-
return this.locksById[utxoId];
|
|
636
|
-
}
|
|
637
|
-
};
|
|
638
|
-
|
|
639
|
-
// src/FrameCalculator.ts
|
|
640
|
-
var FrameCalculator = class _FrameCalculator {
|
|
641
|
-
constructor() {
|
|
642
|
-
__publicField(this, "miningConfig");
|
|
643
|
-
__publicField(this, "genesisTick");
|
|
644
|
-
__publicField(this, "tickMillis");
|
|
645
|
-
}
|
|
646
|
-
async load(client) {
|
|
647
|
-
return await this.getConfig(client);
|
|
648
|
-
}
|
|
649
|
-
async getForTick(client, tick) {
|
|
650
|
-
const { ticksBetweenFrames, biddingStartTick } = await this.getConfig(client);
|
|
651
|
-
const ticksSinceMiningStart = tick - biddingStartTick;
|
|
652
|
-
return Math.floor(ticksSinceMiningStart / ticksBetweenFrames);
|
|
653
|
-
}
|
|
654
|
-
async getTickRangeForFrame(client, frameId) {
|
|
655
|
-
const { ticksBetweenFrames, biddingStartTick } = await this.getConfig(client);
|
|
656
|
-
return _FrameCalculator.calculateTickRangeForFrame(frameId, {
|
|
657
|
-
ticksBetweenFrames,
|
|
658
|
-
biddingStartTick
|
|
659
|
-
});
|
|
660
|
-
}
|
|
661
|
-
async getForHeader(client, header) {
|
|
662
|
-
if (header.number.toNumber() === 0) return 0;
|
|
663
|
-
const tick = getTickFromHeader(client, header);
|
|
664
|
-
if (tick === void 0) return void 0;
|
|
665
|
-
return this.getForTick(client, tick);
|
|
666
|
-
}
|
|
667
|
-
static frameToDateRange(frameId, config2) {
|
|
668
|
-
const [start, end] = _FrameCalculator.calculateTickRangeForFrame(frameId, config2);
|
|
669
|
-
return [new Date(start * config2.tickMillis), new Date(end * config2.tickMillis)];
|
|
670
|
-
}
|
|
671
|
-
static calculateTickRangeForFrame(frameId, config2) {
|
|
672
|
-
const { ticksBetweenFrames, biddingStartTick } = config2;
|
|
673
|
-
const startingTick = biddingStartTick + Math.floor(frameId * ticksBetweenFrames);
|
|
674
|
-
const endingTick = startingTick + ticksBetweenFrames - 1;
|
|
675
|
-
return [startingTick, endingTick];
|
|
676
|
-
}
|
|
677
|
-
async getConfig(client) {
|
|
678
|
-
this.miningConfig ?? (this.miningConfig = await client.query.miningSlot.miningConfig().then((x) => ({
|
|
679
|
-
ticksBetweenSlots: x.ticksBetweenSlots.toNumber(),
|
|
680
|
-
slotBiddingStartAfterTicks: x.slotBiddingStartAfterTicks.toNumber()
|
|
681
|
-
})));
|
|
682
|
-
this.genesisTick ?? (this.genesisTick = await client.query.ticks.genesisTick().then((x) => x.toNumber()));
|
|
683
|
-
this.tickMillis ?? (this.tickMillis = await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber()));
|
|
684
|
-
const config2 = this.miningConfig;
|
|
685
|
-
const genesisTick = this.genesisTick;
|
|
686
|
-
return {
|
|
687
|
-
ticksBetweenFrames: config2.ticksBetweenSlots,
|
|
688
|
-
slotBiddingStartAfterTicks: config2.slotBiddingStartAfterTicks,
|
|
689
|
-
genesisTick,
|
|
690
|
-
tickMillis: this.tickMillis,
|
|
691
|
-
biddingStartTick: genesisTick + config2.slotBiddingStartAfterTicks
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
};
|
|
695
|
-
|
|
696
|
-
// src/AccountMiners.ts
|
|
697
|
-
var AccountMiners = class _AccountMiners {
|
|
698
|
-
constructor(accountset, registeredMiners, options = { shouldLog: false }) {
|
|
699
|
-
this.accountset = accountset;
|
|
700
|
-
this.options = options;
|
|
701
|
-
__publicField(this, "events", createNanoEvents());
|
|
702
|
-
__publicField(this, "frameCalculator");
|
|
703
|
-
__publicField(this, "trackedAccountsByAddress", {});
|
|
704
|
-
this.frameCalculator = new FrameCalculator();
|
|
705
|
-
for (const miner of registeredMiners) {
|
|
706
|
-
this.trackedAccountsByAddress[miner.address] = {
|
|
707
|
-
startingFrameId: miner.seat.startingFrameId,
|
|
708
|
-
subaccountIndex: miner.subaccountIndex
|
|
709
|
-
};
|
|
710
|
-
}
|
|
711
|
-
}
|
|
712
|
-
async watch() {
|
|
713
|
-
const blockWatch = new BlockWatch(this.accountset.client, {
|
|
714
|
-
shouldLog: this.options.shouldLog
|
|
715
|
-
});
|
|
716
|
-
blockWatch.events.on("block", this.onBlock.bind(this));
|
|
717
|
-
await blockWatch.start();
|
|
718
|
-
return blockWatch;
|
|
719
|
-
}
|
|
720
|
-
async onBlock(header, digests, events) {
|
|
721
|
-
var _a;
|
|
722
|
-
const { author, tick } = digests;
|
|
723
|
-
if (author) {
|
|
724
|
-
const voteAuthor = this.trackedAccountsByAddress[author];
|
|
725
|
-
if (voteAuthor && this.options.shouldLog) {
|
|
726
|
-
console.log("> Our vote author", this.accountset.accountRegistry.getName(author));
|
|
727
|
-
}
|
|
728
|
-
} else {
|
|
729
|
-
console.warn("> No vote author found");
|
|
730
|
-
}
|
|
731
|
-
const client = await this.accountset.client;
|
|
732
|
-
const currentFrameId = await this.frameCalculator.getForTick(client, tick);
|
|
733
|
-
let newMiners;
|
|
734
|
-
const dataByCohort = { duringFrameId: currentFrameId };
|
|
735
|
-
for (const event of events) {
|
|
736
|
-
if (client.events.miningSlot.NewMiners.is(event)) {
|
|
737
|
-
newMiners = {
|
|
738
|
-
frameId: event.data.frameId.toNumber(),
|
|
739
|
-
addresses: event.data.newMiners.map((x) => x.accountId.toHuman())
|
|
740
|
-
};
|
|
741
|
-
}
|
|
742
|
-
if (client.events.blockRewards.RewardCreated.is(event)) {
|
|
743
|
-
const { rewards } = event.data;
|
|
744
|
-
for (const reward of rewards) {
|
|
745
|
-
const { argons, ownership } = reward;
|
|
746
|
-
const entry = this.trackedAccountsByAddress[author];
|
|
747
|
-
if (entry) {
|
|
748
|
-
dataByCohort[_a = entry.startingFrameId] ?? (dataByCohort[_a] = {
|
|
749
|
-
argonsMinted: 0n,
|
|
750
|
-
argonsMined: 0n,
|
|
751
|
-
argonotsMined: 0n
|
|
752
|
-
});
|
|
753
|
-
dataByCohort[entry.startingFrameId].argonotsMined += ownership.toBigInt();
|
|
754
|
-
dataByCohort[entry.startingFrameId].argonsMined += argons.toBigInt();
|
|
755
|
-
this.events.emit("mined", header, {
|
|
756
|
-
author,
|
|
757
|
-
argons: argons.toBigInt(),
|
|
758
|
-
argonots: ownership.toBigInt(),
|
|
759
|
-
forCohortWithStartingFrameId: entry.startingFrameId,
|
|
760
|
-
duringFrameId: currentFrameId
|
|
761
|
-
});
|
|
762
|
-
}
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
if (client.events.mint.MiningMint.is(event)) {
|
|
766
|
-
const { perMiner } = event.data;
|
|
767
|
-
const amountPerMiner = perMiner.toBigInt();
|
|
768
|
-
if (amountPerMiner > 0n) {
|
|
769
|
-
for (const [address, info] of Object.entries(this.trackedAccountsByAddress)) {
|
|
770
|
-
const { startingFrameId } = info;
|
|
771
|
-
dataByCohort[startingFrameId] ?? (dataByCohort[startingFrameId] = {
|
|
772
|
-
argonsMinted: 0n,
|
|
773
|
-
argonsMined: 0n,
|
|
774
|
-
argonotsMined: 0n
|
|
775
|
-
});
|
|
776
|
-
dataByCohort[startingFrameId].argonsMinted += amountPerMiner;
|
|
777
|
-
this.events.emit("minted", header, {
|
|
778
|
-
accountId: address,
|
|
779
|
-
argons: amountPerMiner,
|
|
780
|
-
forCohortWithStartingFrameId: startingFrameId,
|
|
781
|
-
duringFrameId: currentFrameId
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
}
|
|
786
|
-
}
|
|
787
|
-
if (newMiners) {
|
|
788
|
-
this.newCohortMiners(newMiners.frameId, newMiners.addresses);
|
|
789
|
-
}
|
|
790
|
-
return dataByCohort;
|
|
791
|
-
}
|
|
792
|
-
newCohortMiners(frameId, addresses) {
|
|
793
|
-
for (const [address, info] of Object.entries(this.trackedAccountsByAddress)) {
|
|
794
|
-
if (info.startingFrameId === frameId - 10) {
|
|
795
|
-
delete this.trackedAccountsByAddress[address];
|
|
796
|
-
}
|
|
797
|
-
}
|
|
798
|
-
for (const address of addresses) {
|
|
799
|
-
const entry = this.accountset.subAccountsByAddress[address];
|
|
800
|
-
if (entry) {
|
|
801
|
-
this.trackedAccountsByAddress[address] = {
|
|
802
|
-
startingFrameId: frameId,
|
|
803
|
-
subaccountIndex: entry.index
|
|
804
|
-
};
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
}
|
|
808
|
-
static async loadAt(accountset, options = {}) {
|
|
809
|
-
const seats = await accountset.miningSeats(options.blockHash);
|
|
810
|
-
const registered = seats.filter((x) => x.seat !== void 0);
|
|
811
|
-
return new _AccountMiners(accountset, registered, {
|
|
812
|
-
shouldLog: options.shouldLog ?? false
|
|
813
|
-
});
|
|
814
|
-
}
|
|
815
|
-
};
|
|
816
|
-
var Accountset = class {
|
|
817
|
-
constructor(options) {
|
|
818
|
-
__publicField(this, "txSubmitterPair");
|
|
819
|
-
__publicField(this, "isProxy", false);
|
|
820
|
-
__publicField(this, "seedAddress");
|
|
821
|
-
__publicField(this, "subAccountsByAddress", {});
|
|
822
|
-
__publicField(this, "accountRegistry");
|
|
823
|
-
__publicField(this, "client");
|
|
824
|
-
__publicField(this, "sessionKeyMnemonic");
|
|
825
|
-
if ("seedAccount" in options) {
|
|
826
|
-
this.txSubmitterPair = options.seedAccount;
|
|
827
|
-
this.seedAddress = options.seedAccount.address;
|
|
828
|
-
this.isProxy = false;
|
|
829
|
-
} else {
|
|
830
|
-
this.isProxy = options.isProxy;
|
|
831
|
-
this.txSubmitterPair = options.txSubmitter;
|
|
832
|
-
this.seedAddress = options.seedAddress;
|
|
833
|
-
}
|
|
834
|
-
this.sessionKeyMnemonic = options.sessionKeyMnemonic;
|
|
835
|
-
this.accountRegistry = options.accountRegistry ?? AccountRegistry.factory(options.name);
|
|
836
|
-
this.client = options.client;
|
|
837
|
-
const defaultRange = options.subaccountRange ?? getDefaultSubaccountRange();
|
|
838
|
-
this.accountRegistry.register(this.seedAddress, `${this.accountRegistry.me}//seed`);
|
|
839
|
-
for (const i of defaultRange) {
|
|
840
|
-
const pair = this.txSubmitterPair.derive(`//${i}`);
|
|
841
|
-
this.subAccountsByAddress[pair.address] = { pair, index: i };
|
|
842
|
-
this.accountRegistry.register(pair.address, `${this.accountRegistry.me}//${i}`);
|
|
843
|
-
}
|
|
844
|
-
}
|
|
845
|
-
get addresses() {
|
|
846
|
-
return [this.seedAddress, ...Object.keys(this.subAccountsByAddress)];
|
|
847
|
-
}
|
|
848
|
-
get namedAccounts() {
|
|
849
|
-
return this.accountRegistry.namedAccounts;
|
|
850
|
-
}
|
|
851
|
-
async submitterBalance(blockHash) {
|
|
852
|
-
const client = await this.client;
|
|
853
|
-
const api = blockHash ? await client.at(blockHash) : client;
|
|
854
|
-
const accountData = await api.query.system.account(this.txSubmitterPair.address);
|
|
855
|
-
return accountData.data.free.toBigInt();
|
|
856
|
-
}
|
|
857
|
-
async balance(blockHash) {
|
|
858
|
-
const client = await this.client;
|
|
859
|
-
const api = blockHash ? await client.at(blockHash) : client;
|
|
860
|
-
const accountData = await api.query.system.account(this.seedAddress);
|
|
861
|
-
return accountData.data.free.toBigInt();
|
|
862
|
-
}
|
|
863
|
-
async totalArgonsAt(blockHash) {
|
|
864
|
-
const client = await this.client;
|
|
865
|
-
const api = blockHash ? await client.at(blockHash) : client;
|
|
866
|
-
const addresses = this.addresses;
|
|
867
|
-
const results = await api.query.system.account.multi(addresses);
|
|
868
|
-
return results.map((account, i) => {
|
|
869
|
-
const address = addresses[i];
|
|
870
|
-
return {
|
|
871
|
-
address,
|
|
872
|
-
amount: account.data.free.toBigInt(),
|
|
873
|
-
index: this.subAccountsByAddress[address]?.index ?? Number.NaN
|
|
874
|
-
};
|
|
875
|
-
});
|
|
876
|
-
}
|
|
877
|
-
async totalArgonotsAt(blockHash) {
|
|
878
|
-
const client = await this.client;
|
|
879
|
-
const api = blockHash ? await client.at(blockHash) : client;
|
|
880
|
-
const addresses = this.addresses;
|
|
881
|
-
const results = await api.query.ownership.account.multi(addresses);
|
|
882
|
-
return results.map((account, i) => {
|
|
883
|
-
const address = addresses[i];
|
|
884
|
-
return {
|
|
885
|
-
address,
|
|
886
|
-
amount: account.free.toBigInt(),
|
|
887
|
-
index: this.subAccountsByAddress[address]?.index ?? Number.NaN
|
|
888
|
-
};
|
|
889
|
-
});
|
|
890
|
-
}
|
|
891
|
-
async getAvailableMinerAccounts(maxSeats) {
|
|
892
|
-
const miningSeats = await this.miningSeats();
|
|
893
|
-
const subaccountRange = [];
|
|
894
|
-
for (const seat of miningSeats) {
|
|
895
|
-
if (seat.hasWinningBid) {
|
|
896
|
-
continue;
|
|
897
|
-
}
|
|
898
|
-
if (seat.isLastDay || seat.seat === void 0) {
|
|
899
|
-
subaccountRange.push({
|
|
900
|
-
index: seat.subaccountIndex,
|
|
901
|
-
isRebid: seat.seat !== void 0,
|
|
902
|
-
address: seat.address
|
|
903
|
-
});
|
|
904
|
-
if (subaccountRange.length >= maxSeats) {
|
|
905
|
-
break;
|
|
906
|
-
}
|
|
907
|
-
}
|
|
908
|
-
}
|
|
909
|
-
return subaccountRange;
|
|
910
|
-
}
|
|
911
|
-
async loadRegisteredMiners(api) {
|
|
912
|
-
const addresses = Object.keys(this.subAccountsByAddress);
|
|
913
|
-
const rawIndices = await api.query.miningSlot.accountIndexLookup.multi(addresses);
|
|
914
|
-
const frameIds = [
|
|
915
|
-
...new Set(
|
|
916
|
-
rawIndices.map((x) => x.isNone ? void 0 : x.value[0].toNumber()).filter((x) => x !== void 0)
|
|
917
|
-
)
|
|
918
|
-
];
|
|
919
|
-
const bidAmountsByFrame = {};
|
|
920
|
-
if (frameIds.length) {
|
|
921
|
-
console.log("Looking up cohorts for frames", frameIds);
|
|
922
|
-
const cohorts = await api.query.miningSlot.minersByCohort.multi(frameIds);
|
|
923
|
-
for (let i = 0; i < frameIds.length; i++) {
|
|
924
|
-
const cohort = cohorts[i];
|
|
925
|
-
const frameId = frameIds[i];
|
|
926
|
-
bidAmountsByFrame[frameId] = cohort.map((x) => x.bid.toBigInt());
|
|
927
|
-
}
|
|
928
|
-
}
|
|
929
|
-
const addressToMiningIndex = {};
|
|
930
|
-
for (let i = 0; i < addresses.length; i++) {
|
|
931
|
-
const address = addresses[i];
|
|
932
|
-
if (rawIndices[i].isNone) continue;
|
|
933
|
-
const [frameIdRaw, indexRaw] = rawIndices[i].value;
|
|
934
|
-
const frameId = frameIdRaw.toNumber();
|
|
935
|
-
const index = indexRaw.toNumber();
|
|
936
|
-
const bidAmount = bidAmountsByFrame[frameId]?.[index];
|
|
937
|
-
addressToMiningIndex[address] = {
|
|
938
|
-
startingFrameId: frameId,
|
|
939
|
-
index,
|
|
940
|
-
bidAmount: bidAmount ?? 0n
|
|
941
|
-
};
|
|
942
|
-
}
|
|
943
|
-
const nextFrameId = await api.query.miningSlot.nextFrameId();
|
|
944
|
-
return addresses.map((address) => {
|
|
945
|
-
const cohort = addressToMiningIndex[address];
|
|
946
|
-
let isLastDay = false;
|
|
947
|
-
if (cohort !== void 0) {
|
|
948
|
-
isLastDay = nextFrameId.toNumber() - cohort.startingFrameId === 10;
|
|
949
|
-
}
|
|
950
|
-
return {
|
|
951
|
-
address,
|
|
952
|
-
seat: cohort,
|
|
953
|
-
isLastDay,
|
|
954
|
-
subaccountIndex: this.subAccountsByAddress[address]?.index ?? Number.NaN
|
|
955
|
-
};
|
|
956
|
-
});
|
|
957
|
-
}
|
|
958
|
-
async miningSeats(blockHash) {
|
|
959
|
-
const client = await this.client;
|
|
960
|
-
const api = blockHash ? await client.at(blockHash) : client;
|
|
961
|
-
const miners = await this.loadRegisteredMiners(api);
|
|
962
|
-
const nextCohort = await api.query.miningSlot.bidsForNextSlotCohort();
|
|
963
|
-
return miners.map((miner) => {
|
|
964
|
-
const bid = nextCohort.find((x) => x.accountId.toHuman() === miner.address);
|
|
965
|
-
return {
|
|
966
|
-
...miner,
|
|
967
|
-
hasWinningBid: !!bid,
|
|
968
|
-
bidAmount: bid?.bid.toBigInt() ?? miner.seat?.bidAmount ?? 0n
|
|
969
|
-
};
|
|
970
|
-
});
|
|
971
|
-
}
|
|
972
|
-
async bids(blockHash) {
|
|
973
|
-
const client = await this.client;
|
|
974
|
-
const api = blockHash ? await client.at(blockHash) : client;
|
|
975
|
-
const addresses = Object.keys(this.subAccountsByAddress);
|
|
976
|
-
const nextCohort = await api.query.miningSlot.bidsForNextSlotCohort();
|
|
977
|
-
const registrationsByAddress = Object.fromEntries(
|
|
978
|
-
nextCohort.map((x, i) => [x.accountId.toHuman(), { ...x, index: i }])
|
|
979
|
-
);
|
|
980
|
-
return addresses.map((address) => {
|
|
981
|
-
const entry = registrationsByAddress[address];
|
|
982
|
-
return {
|
|
983
|
-
address,
|
|
984
|
-
bidPlace: entry?.index,
|
|
985
|
-
bidAmount: entry?.bid?.toBigInt(),
|
|
986
|
-
index: this.subAccountsByAddress[address]?.index ?? Number.NaN
|
|
987
|
-
};
|
|
988
|
-
});
|
|
989
|
-
}
|
|
990
|
-
async consolidate(subaccounts) {
|
|
991
|
-
const client = await this.client;
|
|
992
|
-
const accounts = this.getAccountsInRange(subaccounts);
|
|
993
|
-
const results = [];
|
|
994
|
-
await Promise.allSettled(
|
|
995
|
-
accounts.map(({ pair, index }) => {
|
|
996
|
-
if (!pair) {
|
|
997
|
-
results.push({
|
|
998
|
-
index,
|
|
999
|
-
failedError: new Error(`No keypair for //${index}`)
|
|
1000
|
-
});
|
|
1001
|
-
return Promise.resolve();
|
|
1002
|
-
}
|
|
1003
|
-
return new Promise((resolve) => {
|
|
1004
|
-
client.tx.utility.batchAll([
|
|
1005
|
-
client.tx.balances.transferAll(this.seedAddress, true),
|
|
1006
|
-
client.tx.ownership.transferAll(this.seedAddress, true)
|
|
1007
|
-
]).signAndSend(pair, (cb) => {
|
|
1008
|
-
logExtrinsicResult(cb);
|
|
1009
|
-
if (cb.dispatchError) {
|
|
1010
|
-
const error = dispatchErrorToString(client, cb.dispatchError);
|
|
1011
|
-
results.push({
|
|
1012
|
-
index,
|
|
1013
|
-
failedError: new Error(`Error consolidating //${index}: ${error}`)
|
|
1014
|
-
});
|
|
1015
|
-
resolve();
|
|
1016
|
-
}
|
|
1017
|
-
if (cb.isInBlock) {
|
|
1018
|
-
results.push({ index, inBlock: cb.status.asInBlock.toHex() });
|
|
1019
|
-
resolve();
|
|
1020
|
-
}
|
|
1021
|
-
}).catch((e) => {
|
|
1022
|
-
results.push({ index, failedError: e });
|
|
1023
|
-
resolve();
|
|
1024
|
-
});
|
|
1025
|
-
});
|
|
1026
|
-
})
|
|
1027
|
-
);
|
|
1028
|
-
return results;
|
|
1029
|
-
}
|
|
1030
|
-
status(opts) {
|
|
1031
|
-
const { argons, argonots, accountSubset, bids, seats } = opts;
|
|
1032
|
-
const accounts = [
|
|
1033
|
-
{
|
|
1034
|
-
index: "main",
|
|
1035
|
-
address: this.seedAddress,
|
|
1036
|
-
argons: formatArgons(argons.find((x) => x.address === this.seedAddress)?.amount ?? 0n),
|
|
1037
|
-
argonots: formatArgons(argonots.find((x) => x.address === this.seedAddress)?.amount ?? 0n)
|
|
1038
|
-
}
|
|
1039
|
-
];
|
|
1040
|
-
for (const [address, { index }] of Object.entries(this.subAccountsByAddress)) {
|
|
1041
|
-
const argonAmount = argons.find((x) => x.address === address)?.amount ?? 0n;
|
|
1042
|
-
const argonotAmount = argonots.find((x) => x.address === address)?.amount ?? 0n;
|
|
1043
|
-
const bid = bids.find((x) => x.address === address);
|
|
1044
|
-
const seat = seats.find((x) => x.address === address)?.seat;
|
|
1045
|
-
const entry = {
|
|
1046
|
-
index: ` //${index}`,
|
|
1047
|
-
address,
|
|
1048
|
-
argons: formatArgons(argonAmount),
|
|
1049
|
-
argonots: formatArgons(argonotAmount),
|
|
1050
|
-
seat,
|
|
1051
|
-
bidPlace: bid?.bidPlace,
|
|
1052
|
-
bidAmount: bid?.bidAmount ?? 0n
|
|
1053
|
-
};
|
|
1054
|
-
if (accountSubset) {
|
|
1055
|
-
entry.isWorkingOn = accountSubset.some((x) => x.address === address);
|
|
1056
|
-
}
|
|
1057
|
-
accounts.push(entry);
|
|
1058
|
-
}
|
|
1059
|
-
return accounts;
|
|
1060
|
-
}
|
|
1061
|
-
async registerKeys(url) {
|
|
1062
|
-
const client = await getClient(url.replace("ws:", "http:"));
|
|
1063
|
-
const keys = this.keys();
|
|
1064
|
-
for (const [name, key] of Object.entries(keys)) {
|
|
1065
|
-
console.log("Registering key", name, key.publicKey);
|
|
1066
|
-
const result = await client.rpc.author.insertKey(name, key.privateKey, key.publicKey);
|
|
1067
|
-
const saved = await client.rpc.author.hasKey(key.publicKey, name);
|
|
1068
|
-
if (!saved) {
|
|
1069
|
-
console.error("Failed to register key", name, key.publicKey);
|
|
1070
|
-
throw new Error(`Failed to register ${name} key ${key.publicKey}`);
|
|
1071
|
-
}
|
|
1072
|
-
console.log(`Registered ${name} key`, result.toHuman());
|
|
1073
|
-
}
|
|
1074
|
-
await client.disconnect();
|
|
1075
|
-
}
|
|
1076
|
-
keys(keysVersion) {
|
|
1077
|
-
const config2 = getConfig();
|
|
1078
|
-
let version = keysVersion ?? config2.keysVersion ?? 0;
|
|
1079
|
-
const seedMnemonic = this.sessionKeyMnemonic ?? config2.keysMnemonic;
|
|
1080
|
-
if (!seedMnemonic) {
|
|
1081
|
-
throw new Error("KEYS_MNEMONIC environment variable not set. Cannot derive keys.");
|
|
1082
|
-
}
|
|
1083
|
-
const blockSealKey = `${seedMnemonic}//block-seal//${version}`;
|
|
1084
|
-
const granKey = `${seedMnemonic}//grandpa//${version}`;
|
|
1085
|
-
const blockSealAccount = new Keyring().createFromUri(blockSealKey, {
|
|
1086
|
-
type: "ed25519"
|
|
1087
|
-
});
|
|
1088
|
-
const grandpaAccount = new Keyring().createFromUri(granKey, {
|
|
1089
|
-
type: "ed25519"
|
|
1090
|
-
});
|
|
1091
|
-
return {
|
|
1092
|
-
seal: {
|
|
1093
|
-
privateKey: blockSealKey,
|
|
1094
|
-
publicKey: u8aToHex(blockSealAccount.publicKey),
|
|
1095
|
-
rawPublicKey: blockSealAccount.publicKey
|
|
1096
|
-
},
|
|
1097
|
-
gran: {
|
|
1098
|
-
privateKey: granKey,
|
|
1099
|
-
publicKey: u8aToHex(grandpaAccount.publicKey),
|
|
1100
|
-
rawPublicKey: grandpaAccount.publicKey
|
|
1101
|
-
}
|
|
1102
|
-
};
|
|
1103
|
-
}
|
|
1104
|
-
async tx(tx) {
|
|
1105
|
-
const client = await this.client;
|
|
1106
|
-
return new TxSubmitter(client, tx, this.txSubmitterPair);
|
|
1107
|
-
}
|
|
1108
|
-
/**
|
|
1109
|
-
* Create but don't submit a mining bid transaction.
|
|
1110
|
-
* @param options
|
|
1111
|
-
*/
|
|
1112
|
-
async createMiningBidTx(options) {
|
|
1113
|
-
const client = await this.client;
|
|
1114
|
-
const { bidAmount, subaccounts } = options;
|
|
1115
|
-
const batch = client.tx.utility.batch(
|
|
1116
|
-
subaccounts.map((x) => {
|
|
1117
|
-
const keys = this.keys();
|
|
1118
|
-
return client.tx.miningSlot.bid(
|
|
1119
|
-
bidAmount,
|
|
1120
|
-
{
|
|
1121
|
-
grandpa: keys.gran.rawPublicKey,
|
|
1122
|
-
blockSealAuthority: keys.seal.rawPublicKey
|
|
1123
|
-
},
|
|
1124
|
-
x.address
|
|
1125
|
-
);
|
|
1126
|
-
})
|
|
1127
|
-
);
|
|
1128
|
-
let tx = batch;
|
|
1129
|
-
if (this.isProxy) {
|
|
1130
|
-
tx = client.tx.proxy.proxy(this.seedAddress, "MiningBid", batch);
|
|
1131
|
-
}
|
|
1132
|
-
return new TxSubmitter(client, tx, this.txSubmitterPair);
|
|
1133
|
-
}
|
|
1134
|
-
/**
|
|
1135
|
-
* Create a mining bid. This will create a bid for each account in the given range from the seed account as funding.
|
|
1136
|
-
*/
|
|
1137
|
-
async createMiningBids(options) {
|
|
1138
|
-
const accounts = this.getAccountsInRange(options.subaccountRange);
|
|
1139
|
-
const client = await this.client;
|
|
1140
|
-
const submitter = await this.createMiningBidTx({
|
|
1141
|
-
...options,
|
|
1142
|
-
subaccounts: accounts
|
|
1143
|
-
});
|
|
1144
|
-
const { tip = 0n } = options;
|
|
1145
|
-
const txFee = await submitter.feeEstimate(tip);
|
|
1146
|
-
let minBalance = options.bidAmount * BigInt(accounts.length);
|
|
1147
|
-
let totalFees = tip + 1n + txFee;
|
|
1148
|
-
const seedBalance = await client.query.system.account(this.seedAddress).then((x) => x.data.free.toBigInt());
|
|
1149
|
-
if (!this.isProxy) {
|
|
1150
|
-
minBalance += totalFees;
|
|
1151
|
-
}
|
|
1152
|
-
if (seedBalance < minBalance) {
|
|
1153
|
-
throw new Error(
|
|
1154
|
-
`Insufficient balance to create mining bids. Seed account has ${formatArgons(
|
|
1155
|
-
seedBalance
|
|
1156
|
-
)} but needs ${formatArgons(minBalance)}`
|
|
1157
|
-
);
|
|
1158
|
-
}
|
|
1159
|
-
if (this.isProxy) {
|
|
1160
|
-
const { canAfford, availableBalance } = await submitter.canAfford({
|
|
1161
|
-
tip
|
|
1162
|
-
});
|
|
1163
|
-
if (!canAfford) {
|
|
1164
|
-
throw new Error(
|
|
1165
|
-
`Insufficient balance to pay proxy fees. Proxy account has ${formatArgons(
|
|
1166
|
-
availableBalance
|
|
1167
|
-
)} but needs ${formatArgons(totalFees)}`
|
|
1168
|
-
);
|
|
1169
|
-
}
|
|
1170
|
-
}
|
|
1171
|
-
console.log("Creating bids", {
|
|
1172
|
-
perSeatBid: options.bidAmount,
|
|
1173
|
-
subaccounts: options.subaccountRange,
|
|
1174
|
-
txFee
|
|
1175
|
-
});
|
|
1176
|
-
const txResult = await submitter.submit({
|
|
1177
|
-
tip,
|
|
1178
|
-
useLatestNonce: true
|
|
1179
|
-
});
|
|
1180
|
-
const bidError = await txResult.inBlockPromise.then(() => void 0).catch((x) => x);
|
|
1181
|
-
return {
|
|
1182
|
-
finalFee: txResult.finalFee,
|
|
1183
|
-
bidError,
|
|
1184
|
-
blockHash: txResult.includedInBlock,
|
|
1185
|
-
successfulBids: txResult.batchInterruptedIndex !== void 0 ? txResult.batchInterruptedIndex : accounts.length
|
|
1186
|
-
};
|
|
1187
|
-
}
|
|
1188
|
-
getAccountsInRange(range) {
|
|
1189
|
-
const entries = new Set(range ?? getDefaultSubaccountRange());
|
|
1190
|
-
return Object.entries(this.subAccountsByAddress).filter(([_, account]) => {
|
|
1191
|
-
return entries.has(account.index);
|
|
1192
|
-
}).map(([address, { pair, index }]) => ({ pair, index, address }));
|
|
1193
|
-
}
|
|
1194
|
-
async watchBlocks(shouldLog = false) {
|
|
1195
|
-
const accountMiners = await AccountMiners.loadAt(this, { shouldLog });
|
|
1196
|
-
await accountMiners.watch();
|
|
1197
|
-
return accountMiners;
|
|
1198
|
-
}
|
|
1199
|
-
};
|
|
1200
|
-
function getDefaultSubaccountRange() {
|
|
1201
|
-
try {
|
|
1202
|
-
const config2 = getConfig();
|
|
1203
|
-
return parseSubaccountRange(config2.subaccountRange ?? "0-9");
|
|
1204
|
-
} catch {
|
|
1205
|
-
console.error(
|
|
1206
|
-
"Failed to parse SUBACCOUNT_RANGE configuration. Defaulting to 0-9. Please check the format of the subaccountRange config value."
|
|
1207
|
-
);
|
|
1208
|
-
return Array.from({ length: 10 }, (_, i) => i);
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
function parseSubaccountRange(range) {
|
|
1212
|
-
if (!range) {
|
|
1213
|
-
return void 0;
|
|
1214
|
-
}
|
|
1215
|
-
const indices = [];
|
|
1216
|
-
for (const entry of range.split(",")) {
|
|
1217
|
-
if (entry.includes("-")) {
|
|
1218
|
-
const [start, end] = entry.split("-").map((x) => parseInt(x, 10));
|
|
1219
|
-
for (let i = start; i <= end; i++) {
|
|
1220
|
-
indices.push(i);
|
|
1221
|
-
}
|
|
1222
|
-
continue;
|
|
1223
|
-
}
|
|
1224
|
-
const record = parseInt(entry.trim(), 10);
|
|
1225
|
-
if (Number.isNaN(record) || !Number.isInteger(record)) {
|
|
1226
|
-
throw new Error(`Invalid range entry: ${entry}`);
|
|
1227
|
-
}
|
|
1228
|
-
if (Number.isInteger(record)) {
|
|
1229
|
-
indices.push(record);
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1232
|
-
return indices;
|
|
1233
|
-
}
|
|
1234
|
-
var MiningBids = class {
|
|
1235
|
-
constructor(client, shouldLog = true) {
|
|
1236
|
-
this.client = client;
|
|
1237
|
-
this.shouldLog = shouldLog;
|
|
1238
|
-
__publicField(this, "nextCohort", []);
|
|
1239
|
-
}
|
|
1240
|
-
async maxCohortSize() {
|
|
1241
|
-
const client = await this.client;
|
|
1242
|
-
return client.query.miningSlot.nextCohortSize().then((x) => x.toNumber());
|
|
1243
|
-
}
|
|
1244
|
-
async onCohortChange(options) {
|
|
1245
|
-
const { onBiddingStart, onBiddingEnd } = options;
|
|
1246
|
-
const client = await this.client;
|
|
1247
|
-
let openCohortStartingFrameId = 0;
|
|
1248
|
-
const unsubscribe = await client.queryMulti(
|
|
1249
|
-
[
|
|
1250
|
-
client.query.miningSlot.isNextSlotBiddingOpen,
|
|
1251
|
-
client.query.miningSlot.nextFrameId
|
|
1252
|
-
],
|
|
1253
|
-
async ([isBiddingOpen, rawNextCohortStartingFrameId]) => {
|
|
1254
|
-
const nextFrameId = rawNextCohortStartingFrameId.toNumber();
|
|
1255
|
-
if (isBiddingOpen.isTrue) {
|
|
1256
|
-
if (openCohortStartingFrameId !== 0) {
|
|
1257
|
-
await onBiddingEnd?.(openCohortStartingFrameId);
|
|
1258
|
-
}
|
|
1259
|
-
openCohortStartingFrameId = nextFrameId;
|
|
1260
|
-
await onBiddingStart?.(nextFrameId);
|
|
1261
|
-
} else {
|
|
1262
|
-
await onBiddingEnd?.(nextFrameId);
|
|
1263
|
-
openCohortStartingFrameId = 0;
|
|
1264
|
-
}
|
|
1265
|
-
}
|
|
1266
|
-
);
|
|
1267
|
-
return { unsubscribe };
|
|
1268
|
-
}
|
|
1269
|
-
async watch(accountNames, blockHash, printFn) {
|
|
1270
|
-
const client = await this.client;
|
|
1271
|
-
const api = blockHash ? await client.at(blockHash) : client;
|
|
1272
|
-
const unsubscribe = await api.query.miningSlot.bidsForNextSlotCohort(async (next) => {
|
|
1273
|
-
this.nextCohort = await Promise.all(next.map((x) => this.toBid(accountNames, x)));
|
|
1274
|
-
if (!this.shouldLog) return;
|
|
1275
|
-
console.clear();
|
|
1276
|
-
const block = await client.query.system.number();
|
|
1277
|
-
if (!printFn) {
|
|
1278
|
-
console.log("At block", block.toNumber());
|
|
1279
|
-
this.print();
|
|
1280
|
-
} else {
|
|
1281
|
-
printFn(block.toNumber());
|
|
1282
|
-
}
|
|
1283
|
-
});
|
|
1284
|
-
return { unsubscribe };
|
|
1285
|
-
}
|
|
1286
|
-
async loadAt(accountNames, blockHash) {
|
|
1287
|
-
const client = await this.client;
|
|
1288
|
-
const api = blockHash ? await client.at(blockHash) : client;
|
|
1289
|
-
const nextCohort = await api.query.miningSlot.bidsForNextSlotCohort();
|
|
1290
|
-
this.nextCohort = await Promise.all(nextCohort.map((x) => this.toBid(accountNames, x)));
|
|
1291
|
-
}
|
|
1292
|
-
async toBid(accountNames, bid) {
|
|
1293
|
-
return {
|
|
1294
|
-
accountId: bid.accountId.toString(),
|
|
1295
|
-
isOurs: accountNames.get(bid.accountId.toString()) ?? "n",
|
|
1296
|
-
bidAmount: bid.bid.toBigInt()
|
|
1297
|
-
};
|
|
1298
|
-
}
|
|
1299
|
-
print() {
|
|
1300
|
-
const bids = this.nextCohort.map((bid) => {
|
|
1301
|
-
return {
|
|
1302
|
-
account: bid.accountId,
|
|
1303
|
-
isOurs: bid.isOurs,
|
|
1304
|
-
bidAmount: formatArgons(bid.bidAmount)
|
|
1305
|
-
};
|
|
1306
|
-
});
|
|
1307
|
-
if (bids.length) {
|
|
1308
|
-
console.log("\n\nMining Bids:");
|
|
1309
|
-
printTable(bids);
|
|
1310
|
-
}
|
|
1311
|
-
}
|
|
1312
|
-
};
|
|
1313
|
-
var { ROUND_FLOOR: ROUND_FLOOR2 } = BigNumber;
|
|
350
|
+
var { ROUND_FLOOR: ROUND_FLOOR2 } = BigNumber2;
|
|
1314
351
|
var Vault = class _Vault {
|
|
1315
352
|
constructor(id, vault, tickDuration) {
|
|
1316
353
|
this.tickDuration = tickDuration;
|
|
@@ -1335,8 +372,9 @@ var Vault = class _Vault {
|
|
|
1335
372
|
}
|
|
1336
373
|
load(vault) {
|
|
1337
374
|
this.securitization = vault.securitization.toBigInt();
|
|
1338
|
-
this.securitizationRatio =
|
|
1339
|
-
vault.securitizationRatio.toBigInt()
|
|
375
|
+
this.securitizationRatio = fromFixedNumber(
|
|
376
|
+
vault.securitizationRatio.toBigInt(),
|
|
377
|
+
FIXED_U128_DECIMALS
|
|
1340
378
|
).toNumber();
|
|
1341
379
|
this.argonsLocked = vault.argonsLocked.toBigInt();
|
|
1342
380
|
this.argonsPendingActivation = vault.argonsPendingActivation.toBigInt();
|
|
@@ -1347,12 +385,14 @@ var Vault = class _Vault {
|
|
|
1347
385
|
}
|
|
1348
386
|
}
|
|
1349
387
|
this.terms = {
|
|
1350
|
-
bitcoinAnnualPercentRate:
|
|
1351
|
-
vault.terms.bitcoinAnnualPercentRate.toBigInt()
|
|
388
|
+
bitcoinAnnualPercentRate: fromFixedNumber(
|
|
389
|
+
vault.terms.bitcoinAnnualPercentRate.toBigInt(),
|
|
390
|
+
FIXED_U128_DECIMALS
|
|
1352
391
|
),
|
|
1353
392
|
bitcoinBaseFee: vault.terms.bitcoinBaseFee.toBigInt(),
|
|
1354
|
-
liquidityPoolProfitSharing:
|
|
1355
|
-
vault.terms.liquidityPoolProfitSharing.toBigInt()
|
|
393
|
+
liquidityPoolProfitSharing: fromFixedNumber(
|
|
394
|
+
vault.terms.liquidityPoolProfitSharing.toBigInt(),
|
|
395
|
+
PERMILL_DECIMALS
|
|
1356
396
|
)
|
|
1357
397
|
};
|
|
1358
398
|
this.operatorAccountId = vault.operatorAccountId.toString();
|
|
@@ -1361,12 +401,14 @@ var Vault = class _Vault {
|
|
|
1361
401
|
const [tickApply, terms] = vault.pendingTerms.value;
|
|
1362
402
|
this.pendingTermsChangeTick = tickApply.toNumber();
|
|
1363
403
|
this.pendingTerms = {
|
|
1364
|
-
bitcoinAnnualPercentRate:
|
|
1365
|
-
terms.bitcoinAnnualPercentRate.toBigInt()
|
|
404
|
+
bitcoinAnnualPercentRate: fromFixedNumber(
|
|
405
|
+
terms.bitcoinAnnualPercentRate.toBigInt(),
|
|
406
|
+
FIXED_U128_DECIMALS
|
|
1366
407
|
),
|
|
1367
408
|
bitcoinBaseFee: terms.bitcoinBaseFee.toBigInt(),
|
|
1368
|
-
liquidityPoolProfitSharing:
|
|
1369
|
-
vault.terms.liquidityPoolProfitSharing.toBigInt()
|
|
409
|
+
liquidityPoolProfitSharing: fromFixedNumber(
|
|
410
|
+
vault.terms.liquidityPoolProfitSharing.toBigInt(),
|
|
411
|
+
PERMILL_DECIMALS
|
|
1370
412
|
)
|
|
1371
413
|
};
|
|
1372
414
|
}
|
|
@@ -1380,20 +422,20 @@ var Vault = class _Vault {
|
|
|
1380
422
|
return [...this.argonsScheduledForRelease.values()].reduce((acc, val) => acc + val, 0n);
|
|
1381
423
|
}
|
|
1382
424
|
securitizationRatioBN() {
|
|
1383
|
-
return new
|
|
425
|
+
return new BigNumber2__default(this.securitizationRatio);
|
|
1384
426
|
}
|
|
1385
427
|
recoverySecuritization() {
|
|
1386
|
-
const reserved = new
|
|
428
|
+
const reserved = new BigNumber2__default(1).div(this.securitizationRatioBN());
|
|
1387
429
|
return this.securitization - BigInt(reserved.multipliedBy(this.securitization.toString()).toFixed(0, ROUND_FLOOR2));
|
|
1388
430
|
}
|
|
1389
431
|
minimumSecuritization() {
|
|
1390
432
|
return BigInt(
|
|
1391
|
-
this.securitizationRatioBN().multipliedBy(this.argonsLocked.toString()).decimalPlaces(0,
|
|
433
|
+
this.securitizationRatioBN().multipliedBy(this.argonsLocked.toString()).decimalPlaces(0, BigNumber2__default.ROUND_CEIL).toString()
|
|
1392
434
|
);
|
|
1393
435
|
}
|
|
1394
436
|
activatedSecuritization() {
|
|
1395
437
|
const activated = this.argonsLocked - this.argonsPendingActivation;
|
|
1396
|
-
const maxRatio =
|
|
438
|
+
const maxRatio = BigNumber2__default(Math.min(this.securitizationRatio, 2));
|
|
1397
439
|
return BigInt(maxRatio.multipliedBy(activated.toString()).toFixed(0, ROUND_FLOOR2));
|
|
1398
440
|
}
|
|
1399
441
|
/**
|
|
@@ -1404,7 +446,7 @@ var Vault = class _Vault {
|
|
|
1404
446
|
return activated / 10n;
|
|
1405
447
|
}
|
|
1406
448
|
calculateBitcoinFee(amount) {
|
|
1407
|
-
const fee = this.terms.bitcoinAnnualPercentRate.multipliedBy(Number(amount)).integerValue(
|
|
449
|
+
const fee = this.terms.bitcoinAnnualPercentRate.multipliedBy(Number(amount)).integerValue(BigNumber2__default.ROUND_CEIL);
|
|
1408
450
|
return BigInt(fee.toString()) + this.terms.bitcoinBaseFee;
|
|
1409
451
|
}
|
|
1410
452
|
static async get(client, vaultId, tickDurationMillis) {
|
|
@@ -1415,7 +457,7 @@ var Vault = class _Vault {
|
|
|
1415
457
|
const tickDuration = tickDurationMillis ?? await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber());
|
|
1416
458
|
return new _Vault(vaultId, rawVault.unwrap(), tickDuration);
|
|
1417
459
|
}
|
|
1418
|
-
static async create(client, keypair, args,
|
|
460
|
+
static async create(client, keypair, args, config = {}) {
|
|
1419
461
|
const {
|
|
1420
462
|
securitization,
|
|
1421
463
|
securitizationRatio,
|
|
@@ -1436,18 +478,21 @@ var Vault = class _Vault {
|
|
|
1436
478
|
xpubBytes = bytes;
|
|
1437
479
|
}
|
|
1438
480
|
}
|
|
1439
|
-
|
|
481
|
+
const vaultParams = {
|
|
1440
482
|
terms: {
|
|
1441
483
|
// convert to fixed u128
|
|
1442
|
-
bitcoinAnnualPercentRate: toFixedNumber(annualPercentRate,
|
|
484
|
+
bitcoinAnnualPercentRate: toFixedNumber(annualPercentRate, FIXED_U128_DECIMALS),
|
|
1443
485
|
bitcoinBaseFee: BigInt(baseFee),
|
|
1444
|
-
liquidityPoolProfitSharing: toFixedNumber(
|
|
486
|
+
liquidityPoolProfitSharing: toFixedNumber(
|
|
487
|
+
args.liquidityPoolProfitSharing,
|
|
488
|
+
PERMILL_DECIMALS
|
|
489
|
+
)
|
|
1445
490
|
},
|
|
1446
|
-
securitizationRatio: toFixedNumber(securitizationRatio,
|
|
491
|
+
securitizationRatio: toFixedNumber(securitizationRatio, FIXED_U128_DECIMALS),
|
|
1447
492
|
securitization: BigInt(securitization),
|
|
1448
493
|
bitcoinXpubkey: xpubBytes
|
|
1449
494
|
};
|
|
1450
|
-
|
|
495
|
+
const tx = new TxSubmitter(client, client.tx.vaults.create(vaultParams), keypair);
|
|
1451
496
|
if (doNotExceedBalance) {
|
|
1452
497
|
const finalTip = tip ?? 0n;
|
|
1453
498
|
let txFee = await tx.feeEstimate(finalTip);
|
|
@@ -1484,880 +529,39 @@ var Vault = class _Vault {
|
|
|
1484
529
|
if (rawVault.isNone) {
|
|
1485
530
|
throw new Error("Vault creation failed, vault not found");
|
|
1486
531
|
}
|
|
1487
|
-
const tickDuration =
|
|
532
|
+
const tickDuration = config.tickDurationMillis ?? await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber());
|
|
1488
533
|
const vault = new _Vault(vaultId, rawVault.unwrap(), tickDuration);
|
|
1489
534
|
return { vault, txResult: result };
|
|
1490
535
|
}
|
|
1491
536
|
};
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
__publicField(this, "vaultOnlyWatchMode", false);
|
|
1506
|
-
__publicField(this, "shouldLog", true);
|
|
1507
|
-
this.mainchain = accountset.client;
|
|
1508
|
-
if (options.vaultOnlyWatchMode !== void 0) {
|
|
1509
|
-
this.vaultOnlyWatchMode = options.vaultOnlyWatchMode;
|
|
1510
|
-
}
|
|
1511
|
-
if (options.shouldLog !== void 0) {
|
|
1512
|
-
this.shouldLog = options.shouldLog;
|
|
1513
|
-
}
|
|
1514
|
-
this.miningBids = new MiningBids(this.mainchain, this.shouldLog);
|
|
1515
|
-
this.blockWatch = new BlockWatch(this.mainchain, {
|
|
1516
|
-
shouldLog: this.shouldLog
|
|
1517
|
-
});
|
|
1518
|
-
this.blockWatch.events.on(
|
|
1519
|
-
"vaults-updated",
|
|
1520
|
-
(header, vaultIds) => this.onVaultsUpdated(header.hash, vaultIds)
|
|
1521
|
-
);
|
|
1522
|
-
this.blockWatch.events.on("mining-bid", async (header, _bid) => {
|
|
1523
|
-
await this.miningBids.loadAt(this.accountset.namedAccounts, header.hash);
|
|
1524
|
-
this.printBids(header.hash);
|
|
1525
|
-
});
|
|
1526
|
-
this.blockWatch.events.on("mining-bid-ousted", async (header) => {
|
|
1527
|
-
await this.miningBids.loadAt(this.accountset.namedAccounts, header.hash);
|
|
1528
|
-
this.printBids(header.hash);
|
|
1529
|
-
});
|
|
1530
|
-
}
|
|
1531
|
-
stop() {
|
|
1532
|
-
this.blockWatch.stop();
|
|
1533
|
-
}
|
|
1534
|
-
async monitor(justPrint = false) {
|
|
1535
|
-
const client = await this.mainchain;
|
|
1536
|
-
this.tickDuration = (await client.query.ticks.genesisTicker()).tickDurationMillis.toNumber();
|
|
1537
|
-
const blockHeader = await client.rpc.chain.getHeader();
|
|
1538
|
-
const blockHash = new Uint8Array(blockHeader.hash);
|
|
1539
|
-
console.log(
|
|
1540
|
-
`${justPrint ? "Run" : "Started"} at block ${blockHeader.number} - ${blockHeader.hash.toHuman()}`
|
|
1541
|
-
);
|
|
1542
|
-
await this.miningBids.loadAt(this.accountset.namedAccounts, blockHash);
|
|
1543
|
-
const vaults = await client.query.vaults.vaultsById.entries();
|
|
1544
|
-
for (const [storageKey, rawVault] of vaults) {
|
|
1545
|
-
const vaultId = storageKey.args[0].toNumber();
|
|
1546
|
-
this.updateVault(vaultId, rawVault);
|
|
1547
|
-
}
|
|
1548
|
-
await client.query.liquidityPools.capitalRaising((x) => {
|
|
1549
|
-
var _a;
|
|
1550
|
-
this.activatedCapitalByVault = {};
|
|
1551
|
-
for (const entry of x) {
|
|
1552
|
-
const vaultId = entry.vaultId.toNumber();
|
|
1553
|
-
this.activatedCapitalByVault[vaultId] = entry.activatedCapital.toBigInt();
|
|
1554
|
-
}
|
|
1555
|
-
for (const [vaultId, vault] of Object.entries(this.vaultsById)) {
|
|
1556
|
-
const id = Number(vaultId);
|
|
1557
|
-
(_a = this.activatedCapitalByVault)[id] ?? (_a[id] = 0n);
|
|
1558
|
-
this.checkMiningBondAlerts(id, vault);
|
|
1559
|
-
}
|
|
1560
|
-
});
|
|
1561
|
-
this.printVaults();
|
|
1562
|
-
if (!this.vaultOnlyWatchMode && this.shouldLog) {
|
|
1563
|
-
this.miningBids.print();
|
|
1564
|
-
}
|
|
1565
|
-
if (!justPrint) await this.blockWatch.start();
|
|
1566
|
-
}
|
|
1567
|
-
printVaults() {
|
|
1568
|
-
if (!this.shouldLog) return;
|
|
1569
|
-
const vaults = [];
|
|
1570
|
-
for (const [vaultId, vault] of Object.entries(this.vaultsById)) {
|
|
1571
|
-
vaults.push({
|
|
1572
|
-
id: vaultId,
|
|
1573
|
-
btcSpace: `${formatArgons(vault.availableBitcoinSpace())} (${formatArgons(vault.argonsPendingActivation)} pending)`,
|
|
1574
|
-
btcDeal: `${formatArgons(vault.terms.bitcoinBaseFee)} + ${formatPercent(vault.terms.bitcoinAnnualPercentRate)}`,
|
|
1575
|
-
securitization: `${formatArgons(vault.securitization)} at ${vault.securitizationRatio}x`,
|
|
1576
|
-
securActivated: `${formatArgons(vault.activatedSecuritizationPerSlot())}/slot`,
|
|
1577
|
-
liquidPoolDeal: `${formatPercent(vault.terms.liquidityPoolProfitSharing)} sharing`,
|
|
1578
|
-
operator: `${this.accountset.namedAccounts.has(vault.operatorAccountId) ? ` (${this.accountset.namedAccounts.get(vault.operatorAccountId)})` : vault.operatorAccountId}`,
|
|
1579
|
-
state: vault.isClosed ? "closed" : vault.openedDate < /* @__PURE__ */ new Date() ? "open" : "pending"
|
|
1580
|
-
});
|
|
1581
|
-
}
|
|
1582
|
-
if (vaults.length) {
|
|
1583
|
-
if (this.vaultOnlyWatchMode) {
|
|
1584
|
-
console.clear();
|
|
1585
|
-
}
|
|
1586
|
-
console.log("\n\nVaults:");
|
|
1587
|
-
printTable(vaults);
|
|
1588
|
-
}
|
|
1589
|
-
}
|
|
1590
|
-
async recheckAfterActive(vaultId) {
|
|
1591
|
-
const activationDate = this.vaultsById[vaultId].openedDate;
|
|
1592
|
-
if (this.shouldLog) {
|
|
1593
|
-
console.log(`Waiting for vault ${vaultId} to activate ${activationDate}`);
|
|
1594
|
-
}
|
|
1595
|
-
await new Promise((resolve) => setTimeout(resolve, activationDate.getTime() - Date.now()));
|
|
1596
|
-
const client = await this.mainchain;
|
|
1597
|
-
let isReady = false;
|
|
1598
|
-
while (!isReady) {
|
|
1599
|
-
const rawVault = await client.query.vaults.vaultsById(vaultId);
|
|
1600
|
-
if (!rawVault.isSome) return;
|
|
1601
|
-
const vault = new Vault(vaultId, rawVault.value, this.tickDuration);
|
|
1602
|
-
this.vaultsById[vaultId] = vault;
|
|
1603
|
-
if (vault.isClosed) return;
|
|
1604
|
-
if (vault.openedDate < /* @__PURE__ */ new Date()) {
|
|
1605
|
-
isReady = true;
|
|
1606
|
-
break;
|
|
1607
|
-
}
|
|
1608
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
1609
|
-
}
|
|
1610
|
-
this.checkAlerts(vaultId, this.vaultsById[vaultId]);
|
|
1611
|
-
}
|
|
1612
|
-
async onVaultsUpdated(blockHash, vaultIds) {
|
|
1613
|
-
await this.reloadVaultsAt([...vaultIds], blockHash).catch((err) => {
|
|
1614
|
-
console.error(`Failed to reload vault ${[...vaultIds]} at block ${blockHash}:`, err);
|
|
1615
|
-
});
|
|
1616
|
-
this.printVaults();
|
|
1617
|
-
}
|
|
1618
|
-
async reloadVaultsAt(vaultIds, blockHash) {
|
|
1619
|
-
const client = await this.mainchain;
|
|
1620
|
-
const api = await client.at(blockHash);
|
|
1621
|
-
const vaults = await api.query.vaults.vaultsById.multi(vaultIds);
|
|
1622
|
-
for (let i = 0; i < vaultIds.length; i += 1) {
|
|
1623
|
-
this.updateVault(vaultIds[i], vaults[i]);
|
|
1624
|
-
}
|
|
1625
|
-
}
|
|
1626
|
-
updateVault(vaultId, rawVault) {
|
|
1627
|
-
if (rawVault.isNone) return;
|
|
1628
|
-
const vault = new Vault(vaultId, rawVault.value, this.tickDuration);
|
|
1629
|
-
this.vaultsById[vaultId] = vault;
|
|
1630
|
-
if (vault.openedDate > /* @__PURE__ */ new Date()) {
|
|
1631
|
-
void this.recheckAfterActive(vaultId);
|
|
1632
|
-
} else {
|
|
1633
|
-
this.checkAlerts(vaultId, vault);
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
checkAlerts(vaultId, vault) {
|
|
1637
|
-
if (this.alerts.bitcoinSpaceAvailable !== void 0) {
|
|
1638
|
-
const availableBitcoinSpace = vault.availableBitcoinSpace();
|
|
1639
|
-
if (availableBitcoinSpace >= this.alerts.bitcoinSpaceAvailable) {
|
|
1640
|
-
console.warn(
|
|
1641
|
-
`Vault ${vaultId} has available bitcoins above ${formatArgons(this.alerts.bitcoinSpaceAvailable)}`
|
|
1642
|
-
);
|
|
1643
|
-
this.events.emit("bitcoin-space-above", vaultId, availableBitcoinSpace);
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
}
|
|
1647
|
-
checkMiningBondAlerts(vaultId, vault) {
|
|
1648
|
-
if (this.alerts.liquidityPoolSpaceAvailable === void 0) return;
|
|
1649
|
-
const activatedSecuritization = vault.activatedSecuritizationPerSlot();
|
|
1650
|
-
const capitalization = this.activatedCapitalByVault[vaultId] ?? 0n;
|
|
1651
|
-
const available = activatedSecuritization - capitalization;
|
|
1652
|
-
if (available >= this.alerts.liquidityPoolSpaceAvailable) {
|
|
1653
|
-
this.events.emit("liquidity-pool-space-above", vaultId, available);
|
|
1654
|
-
}
|
|
1655
|
-
}
|
|
1656
|
-
printBids(blockHash) {
|
|
1657
|
-
if (!this.shouldLog) return;
|
|
1658
|
-
if (this.lastPrintedBids === blockHash) return;
|
|
1659
|
-
this.miningBids.print();
|
|
1660
|
-
this.lastPrintedBids = blockHash;
|
|
1661
|
-
}
|
|
1662
|
-
};
|
|
1663
|
-
|
|
1664
|
-
// src/CohortBidder.ts
|
|
1665
|
-
var CohortBidder = class {
|
|
1666
|
-
constructor(accountset, cohortStartingFrameId, subaccounts, options, callbacks) {
|
|
1667
|
-
this.accountset = accountset;
|
|
1668
|
-
this.cohortStartingFrameId = cohortStartingFrameId;
|
|
1669
|
-
this.subaccounts = subaccounts;
|
|
1670
|
-
this.options = options;
|
|
1671
|
-
this.callbacks = callbacks;
|
|
1672
|
-
__publicField(this, "txFees", 0n);
|
|
1673
|
-
__publicField(this, "bidsAttempted", 0);
|
|
1674
|
-
__publicField(this, "winningBids", []);
|
|
1675
|
-
__publicField(this, "myAddresses", /* @__PURE__ */ new Set());
|
|
1676
|
-
__publicField(this, "currentBids", {
|
|
1677
|
-
bids: [],
|
|
1678
|
-
mostRecentBidTick: 0,
|
|
1679
|
-
atTick: 0,
|
|
1680
|
-
atBlockNumber: 0
|
|
1681
|
-
});
|
|
1682
|
-
__publicField(this, "unsubscribe");
|
|
1683
|
-
__publicField(this, "pendingRequest");
|
|
1684
|
-
__publicField(this, "isStopped", false);
|
|
1685
|
-
__publicField(this, "millisPerTick");
|
|
1686
|
-
__publicField(this, "minIncrement", 10000n);
|
|
1687
|
-
__publicField(this, "nextCohortSize");
|
|
1688
|
-
__publicField(this, "lastBidTick", 0);
|
|
1689
|
-
__publicField(this, "evaluateInterval");
|
|
1690
|
-
this.subaccounts.forEach((x) => {
|
|
1691
|
-
this.myAddresses.add(x.address);
|
|
1692
|
-
});
|
|
1693
|
-
}
|
|
1694
|
-
get clientPromise() {
|
|
1695
|
-
return this.accountset.client;
|
|
1696
|
-
}
|
|
1697
|
-
async start() {
|
|
1698
|
-
console.log(`Starting cohort ${this.cohortStartingFrameId} bidder`, {
|
|
1699
|
-
maxBid: formatArgons(this.options.maxBid),
|
|
1700
|
-
minBid: formatArgons(this.options.minBid),
|
|
1701
|
-
bidIncrement: formatArgons(this.options.bidIncrement),
|
|
1702
|
-
maxBudget: formatArgons(this.options.maxBudget),
|
|
1703
|
-
bidDelay: this.options.bidDelay,
|
|
1704
|
-
subaccounts: this.subaccounts
|
|
1705
|
-
});
|
|
1706
|
-
const client = await this.clientPromise;
|
|
1707
|
-
this.minIncrement = client.consts.miningSlot.bidIncrements.toBigInt();
|
|
1708
|
-
this.nextCohortSize = await client.query.miningSlot.nextCohortSize().then((x) => x.toNumber());
|
|
1709
|
-
if (this.subaccounts.length > this.nextCohortSize) {
|
|
1710
|
-
console.info(
|
|
1711
|
-
`Cohort size ${this.nextCohortSize} is less than provided subaccounts ${this.subaccounts.length}.`
|
|
1712
|
-
);
|
|
1713
|
-
this.subaccounts.length = this.nextCohortSize;
|
|
1714
|
-
}
|
|
1715
|
-
this.millisPerTick = await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber());
|
|
1716
|
-
let didStart = false;
|
|
1717
|
-
this.unsubscribe = await client.queryMulti(
|
|
1718
|
-
[
|
|
1719
|
-
client.query.miningSlot.bidsForNextSlotCohort,
|
|
1720
|
-
client.query.miningSlot.nextFrameId,
|
|
1721
|
-
client.query.ticks.currentTick,
|
|
1722
|
-
client.query.system.number
|
|
1723
|
-
],
|
|
1724
|
-
async ([rawBids, nextFrameId, currentTick, blockNumber]) => {
|
|
1725
|
-
if (nextFrameId.toNumber() === this.cohortStartingFrameId) {
|
|
1726
|
-
this.updateBidList(rawBids, blockNumber.toNumber(), currentTick.toNumber());
|
|
1727
|
-
if (!didStart) {
|
|
1728
|
-
didStart = true;
|
|
1729
|
-
this.scheduleEvaluation();
|
|
1730
|
-
void this.checkWinningBids();
|
|
1731
|
-
}
|
|
1732
|
-
}
|
|
1733
|
-
}
|
|
1734
|
-
);
|
|
1735
|
-
}
|
|
1736
|
-
async stop() {
|
|
1737
|
-
if (this.isStopped) return this.winningBids;
|
|
1738
|
-
this.isStopped = true;
|
|
1739
|
-
clearInterval(this.evaluateInterval);
|
|
1740
|
-
console.log("Stopping bidder for cohort", this.cohortStartingFrameId);
|
|
1741
|
-
if (this.unsubscribe) {
|
|
1742
|
-
this.unsubscribe();
|
|
1743
|
-
}
|
|
1744
|
-
const client = await this.clientPromise;
|
|
1745
|
-
const [nextFrameId, isBiddingOpen] = await client.queryMulti([
|
|
1746
|
-
client.query.miningSlot.nextFrameId,
|
|
1747
|
-
client.query.miningSlot.isNextSlotBiddingOpen
|
|
1748
|
-
]);
|
|
1749
|
-
if (nextFrameId.toNumber() === this.cohortStartingFrameId && isBiddingOpen.isTrue) {
|
|
1750
|
-
console.log("Bidding is still open, waiting for it to close");
|
|
1751
|
-
await new Promise(async (resolve) => {
|
|
1752
|
-
const unsub = await client.query.miningSlot.isNextSlotBiddingOpen((isOpen) => {
|
|
1753
|
-
if (isOpen.isFalse) {
|
|
1754
|
-
unsub();
|
|
1755
|
-
resolve();
|
|
1756
|
-
}
|
|
1757
|
-
});
|
|
1758
|
-
});
|
|
1759
|
-
}
|
|
1760
|
-
void await this.pendingRequest;
|
|
1761
|
-
const currentFrameId = await client.query.miningSlot.nextFrameId();
|
|
1762
|
-
let blockNumber;
|
|
1763
|
-
if (currentFrameId.toNumber() > this.cohortStartingFrameId) {
|
|
1764
|
-
blockNumber = await client.query.miningSlot.frameStartBlockNumbers().then((x) => x[0]?.toNumber()) - 1;
|
|
1765
|
-
} else {
|
|
1766
|
-
blockNumber = await client.query.system.number().then((x) => x.toNumber());
|
|
1767
|
-
}
|
|
1768
|
-
const blockHash = await client.query.system.blockHash(blockNumber);
|
|
1769
|
-
const api = await client.at(blockHash);
|
|
1770
|
-
const rawBids = await api.query.miningSlot.bidsForNextSlotCohort();
|
|
1771
|
-
const currentTick = await api.query.ticks.currentTick().then((x) => x.toNumber());
|
|
1772
|
-
this.updateBidList(rawBids, blockNumber, currentTick);
|
|
1773
|
-
console.log("Bidder stopped", {
|
|
1774
|
-
cohortStartingFrameId: this.cohortStartingFrameId,
|
|
1775
|
-
blockNumber,
|
|
1776
|
-
winningBids: this.winningBids
|
|
1777
|
-
});
|
|
1778
|
-
return this.winningBids;
|
|
1779
|
-
}
|
|
1780
|
-
async checkWinningBids() {
|
|
1781
|
-
if (this.isStopped) return;
|
|
1782
|
-
if (this.pendingRequest) {
|
|
1783
|
-
console.log("Current bid is still in progress, skipping this check");
|
|
1784
|
-
return;
|
|
1785
|
-
}
|
|
1786
|
-
if (this.currentBids.mostRecentBidTick < this.lastBidTick) {
|
|
1787
|
-
console.log(`Waiting for bids more recent than our last attempt.`, {
|
|
1788
|
-
ownAttemptedBidTick: this.lastBidTick,
|
|
1789
|
-
liveBidsTick: this.currentBids.mostRecentBidTick
|
|
1790
|
-
});
|
|
1791
|
-
return;
|
|
1792
|
-
}
|
|
1793
|
-
const bids = [...this.currentBids.bids];
|
|
1794
|
-
const bidsAtTick = this.currentBids.atTick;
|
|
1795
|
-
const blockNumber = this.currentBids.atBlockNumber;
|
|
1796
|
-
const winningBids = bids.filter((x) => this.myAddresses.has(x.address));
|
|
1797
|
-
if (winningBids.length >= this.subaccounts.length) {
|
|
1798
|
-
console.log(`No updates needed. Winning all remaining seats (${winningBids.length}).`);
|
|
1799
|
-
return;
|
|
1800
|
-
}
|
|
1801
|
-
console.log(
|
|
1802
|
-
`Checking bids for cohort ${this.cohortStartingFrameId}, Still trying for seats: ${this.subaccounts.length}`
|
|
1803
|
-
);
|
|
1804
|
-
const winningAddresses = new Set(winningBids.map((x) => x.address));
|
|
1805
|
-
let lowestBid;
|
|
1806
|
-
let myAllocatedBids = 0n;
|
|
1807
|
-
for (const bid of bids) {
|
|
1808
|
-
lowestBid ?? (lowestBid = bid.bidMicrogons);
|
|
1809
|
-
if (this.myAddresses.has(bid.address)) {
|
|
1810
|
-
myAllocatedBids += bid.bidMicrogons;
|
|
1811
|
-
} else {
|
|
1812
|
-
if (bid.bidMicrogons < lowestBid) {
|
|
1813
|
-
lowestBid = bid.bidMicrogons;
|
|
1814
|
-
}
|
|
1815
|
-
}
|
|
1816
|
-
}
|
|
1817
|
-
lowestBid ?? (lowestBid = -this.options.bidIncrement);
|
|
1818
|
-
let nextBid = lowestBid + this.options.bidIncrement;
|
|
1819
|
-
if (nextBid < this.options.minBid) {
|
|
1820
|
-
nextBid = this.options.minBid;
|
|
1821
|
-
}
|
|
1822
|
-
if (nextBid > this.options.maxBid) {
|
|
1823
|
-
nextBid = this.options.maxBid;
|
|
1824
|
-
}
|
|
1825
|
-
const fakeTx = await this.accountset.createMiningBidTx({
|
|
1826
|
-
subaccounts: this.subaccounts,
|
|
1827
|
-
bidAmount: nextBid
|
|
1828
|
-
});
|
|
1829
|
-
let availableBalanceForBids = await this.accountset.submitterBalance();
|
|
1830
|
-
availableBalanceForBids += myAllocatedBids;
|
|
1831
|
-
const tip = this.options.tipPerTransaction ?? 0n;
|
|
1832
|
-
const feeEstimate = await fakeTx.feeEstimate(tip);
|
|
1833
|
-
const estimatedFeePlusTip = feeEstimate + tip;
|
|
1834
|
-
let budgetForSeats = this.options.maxBudget - estimatedFeePlusTip;
|
|
1835
|
-
if (budgetForSeats > availableBalanceForBids) {
|
|
1836
|
-
budgetForSeats = availableBalanceForBids - estimatedFeePlusTip;
|
|
1837
|
-
}
|
|
1838
|
-
if (nextBid < lowestBid) {
|
|
1839
|
-
console.log(
|
|
1840
|
-
`Next bid within parameters is ${formatArgons(nextBid)}, but it's not enough. Current lowest bid is ${formatArgons(lowestBid)}.`
|
|
1841
|
-
);
|
|
1842
|
-
this.safeRecordParamsAdjusted({
|
|
1843
|
-
tick: bidsAtTick,
|
|
1844
|
-
blockNumber,
|
|
1845
|
-
maxSeats: 0,
|
|
1846
|
-
winningBidCount: winningBids.length,
|
|
1847
|
-
reason: "max-bid-too-low",
|
|
1848
|
-
availableBalanceForBids
|
|
1849
|
-
});
|
|
1850
|
-
return;
|
|
1851
|
-
}
|
|
1852
|
-
if (nextBid - lowestBid < Number(this.minIncrement)) {
|
|
1853
|
-
console.log(
|
|
1854
|
-
`Can't make any more bids for ${this.cohortStartingFrameId} with given constraints (next bid below min increment).`,
|
|
1855
|
-
{
|
|
1856
|
-
lowestCurrentBid: formatArgons(lowestBid),
|
|
1857
|
-
nextAttemptedBid: formatArgons(nextBid),
|
|
1858
|
-
maxBid: formatArgons(this.options.maxBid)
|
|
1859
|
-
}
|
|
1860
|
-
);
|
|
1861
|
-
this.safeRecordParamsAdjusted({
|
|
1862
|
-
tick: bidsAtTick,
|
|
1863
|
-
blockNumber,
|
|
1864
|
-
maxSeats: 0,
|
|
1865
|
-
winningBidCount: winningBids.length,
|
|
1866
|
-
reason: "max-bid-too-low",
|
|
1867
|
-
availableBalanceForBids
|
|
1868
|
-
});
|
|
1869
|
-
return;
|
|
1870
|
-
}
|
|
1871
|
-
const seatsInBudget = nextBid === 0n ? this.subaccounts.length : Number(budgetForSeats / nextBid);
|
|
1872
|
-
let accountsToUse = [...this.subaccounts];
|
|
1873
|
-
if (accountsToUse.length > seatsInBudget) {
|
|
1874
|
-
this.safeRecordParamsAdjusted({
|
|
1875
|
-
tick: bidsAtTick,
|
|
1876
|
-
blockNumber,
|
|
1877
|
-
maxSeats: this.subaccounts.length,
|
|
1878
|
-
winningBidCount: winningBids.length,
|
|
1879
|
-
reason: availableBalanceForBids - estimatedFeePlusTip < nextBid * BigInt(seatsInBudget) ? "insufficient-balance" : "max-budget-too-low",
|
|
1880
|
-
availableBalanceForBids
|
|
1881
|
-
});
|
|
1882
|
-
accountsToUse.sort((a, b) => {
|
|
1883
|
-
const isWinningA = winningAddresses.has(a.address);
|
|
1884
|
-
const isWinningB = winningAddresses.has(b.address);
|
|
1885
|
-
if (isWinningA && !isWinningB) return -1;
|
|
1886
|
-
if (!isWinningA && isWinningB) return 1;
|
|
1887
|
-
if (a.isRebid && !b.isRebid) return -1;
|
|
1888
|
-
if (!a.isRebid && b.isRebid) return 1;
|
|
1889
|
-
return a.index - b.index;
|
|
1890
|
-
});
|
|
1891
|
-
accountsToUse.length = seatsInBudget;
|
|
1892
|
-
}
|
|
1893
|
-
if (accountsToUse.length > winningBids.length) {
|
|
1894
|
-
this.pendingRequest = this.submitBids(nextBid, accountsToUse);
|
|
1895
|
-
}
|
|
1896
|
-
}
|
|
1897
|
-
async submitBids(microgonsPerSeat, subaccounts) {
|
|
1898
|
-
try {
|
|
1899
|
-
this.bidsAttempted += subaccounts.length;
|
|
1900
|
-
const submitter = await this.accountset.createMiningBidTx({
|
|
1901
|
-
subaccounts,
|
|
1902
|
-
bidAmount: microgonsPerSeat
|
|
1903
|
-
});
|
|
1904
|
-
const tip = this.options.tipPerTransaction ?? 0n;
|
|
1905
|
-
const txResult = await submitter.submit({
|
|
1906
|
-
tip,
|
|
1907
|
-
useLatestNonce: true
|
|
1908
|
-
});
|
|
1909
|
-
const bidError = await txResult.inBlockPromise.then(() => void 0).catch((x) => x);
|
|
1910
|
-
const client = await this.clientPromise;
|
|
1911
|
-
let api = txResult.includedInBlock ? await client.at(txResult.includedInBlock) : client;
|
|
1912
|
-
this.lastBidTick = await api.query.ticks.currentTick().then((x) => x.toNumber());
|
|
1913
|
-
const blockNumber = await api.query.system.number().then((x) => x.toNumber());
|
|
1914
|
-
const bidAtTick = this.lastBidTick;
|
|
1915
|
-
try {
|
|
1916
|
-
this.callbacks?.onBidsSubmitted?.({
|
|
1917
|
-
tick: bidAtTick,
|
|
1918
|
-
blockNumber,
|
|
1919
|
-
microgonsPerSeat,
|
|
1920
|
-
txFeePlusTip: txResult.finalFee ?? 0n,
|
|
1921
|
-
submittedCount: subaccounts.length
|
|
1922
|
-
});
|
|
1923
|
-
} catch (error) {
|
|
1924
|
-
console.error("Error in onBidsSubmitted callback:", error);
|
|
1925
|
-
}
|
|
1926
|
-
const successfulBids = txResult.batchInterruptedIndex ?? subaccounts.length;
|
|
1927
|
-
this.txFees += txResult.finalFee ?? 0n;
|
|
1928
|
-
console.log("Result of bids for cohort", {
|
|
1929
|
-
successfulBids,
|
|
1930
|
-
bidsPlaced: subaccounts.length,
|
|
1931
|
-
bidPerSeat: formatArgons(microgonsPerSeat),
|
|
1932
|
-
bidAtTick
|
|
1933
|
-
});
|
|
1934
|
-
if (bidError) {
|
|
1935
|
-
try {
|
|
1936
|
-
this.callbacks?.onBidsRejected?.({
|
|
1937
|
-
tick: bidAtTick,
|
|
1938
|
-
blockNumber,
|
|
1939
|
-
microgonsPerSeat,
|
|
1940
|
-
submittedCount: subaccounts.length,
|
|
1941
|
-
rejectedCount: subaccounts.length - successfulBids,
|
|
1942
|
-
bidError
|
|
1943
|
-
});
|
|
1944
|
-
} catch (error) {
|
|
1945
|
-
console.error("Error in onBidsRejected callback:", error);
|
|
1946
|
-
}
|
|
1947
|
-
throw bidError;
|
|
1948
|
-
}
|
|
1949
|
-
} catch (err) {
|
|
1950
|
-
console.error(`Error bidding for cohort ${this.cohortStartingFrameId}:`, err);
|
|
1951
|
-
} finally {
|
|
1952
|
-
this.pendingRequest = void 0;
|
|
1953
|
-
this.scheduleEvaluation();
|
|
1954
|
-
}
|
|
1955
|
-
}
|
|
1956
|
-
scheduleEvaluation() {
|
|
1957
|
-
const millisPerTick = this.millisPerTick;
|
|
1958
|
-
const delayTicks = Math.max(this.options.bidDelay, 1);
|
|
1959
|
-
const delay = delayTicks * millisPerTick;
|
|
1960
|
-
if (this.evaluateInterval) clearInterval(this.evaluateInterval);
|
|
1961
|
-
console.log(`Scheduling next evaluation in ${delay}ms`);
|
|
1962
|
-
this.evaluateInterval = setInterval(() => this.checkWinningBids().catch(console.error), delay);
|
|
1963
|
-
}
|
|
1964
|
-
updateBidList(rawBids, blockNumber, tick) {
|
|
1965
|
-
try {
|
|
1966
|
-
let mostRecentBidTick = 0;
|
|
1967
|
-
let hasDiffs = this.currentBids.bids.length !== rawBids.length;
|
|
1968
|
-
const bids = [];
|
|
1969
|
-
for (let i = 0; i < rawBids.length; i += 1) {
|
|
1970
|
-
const rawBid = rawBids[i];
|
|
1971
|
-
const bidAtTick = rawBid.bidAtTick.toNumber();
|
|
1972
|
-
if (bidAtTick > mostRecentBidTick) {
|
|
1973
|
-
mostRecentBidTick = bidAtTick;
|
|
1974
|
-
}
|
|
1975
|
-
const address = rawBid.accountId.toHuman();
|
|
1976
|
-
const bidMicrogons = rawBid.bid.toBigInt();
|
|
1977
|
-
if (!hasDiffs) {
|
|
1978
|
-
const existing = this.currentBids.bids[i];
|
|
1979
|
-
hasDiffs = existing?.address !== address || existing?.bidMicrogons !== bidMicrogons;
|
|
1980
|
-
}
|
|
1981
|
-
bids.push({
|
|
1982
|
-
address,
|
|
1983
|
-
bidMicrogons,
|
|
1984
|
-
bidAtTick
|
|
1985
|
-
});
|
|
1986
|
-
}
|
|
1987
|
-
if (blockNumber > this.currentBids.atBlockNumber && hasDiffs) {
|
|
1988
|
-
this.currentBids.bids = bids;
|
|
1989
|
-
this.currentBids.mostRecentBidTick = mostRecentBidTick;
|
|
1990
|
-
this.currentBids.atTick = tick;
|
|
1991
|
-
this.currentBids.atBlockNumber = blockNumber;
|
|
1992
|
-
this.winningBids = bids.filter((x) => this.myAddresses.has(x.address));
|
|
1993
|
-
console.log("Now winning bids:", this.winningBids.length);
|
|
1994
|
-
if (this.callbacks?.onBidsUpdated) {
|
|
1995
|
-
this.callbacks.onBidsUpdated({
|
|
1996
|
-
bids: this.winningBids,
|
|
1997
|
-
atBlockNumber: blockNumber,
|
|
1998
|
-
tick: mostRecentBidTick
|
|
1999
|
-
});
|
|
2000
|
-
}
|
|
2001
|
-
}
|
|
2002
|
-
} catch (err) {
|
|
2003
|
-
console.error("Error processing updated bids list:", err);
|
|
2004
|
-
}
|
|
2005
|
-
}
|
|
2006
|
-
safeRecordParamsAdjusted(args) {
|
|
2007
|
-
try {
|
|
2008
|
-
this.callbacks?.onBidParamsAdjusted?.(args);
|
|
2009
|
-
} catch (err) {
|
|
2010
|
-
console.error("Error in onBidParamsAdjusted callback:", err);
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
|
-
};
|
|
2014
|
-
var EMPTY_TABLE = {
|
|
2015
|
-
headerBottom: { left: " ", mid: " ", other: "\u2500", right: " " },
|
|
2016
|
-
headerTop: { left: " ", mid: " ", other: " ", right: " " },
|
|
2017
|
-
rowSeparator: { left: " ", mid: " ", other: " ", right: " " },
|
|
2018
|
-
tableBottom: { left: " ", mid: " ", other: " ", right: " " },
|
|
2019
|
-
vertical: " "
|
|
2020
|
-
};
|
|
2021
|
-
var BidPool = class {
|
|
2022
|
-
constructor(client, keypair, accountRegistry = AccountRegistry.factory()) {
|
|
2023
|
-
this.client = client;
|
|
2024
|
-
this.keypair = keypair;
|
|
2025
|
-
this.accountRegistry = accountRegistry;
|
|
2026
|
-
__publicField(this, "bidPoolAmount", 0n);
|
|
2027
|
-
__publicField(this, "nextFrameId", 1);
|
|
2028
|
-
__publicField(this, "poolVaultCapitalByFrame", {});
|
|
2029
|
-
__publicField(this, "vaultSecuritization", []);
|
|
2030
|
-
__publicField(this, "printTimeout");
|
|
2031
|
-
__publicField(this, "blockWatch");
|
|
2032
|
-
__publicField(this, "vaultsById", {});
|
|
2033
|
-
__publicField(this, "tickDuration");
|
|
2034
|
-
__publicField(this, "lastDistributedFrameId");
|
|
2035
|
-
__publicField(this, "FrameSubscriptions", {});
|
|
2036
|
-
this.blockWatch = new BlockWatch(client, { shouldLog: false });
|
|
2037
|
-
}
|
|
2038
|
-
async onVaultsUpdated(blockHash, vaultIdSet) {
|
|
2039
|
-
const client = await this.client;
|
|
2040
|
-
this.tickDuration ?? (this.tickDuration = (await client.query.ticks.genesisTicker()).tickDurationMillis.toNumber());
|
|
2041
|
-
const api = await client.at(blockHash);
|
|
2042
|
-
const vaultIds = [...vaultIdSet];
|
|
2043
|
-
const rawVaults = await api.query.vaults.vaultsById.multi(vaultIds);
|
|
2044
|
-
for (let i = 0; i < vaultIds.length; i += 1) {
|
|
2045
|
-
const rawVault = rawVaults[i];
|
|
2046
|
-
if (rawVault.isNone) continue;
|
|
2047
|
-
const vaultId = vaultIds[i];
|
|
2048
|
-
this.vaultsById[vaultId] = new Vault(vaultId, rawVault.unwrap(), this.tickDuration);
|
|
2049
|
-
}
|
|
2050
|
-
const vaults = Object.entries(this.vaultsById);
|
|
2051
|
-
const newSecuritization = [];
|
|
2052
|
-
for (const [vaultId, vault] of vaults) {
|
|
2053
|
-
const amount = vault.activatedSecuritizationPerSlot();
|
|
2054
|
-
newSecuritization.push({
|
|
2055
|
-
vaultId: Number(vaultId),
|
|
2056
|
-
bitcoinSpace: vault.availableBitcoinSpace(),
|
|
2057
|
-
activatedSecuritization: amount,
|
|
2058
|
-
vaultSharingPercent: vault.terms.liquidityPoolProfitSharing
|
|
2059
|
-
});
|
|
2060
|
-
}
|
|
2061
|
-
newSecuritization.sort((a, b) => {
|
|
2062
|
-
const diff2 = b.activatedSecuritization - a.activatedSecuritization;
|
|
2063
|
-
if (diff2 !== 0n) return Number(diff2);
|
|
2064
|
-
return a.vaultId - b.vaultId;
|
|
2065
|
-
});
|
|
2066
|
-
this.vaultSecuritization = newSecuritization;
|
|
2067
|
-
this.printDebounce();
|
|
2068
|
-
}
|
|
2069
|
-
async getBidPool() {
|
|
2070
|
-
const client = await this.client;
|
|
2071
|
-
const balanceBytes = await client.rpc.state.call("MiningSlotApi_bid_pool", "");
|
|
2072
|
-
const balance = client.createType("U128", balanceBytes);
|
|
2073
|
-
return balance.toBigInt();
|
|
2074
|
-
}
|
|
2075
|
-
async loadAt(blockHash) {
|
|
2076
|
-
const client = await this.client;
|
|
2077
|
-
blockHash ?? (blockHash = new Uint8Array((await client.rpc.chain.getHeader()).hash));
|
|
2078
|
-
const api = await client.at(blockHash);
|
|
2079
|
-
const rawVaultIds = await api.query.vaults.vaultsById.keys();
|
|
2080
|
-
const vaultIds = rawVaultIds.map((x) => x.args[0].toNumber());
|
|
2081
|
-
this.bidPoolAmount = await this.getBidPool();
|
|
2082
|
-
this.nextFrameId = (await api.query.miningSlot.nextFrameId()).toNumber();
|
|
2083
|
-
const contributors = await api.query.liquidityPools.vaultPoolsByFrame.entries();
|
|
2084
|
-
for (const [frameId, funds] of contributors) {
|
|
2085
|
-
const FrameIdNumber = frameId.args[0].toNumber();
|
|
2086
|
-
this.loadFrameData(FrameIdNumber, funds);
|
|
2087
|
-
}
|
|
2088
|
-
for (const entrant of await api.query.liquidityPools.capitalActive()) {
|
|
2089
|
-
this.setVaultFrameData(entrant.frameId.toNumber(), entrant.vaultId.toNumber(), {
|
|
2090
|
-
activatedCapital: entrant.activatedCapital.toBigInt()
|
|
2091
|
-
});
|
|
2092
|
-
}
|
|
2093
|
-
for (const entrant of await api.query.liquidityPools.capitalRaising()) {
|
|
2094
|
-
this.setVaultFrameData(entrant.frameId.toNumber(), entrant.vaultId.toNumber(), {
|
|
2095
|
-
activatedCapital: entrant.activatedCapital.toBigInt()
|
|
2096
|
-
});
|
|
2097
|
-
}
|
|
2098
|
-
await this.onVaultsUpdated(blockHash, new Set(vaultIds));
|
|
2099
|
-
this.print();
|
|
2100
|
-
}
|
|
2101
|
-
async watch() {
|
|
2102
|
-
await this.loadAt();
|
|
2103
|
-
await this.blockWatch.start();
|
|
2104
|
-
this.blockWatch.events.on("vaults-updated", (b, v) => this.onVaultsUpdated(b.hash, v));
|
|
2105
|
-
const api = await this.client;
|
|
2106
|
-
this.blockWatch.events.on("event", async (_, event) => {
|
|
2107
|
-
if (api.events.liquidityPools.BidPoolDistributed.is(event)) {
|
|
2108
|
-
const { frameId: rawFrameId } = event.data;
|
|
2109
|
-
this.lastDistributedFrameId = rawFrameId.toNumber();
|
|
2110
|
-
this.bidPoolAmount = await this.getBidPool();
|
|
2111
|
-
this.FrameSubscriptions[rawFrameId.toNumber()]?.();
|
|
2112
|
-
const entrant = await api.query.liquidityPools.vaultPoolsByFrame(rawFrameId);
|
|
2113
|
-
this.loadFrameData(rawFrameId.toNumber(), entrant);
|
|
2114
|
-
this.printDebounce();
|
|
2115
|
-
}
|
|
2116
|
-
if (api.events.liquidityPools.NextBidPoolCapitalLocked.is(event)) {
|
|
2117
|
-
const { frameId } = event.data;
|
|
2118
|
-
for (let inc = 0; inc < 2; inc++) {
|
|
2119
|
-
const id = frameId.toNumber() + inc;
|
|
2120
|
-
if (!this.FrameSubscriptions[id]) {
|
|
2121
|
-
this.FrameSubscriptions[id] = await api.query.liquidityPools.vaultPoolsByFrame(
|
|
2122
|
-
id,
|
|
2123
|
-
async (entrant) => {
|
|
2124
|
-
this.loadFrameData(id, entrant);
|
|
2125
|
-
this.printDebounce();
|
|
2126
|
-
}
|
|
2127
|
-
);
|
|
2128
|
-
}
|
|
2129
|
-
}
|
|
2130
|
-
}
|
|
2131
|
-
});
|
|
2132
|
-
const unsubscribe = await api.queryMulti(
|
|
2133
|
-
[
|
|
2134
|
-
api.query.miningSlot.bidsForNextSlotCohort,
|
|
2135
|
-
api.query.miningSlot.nextFrameId,
|
|
2136
|
-
api.query.liquidityPools.capitalActive,
|
|
2137
|
-
api.query.liquidityPools.capitalRaising
|
|
2138
|
-
],
|
|
2139
|
-
async ([_bids, nextFrameId, openVaultBidPoolCapital, nextPoolCapital]) => {
|
|
2140
|
-
this.bidPoolAmount = await this.getBidPool();
|
|
2141
|
-
this.nextFrameId = nextFrameId.toNumber();
|
|
2142
|
-
for (const entrant of [...openVaultBidPoolCapital, ...nextPoolCapital]) {
|
|
2143
|
-
this.setVaultFrameData(entrant.frameId.toNumber(), entrant.vaultId.toNumber(), {
|
|
2144
|
-
activatedCapital: entrant.activatedCapital.toBigInt()
|
|
2145
|
-
});
|
|
2146
|
-
}
|
|
2147
|
-
this.printDebounce();
|
|
2148
|
-
}
|
|
2149
|
-
);
|
|
2150
|
-
return { unsubscribe };
|
|
2151
|
-
}
|
|
2152
|
-
async bondArgons(vaultId, amount, options) {
|
|
2153
|
-
const client = await this.client;
|
|
2154
|
-
const tx = client.tx.liquidityPools.bondArgons(vaultId, amount);
|
|
2155
|
-
const txSubmitter = new TxSubmitter(client, tx, this.keypair);
|
|
2156
|
-
const affordability = await txSubmitter.canAfford({
|
|
2157
|
-
tip: options?.tip,
|
|
2158
|
-
unavailableBalance: amount
|
|
2159
|
-
});
|
|
2160
|
-
if (!affordability.canAfford) {
|
|
2161
|
-
console.warn("Insufficient balance to bond argons to liquidity pool", {
|
|
2162
|
-
...affordability,
|
|
2163
|
-
argonsNeeded: amount
|
|
2164
|
-
});
|
|
2165
|
-
throw new Error("Insufficient balance to bond argons to liquidity pool");
|
|
2166
|
-
}
|
|
2167
|
-
const result = await txSubmitter.submit({
|
|
2168
|
-
tip: options?.tip,
|
|
2169
|
-
useLatestNonce: true
|
|
2170
|
-
});
|
|
2171
|
-
await result.inBlockPromise;
|
|
2172
|
-
return result;
|
|
2173
|
-
}
|
|
2174
|
-
printDebounce() {
|
|
2175
|
-
if (this.printTimeout) {
|
|
2176
|
-
clearTimeout(this.printTimeout);
|
|
2177
|
-
}
|
|
2178
|
-
this.printTimeout = setTimeout(() => {
|
|
2179
|
-
this.print();
|
|
2180
|
-
}, 100);
|
|
2181
|
-
}
|
|
2182
|
-
getOperatorName(vaultId) {
|
|
2183
|
-
const vault = this.vaultsById[vaultId];
|
|
2184
|
-
return this.accountRegistry.getName(vault.operatorAccountId) ?? vault.operatorAccountId;
|
|
2185
|
-
}
|
|
2186
|
-
print() {
|
|
2187
|
-
console.clear();
|
|
2188
|
-
const lastDistributedFrameId = this.lastDistributedFrameId;
|
|
2189
|
-
const distributedFrame = this.poolVaultCapitalByFrame[this.lastDistributedFrameId ?? -1] ?? {};
|
|
2190
|
-
if (Object.keys(distributedFrame).length > 0) {
|
|
2191
|
-
console.log(`
|
|
2192
|
-
|
|
2193
|
-
Distributed (Frame ${lastDistributedFrameId})`);
|
|
2194
|
-
const rows = [];
|
|
2195
|
-
let maxWidth2 = 0;
|
|
2196
|
-
for (const [key, entry] of Object.entries(distributedFrame)) {
|
|
2197
|
-
const { table, width } = this.createBondCapitalTable(
|
|
2198
|
-
entry.earnings ?? 0n,
|
|
2199
|
-
entry.contributors ?? [],
|
|
2200
|
-
`Earnings (shared = ${formatPercent(entry.vaultSharingPercent)})`
|
|
2201
|
-
);
|
|
2202
|
-
if (width > maxWidth2) {
|
|
2203
|
-
maxWidth2 = width;
|
|
2204
|
-
}
|
|
2205
|
-
rows.push({
|
|
2206
|
-
Vault: key,
|
|
2207
|
-
Who: this.getOperatorName(Number(key)),
|
|
2208
|
-
Balances: table
|
|
2209
|
-
});
|
|
2210
|
-
}
|
|
2211
|
-
new Table({
|
|
2212
|
-
columns: [
|
|
2213
|
-
{ name: "Vault", alignment: "left" },
|
|
2214
|
-
{ name: "Who", alignment: "left" },
|
|
2215
|
-
{
|
|
2216
|
-
name: "Balances",
|
|
2217
|
-
title: "Contributor Balances",
|
|
2218
|
-
alignment: "center",
|
|
2219
|
-
minLen: maxWidth2
|
|
2220
|
-
}
|
|
2221
|
-
],
|
|
2222
|
-
rows
|
|
2223
|
-
}).printTable();
|
|
2224
|
-
}
|
|
2225
|
-
console.log(
|
|
2226
|
-
`
|
|
2227
|
-
|
|
2228
|
-
Active Bid Pool: ${formatArgons(this.bidPoolAmount)} (Frame ${this.nextFrameId})`
|
|
2229
|
-
);
|
|
2230
|
-
const Frame = this.poolVaultCapitalByFrame[this.nextFrameId];
|
|
2231
|
-
if (Object.keys(Frame ?? {}).length > 0) {
|
|
2232
|
-
const rows = [];
|
|
2233
|
-
let maxWidth2 = 0;
|
|
2234
|
-
for (const [key, entry] of Object.entries(Frame)) {
|
|
2235
|
-
const { table, width } = this.createBondCapitalTable(
|
|
2236
|
-
entry.activatedCapital,
|
|
2237
|
-
entry.contributors ?? []
|
|
2238
|
-
);
|
|
2239
|
-
if (width > maxWidth2) {
|
|
2240
|
-
maxWidth2 = width;
|
|
2241
|
-
}
|
|
2242
|
-
rows.push({
|
|
2243
|
-
Vault: key,
|
|
2244
|
-
Who: this.getOperatorName(Number(key)),
|
|
2245
|
-
"Pool Capital": table
|
|
2246
|
-
});
|
|
2247
|
-
}
|
|
2248
|
-
new Table({
|
|
2249
|
-
columns: [
|
|
2250
|
-
{ name: "Vault", alignment: "left" },
|
|
2251
|
-
{ name: "Who", alignment: "left" },
|
|
2252
|
-
{ name: "Pool Capital", alignment: "left", minLen: maxWidth2 }
|
|
2253
|
-
],
|
|
2254
|
-
rows
|
|
2255
|
-
}).printTable();
|
|
2256
|
-
}
|
|
2257
|
-
const raisingFunds = this.poolVaultCapitalByFrame[this.nextFrameId + 1] ?? [];
|
|
2258
|
-
let maxWidth = 0;
|
|
2259
|
-
const nextCapital = [];
|
|
2260
|
-
for (const x of this.vaultSecuritization) {
|
|
2261
|
-
const entry = raisingFunds[x.vaultId] ?? {};
|
|
2262
|
-
const { table, width } = this.createBondCapitalTable(
|
|
2263
|
-
x.activatedSecuritization,
|
|
2264
|
-
entry.contributors ?? []
|
|
2265
|
-
);
|
|
2266
|
-
if (width > maxWidth) {
|
|
2267
|
-
maxWidth = width;
|
|
2268
|
-
}
|
|
2269
|
-
nextCapital.push({
|
|
2270
|
-
Vault: x.vaultId,
|
|
2271
|
-
Owner: this.getOperatorName(x.vaultId),
|
|
2272
|
-
"Bitcoin Space": formatArgons(x.bitcoinSpace),
|
|
2273
|
-
"Activated Securitization": `${formatArgons(x.activatedSecuritization)} / slot`,
|
|
2274
|
-
"Liquidity Pool": `${formatPercent(x.vaultSharingPercent)} profit sharing${table}`
|
|
2275
|
-
});
|
|
2276
|
-
}
|
|
2277
|
-
if (nextCapital.length) {
|
|
2278
|
-
console.log(`
|
|
2279
|
-
|
|
2280
|
-
Raising Funds (Frame ${this.nextFrameId + 1}):`);
|
|
2281
|
-
new Table({
|
|
2282
|
-
columns: [
|
|
2283
|
-
{ name: "Vault", alignment: "left" },
|
|
2284
|
-
{ name: "Owner", alignment: "left" },
|
|
2285
|
-
{ name: "Bitcoin Space", alignment: "right" },
|
|
2286
|
-
{ name: "Activated Securitization", alignment: "right" },
|
|
2287
|
-
{ name: "Liquidity Pool", alignment: "left", minLen: maxWidth }
|
|
2288
|
-
],
|
|
2289
|
-
rows: nextCapital
|
|
2290
|
-
}).printTable();
|
|
2291
|
-
}
|
|
2292
|
-
}
|
|
2293
|
-
setVaultFrameData(frameId, vaultId, data) {
|
|
2294
|
-
var _a, _b;
|
|
2295
|
-
this.poolVaultCapitalByFrame ?? (this.poolVaultCapitalByFrame = {});
|
|
2296
|
-
(_a = this.poolVaultCapitalByFrame)[frameId] ?? (_a[frameId] = {});
|
|
2297
|
-
(_b = this.poolVaultCapitalByFrame[frameId])[vaultId] ?? (_b[vaultId] = {
|
|
2298
|
-
activatedCapital: data.activatedCapital ?? data.contributors?.reduce((a, b) => a + b.amount, 0n) ?? 0n
|
|
2299
|
-
});
|
|
2300
|
-
Object.assign(this.poolVaultCapitalByFrame[frameId][vaultId], filterUndefined(data));
|
|
2301
|
-
}
|
|
2302
|
-
createBondCapitalTable(total, contributors, title = "Total") {
|
|
2303
|
-
const table = new Table({
|
|
2304
|
-
style: EMPTY_TABLE,
|
|
2305
|
-
columns: [
|
|
2306
|
-
{ name: "who", title, minLen: 10, alignment: "right" },
|
|
2307
|
-
{
|
|
2308
|
-
name: "amount",
|
|
2309
|
-
title: formatArgons(total),
|
|
2310
|
-
minLen: 7,
|
|
2311
|
-
alignment: "left"
|
|
2312
|
-
}
|
|
2313
|
-
]
|
|
2314
|
-
});
|
|
2315
|
-
for (const x of contributors) {
|
|
2316
|
-
table.addRow({
|
|
2317
|
-
who: this.accountRegistry.getName(x.address) ?? x.address,
|
|
2318
|
-
amount: formatArgons(x.amount)
|
|
2319
|
-
});
|
|
2320
|
-
}
|
|
2321
|
-
const str = table.render();
|
|
2322
|
-
const width = str.indexOf("\n");
|
|
2323
|
-
return { table: str, width };
|
|
2324
|
-
}
|
|
2325
|
-
loadFrameData(frameId, vaultFunds) {
|
|
2326
|
-
for (const [vaultId, fund] of vaultFunds) {
|
|
2327
|
-
const vaultIdNumber = vaultId.toNumber();
|
|
2328
|
-
const contributors = fund.contributorBalances.map(([a, b]) => ({
|
|
2329
|
-
address: a.toHuman(),
|
|
2330
|
-
amount: b.toBigInt()
|
|
2331
|
-
}));
|
|
2332
|
-
if (fund.distributedProfits.isSome) {
|
|
2333
|
-
if (frameId > (this.lastDistributedFrameId ?? 0)) {
|
|
2334
|
-
this.lastDistributedFrameId = frameId;
|
|
2335
|
-
}
|
|
2336
|
-
}
|
|
2337
|
-
this.setVaultFrameData(frameId, vaultIdNumber, {
|
|
2338
|
-
earnings: fund.distributedProfits.isSome ? fund.distributedProfits.unwrap().toBigInt() : void 0,
|
|
2339
|
-
vaultSharingPercent: convertPermillToBigNumber(fund.vaultSharingPercent.toBigInt()),
|
|
2340
|
-
contributors
|
|
2341
|
-
});
|
|
2342
|
-
}
|
|
2343
|
-
}
|
|
2344
|
-
};
|
|
537
|
+
function toFixedNumber(value, decimals) {
|
|
538
|
+
const factor = new BigNumber2__default(10).pow(decimals);
|
|
539
|
+
const bn = new BigNumber2__default(value);
|
|
540
|
+
const int = bn.times(factor).integerValue(BigNumber2__default.ROUND_DOWN);
|
|
541
|
+
return BigInt(int.toFixed(0));
|
|
542
|
+
}
|
|
543
|
+
function fromFixedNumber(value, decimals = FIXED_U128_DECIMALS) {
|
|
544
|
+
const factor = new BigNumber2__default(10).pow(decimals);
|
|
545
|
+
const bn = new BigNumber2__default(value.toString());
|
|
546
|
+
return bn.div(factor);
|
|
547
|
+
}
|
|
548
|
+
var FIXED_U128_DECIMALS = 18;
|
|
549
|
+
var PERMILL_DECIMALS = 6;
|
|
2345
550
|
var SATS_PER_BTC = 100000000n;
|
|
2346
|
-
var BitcoinLocks = class
|
|
551
|
+
var BitcoinLocks = class {
|
|
2347
552
|
constructor(client) {
|
|
2348
553
|
this.client = client;
|
|
2349
554
|
}
|
|
2350
555
|
async getUtxoIdFromEvents(events) {
|
|
2351
|
-
const client = await this.client;
|
|
2352
556
|
for (const event of events) {
|
|
2353
|
-
if (client.events.bitcoinLocks.BitcoinLockCreated.is(event)) {
|
|
557
|
+
if (this.client.events.bitcoinLocks.BitcoinLockCreated.is(event)) {
|
|
2354
558
|
return event.data.utxoId.toNumber();
|
|
2355
559
|
}
|
|
2356
560
|
}
|
|
2357
561
|
return void 0;
|
|
2358
562
|
}
|
|
2359
563
|
async getMarketRate(satoshis) {
|
|
2360
|
-
const client =
|
|
564
|
+
const client = this.client;
|
|
2361
565
|
const sats = client.createType("U64", satoshis.toString());
|
|
2362
566
|
const marketRate = await client.rpc.state.call("BitcoinApis_market_rate", sats.toHex(true));
|
|
2363
567
|
const rate = client.createType("Option<U128>", marketRate);
|
|
@@ -2367,7 +571,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2367
571
|
return rate.value.toBigInt();
|
|
2368
572
|
}
|
|
2369
573
|
async getRedemptionRate(satoshis) {
|
|
2370
|
-
const client =
|
|
574
|
+
const client = this.client;
|
|
2371
575
|
const sats = client.createType("U64", satoshis.toString());
|
|
2372
576
|
const marketRate = await client.rpc.state.call("BitcoinApis_redemption_rate", sats.toHex(true));
|
|
2373
577
|
const rate = client.createType("Option<U128>", marketRate);
|
|
@@ -2377,7 +581,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2377
581
|
return rate.value.toBigInt();
|
|
2378
582
|
}
|
|
2379
583
|
async getConfig() {
|
|
2380
|
-
const client =
|
|
584
|
+
const client = this.client;
|
|
2381
585
|
const bitcoinNetwork = await client.query.bitcoinUtxos.bitcoinNetwork();
|
|
2382
586
|
return {
|
|
2383
587
|
lockReleaseCosignDeadlineFrames: client.consts.bitcoinLocks.lockReleaseCosignDeadlineFrames.toNumber(),
|
|
@@ -2387,24 +591,19 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2387
591
|
};
|
|
2388
592
|
}
|
|
2389
593
|
async getBitcoinConfirmedBlockHeight() {
|
|
2390
|
-
|
|
2391
|
-
return await client.query.bitcoinUtxos.confirmedBitcoinBlockTip().then((x) => x.value?.blockHeight.toNumber() ?? 0);
|
|
594
|
+
return await this.client.query.bitcoinUtxos.confirmedBitcoinBlockTip().then((x) => x.value?.blockHeight.toNumber() ?? 0);
|
|
2392
595
|
}
|
|
2393
596
|
/**
|
|
2394
597
|
* Gets the UTXO reference by ID.
|
|
2395
598
|
* @param utxoId - The UTXO ID to look up.
|
|
2396
|
-
* @param
|
|
599
|
+
* @param clientAtHeight - Optional client at the block height to query the UTXO reference at a specific point in time.
|
|
2397
600
|
* @return An object containing the transaction ID and output index, or undefined if not found.
|
|
2398
601
|
* @return.txid - The Bitcoin transaction ID of the UTXO.
|
|
2399
602
|
* @return.vout - The output index of the UTXO in the transaction.
|
|
2400
603
|
* @return.bitcoinTxid - The Bitcoin transaction ID of the UTXO formatted in little endian
|
|
2401
604
|
*/
|
|
2402
|
-
async getUtxoRef(utxoId,
|
|
2403
|
-
|
|
2404
|
-
if (atHeight !== void 0) {
|
|
2405
|
-
const blockHash = await client.rpc.chain.getBlockHash(atHeight);
|
|
2406
|
-
client = await client.at(blockHash);
|
|
2407
|
-
}
|
|
605
|
+
async getUtxoRef(utxoId, clientAtHeight) {
|
|
606
|
+
const client = clientAtHeight ?? this.client;
|
|
2408
607
|
const refRaw = await client.query.bitcoinUtxos.utxoIdToRef(utxoId);
|
|
2409
608
|
if (!refRaw) {
|
|
2410
609
|
return;
|
|
@@ -2415,12 +614,8 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2415
614
|
const vout = ref.outputIndex.toNumber();
|
|
2416
615
|
return { txid, vout, bitcoinTxid };
|
|
2417
616
|
}
|
|
2418
|
-
async getReleaseRequest(utxoId,
|
|
2419
|
-
|
|
2420
|
-
if (atHeight !== void 0) {
|
|
2421
|
-
const blockHash = await client.rpc.chain.getBlockHash(atHeight);
|
|
2422
|
-
client = await client.at(blockHash);
|
|
2423
|
-
}
|
|
617
|
+
async getReleaseRequest(utxoId, clientAtHeight) {
|
|
618
|
+
const client = clientAtHeight ?? this.client;
|
|
2424
619
|
const requestMaybe = await client.query.bitcoinLocks.lockReleaseRequestsByUtxoId(utxoId);
|
|
2425
620
|
if (!requestMaybe.isSome) {
|
|
2426
621
|
return void 0;
|
|
@@ -2436,7 +631,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2436
631
|
}
|
|
2437
632
|
async submitVaultSignature(args) {
|
|
2438
633
|
const { utxoId, vaultSignature, argonKeyring, txProgressCallback } = args;
|
|
2439
|
-
const client =
|
|
634
|
+
const client = this.client;
|
|
2440
635
|
if (!vaultSignature || vaultSignature.byteLength < 70 || vaultSignature.byteLength > 73) {
|
|
2441
636
|
throw new Error(
|
|
2442
637
|
`Invalid vault signature length: ${vaultSignature.byteLength}. Must be 70-73 bytes.`
|
|
@@ -2448,8 +643,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2448
643
|
return await submitter.submit({ txProgressCallback });
|
|
2449
644
|
}
|
|
2450
645
|
async getBitcoinLock(utxoId) {
|
|
2451
|
-
const
|
|
2452
|
-
const utxoRaw = await client.query.bitcoinLocks.locksByUtxoId(utxoId);
|
|
646
|
+
const utxoRaw = await this.client.query.bitcoinLocks.locksByUtxoId(utxoId);
|
|
2453
647
|
if (!utxoRaw.isSome) {
|
|
2454
648
|
return;
|
|
2455
649
|
}
|
|
@@ -2458,7 +652,8 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2458
652
|
const wscriptHash = utxo.utxoScriptPubkey.asP2wsh.wscriptHash.toHex().replace("0x", "");
|
|
2459
653
|
const p2wshScriptHashHex = `0x${p2shBytesPrefix}${wscriptHash}`;
|
|
2460
654
|
const vaultId = utxo.vaultId.toNumber();
|
|
2461
|
-
const
|
|
655
|
+
const peggedPrice = utxo.peggedPrice.toBigInt();
|
|
656
|
+
const liquidityPromised = utxo.liquidityPromised.toBigInt();
|
|
2462
657
|
const ownerAccount = utxo.ownerAccount.toHuman();
|
|
2463
658
|
const satoshis = utxo.satoshis.toBigInt();
|
|
2464
659
|
const vaultPubkey = utxo.vaultPubkey.toHex();
|
|
@@ -2482,7 +677,8 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2482
677
|
utxoId,
|
|
2483
678
|
p2wshScriptHashHex,
|
|
2484
679
|
vaultId,
|
|
2485
|
-
|
|
680
|
+
peggedPrice,
|
|
681
|
+
liquidityPromised,
|
|
2486
682
|
ownerAccount,
|
|
2487
683
|
satoshis,
|
|
2488
684
|
vaultPubkey,
|
|
@@ -2503,7 +699,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2503
699
|
* @param waitForSignatureMillis - Optional timeout in milliseconds to wait for the signature. If -1, waits indefinitely.
|
|
2504
700
|
*/
|
|
2505
701
|
async findVaultCosignSignature(utxoId, waitForSignatureMillis) {
|
|
2506
|
-
const client =
|
|
702
|
+
const client = this.client;
|
|
2507
703
|
const releaseHeight = await client.query.bitcoinLocks.lockReleaseCosignHeightById(utxoId);
|
|
2508
704
|
if (releaseHeight.isSome) {
|
|
2509
705
|
const releaseHeightValue = releaseHeight.unwrap().toNumber();
|
|
@@ -2538,7 +734,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2538
734
|
});
|
|
2539
735
|
}
|
|
2540
736
|
async blockHashAtHeight(atHeight) {
|
|
2541
|
-
const client =
|
|
737
|
+
const client = this.client;
|
|
2542
738
|
for (let i = 0; i < 10; i++) {
|
|
2543
739
|
const currentHeight = await client.query.system.number().then((x) => x.toNumber());
|
|
2544
740
|
if (atHeight > currentHeight) {
|
|
@@ -2559,7 +755,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2559
755
|
return void 0;
|
|
2560
756
|
}
|
|
2561
757
|
async getVaultCosignSignature(utxoId, atHeight) {
|
|
2562
|
-
const client =
|
|
758
|
+
const client = this.client;
|
|
2563
759
|
const blockHash = await this.blockHashAtHeight(atHeight);
|
|
2564
760
|
if (!blockHash) {
|
|
2565
761
|
console.warn(`Block hash not found for height ${atHeight}`);
|
|
@@ -2577,8 +773,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2577
773
|
return void 0;
|
|
2578
774
|
}
|
|
2579
775
|
async findPendingMints(utxoId) {
|
|
2580
|
-
const
|
|
2581
|
-
const pendingMint = await client.query.mint.pendingMintUtxos();
|
|
776
|
+
const pendingMint = await this.client.query.mint.pendingMintUtxos();
|
|
2582
777
|
const mintsPending = [];
|
|
2583
778
|
for (const [utxoIdRaw, _accountId, mintAmountRaw] of pendingMint) {
|
|
2584
779
|
if (utxoIdRaw.toNumber() === utxoId) {
|
|
@@ -2589,7 +784,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2589
784
|
}
|
|
2590
785
|
async createInitializeLockTx(args) {
|
|
2591
786
|
const { vault, argonKeyring, satoshis, tip = 0n, ownerBitcoinPubkey } = args;
|
|
2592
|
-
const client =
|
|
787
|
+
const client = this.client;
|
|
2593
788
|
if (ownerBitcoinPubkey.length !== 33) {
|
|
2594
789
|
throw new Error(
|
|
2595
790
|
`Invalid Bitcoin key length: ${ownerBitcoinPubkey.length}. Must be a compressed pukey (33 bytes).`
|
|
@@ -2617,7 +812,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2617
812
|
return { tx, securityFee, txFee };
|
|
2618
813
|
}
|
|
2619
814
|
async getBitcoinLockFromTxResult(txResult) {
|
|
2620
|
-
const client =
|
|
815
|
+
const client = this.client;
|
|
2621
816
|
const blockHash = await txResult.inBlockPromise;
|
|
2622
817
|
const blockHeight = await client.at(blockHash).then((x) => x.query.system.number()).then((x) => x.toNumber());
|
|
2623
818
|
const utxoId = await this.getUtxoIdFromEvents(txResult.events) ?? 0;
|
|
@@ -2632,7 +827,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2632
827
|
}
|
|
2633
828
|
async initializeLock(args) {
|
|
2634
829
|
const { argonKeyring, tip = 0n, txProgressCallback } = args;
|
|
2635
|
-
const client =
|
|
830
|
+
const client = this.client;
|
|
2636
831
|
const { tx, securityFee } = await this.createInitializeLockTx(args);
|
|
2637
832
|
const submitter = new TxSubmitter(client, tx, argonKeyring);
|
|
2638
833
|
const txResult = await submitter.submit({
|
|
@@ -2654,7 +849,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2654
849
|
return argonAmount * SATS_PER_BTC / marketRatePerBitcoin;
|
|
2655
850
|
}
|
|
2656
851
|
async requestRelease(args) {
|
|
2657
|
-
const client =
|
|
852
|
+
const client = this.client;
|
|
2658
853
|
const {
|
|
2659
854
|
lock,
|
|
2660
855
|
releaseRequest: { bitcoinNetworkFee, toScriptPubkey },
|
|
@@ -2671,8 +866,8 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2671
866
|
argonKeyring
|
|
2672
867
|
);
|
|
2673
868
|
let redemptionPrice = await this.getRedemptionRate(lock.satoshis);
|
|
2674
|
-
if (redemptionPrice > lock.
|
|
2675
|
-
redemptionPrice = lock.
|
|
869
|
+
if (redemptionPrice > lock.peggedPrice) {
|
|
870
|
+
redemptionPrice = lock.peggedPrice;
|
|
2676
871
|
}
|
|
2677
872
|
const canAfford = await submitter.canAfford({
|
|
2678
873
|
tip,
|
|
@@ -2696,21 +891,20 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2696
891
|
blockHeight
|
|
2697
892
|
};
|
|
2698
893
|
}
|
|
2699
|
-
async releasePrice(satoshis,
|
|
2700
|
-
await this.client;
|
|
894
|
+
async releasePrice(satoshis, peggedPrice) {
|
|
2701
895
|
const redemptionRate = await this.getRedemptionRate(satoshis);
|
|
2702
|
-
if (redemptionRate >
|
|
896
|
+
if (redemptionRate > peggedPrice) {
|
|
2703
897
|
return redemptionRate;
|
|
2704
898
|
}
|
|
2705
|
-
return
|
|
899
|
+
return peggedPrice;
|
|
2706
900
|
}
|
|
2707
901
|
async getRatchetPrice(lock, vault) {
|
|
2708
|
-
const { createdAtHeight, vaultClaimHeight,
|
|
2709
|
-
const client =
|
|
902
|
+
const { createdAtHeight, vaultClaimHeight, peggedPrice, satoshis } = lock;
|
|
903
|
+
const client = this.client;
|
|
2710
904
|
const marketRate = await this.getMarketRate(BigInt(satoshis));
|
|
2711
905
|
let ratchetingFee = vault.terms.bitcoinBaseFee;
|
|
2712
906
|
let burnAmount = 0n;
|
|
2713
|
-
if (marketRate >
|
|
907
|
+
if (marketRate > peggedPrice) {
|
|
2714
908
|
const lockFee = vault.calculateBitcoinFee(marketRate);
|
|
2715
909
|
const currentBitcoinHeight = await client.query.bitcoinUtxos.confirmedBitcoinBlockTip().then((x) => x.unwrap().blockHeight.toNumber());
|
|
2716
910
|
const blockLength = vaultClaimHeight - createdAtHeight;
|
|
@@ -2718,7 +912,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2718
912
|
const remainingDuration = 1 - elapsed;
|
|
2719
913
|
ratchetingFee = BigInt(remainingDuration * Number(lockFee));
|
|
2720
914
|
} else {
|
|
2721
|
-
burnAmount = await this.releasePrice(lock.satoshis,
|
|
915
|
+
burnAmount = await this.releasePrice(lock.satoshis, peggedPrice);
|
|
2722
916
|
}
|
|
2723
917
|
return {
|
|
2724
918
|
ratchetingFee,
|
|
@@ -2728,7 +922,7 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2728
922
|
}
|
|
2729
923
|
async ratchet(args) {
|
|
2730
924
|
const { lock, argonKeyring, tip = 0n, vault, txProgressCallback } = args;
|
|
2731
|
-
const client =
|
|
925
|
+
const client = this.client;
|
|
2732
926
|
const ratchetPrice = await this.getRatchetPrice(lock, vault);
|
|
2733
927
|
const txSubmitter = new TxSubmitter(
|
|
2734
928
|
client,
|
|
@@ -2761,94 +955,35 @@ var BitcoinLocks = class _BitcoinLocks {
|
|
|
2761
955
|
const api = await client.at(blockHash);
|
|
2762
956
|
const blockHeight = await api.query.system.number().then((x) => x.toNumber());
|
|
2763
957
|
const bitcoinBlockHeight = await api.query.bitcoinUtxos.confirmedBitcoinBlockTip().then((x) => x.unwrap().blockHeight.toNumber());
|
|
2764
|
-
const { amountBurned,
|
|
2765
|
-
let mintAmount =
|
|
2766
|
-
if (
|
|
2767
|
-
mintAmount -=
|
|
958
|
+
const { amountBurned, newPeggedPrice, originalPeggedPrice } = ratchetEvent.data;
|
|
959
|
+
let mintAmount = newPeggedPrice.toBigInt();
|
|
960
|
+
if (newPeggedPrice > originalPeggedPrice) {
|
|
961
|
+
mintAmount -= originalPeggedPrice.toBigInt();
|
|
2768
962
|
}
|
|
2769
963
|
return {
|
|
2770
964
|
txFee: submission.finalFee ?? 0n,
|
|
2771
965
|
securityFee: ratchetPrice.ratchetingFee,
|
|
2772
966
|
pendingMint: mintAmount,
|
|
2773
|
-
|
|
967
|
+
newPeggedPrice: newPeggedPrice.toBigInt(),
|
|
2774
968
|
burned: amountBurned.toBigInt(),
|
|
2775
969
|
blockHeight,
|
|
2776
970
|
bitcoinBlockHeight
|
|
2777
971
|
};
|
|
2778
972
|
}
|
|
2779
|
-
static async waitForSpace(accountset, options) {
|
|
2780
|
-
const { argonAmount, bitcoinXpub, maxLockFee, tip = 0n } = options;
|
|
2781
|
-
const vaults = new VaultMonitor(accountset, {
|
|
2782
|
-
bitcoinSpaceAvailable: argonAmount
|
|
2783
|
-
});
|
|
2784
|
-
const bitcoinXpubBuffer = hexToU8a(bitcoinXpub);
|
|
2785
|
-
return new Promise(async (resolve, reject) => {
|
|
2786
|
-
vaults.events.on("bitcoin-space-above", async (vaultId, amount) => {
|
|
2787
|
-
const vault = vaults.vaultsById[vaultId];
|
|
2788
|
-
const fee = vault.calculateBitcoinFee(amount);
|
|
2789
|
-
console.log(
|
|
2790
|
-
`Vault ${vaultId} has ${formatArgons(amount)} argons available for bitcoin. Lock fee is ${formatArgons(fee)}`
|
|
2791
|
-
);
|
|
2792
|
-
if (maxLockFee !== void 0 && fee > maxLockFee) {
|
|
2793
|
-
console.log(
|
|
2794
|
-
`Skipping vault ${vaultId} due to high lock fee: ${formatArgons(maxLockFee)}`
|
|
2795
|
-
);
|
|
2796
|
-
return;
|
|
2797
|
-
}
|
|
2798
|
-
try {
|
|
2799
|
-
const bitcoinLock = new _BitcoinLocks(accountset.client);
|
|
2800
|
-
let satoshis = await bitcoinLock.requiredSatoshisForArgonLiquidity(amount);
|
|
2801
|
-
satoshis -= options.satoshiWiggleRoomForDynamicPrice ?? 500n;
|
|
2802
|
-
const { txResult, lock, securityFee } = await bitcoinLock.initializeLock({
|
|
2803
|
-
vault,
|
|
2804
|
-
satoshis,
|
|
2805
|
-
argonKeyring: accountset.txSubmitterPair,
|
|
2806
|
-
ownerBitcoinPubkey: bitcoinXpubBuffer,
|
|
2807
|
-
tip
|
|
2808
|
-
});
|
|
2809
|
-
resolve({
|
|
2810
|
-
satoshis,
|
|
2811
|
-
argons: argonAmount,
|
|
2812
|
-
vaultId,
|
|
2813
|
-
securityFee,
|
|
2814
|
-
txFee: txResult.finalFee,
|
|
2815
|
-
finalizedPromise: txResult.finalizedPromise,
|
|
2816
|
-
utxoId: lock.utxoId
|
|
2817
|
-
});
|
|
2818
|
-
} catch (err) {
|
|
2819
|
-
console.error("Error submitting bitcoin lock tx:", err);
|
|
2820
|
-
reject(err);
|
|
2821
|
-
} finally {
|
|
2822
|
-
vaults.stop();
|
|
2823
|
-
}
|
|
2824
|
-
});
|
|
2825
|
-
await vaults.monitor();
|
|
2826
|
-
});
|
|
2827
|
-
}
|
|
2828
973
|
};
|
|
2829
|
-
|
|
2830
|
-
// src/keyringUtils.ts
|
|
2831
|
-
function keyringFromSuri(suri, cryptoType = "sr25519") {
|
|
2832
|
-
return new Keyring({ type: cryptoType }).createFromUri(suri);
|
|
2833
|
-
}
|
|
2834
|
-
function createKeyringPair(opts) {
|
|
2835
|
-
const { cryptoType } = opts;
|
|
2836
|
-
const seed = mnemonicGenerate();
|
|
2837
|
-
return keyringFromSuri(seed, cryptoType);
|
|
2838
|
-
}
|
|
2839
974
|
async function waitForLoad() {
|
|
2840
975
|
await cryptoWaitReady();
|
|
2841
976
|
}
|
|
2842
|
-
async function getClient(host) {
|
|
977
|
+
async function getClient(host, options) {
|
|
2843
978
|
let provider;
|
|
2844
979
|
if (host.startsWith("http")) {
|
|
2845
980
|
provider = new HttpProvider(host);
|
|
2846
981
|
} else {
|
|
2847
982
|
provider = new WsProvider(host);
|
|
2848
983
|
}
|
|
2849
|
-
return await ApiPromise.create({ provider, noInitWarn: true });
|
|
984
|
+
return await ApiPromise.create({ provider, noInitWarn: true, ...options ?? {} });
|
|
2850
985
|
}
|
|
2851
986
|
|
|
2852
|
-
export {
|
|
987
|
+
export { BitcoinLocks, ExtrinsicError2 as ExtrinsicError, FIXED_U128_DECIMALS, MICROGONS_PER_ARGON, PERMILL_DECIMALS, SATS_PER_BTC, TxResult, TxSubmitter, Vault, WageProtector, checkForExtrinsicSuccess, createKeyringPair, dispatchErrorToExtrinsicError, dispatchErrorToString, formatArgons, fromFixedNumber, getAuthorFromHeader, getClient, getTickFromHeader, gettersToObject, keyringFromSuri, toFixedNumber, waitForLoad };
|
|
2853
988
|
//# sourceMappingURL=index.js.map
|
|
2854
989
|
//# sourceMappingURL=index.js.map
|