// Helper class to decode move call import { bcs } from '@mysten/sui.js/bcs'; import { MoveCallTransaction, TransactionBlockInput } from '@mysten/sui.js/dist/cjs/builder/Transactions'; import { TransactionBlock } from '@mysten/sui.js/transactions'; import { normalizeStructTag, normalizeSuiAddress } from '@mysten/sui.js/utils'; export class MoveCallHelper { constructor( public readonly moveCall: MoveCallTransaction, public readonly txb: TransactionBlock, ) {} decodeSharedObjectId(argIndex: number) { const input = this.getInputParam(argIndex); return MoveCallHelper.getSharedObjectId(input); } decodeOwnedObjectId(argIndex: number) { const input = this.getInputParam(argIndex); return MoveCallHelper.getOwnedObjectId(input); } decodeInputU64(argIndex: number) { const strVal = this.decodePureArg(argIndex, 'u64'); return BigInt(strVal); } decodeInputAddress(argIndex: number) { const input = this.decodePureArg(argIndex, 'address'); return normalizeSuiAddress(input); } decodeInputString(argIndex: number) { return this.decodePureArg(argIndex, 'string'); } decodeInputBool(argIndex: number) { return this.decodePureArg(argIndex, 'bool'); } decodePureArg(argIndex: number, bcsType: string) { const input = this.getInputParam(argIndex); return MoveCallHelper.getPureInputValue(input, bcsType); } getInputParam(argIndex: number) { const arg = this.moveCall.arguments[argIndex]; if (arg.kind !== 'Input') { throw new Error('not input type'); } return this.txb.blockData.inputs[arg.index]; } static getPureInputValue(input: TransactionBlockInput, bcsType: string) { if (input.type !== 'pure') { throw new Error('not pure argument'); } if (typeof input.value === 'object' && 'Pure' in input.value) { const bcsNums = input.value.Pure; return bcs.de(bcsType, new Uint8Array(bcsNums)) as T; } return input.value as T; } static getOwnedObjectId(input: TransactionBlockInput) { if (input.type !== 'object') { throw new Error(`not object argument: ${JSON.stringify(input)}`); } if (typeof input.value === 'object') { if (!('Object' in input.value) || !('ImmOrOwned' in input.value.Object)) { throw new Error('not ImmOrOwned'); } return normalizeSuiAddress(input.value.Object.ImmOrOwned.objectId as string); } return normalizeSuiAddress(input.value as string); } static getSharedObjectId(input: TransactionBlockInput) { if (input.type !== 'object') { throw new Error(`not object argument: ${JSON.stringify(input)}`); } if (typeof input.value !== 'object') { return normalizeSuiAddress(input.value as string); } if (!('Object' in input.value) || !('Shared' in input.value.Object)) { throw new Error('not Shared'); } return normalizeSuiAddress(input.value.Object.Shared.objectId as string); } static getPureInput(input: TransactionBlockInput, bcsType: string) { if (input.type !== 'pure') { throw new Error('not pure argument'); } if (typeof input.value !== 'object') { return input.value as T; } if (!('Pure' in input.value)) { throw new Error('Pure not in value'); } const bcsVal = input.value.Pure; return bcs.de(bcsType, new Uint8Array(bcsVal)) as T; } typeArg(index: number) { return normalizeStructTag(this.moveCall.typeArguments[index]); } txArg(index: number) { return this.moveCall.arguments[index]; } }