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