UNPKG

airgap-coin-lib

Version:

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

897 lines 47.1 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 __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 }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var BECH32 = require("../../dependencies/src/bech32-1.1.3/index"); var bignumber_1 = require("../../dependencies/src/bignumber.js-9.0.0/bignumber"); var index_1 = require("../../dependencies/src/bip32-2.0.4/src/index"); var index_2 = require("../../dependencies/src/bip39-2.5.0/index"); var RIPEMD160 = require("../../dependencies/src/ripemd160-2.0.2/index"); var SECP256K1 = require("../../dependencies/src/secp256k1-3.7.1/elliptic"); var sha = require("../../dependencies/src/sha.js-2.4.11/index"); var assert_1 = require("../../utils/assert"); var NonExtendedProtocol_1 = require("../NonExtendedProtocol"); var CosmosDelegateMessage_1 = require("./cosmos-message/CosmosDelegateMessage"); var CosmosMessage_1 = require("./cosmos-message/CosmosMessage"); var CosmosSendMessage_1 = require("./cosmos-message/CosmosSendMessage"); var CosmosWithdrawDelegationRewardMessage_1 = require("./cosmos-message/CosmosWithdrawDelegationRewardMessage"); var CosmosCoin_1 = require("./CosmosCoin"); var CosmosCryptoClient_1 = require("./CosmosCryptoClient"); var CosmosFee_1 = require("./CosmosFee"); var CosmosProtocolOptions_1 = require("./CosmosProtocolOptions"); var CosmosTransaction_1 = require("./CosmosTransaction"); var ProtocolSymbols_1 = require("../../utils/ProtocolSymbols"); var CosmosDelegationActionType; (function (CosmosDelegationActionType) { CosmosDelegationActionType["DELEGATE"] = "delegate"; CosmosDelegationActionType["UNDELEGATE"] = "undelegate"; CosmosDelegationActionType["WITHDRAW_ALL_REWARDS"] = "withdraw_all_rewards"; CosmosDelegationActionType["WITHDRAW_VALIDATOR_REWARDS"] = "withdraw_validator_rewards"; })(CosmosDelegationActionType = exports.CosmosDelegationActionType || (exports.CosmosDelegationActionType = {})); var CosmosProtocol = /** @class */ (function (_super) { __extends(CosmosProtocol, _super); function CosmosProtocol(options) { if (options === void 0) { options = new CosmosProtocolOptions_1.CosmosProtocolOptions(); } var _this = _super.call(this) || this; _this.options = options; _this.symbol = 'ATOM'; _this.name = 'Cosmos'; _this.marketSymbol = 'atom'; _this.feeSymbol = 'atom'; _this.feeDefaults = { low: '0.0005', medium: '0.005', high: '0.0075' }; _this.decimals = 6; _this.feeDecimals = 6; _this.identifier = ProtocolSymbols_1.MainProtocolSymbols.COSMOS; _this.units = [ { unitSymbol: 'atom', factor: '1' }, { unitSymbol: 'uatom', factor: '0.000001' } ]; _this.supportsHD = false; _this.standardDerivationPath = "m/44'/118'/0'/0/0"; _this.addressIsCaseSensitive = false; _this.addressValidationPattern = '^(cosmos|cosmosvaloper)[a-zA-Z0-9]{39}$'; _this.addressPlaceholder = 'cosmos...'; _this.addressPrefix = 'cosmos'; _this.defaultGas = new bignumber_1.default('200000'); return _this; } Object.defineProperty(CosmosProtocol.prototype, "infoClient", { get: function () { return this.options.config.infoClient; }, enumerable: true, configurable: true }); Object.defineProperty(CosmosProtocol.prototype, "nodeClient", { get: function () { return this.options.config.nodeClient; }, enumerable: true, configurable: true }); CosmosProtocol.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)]; }); }); }; CosmosProtocol.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)]; }); }); }; CosmosProtocol.prototype.generateKeyPair = function (mnemonic, derivationPath, password) { if (derivationPath === void 0) { derivationPath = this.standardDerivationPath; } index_2.validateMnemonic(mnemonic); var seed = index_2.mnemonicToSeed(mnemonic, password); var node = index_1.fromSeed(seed); return this.generateKeyPairFromNode(node, derivationPath); }; CosmosProtocol.prototype.generateKeyPairFromNode = function (node, derivationPath) { var keys = node.derivePath(derivationPath); var privateKey = keys.privateKey; if (privateKey === undefined) { throw new Error('Cannot generate private key'); } return { publicKey: keys.publicKey, privateKey: privateKey }; }; CosmosProtocol.prototype.getPublicKeyFromMnemonic = function (mnemonic, derivationPath, password) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.generateKeyPair(mnemonic, derivationPath, password).publicKey.toString('hex')]; }); }); }; CosmosProtocol.prototype.getPrivateKeyFromMnemonic = function (mnemonic, derivationPath, password) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.generateKeyPair(mnemonic, derivationPath, password).privateKey]; }); }); }; CosmosProtocol.prototype.getPublicKeyFromHexSecret = function (secret, derivationPath) { return __awaiter(this, void 0, void 0, function () { var node; return __generator(this, function (_a) { node = index_1.fromSeed(Buffer.from(secret, 'hex')); return [2 /*return*/, this.generateKeyPairFromNode(node, derivationPath).publicKey.toString('hex')]; }); }); }; CosmosProtocol.prototype.getPublicKeyFromPrivateKey = function (privateKey) { var publicKey = SECP256K1.publicKeyCreate(privateKey); return Buffer.from(publicKey, 'binary'); }; CosmosProtocol.prototype.getPrivateKeyFromHexSecret = function (secret, derivationPath) { return __awaiter(this, void 0, void 0, function () { var node; return __generator(this, function (_a) { node = index_1.fromSeed(Buffer.from(secret, 'hex')); return [2 /*return*/, this.generateKeyPairFromNode(node, derivationPath).privateKey]; }); }); }; CosmosProtocol.prototype.getAddressFromPublicKey = function (publicKey) { return __awaiter(this, void 0, void 0, function () { var pubkey, sha256Hash, hash, address; return __generator(this, function (_a) { pubkey = Buffer.from(publicKey, 'hex'); sha256Hash = sha('sha256').update(pubkey).digest(); hash = new RIPEMD160().update(Buffer.from(sha256Hash)).digest(); address = BECH32.encode(this.addressPrefix, BECH32.toWords(hash)); return [2 /*return*/, address]; }); }); }; CosmosProtocol.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()]]; } }); }); }; CosmosProtocol.prototype.getTransactionsFromPublicKey = function (publicKey, limit, cursor) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.getTransactionsFromAddresses; return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: return [2 /*return*/, _a.apply(this, [[_b.sent()], limit, cursor])]; } }); }); }; CosmosProtocol.prototype.getTransactionsFromAddresses = function (addresses, limit, cursor) { return __awaiter(this, void 0, void 0, function () { var promises, _i, addresses_1, address, transactions; return __generator(this, function (_a) { switch (_a.label) { case 0: promises = []; for (_i = 0, addresses_1 = addresses; _i < addresses_1.length; _i++) { address = addresses_1[_i]; promises.push(this.infoClient.fetchTransactions(this, address, limit, cursor)); } return [4 /*yield*/, Promise.all(promises).then(function (transactions) { return transactions.reduce(function (current, next) { return current.concat(next); }); })]; case 1: transactions = _a.sent(); return [2 /*return*/, { transactions: transactions, cursor: { offset: cursor ? (cursor.offset + limit) : limit } }]; } }); }); }; CosmosProtocol.prototype.signWithPrivateKey = function (privateKey, transaction) { return __awaiter(this, void 0, void 0, function () { var publicKey, toSign, sha256Hash, hash, signed, sigBase64, signedTransaction; return __generator(this, function (_a) { publicKey = this.getPublicKeyFromPrivateKey(privateKey); toSign = transaction.toRPCBody(); sha256Hash = sha('sha256') .update(Buffer.from(JSON.stringify(toSign))) .digest(); hash = Buffer.from(sha256Hash); signed = SECP256K1.sign(hash, privateKey); sigBase64 = Buffer.from(signed.signature, 'binary').toString('base64'); signedTransaction = { tx: { msg: toSign.msgs, fee: toSign.fee, signatures: [ { signature: sigBase64, pub_key: { type: 'tendermint/PubKeySecp256k1', value: publicKey.toString('base64') } } ], memo: toSign.memo }, mode: 'sync' }; return [2 /*return*/, JSON.stringify(signedTransaction)]; }); }); }; CosmosProtocol.prototype.getTransactionDetails = function (transaction) { return __awaiter(this, void 0, void 0, function () { var result; return __generator(this, function (_a) { result = transaction.transaction.toAirGapTransactions(this); return [2 /*return*/, result]; }); }); }; CosmosProtocol.prototype.getTransactionDetailsFromSigned = function (transaction) { return __awaiter(this, void 0, void 0, function () { var json, fee, result; var _this = this; return __generator(this, function (_a) { json = JSON.parse(transaction.transaction).tx; fee = json.fee.amount .map(function (_a) { var amount = _a.amount; return new bignumber_1.default(amount); }) .reduce(function (current, next) { return current.plus(next); }) .toString(10); result = json.msg .map(function (message) { var type = message.type; switch (type) { case CosmosMessage_1.CosmosMessageType.Send.value: var sendMessage = CosmosSendMessage_1.CosmosSendMessage.fromRPCBody(message); return sendMessage.toAirGapTransaction(_this, fee); case CosmosMessage_1.CosmosMessageType.Undelegate.value: case CosmosMessage_1.CosmosMessageType.Delegate.value: var delegateMessage = CosmosDelegateMessage_1.CosmosDelegateMessage.fromRPCBody(message); return delegateMessage.toAirGapTransaction(_this, fee); case CosmosMessage_1.CosmosMessageType.WithdrawDelegationReward.value: var withdrawMessage = CosmosWithdrawDelegationRewardMessage_1.CosmosWithdrawDelegationRewardMessage.fromRPCBody(message); return withdrawMessage.toAirGapTransaction(_this, fee); default: throw Error('Unknown transaction'); } }) .map(function (tx) { if (!tx.transactionDetails) { tx.transactionDetails = {}; } tx.transactionDetails.accountNumber = json.accountNumber; tx.transactionDetails.chainID = json.chainID; tx.transactionDetails.memo = json.memo; tx.transactionDetails.sequence = json.sequence; return tx; }); return [2 /*return*/, result]; }); }); }; CosmosProtocol.prototype.getBalanceOfAddresses = function (addresses) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.getBalance(addresses)]; }); }); }; CosmosProtocol.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()]])]; } }); }); }; CosmosProtocol.prototype.getAvailableBalanceOfAddresses = function (addresses) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.getBalance(addresses, false)]; }); }); }; CosmosProtocol.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'); }); }); }; CosmosProtocol.prototype.getBalance = function (addresses, totalBalance) { if (totalBalance === void 0) { totalBalance = true; } return __awaiter(this, void 0, void 0, function () { var promises, _i, addresses_2, address; return __generator(this, function (_a) { switch (_a.label) { case 0: promises = []; for (_i = 0, addresses_2 = addresses; _i < addresses_2.length; _i++) { address = addresses_2[_i]; promises.push(this.nodeClient.fetchBalance(address, totalBalance)); } return [4 /*yield*/, Promise.all(promises).then(function (balances) { return balances.reduce(function (current, next) { return current.plus(next); }); })]; case 1: return [2 /*return*/, (_a.sent()).toString(10)]; } }); }); }; CosmosProtocol.prototype.estimateMaxTransactionValueFromPublicKey = function (publicKey, recipients, fee) { return __awaiter(this, void 0, void 0, function () { var address, balance, balanceWrapper, maxFee, estimatedFeeDefaults, amountWithoutFees; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: address = _a.sent(); return [4 /*yield*/, this.getAvailableBalanceOfAddresses([address])]; case 2: balance = _a.sent(); balanceWrapper = new bignumber_1.default(balance); if (!(fee !== undefined)) return [3 /*break*/, 3]; maxFee = new bignumber_1.default(fee); return [3 /*break*/, 5]; case 3: return [4 /*yield*/, this.estimateFeeDefaultsFromPublicKey(publicKey, recipients, [balance])]; case 4: estimatedFeeDefaults = _a.sent(); maxFee = new bignumber_1.default(estimatedFeeDefaults.medium).shiftedBy(this.decimals); if (maxFee.gte(balanceWrapper)) { maxFee = new bignumber_1.default(0); } _a.label = 5; case 5: amountWithoutFees = balanceWrapper.minus(maxFee); if (amountWithoutFees.isNegative()) { amountWithoutFees = new bignumber_1.default(0); } return [2 /*return*/, amountWithoutFees.toFixed()]; } }); }); }; CosmosProtocol.prototype.estimateFeeDefaultsFromPublicKey = function (publicKey, recipients, values, data) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.feeDefaults]; }); }); }; CosmosProtocol.prototype.prepareTransactionFromPublicKey = function (publicKey, recipients, values, fee, data) { return __awaiter(this, void 0, void 0, function () { var wrappedValues, wrappedFee, address, nodeInfo, account, balance, _a, messages, i, message, memo, transaction; return __generator(this, function (_b) { switch (_b.label) { case 0: wrappedValues = values.map(function (value) { return new bignumber_1.default(value); }); wrappedFee = new bignumber_1.default(fee); if (recipients.length !== wrappedValues.length) { return [2 /*return*/, Promise.reject('recipients length does not match with values')]; } return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: address = _b.sent(); return [4 /*yield*/, this.nodeClient.fetchNodeInfo()]; case 2: nodeInfo = _b.sent(); return [4 /*yield*/, this.nodeClient.fetchAccount(address)]; case 3: account = _b.sent(); _a = bignumber_1.default.bind; return [4 /*yield*/, this.getAvailableBalanceOfAddresses([address])]; case 4: balance = new (_a.apply(bignumber_1.default, [void 0, _b.sent()]))(); if (balance.lt(values.reduce(function (pv, cv) { return pv.plus(cv); }, wrappedFee))) { throw new Error('not enough balance'); } messages = []; for (i = 0; i < recipients.length; ++i) { message = new CosmosSendMessage_1.CosmosSendMessage(address, recipients[i], [ new CosmosCoin_1.CosmosCoin('uatom', wrappedValues[i].toString(10)) ]); messages.push(message); } memo = data !== undefined && typeof data === 'string' ? data : ''; transaction = new CosmosTransaction_1.CosmosTransaction(messages, new CosmosFee_1.CosmosFee([new CosmosCoin_1.CosmosCoin('uatom', wrappedFee.toString(10))], this.defaultGas.toString(10)), memo, nodeInfo.network, account.value.account_number, account.value.sequence); return [2 /*return*/, transaction]; } }); }); }; CosmosProtocol.prototype.getDefaultDelegatee = function () { return __awaiter(this, void 0, void 0, function () { var validators; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.nodeClient.fetchValidators()]; case 1: validators = _a.sent(); return [2 /*return*/, validators.length > 0 ? validators[0].operator_address : '']; } }); }); }; CosmosProtocol.prototype.getCurrentDelegateesForPublicKey = function (publicKey) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.getCurrentDelegateesForAddress; return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; CosmosProtocol.prototype.getCurrentDelegateesForAddress = function (address) { return __awaiter(this, void 0, void 0, function () { var delegations; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.nodeClient.fetchDelegations(address)]; case 1: delegations = _a.sent(); return [2 /*return*/, delegations.map(function (delegation) { return delegation.validator_address; })]; } }); }); }; CosmosProtocol.prototype.getDelegateeDetails = function (address) { return __awaiter(this, void 0, void 0, function () { var validator, statusCodes; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.nodeClient.fetchValidator(address)]; case 1: validator = _a.sent(); statusCodes = { 0: 'jailed', 1: 'inactive', 2: 'active' }; return [2 /*return*/, { name: validator.description.moniker, status: statusCodes[validator.status], address: validator.operator_address }]; } }); }); }; CosmosProtocol.prototype.isPublicKeyDelegating = function (publicKey) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = this.isAddressDelegating; return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: return [2 /*return*/, _a.apply(this, [_b.sent()])]; } }); }); }; CosmosProtocol.prototype.isAddressDelegating = function (address) { return __awaiter(this, void 0, void 0, function () { var delegations; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.nodeClient.fetchDelegations(address)]; case 1: delegations = _a.sent(); return [2 /*return*/, delegations.length > 0]; } }); }); }; CosmosProtocol.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()])]; } }); }); }; CosmosProtocol.prototype.getDelegatorDetailsFromAddress = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.getDelegatorDetails(address)]; }); }); }; CosmosProtocol.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])]; } }); }); }; CosmosProtocol.prototype.getDelegationDetailsFromAddress = function (address, delegatees) { return __awaiter(this, void 0, void 0, function () { var validator, results, delegatorDetails, validatorDetails; return __generator(this, function (_a) { switch (_a.label) { case 0: if (delegatees.length > 1) { return [2 /*return*/, Promise.reject('Multiple validators for a single delegation are not supported.')]; } validator = delegatees[0]; return [4 /*yield*/, Promise.all([this.getDelegatorDetails(address, validator), this.getDelegateeDetails(validator)])]; case 1: results = _a.sent(); delegatorDetails = results[0]; validatorDetails = results[1]; return [2 /*return*/, { delegator: delegatorDetails, delegatees: [validatorDetails] }]; } }); }); }; CosmosProtocol.prototype.prepareDelegatorActionFromPublicKey = function (publicKey, type, data) { return __awaiter(this, void 0, void 0, function () { var _a; return __generator(this, function (_b) { switch (_b.label) { case 0: _a = type; switch (_a) { case CosmosDelegationActionType.DELEGATE: return [3 /*break*/, 1]; case CosmosDelegationActionType.UNDELEGATE: return [3 /*break*/, 3]; case CosmosDelegationActionType.WITHDRAW_ALL_REWARDS: return [3 /*break*/, 5]; case CosmosDelegationActionType.WITHDRAW_VALIDATOR_REWARDS: return [3 /*break*/, 7]; } return [3 /*break*/, 9]; case 1: assert_1.assertFields(CosmosDelegationActionType[type] + " action", data, 'validator', 'amount'); return [4 /*yield*/, this.delegate(publicKey, data.validator, data.amount)]; case 2: return [2 /*return*/, [_b.sent()]]; case 3: assert_1.assertFields(CosmosDelegationActionType[type] + " action", data, 'validator', 'amount'); return [4 /*yield*/, this.undelegate(publicKey, data.validator, data.amount)]; case 4: return [2 /*return*/, [_b.sent()]]; case 5: return [4 /*yield*/, this.withdrawDelegationRewards(publicKey)]; case 6: return [2 /*return*/, [_b.sent()]]; case 7: assert_1.assertFields(CosmosDelegationActionType[type] + " action", data, 'validator'); return [4 /*yield*/, this.withdrawDelegationRewards(publicKey, [data.validator])]; case 8: return [2 /*return*/, [_b.sent()]]; case 9: return [2 /*return*/, Promise.reject("Delegator action type " + type + " is not supported.")]; } }); }); }; CosmosProtocol.prototype.undelegate = function (publicKey, validatorAddress, amount, memo) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.delegate(publicKey, validatorAddress, amount, true, memo)]; }); }); }; CosmosProtocol.prototype.delegate = function (publicKey, validatorAddress, amount, undelegate, memo) { if (undelegate === void 0) { undelegate = false; } return __awaiter(this, void 0, void 0, function () { var address, nodeInfo, account, message; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 1: address = _a.sent(); return [4 /*yield*/, this.nodeClient.fetchNodeInfo()]; case 2: nodeInfo = _a.sent(); return [4 /*yield*/, this.nodeClient.fetchAccount(address)]; case 3: account = _a.sent(); message = new CosmosDelegateMessage_1.CosmosDelegateMessage(address, Array.isArray(validatorAddress) ? validatorAddress[0] : validatorAddress, new CosmosCoin_1.CosmosCoin('uatom', amount), undelegate); return [2 /*return*/, new CosmosTransaction_1.CosmosTransaction([message], new CosmosFee_1.CosmosFee([new CosmosCoin_1.CosmosCoin('uatom', new bignumber_1.default(this.feeDefaults.low).shiftedBy(this.feeDecimals).toString(10))], this.defaultGas.toString(10)), memo !== undefined ? memo : '', nodeInfo.network, account.value.account_number, account.value.sequence)]; } }); }); }; CosmosProtocol.prototype.withdrawDelegationRewards = function (publicKey, _validatorAddresses, memo) { if (_validatorAddresses === void 0) { _validatorAddresses = []; } return __awaiter(this, void 0, void 0, function () { var validatorAddresses, address_1, rewards, filteredRewards, address, nodeInfo, account, messages; return __generator(this, function (_a) { switch (_a.label) { case 0: if (!(_validatorAddresses.length > 0)) return [3 /*break*/, 1]; validatorAddresses = _validatorAddresses; return [3 /*break*/, 4]; case 1: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 2: address_1 = _a.sent(); return [4 /*yield*/, this.nodeClient.fetchRewardDetails(address_1)]; case 3: rewards = _a.sent(); filteredRewards = rewards.filter(function (reward) { return reward.reward .reduce(function (total, next) { return total.plus(new bignumber_1.default(next.amount)); }, new bignumber_1.default(0)) .decimalPlaces(0, bignumber_1.default.ROUND_FLOOR) .gt(0); }); validatorAddresses = filteredRewards.map(function (reward) { return reward.validator_address; }); _a.label = 4; case 4: return [4 /*yield*/, this.getAddressFromPublicKey(publicKey)]; case 5: address = _a.sent(); return [4 /*yield*/, this.nodeClient.fetchNodeInfo()]; case 6: nodeInfo = _a.sent(); return [4 /*yield*/, this.nodeClient.fetchAccount(address)]; case 7: account = _a.sent(); messages = validatorAddresses.map(function (validatorAddress) { return new CosmosWithdrawDelegationRewardMessage_1.CosmosWithdrawDelegationRewardMessage(address, validatorAddress); }); return [2 /*return*/, new CosmosTransaction_1.CosmosTransaction(messages, new CosmosFee_1.CosmosFee([new CosmosCoin_1.CosmosCoin('uatom', new bignumber_1.default(this.feeDefaults.low).shiftedBy(this.feeDecimals).toString(10))], this.defaultGas.toString(10)), memo !== undefined ? memo : '', nodeInfo.network, account.value.account_number, account.value.sequence)]; } }); }); }; CosmosProtocol.prototype.withdrawAllDelegationRewards = function (delegatorAddress, fee, memo) { return __awaiter(this, void 0, void 0, function () { var nodeInfo, account; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.nodeClient.fetchNodeInfo()]; case 1: nodeInfo = _a.sent(); return [4 /*yield*/, this.nodeClient.fetchAccount(delegatorAddress)]; case 2: account = _a.sent(); return [2 /*return*/, this.nodeClient.withdrawAllDelegationRewards(delegatorAddress, nodeInfo.network, account.value.account_number, account.value.sequence, this.defaultGas, fee, memo !== undefined ? memo : '')]; } }); }); }; CosmosProtocol.prototype.fetchTotalReward = function (delegatorAddress) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchTotalReward(delegatorAddress)]; }); }); }; CosmosProtocol.prototype.fetchRewardForDelegation = function (delegatorAddress, validatorAddress) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchRewardForDelegation(delegatorAddress, validatorAddress)]; }); }); }; CosmosProtocol.prototype.fetchDelegations = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchDelegations(address)]; }); }); }; CosmosProtocol.prototype.fetchTotalDelegatedAmount = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchTotalDelegatedAmount(address)]; }); }); }; CosmosProtocol.prototype.fetchValidator = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchValidator(address)]; }); }); }; CosmosProtocol.prototype.fetchUnbondingDelegations = function (delegatorAddress) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchUnbondingDelegations(delegatorAddress)]; }); }); }; CosmosProtocol.prototype.fetchTotalUnbondingAmount = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchTotalUnbondingAmount(address)]; }); }); }; CosmosProtocol.prototype.fetchValidators = function () { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchValidators()]; }); }); }; CosmosProtocol.prototype.fetchSelfDelegation = function (address) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.fetchSelfDelegation(address)]; }); }); }; CosmosProtocol.prototype.broadcastTransaction = function (rawTransaction) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, this.nodeClient.broadcastSignedTransaction(rawTransaction)]; }); }); }; CosmosProtocol.prototype.getDelegatorDetails = function (address, validator) { var _a; return __awaiter(this, void 0, void 0, function () { var results, totalBalance, availableBalance, delegations, rewardDetails, unclaimedRewards, unclaimedTotalRewards, unclaimedValidatorRewards, isDelegating, availableActions; return __generator(this, function (_b) { switch (_b.label) { case 0: return [4 /*yield*/, Promise.all([ this.getBalanceOfAddresses([address]), this.getAvailableBalanceOfAddresses([address]), this.nodeClient.fetchDelegations(address).catch(function () { return []; }), this.nodeClient.fetchRewardDetails(address).catch(function () { return []; }) ])]; case 1: results = _b.sent(); totalBalance = results[0]; availableBalance = new bignumber_1.default(results[1]); delegations = results[2]; rewardDetails = results[3]; unclaimedRewards = rewardDetails.map(function (details) { return [ details.validator_address, details.reward.reduce(function (total, next) { return total.plus(next.amount); }, new bignumber_1.default(0)).decimalPlaces(0, bignumber_1.default.ROUND_FLOOR) ]; }); unclaimedTotalRewards = unclaimedRewards.reduce(function (total, next) { return total.plus(next[1]); }, new bignumber_1.default(0)); unclaimedValidatorRewards = validator ? ((_a = unclaimedRewards.find(function (_a) { var validatorAddress = _a[0], _ = _a[1]; return validatorAddress === validator; })) === null || _a === void 0 ? void 0 : _a[1]) || new bignumber_1.default(0) : undefined; isDelegating = validator ? delegations.some(function (delegation) { return delegation.validator_address === validator; }) : delegations.length > 0; availableActions = this.getAvailableDelegatorActions(isDelegating, availableBalance, unclaimedTotalRewards, unclaimedValidatorRewards); return [2 /*return*/, { address: address, balance: totalBalance, delegatees: delegations.map(function (delegation) { return delegation.validator_address; }), availableActions: availableActions }]; } }); }); }; CosmosProtocol.prototype.getAvailableDelegatorActions = function (isDelegating, availableBalance, unclaimedTotalRewards, unclaimedDelegationRewards) { var _a; var actions = []; var requiredFee = new bignumber_1.default(this.feeDefaults.low).shiftedBy(this.feeDecimals); var hasSufficientBalance = availableBalance.gt(requiredFee); if (hasSufficientBalance) { actions.push({ type: CosmosDelegationActionType.DELEGATE, args: ['validator', 'amount'] }); } if (isDelegating) { actions.push({ type: CosmosDelegationActionType.UNDELEGATE, args: ['validator', 'amount'] }); } if (unclaimedTotalRewards.gt(0)) { actions.push({ type: CosmosDelegationActionType.WITHDRAW_ALL_REWARDS }); } if ((_a = unclaimedDelegationRewards) === null || _a === void 0 ? void 0 : _a.gt(0)) { actions.push({ type: CosmosDelegationActionType.WITHDRAW_VALIDATOR_REWARDS, args: ['validator'] }); } return actions; }; CosmosProtocol.prototype.signMessage = function (message, keypair) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, new CosmosCryptoClient_1.CosmosCryptoClient().signMessage(message, keypair)]; }); }); }; CosmosProtocol.prototype.verifyMessage = function (message, signature, publicKey) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, new CosmosCryptoClient_1.CosmosCryptoClient().verifyMessage(message, signature, publicKey)]; }); }); }; CosmosProtocol.prototype.getTransactionStatuses = function (transactionHashes) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { return [2 /*return*/, Promise.reject('Transaction status not implemented')]; }); }); }; return CosmosProtocol; }(NonExtendedProtocol_1.NonExtendedProtocol)); exports.CosmosProtocol = CosmosProtocol; //# sourceMappingURL=CosmosProtocol.js.map