I am using fireBlocks sdk. To withdraw crypto.
you can check my code here →
Hello Shahid,
Can you please post the code in the code block here instead of Pastebin URLs?
const fireblocksSettings = require("../fireblocksSettings");
const mathOps = require("../utils/math");
const logger = require("../logger");
const { slippage } = require("../fireblocksSettings");
const AggregatorService = require("./AggregatorService");
const VaultAssetService = require("./VaultAssetService");
const TransactionService = require("./TransactionService");
const ProviderService = require("./ProviderService");
const TransactionFactory = require("../factories/TransactionFactory");
const appConfig = new (require(`../config.${process.env.NODE_ENV}`))();
const FireblocksSDK = require("fireblocks-sdk").FireblocksSDK;
const fireblocks = new FireblocksSDK(
appConfig.fireblocksSecret,
appConfig.fireblocksKey,
);
class WithdrawService {
constructor(securityContext) {
this.transactionServiceInstance = new TransactionService(securityContext);
this.vaultAssetServiceInstance = new VaultAssetService(securityContext);
this.aggregatorServiceInstance = new AggregatorService();
}
execute = async (
{
amount,
fireblocksAssetId,
vaultId,
inTokenAddress,
externalAddress,
txnUserId,
},
tenantId,
userId,
) => {
let providerService = new ProviderService(vaultId, inTokenAddress);
const vaultAsset = await fireblocks.getVaultAccountAsset(
vaultId,
fireblocksAssetId,
);
if (vaultAsset.available < amount)
throw new Error("Insufficient balance. Balance:" + vaultAsset.available);
const withdrawalCommission = mathOps.getWithdrawCommission(amount);
logger.info(`withdrawalCommission is comission is ${withdrawalCommission}`);
const usersCut = mathOps.getUsersCut(amount);
logger.info(`user cut is is , ${usersCut}`);
if (fireblocksAssetId == fireblocksSettings.usdcAssetId) {
const cryptoWithdrawalCommissionUSDCData =
await this.transferCommissionUSDC(
{
assetId: fireblocksAssetId,
vaultId: vaultId,
amount: withdrawalCommission,
txnUserId: txnUserId,
},
tenantId,
userId,
);
} else {
const account = await this.getTxnAccount(
vaultId,
fireblocksAssetId,
tenantId,
userId,
);
logger.info(`Account : ${account}`);
const commissionAccount = await this.getTxnAccount(
fireblocksSettings.withdrawalCommission,
fireblocksSettings.usdcAssetId,
tenantId,
userId,
);
logger.info(`Commission Account : ${commissionAccount}`);
let gasPrice = await providerService.getGas();
const aggregatorResult =
await this.aggregatorServiceInstance.getCryptoWithdrawSwapQuote({
inTokenAddress: inTokenAddress,
withdrawalCommission: withdrawalCommission,
gasPrice: gasPrice,
account: commissionAccount,
});
logger.info("got swap quote\n" + JSON.stringify(aggregatorResult));
const commissionData = await this.transferCommission(
{
assetId: fireblocksAssetId,
vaultId: vaultId,
contractParam: aggregatorResult.data.data,
withdrawalCommission: withdrawalCommission,
txnUserId: txnUserId,
fee: aggregatorResult.data.estimatedGas,
},
tenantId,
userId,
);
}
const withdrawalData = await this.transferWithdrawal(
{
assetId: fireblocksAssetId,
vaultId: vaultId,
externalAddress: externalAddress,
amount: usersCut,
txnUserId: txnUserId,
},
tenantId,
userId,
);
return withdrawalData;
};
getTxnAccount = async (vaultId, assetId, tenantId, userId) => {
const addressResult = await this.vaultAssetServiceInstance.getAddresses(
{ vaultAccountId: vaultId, assetId: assetId },
tenantId,
userId,
);
return addressResult[0].address;
};
transferWithdrawal = async (
{ assetId, vaultId, externalAddress, amount, txnUserId },
tenantId,
userId,
) =>
await this.transactionServiceInstance.create(
TransactionFactory.cryptoWithdrawal(
assetId,
vaultId,
externalAddress,
amount,
txnUserId,
),
tenantId,
userId,
);
transferCommission = async (
{ assetId, vaultId, contractParam, withdrawalCommission, txnUserId, fee },
tenantId,
userId,
) =>
await this.transactionServiceInstance.create(
TransactionFactory.cryptoWithdrawalCommissionContract(
assetId,
vaultId,
contractParam,
assetId === fireblocksSettings.baseAssetId ? withdrawalCommission : "0",
txnUserId,
),
tenantId,
userId,
);
transferCommissionUSDC = async (
{ assetId, vaultId, amount, txnUserId },
tenantId,
userId,
) =>
await this.transactionServiceInstance.create(
TransactionFactory.cryptoUSDCWithdrawalCommission(
assetId,
vaultId,
amount,
txnUserId,
),
tenantId,
userId,
);
}
module.exports = WithdrawService;
Hello @Shahid Thank you for sharing, I am with Fireblocks support and I am looking into why the execution gets reverted for this transfer.
Hello @Shahid I believe the error you received, “transfer amount exceeds allowance” refers to a smart contract level error where you must call an approve function in this BEP20 contract your interacting with. Can you please share the smart contract address?