lisk-framework
Version:
Lisk blockchain application platform
100 lines • 5.52 kB
JavaScript
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
;