@tatumio/tatum-v1
Version:
Tatum API client allows browsers and Node.js clients to interact with Tatum API.
526 lines • 58.6 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.sendApproveFromCustodialWallet = exports.prepareApproveFromCustodialWallet = exports.sendBatchTransferFromCustodialWallet = exports.prepareBatchTransferFromCustodialWallet = exports.sendTransferFromCustodialWallet = exports.prepareTransferFromCustodialWallet = exports.sendCustodialWallet = exports.prepareCustodialWalletBatch = exports.generateCustodialWalletBatch = exports.prepareCustodialWallet = exports.generateCustodialWallet = exports.getCustodialAddresses = exports.obtainCustodialAddressType = void 0;
const bignumber_js_1 = __importDefault(require("bignumber.js"));
const blockchain_1 = require("../blockchain");
const tatum_1 = require("../connector/tatum");
const constants_1 = require("../constants");
const custodial_1 = require("../contracts/custodial");
const fungible_1 = require("../fungible");
const helpers_1 = require("../helpers");
const model_1 = require("../model");
const transaction_1 = require("../transaction");
const generateBatch = (body) => tatum_1.post('/v3/blockchain/sc/custodial/batch', body);
const obtainCustodialAddressType = (body) => {
if (body.chain === model_1.Currency.TRON && body.enableSemiFungibleTokens) {
throw new Error('MultiToken not supported for TRON.');
}
let abi;
let code;
if (body.enableFungibleTokens && body.enableNonFungibleTokens && body.enableSemiFungibleTokens && body.enableBatchTransactions) {
code = custodial_1.CustodialFullTokenWalletWithBatch.bytecode;
abi = custodial_1.CustodialFullTokenWalletWithBatch.abi;
}
else if (body.enableFungibleTokens && body.enableNonFungibleTokens && body.enableSemiFungibleTokens && !body.enableBatchTransactions) {
code = custodial_1.CustodialFullTokenWallet.bytecode;
abi = custodial_1.CustodialFullTokenWallet.abi;
}
else if (body.enableFungibleTokens && body.enableNonFungibleTokens && !body.enableSemiFungibleTokens && body.enableBatchTransactions) {
code = custodial_1.Custodial_20_721_TokenWalletWithBatch.bytecode;
abi = custodial_1.Custodial_20_721_TokenWalletWithBatch.abi;
}
else if (body.enableFungibleTokens && body.enableNonFungibleTokens && !body.enableSemiFungibleTokens && !body.enableBatchTransactions) {
code = custodial_1.Custodial_20_721_TokenWallet.bytecode;
abi = custodial_1.Custodial_20_721_TokenWallet.abi;
}
else if (body.enableFungibleTokens && !body.enableNonFungibleTokens && body.enableSemiFungibleTokens && body.enableBatchTransactions) {
code = custodial_1.Custodial_20_1155_TokenWalletWithBatch.bytecode;
abi = custodial_1.Custodial_20_1155_TokenWalletWithBatch.abi;
}
else if (body.enableFungibleTokens && !body.enableNonFungibleTokens && body.enableSemiFungibleTokens && !body.enableBatchTransactions) {
code = custodial_1.Custodial_20_1155_TokenWallet.bytecode;
abi = custodial_1.Custodial_20_1155_TokenWallet.abi;
}
else if (!body.enableFungibleTokens && body.enableNonFungibleTokens && body.enableSemiFungibleTokens && body.enableBatchTransactions) {
code = custodial_1.Custodial_721_1155_TokenWalletWithBatch.bytecode;
abi = custodial_1.Custodial_721_1155_TokenWalletWithBatch.abi;
}
else if (!body.enableFungibleTokens && body.enableNonFungibleTokens && body.enableSemiFungibleTokens && !body.enableBatchTransactions) {
code = custodial_1.Custodial_721_1155_TokenWallet.bytecode;
abi = custodial_1.Custodial_721_1155_TokenWallet.abi;
}
else if (body.enableFungibleTokens && !body.enableNonFungibleTokens && !body.enableSemiFungibleTokens && body.enableBatchTransactions) {
code = custodial_1.Custodial_20_TokenWalletWithBatch.bytecode;
abi = custodial_1.Custodial_20_TokenWalletWithBatch.abi;
}
else if (body.enableFungibleTokens && !body.enableNonFungibleTokens && !body.enableSemiFungibleTokens && !body.enableBatchTransactions) {
code = custodial_1.Custodial_20_TokenWallet.bytecode;
abi = custodial_1.Custodial_20_TokenWallet.abi;
}
else if (!body.enableFungibleTokens && body.enableNonFungibleTokens && !body.enableSemiFungibleTokens && body.enableBatchTransactions) {
code = custodial_1.Custodial_721_TokenWalletWithBatch.bytecode;
abi = custodial_1.Custodial_721_TokenWalletWithBatch.abi;
}
else if (!body.enableFungibleTokens && body.enableNonFungibleTokens && !body.enableSemiFungibleTokens && !body.enableBatchTransactions) {
code = custodial_1.Custodial_721_TokenWallet.bytecode;
abi = custodial_1.Custodial_721_TokenWallet.abi;
}
else if (!body.enableFungibleTokens && !body.enableNonFungibleTokens && body.enableSemiFungibleTokens && body.enableBatchTransactions) {
code = custodial_1.Custodial_1155_TokenWalletWithBatch.bytecode;
abi = custodial_1.Custodial_1155_TokenWalletWithBatch.abi;
}
else if (!body.enableFungibleTokens && !body.enableNonFungibleTokens && body.enableSemiFungibleTokens && !body.enableBatchTransactions) {
code = custodial_1.Custodial_1155_TokenWallet.bytecode;
abi = custodial_1.Custodial_1155_TokenWallet.abi;
}
else {
throw new Error('Unsupported combination of inputs.');
}
return { abi, code };
};
exports.obtainCustodialAddressType = obtainCustodialAddressType;
const getCustodialFactoryContractAddress = (chain, testnet) => {
switch (chain) {
case model_1.Currency.CELO:
return testnet ? '0x481D6f967B120E094D3551DA2C4951242Be582af' : '0xC7f23843d5A51221df4B6D0778910b39b40134b4';
case model_1.Currency.TRON:
return testnet ? 'TRM8P5gpzAr85p2a5BMvqb9UfEdFEwEgA7' : 'TG59uLNQvCR45F6yKHPXipvCu7wg5D88Wr';
case model_1.Currency.ONE:
return testnet ? '0xb1462fE8E9Cf82c0296022Cca7bEfA3Fd4c12B34' : '0x86e27174edd52469f928f6206f3d8e4316525f00';
case model_1.Currency.XDC:
return testnet ? 'xdc6709Bdda623aF7EB152cB2fE2562aB7e031e564f' : 'xdc3485fdba44736859267789ac9c248cc4c1443956';
case model_1.Currency.ETH:
return testnet ? '0x4c6315C5d9b0220a8e171AF18766647EFe675a1F' : '0xd8050943c1E2764F750EC868ae1B375C4768d89A';
case model_1.Currency.MATIC:
return testnet ? '0x6792a82ffab4890cfbcee6c2c775ae9c898afe71' : '0xfc05d7fed6af03df8095cc93b674acac3f72756c';
case model_1.Currency.KLAY:
return testnet ? '0xd68c48173ccb0313442b23aed68b71961c618ade' : '0xb1462fE8E9Cf82c0296022Cca7bEfA3Fd4c12B34';
case model_1.Currency.BSC:
return testnet ? '0xeac818b4CC468Cf6556f772C4BB86e132E6ac0F3' : '0x9067f90c0975679158331fe43ad7a0a105424e0d';
default:
throw new Error('Unsupported chain.');
}
};
const getCustodialAddresses = (chain, txId) => tatum_1.get(`/v3/blockchain/sc/custodial/${chain}/${txId}`);
exports.getCustodialAddresses = getCustodialAddresses;
/**
* This method is @Deprecated. Use @link{generateCustodialWalletBatch} instead
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const generateCustodialWallet = async (testnet, body, provider) => {
console.log('This method is deprecated. For better gas consumption, use generateCustodialWalletBatch.');
switch (body.chain) {
case model_1.Currency.CELO:
return await transaction_1.sendCeloGenerateCustodialWalletSignedTransaction(testnet, body, provider);
case model_1.Currency.ONE:
return await transaction_1.sendOneGenerateCustodialWalletSignedTransaction(testnet, body, provider);
case model_1.Currency.ETH:
return await transaction_1.sendEthGenerateCustodialWalletSignedTransaction(body, provider);
case model_1.Currency.BSC:
return await transaction_1.sendBscGenerateCustodialWalletSignedTransaction(body, provider);
case model_1.Currency.MATIC:
return await transaction_1.sendPolygonGenerateCustodialWalletSignedTransaction(testnet, body, provider);
case model_1.Currency.TRON:
return await transaction_1.sendTronGenerateCustodialWalletSignedTransaction(testnet, body, provider);
default:
throw new Error('Unsupported chain');
}
};
exports.generateCustodialWallet = generateCustodialWallet;
/**
* This method is @Deprecated. Use @link{prepareCustodialWalletBatch} instead
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const prepareCustodialWallet = async (testnet, body, provider) => {
console.log('This method is deprecated. For better gas consumption, use prepareCustodialWalletBatch.');
switch (body.chain) {
case model_1.Currency.CELO:
return await transaction_1.prepareCeloGenerateCustodialWalletSignedTransaction(testnet, body, provider);
case model_1.Currency.ONE:
return await transaction_1.prepareOneGenerateCustodialWalletSignedTransaction(testnet, body, provider);
case model_1.Currency.ETH:
return await transaction_1.prepareEthGenerateCustodialWalletSignedTransaction(body, provider);
case model_1.Currency.BSC:
return await transaction_1.prepareBscGenerateCustodialWalletSignedTransaction(body, provider);
case model_1.Currency.MATIC:
return await transaction_1.preparePolygonGenerateCustodialWalletSignedTransaction(testnet, body, provider);
case model_1.Currency.TRON:
return await transaction_1.prepareTronGenerateCustodialWalletSignedTransaction(testnet, body, provider);
default:
throw new Error('Unsupported chain');
}
};
exports.prepareCustodialWallet = prepareCustodialWallet;
/**
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const generateCustodialWalletBatch = async (testnet, body, provider) => {
if (body.feesCovered) {
return await generateBatch(body);
}
if (body.signatureId) {
return await tatum_1.post(`v3/blockchain/sc/custodial/batch`, body);
}
const txData = await exports.prepareCustodialWalletBatch(testnet, body, provider);
switch (body.chain) {
case model_1.Currency.CELO:
return await blockchain_1.celoBroadcast(txData, body.signatureId);
case model_1.Currency.TRON:
return await blockchain_1.tronBroadcast(txData, body.signatureId);
case model_1.Currency.ETH:
return await blockchain_1.ethBroadcast(txData, body.signatureId);
case model_1.Currency.MATIC:
return await blockchain_1.polygonBroadcast(txData, body.signatureId);
case model_1.Currency.ONE:
return await blockchain_1.oneBroadcast(txData, body.signatureId);
case model_1.Currency.XDC:
return await blockchain_1.xdcBroadcast(txData, body.signatureId);
case model_1.Currency.KLAY:
return await blockchain_1.klaytnBroadcast(txData, body.signatureId);
case model_1.Currency.BSC:
return await blockchain_1.bscBroadcast(txData, body.signatureId);
default:
throw new Error('Unsupported chain');
}
};
exports.generateCustodialWalletBatch = generateCustodialWalletBatch;
/**
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const prepareCustodialWalletBatch = async (testnet, body, provider) => {
await tatum_1.validateBody(body, model_1.GenerateCustodialAddressBatch);
const params = body.chain === model_1.Currency.TRON
? [{ type: 'address', value: transaction_1.convertAddressToHex(body.owner.trim()) },
{ type: 'uint256', value: `0x${new bignumber_js_1.default(body.batchCount).toString(16)}` }]
: [body.chain === model_1.Currency.XDC ? transaction_1.fromXdcAddress(body.owner) : body.owner.trim(), `0x${new bignumber_js_1.default(body.batchCount).toString(16)}`];
const methodName = body.chain === model_1.Currency.TRON ? 'cloneNewWallet(address,uint256)' : 'cloneNewWallet';
return await helpers_1.helperPrepareSCCall(testnet, Object.assign(Object.assign({}, body), { contractAddress: getCustodialFactoryContractAddress(body.chain, testnet) }), model_1.GenerateCustodialAddressBatch, methodName, params, body.chain === model_1.Currency.TRON ? methodName : undefined, provider, [constants_1.CUSTODIAL_PROXY_ABI]);
};
exports.prepareCustodialWalletBatch = prepareCustodialWalletBatch;
/**
* @Deprecated, use generateCustodialWalletBatch
* Generate new smart contract based custodial wallet. This wallet is able to receive any type of assets, but transaction costs connected to the withdrawal
* of assets is covered by the deployer.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const sendCustodialWallet = async (testnet, body, provider) => {
if (body.signatureId) {
return await tatum_1.post(`v3/blockchain/sc/custodial`, body);
}
let txData;
switch (body.chain) {
case model_1.Currency.CELO:
txData = await transaction_1.prepareCeloGenerateCustodialWalletSignedTransaction(testnet, body, provider);
break;
case model_1.Currency.ONE:
txData = await transaction_1.prepareOneGenerateCustodialWalletSignedTransaction(testnet, body, provider);
break;
case model_1.Currency.ETH:
txData = await transaction_1.prepareEthGenerateCustodialWalletSignedTransaction(body, provider);
break;
case model_1.Currency.BSC:
txData = await transaction_1.prepareBscGenerateCustodialWalletSignedTransaction(body, provider);
break;
case model_1.Currency.MATIC:
txData = await transaction_1.preparePolygonGenerateCustodialWalletSignedTransaction(testnet, body, provider);
break;
case model_1.Currency.KLAY:
txData = await transaction_1.prepareKlaytnGenerateCustodialWalletSignedTransaction(testnet, body, provider);
break;
case model_1.Currency.TRON:
txData = await transaction_1.prepareTronGenerateCustodialWalletSignedTransaction(testnet, body, provider);
break;
default:
throw new Error('Unsupported chain');
}
return helpers_1.helperBroadcastTx(body.chain, txData);
};
exports.sendCustodialWallet = sendCustodialWallet;
/**
* Prepare signed transaction from the custodial SC wallet.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const prepareTransferFromCustodialWallet = async (testnet, body, provider) => {
let r;
let decimals;
if (body.chain === model_1.Currency.TRON) {
decimals = 6;
await tatum_1.validateBody(body, model_1.TransferFromTronCustodialAddress);
}
else {
decimals = 18;
await tatum_1.validateBody(body, model_1.TransferFromCustodialAddress);
}
if (body.chain === model_1.Currency.CELO) {
r = new model_1.CeloSmartContractMethodInvocation();
}
else {
r = new model_1.SmartContractMethodInvocation();
}
r.fee = body.fee;
r.nonce = body.nonce;
r.fromPrivateKey = body.fromPrivateKey;
r.signatureId = body.signatureId;
r.index = body.index;
r.contractAddress = body.custodialAddress;
r.methodName = 'transfer';
let amount = new bignumber_js_1.default(body.amount || 0);
let tokenId = new bignumber_js_1.default(body.tokenId || 0);
if (body.contractType === model_1.ContractType.NATIVE_ASSET) {
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(decimals));
}
else if (body.contractType === model_1.ContractType.FUNGIBLE_TOKEN) {
tokenId = new bignumber_js_1.default(0);
switch (body.chain) {
case model_1.Currency.CELO:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getCeloErc20ContractDecimals(testnet, body.tokenAddress, provider)));
break;
case model_1.Currency.ONE:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getOne20ContractDecimals(testnet, body.tokenAddress, provider)));
break;
case model_1.Currency.XDC:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await fungible_1.getErc20Decimals(testnet, model_1.Currency.XDC, body.tokenAddress, provider)));
break;
case model_1.Currency.ETH:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getEthErc20ContractDecimals(testnet, body.tokenAddress, provider)));
break;
case model_1.Currency.BSC:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getBscBep20ContractDecimals(testnet, body.tokenAddress, provider)));
break;
case model_1.Currency.MATIC:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getPolygonErc20ContractDecimals(testnet, body.tokenAddress, provider)));
break;
case model_1.Currency.KLAY:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getKlayErc20ContractDecimals(testnet, body.tokenAddress, provider)));
break;
case model_1.Currency.TRON:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getTronTrc20ContractDecimals(testnet, body.tokenAddress, provider)));
break;
default:
throw new Error('Unsupported combination of inputs.');
}
}
r.params = [body.tokenAddress || '0x000000000000000000000000000000000000dEaD', body.contractType, body.recipient, `0x${amount.toString(16)}`, `0x${new bignumber_js_1.default(tokenId).toString(16)}`];
r.methodABI = custodial_1.CustodialFullTokenWallet.abi.find(a => a.name === 'transfer');
switch (body.chain) {
case model_1.Currency.CELO:
return await transaction_1.prepareCeloSmartContractWriteMethodInvocation(testnet, Object.assign(Object.assign({}, r), { feeCurrency: body.feeCurrency || model_1.Currency.CELO }), provider);
case model_1.Currency.ONE:
return await transaction_1.prepareOneSmartContractWriteMethodInvocation(testnet, r, provider);
case model_1.Currency.XDC:
return await transaction_1.prepareXdcSmartContractWriteMethodInvocation(r, provider);
case model_1.Currency.ETH:
return await transaction_1.prepareSmartContractWriteMethodInvocation(r, provider);
case model_1.Currency.BSC:
return await transaction_1.prepareBscSmartContractWriteMethodInvocation(r, provider);
case model_1.Currency.MATIC:
return await transaction_1.preparePolygonSmartContractWriteMethodInvocation(testnet, r, provider);
case model_1.Currency.KLAY:
return await transaction_1.prepareKlaytnSmartContractWriteMethodInvocation(testnet, r, provider);
case model_1.Currency.TRON: {
const { feeLimit, from } = body;
r.methodName = 'transfer(address,uint256,address,uint256,uint256)';
r.params = [
{ type: 'address', value: transaction_1.convertAddressToHex(r.params[0]) },
{ type: 'uint256', value: r.params[1] },
{ type: 'address', value: transaction_1.convertAddressToHex(r.params[2]) },
{ type: 'uint256', value: r.params[3] },
{ type: 'uint256', value: r.params[4] },
];
return await transaction_1.prepareTronSmartContractInvocation(testnet, r, feeLimit, from, provider);
}
default:
throw new Error('Unsupported combination of inputs.');
}
};
exports.prepareTransferFromCustodialWallet = prepareTransferFromCustodialWallet;
/**
* Send signed transaction from the custodial SC wallet.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const sendTransferFromCustodialWallet = async (testnet, body, provider) => {
if (body.signatureId) {
return await tatum_1.post(`v3/blockchain/sc/custodial/transfer`, body);
}
return helpers_1.helperBroadcastTx(body.chain, await exports.prepareTransferFromCustodialWallet(testnet, body, provider));
};
exports.sendTransferFromCustodialWallet = sendTransferFromCustodialWallet;
/**
* Prepare signed batch transaction from the custodial SC wallet.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const prepareBatchTransferFromCustodialWallet = async (testnet, body, provider) => {
let r;
let decimals;
if (body.chain === model_1.Currency.TRON) {
await tatum_1.validateBody(body, model_1.TransferFromTronCustodialAddressBatch);
decimals = 6;
}
else {
await tatum_1.validateBody(body, model_1.TransferFromCustodialAddressBatch);
decimals = 18;
}
if (body.chain === model_1.Currency.CELO) {
r = new model_1.CeloSmartContractMethodInvocation();
}
else {
r = new model_1.SmartContractMethodInvocation();
}
r.fee = body.fee;
r.nonce = body.nonce;
r.fromPrivateKey = body.fromPrivateKey;
r.signatureId = body.signatureId;
r.index = body.index;
r.contractAddress = body.custodialAddress;
r.methodName = 'transferBatch';
const amounts = [];
const tokenIds = [];
for (let i = 0; i < body.contractType.length; i++) {
let amount = new bignumber_js_1.default(body.amount ? body.amount[i] : 0);
let tokenId = new bignumber_js_1.default(body.tokenId ? body.tokenId[i] : 0);
if (body.contractType[i] === model_1.ContractType.NATIVE_ASSET) {
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(decimals));
}
else if (body.contractType[i] === model_1.ContractType.NON_FUNGIBLE_TOKEN) {
amount = new bignumber_js_1.default(0);
}
else if (body.contractType[i] === model_1.ContractType.FUNGIBLE_TOKEN && body.tokenAddress) {
tokenId = new bignumber_js_1.default(0);
switch (body.chain) {
case model_1.Currency.CELO:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getCeloErc20ContractDecimals(testnet, body.tokenAddress[i], provider)));
break;
case model_1.Currency.ONE:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getOne20ContractDecimals(testnet, body.tokenAddress[i], provider)));
break;
case model_1.Currency.XDC:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await fungible_1.getErc20Decimals(testnet, model_1.Currency.XDC, body.tokenAddress[i], provider)));
break;
case model_1.Currency.ETH:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getEthErc20ContractDecimals(testnet, body.tokenAddress[i], provider)));
break;
case model_1.Currency.BSC:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getBscBep20ContractDecimals(testnet, body.tokenAddress[i], provider)));
break;
case model_1.Currency.MATIC:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getPolygonErc20ContractDecimals(testnet, body.tokenAddress[i], provider)));
break;
case model_1.Currency.KLAY:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getKlayErc20ContractDecimals(testnet, body.tokenAddress[i], provider)));
break;
case model_1.Currency.TRON:
amount = amount.multipliedBy(new bignumber_js_1.default(10).pow(await transaction_1.getTronTrc20ContractDecimals(testnet, body.tokenAddress[i], provider)));
break;
default:
throw new Error('Unsupported combination of inputs.');
}
}
amounts.push(`0x${amount.toString(16)}`);
tokenIds.push(`0x${tokenId.toString(16)}`);
}
r.params = [(body.tokenAddress || []).map(t => t === '0' ? '0x000000000000000000000000000000000000dEaD' : t), body.contractType, body.recipient, amounts, tokenIds];
r.methodABI = custodial_1.CustodialFullTokenWalletWithBatch.abi.find(a => a.name === 'transferBatch');
switch (body.chain) {
case model_1.Currency.CELO:
return await transaction_1.prepareCeloSmartContractWriteMethodInvocation(testnet, Object.assign(Object.assign({}, r), { feeCurrency: body.feeCurrency || model_1.Currency.CELO }), provider);
case model_1.Currency.ONE:
return await transaction_1.prepareOneSmartContractWriteMethodInvocation(testnet, r, provider);
case model_1.Currency.XDC:
return await transaction_1.prepareXdcSmartContractWriteMethodInvocation(r, provider);
case model_1.Currency.ETH:
return await transaction_1.prepareSmartContractWriteMethodInvocation(r, provider);
case model_1.Currency.BSC:
return await transaction_1.prepareBscSmartContractWriteMethodInvocation(r, provider);
case model_1.Currency.MATIC:
return await transaction_1.preparePolygonSmartContractWriteMethodInvocation(testnet, r, provider);
case model_1.Currency.KLAY:
return await transaction_1.prepareKlaytnSmartContractWriteMethodInvocation(testnet, r, provider);
case model_1.Currency.TRON: {
const body1 = body;
return await transaction_1.prepareTronCustodialTransferBatch(testnet, r, body1.feeLimit, body1.from, provider);
}
default:
throw new Error('Unsupported combination of inputs.');
}
};
exports.prepareBatchTransferFromCustodialWallet = prepareBatchTransferFromCustodialWallet;
/**
* Send signed batch transaction from the custodial SC wallet.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const sendBatchTransferFromCustodialWallet = async (testnet, body, provider) => {
if (body.signatureId) {
return await tatum_1.post(`v3/blockchain/sc/custodial/transfer/batch`, body);
}
return helpers_1.helperBroadcastTx(body.chain, await exports.prepareBatchTransferFromCustodialWallet(testnet, body, provider));
};
exports.sendBatchTransferFromCustodialWallet = sendBatchTransferFromCustodialWallet;
/**
* Prepare signed approve transaction from the custodial SC wallet.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const prepareApproveFromCustodialWallet = async (testnet, body, provider) => {
await tatum_1.validateBody(body, model_1.ApproveCustodialTransfer);
const decimals = body.contractType === model_1.ContractType.FUNGIBLE_TOKEN ? await fungible_1.getErc20Decimals(testnet, body.chain, body.tokenAddress, provider) : 0;
const params = [body.tokenAddress.trim(), body.contractType, body.spender,
`0x${new bignumber_js_1.default(body.amount || 0).multipliedBy(new bignumber_js_1.default(10).pow(decimals)).toString(16)}`, `0x${new bignumber_js_1.default(body.tokenId || 0).toString(16)}`];
delete body.amount;
return await helpers_1.helperPrepareSCCall(testnet, Object.assign(Object.assign({}, body), { contractAddress: body.custodialAddress }), model_1.ApproveCustodialTransfer, 'approve', params, undefined, provider, custodial_1.CustodialFullTokenWallet.abi);
};
exports.prepareApproveFromCustodialWallet = prepareApproveFromCustodialWallet;
/**
* Send signed approve transaction from the custodial SC wallet.
* @param testnet chain to work with
* @param body request data
* @param provider optional provider to enter. if not present, Tatum Web3 will be used.
* @returns {txId: string} Transaction ID of the operation, or signatureID in case of Tatum KMS
*/
const sendApproveFromCustodialWallet = async (testnet, body, provider) => {
if (body.signatureId) {
return await tatum_1.post(`v3/blockchain/sc/custodial/approve`, body);
}
return helpers_1.helperBroadcastTx(body.chain, await exports.prepareApproveFromCustodialWallet(testnet, body, provider));
};
exports.sendApproveFromCustodialWallet = sendApproveFromCustodialWallet;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY3VzdG9kaWFsLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3dhbGxldC9jdXN0b2RpYWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsZ0VBQXFDO0FBQ3JDLDhDQVN1QjtBQUN2Qiw4Q0FBNkQ7QUFDN0QsNENBQW1EO0FBQ25ELHNEQWVnQztBQUNoQywwQ0FBK0M7QUFDL0Msd0NBQW9FO0FBQ3BFLG9DQWNrQjtBQUNsQixnREFnQ3dCO0FBRXhCLE1BQU0sYUFBYSxHQUFHLENBQUMsSUFBbUMsRUFBNEIsRUFBRSxDQUFDLFlBQUksQ0FBQyxtQ0FBbUMsRUFBRSxJQUFJLENBQUMsQ0FBQTtBQUVqSSxNQUFNLDBCQUEwQixHQUFHLENBQUMsSUFBOEIsRUFBRSxFQUFFO0lBQzNFLElBQUksSUFBSSxDQUFDLEtBQUssS0FBSyxnQkFBUSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsd0JBQXdCLEVBQUU7UUFDakUsTUFBTSxJQUFJLEtBQUssQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFDO0tBQ3ZEO0lBQ0QsSUFBSSxHQUFHLENBQUM7SUFDUixJQUFJLElBQUksQ0FBQztJQUNULElBQUksSUFBSSxDQUFDLG9CQUFvQixJQUFJLElBQUksQ0FBQyx1QkFBdUIsSUFBSSxJQUFJLENBQUMsd0JBQXdCLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFO1FBQzlILElBQUksR0FBRyw2Q0FBaUMsQ0FBQyxRQUFRLENBQUM7UUFDbEQsR0FBRyxHQUFHLDZDQUFpQyxDQUFDLEdBQUcsQ0FBQztLQUM3QztTQUFNLElBQUksSUFBSSxDQUFDLG9CQUFvQixJQUFJLElBQUksQ0FBQyx1QkFBdUIsSUFBSSxJQUFJLENBQUMsd0JBQXdCLElBQUksQ0FBQyxJQUFJLENBQUMsdUJBQXVCLEVBQUU7UUFDdEksSUFBSSxHQUFHLG9DQUF3QixDQUFDLFFBQVEsQ0FBQztRQUN6QyxHQUFHLEdBQUcsb0NBQXdCLENBQUMsR0FBRyxDQUFDO0tBQ3BD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