@axelar-network/axelar-cgp-sui
Version:
Axelar Sui Move contracts
150 lines • 7.39 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.approve = approve;
exports.execute = execute;
exports.approveAndExecute = approveAndExecute;
const bcs_1 = require("@mysten/bcs");
const bcs_2 = require("@mysten/sui/bcs");
const utils_1 = require("ethers/lib/utils");
const bcs_3 = require("./bcs");
const tx_builder_base_1 = require("./tx-builder-base");
const types_1 = require("./types");
const utils_2 = require("./utils");
const { gateway: { WeightedSigners, MessageToSign, Proof, Message, Transaction }, } = bcs_3.bcsStructs;
function approve(client, keypair, gatewayApprovalInfo, messageInfo, options) {
return __awaiter(this, void 0, void 0, function* () {
const { packageId, gateway, signers, signerKeys, domainSeparator } = gatewayApprovalInfo;
const messageData = bcs_2.bcs.vector(Message).serialize([messageInfo]).toBytes();
const hashed = (0, utils_2.hashMessage)(messageData, types_1.GatewayMessageType.ApproveMessages);
const message = MessageToSign.serialize({
domain_separator: (0, bcs_1.fromHEX)(domainSeparator),
signers_hash: (0, utils_1.keccak256)(WeightedSigners.serialize(signers).toBytes()),
data_hash: hashed,
}).toBytes();
let minSigners = 0;
let totalWeight = 0;
for (let i = 0; i < signers.signers.length; i++) {
totalWeight += signers.signers[i].weight;
if (totalWeight >= signers.threshold) {
minSigners = i + 1;
break;
}
}
const signatures = (0, utils_2.signMessage)(signerKeys.slice(0, minSigners), message);
const encodedProof = Proof.serialize({
signers,
signatures,
}).toBytes();
const txBuilder = new tx_builder_base_1.TxBuilderBase(client);
yield txBuilder.moveCall({
target: `${packageId}::gateway::approve_messages`,
arguments: [gateway, (0, utils_1.hexlify)(messageData), (0, utils_1.hexlify)(encodedProof)],
});
yield txBuilder.signAndExecute(keypair, options);
});
}
function execute(client, keypair, discoveryInfo, gatewayInfo, messageInfo, options) {
return __awaiter(this, void 0, void 0, function* () {
let moveCalls = [createInitialMoveCall(discoveryInfo, messageInfo.destination_id)];
let isFinal = false;
while (!isFinal) {
const builder = new tx_builder_base_1.TxBuilderBase(client);
doMoveCalls(builder.tx, moveCalls, messageInfo.payload);
const nextTx = yield inspectTransaction(builder, keypair);
isFinal = nextTx.is_final;
moveCalls = nextTx.move_calls;
}
const txBuilder = new tx_builder_base_1.TxBuilderBase(client);
const ApprovedMessage = yield createApprovedMessageCall(txBuilder, gatewayInfo, messageInfo);
doMoveCalls(txBuilder.tx, moveCalls, messageInfo.payload, ApprovedMessage);
return txBuilder.signAndExecute(keypair, options);
});
}
function approveAndExecute(client_1, keypair_1, gatewayApprovalInfo_1, discoveryInfo_1, messageInfo_1) {
return __awaiter(this, arguments, void 0, function* (client, keypair, gatewayApprovalInfo, discoveryInfo, messageInfo, options = {
showEvents: true,
}) {
yield approve(client, keypair, gatewayApprovalInfo, messageInfo, options);
return execute(client, keypair, discoveryInfo, gatewayApprovalInfo, messageInfo, options);
});
}
function createInitialMoveCall(discoveryInfo, destinationId) {
const { packageId, discovery } = discoveryInfo;
const discoveryArg = [types_1.MoveCallType.Object, ...(0, utils_1.arrayify)(discovery)];
const targetIdArg = [types_1.MoveCallType.Pure, ...(0, utils_1.arrayify)(destinationId)];
return {
function: {
package_id: packageId,
module_name: 'discovery',
name: 'get_transaction',
},
arguments: [discoveryArg, targetIdArg],
type_arguments: [],
};
}
function inspectTransaction(builder, keypair) {
return __awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d;
const resp = yield builder.devInspect(keypair.toSuiAddress());
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const txData = (_d = (_c = (_b = (_a = resp.results) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.returnValues) === null || _c === void 0 ? void 0 : _c[0]) === null || _d === void 0 ? void 0 : _d[0];
return Transaction.parse(new Uint8Array(txData));
});
}
function createApprovedMessageCall(builder, gatewayInfo, messageInfo) {
return builder.moveCall({
target: `${gatewayInfo.packageId}::gateway::take_approved_message`,
arguments: [
gatewayInfo.gateway,
messageInfo.source_chain,
messageInfo.message_id,
messageInfo.source_address,
messageInfo.destination_id,
messageInfo.payload,
],
});
}
/* eslint-disable @typescript-eslint/no-explicit-any */
function doMoveCalls(tx, moveCalls, payload, ApprovedMessage) {
const txResults = [];
for (const call of moveCalls) {
const moveCall = buildMoveCall(tx, call, payload, txResults, ApprovedMessage);
const txResult = tx.moveCall(moveCall);
txResults.push(Array.isArray(txResult) ? txResult : [txResult]);
}
}
/* eslint-disable @typescript-eslint/no-explicit-any */
function buildMoveCall(tx, moveCallInfo, payload, previousReturns, ApprovedMessage) {
const decodeArgs = (args) => args.map(([argType, ...arg]) => {
switch (argType) {
case types_1.MoveCallType.Object:
return tx.object((0, utils_1.hexlify)(arg));
case types_1.MoveCallType.Pure:
return tx.pure((0, utils_1.arrayify)(arg));
case types_1.MoveCallType.ApproveMessage:
return ApprovedMessage;
case types_1.MoveCallType.Payload:
return tx.pure(bcs_2.bcs.vector(bcs_2.bcs.U8).serialize((0, utils_1.arrayify)(payload)));
case types_1.MoveCallType.HotPotato:
return previousReturns[arg[1]][arg[2]];
default:
throw new Error(`Invalid argument prefix: ${argType}`);
}
});
const { package_id: packageId, module_name: moduleName, name } = moveCallInfo.function;
return {
target: `${packageId}::${moduleName}::${name}`,
arguments: decodeArgs(moveCallInfo.arguments),
typeArguments: moveCallInfo.type_arguments,
};
}
//# sourceMappingURL=execute.js.map