UNPKG

@mysten/sui

Version:
126 lines (106 loc) 3.35 kB
// Copyright (c) Mysten Labs, Inc. // SPDX-License-Identifier: Apache-2.0 import type { Argument } from './data/internal.js'; import type { ClientWithCoreApi } from '../client/index.js'; import type { TransactionDataBuilder } from './TransactionData.js'; import type { BcsType } from '@mysten/bcs'; import { Inputs } from './Inputs.js'; import { bcs } from '../bcs/index.js'; import { coreClientResolveTransactionPlugin } from '../client/core-resolver.js'; export interface BuildTransactionOptions { client?: ClientWithCoreApi; onlyTransactionKind?: boolean; } export interface SerializeTransactionOptions extends BuildTransactionOptions { supportedIntents?: string[]; } export type TransactionPlugin = ( transactionData: TransactionDataBuilder, options: BuildTransactionOptions, next: () => Promise<void>, ) => Promise<void>; export function needsTransactionResolution( data: TransactionDataBuilder, options: BuildTransactionOptions, ): boolean { if ( data.inputs.some((input) => { return input.UnresolvedObject || input.UnresolvedPure; }) ) { return true; } if (!options.onlyTransactionKind) { if (!data.gasData.price || !data.gasData.budget || !data.gasData.payment) { return true; } if (data.gasData.payment.length === 0 && !data.expiration) { return true; } } return false; } export async function resolveTransactionPlugin( transactionData: TransactionDataBuilder, options: BuildTransactionOptions, next: () => Promise<void>, ) { normalizeRawArguments(transactionData); if (!needsTransactionResolution(transactionData, options)) { await validate(transactionData); return next(); } const client = getClient(options); const plugin = client.core?.resolveTransactionPlugin() ?? coreClientResolveTransactionPlugin; return plugin(transactionData, options, async () => { await validate(transactionData); await next(); }); } function validate(transactionData: TransactionDataBuilder) { transactionData.inputs.forEach((input, index) => { if (input.$kind !== 'Object' && input.$kind !== 'Pure' && input.$kind !== 'FundsWithdrawal') { throw new Error( `Input at index ${index} has not been resolved. Expected a Pure, Object, or FundsWithdrawal input, but found ${JSON.stringify( input, )}`, ); } }); } export function getClient(options: BuildTransactionOptions) { if (!options.client) { throw new Error( `No sui client passed to Transaction#build, but transaction data was not sufficient to build offline.`, ); } return options.client; } function normalizeRawArguments(transactionData: TransactionDataBuilder) { for (const command of transactionData.commands) { switch (command.$kind) { case 'SplitCoins': command.SplitCoins.amounts.forEach((amount) => { normalizeRawArgument(amount, bcs.U64, transactionData); }); break; case 'TransferObjects': normalizeRawArgument(command.TransferObjects.address, bcs.Address, transactionData); break; } } } function normalizeRawArgument( arg: Argument, schema: BcsType<any>, transactionData: TransactionDataBuilder, ) { if (arg.$kind !== 'Input') { return; } const input = transactionData.inputs[arg.Input]; if (input.$kind !== 'UnresolvedPure') { return; } transactionData.inputs[arg.Input] = Inputs.Pure(schema.serialize(input.UnresolvedPure.value)); }