UNPKG

airgap-coin-lib

Version:

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

452 lines 26 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 }; } }; Object.defineProperty(exports, "__esModule", { value: true }); var bignumber_1 = require("../../../dependencies/src/bignumber.js-9.0.0/bignumber"); var hex_1 = require("../../../utils/hex"); var TezosProtocol_1 = require("../TezosProtocol"); var TezosUtils_1 = require("../TezosUtils"); var MichelsonPair_1 = require("../types/michelson/generics/MichelsonPair"); var MichelsonAddress_1 = require("../types/michelson/primitives/MichelsonAddress"); var MichelsonInt_1 = require("../types/michelson/primitives/MichelsonInt"); var MichelsonString_1 = require("../types/michelson/primitives/MichelsonString"); var TezosOperationType_1 = require("../types/TezosOperationType"); var utils_1 = require("../types/utils"); var TezosFAProtocol_1 = require("./TezosFAProtocol"); var MichelsonList_1 = require("../types/michelson/generics/MichelsonList"); var TezosFA2ContractEntrypoint; (function (TezosFA2ContractEntrypoint) { TezosFA2ContractEntrypoint["BALANCE"] = "balance_of"; TezosFA2ContractEntrypoint["TRANSFER"] = "transfer"; TezosFA2ContractEntrypoint["UPDATE_OPERATORS"] = "update_operators"; TezosFA2ContractEntrypoint["TOKEN_METADATA_REGISTRY"] = "token_metadata_registry"; TezosFA2ContractEntrypoint["TOKEN_METADATA"] = "token_metadata"; })(TezosFA2ContractEntrypoint || (TezosFA2ContractEntrypoint = {})); var TezosFA2Protocol = /** @class */ (function (_super) { __extends(TezosFA2Protocol, _super); function TezosFA2Protocol(options) { var _a, _b, _c; var _d, _e; var _this = _super.call(this, options) || this; _this.tokenID = options.config.tokenID; _this.tokenMetadataBigMapID = options.config.tokenMetadataBigMapID; _this.tokenMetadataBigMapName = (_d = options.config.tokenMetadataBigMapName, (_d !== null && _d !== void 0 ? _d : TezosFA2Protocol.DEFAULT_TOKEN_METADATA_BIG_MAP_NAME)); _this.tokenMedatadaBigMapValueRegex = (_e = options.config.tokenMetadataBigMapRegex, (_e !== null && _e !== void 0 ? _e : TezosFA2Protocol.DEFAULT_TOKEN_METADATA_BIG_MAP_VALUE_REGEX)); _this.defaultCallbackContract = (_a = {}, _a[TezosProtocol_1.TezosNetwork.MAINNET] = (_b = {}, _b[TezosFA2ContractEntrypoint.BALANCE] = 'KT1LyHDYnML5eCuTEVCTynUpivwG6ns6khiG', _b[TezosFA2ContractEntrypoint.TOKEN_METADATA_REGISTRY] = 'KT1L16VBmW8tkovhLmonhfvf6dtTZya6k6af', _b), _a[TezosProtocol_1.TezosNetwork.DELPHINET] = (_c = {}, _c[TezosFA2ContractEntrypoint.BALANCE] = 'KT1LQRsAjvUmP4PQi5WXGFyGWPWwbevCLuiw', _c[TezosFA2ContractEntrypoint.TOKEN_METADATA_REGISTRY] = 'KT1VnbvGMNg21xGDqJtW2UkzHyyAB21GV4oy', _c), _a); return _this; } TezosFA2Protocol.prototype.getBalanceOfAddresses = function (addresses) { return __awaiter(this, void 0, void 0, function () { var tokenID, results; return __generator(this, function (_a) { switch (_a.label) { case 0: tokenID = this.tokenID; if (tokenID === undefined) { throw new Error("Can't check the balance, no tokenID has been provided."); } return [4 /*yield*/, this.balanceOf(addresses.map(function (address) { return { address: address, tokenID: tokenID }; }, this.defaultSourceAddress))]; case 1: results = _a.sent(); return [2 /*return*/, results.reduce(function (sum, next) { return sum.plus(next.amount); }, new bignumber_1.default(0)).toFixed()]; } }); }); }; TezosFA2Protocol.prototype.estimateFeeDefaultsFromPublicKey = function (publicKey, recipients, values, data) { return __awaiter(this, void 0, void 0, function () { var transferCall, operation; return __generator(this, function (_a) { switch (_a.label) { case 0: // return this.feeDefaults if (recipients.length !== values.length) { throw new Error('length of recipients and values does not match!'); } return [4 /*yield*/, this.createTransferCall(publicKey, recipients, values, this.feeDefaults.medium, data)]; case 1: transferCall = _a.sent(); operation = { kind: TezosOperationType_1.TezosOperationType.TRANSACTION, amount: '0', destination: this.contractAddress, parameters: transferCall.toJSON(), fee: '0' }; return [2 /*return*/, this.estimateFeeDefaultsForOperations(publicKey, [operation])]; } }); }); }; TezosFA2Protocol.prototype.prepareTransactionFromPublicKey = function (publicKey, recipients, values, fee, data) { return __awaiter(this, void 0, void 0, function () { var transferCall; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.createTransferCall(publicKey, recipients, values, fee, data)]; case 1: transferCall = _a.sent(); return [2 /*return*/, this.prepareContractCall([transferCall], fee, publicKey)]; } }); }); }; TezosFA2Protocol.prototype.transactionDetailsFromParameters = function (parameters) { var _this = this; var defaultDetails = { extra: { type: parameters.entrypoint } }; if (parameters.entrypoint !== TezosFA2ContractEntrypoint.TRANSFER) { console.warn('Only calls to the transfer entrypoint can be converted to IAirGapTransaction'); return [defaultDetails]; } try { var callArgumentsList = MichelsonList_1.MichelsonList.from(parameters.value, function (pairJSON) { return MichelsonPair_1.MichelsonPair.from(pairJSON, function (fromJSON) { return MichelsonAddress_1.MichelsonAddress.from(fromJSON, 'from_'); }, function (txsJSON) { return MichelsonList_1.MichelsonList.from(txsJSON, function (pairJSON) { return MichelsonPair_1.MichelsonPair.from(pairJSON, function (toJSON) { return MichelsonAddress_1.MichelsonAddress.from(toJSON, 'to_'); }, function (pairJSON) { return MichelsonPair_1.MichelsonPair.from(pairJSON, function (tokenJSON) { return MichelsonInt_1.MichelsonInt.from(tokenJSON, 'token_id'); }, function (amountJSON) { return MichelsonInt_1.MichelsonInt.from(amountJSON, 'amount'); }); }); }, 'txs'); }); }).asRawValue(); return Array.isArray(callArgumentsList) ? callArgumentsList.map(function (callArguments) { if (!_this.isTransferRequest(callArguments)) { return []; } var from = hex_1.isHex(callArguments.from_) ? TezosUtils_1.TezosUtils.parseAddress(callArguments.from_) : callArguments.from_; var transferDetails = callArguments.txs.map(function (tx) { var to = hex_1.isHex(tx.to_) ? TezosUtils_1.TezosUtils.parseAddress(tx.to_) : tx.to_; return [to, tx.token_id, tx.amount]; }); return transferDetails.map(function (_a) { var to = _a[0], tokenID = _a[1], amount = _a[2]; return __assign(__assign({}, defaultDetails), { amount: amount.toFixed(), from: [from], to: [to], extra: { type: parameters.entrypoint, assetID: (_this.tokenID === undefined || !tokenID.eq(_this.tokenID)) ? tokenID.toString() : undefined } }); }); }).reduce(function (flatten, next) { return flatten.concat(next); }, []) : [defaultDetails]; } catch (_a) { return [defaultDetails]; } }; TezosFA2Protocol.prototype.balanceOf = function (balanceRequests, source, callbackContract) { if (callbackContract === void 0) { callbackContract = this.callbackContract(TezosFA2ContractEntrypoint.BALANCE); } return __awaiter(this, void 0, void 0, function () { var balanceOfCall, results; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.contract.createContractCall(TezosFA2ContractEntrypoint.BALANCE, { requests: balanceRequests.map(function (request) { return { owner: request.address, token_id: request.tokenID }; }), callback: callbackContract })]; case 1: balanceOfCall = _a.sent(); return [4 /*yield*/, this.runContractCall(balanceOfCall, this.requireSource(source))]; case 2: results = _a.sent(); if (utils_1.isMichelineSequence(results)) { return [2 /*return*/, results.map(function (node) { try { var pair = MichelsonPair_1.MichelsonPair.from(node, function (value) { return MichelsonPair_1.MichelsonPair.from(value, MichelsonAddress_1.MichelsonAddress.from, MichelsonInt_1.MichelsonInt.from); }, MichelsonInt_1.MichelsonInt.from); var accountWithTokenID = MichelsonPair_1.MichelsonPair.from(pair.first.get()); var account = MichelsonAddress_1.MichelsonAddress.from(accountWithTokenID.first.get()); var tokenID = MichelsonInt_1.MichelsonInt.from(accountWithTokenID.second.get()); var amount = MichelsonInt_1.MichelsonInt.from(pair.second.get()); return { address: account.address instanceof MichelsonString_1.MichelsonString ? account.address.value : TezosUtils_1.TezosUtils.parseAddress(account.address.value), tokenID: tokenID.value.toNumber(), amount: amount.value.toFixed() }; } catch (error) { console.warn(error); return undefined; } }).filter(function (balanceOfResults) { return balanceOfResults !== undefined; })]; } else { return [2 /*return*/, []]; } return [2 /*return*/]; } }); }); }; TezosFA2Protocol.prototype.transfer = function (transferRequests, fee, publicKey) { return __awaiter(this, void 0, void 0, function () { var transferCall; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.contract.createContractCall(TezosFA2ContractEntrypoint.TRANSFER, transferRequests.map(function (request) { return { from_: request.from, txs: request.txs.map(function (tx) { return { to_: tx.to, token_id: tx.tokenID, amount: tx.amount }; }) }; }))]; case 1: transferCall = _a.sent(); return [2 /*return*/, this.prepareContractCall([transferCall], fee, publicKey)]; } }); }); }; TezosFA2Protocol.prototype.updateOperators = function (updateRequests, fee, publicKey) { return __awaiter(this, void 0, void 0, function () { var updateCall; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.contract.createContractCall(TezosFA2ContractEntrypoint.UPDATE_OPERATORS, updateRequests.map(function (request) { var _a; var args = (_a = {}, _a[request.operation + "_operator"] = { owner: request.owner, operator: request.operator, token_id: request.tokenId }, _a); return [request.operation === 'add' ? 'Left' : 'Right', args]; }))]; case 1: updateCall = _a.sent(); return [2 /*return*/, this.prepareContractCall([updateCall], fee, publicKey)]; } }); }); }; TezosFA2Protocol.prototype.tokenMetadataRegistry = function (source, callbackContract) { if (callbackContract === void 0) { callbackContract = this.callbackContract(TezosFA2ContractEntrypoint.TOKEN_METADATA_REGISTRY); } return __awaiter(this, void 0, void 0, function () { var tokenMetadataRegistryCall, result; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.contract.createContractCall(TezosFA2ContractEntrypoint.TOKEN_METADATA_REGISTRY, callbackContract)]; case 1: tokenMetadataRegistryCall = _a.sent(); return [4 /*yield*/, this.runContractCall(tokenMetadataRegistryCall, this.requireSource(source)).catch(function () { return []; })]; case 2: result = _a.sent(); if (utils_1.isMichelinePrimitive('string', result)) { return [2 /*return*/, result.string]; } else if (utils_1.isMichelinePrimitive('bytes', result)) { return [2 /*return*/, TezosUtils_1.TezosUtils.parseAddress(result.bytes)]; } else { return [2 /*return*/, '']; } return [2 /*return*/]; } }); }); }; TezosFA2Protocol.prototype.tokenMetadata = function (tokenIDs, handler, fee, publicKey) { return __awaiter(this, void 0, void 0, function () { var tokenMetadataCall; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.contract.createContractCall(TezosFA2ContractEntrypoint.TOKEN_METADATA, { token_ids: tokenIDs, handler: handler })]; case 1: tokenMetadataCall = _a.sent(); return [2 /*return*/, this.prepareContractCall([tokenMetadataCall], fee, publicKey)]; } }); }); }; TezosFA2Protocol.prototype.getTokenMetadata = function (tokenIDs) { return __awaiter(this, void 0, void 0, function () { var metadataResponse; var _this = this; return __generator(this, function (_a) { switch (_a.label) { case 0: return [4 /*yield*/, this.contract.bigMapValues({ bigMapID: this.tokenMetadataBigMapID, predicates: tokenIDs ? [ { field: 'key', operation: 'in', set: tokenIDs } ] : undefined })]; case 1: metadataResponse = _a.sent(); return [2 /*return*/, metadataResponse .map(function (response) { var match = response.value ? _this.tokenMedatadaBigMapValueRegex.exec(response.value) : null; return match && _this.isTokenMetadata(match.groups) ? { tokenID: new bignumber_1.default(match.groups.tokenID).toNumber(), symbol: match.groups.symbol, name: match.groups.name, decimals: new bignumber_1.default(match.groups.decimals).toNumber(), extras: match.groups.extras } : null; }) .filter(function (metadata) { return metadata !== null; })]; } }); }); }; TezosFA2Protocol.prototype.fetchTokenHolders = function (tokenIDs) { return __awaiter(this, void 0, void 0, function () { return __generator(this, function (_a) { // there is no standard way to fetch token holders for now, every subclass needs to implement its own logic return [2 /*return*/, []]; }); }); }; TezosFA2Protocol.prototype.createTransferCall = function (publicKey, recipients, values, fee, data) { return __awaiter(this, void 0, void 0, function () { var addressIndex, tokenID, addresses, fromAddress, recipientsWithValues, transferCall; return __generator(this, function (_a) { switch (_a.label) { case 0: if (recipients.length !== values.length) { throw new Error('length of recipients and values does not match!'); } addressIndex = data && data.addressIndex !== undefined ? data.addressIndex : 0; tokenID = data && data.tokenID !== undefined ? data.tokenID : 0; return [4 /*yield*/, this.getAddressesFromPublicKey(publicKey)]; case 1: addresses = _a.sent(); if (!addresses[addressIndex]) { throw new Error('no kt-address with this index exists'); } fromAddress = addresses[addressIndex]; recipientsWithValues = recipients.map(function (recipient, index) { return [recipient, values[index]]; }); return [4 /*yield*/, this.contract.createContractCall(TezosFA2ContractEntrypoint.TRANSFER, [ { from_: fromAddress, txs: recipientsWithValues.map(function (_a) { var recipient = _a[0], value = _a[1]; return { to_: recipient, token_id: tokenID, amount: value }; }) } ])]; case 2: transferCall = _a.sent(); return [2 /*return*/, transferCall]; } }); }); }; TezosFA2Protocol.prototype.callbackContract = function (entrypoint) { var networkCallbacks = this.defaultCallbackContract[this.options.network.extras.network]; var callback = networkCallbacks ? networkCallbacks[entrypoint] : undefined; return (callback !== null && callback !== void 0 ? callback : ''); }; TezosFA2Protocol.prototype.isTransferRequest = function (obj) { var anyObj = obj; return (anyObj instanceof Object && typeof anyObj.from_ === 'string' && Array.isArray(anyObj.txs) && anyObj.txs.every(function (tx) { return tx instanceof Object && typeof tx.to_ === 'string' && bignumber_1.default.isBigNumber(tx.token_id) && bignumber_1.default.isBigNumber(tx.amount); })); }; TezosFA2Protocol.prototype.isTokenMetadata = function (obj) { return (typeof obj === 'object' && obj !== null && 'tokenID' in obj && 'symbol' in obj && 'name' in obj && 'decimals' in obj); }; TezosFA2Protocol.DEFAULT_TOKEN_METADATA_BIG_MAP_NAME = 'token_metadata'; TezosFA2Protocol.DEFAULT_TOKEN_METADATA_BIG_MAP_VALUE_REGEX = /Pair\s\(Pair\s(?<tokenID>\d+)\s\(Pair\s\"(?<symbol>\w*)\"\s\(Pair\s\"(?<name>\w*)\"\s\(Pair\s(?<decimals>\d*)\s\{(?<extras>.*)\}\)\)\)\)/; // temporary until we get Micheline JSON from the API return TezosFA2Protocol; }(TezosFAProtocol_1.TezosFAProtocol)); exports.TezosFA2Protocol = TezosFA2Protocol; //# sourceMappingURL=TezosFA2Protocol.js.map