@tatumio/tatum-v1
Version:
Tatum API client allows browsers and Node.js clients to interact with Tatum API.
735 lines • 74.4 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendEgldDeployNftTransaction = exports.sendEgldTransferNftTransaction = exports.sendEgldSmartContractMethodInvocationTransaction = exports.sendEgldDeployEsdtTransaction = exports.sendEgldTransaction = exports.sendEgldStoreDataTransaction = exports.prepareEgldSignedTransaction = exports.prepareEgldTransferNftSignedTransaction = exports.prepareEgldWipeNftSignedTransaction = exports.prepareEgldFreezeNftSignedTransaction = exports.prepareEgldAddOrBurnNftQuantitySignedTransaction = exports.prepareEgldStopNftCreateSignedTransaction = exports.prepareEgldTransferNftCreateRoleSignedTransaction = exports.prepareEgldCreateNftOrSftSignedTransaction = exports.prepareEgldDeployNftOrSftSignedTransaction = exports.prepareEgldControlChangesEsdtSignedTransaction = exports.prepareEgldFreezeOrWipeOrOwvershipEsdtSignedTransaction = exports.prepareEgldSpecialRoleEsdtOrNftSignedTransaction = exports.prepareEgldPauseEsdtSignedTransaction = exports.prepareEgldBurnEsdtSignedTransaction = exports.prepareEgldMintEsdtSignedTransaction = exports.prepareEgldTransferEsdtSignedTransaction = exports.prepareEgldDeployEsdtSignedTransaction = exports.egldGetTxsCount = exports.prepareEgldStoreDataTransaction = exports.signEgldKMSTransaction = exports.getEgldClient = exports.signEgldTransaction = exports.egldGetGasLimit = exports.egldGetGasPrice = exports.egldGetConfig = void 0;
const bignumber_js_1 = require("bignumber.js");
const erdjs_1 = require("@elrondnetwork/erdjs");
const blockchain_1 = require("../blockchain");
const tatum_1 = require("../connector/tatum");
const constants_1 = require("../constants");
const model_1 = require("../model");
const address_1 = require("../wallet/address");
const ELROND_V3_ENDPOINT = () => `${process.env.TATUM_API_URL || constants_1.TATUM_API_URL}/v3/egld/node/${process.env.TATUM_API_KEY}`;
/**
* Get Elrond network config
*/
const egldGetConfig = async (provider) => {
const client = exports.getEgldClient(provider);
try {
const { data } = await tatum_1.axios.get(`${client}/network/config`);
return data;
}
catch (e) {
console.error(e.toString());
}
return null;
};
exports.egldGetConfig = egldGetConfig;
/**
* Estimate Gas price for the transaction.
*/
const egldGetGasPrice = async (provider) => {
var _a, _b;
const { data } = await exports.egldGetConfig(provider);
const price = (_a = data === null || data === void 0 ? void 0 : data.config) === null || _a === void 0 ? void 0 : _a.erd_min_gas_price;
if (price) {
return price;
}
throw Error(((_b = data === null || data === void 0 ? void 0 : data.data) === null || _b === void 0 ? void 0 : _b.returnMessage) || 'egld.gasPrice.error');
};
exports.egldGetGasPrice = egldGetGasPrice;
/**
* Estimate Gas limit for the transaction.
*/
const egldGetGasLimit = async (tx, provider) => {
var _a, _b;
const client = exports.getEgldClient(provider);
const { data } = await tatum_1.axios.post(`${client}/transaction/cost`, tx);
const gas = (_a = data === null || data === void 0 ? void 0 : data.data) === null || _a === void 0 ? void 0 : _a.txGasUnits;
if (gas) {
return gas;
}
throw Error(((_b = data === null || data === void 0 ? void 0 : data.data) === null || _b === void 0 ? void 0 : _b.returnMessage) || 'egld.gasLimit.error');
};
exports.egldGetGasLimit = egldGetGasLimit;
/**
* Sign transaction
*/
const signEgldTransaction = async (tx, fromPrivateKey) => {
const fromAddrSigner = new erdjs_1.UserSigner(erdjs_1.UserSecretKey.fromString(fromPrivateKey));
fromAddrSigner.sign(tx);
return JSON.stringify(tx.toSendable());
};
exports.signEgldTransaction = signEgldTransaction;
/**
* Returns EGLD server to connect to.
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
*/
const getEgldClient = (provider) => (provider || ELROND_V3_ENDPOINT());
exports.getEgldClient = getEgldClient;
/**
* Sign EGLD pending transaction from Tatum KMS
* @param tx pending transaction from KMS
* @param fromPrivateKey private key to sign transaction with.
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const signEgldKMSTransaction = async (tx, fromPrivateKey, provider) => {
if (tx.chain !== model_1.Currency.EGLD) {
throw Error('Unsupported chain.');
}
const client = exports.getEgldClient(provider);
const transaction = JSON.parse(tx.serializedTransaction);
return await prepareSignedTransactionAbstraction(client, transaction, undefined, fromPrivateKey);
};
exports.signEgldKMSTransaction = signEgldKMSTransaction;
/**
* Sign EGLD Store data transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldStoreDataTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.CreateRecord);
const { fromPrivateKey, signatureId, from, data, } = body;
const client = exports.getEgldClient(provider);
const address = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
if (!address) {
throw new Error('Recipient must be provided.');
}
const tx = {
from: from || 0,
to: address,
value: '0',
data,
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldStoreDataTransaction = prepareEgldStoreDataTransaction;
/**
* Encode number for ESDT transaction
* @param n number or BigNumber
* @returns n as hex encoded string with an even number of characters
*/
const encodeNumber = (n) => {
const bn = new bignumber_js_1.BigNumber(n);
if (bn.isNaN()) {
return '';
}
const result = bn.toString(16).toLowerCase();
return `${(result.length % 2 ? '' : '0') + result}`;
};
/**
* Prepare properties for ESDT Issue transaction
* @param props content of the data transaction
* @returns props as encoded string
*/
const prepareProperties = (props) => {
if (!props) {
return '';
}
const keys = Object.keys(props);
const asHexTrue = '0x01'; // Buffer.from('true').toString('hex')
const asHexFalse = '0x'; // Buffer.from('false').toString('hex')
let result = '';
for (const k of keys) {
result += `@${Buffer.from(k).toString('hex')}@${props[k] ? asHexTrue : asHexFalse}`;
}
return result;
};
/**
* Prepare data for ESDT transactions
* @param data content of the data
* @returns data as string
*/
const prepareEgldEsdtIssuanceData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtIssue);
const tokenName = Buffer.from(data.name).toString('hex');
const tokenTicker = Buffer.from(data.symbol).toString('hex');
const initialSupply = encodeNumber(data.supply);
const decimals = encodeNumber(data.digits);
const properties = prepareProperties(data.properties);
return `${data.service}@${tokenName}@${tokenTicker}@${initialSupply}@${decimals}` + properties;
};
const prepareEgldEsdtTransferData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtTransfer);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const value = encodeNumber(data.value);
let args = '';
if (data.methodName) {
args += '@' + Buffer.from(data.methodName).toString('hex');
for (const k of data.arguments || []) {
if (new bignumber_js_1.BigNumber(k).isNaN()) {
args += `@${Buffer.from(k).toString('hex')}`;
}
else {
args += `@${encodeNumber(new bignumber_js_1.BigNumber(k))}`;
}
}
}
return `${data.service}@${tokenId}@${value}` + args;
};
const prepareEgldEsdtMintOrBurnData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtMint);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const supply = encodeNumber(data.supply);
return `${data.service}@${tokenId}@${supply}`;
};
const prepareEgldEsdtPauseData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtToken);
const tokenId = Buffer.from(data.tokenId).toString('hex');
return `${data.service}@${tokenId}`;
};
const prepareEgldEsdtFreezeOrWipeOrOwnershipData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtFreezeOrWipeOrOwnership);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const account = Buffer.from(data.account).toString('hex');
return `${data.service}@${tokenId}@${account}`;
};
const prepareEgldEsdtSpecialRoleData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtSpecialRole);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const account = Buffer.from(data.account).toString('hex');
let roles = '';
for (const k of data.role) {
roles += `@${Buffer.from(k).toString('hex')}`;
}
return `${data.service}@${tokenId}@${account}` + roles;
};
const prepareEgldEsdtControlChangesData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtControlChanges);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const properties = prepareProperties(data.properties);
return `${data.service}@${tokenId}` + properties;
};
const prepareEgldIssuanceNftOrSftData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtIssueNftOrSft);
const tokenName = Buffer.from(data.name).toString('hex');
const tokenTicker = Buffer.from(data.symbol).toString('hex');
const properties = prepareProperties(data.properties);
return `${data.service}@${tokenName}@${tokenTicker}` + properties;
};
const prepareEgldCreateNftOrSftData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtCreateNftOrSft);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const nftName = Buffer.from(data.nftName).toString('hex');
const quantity = encodeNumber(data.quantity);
const royalties = encodeNumber(new bignumber_js_1.BigNumber(data.royalties).multipliedBy(100));
const attributes = Buffer.from(data.attributes).toString('hex');
let uris = '';
for (const k of data.uri) {
uris += `@${Buffer.from(k).toString('hex')}`;
}
return `${data.service}@${tokenId}@${quantity}@${nftName}@${royalties}`
+ `@${data.hash}@${attributes}` + uris;
};
const prepareEgldTransferNftCreateRoleData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtTransferNftCreateRole);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const from = Buffer.from(data.from).toString('hex');
const to = Buffer.from(data.to).toString('hex');
return `${data.service}@${tokenId}@${from}@${to}`;
};
const prepareEgldStopNftCreateData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtToken);
const tokenId = Buffer.from(data.tokenId).toString('hex');
return `${data.service}@${tokenId}`;
};
const prepareEgldAddOrBurnNftQuantityData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtAddOrBurnNftQuantity);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const nonce = encodeNumber(data.nonce);
const quantity = encodeNumber(data.quantity);
return `${data.service}@${tokenId}@${nonce}@${quantity}`;
};
const prepareEgldFreezeOrWipeNftData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtFreezeOrWipeNft);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const nonce = encodeNumber(data.nonce);
const account = Buffer.from(data.account).toString('hex');
return `${data.service}@${tokenId}@${nonce}@${account}`;
};
const prepareEgldTransferNftData = async (data) => {
await tatum_1.validateBody(data, model_1.EsdtTransferNft);
const tokenId = Buffer.from(data.tokenId).toString('hex');
const nonce = encodeNumber(data.nonce);
const quantity = encodeNumber(data.quantity);
const to = Buffer.from(data.to).toString('hex');
let args = '';
if (data.methodName) {
args += '@' + Buffer.from(data.methodName).toString('hex');
for (const k of data.arguments || []) {
if (new bignumber_js_1.BigNumber(k).isNaN()) {
args += `@${Buffer.from(k).toString('hex')}`;
}
else {
args += `@${encodeNumber(new bignumber_js_1.BigNumber(k))}`;
}
}
}
return `${data.service}@${tokenId}@${nonce}@${quantity}@${to}` + args;
};
/**
* Sign transaction abstraction. Nothing is broadcast to the blockchain.
* @param client Web3 client of the EGLD Server to connect to. If not set, default public server will be used.
* @param transaction content of the transaction to broadcast
* @param signatureId signature ID
* @param fromPrivateKey private key
* @param fee Fee object
* @returns transaction data to be broadcast to blockchain.
*/
const prepareSignedTransactionAbstraction = async (client, transaction, signatureId, fromPrivateKey) => {
const sender = transaction.from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const { data } = await exports.egldGetConfig(client);
const { config } = data;
const gasPrice = (config === null || config === void 0 ? void 0 : config.erd_min_gas_price) || 1000000000;
const nonce = await exports.egldGetTxsCount(sender, client);
const egldTx = {
nonce,
value: new bignumber_js_1.BigNumber(transaction.value).isLessThan(0) ? '0' : new bignumber_js_1.BigNumber(transaction.value).multipliedBy(1e18).toFixed(),
receiver: transaction.to,
sender,
gasPrice,
gasLimit: 0,
data: transaction.data ? Buffer.from(transaction.data).toString('base64') : undefined,
chainID: config.erd_chain_id,
version: config.erd_min_transaction_version,
};
const gasLimit = await exports.egldGetGasLimit(egldTx, client);
egldTx.gasLimit = gasLimit;
if (signatureId) {
return JSON.stringify({
from: sender,
to: transaction.to,
value: transaction.value,
data: transaction.data,
gasPrice,
gasLimit,
});
}
const erdjsTransaction = new erdjs_1.Transaction({
nonce: new erdjs_1.Nonce(egldTx.nonce),
value: erdjs_1.Balance.fromString(egldTx.value),
receiver: new erdjs_1.Address(egldTx.receiver),
sender: new erdjs_1.Address(egldTx.sender),
gasPrice: new erdjs_1.GasPrice(egldTx.gasPrice),
gasLimit: new erdjs_1.GasLimit(egldTx.gasLimit),
data: transaction.data ? new erdjs_1.TransactionPayload(transaction.data) : undefined,
chainID: new erdjs_1.ChainID(egldTx.chainID),
version: new erdjs_1.TransactionVersion(egldTx.version),
});
return await exports.signEgldTransaction(erdjsTransaction, fromPrivateKey);
};
const egldGetTxsCount = async (address, client) => {
const { nonce } = (await tatum_1.axios.get(`${client}/address/${address}/nonce`, {
headers: { 'Content-Type': 'application/json' },
})).data.data;
return nonce;
};
exports.egldGetTxsCount = egldGetTxsCount;
/**
* Sign ESDT transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldDeployEsdtSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0.05;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
value,
data: await prepareEgldEsdtIssuanceData(Object.assign(Object.assign({}, data), { service: data.service || 'issue' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldDeployEsdtSignedTransaction = prepareEgldDeployEsdtSignedTransaction;
/**
* Sign ESDT transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldTransferEsdtSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, to, data, } = body;
const client = exports.getEgldClient(provider);
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to,
data: await prepareEgldEsdtTransferData(Object.assign(Object.assign({}, data), { service: data.service || 'ESDTTransfer' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldTransferEsdtSignedTransaction = prepareEgldTransferEsdtSignedTransaction;
/**
* Sign ESDT mint transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldMintEsdtSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, data, } = body;
const client = exports.getEgldClient(provider);
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
data: await prepareEgldEsdtMintOrBurnData(Object.assign(Object.assign({}, data), { service: data.service || 'mint' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldMintEsdtSignedTransaction = prepareEgldMintEsdtSignedTransaction;
/**
* Sign ESDT burn transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldBurnEsdtSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, data, } = body;
const client = exports.getEgldClient(provider);
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
data: await prepareEgldEsdtMintOrBurnData(Object.assign(Object.assign({}, data), { service: data.service || 'ESDTBurn' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldBurnEsdtSignedTransaction = prepareEgldBurnEsdtSignedTransaction;
/**
* Sign ESDT pause transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldPauseEsdtSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, data, } = body;
const client = exports.getEgldClient(provider);
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
data: await prepareEgldEsdtPauseData(Object.assign(Object.assign({}, data), { service: data.service || 'pause' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldPauseEsdtSignedTransaction = prepareEgldPauseEsdtSignedTransaction;
/**
* Sign ESDT special role transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldSpecialRoleEsdtOrNftSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, data, } = body;
const client = exports.getEgldClient(provider);
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
data: await prepareEgldEsdtSpecialRoleData(Object.assign(Object.assign({}, data), { service: data.service || 'setSpecialRole' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldSpecialRoleEsdtOrNftSignedTransaction = prepareEgldSpecialRoleEsdtOrNftSignedTransaction;
/**
* Sign ESDT freze | wipe | transfer ownership transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldFreezeOrWipeOrOwvershipEsdtSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, data, } = body;
const client = exports.getEgldClient(provider);
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
data: await prepareEgldEsdtFreezeOrWipeOrOwnershipData(Object.assign(Object.assign({}, data), { service: data.service || 'transferOwnership' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldFreezeOrWipeOrOwvershipEsdtSignedTransaction = prepareEgldFreezeOrWipeOrOwvershipEsdtSignedTransaction;
/**
* Sign ESDT control changes (upgrading props) transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldControlChangesEsdtSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, data, } = body;
const client = exports.getEgldClient(provider);
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
data: await prepareEgldEsdtControlChangesData(Object.assign(Object.assign({}, data), { service: data.service || 'controlChanges' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldControlChangesEsdtSignedTransaction = prepareEgldControlChangesEsdtSignedTransaction;
/**
* Sign ESDT issue transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldDeployNftOrSftSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0.05;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
// @ts-ignore
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
value,
data: await prepareEgldIssuanceNftOrSftData(Object.assign(Object.assign({}, data), { service: data.service || 'issueNonFungible' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldDeployNftOrSftSignedTransaction = prepareEgldDeployNftOrSftSignedTransaction;
/**
* Sign ESDT create NFT/SFT transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldCreateNftOrSftSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: sender,
value,
data: await prepareEgldCreateNftOrSftData(Object.assign(Object.assign({}, data), { service: data.service || 'ESDTNFTCreate' })),
};
// gas limit = 60000000 + (1500 * data.length) + (50000 * NFT size)
// const gasLimit = fee?.gasLimit ? fee.gasLimit : new BigNumber('60000000').plus((tx.data as string).length).multipliedBy(1500).toString()
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldCreateNftOrSftSignedTransaction = prepareEgldCreateNftOrSftSignedTransaction;
/**
* Sign ESDT transfer NFT create role transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldTransferNftCreateRoleSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
value,
data: await prepareEgldTransferNftCreateRoleData(Object.assign(Object.assign({}, data), { service: data.service || 'transferNFTCreateRole' })),
};
// gas limit = 60000000 + (1500 * data.length)
// const gasLimit = fee?.gasLimit ? fee.gasLimit : new BigNumber('60000000').plus((tx.data as string).length).multipliedBy(1500).toString()
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldTransferNftCreateRoleSignedTransaction = prepareEgldTransferNftCreateRoleSignedTransaction;
/**
* Sign ESDT stop NFT create transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldStopNftCreateSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
value,
data: await prepareEgldStopNftCreateData(Object.assign(Object.assign({}, data), { service: data.service || 'stopNFTCreate' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldStopNftCreateSignedTransaction = prepareEgldStopNftCreateSignedTransaction;
/**
* Sign ESDT Burn or Add quantity (SFT only) transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldAddOrBurnNftQuantitySignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: sender,
value,
data: await prepareEgldAddOrBurnNftQuantityData(Object.assign(Object.assign({}, data), { service: data.service || 'ESDTNFTBurn' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldAddOrBurnNftQuantitySignedTransaction = prepareEgldAddOrBurnNftQuantitySignedTransaction;
/**
* Sign ESDT freeze NFT transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldFreezeNftSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
value,
data: await prepareEgldFreezeOrWipeNftData(Object.assign(Object.assign({}, data), { service: data.service || 'freezeSingleNFT' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldFreezeNftSignedTransaction = prepareEgldFreezeNftSignedTransaction;
/**
* Sign ESDT freeze NFT transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldWipeNftSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: constants_1.ESDT_SYSTEM_SMART_CONTRACT_ADDRESS,
value,
data: await prepareEgldFreezeOrWipeNftData(Object.assign(Object.assign({}, data), { service: data.service || 'wipeSingleNFT' })),
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldWipeNftSignedTransaction = prepareEgldWipeNftSignedTransaction;
/**
* Sign ESDT transfer NFT transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldTransferNftSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, amount, data, } = body;
const client = exports.getEgldClient(provider);
const value = amount ? new bignumber_js_1.BigNumber(amount).toNumber() : 0;
const sender = from || await address_1.generateAddressFromPrivatekey(model_1.Currency.EGLD, false, fromPrivateKey);
const tx = {
from: sender,
to: sender,
value,
data: await prepareEgldTransferNftData(Object.assign(Object.assign({}, data), { service: data.service || 'ESDTNFTTransfer' })),
};
// TRANSFER: GasLimit: 1000000 + length of Data field in bytes * 1500
// TRANSFER TO SMART CONTRACT: GasLimit: 1000000 + extra for smart contract call
// const gasLimit = fee?.gasLimit ? fee.gasLimit : new BigNumber('1000000').plus((tx.data as string).length).multipliedBy(1500).toString()
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldTransferNftSignedTransaction = prepareEgldTransferNftSignedTransaction;
/**
* Sign EGLD transaction with private keys locally. Nothing is broadcast to the blockchain.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction data to be broadcast to blockchain.
*/
const prepareEgldSignedTransaction = async (body, provider) => {
await tatum_1.validateBody(body, model_1.EgldEsdtTransaction);
const { fromPrivateKey, signatureId, from, to, amount, data, } = body;
const client = exports.getEgldClient(provider);
const tx = {
from: from || 0,
to: to,
value: amount,
data,
};
return await prepareSignedTransactionAbstraction(client, tx, signatureId, fromPrivateKey);
};
exports.prepareEgldSignedTransaction = prepareEgldSignedTransaction;
/**
* Send EGLD store data transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
* This operation is irreversible.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction id of the transaction in the blockchain
*/
const sendEgldStoreDataTransaction = async (body, provider) => blockchain_1.egldBroadcast(await exports.prepareEgldStoreDataTransaction(body, provider), body.signatureId);
exports.sendEgldStoreDataTransaction = sendEgldStoreDataTransaction;
/**
* Send EGLD or supported ERC20 transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
* This operation is irreversible.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction id of the transaction in the blockchain
*/
const sendEgldTransaction = async (body, provider) => blockchain_1.egldBroadcast(await exports.prepareEgldSignedTransaction(body, provider), body.signatureId);
exports.sendEgldTransaction = sendEgldTransaction;
/**
* Send EGLD deploy ESDT transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
* This operation is irreversible.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction id of the transaction in the blockchain
*/
const sendEgldDeployEsdtTransaction = async (body, provider) => blockchain_1.egldBroadcast(await exports.prepareEgldDeployEsdtSignedTransaction(body, provider), body.signatureId);
exports.sendEgldDeployEsdtTransaction = sendEgldDeployEsdtTransaction;
/**
* Send EGLD invoke smart contract transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
* This operation is irreversible.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction id of the transaction in the blockchain
*/
const sendEgldSmartContractMethodInvocationTransaction = async (body, provider) => {
return blockchain_1.egldBroadcast(await exports.prepareEgldTransferEsdtSignedTransaction(body, provider), body.signatureId);
};
exports.sendEgldSmartContractMethodInvocationTransaction = sendEgldSmartContractMethodInvocationTransaction;
/**
* Send EGLD ERC721 transaction to the blockchain. This method broadcasts signed transaction to the blockchain.
* This operation is irreversible.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction id of the transaction in the blockchain
*/
const sendEgldTransferNftTransaction = async (body, provider) => blockchain_1.egldBroadcast(await exports.prepareEgldTransferNftSignedTransaction(body, provider), body.signatureId);
exports.sendEgldTransferNftTransaction = sendEgldTransferNftTransaction;
/**
* Send EGLD NFT deploy to the blockchain. This method broadcasts signed transaction to the blockchain.
* This operation is irreversible.
* @param body content of the transaction to broadcast
* @param provider url of the EGLD Server to connect to. If not set, default public server will be used.
* @returns transaction id of the transaction in the blockchain
*/
const sendEgldDeployNftTransaction = async (body, provider) => blockchain_1.egldBroadcast(await exports.prepareEgldDeployNftOrSftSignedTransaction(body, provider), body.signatureId);
exports.sendEgldDeployNftTransaction = sendEgldDeployNftTransaction;
// TODO: add ERC-1155 support
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZWdsZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy90cmFuc2FjdGlvbi9lZ2xkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtDQUF5QztBQUV6QyxnREFZOEI7QUFDOUIsOENBQThDO0FBQzlDLDhDQUF5RDtBQUN6RCw0Q0FBaUY7QUFDakYsb0NBb0JrQjtBQUNsQiwrQ0FBa0U7QUFFbEUsTUFBTSxrQkFBa0IsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsYUFBYSxJQUFJLHlCQUFhLGlCQUFpQixPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxDQUFDO0FBRTNIOztHQUVHO0FBQ0ksTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLFFBQWlCLEVBQUUsRUFBRTtJQUNyRCxNQUFNLE1BQU0sR0FBRyxxQkFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3ZDLElBQUk7UUFDQSxNQUFNLEVBQUMsSUFBSSxFQUFDLEdBQUcsTUFBTSxhQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsTUFBTSxpQkFBaUIsQ0FBQyxDQUFDO1FBQzNELE9BQU8sSUFBSSxDQUFBO0tBQ2Q7SUFBQyxPQUFPLENBQU0sRUFBRTtRQUNiLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUE7S0FDOUI7SUFDRCxPQUFPLElBQUksQ0FBQTtBQUNmLENBQUMsQ0FBQTtBQVRZLFFBQUEsYUFBYSxpQkFTekI7QUFFRDs7R0FFRztBQUNJLE1BQU0sZUFBZSxHQUFHLEtBQUssRUFBRSxRQUFpQixFQUFtQixFQUFFOztJQUMxRSxNQUFNLEVBQUUsSUFBSSxFQUFFLEdBQUcsTUFBTSxxQkFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9DLE1BQU0sS0FBSyxHQUFHLE1BQUEsSUFBSSxhQUFKLElBQUksdUJBQUosSUFBSSxDQUFFLE1BQU0sMENBQUUsaUJBQWlCLENBQUM7SUFDOUMs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