@argonprotocol/mainchain 1.3.11 → 1.3.13
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/browser/index.d.ts +119 -87
- package/browser/index.js +327 -246
- package/browser/index.js.map +1 -1
- package/lib/index.cjs +320 -249
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.cts +119 -87
- package/lib/index.d.ts +119 -87
- package/lib/index.js +319 -248
- package/lib/index.js.map +1 -1
- package/package.json +2 -2
package/lib/index.js
CHANGED
|
@@ -81,158 +81,6 @@ var WageProtector = class _WageProtector {
|
|
|
81
81
|
}
|
|
82
82
|
};
|
|
83
83
|
|
|
84
|
-
// src/TxSubmitter.ts
|
|
85
|
-
function logExtrinsicResult(result) {
|
|
86
|
-
const json = result.status.toJSON();
|
|
87
|
-
const status = Object.keys(json)[0];
|
|
88
|
-
console.debug('Transaction update: "%s"', status, json[status]);
|
|
89
|
-
}
|
|
90
|
-
var TxSubmitter = class {
|
|
91
|
-
constructor(client, tx, pair) {
|
|
92
|
-
this.client = client;
|
|
93
|
-
this.tx = tx;
|
|
94
|
-
this.pair = pair;
|
|
95
|
-
}
|
|
96
|
-
async feeEstimate(tip) {
|
|
97
|
-
const { partialFee } = await this.tx.paymentInfo(this.pair, { tip });
|
|
98
|
-
return partialFee.toBigInt();
|
|
99
|
-
}
|
|
100
|
-
async canAfford(options = {}) {
|
|
101
|
-
const { tip, unavailableBalance } = options;
|
|
102
|
-
const account = await this.client.query.system.account(this.pair.address);
|
|
103
|
-
let availableBalance = account.data.free.toBigInt();
|
|
104
|
-
const userBalance = availableBalance;
|
|
105
|
-
if (unavailableBalance) {
|
|
106
|
-
availableBalance -= unavailableBalance;
|
|
107
|
-
}
|
|
108
|
-
const existentialDeposit = options.includeExistentialDeposit ? this.client.consts.balances.existentialDeposit.toBigInt() : 0n;
|
|
109
|
-
const fees = await this.feeEstimate(tip);
|
|
110
|
-
const totalCharge = fees + (tip ?? 0n);
|
|
111
|
-
const canAfford = availableBalance >= totalCharge + existentialDeposit;
|
|
112
|
-
return { canAfford, availableBalance: userBalance, txFee: fees };
|
|
113
|
-
}
|
|
114
|
-
async submit(options = {}) {
|
|
115
|
-
const { logResults, waitForBlock, useLatestNonce, ...apiOptions } = options;
|
|
116
|
-
await waitForLoad();
|
|
117
|
-
const result = new TxResult(this.client, logResults);
|
|
118
|
-
result.txProgressCallback = options.txProgressCallback;
|
|
119
|
-
let toHuman = this.tx.toHuman().method;
|
|
120
|
-
const txString = [];
|
|
121
|
-
let api = formatCall(toHuman);
|
|
122
|
-
const args = [];
|
|
123
|
-
if (api === "proxy.proxy") {
|
|
124
|
-
toHuman = toHuman.args.call;
|
|
125
|
-
txString.push("Proxy");
|
|
126
|
-
api = formatCall(toHuman);
|
|
127
|
-
}
|
|
128
|
-
if (api.startsWith("utility.batch")) {
|
|
129
|
-
const calls = toHuman.args.calls.map(formatCall).join(", ");
|
|
130
|
-
txString.push(`Batch[${calls}]`);
|
|
131
|
-
} else {
|
|
132
|
-
txString.push(api);
|
|
133
|
-
args.push(toHuman.args);
|
|
134
|
-
}
|
|
135
|
-
args.unshift(txString.join("->"));
|
|
136
|
-
if (useLatestNonce && !apiOptions.nonce) {
|
|
137
|
-
apiOptions.nonce = await this.client.rpc.system.accountNextIndex(this.pair.address);
|
|
138
|
-
}
|
|
139
|
-
console.log("Submitting transaction from %s:", this.pair.address, ...args);
|
|
140
|
-
await this.tx.signAndSend(this.pair, apiOptions, result.onResult.bind(result));
|
|
141
|
-
if (waitForBlock) {
|
|
142
|
-
await result.inBlockPromise;
|
|
143
|
-
}
|
|
144
|
-
return result;
|
|
145
|
-
}
|
|
146
|
-
};
|
|
147
|
-
function formatCall(call) {
|
|
148
|
-
return `${call.section}.${call.method}`;
|
|
149
|
-
}
|
|
150
|
-
var TxResult = class {
|
|
151
|
-
constructor(client, shouldLog = false) {
|
|
152
|
-
this.client = client;
|
|
153
|
-
this.shouldLog = shouldLog;
|
|
154
|
-
this.inBlockPromise = new Promise((resolve, reject) => {
|
|
155
|
-
this.inBlockResolve = resolve;
|
|
156
|
-
this.inBlockReject = reject;
|
|
157
|
-
});
|
|
158
|
-
this.finalizedPromise = new Promise((resolve, reject) => {
|
|
159
|
-
this.finalizedResolve = resolve;
|
|
160
|
-
this.finalizedReject = reject;
|
|
161
|
-
});
|
|
162
|
-
this.inBlockPromise.catch(() => null);
|
|
163
|
-
this.finalizedPromise.catch(() => null);
|
|
164
|
-
}
|
|
165
|
-
inBlockPromise;
|
|
166
|
-
finalizedPromise;
|
|
167
|
-
status;
|
|
168
|
-
events = [];
|
|
169
|
-
/**
|
|
170
|
-
* The index of the batch that was interrupted, if any.
|
|
171
|
-
*/
|
|
172
|
-
batchInterruptedIndex;
|
|
173
|
-
includedInBlock;
|
|
174
|
-
/**
|
|
175
|
-
* The final fee paid for the transaction, including the fee tip.
|
|
176
|
-
*/
|
|
177
|
-
finalFee;
|
|
178
|
-
/**
|
|
179
|
-
* The fee tip paid for the transaction.
|
|
180
|
-
*/
|
|
181
|
-
finalFeeTip;
|
|
182
|
-
txProgressCallback;
|
|
183
|
-
inBlockResolve;
|
|
184
|
-
inBlockReject;
|
|
185
|
-
finalizedResolve;
|
|
186
|
-
finalizedReject;
|
|
187
|
-
onResult(result) {
|
|
188
|
-
this.status = result.status;
|
|
189
|
-
if (this.shouldLog) {
|
|
190
|
-
logExtrinsicResult(result);
|
|
191
|
-
}
|
|
192
|
-
const { events, status, dispatchError, isFinalized } = result;
|
|
193
|
-
if (status.isInBlock) {
|
|
194
|
-
this.includedInBlock = new Uint8Array(status.asInBlock);
|
|
195
|
-
let encounteredError = dispatchError;
|
|
196
|
-
let batchErrorIndex;
|
|
197
|
-
for (const event of events) {
|
|
198
|
-
this.events.push(event.event);
|
|
199
|
-
if (this.client.events.utility.BatchInterrupted.is(event.event)) {
|
|
200
|
-
batchErrorIndex = event.event.data[0].toNumber();
|
|
201
|
-
this.batchInterruptedIndex = batchErrorIndex;
|
|
202
|
-
encounteredError = event.event.data[1];
|
|
203
|
-
}
|
|
204
|
-
if (this.client.events.transactionPayment.TransactionFeePaid.is(event.event)) {
|
|
205
|
-
const [_who, actualFee, tip] = event.event.data;
|
|
206
|
-
this.finalFee = actualFee.toBigInt();
|
|
207
|
-
this.finalFeeTip = tip.toBigInt();
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
if (encounteredError) {
|
|
211
|
-
const error = dispatchErrorToExtrinsicError(this.client, encounteredError, batchErrorIndex);
|
|
212
|
-
this.reject(error);
|
|
213
|
-
} else {
|
|
214
|
-
this.inBlockResolve(new Uint8Array(status.asInBlock));
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
if (isFinalized) {
|
|
218
|
-
this.finalizedResolve(status.asFinalized);
|
|
219
|
-
}
|
|
220
|
-
if (this.txProgressCallback) {
|
|
221
|
-
let percent = 0;
|
|
222
|
-
if (result.status.isBroadcast) {
|
|
223
|
-
percent = 50;
|
|
224
|
-
} else if (result.status.isInBlock) {
|
|
225
|
-
percent = 100;
|
|
226
|
-
}
|
|
227
|
-
this.txProgressCallback(percent, this);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
reject(error) {
|
|
231
|
-
this.inBlockReject(error);
|
|
232
|
-
this.finalizedReject(error);
|
|
233
|
-
}
|
|
234
|
-
};
|
|
235
|
-
|
|
236
84
|
// src/utils.ts
|
|
237
85
|
import BigNumber, * as BN from "bignumber.js";
|
|
238
86
|
var { ROUND_FLOOR } = BN;
|
|
@@ -280,12 +128,13 @@ function dispatchErrorToString(client, error) {
|
|
|
280
128
|
}
|
|
281
129
|
return message;
|
|
282
130
|
}
|
|
283
|
-
var
|
|
284
|
-
constructor(errorCode, details, batchInterruptedIndex) {
|
|
131
|
+
var ExtrinsicError = class extends Error {
|
|
132
|
+
constructor(errorCode, details, batchInterruptedIndex, txFee = 0n) {
|
|
285
133
|
super(errorCode);
|
|
286
134
|
this.errorCode = errorCode;
|
|
287
135
|
this.details = details;
|
|
288
136
|
this.batchInterruptedIndex = batchInterruptedIndex;
|
|
137
|
+
this.txFee = txFee;
|
|
289
138
|
}
|
|
290
139
|
toString() {
|
|
291
140
|
if (this.batchInterruptedIndex !== void 0) {
|
|
@@ -294,13 +143,13 @@ var ExtrinsicError2 = class extends Error {
|
|
|
294
143
|
return `${this.errorCode} ${this.details ?? ""}`;
|
|
295
144
|
}
|
|
296
145
|
};
|
|
297
|
-
function dispatchErrorToExtrinsicError(client, error, batchInterruptedIndex) {
|
|
146
|
+
function dispatchErrorToExtrinsicError(client, error, batchInterruptedIndex, txFee) {
|
|
298
147
|
if (error.isModule) {
|
|
299
148
|
const decoded = client.registry.findMetaError(error.asModule);
|
|
300
149
|
const { docs, name, section } = decoded;
|
|
301
|
-
return new
|
|
150
|
+
return new ExtrinsicError(`${section}.${name}`, docs.join(" "), batchInterruptedIndex, txFee);
|
|
302
151
|
}
|
|
303
|
-
return new
|
|
152
|
+
return new ExtrinsicError(error.toString(), void 0, batchInterruptedIndex, txFee);
|
|
304
153
|
}
|
|
305
154
|
function checkForExtrinsicSuccess(events, client) {
|
|
306
155
|
return new Promise((resolve, reject) => {
|
|
@@ -320,6 +169,243 @@ function checkForExtrinsicSuccess(events, client) {
|
|
|
320
169
|
});
|
|
321
170
|
}
|
|
322
171
|
|
|
172
|
+
// src/TxResult.ts
|
|
173
|
+
var TxResult = class {
|
|
174
|
+
constructor(client, extrinsic) {
|
|
175
|
+
this.client = client;
|
|
176
|
+
this.extrinsic = extrinsic;
|
|
177
|
+
this.waitForFinalizedBlock = new Promise((resolve, reject) => {
|
|
178
|
+
this.finalizedResolve = resolve;
|
|
179
|
+
this.finalizedReject = reject;
|
|
180
|
+
});
|
|
181
|
+
this.waitForInFirstBlock = new Promise((resolve, reject) => {
|
|
182
|
+
this.inBlockResolve = resolve;
|
|
183
|
+
this.inBlockReject = reject;
|
|
184
|
+
});
|
|
185
|
+
this.waitForFinalizedBlock.catch(() => null);
|
|
186
|
+
this.waitForInFirstBlock.catch(() => null);
|
|
187
|
+
}
|
|
188
|
+
#isBroadcast = false;
|
|
189
|
+
#submissionError;
|
|
190
|
+
set isBroadcast(value) {
|
|
191
|
+
this.#isBroadcast = value;
|
|
192
|
+
this.updateProgress();
|
|
193
|
+
}
|
|
194
|
+
get isBroadcast() {
|
|
195
|
+
return this.#isBroadcast;
|
|
196
|
+
}
|
|
197
|
+
set submissionError(value) {
|
|
198
|
+
if (value) {
|
|
199
|
+
this.#submissionError = value;
|
|
200
|
+
this.finalizedReject(value);
|
|
201
|
+
this.inBlockReject(value);
|
|
202
|
+
this.updateProgress();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
get submissionError() {
|
|
206
|
+
return this.#submissionError;
|
|
207
|
+
}
|
|
208
|
+
waitForFinalizedBlock;
|
|
209
|
+
waitForInFirstBlock;
|
|
210
|
+
events = [];
|
|
211
|
+
extrinsicError;
|
|
212
|
+
extrinsicIndex;
|
|
213
|
+
txProgressCallback;
|
|
214
|
+
/**
|
|
215
|
+
* The index of the batch that was interrupted, if any.
|
|
216
|
+
*/
|
|
217
|
+
batchInterruptedIndex;
|
|
218
|
+
blockHash;
|
|
219
|
+
blockNumber;
|
|
220
|
+
/**
|
|
221
|
+
* The final fee paid for the transaction, including the fee tip.
|
|
222
|
+
*/
|
|
223
|
+
finalFee;
|
|
224
|
+
/**
|
|
225
|
+
* The fee tip paid for the transaction.
|
|
226
|
+
*/
|
|
227
|
+
finalFeeTip;
|
|
228
|
+
txProgress = 0;
|
|
229
|
+
isFinalized = false;
|
|
230
|
+
finalizedResolve;
|
|
231
|
+
finalizedReject;
|
|
232
|
+
inBlockResolve;
|
|
233
|
+
inBlockReject;
|
|
234
|
+
async setSeenInBlock(block) {
|
|
235
|
+
const { blockHash, blockNumber, events } = block;
|
|
236
|
+
if (blockHash !== this.blockHash) {
|
|
237
|
+
this.parseEvents(events);
|
|
238
|
+
this.blockHash = blockHash;
|
|
239
|
+
this.blockNumber = blockNumber ?? await this.client.rpc.chain.getHeader(blockHash).then((h) => h.number.toNumber());
|
|
240
|
+
this.extrinsicIndex = block.extrinsicIndex;
|
|
241
|
+
this.updateProgress();
|
|
242
|
+
if (this.extrinsicError) {
|
|
243
|
+
this.inBlockReject(this.extrinsicError);
|
|
244
|
+
} else {
|
|
245
|
+
this.inBlockResolve(blockHash);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
setFinalized() {
|
|
250
|
+
this.isFinalized = true;
|
|
251
|
+
this.updateProgress();
|
|
252
|
+
let error = this.extrinsicError ?? this.submissionError;
|
|
253
|
+
if (!error && !this.blockHash) {
|
|
254
|
+
error = new Error("Cannot finalize transaction before it is included in a block");
|
|
255
|
+
}
|
|
256
|
+
if (error) {
|
|
257
|
+
this.finalizedReject(error);
|
|
258
|
+
this.inBlockReject(error);
|
|
259
|
+
} else {
|
|
260
|
+
this.finalizedResolve(this.blockHash);
|
|
261
|
+
this.inBlockResolve(this.blockHash);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
onSubscriptionResult(result) {
|
|
265
|
+
const { events, status, isFinalized, txIndex } = result;
|
|
266
|
+
const extrinsicEvents = events.map((x) => x.event);
|
|
267
|
+
if (status.isBroadcast) {
|
|
268
|
+
this.isBroadcast = true;
|
|
269
|
+
if (result.internalError) this.submissionError = result.internalError;
|
|
270
|
+
}
|
|
271
|
+
if (status.isInBlock) {
|
|
272
|
+
void this.setSeenInBlock({
|
|
273
|
+
blockHash: Uint8Array.from(status.asInBlock),
|
|
274
|
+
events: extrinsicEvents,
|
|
275
|
+
extrinsicIndex: txIndex
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
if (isFinalized) {
|
|
279
|
+
this.setFinalized();
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
updateProgress() {
|
|
283
|
+
if (this.isFinalized || this.submissionError) {
|
|
284
|
+
this.txProgress = 100;
|
|
285
|
+
} else if (this.blockNumber) {
|
|
286
|
+
const elapsedBlocks = this.blockNumber - this.extrinsic.submittedAtBlockNumber;
|
|
287
|
+
const FINALIZATION_BLOCKS = 5;
|
|
288
|
+
const remainingPercent = Math.max(0, FINALIZATION_BLOCKS - elapsedBlocks) * 20;
|
|
289
|
+
const percent = 100 - remainingPercent;
|
|
290
|
+
this.txProgress = Math.min(percent, 99);
|
|
291
|
+
} else if (this.extrinsic.submittedAtBlockNumber) {
|
|
292
|
+
this.txProgress = 10;
|
|
293
|
+
}
|
|
294
|
+
this.txProgressCallback?.(this.txProgress);
|
|
295
|
+
}
|
|
296
|
+
parseEvents(events) {
|
|
297
|
+
let encounteredError;
|
|
298
|
+
for (const event of events) {
|
|
299
|
+
if (this.client.events.system.ExtrinsicFailed.is(event)) {
|
|
300
|
+
const { dispatchError } = event.data;
|
|
301
|
+
encounteredError ??= dispatchError;
|
|
302
|
+
}
|
|
303
|
+
if (this.client.events.utility.BatchInterrupted.is(event)) {
|
|
304
|
+
const { index, error } = event.data;
|
|
305
|
+
this.batchInterruptedIndex = index.toNumber();
|
|
306
|
+
encounteredError = error;
|
|
307
|
+
}
|
|
308
|
+
if (this.client.events.transactionPayment.TransactionFeePaid.is(event)) {
|
|
309
|
+
const { actualFee, tip } = event.data;
|
|
310
|
+
this.finalFee = actualFee.toBigInt();
|
|
311
|
+
this.finalFeeTip = tip.toBigInt();
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
if (encounteredError) {
|
|
315
|
+
this.extrinsicError = dispatchErrorToExtrinsicError(
|
|
316
|
+
this.client,
|
|
317
|
+
encounteredError,
|
|
318
|
+
this.batchInterruptedIndex,
|
|
319
|
+
this.finalFee
|
|
320
|
+
);
|
|
321
|
+
} else {
|
|
322
|
+
this.extrinsicError = void 0;
|
|
323
|
+
}
|
|
324
|
+
this.events = events;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
// src/TxSubmitter.ts
|
|
329
|
+
var TxSubmitter = class {
|
|
330
|
+
constructor(client, tx, pair) {
|
|
331
|
+
this.client = client;
|
|
332
|
+
this.tx = tx;
|
|
333
|
+
this.pair = pair;
|
|
334
|
+
}
|
|
335
|
+
async feeEstimate(tip) {
|
|
336
|
+
const { partialFee } = await this.tx.paymentInfo(this.pair, { tip });
|
|
337
|
+
return partialFee.toBigInt();
|
|
338
|
+
}
|
|
339
|
+
async canAfford(options = {}) {
|
|
340
|
+
const { tip, unavailableBalance } = options;
|
|
341
|
+
const account = await this.client.query.system.account(this.pair.address);
|
|
342
|
+
let availableBalance = account.data.free.toBigInt();
|
|
343
|
+
const userBalance = availableBalance;
|
|
344
|
+
if (unavailableBalance) {
|
|
345
|
+
availableBalance -= unavailableBalance;
|
|
346
|
+
}
|
|
347
|
+
const existentialDeposit = options.includeExistentialDeposit ? this.client.consts.balances.existentialDeposit.toBigInt() : 0n;
|
|
348
|
+
const fees = await this.feeEstimate(tip);
|
|
349
|
+
const totalCharge = fees + (tip ?? 0n);
|
|
350
|
+
const canAfford = availableBalance >= totalCharge + existentialDeposit;
|
|
351
|
+
return { canAfford, availableBalance: userBalance, txFee: fees };
|
|
352
|
+
}
|
|
353
|
+
async submit(options = {}) {
|
|
354
|
+
const { useLatestNonce, ...apiOptions } = options;
|
|
355
|
+
await waitForLoad();
|
|
356
|
+
const blockHeight = await this.client.rpc.chain.getHeader().then((h) => h.number.toNumber());
|
|
357
|
+
if (options.logResults) {
|
|
358
|
+
this.logRequest();
|
|
359
|
+
}
|
|
360
|
+
if (useLatestNonce && !apiOptions.nonce) {
|
|
361
|
+
apiOptions.nonce = await this.client.rpc.system.accountNextIndex(this.pair.address);
|
|
362
|
+
}
|
|
363
|
+
const signedTx = await this.tx.signAsync(this.pair, apiOptions);
|
|
364
|
+
const txHash = signedTx.hash.toHex();
|
|
365
|
+
const result = new TxResult(this.client, {
|
|
366
|
+
signedHash: txHash,
|
|
367
|
+
method: signedTx.method.toHuman(),
|
|
368
|
+
accountAddress: this.pair.address,
|
|
369
|
+
submittedTime: /* @__PURE__ */ new Date(),
|
|
370
|
+
submittedAtBlockNumber: blockHeight
|
|
371
|
+
});
|
|
372
|
+
if (options.disableAutomaticTxTracking !== true) {
|
|
373
|
+
await signedTx.send(result.onSubscriptionResult.bind(result));
|
|
374
|
+
} else {
|
|
375
|
+
try {
|
|
376
|
+
await signedTx.send();
|
|
377
|
+
result.isBroadcast = true;
|
|
378
|
+
} catch (error) {
|
|
379
|
+
result.submissionError = error;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return result;
|
|
383
|
+
}
|
|
384
|
+
logRequest() {
|
|
385
|
+
let toHuman = this.tx.toHuman().method;
|
|
386
|
+
const txString = [];
|
|
387
|
+
let api = formatCall(toHuman);
|
|
388
|
+
const args = [];
|
|
389
|
+
if (api === "proxy.proxy") {
|
|
390
|
+
toHuman = toHuman.args.call;
|
|
391
|
+
txString.push("Proxy");
|
|
392
|
+
api = formatCall(toHuman);
|
|
393
|
+
}
|
|
394
|
+
if (api.startsWith("utility.batch")) {
|
|
395
|
+
const calls = toHuman.args.calls.map(formatCall).join(", ");
|
|
396
|
+
txString.push(`Batch[${calls}]`);
|
|
397
|
+
} else {
|
|
398
|
+
txString.push(api);
|
|
399
|
+
args.push(toHuman.args);
|
|
400
|
+
}
|
|
401
|
+
args.unshift(txString.join("->"));
|
|
402
|
+
console.log("Submitting transaction from %s:", this.pair.address, ...args);
|
|
403
|
+
}
|
|
404
|
+
};
|
|
405
|
+
function formatCall(call) {
|
|
406
|
+
return `${call.section}.${call.method}`;
|
|
407
|
+
}
|
|
408
|
+
|
|
323
409
|
// src/keyringUtils.ts
|
|
324
410
|
function keyringFromSuri(suri, cryptoType = "sr25519") {
|
|
325
411
|
return new Keyring({ type: cryptoType }).createFromUri(suri);
|
|
@@ -517,29 +603,29 @@ var Vault = class _Vault {
|
|
|
517
603
|
);
|
|
518
604
|
}
|
|
519
605
|
const result = await tx.submit({
|
|
520
|
-
|
|
521
|
-
useLatestNonce: true
|
|
522
|
-
waitForBlock: true,
|
|
523
|
-
txProgressCallback
|
|
606
|
+
...args,
|
|
607
|
+
useLatestNonce: true
|
|
524
608
|
});
|
|
525
|
-
await
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
609
|
+
const tickDuration = config.tickDurationMillis ?? await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber());
|
|
610
|
+
async function getVault() {
|
|
611
|
+
await result.waitForFinalizedBlock;
|
|
612
|
+
let vaultId;
|
|
613
|
+
for (const event of result.events) {
|
|
614
|
+
if (client.events.vaults.VaultCreated.is(event)) {
|
|
615
|
+
vaultId = event.data.vaultId.toNumber();
|
|
616
|
+
break;
|
|
617
|
+
}
|
|
531
618
|
}
|
|
619
|
+
if (vaultId === void 0) {
|
|
620
|
+
throw new Error("Vault creation failed, no VaultCreated event found");
|
|
621
|
+
}
|
|
622
|
+
const rawVault = await client.query.vaults.vaultsById(vaultId);
|
|
623
|
+
if (rawVault.isNone) {
|
|
624
|
+
throw new Error("Vault creation failed, vault not found");
|
|
625
|
+
}
|
|
626
|
+
return new _Vault(vaultId, rawVault.unwrap(), tickDuration);
|
|
532
627
|
}
|
|
533
|
-
|
|
534
|
-
throw new Error("Vault creation failed, no VaultCreated event found");
|
|
535
|
-
}
|
|
536
|
-
const rawVault = await client.query.vaults.vaultsById(vaultId);
|
|
537
|
-
if (rawVault.isNone) {
|
|
538
|
-
throw new Error("Vault creation failed, vault not found");
|
|
539
|
-
}
|
|
540
|
-
const tickDuration = config.tickDurationMillis ?? await client.query.ticks.genesisTicker().then((x) => x.tickDurationMillis.toNumber());
|
|
541
|
-
const vault = new _Vault(vaultId, rawVault.unwrap(), tickDuration);
|
|
542
|
-
return { vault, txResult: result };
|
|
628
|
+
return { getVault, txResult: result };
|
|
543
629
|
}
|
|
544
630
|
};
|
|
545
631
|
|
|
@@ -678,7 +764,7 @@ var BitcoinLocks = class {
|
|
|
678
764
|
const signature = u8aToHex(vaultSignature);
|
|
679
765
|
const tx = client.tx.bitcoinLocks.cosignRelease(utxoId, signature);
|
|
680
766
|
const submitter = new TxSubmitter(client, tx, argonKeyring);
|
|
681
|
-
return await submitter.submit(
|
|
767
|
+
return await submitter.submit(args);
|
|
682
768
|
}
|
|
683
769
|
async getBitcoinLock(utxoId) {
|
|
684
770
|
const utxoRaw = await this.client.query.bitcoinLocks.locksByUtxoId(utxoId);
|
|
@@ -844,17 +930,11 @@ var BitcoinLocks = class {
|
|
|
844
930
|
unavailableBalance: securityFee + (args.reducedBalanceBy ?? 0n),
|
|
845
931
|
includeExistentialDeposit: true
|
|
846
932
|
});
|
|
847
|
-
|
|
848
|
-
throw new Error(
|
|
849
|
-
`Insufficient funds to initialize lock. Available: ${formatArgons(availableBalance)}, Required: ${satoshis}`
|
|
850
|
-
);
|
|
851
|
-
}
|
|
852
|
-
return { tx, securityFee, txFee };
|
|
933
|
+
return { tx, securityFee, txFee, canAfford, availableBalance, txFeePlusTip: txFee + tip };
|
|
853
934
|
}
|
|
854
935
|
async getBitcoinLockFromTxResult(txResult) {
|
|
855
|
-
|
|
856
|
-
const
|
|
857
|
-
const blockHeight = await client.at(blockHash).then((x) => x.query.system.number()).then((x) => x.toNumber());
|
|
936
|
+
await txResult.waitForFinalizedBlock;
|
|
937
|
+
const blockHeight = txResult.blockNumber;
|
|
858
938
|
const utxoId = await this.getUtxoIdFromEvents(txResult.events) ?? 0;
|
|
859
939
|
if (utxoId === 0) {
|
|
860
940
|
throw new Error("Bitcoin lock creation failed, no UTXO ID found in transaction events");
|
|
@@ -866,20 +946,18 @@ var BitcoinLocks = class {
|
|
|
866
946
|
return { lock, createdAtHeight: blockHeight, txResult };
|
|
867
947
|
}
|
|
868
948
|
async initializeLock(args) {
|
|
869
|
-
const { argonKeyring
|
|
949
|
+
const { argonKeyring } = args;
|
|
870
950
|
const client = this.client;
|
|
871
|
-
const { tx, securityFee } = await this.createInitializeLockTx(args);
|
|
951
|
+
const { tx, securityFee, canAfford, txFeePlusTip } = await this.createInitializeLockTx(args);
|
|
952
|
+
if (!canAfford) {
|
|
953
|
+
throw new Error(
|
|
954
|
+
`Insufficient funds to initialize bitcoin lock. Required security fee: ${formatArgons(securityFee)}, Tx fee plus tip: ${formatArgons(txFeePlusTip)}`
|
|
955
|
+
);
|
|
956
|
+
}
|
|
872
957
|
const submitter = new TxSubmitter(client, tx, argonKeyring);
|
|
873
|
-
const txResult = await submitter.submit({
|
|
874
|
-
waitForBlock: true,
|
|
875
|
-
logResults: true,
|
|
876
|
-
tip,
|
|
877
|
-
txProgressCallback
|
|
878
|
-
});
|
|
879
|
-
const { lock, createdAtHeight } = await this.getBitcoinLockFromTxResult(txResult);
|
|
958
|
+
const txResult = await submitter.submit({ logResults: true, ...args });
|
|
880
959
|
return {
|
|
881
|
-
|
|
882
|
-
createdAtHeight,
|
|
960
|
+
getLock: () => this.getBitcoinLockFromTxResult(txResult),
|
|
883
961
|
txResult,
|
|
884
962
|
securityFee
|
|
885
963
|
};
|
|
@@ -895,8 +973,7 @@ var BitcoinLocks = class {
|
|
|
895
973
|
priceIndex,
|
|
896
974
|
releaseRequest: { bitcoinNetworkFee, toScriptPubkey },
|
|
897
975
|
argonKeyring,
|
|
898
|
-
tip
|
|
899
|
-
txProgressCallback
|
|
976
|
+
tip = 0n
|
|
900
977
|
} = args;
|
|
901
978
|
if (!toScriptPubkey.startsWith("0x")) {
|
|
902
979
|
throw new Error("toScriptPubkey must be a hex string starting with 0x");
|
|
@@ -913,21 +990,13 @@ var BitcoinLocks = class {
|
|
|
913
990
|
});
|
|
914
991
|
if (!canAfford.canAfford) {
|
|
915
992
|
throw new Error(
|
|
916
|
-
`Insufficient funds to release lock. Available: ${formatArgons(canAfford.availableBalance)}, Required: ${formatArgons(redemptionPrice)}`
|
|
993
|
+
`Insufficient funds to release lock. Available: ${formatArgons(canAfford.availableBalance)}, Required: ${formatArgons(redemptionPrice + canAfford.txFee + tip)}`
|
|
917
994
|
);
|
|
918
995
|
}
|
|
919
|
-
|
|
920
|
-
waitForBlock: true,
|
|
996
|
+
return submitter.submit({
|
|
921
997
|
logResults: true,
|
|
922
|
-
|
|
923
|
-
txProgressCallback
|
|
998
|
+
...args
|
|
924
999
|
});
|
|
925
|
-
const blockHash = await txResult.inBlockPromise;
|
|
926
|
-
const blockHeight = await client.at(blockHash).then((x) => x.query.system.number()).then((x) => x.toNumber());
|
|
927
|
-
return {
|
|
928
|
-
blockHash,
|
|
929
|
-
blockHeight
|
|
930
|
-
};
|
|
931
1000
|
}
|
|
932
1001
|
async releasePrice(priceIndex, lock) {
|
|
933
1002
|
return await this.getRedemptionRate(priceIndex, lock);
|
|
@@ -974,41 +1043,43 @@ var BitcoinLocks = class {
|
|
|
974
1043
|
)}`
|
|
975
1044
|
);
|
|
976
1045
|
}
|
|
977
|
-
const
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
(
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1046
|
+
const txResult = await txSubmitter.submit(args);
|
|
1047
|
+
const getRatchetResult = async () => {
|
|
1048
|
+
const blockHash = await txResult.waitForFinalizedBlock;
|
|
1049
|
+
const ratchetEvent = txResult.events.find(
|
|
1050
|
+
(x) => client.events.bitcoinLocks.BitcoinLockRatcheted.is(x)
|
|
1051
|
+
);
|
|
1052
|
+
if (!ratchetEvent) {
|
|
1053
|
+
throw new Error(`Ratchet event not found in transaction events`);
|
|
1054
|
+
}
|
|
1055
|
+
const api = await client.at(blockHash);
|
|
1056
|
+
const bitcoinBlockHeight = await api.query.bitcoinUtxos.confirmedBitcoinBlockTip().then((x) => x.unwrap().blockHeight.toNumber());
|
|
1057
|
+
const {
|
|
1058
|
+
amountBurned,
|
|
1059
|
+
liquidityPromised: liquidityPromisedRaw,
|
|
1060
|
+
newPeggedPrice,
|
|
1061
|
+
originalPeggedPrice,
|
|
1062
|
+
securityFee
|
|
1063
|
+
} = ratchetEvent.data;
|
|
1064
|
+
const liquidityPromised = liquidityPromisedRaw.toBigInt();
|
|
1065
|
+
let mintAmount = liquidityPromised;
|
|
1066
|
+
if (liquidityPromised > originalPeggedPrice.toBigInt()) {
|
|
1067
|
+
mintAmount -= originalPeggedPrice.toBigInt();
|
|
1068
|
+
}
|
|
1069
|
+
return {
|
|
1070
|
+
txFee: txResult.finalFee ?? 0n,
|
|
1071
|
+
blockHeight: txResult.blockNumber,
|
|
1072
|
+
bitcoinBlockHeight,
|
|
1073
|
+
pendingMint: mintAmount,
|
|
1074
|
+
liquidityPromised,
|
|
1075
|
+
newPeggedPrice: newPeggedPrice.toBigInt(),
|
|
1076
|
+
burned: amountBurned.toBigInt(),
|
|
1077
|
+
securityFee: securityFee.toBigInt()
|
|
1078
|
+
};
|
|
1079
|
+
};
|
|
1003
1080
|
return {
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
pendingMint: mintAmount,
|
|
1007
|
-
liquidityPromised,
|
|
1008
|
-
newPeggedPrice: newPeggedPrice.toBigInt(),
|
|
1009
|
-
burned: amountBurned.toBigInt(),
|
|
1010
|
-
blockHeight,
|
|
1011
|
-
bitcoinBlockHeight
|
|
1081
|
+
txResult,
|
|
1082
|
+
getRatchetResult
|
|
1012
1083
|
};
|
|
1013
1084
|
}
|
|
1014
1085
|
};
|
|
@@ -1073,7 +1144,7 @@ var PriceIndex = class {
|
|
|
1073
1144
|
|
|
1074
1145
|
// src/index.ts
|
|
1075
1146
|
import { u8aToHex as u8aToHex2, hexToU8a as hexToU8a2, u8aEq } from "@polkadot/util";
|
|
1076
|
-
import { GenericEvent
|
|
1147
|
+
import { GenericEvent, GenericBlock, GenericAddress } from "@polkadot/types/generic";
|
|
1077
1148
|
import {
|
|
1078
1149
|
BTreeMap,
|
|
1079
1150
|
Bytes,
|
|
@@ -1117,11 +1188,11 @@ export {
|
|
|
1117
1188
|
Bytes,
|
|
1118
1189
|
Compact,
|
|
1119
1190
|
Enum,
|
|
1120
|
-
|
|
1191
|
+
ExtrinsicError,
|
|
1121
1192
|
FIXED_U128_DECIMALS,
|
|
1122
1193
|
GenericAddress,
|
|
1123
1194
|
GenericBlock,
|
|
1124
|
-
|
|
1195
|
+
GenericEvent,
|
|
1125
1196
|
Keyring,
|
|
1126
1197
|
MICROGONS_PER_ARGON,
|
|
1127
1198
|
Null,
|