UNPKG

@onekeyfe/blockchain-libs

Version:
262 lines 11.3 kB
"use strict"; /* Copyright (c) 2019 Algorand, llc */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (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 (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __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.Transaction = exports.ALGORAND_MIN_TX_FEE = void 0; const hi_base32_1 = __importDefault(require("hi-base32")); const address = __importStar(require("./address")); const encoding = __importStar(require("./encoding")); const nacl = __importStar(require("./naclWrappers")); const types_1 = require("./types"); const utils = __importStar(require("./utils")); const ALGORAND_TRANSACTION_LENGTH = 52; exports.ALGORAND_MIN_TX_FEE = 1000; // version v5 const ALGORAND_TRANSACTION_LEASE_LENGTH = 32; const NUM_ADDL_BYTES_AFTER_SIGNING = 75; // NUM_ADDL_BYTES_AFTER_SIGNING is the number of bytes added to a txn after signing it /** * Transaction enables construction of Algorand transactions * */ class Transaction { constructor({ ...transaction }) { this.name = 'Transaction'; this.tag = Buffer.from('TX'); // Populate defaults const defaults = { type: types_1.TransactionType.pay, flatFee: false, nonParticipation: false, }; // Default type if (typeof transaction.type === 'undefined') { transaction.type = defaults.type; } // Default flatFee if (typeof transaction.flatFee === 'undefined') { transaction.flatFee = defaults.flatFee; } // Move suggested parameters from its object to inline if (transaction.suggestedParams !== undefined) { // Create a temporary reference to the transaction object that has params inline and also as a suggested params object // - Helpful for moving params from named object to inline const reference = transaction; reference.genesisHash = reference.suggestedParams.genesisHash; reference.fee = reference.suggestedParams.fee; if (reference.suggestedParams.flatFee !== undefined) reference.flatFee = reference.suggestedParams.flatFee; reference.firstRound = reference.suggestedParams.firstRound; reference.lastRound = reference.suggestedParams.lastRound; reference.genesisID = reference.suggestedParams.genesisID; } // At this point all suggestedParams have been moved to be inline, so we can reassign the transaction object type // to one which is more useful as we prepare properties for storing const txn = transaction; txn.from = address.decodeAddress(txn.from); if (txn.to !== undefined) txn.to = address.decodeAddress(txn.to); if (txn.closeRemainderTo !== undefined) txn.closeRemainderTo = address.decodeAddress(txn.closeRemainderTo); if (txn.assetRevocationTarget !== undefined) txn.assetRevocationTarget = address.decodeAddress(txn.assetRevocationTarget); if (txn.reKeyTo !== undefined) txn.reKeyTo = address.decodeAddress(txn.reKeyTo); if (txn.genesisHash === undefined) throw Error('genesis hash must be specified and in a base64 string.'); txn.genesisHash = Buffer.from(txn.genesisHash, 'base64'); if (txn.amount !== undefined && (!(Number.isSafeInteger(txn.amount) || (typeof txn.amount === 'bigint' && txn.amount <= BigInt('0xffffffffffffffff'))) || txn.amount < 0)) throw Error('Amount must be a positive number and smaller than 2^64-1'); if (!Number.isSafeInteger(txn.fee) || txn.fee < 0) throw Error('fee must be a positive number and smaller than 2^53-1'); if (!Number.isSafeInteger(txn.firstRound) || txn.firstRound < 0) throw Error('firstRound must be a positive number'); if (!Number.isSafeInteger(txn.lastRound) || txn.lastRound < 0) throw Error('lastRound must be a positive number'); if (txn.extraPages !== undefined && (!Number.isInteger(txn.extraPages) || txn.extraPages < 0 || txn.extraPages > 3)) throw Error('extraPages must be an Integer between and including 0 to 3'); if (txn.assetIndex !== undefined && (!Number.isSafeInteger(txn.assetIndex) || txn.assetIndex < 0)) throw Error('Asset index must be a positive number and smaller than 2^53-1'); if (txn.note !== undefined) { if (txn.note.constructor !== Uint8Array) throw Error('note must be a Uint8Array.'); } else { txn.note = new Uint8Array(0); } if (txn.lease !== undefined) { if (txn.lease.constructor !== Uint8Array) throw Error('lease must be a Uint8Array.'); if (txn.lease.length !== ALGORAND_TRANSACTION_LEASE_LENGTH) throw Error(`lease must be of length ${ALGORAND_TRANSACTION_LEASE_LENGTH.toString()}.`); if (txn.lease.every((value) => value === 0)) { // if lease contains all 0s, omit it txn.lease = new Uint8Array(0); } } else { txn.lease = new Uint8Array(0); } // Remove unwanted properties and store transaction on instance delete txn.suggestedParams; Object.assign(this, utils.removeUndefinedProperties(txn)); // Modify Fee if (!txn.flatFee) { this.fee *= this.estimateSize(); // If suggested fee too small and will be rejected, set to min tx fee if (this.fee < exports.ALGORAND_MIN_TX_FEE) { this.fee = exports.ALGORAND_MIN_TX_FEE; } } // say we are aware of groups this.group = undefined; } // eslint-disable-next-line camelcase get_obj_for_encoding() { var _a, _b, _c, _d; if (this.type === 'pay') { const txn = { amt: this.amount, fee: this.fee, fv: this.firstRound, lv: this.lastRound, note: Buffer.from(this.note), snd: Buffer.from(this.from.publicKey), type: 'pay', gen: this.genesisID, gh: this.genesisHash, lx: Buffer.from(this.lease), grp: this.group, }; // parse close address if (this.closeRemainderTo !== undefined && address.encodeAddress(this.closeRemainderTo.publicKey) !== address.ALGORAND_ZERO_ADDRESS_STRING) { txn.close = Buffer.from(this.closeRemainderTo.publicKey); } if (this.reKeyTo !== undefined) { txn.rekey = Buffer.from(this.reKeyTo.publicKey); } // allowed zero values if (this.to !== undefined) txn.rcv = Buffer.from(this.to.publicKey); if (!((_a = txn.note) === null || _a === void 0 ? void 0 : _a.length)) delete txn.note; if (!txn.amt) delete txn.amt; if (!txn.fee) delete txn.fee; if (!txn.fv) delete txn.fv; if (!txn.gen) delete txn.gen; if (txn.grp === undefined) delete txn.grp; if (!((_b = txn.lx) === null || _b === void 0 ? void 0 : _b.length)) delete txn.lx; if (!txn.rekey) delete txn.rekey; return txn; } if (this.type === 'axfer') { // asset transfer, acceptance, revocation, mint, or burn const txn = { aamt: this.amount, fee: this.fee, fv: this.firstRound, lv: this.lastRound, note: Buffer.from(this.note), snd: Buffer.from(this.from.publicKey), arcv: Buffer.from(this.to.publicKey), type: this.type, gen: this.genesisID, gh: this.genesisHash, lx: Buffer.from(this.lease), grp: this.group, xaid: this.assetIndex, }; if (this.closeRemainderTo !== undefined) txn.aclose = Buffer.from(this.closeRemainderTo.publicKey); if (this.assetRevocationTarget !== undefined) txn.asnd = Buffer.from(this.assetRevocationTarget.publicKey); // allowed zero values if (!((_c = txn.note) === null || _c === void 0 ? void 0 : _c.length)) delete txn.note; if (!((_d = txn.lx) === null || _d === void 0 ? void 0 : _d.length)) delete txn.lx; if (!txn.aamt) delete txn.aamt; if (!txn.amt) delete txn.amt; if (!txn.fee) delete txn.fee; if (!txn.fv) delete txn.fv; if (!txn.gen) delete txn.gen; if (txn.grp === undefined) delete txn.grp; if (!txn.aclose) delete txn.aclose; if (!txn.asnd) delete txn.asnd; if (!txn.rekey) delete txn.rekey; if (this.reKeyTo !== undefined) { txn.rekey = Buffer.from(this.reKeyTo.publicKey); } return txn; } return undefined; } estimateSize() { return this.toByte().length + NUM_ADDL_BYTES_AFTER_SIGNING; } bytesToSign() { const encodedMsg = this.toByte(); return Buffer.from(utils.concatArrays(this.tag, encodedMsg)); } toByte() { return encoding.encode(this.get_obj_for_encoding()); } rawTxID() { const enMsg = this.toByte(); const gh = Buffer.from(utils.concatArrays(this.tag, enMsg)); return Buffer.from(nacl.genericHash(gh)); } txID() { const hash = this.rawTxID(); return hi_base32_1.default.encode(hash).slice(0, ALGORAND_TRANSACTION_LENGTH); } } exports.Transaction = Transaction; exports.default = Transaction; //# sourceMappingURL=transaction.js.map