UNPKG

lisk-framework

Version:

Lisk blockchain application platform

100 lines 5.52 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TransferCrossChainCommand = void 0; const lisk_codec_1 = require("@liskhq/lisk-codec"); const cryptography = require("@liskhq/lisk-cryptography"); const lisk_utils_1 = require("@liskhq/lisk-utils"); const base_command_1 = require("../../base_command"); const state_machine_1 = require("../../../state_machine"); const schemas_1 = require("../schemas"); const constants_1 = require("../constants"); const utils_1 = require("../utils"); const escrow_1 = require("../stores/escrow"); const user_1 = require("../stores/user"); const transfer_cross_chain_1 = require("../events/transfer_cross_chain"); const errors_1 = require("../../../errors"); class TransferCrossChainCommand extends base_command_1.BaseCommand { constructor() { super(...arguments); this.schema = schemas_1.crossChainTransferParamsSchema; } init(args) { this._moduleName = args.moduleName; this._method = args.method; this._interoperabilityMethod = args.interoperabilityMethod; this._internalMethod = args.internalMethod; } async verify(context) { var _a; const { params } = context; try { const [tokenChainID, _] = (0, utils_1.splitTokenID)(params.tokenID); if (params.receivingChainID.equals(context.chainID)) { throw new Error('Receiving chain cannot be the sending chain.'); } if (![context.chainID, params.receivingChainID].some(allowedChainID => tokenChainID.equals(allowedChainID))) { throw new Error('Token must be native to either the sending or the receiving chain.'); } const messageFeeTokenID = await this._interoperabilityMethod.getMessageFeeTokenID(context.getMethodContext(), params.receivingChainID); if (!messageFeeTokenID.equals(params.messageFeeTokenID)) { throw new Error('Invalid message fee Token ID.'); } const balanceCheck = new lisk_utils_1.dataStructures.BufferMap(); balanceCheck.set(params.tokenID, params.amount); balanceCheck.set(messageFeeTokenID, ((_a = balanceCheck.get(messageFeeTokenID)) !== null && _a !== void 0 ? _a : BigInt(0)) + params.messageFee); for (const [tokenID, amount] of balanceCheck.entries()) { const availableBalance = await this._method.getAvailableBalance(context.getMethodContext(), context.transaction.senderAddress, tokenID); if (availableBalance < amount) { throw new errors_1.InsufficientBalanceError(cryptography.address.getLisk32AddressFromAddress(context.transaction.senderAddress), availableBalance.toString(), amount.toString(), tokenID.toString('hex')); } } } catch (err) { return { status: state_machine_1.VerifyStatus.FAIL, error: err, }; } return { status: state_machine_1.VerifyStatus.OK, }; } async execute(context) { const { params, transaction: { senderAddress }, } = context; const [tokenChainID, _] = (0, utils_1.splitTokenID)(params.tokenID); const escrowStore = this.stores.get(escrow_1.EscrowStore); const escrowAccountKey = escrowStore.getKey(params.receivingChainID, params.tokenID); const escrowAccoutExists = await escrowStore.has(context, escrowAccountKey); if (tokenChainID.equals(context.chainID) && !escrowAccoutExists) { await this._internalMethod.initializeEscrowAccount(context.getMethodContext(), params.receivingChainID, params.tokenID); } const userStore = this.stores.get(user_1.UserStore); const senderAccountKey = userStore.getKey(senderAddress, params.tokenID); const senderAccount = await userStore.get(context, senderAccountKey); if (senderAccount.availableBalance < params.amount) { throw new errors_1.InsufficientBalanceError(cryptography.address.getLisk32AddressFromAddress(senderAddress), senderAccount.availableBalance.toString(), params.amount.toString(), params.tokenID.toString('hex')); } senderAccount.availableBalance -= params.amount; await userStore.save(context, senderAddress, params.tokenID, senderAccount); if (tokenChainID.equals(context.chainID)) { await escrowStore.addAmount(context, params.receivingChainID, params.tokenID, params.amount); } this.events.get(transfer_cross_chain_1.TransferCrossChainEvent).log(context, { senderAddress, receivingChainID: params.receivingChainID, tokenID: params.tokenID, amount: params.amount, recipientAddress: params.recipientAddress, }); const transferCCM = { amount: params.amount, data: params.data, recipientAddress: params.recipientAddress, senderAddress, tokenID: params.tokenID, }; await this._interoperabilityMethod.send(context.getMethodContext(), senderAddress, this._moduleName, constants_1.CROSS_CHAIN_COMMAND_NAME_TRANSFER, params.receivingChainID, params.messageFee, lisk_codec_1.codec.encode(schemas_1.crossChainTransferMessageParams, transferCCM), context.header.timestamp); } } exports.TransferCrossChainCommand = TransferCrossChainCommand; //# sourceMappingURL=transfer_cross_chain.js.map