@flarenetwork/flare-stake-tool
Version:
Utilities for staking on the Flare network
683 lines • 28.7 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildExportCTx = buildExportCTx;
exports.buildImportCTx = buildImportCTx;
exports.buildImportPTx = buildImportPTx;
exports.buildExportPTx = buildExportPTx;
exports.buildAddDelegatorTx = buildAddDelegatorTx;
exports.buildAddValidatorTx = buildAddValidatorTx;
exports.buildBaseTx = buildBaseTx;
exports.buildEvmTx = buildEvmTx;
exports.finalizeAndConvertEvmTx = finalizeAndConvertEvmTx;
exports.signAndSubmitTx = signAndSubmitTx;
exports.submitTxHex = submitTxHex;
exports.getStakeTransaction = getStakeTransaction;
const utils = __importStar(require("../utils"));
const settings = __importStar(require("../settings"));
const chain = __importStar(require("./chain"));
const pubk = __importStar(require("./pubk"));
const bn_js_1 = __importDefault(require("bn.js"));
const flarejs_1 = require("@flarenetwork/flarejs");
const tx_1 = require("@ethereumjs/tx");
const rlp_1 = require("@ethereumjs/rlp");
const common_1 = require("@ethereumjs/common");
const context_1 = require("./context");
const TX_WAIT_MS = 15000;
const TX_CHECK_MS = 1000;
async function buildExportCTx(account, params) {
let importFeeReservation = await chain.getPTxDefaultFee(account.network);
if (!params.exportFee || params.exportFee.isZero()) {
params.exportFee = await _getExportCTxFee(account, params.amount, importFeeReservation);
}
let unsignedTx = await _getUnsignedExportCTx(account, params.amount, params.exportFee, importFeeReservation);
let unsignedTxHex = _unsignedTxToHex(unsignedTx);
return {
txDetails: {
...params,
importFeeReservation,
unsignedTxHex
},
unsignedTx
};
}
async function _getExportCTxFee(account, amount, importFeeReservation) {
const baseFee = await chain.getCTxBaseFee(account.network);
const tx = await _getUnsignedExportCTx(account, amount, new bn_js_1.default(0), importFeeReservation);
const cost = new bn_js_1.default(flarejs_1.utils.costCorethTx(tx).toString());
return baseFee.mul(cost);
}
async function _getUnsignedExportCTx(account, amount, exportFee, importFeeReservation) {
const context = await (0, context_1.getContext)(account.network);
const cAddress = flarejs_1.utils.hexToBuffer(account.cAddress);
const pAddress = flarejs_1.utils.bech32ToBytes(account.pAddress);
const nonce = await chain.numberOfCTxs(account.network, account.cAddress);
return flarejs_1.evm.newExportTx(context, BigInt(amount.add(importFeeReservation).toString()), context.pBlockchainID, cAddress, [pAddress], BigInt(exportFee.toString()), BigInt(nonce));
}
async function buildImportCTx(account, params) {
if (!params.importFee || params.importFee.isZero()) {
params.importFee = await _getImportCTxFee(account);
}
let unsignedTx = await _getUnsignedImportCTx(account, params.importFee);
let amount = await chain.getPCBalance(account.network, account.pAddress);
let unsignedTxHex = _unsignedTxToHex(unsignedTx);
return {
txDetails: { ...params, amount, unsignedTxHex },
unsignedTx
};
}
async function _getImportCTxFee(account) {
const baseFee = await chain.getCTxBaseFee(account.network);
const tx = await _getUnsignedImportCTx(account, new bn_js_1.default(0));
const cost = new bn_js_1.default(flarejs_1.utils.costCorethTx(tx).toString());
return baseFee.mul(cost);
}
async function _getUnsignedImportCTx(account, importFee) {
const context = await (0, context_1.getContext)(account.network);
const pAddressString = `C-${account.pAddress.slice(2)}`;
const pAddress = flarejs_1.utils.bech32ToBytes(pAddressString);
const cAddress = flarejs_1.utils.hexToBuffer(account.cAddress);
const evmapi = new flarejs_1.evm.EVMApi(settings.URL[account.network]);
const { utxos } = await evmapi.getUTXOs({
addresses: [pAddressString],
sourceChain: 'P'
});
return flarejs_1.evm.newImportTx(context, cAddress, [pAddress], utxos, context.pBlockchainID, BigInt(importFee.toString()));
}
async function buildImportPTx(account, params) {
const context = await (0, context_1.getContext)(account.network);
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[account.network]);
const pAddressString = account.pAddress;
const pAddress = flarejs_1.utils.bech32ToBytes(pAddressString);
const { utxos } = await pvmapi.getUTXOs({
addresses: [pAddressString],
sourceChain: 'C'
});
const unsignedTx = flarejs_1.pvm.newImportTx(context, context.cBlockchainID, utxos, [pAddress], [pAddress]);
const amount = await chain.getCPBalance(account.network, account.pAddress);
const importFee = await chain.getPTxDefaultFee(account.network);
const unsignedTxHex = _unsignedTxToHex(unsignedTx);
return {
txDetails: {
...params,
amount,
importFee,
unsignedTxHex
},
unsignedTx
};
}
async function buildExportPTx(account, params) {
const context = await (0, context_1.getContext)(account.network);
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[account.network]);
const pAddressString = account.pAddress;
const pAddress = flarejs_1.utils.bech32ToBytes(pAddressString);
const exportFee = await chain.getPTxDefaultFee(account.network);
let amount = params.amount;
if (!amount || amount.isZero()) {
amount = (await chain.getPBalance(account.network, account.pAddress)).sub(exportFee);
}
if (amount.lte(new bn_js_1.default(0))) {
throw new Error('Export amount is smaller than or equal to zero');
}
const { utxos } = await pvmapi.getUTXOs({ addresses: [pAddressString] });
const output = flarejs_1.TransferableOutput.fromNative(context.avaxAssetID, BigInt(amount.toString()), [
pAddress
]);
const unsignedTx = flarejs_1.pvm.newExportTx(context, context.cBlockchainID, [pAddress], utxos, [
output
]);
const unsignedTxHex = _unsignedTxToHex(unsignedTx);
return {
txDetails: { ...params, exportFee, unsignedTxHex },
unsignedTx
};
}
async function buildAddDelegatorTx(account, params) {
const context = await (0, context_1.getContext)(account.network);
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[account.network]);
const pAddressString = account.pAddress;
const pAddress = flarejs_1.utils.bech32ToBytes(pAddressString);
const { utxos } = await pvmapi.getUTXOs({ addresses: [pAddressString] });
const unsignedTx = flarejs_1.pvm.newAddPermissionlessDelegatorTx(context, utxos, [pAddress], params.nodeId, flarejs_1.networkIDs.PrimaryNetworkID.toString(), BigInt(params.startTime.toString()), BigInt(params.endTime.toString()), BigInt(params.amount.toString()), [pAddress]);
const unsignedTxHex = _unsignedTxToHex(unsignedTx);
return {
txDetails: { ...params, unsignedTxHex },
unsignedTx
};
}
async function buildAddValidatorTx(account, params) {
const context = await (0, context_1.getContext)(account.network);
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[account.network]);
const pAddressString = account.pAddress;
const pAddress = flarejs_1.utils.bech32ToBytes(pAddressString);
const { utxos } = await pvmapi.getUTXOs({ addresses: [pAddressString] });
const unsignedTx = flarejs_1.pvm.newAddPermissionlessValidatorTx(context, utxos, [pAddress], params.nodeId, flarejs_1.networkIDs.PrimaryNetworkID.toString(), BigInt(params.startTime.toString()), BigInt(params.endTime.toString()), BigInt(params.amount.toString()), [pAddress], [pAddress], params.delegationFee, {
changeAddresses: [pAddress]
}, 1, 0n, params.popBLSPublicKey, params.popBLSSignature);
const unsignedTxHex = _unsignedTxToHex(unsignedTx);
return {
txDetails: { ...params, unsignedTxHex },
unsignedTx
};
}
async function buildBaseTx(account, params) {
const context = await (0, context_1.getContext)(account.network);
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[account.network]);
const pAddressString = account.pAddress;
const pAddressBytes = flarejs_1.utils.bech32ToBytes(pAddressString);
const { utxos } = await pvmapi.getUTXOs({ addresses: [pAddressString] });
const pChainTransferAddressBytes = flarejs_1.utils.bech32ToBytes(params.recipientAddress);
const unsignedTx = flarejs_1.pvm.newBaseTx(context, [pAddressBytes], utxos, [
flarejs_1.TransferableOutput.fromNative(context.avaxAssetID, BigInt(params.amount), [pChainTransferAddressBytes])
]);
const unsignedTxHex = _unsignedTxToHex(unsignedTx);
return {
txDetails: { ...params, unsignedTxHex },
unsignedTx
};
}
function _unsignedTxToHex(unsignedTx) {
return utils.toHex(unsignedTx.toBytes());
}
async function buildEvmTx(account, params, evmTx) {
let txData = {
from: account.cAddress,
chainId: BigInt(settings.CHAIN_ID[account.network]),
...evmTx
};
if (!txData.value) {
txData.value = BigInt(0);
}
if (!txData.nonce) {
txData.nonce = await chain.numberOfCTxs(account.network, account.cAddress);
}
if (!txData.maxFeePerGas || !txData.maxPriorityFeePerGas) {
let feeEstimate = await chain.estimateEIP1559Fee(account.network);
txData.maxFeePerGas = feeEstimate[0];
txData.maxPriorityFeePerGas = feeEstimate[1];
}
if (!txData.gasLimit) {
let web3 = chain.getWeb3(account.network);
let estimatedGasLimit = await web3.eth.estimateGas(txData);
txData.gasLimit = (estimatedGasLimit * BigInt(10500)) / BigInt(10000);
}
let unsignedTx;
let unsignedTxHex;
if (params.txType == 0) {
let common = common_1.Common.custom({ chainId: txData.chainId });
let evmLegacyTx = {
from: txData.from,
to: Uint8Array.from(utils.toBuffer(txData.to)),
data: Uint8Array.from(utils.toBuffer(txData.data ?? '')),
value: txData.value,
gasLimit: txData.gasLimit,
gasPrice: txData.maxFeePerGas - txData.maxPriorityFeePerGas,
nonce: txData.nonce,
chainId: txData.chainId
};
unsignedTx = tx_1.LegacyTransaction.fromTxData(evmLegacyTx, { common });
unsignedTxHex = utils.toHex(rlp_1.RLP.encode(unsignedTx.getMessageToSign()));
}
else if (params.txType == 2) {
let evmEIP1559Tx = {
from: txData.from,
to: Uint8Array.from(utils.toBuffer(txData.to)),
data: Uint8Array.from(utils.toBuffer(txData.data ?? '')),
value: txData.value,
gasLimit: txData.gasLimit,
maxPriorityFeePerGas: txData.maxPriorityFeePerGas,
maxFeePerGas: txData.maxFeePerGas,
nonce: txData.nonce,
chainId: txData.chainId
};
unsignedTx = tx_1.FeeMarketEIP1559Transaction.fromTxData(evmEIP1559Tx);
unsignedTxHex = utils.toHex(unsignedTx.getMessageToSign());
}
else {
throw new Error('Unsupported transaction type');
}
return {
txDetails: {
...params,
...txData,
unsignedTxHex,
isEvmTx: true
},
unsignedTx
};
}
async function finalizeAndConvertEvmTx(from, txHex, txType) {
let tx = tx_1.TransactionFactory.fromSerializedData(utils.toBuffer(txHex));
let chainId;
let accessList;
if (tx instanceof tx_1.LegacyTransaction) {
if (!tx.v) {
throw new Error('Legacy transaction must have v field defined');
}
chainId = tx.v;
accessList = null;
}
else if (tx instanceof tx_1.FeeMarketEIP1559Transaction) {
chainId = tx.chainId;
accessList = tx.accessList;
}
else {
throw new Error('Unsupported EVM transaction type given');
}
let network = _getNetworkFromChainId(chainId);
let to = utils.toHex(tx.to ? tx.to.toString() : '');
let value = tx.value;
let data = utils.toHex(tx.data);
let nonce = await chain.numberOfCTxs(network, from);
let feeEstimate = await chain.estimateEIP1559Fee(network);
let maxFeePerGas = feeEstimate[0];
let maxPriorityFeePerGas = feeEstimate[1];
let web3 = chain.getWeb3(network);
let estimatedGasLimit = await web3.eth.estimateGas({
from,
to,
value,
data,
nonce
});
let gasLimit = (estimatedGasLimit * BigInt(10500)) / BigInt(10000);
let unsignedTxHex;
if (txType == 0) {
let toArray = Uint8Array.from(utils.toBuffer(to));
let dataArray = Uint8Array.from(utils.toBuffer(data));
let common = common_1.Common.custom({ chainId });
let gasPrice = maxFeePerGas - maxPriorityFeePerGas;
let unsignedTx = tx_1.LegacyTransaction.fromTxData({ to: toArray, value, data: dataArray, nonce, gasLimit, gasPrice }, { common });
unsignedTxHex = utils.toHex(rlp_1.RLP.encode(unsignedTx.getMessageToSign()));
}
else if (txType == 2) {
let toArray = Uint8Array.from(utils.toBuffer(to));
let dataArray = Uint8Array.from(utils.toBuffer(data));
let unsignedTx = tx_1.FeeMarketEIP1559Transaction.fromTxData({
chainId,
to: toArray,
value,
data: dataArray,
nonce,
gasLimit,
maxFeePerGas,
maxPriorityFeePerGas,
accessList
});
unsignedTxHex = utils.toHex(unsignedTx.getMessageToSign());
}
else {
throw new Error('Unsupported EVM transaction type requested');
}
return unsignedTxHex;
}
async function signAndSubmitTx(unsignedTxData, sign, presubmit) {
let unsignedTxHash;
let unsignedTx = unsignedTxData.unsignedTx;
if (unsignedTx instanceof tx_1.LegacyTransaction) {
unsignedTxHash = utils.toHex(unsignedTx.getHashedMessageToSign());
}
else if (unsignedTx instanceof tx_1.FeeMarketEIP1559Transaction) {
unsignedTxHash = utils.toHex(unsignedTx.getHashedMessageToSign());
}
else if (unsignedTx instanceof flarejs_1.UnsignedTx) {
unsignedTxHash = utils.toHex((0, flarejs_1.messageHashFromUnsignedTx)(unsignedTx));
}
else {
throw new Error(`Can't issue transaction of type ${typeof unsignedTx}`);
}
let signatureResponse = await sign({
...unsignedTxData.txDetails,
unsignedTxHash
});
let id = '';
let submitted = false;
let network = unsignedTxData.txDetails.network;
let signedTxData = { ...unsignedTxData, signature: '', signedTx: '' };
if (signatureResponse.startsWith('id:')) {
// the transaction was not just signed but also submitted to the network
id = signatureResponse.slice(3);
submitted = true;
}
else {
let signature = utils.toHex(signatureResponse, false);
signedTxData.signature = signature;
let publicKey = pubk.recoverPublicKeyFromMsg(unsignedTxHash, signature);
if (!pubk.equalPublicKey(publicKey, unsignedTxData.txDetails.publicKey)) {
if (unsignedTx instanceof flarejs_1.UnsignedTx) {
publicKey = pubk.recoverPublicKeyFromEthMsg(utils.toHex(unsignedTxHash, false), signature);
if (!pubk.equalPublicKey(publicKey, unsignedTxData.txDetails.publicKey)) {
throw new Error('The public key recovered from the (ETH) signature does not match the expected public key');
}
}
else {
throw new Error('The public key recovered from the signature does not match the expected public key');
}
}
let signedTx;
if (unsignedTx instanceof tx_1.LegacyTransaction || unsignedTx instanceof tx_1.FeeMarketEIP1559Transaction) {
let expandedSignature = _expandSignature(signature);
let tx;
if (unsignedTx instanceof tx_1.LegacyTransaction) {
let v = expandedSignature.recoveryParam;
if (v == 0 || v == 1) {
v += 27;
}
if (v == 27 || v == 28) {
v += 8 + 2 * parseInt(settings.CHAIN_ID[network], 16);
}
tx = tx_1.LegacyTransaction.fromTxData({
...(unsignedTx.toJSON()),
v: BigInt(v.toString()),
r: BigInt(expandedSignature.r.toString()),
s: BigInt(expandedSignature.s.toString())
});
}
else {
const txData = unsignedTx.toJSON();
delete txData.gasPrice;
tx = tx_1.FeeMarketEIP1559Transaction.fromTxData({
...txData,
v: BigInt(expandedSignature.recoveryParam.toString()),
r: BigInt(expandedSignature.r.toString()),
s: BigInt(expandedSignature.s.toString())
});
}
signedTx = tx.serialize();
}
else if (unsignedTx instanceof flarejs_1.EVMUnsignedTx) {
const compressedPublicKey = pubk.compressPublicKey(Buffer.from('04' + publicKey, 'hex'));
const expandedSignature = _expandSignature(signature);
signTxDbg(unsignedTx, [
{
signature: _transformSignature(expandedSignature),
publicKey: compressedPublicKey
}
]);
signedTx = unsignedTx.getSignedTx().toBytes();
}
else {
// unsignedTx instanceof UnsignedTx
const compressedPublicKey = pubk.compressPublicKey(Buffer.from('04' + publicKey, 'hex'));
const expandedSignature = _expandSignature(signature);
signTxDbg(unsignedTx, [
{
signature: _transformSignature(expandedSignature),
// signature: Buffer.from(signature, "hex"),
publicKey: compressedPublicKey
}
]);
signedTx = unsignedTx.getSignedTx().toBytes();
}
signedTxData.signedTx = utils.toHex(signedTx);
let txSummary = {
network: signedTxData.txDetails.network,
type: signedTxData.txDetails.type,
publicKey: signedTxData.txDetails.publicKey,
unsignedTx: signedTxData.txDetails.unsignedTxHex,
unsignedTxHash: signedTxData.txDetails.unsignedTxHash,
signature: signedTxData.signature,
signedTx: signedTxData.signedTx
};
if (!presubmit || (await presubmit(txSummary))) {
if (unsignedTx instanceof tx_1.LegacyTransaction || unsignedTx instanceof tx_1.FeeMarketEIP1559Transaction) {
let web3 = chain.getWeb3(network);
id = await _submitEvmTx(web3, signedTxData.signedTx);
}
else {
if (unsignedTx instanceof flarejs_1.EVMUnsignedTx) {
const evmapi = new flarejs_1.evm.EVMApi(settings.URL[network]);
id = (await evmapi.issueTx({
tx: utils.toHex(flarejs_1.utils.addChecksum(signedTx))
})).txID;
}
else if (unsignedTx instanceof flarejs_1.UnsignedTx) {
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[network]);
id = (await pvmapi.issueTx({
tx: utils.toHex(flarejs_1.utils.addChecksum(signedTx))
})).txID;
}
else {
throw new Error(`Can not issue transaction of type ${typeof unsignedTx}`);
}
}
submitted = true;
}
}
let status = '';
let confirmed = false;
if (submitted) {
let result;
if (unsignedTx instanceof tx_1.LegacyTransaction || unsignedTx instanceof tx_1.FeeMarketEIP1559Transaction) {
result = await _waitForEvmTxConfirmation(chain.getWeb3(network), id);
}
else if (unsignedTx instanceof flarejs_1.EVMUnsignedTx) {
const evmapi = new flarejs_1.evm.EVMApi(settings.URL[network]);
result = await _waitForCTxConfirmation(evmapi, id);
}
else if (unsignedTx instanceof flarejs_1.UnsignedTx) {
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[network]);
result = await _waitForPTxConfirmation(pvmapi, id);
}
else {
throw new Error(`Can not issue transaction of type ${typeof unsignedTx}`);
}
status = result[0];
confirmed = result[1];
}
return { ...signedTxData, id, status, submitted, confirmed };
}
function _expandSignature(signature) {
let recoveryParam = parseInt(signature.slice(128, 130), 16);
if (recoveryParam === 27 || recoveryParam === 28) {
recoveryParam -= 27;
}
return {
r: new bn_js_1.default(signature.slice(0, 64), 'hex'),
s: new bn_js_1.default(signature.slice(64, 128), 'hex'),
recoveryParam: recoveryParam
};
}
async function submitTxHex(txHex) {
try {
// let ctx = new CTx()
// ctx.fromBuffer(utils.toBuffer(txHex) as any)
// let network = _getNetworkFromChainId(ctx.getUnsignedTx().getTransaction().getNetworkID())
// const context = await getContext(network)
// let avajs = chain.getAvalanche(network)
// TODO: obtain network name from ...
const evmapi = new flarejs_1.evm.EVMApi(settings.URL['localflare']);
let id = await _submitCTx(evmapi, txHex);
let result = await _waitForCTxConfirmation(evmapi, id);
let status = result[0];
let confirmed = result[1];
return [id, status, confirmed];
}
catch (e) {
console.log('Error submitting CTx', e);
}
try {
// let ptx = new PTx()
// ptx.fromBuffer(utils.toBuffer(txHex) as any)
// let network = _getNetworkFromChainId(ptx.getUnsignedTx().getTransaction().getNetworkID())
// let avajs = chain.getAvalanche(network)
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL['localflare']);
let id = await _submitPTx(pvmapi, txHex);
let result = await _waitForPTxConfirmation(pvmapi, id);
let status = result[0];
let confirmed = result[1];
return [id, status, confirmed];
}
catch (e) {
console.log('Error submitting PTx', e);
}
try {
let evmTx = tx_1.TransactionFactory.fromSerializedData(utils.toBuffer(txHex));
let chainId;
if (evmTx instanceof tx_1.LegacyTransaction) {
if (!evmTx.v) {
throw new Error('Legacy transaction must have v field defined');
}
chainId = evmTx.v;
}
else {
chainId = evmTx.chainId;
}
let network = _getNetworkFromChainId(chainId);
let web3 = chain.getWeb3(network);
let id = await _submitEvmTx(web3, txHex);
let result = await _waitForEvmTxConfirmation(web3, id);
let status = result[0];
let confirmed = result[1];
return [id, status, confirmed];
}
catch (e) {
console.log('Error submitting EVM Tx', e);
}
return null;
}
async function _submitCTx(evmapi, txHex) {
const { txID } = await evmapi.issueTx({ tx: txHex });
return txID;
}
async function _submitPTx(pvmapi, txHex) {
const { txID } = await pvmapi.issueTx({ tx: txHex });
return txID;
}
async function _submitEvmTx(web3, txHex) {
let id = '';
await web3.eth.sendSignedTransaction(txHex).on('transactionHash', (txHash) => {
id = txHash;
});
return id;
}
async function _waitForCTxConfirmation(evmapi, txId) {
let status = 'Unkown';
let start = Date.now();
while (Date.now() - start < TX_WAIT_MS) {
status = (await evmapi.getAtomicTxStatus(txId)).status;
await utils.sleep(TX_CHECK_MS); // wait regardless of status for added safety
if (status === 'Accepted' || status === 'Rejected') {
break;
}
}
let confirmed = status === 'Accepted';
return [status, confirmed];
}
async function _waitForPTxConfirmation(pvmapi, txId) {
let status = 'Unkown';
let start = Date.now();
while (Date.now() - start < TX_WAIT_MS) {
status = (await pvmapi.getTxStatus({ txID: txId })).status;
await utils.sleep(TX_CHECK_MS); // wait regardless of status for added safety
if (status === 'Committed' || status === 'Rejected') {
break;
}
}
let confirmed = status === 'Committed';
return [status, confirmed];
}
async function _waitForEvmTxConfirmation(web3, txId) {
let status = 'Unkown';
let start = Date.now();
while (Date.now() - start < TX_WAIT_MS) {
let receipt;
try {
receipt = await web3.eth.getTransactionReceipt(txId);
}
catch (e) {
console.log('Error getting transaction receipt', e);
}
if (receipt) {
status = receipt.status == BigInt(1) ? 'Confirmed' : 'Failed';
break;
}
await utils.sleep(TX_CHECK_MS);
}
let confirmed = status === 'Confirmed';
return [status, confirmed];
}
function _getNetworkFromChainId(chainId) {
let network = '';
let chainIdHex = utils.toHex(chainId.toString(16));
for (let entry of Object.entries(settings.CHAIN_ID)) {
if (entry[1] === chainIdHex) {
network = entry[0];
break;
}
}
if (!network) {
throw new Error('Unsupported network');
}
return network;
}
async function getStakeTransaction(network, txId) {
const pvmapi = new flarejs_1.pvm.PVMApi(settings.URL[network]);
let tx = await pvmapi.getTx({ txID: txId });
switch (tx.unsignedTx._type) {
case flarejs_1.TypeSymbols.AddDelegatorTx:
return tx.unsignedTx;
case flarejs_1.TypeSymbols.AddValidatorTx:
return tx.unsignedTx;
case flarejs_1.TypeSymbols.AddPermissionlessDelegatorTx:
return tx.unsignedTx;
case flarejs_1.TypeSymbols.AddPermissionlessValidatorTx:
return tx.unsignedTx;
default:
throw new Error('Not a stake transaction');
}
}
function _transformSignature(sig) {
const recovery = Buffer.alloc(1);
recovery.writeUInt8(sig.recoveryParam, 0);
const r = Buffer.from(sig.r.toArray('be', 32)); //we have to skip native Buffer class, so this is the way
const s = Buffer.from(sig.s.toArray('be', 32)); //we have to skip native Buffer class, so this is the way
return Buffer.concat([r, s, recovery], 65);
}
function signTxDbg(tx, signingData) {
for (const data of signingData) {
const coordinates = tx.getSigIndicesForPubKey(data.publicKey);
if (coordinates) {
coordinates.forEach(([index, subIndex]) => {
tx.addSignatureAt(data.signature, index, subIndex);
});
}
}
}
//# sourceMappingURL=txs.js.map