UNPKG

airgap-coin-lib

Version:

The airgap-coin-lib is a protocol agnostic library to prepare, sign and broadcast cryptocurrency transactions.

898 lines (897 loc) 56.7 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = function (d, b) { extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return extendStatics(d, b); }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __generator = (this && this.__generator) || function (thisArg, body) { var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); while (_) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { case 0: case 1: t = op; break; case 4: _.label++; return { value: op[1], done: false }; case 5: _.label++; y = op[1]; op = [0]; continue; case 7: op = _.ops.pop(); _.trys.pop(); continue; default: if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } if (t[2]) _.ops.pop(); _.trys.pop(); continue; } op = body.call(thisArg, _); } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; } }; var __spreadArrays = (this && this.__spreadArrays) || function () { for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; for (var r = Array(s), k = 0, i = 0; i < il; i++) for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) r[k] = a[j]; return r; }; Object.defineProperty(exports, "__esModule", { value: true }); var bignumber_1 = require("../../dependencies/src/bignumber.js-9.0.0/bignumber"); var assert_1 = require("../../utils/assert"); var NonExtendedProtocol_1 = require("../NonExtendedProtocol"); var SubstrateAddress_1 = require("./helpers/data/account/SubstrateAddress"); var SubstratePayee_1 = require("./helpers/data/staking/SubstratePayee"); var SubstrateStakingActionType_1 = require("./helpers/data/staking/SubstrateStakingActionType"); var SubstrateTransaction_1 = require("./helpers/data/transaction/SubstrateTransaction"); var SubstrateCryptoClient_1 = require("./SubstrateCryptoClient"); var SubstrateProtocol = /** @class */ (function (_super) { __extends(SubstrateProtocol, _super); function SubstrateProtocol(options) { var _this = _super.call(this) || this; _this.options = options; _this.supportsHD = false; _this.addressIsCaseSensitive = false; _this.addressValidationPattern = '^5[a-km-zA-HJ-NP-Z1-9]+$'; _this.addressPlaceholder = "5ABC..."; return _this; } SubstrateProtocol.prototype.getBlockExplorerLinkForAddress = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.network.blockExplorer.getAddressLink(address)]; }); }); }; SubstrateProtocol.prototype.getBlockExplorerLinkForTxId = function (txId) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.network.blockExplorer.getTransactionLink(txId)]; }); }); }; SubstrateProtocol.prototype.getPublicKeyFromMnemonic = function (mnemonic, derivationPath, password) { return __awaiter(this, void 0, void 0, function () { var keyPair; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.createKeyPairFromMnemonic(mnemonic, derivationPath, password)]; case 1: keyPair = _a.sent(); return [2 /*return*/, keyPair.publicKey.toString('hex')]; } }); }); }; SubstrateProtocol.prototype.getPrivateKeyFromMnemonic = function (mnemonic, derivationPath, password) { return __awaiter(this, void 0, void 0, function () { var keyPair; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.createKeyPairFromMnemonic(mnemonic, derivationPath, password)]; case 1: keyPair = _a.sent(); return [2 /*return*/, keyPair.privateKey]; } }); }); }; SubstrateProtocol.prototype.getPublicKeyFromHexSecret = function (secret, derivationPath) { return __awaiter(this, void 0, void 0, function () { var keyPair; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.createKeyPairFromHexSecret(secret, derivationPath)]; case 1: keyPair = _a.sent(); return [2 /*return*/, keyPair.publicKey.toString('hex')]; } }); }); }; SubstrateProtocol.prototype.getPrivateKeyFromHexSecret = function (secret, derivationPath) { return __awaiter(this, void 0, void 0, function () { var keyPair; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.createKeyPairFromHexSecret(secret, derivationPath)]; case 1: keyPair = _a.sent(); return [2 /*return*/, keyPair.privateKey]; } }); }); }; SubstrateProtocol.prototype.getAddressFromPublicKey = function (publicKey) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.accountController.createAddressFromPublicKey(publicKey)]; }); }); }; SubstrateProtocol.prototype.getAddressesFromPublicKey = function (publicKey) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: return [2 /*return*/, [_a.sent()]]; } }); }); }; SubstrateProtocol.prototype.getTransactionsFromPublicKey = function (publicKey, limit, cursor) { return __awaiter(this, void 0, void 0, function () { var addresses; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getAddressesFromPublicKey(publicKey)]; case 1: addresses = _a.sent(); return [2 /*return*/, this.getTransactionsFromAddresses(addresses, limit, cursor)]; } }); }); }; SubstrateProtocol.prototype.getTransactionsFromAddresses = function (addresses, limit, cursor) { return __awaiter(this, void 0, void 0, function () { var txs, transactions; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all(addresses.map(function (address) { return _this.options.blockExplorerClient.getTransactions(address, limit, _this.decimals, cursor); }))]; case 1: txs = _a.sent(); transactions = txs .reduce(function (flatten, toFlatten) { return flatten.concat(toFlatten); }, []) .map(function (tx) { return (__assign({ protocolIdentifier: _this.identifier, network: _this.options.network, from: [], to: [], isInbound: false, amount: '', fee: '' }, tx)); }); return [2 /*return*/, { transactions: transactions, cursor: { page: cursor ? cursor.page + 1 : 1 } }]; } }); }); }; SubstrateProtocol.prototype.signWithPrivateKey = function (privateKey, rawTransaction) { return __awaiter(this, void 0, void 0, function () { var txs, signed; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: txs = this.options.transactionController.decodeDetails(rawTransaction.encoded); return [4 /*yield*/, Promise.all(txs.map(function (tx) { return _this.options.transactionController.signTransaction(privateKey, tx.transaction, tx.payload); }))]; case 1: signed = _a.sent(); txs.forEach(function (tx, index) { return (tx.transaction = signed[index]); }); return [2 /*return*/, this.options.transactionController.encodeDetails(txs)]; } }); }); }; SubstrateProtocol.prototype.getTransactionDetails = function (transaction) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.getTransactionDetailsFromEncoded(transaction.transaction.encoded)]; }); }); }; SubstrateProtocol.prototype.getTransactionDetailsFromSigned = function (transaction) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.getTransactionDetailsFromEncoded(transaction.transaction)]; }); }); }; SubstrateProtocol.prototype.getBalanceOfAddresses = function (addresses) { return __awaiter(this, void 0, void 0, function () { var balances, balance; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all(addresses.map(function (address) { return _this.options.accountController.getBalance(address); }))]; case 1: balances = _a.sent(); balance = balances.reduce(function (current, next) { return current.plus(next); }); return [2 /*return*/, balance.toString(10)]; } }); }); }; SubstrateProtocol.prototype.getAvailableBalanceOfAddresses = function (addresses) { return __awaiter(this, void 0, void 0, function () { var balances, balance; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all(addresses.map(function (address) { return _this.options.accountController.getTransferableBalance(address, false); }))]; case 1: balances = _a.sent(); balance = balances.reduce(function (current, next) { return current.plus(next); }); return [2 /*return*/, balance.toString(10)]; } }); }); }; SubstrateProtocol.prototype.getBalanceOfPublicKey = function (publicKey) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.getBalanceOfAddresses; return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: return [2 /*return*/, _a.apply(this, [[_b.sent()]])]; } }); }); }; SubstrateProtocol.prototype.getBalanceOfPublicKeyForSubProtocols = function (publicKey, subProtocols) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { throw Promise.reject('get balance of sub protocols not supported'); }); }); }; SubstrateProtocol.prototype.estimateMaxTransactionValueFromPublicKey = function (publicKey, recipients, fee) { return __awaiter(this, void 0, void 0, function () { var results, transferableBalance, futureTransactions, feeEstimate, maxAmount; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all([ this.options.accountController.getTransferableBalance(publicKey), this.getFutureRequiredTransactions(publicKey, 'check') ])]; case 1: results = _a.sent(); transferableBalance = results[0]; futureTransactions = results[1]; return [4 /*yield*/, this.options.transactionController.estimateTransactionFees(publicKey, futureTransactions)]; case 2: feeEstimate = _a.sent(); if (!feeEstimate) { return [2 /*return*/, Promise.reject('Could not estimate max value.')]; } maxAmount = transferableBalance.minus(feeEstimate).minus(new bignumber_1.default(fee || 0)); if (maxAmount.lt(0)) { maxAmount = new bignumber_1.default(0); } return [2 /*return*/, maxAmount.toFixed()]; } }); }); }; SubstrateProtocol.prototype.estimateFeeDefaultsFromPublicKey = function (publicKey, recipients, values, data) { return __awaiter(this, void 0, void 0, function () { var destination, value, transaction, fee; return __generator(this, function (_a) { switch (_a.label) { case 0: destination = recipients[0]; value = values[0]; return [4 /*yield*/, this.options.transactionController.createTransaction(SubstrateTransaction_1.SubstrateTransactionType.TRANSFER, publicKey, 0, { to: destination && destination.length > 0 ? destination : publicKey, value: new bignumber_1.default(value) })]; case 1: transaction = _a.sent(); return [4 /*yield*/, this.options.transactionController.calculateTransactionFee(transaction)]; case 2: fee = _a.sent(); if (!fee) { return [2 /*return*/, Promise.reject('Could not fetch all necessary data.')]; } return [2 /*return*/, { low: fee.shiftedBy(-this.decimals).toFixed(), medium: fee.shiftedBy(-this.decimals).toFixed(), high: fee.shiftedBy(-this.decimals).toFixed() }]; } }); }); }; SubstrateProtocol.prototype.prepareTransactionFromPublicKey = function (publicKey, recipients, values, fee, data) { return __awaiter(this, void 0, void 0, function () { var recipientsWithValues, transferableBalance, totalValue, available, encoded; return __generator(this, function (_a) { switch (_a.label) { case 0: if (recipients.length !== values.length) { return [2 /*return*/, Promise.reject("Recipients length doesn't match values length.")]; } recipientsWithValues = recipients.map(function (recipient, index) { return [recipient, values[index]]; }); return [4 /*yield*/, this.options.accountController.getTransferableBalance(publicKey)]; case 1: transferableBalance = _a.sent(); totalValue = values.map(function (value) { return new bignumber_1.default(value); }).reduce(function (total, next) { return total.plus(next); }, new bignumber_1.default(0)); available = new bignumber_1.default(transferableBalance).minus(totalValue); return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, available, recipientsWithValues.map(function (_a) { var recipient = _a[0], value = _a[1]; return ({ type: SubstrateTransaction_1.SubstrateTransactionType.TRANSFER, tip: 0, args: { to: recipient, value: new bignumber_1.default(value) } }); }))]; case 2: encoded = _a.sent(); return [2 /*return*/, { encoded: encoded }]; } }); }); }; SubstrateProtocol.prototype.broadcastTransaction = function (encoded) { return __awaiter(this, void 0, void 0, function () { var txs, txHashes, error_1; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: txs = this.options.transactionController.decodeDetails(encoded).map(function (tx) { return tx.transaction; }); _a.label = 1; case 1: _a.trys.push([1, 3, , 4]); return [4 /*yield*/, Promise.all(txs.map(function (tx, index) { return _this.options.nodeClient.submitTransaction(tx.encode()).catch(function (error) { error.index = index; throw error; }); }))]; case 2: txHashes = _a.sent(); return [2 /*return*/, txs[0].type !== SubstrateTransaction_1.SubstrateTransactionType.SUBMIT_BATCH ? txHashes[0] : '']; case 3: error_1 = _a.sent(); console.warn("Transaction #" + error_1.index + " submit failure", error_1); return [2 /*return*/, Promise.reject("Error while submitting transaction #" + error_1.index + ": " + SubstrateTransaction_1.SubstrateTransactionType[txs[error_1.index].type] + ".")]; case 4: return [2 /*return*/]; } }); }); }; SubstrateProtocol.prototype.getDefaultDelegatee = function () { return __awaiter(this, void 0, void 0, function () { var validators; return __generator(this, function (_a) { switch (_a.label) { case 0: if (this.defaultValidator) { return [2 /*return*/, this.defaultValidator]; } return [4 /*yield*/, this.options.nodeClient.getValidators()]; case 1: validators = _a.sent(); return [2 /*return*/, validators ? validators[0].toString() : '']; } }); }); }; SubstrateProtocol.prototype.getCurrentDelegateesForPublicKey = function (publicKey) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.accountController.getCurrentValidators(publicKey)]; }); }); }; SubstrateProtocol.prototype.getCurrentDelegateesForAddress = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.accountController.getCurrentValidators(address)]; }); }); }; SubstrateProtocol.prototype.getDelegateeDetails = function (address) { return __awaiter(this, void 0, void 0, function () { var validatorDetails; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.getValidatorDetails(address)]; case 1: validatorDetails = _a.sent(); return [2 /*return*/, { name: validatorDetails.name || '', status: validatorDetails.status || '', address: address }]; } }); }); }; SubstrateProtocol.prototype.isPublicKeyDelegating = function (publicKey) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.accountController.isNominating(publicKey)]; }); }); }; SubstrateProtocol.prototype.isAddressDelegating = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.accountController.isNominating(address)]; }); }); }; SubstrateProtocol.prototype.getDelegatorDetailsFromPublicKey = function (publicKey) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.getDelegatorDetailsFromAddress; return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; SubstrateProtocol.prototype.getDelegatorDetailsFromAddress = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.options.accountController.getNominatorDetails(address)]; }); }); }; SubstrateProtocol.prototype.getDelegationDetailsFromPublicKey = function (publicKey, delegatees) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.getDelegationDetailsFromAddress; return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent(), delegatees])]; } }); }); }; SubstrateProtocol.prototype.getDelegationDetailsFromAddress = function (address, delegatees) { return __awaiter(this, void 0, void 0, function () { var _a, nominatorDetails, validatorsDetails; var _this = this; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, Promise.all([ this.options.accountController.getNominatorDetails(address, delegatees), Promise.all(delegatees.map(function (validator) { return _this.options.accountController.getValidatorDetails(validator); })) ])]; case 1: _a = _b.sent(), nominatorDetails = _a[0], validatorsDetails = _a[1]; nominatorDetails.rewards = nominatorDetails.delegatees.length > 0 && nominatorDetails.stakingDetails ? nominatorDetails.stakingDetails.rewards.map(function (reward) { return ({ index: reward.eraIndex, amount: reward.amount, timestamp: reward.timestamp }); }) : []; return [2 /*return*/, { delegator: nominatorDetails, delegatees: validatorsDetails }]; } }); }); }; // tslint:disable-next-line: cyclomatic-complexity SubstrateProtocol.prototype.prepareDelegatorActionFromPublicKey = function (publicKey, type, data) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { if (!data) { data = {}; } switch (type) { case SubstrateStakingActionType_1.SubstrateStakingActionType.BOND_NOMINATE: assert_1.assertFields(SubstrateStakingActionType_1.SubstrateStakingActionType[type] + " action", data, 'targets', 'value', 'payee'); return [2 /*return*/, this.prepareDelegation(publicKey, data.tip || 0, data.targets, data.controller || publicKey, data.value, data.payee)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.REBOND_NOMINATE: assert_1.assertFields(SubstrateStakingActionType_1.SubstrateStakingActionType[type] + " action", data, 'targets', 'value'); return [2 /*return*/, this.prepareRebondNominate(publicKey, data.tip || 0, data.targets, data.value)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.NOMINATE: assert_1.assertFields(SubstrateStakingActionType_1.SubstrateStakingActionType[type] + " action", data, 'targets'); return [2 /*return*/, this.prepareDelegation(publicKey, data.tip || 0, data.targets)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.CANCEL_NOMINATION: return [2 /*return*/, this.prepareCancelDelegation(publicKey, data.tip || 0, data.value)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.CHANGE_NOMINATION: assert_1.assertFields(SubstrateStakingActionType_1.SubstrateStakingActionType[type] + " action", data, 'targets'); return [2 /*return*/, this.prepareChangeValidator(publicKey, data.tip || 0, data.targets)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.UNBOND: assert_1.assertFields(SubstrateStakingActionType_1.SubstrateStakingActionType[type] + " action", data, 'value'); return [2 /*return*/, this.prepareUnbond(publicKey, data.tip || 0, data.value)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.REBOND: assert_1.assertFields(SubstrateStakingActionType_1.SubstrateStakingActionType[type] + " action", data, 'value'); return [2 /*return*/, this.prepareRebond(publicKey, data.tip || 0, data.value)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.BOND_EXTRA: assert_1.assertFields(SubstrateStakingActionType_1.SubstrateStakingActionType[type] + " action", data, 'value'); return [2 /*return*/, this.prepareBondExtra(publicKey, data.tip || 0, data.value)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.REBOND_EXTRA: assert_1.assertFields(SubstrateStakingActionType_1.SubstrateStakingActionType[type] + " action", data, 'value'); return [2 /*return*/, this.prepareRebondExtra(publicKey, data.tip || 0, data.value)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.WITHDRAW_UNBONDED: return [2 /*return*/, this.prepareWithdrawUnbonded(publicKey, data.tip || 0)]; case SubstrateStakingActionType_1.SubstrateStakingActionType.CHANGE_REWARD_DESTINATION: return [2 /*return*/, Promise.reject('Unsupported delegator action.')]; case SubstrateStakingActionType_1.SubstrateStakingActionType.CHANGE_CONTROLLER: return [2 /*return*/, Promise.reject('Unsupported delegator action.')]; default: return [2 /*return*/, Promise.reject('Unsupported delegator action.')]; } return [2 /*return*/]; }); }); }; SubstrateProtocol.prototype.prepareDelegation = function (publicKey, tip, targets, controller, value, payee) { return __awaiter(this, void 0, void 0, function () { var transferableBalance, available, bondFirst, encoded; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.getTransferableBalance(publicKey, false, false)]; case 1: transferableBalance = _a.sent(); available = new bignumber_1.default(transferableBalance).minus(value || 0); bondFirst = controller !== undefined && value !== undefined && payee !== undefined; return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, available, __spreadArrays((bondFirst ? [ { type: SubstrateTransaction_1.SubstrateTransactionType.BOND, tip: tip, args: { controller: controller, value: bignumber_1.default.isBigNumber(value) ? value : new bignumber_1.default(value), payee: typeof payee === 'string' ? SubstratePayee_1.SubstratePayee[payee] : payee } } ] : []), [ { type: SubstrateTransaction_1.SubstrateTransactionType.NOMINATE, tip: tip, args: { targets: typeof targets === 'string' ? [targets] : targets } } ]))]; case 2: encoded = _a.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.prepareRebondNominate = function (publicKey, tip, targets, value) { return __awaiter(this, void 0, void 0, function () { var _a, transferableBalance, lockedBalance, toDelegate, configs, encoded; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, Promise.all([ this.options.accountController.getTransferableBalance(publicKey, false, false), this.options.accountController.getUnlockingBalance(publicKey) ])]; case 1: _a = _b.sent(), transferableBalance = _a[0], lockedBalance = _a[1]; toDelegate = bignumber_1.default.isBigNumber(value) ? value : new bignumber_1.default(value); configs = []; if (toDelegate.gt(lockedBalance)) { configs.push({ type: SubstrateTransaction_1.SubstrateTransactionType.REBOND, tip: tip, args: { value: lockedBalance } }, { type: SubstrateTransaction_1.SubstrateTransactionType.BOND_EXTRA, tip: tip, args: { value: toDelegate.minus(lockedBalance) } }); } else { configs.push({ type: SubstrateTransaction_1.SubstrateTransactionType.REBOND, tip: tip, args: { value: toDelegate } }); } configs.push({ type: SubstrateTransaction_1.SubstrateTransactionType.NOMINATE, tip: tip, args: { targets: typeof targets === 'string' ? [targets] : targets } }); return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, transferableBalance, configs)]; case 2: encoded = _b.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.prepareCancelDelegation = function (publicKey, tip, value) { return __awaiter(this, void 0, void 0, function () { var transferableBalance, keepController, encoded; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.getTransferableBalance(publicKey, false, false)]; case 1: transferableBalance = _a.sent(); keepController = value === undefined; return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, transferableBalance, __spreadArrays([ { type: SubstrateTransaction_1.SubstrateTransactionType.CANCEL_NOMINATION, tip: tip, args: {} } ], (keepController ? [] : [ { type: SubstrateTransaction_1.SubstrateTransactionType.UNBOND, tip: tip, args: { value: bignumber_1.default.isBigNumber(value) ? value : new bignumber_1.default(value) } } ])))]; case 2: encoded = _a.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.prepareChangeValidator = function (publicKey, tip, targets) { return __awaiter(this, void 0, void 0, function () { var transferableBalance, encoded; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.getTransferableBalance(publicKey, false, false)]; case 1: transferableBalance = _a.sent(); return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, transferableBalance, [ { type: SubstrateTransaction_1.SubstrateTransactionType.NOMINATE, tip: tip, args: { targets: typeof targets === 'string' ? [targets] : targets } } ])]; case 2: encoded = _a.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.prepareUnbond = function (publicKey, tip, value) { return __awaiter(this, void 0, void 0, function () { var transferableBalance, encoded; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.getTransferableBalance(publicKey, false, false)]; case 1: transferableBalance = _a.sent(); return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, transferableBalance, [ { type: SubstrateTransaction_1.SubstrateTransactionType.UNBOND, tip: tip, args: { value: bignumber_1.default.isBigNumber(value) ? value : new bignumber_1.default(value) } } ])]; case 2: encoded = _a.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.prepareRebond = function (publicKey, tip, value) { return __awaiter(this, void 0, void 0, function () { var transferableBalance, encoded; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.getTransferableBalance(publicKey, false, false)]; case 1: transferableBalance = _a.sent(); return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, transferableBalance, [ { type: SubstrateTransaction_1.SubstrateTransactionType.REBOND, tip: tip, args: { value: bignumber_1.default.isBigNumber(value) ? value : new bignumber_1.default(value) } } ])]; case 2: encoded = _a.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.prepareBondExtra = function (publicKey, tip, value) { return __awaiter(this, void 0, void 0, function () { var transferableBalance, encoded; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.options.accountController.getTransferableBalance(publicKey, false, false)]; case 1: transferableBalance = _a.sent(); return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, transferableBalance, [ { type: SubstrateTransaction_1.SubstrateTransactionType.BOND_EXTRA, tip: tip, args: { value: bignumber_1.default.isBigNumber(value) ? value : new bignumber_1.default(value) } } ])]; case 2: encoded = _a.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.prepareRebondExtra = function (publicKey, tip, value) { return __awaiter(this, void 0, void 0, function () { var _a, transferableBalance, lockedBalance, toDelegate, configs, encoded; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, Promise.all([ this.options.accountController.getTransferableBalance(publicKey, false, false), this.options.accountController.getUnlockingBalance(publicKey) ])]; case 1: _a = _b.sent(), transferableBalance = _a[0], lockedBalance = _a[1]; toDelegate = bignumber_1.default.isBigNumber(value) ? value : new bignumber_1.default(value); configs = toDelegate.gt(lockedBalance) ? [ { type: SubstrateTransaction_1.SubstrateTransactionType.REBOND, tip: tip, args: { value: lockedBalance } }, { type: SubstrateTransaction_1.SubstrateTransactionType.BOND_EXTRA, tip: tip, args: { value: toDelegate.minus(lockedBalance) } }, ] : [{ type: SubstrateTransaction_1.SubstrateTransactionType.REBOND, tip: tip, args: { value: toDelegate } }]; return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, transferableBalance, configs)]; case 2: encoded = _b.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.prepareWithdrawUnbonded = function (publicKey, tip) { return __awaiter(this, void 0, void 0, function () { var _a, transferableBalance, slashingSpansNumber, encoded; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, Promise.all([ this.options.accountController.getTransferableBalance(publicKey, false, false), this.options.accountController.getSlashingSpansNumber(publicKey) ])]; case 1: _a = _b.sent(), transferableBalance = _a[0], slashingSpansNumber = _a[1]; return [4 /*yield*/, this.options.transactionController.prepareSubmittableTransactions(publicKey, transferableBalance, [ { type: SubstrateTransaction_1.SubstrateTransactionType.WITHDRAW_UNBONDED, tip: tip, args: { slashingSpansNumber: slashingSpansNumber } } ])]; case 2: encoded = _b.sent(); return [2 /*return*/, [{ encoded: encoded }]]; } }); }); }; SubstrateProtocol.prototype.estimateMaxDelegationValueFromAddress = function (address) { return __awaiter(this, void 0, void 0, function () { var results, transferableBalance, futureTransactions, feeEstimate, maxValue; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all([ this.options.accountController.getTransferableBalance(address, false, false), this.getFutureRequiredTransactions(address, 'delegate') ])]; case 1: results = _a.sent(); transferableBalance = results[0]; futureTransactions = results[1]; return [4 /*yield*/, this.options.transactionController.estimateTransactionFees(address, futureTransactions)]; case 2: feeEstimate = _a.sent(); if (!feeEstimate) { return [2 /*return*/, Promise.reject('Could not estimate max value.')]; } maxValue = transferableBalance.minus(feeEstimate); return [2 /*return*/, (maxValue.gte(0) ? maxValue : new bignumber_1.default(0)).toString(10)]; } }); }); }; SubstrateProtocol.prototype.getFutureRequiredTransactions = function (accountId, intention) { return __awaiter(this, void 0, void 0, function () { var results, isBonded, isNominating, transferableBalance, stakingBalance, unlockingBalance, isUnbonding, requiredTransactions; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, Promise.all([ this.options.accountController.isBonded(accountId), this.options.accountController.isNominating(accountId), this.options.accountController.getTransferableBalance(accountId), this.options.accountController.getTransferableBalance(accountId, false, false), this.options.accountController.getUnlockingBalance(accountId) ])]; case 1: