UNPKG

@axelar-network/axelar-cgp-sui

Version:
145 lines 7.01 kB
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()); }); }; import { fromHEX } from '@mysten/bcs'; import { bcs } from '@mysten/sui/bcs'; import { arrayify, hexlify, keccak256 } from 'ethers/lib/utils'; import { bcsStructs } from './bcs'; import { TxBuilderBase as TxBuilder } from './tx-builder-base'; import { GatewayMessageType, MoveCallType, } from './types'; import { hashMessage, signMessage } from './utils'; const { gateway: { WeightedSigners, MessageToSign, Proof, Message, Transaction }, } = bcsStructs; export 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.vector(Message).serialize([messageInfo]).toBytes(); const hashed = hashMessage(messageData, GatewayMessageType.ApproveMessages); const message = MessageToSign.serialize({ domain_separator: fromHEX(domainSeparator), signers_hash: 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 = signMessage(signerKeys.slice(0, minSigners), message); const encodedProof = Proof.serialize({ signers, signatures, }).toBytes(); const txBuilder = new TxBuilder(client); yield txBuilder.moveCall({ target: `${packageId}::gateway::approve_messages`, arguments: [gateway, hexlify(messageData), hexlify(encodedProof)], }); yield txBuilder.signAndExecute(keypair, options); }); } export 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 TxBuilder(client); doMoveCalls(builder.tx, moveCalls, messageInfo.payload); const nextTx = yield inspectTransaction(builder, keypair); isFinal = nextTx.is_final; moveCalls = nextTx.move_calls; } const txBuilder = new TxBuilder(client); const ApprovedMessage = yield createApprovedMessageCall(txBuilder, gatewayInfo, messageInfo); doMoveCalls(txBuilder.tx, moveCalls, messageInfo.payload, ApprovedMessage); return txBuilder.signAndExecute(keypair, options); }); } export 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 = [MoveCallType.Object, ...arrayify(discovery)]; const targetIdArg = [MoveCallType.Pure, ...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 MoveCallType.Object: return tx.object(hexlify(arg)); case MoveCallType.Pure: return tx.pure(arrayify(arg)); case MoveCallType.ApproveMessage: return ApprovedMessage; case MoveCallType.Payload: return tx.pure(bcs.vector(bcs.U8).serialize(arrayify(payload))); case 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