UNPKG

@mysten/sui

Version:
811 lines (809 loc) 32.9 kB
import { normalizeStructTag, normalizeSuiAddress } from "../utils/sui-types.mjs"; import { bcs as suiBcs } from "../bcs/index.mjs"; import { CoreClient } from "../client/core.mjs"; import { formatMoveAbortMessage } from "../client/utils.mjs"; import { SimulationError } from "../client/errors.mjs"; import { SUI_TYPE_ARG } from "../utils/constants.mjs"; import { Value } from "./proto/google/protobuf/struct.mjs"; import { Ability, FunctionDescriptor_Visibility, OpenSignatureBody_Type, OpenSignature_Reference } from "./proto/sui/rpc/v2/move_package.mjs"; import { Owner_OwnerKind } from "./proto/sui/rpc/v2/owner.mjs"; import { applyGrpcResolvedTransaction, grpcTransactionToTransactionData, transactionDataToGrpcTransaction, transactionToGrpcTransaction } from "../client/transaction-resolver.mjs"; import { CommandArgumentError_CommandArgumentErrorKind } from "./proto/sui/rpc/v2/execution_status.mjs"; import { ChangedObject_IdOperation, ChangedObject_InputObjectState, ChangedObject_OutputObjectState, UnchangedConsensusObject_UnchangedConsensusObjectKind } from "./proto/sui/rpc/v2/effects.mjs"; import { SimulateTransactionRequest_TransactionChecks } from "./proto/sui/rpc/v2/transaction_execution_service.mjs"; import { chunk, fromBase64, toBase64 } from "@mysten/utils"; //#region src/grpc/core.ts var GrpcCoreClient = class extends CoreClient { #client; constructor({ client, ...options }) { super(options); this.#client = client; } async getObjects(options) { const batches = chunk(options.objectIds, 50); const results = []; const paths = [ "owner", "object_type", "digest", "version", "object_id" ]; if (options.include?.content) paths.push("contents"); if (options.include?.previousTransaction) paths.push("previous_transaction"); if (options.include?.objectBcs) paths.push("bcs"); if (options.include?.json) paths.push("json"); if (options.include?.display) paths.push("display"); for (const batch of batches) { const response = await this.#client.ledgerService.batchGetObjects({ requests: batch.map((id) => ({ objectId: id })), readMask: { paths } }); results.push(...response.response.objects.map((object) => { if (object.result.oneofKind === "error") return new Error(object.result.error.message); if (object.result.oneofKind !== "object") return /* @__PURE__ */ new Error("Unexpected result type"); const bcsContent = object.result.object.contents?.value ?? void 0; const objectBcs = object.result.object.bcs?.value ?? void 0; const objectType = object.result.object.objectType; const type = objectType && objectType.includes("::") ? normalizeStructTag(objectType) : objectType ?? ""; const jsonContent = options.include?.json ? object.result.object.json ? Value.toJson(object.result.object.json) : null : void 0; const displayData = mapDisplayProto(options.include?.display, object.result.object.display); return { objectId: object.result.object.objectId, version: object.result.object.version?.toString(), digest: object.result.object.digest, content: bcsContent, owner: mapOwner(object.result.object.owner), type, previousTransaction: object.result.object.previousTransaction ?? void 0, objectBcs, json: jsonContent, display: displayData }; })); } return { objects: results }; } async listOwnedObjects(options) { const paths = [ "owner", "object_type", "digest", "version", "object_id" ]; if (options.include?.content) paths.push("contents"); if (options.include?.previousTransaction) paths.push("previous_transaction"); if (options.include?.objectBcs) paths.push("bcs"); if (options.include?.json) paths.push("json"); if (options.include?.display) paths.push("display"); const response = await this.#client.stateService.listOwnedObjects({ owner: options.owner, objectType: options.type ? (await this.mvr.resolveType({ type: options.type })).type : void 0, pageToken: options.cursor ? fromBase64(options.cursor) : void 0, pageSize: options.limit, readMask: { paths } }); return { objects: response.response.objects.map((object) => ({ objectId: object.objectId, version: object.version?.toString(), digest: object.digest, content: object.contents?.value, owner: mapOwner(object.owner), type: object.objectType, previousTransaction: object.previousTransaction ?? void 0, objectBcs: object.bcs?.value, json: options.include?.json ? object.json ? Value.toJson(object.json) : null : void 0, display: mapDisplayProto(options.include?.display, object.display) })), cursor: response.response.nextPageToken ? toBase64(response.response.nextPageToken) : null, hasNextPage: response.response.nextPageToken !== void 0 }; } async listCoins(options) { const paths = [ "owner", "object_type", "digest", "version", "object_id", "balance" ]; const coinType = options.coinType ?? SUI_TYPE_ARG; const response = await this.#client.stateService.listOwnedObjects({ owner: options.owner, objectType: `0x2::coin::Coin<${(await this.mvr.resolveType({ type: coinType })).type}>`, pageToken: options.cursor ? fromBase64(options.cursor) : void 0, readMask: { paths } }); return { objects: response.response.objects.map((object) => ({ objectId: object.objectId, version: object.version?.toString(), digest: object.digest, owner: mapOwner(object.owner), type: object.objectType, balance: object.balance?.toString() })), cursor: response.response.nextPageToken ? toBase64(response.response.nextPageToken) : null, hasNextPage: response.response.nextPageToken !== void 0 }; } async getBalance(options) { const coinType = options.coinType ?? SUI_TYPE_ARG; const result = await this.#client.stateService.getBalance({ owner: options.owner, coinType: (await this.mvr.resolveType({ type: coinType })).type }); return { balance: { balance: result.response.balance?.balance?.toString() ?? "0", coinType: result.response.balance?.coinType ?? coinType, coinBalance: result.response.balance?.coinBalance?.toString() ?? "0", addressBalance: result.response.balance?.addressBalance?.toString() ?? "0" } }; } async getCoinMetadata(options) { const coinType = (await this.mvr.resolveType({ type: options.coinType })).type; let response; try { ({response} = await this.#client.stateService.getCoinInfo({ coinType })); } catch { return { coinMetadata: null }; } if (!response.metadata) return { coinMetadata: null }; return { coinMetadata: { id: response.metadata.id ?? null, decimals: response.metadata.decimals ?? 0, name: response.metadata.name ?? "", symbol: response.metadata.symbol ?? "", description: response.metadata.description ?? "", iconUrl: response.metadata.iconUrl ?? null } }; } async listBalances(options) { const result = await this.#client.stateService.listBalances({ owner: options.owner, pageToken: options.cursor ? fromBase64(options.cursor) : void 0, pageSize: options.limit }); return { hasNextPage: !!result.response.nextPageToken, cursor: result.response.nextPageToken ? toBase64(result.response.nextPageToken) : null, balances: result.response.balances.map((balance) => ({ balance: balance.balance?.toString() ?? "0", coinType: balance.coinType, coinBalance: balance.coinBalance?.toString() ?? "0", addressBalance: balance.addressBalance?.toString() ?? "0" })) }; } async getTransaction(options) { const paths = [ "digest", "transaction.digest", "signatures", "effects.status" ]; if (options.include?.transaction) paths.push("transaction.sender", "transaction.gas_payment", "transaction.expiration", "transaction.kind"); if (options.include?.bcs) paths.push("transaction.bcs"); if (options.include?.balanceChanges) paths.push("balance_changes"); if (options.include?.effects) paths.push("effects"); if (options.include?.events) paths.push("events"); if (options.include?.objectTypes) { paths.push("effects.changed_objects.object_type"); paths.push("effects.changed_objects.object_id"); } const { response } = await this.#client.ledgerService.getTransaction({ digest: options.digest, readMask: { paths } }); if (!response.transaction) throw new Error(`Transaction ${options.digest} not found`); return parseTransaction(response.transaction, options.include); } async executeTransaction(options) { const paths = [ "digest", "transaction.digest", "signatures", "effects.status" ]; if (options.include?.transaction) paths.push("transaction.sender", "transaction.gas_payment", "transaction.expiration", "transaction.kind"); if (options.include?.bcs) paths.push("transaction.bcs"); if (options.include?.balanceChanges) paths.push("balance_changes"); if (options.include?.effects) paths.push("effects"); if (options.include?.events) paths.push("events"); if (options.include?.objectTypes) { paths.push("effects.changed_objects.object_type"); paths.push("effects.changed_objects.object_id"); } const { response } = await this.#client.transactionExecutionService.executeTransaction({ transaction: { bcs: { value: options.transaction } }, signatures: options.signatures.map((signature) => ({ bcs: { value: fromBase64(signature) }, signature: { oneofKind: void 0 } })), readMask: { paths } }); return parseTransaction(response.transaction, options.include); } async simulateTransaction(options) { const paths = [ "transaction.digest", "transaction.transaction.digest", "transaction.signatures", "transaction.effects.status" ]; if (options.include?.transaction) paths.push("transaction.transaction.sender", "transaction.transaction.gas_payment", "transaction.transaction.expiration", "transaction.transaction.kind"); if (options.include?.bcs) paths.push("transaction.transaction.bcs"); if (options.include?.balanceChanges) paths.push("transaction.balance_changes"); if (options.include?.effects) paths.push("transaction.effects"); if (options.include?.events) paths.push("transaction.events"); if (options.include?.objectTypes) { paths.push("transaction.effects.changed_objects.object_type"); paths.push("transaction.effects.changed_objects.object_id"); } if (options.include?.commandResults) paths.push("command_outputs"); if (!(options.transaction instanceof Uint8Array)) await options.transaction.prepareForSerialization({ client: this }); const { response } = await this.#client.transactionExecutionService.simulateTransaction({ transaction: options.transaction instanceof Uint8Array ? { bcs: { value: options.transaction } } : transactionToGrpcTransaction(options.transaction), readMask: { paths }, doGasSelection: false, checks: options.checksEnabled === false ? SimulateTransactionRequest_TransactionChecks.DISABLED : SimulateTransactionRequest_TransactionChecks.ENABLED }); const transactionResult = parseTransaction(response.transaction, options.include); const commandResults = options.include?.commandResults && response.commandOutputs ? response.commandOutputs.map((output) => ({ returnValues: (output.returnValues ?? []).map((rv) => ({ bcs: rv.value?.value ?? null })), mutatedReferences: (output.mutatedByRef ?? []).map((mr) => ({ bcs: mr.value?.value ?? null })) })) : void 0; if (transactionResult.$kind === "Transaction") return { $kind: "Transaction", Transaction: transactionResult.Transaction, commandResults }; else return { $kind: "FailedTransaction", FailedTransaction: transactionResult.FailedTransaction, commandResults }; } async getReferenceGasPrice() { return { referenceGasPrice: (await this.#client.ledgerService.getEpoch({ readMask: { paths: ["reference_gas_price"] } })).response.epoch?.referenceGasPrice?.toString() ?? "" }; } async getProtocolConfig() { const protocolConfig = (await this.#client.ledgerService.getEpoch({ readMask: { paths: ["protocol_config"] } })).response.epoch?.protocolConfig; if (!protocolConfig) throw new Error("Protocol config not found in response"); const featureFlags = { ...protocolConfig.featureFlags }; const attributes = {}; if (protocolConfig.attributes) for (const [key, value] of Object.entries(protocolConfig.attributes)) attributes[key] = value ?? null; return { protocolConfig: { protocolVersion: protocolConfig.protocolVersion?.toString() ?? null, featureFlags, attributes } }; } async getCurrentSystemState() { const epoch = (await this.#client.ledgerService.getEpoch({ readMask: { paths: [ "system_state.version", "system_state.epoch", "system_state.protocol_version", "system_state.reference_gas_price", "system_state.epoch_start_timestamp_ms", "system_state.safe_mode", "system_state.safe_mode_storage_rewards", "system_state.safe_mode_computation_rewards", "system_state.safe_mode_storage_rebates", "system_state.safe_mode_non_refundable_storage_fee", "system_state.parameters", "system_state.storage_fund", "system_state.stake_subsidy" ] } })).response.epoch; const systemState = epoch?.systemState; if (!systemState) throw new Error("System state not found in response"); const startMs = epoch?.start?.seconds ? Number(epoch.start.seconds) * 1e3 + Math.floor((epoch.start.nanos || 0) / 1e6) : systemState.epochStartTimestampMs ? Number(systemState.epochStartTimestampMs) : null; return { systemState: { systemStateVersion: systemState.version?.toString() ?? null, epoch: systemState.epoch?.toString() ?? null, protocolVersion: systemState.protocolVersion?.toString() ?? null, referenceGasPrice: systemState.referenceGasPrice?.toString() ?? null, epochStartTimestampMs: startMs.toString(), safeMode: systemState.safeMode ?? false, safeModeStorageRewards: systemState.safeModeStorageRewards?.toString() ?? null, safeModeComputationRewards: systemState.safeModeComputationRewards?.toString() ?? null, safeModeStorageRebates: systemState.safeModeStorageRebates?.toString() ?? null, safeModeNonRefundableStorageFee: systemState.safeModeNonRefundableStorageFee?.toString() ?? null, parameters: { epochDurationMs: systemState.parameters?.epochDurationMs?.toString() ?? null, stakeSubsidyStartEpoch: systemState.parameters?.stakeSubsidyStartEpoch?.toString() ?? null, maxValidatorCount: systemState.parameters?.maxValidatorCount?.toString() ?? null, minValidatorJoiningStake: systemState.parameters?.minValidatorJoiningStake?.toString() ?? null, validatorLowStakeThreshold: systemState.parameters?.validatorLowStakeThreshold?.toString() ?? null, validatorLowStakeGracePeriod: systemState.parameters?.validatorLowStakeGracePeriod?.toString() ?? null }, storageFund: { totalObjectStorageRebates: systemState.storageFund?.totalObjectStorageRebates?.toString() ?? null, nonRefundableBalance: systemState.storageFund?.nonRefundableBalance?.toString() ?? null }, stakeSubsidy: { balance: systemState.stakeSubsidy?.balance?.toString() ?? null, distributionCounter: systemState.stakeSubsidy?.distributionCounter?.toString() ?? null, currentDistributionAmount: systemState.stakeSubsidy?.currentDistributionAmount?.toString() ?? null, stakeSubsidyPeriodLength: systemState.stakeSubsidy?.stakeSubsidyPeriodLength?.toString() ?? null, stakeSubsidyDecreaseRate: systemState.stakeSubsidy?.stakeSubsidyDecreaseRate ?? null } } }; } async listDynamicFields(options) { return this.#client.listDynamicFields(options); } async verifyZkLoginSignature(options) { const messageBytes = fromBase64(options.bytes); const messageValue = options.intentScope === "PersonalMessage" ? suiBcs.byteVector().serialize(messageBytes).toBytes() : messageBytes; const { response } = await this.#client.signatureVerificationService.verifySignature({ message: { name: options.intentScope, value: messageValue }, signature: { bcs: { value: fromBase64(options.signature) }, signature: { oneofKind: void 0 } }, address: options.address, jwks: [] }); return { success: response.isValid ?? false, errors: response.reason ? [response.reason] : [] }; } async defaultNameServiceName(options) { return { data: { name: (await this.#client.nameService.reverseLookupName({ address: options.address })).response.record?.name ?? null } }; } async getMoveFunction(options) { const resolvedPackageId = (await this.mvr.resolvePackage({ package: options.packageId })).package; const { response } = await this.#client.movePackageService.getFunction({ packageId: resolvedPackageId, moduleName: options.moduleName, name: options.name }); let visibility = "unknown"; switch (response.function?.visibility) { case FunctionDescriptor_Visibility.PUBLIC: visibility = "public"; break; case FunctionDescriptor_Visibility.PRIVATE: visibility = "private"; break; case FunctionDescriptor_Visibility.FRIEND: visibility = "friend"; break; } return { function: { packageId: normalizeSuiAddress(resolvedPackageId), moduleName: options.moduleName, name: response.function?.name, visibility, isEntry: response.function?.isEntry ?? false, typeParameters: response.function?.typeParameters?.map(({ constraints }) => ({ isPhantom: false, constraints: constraints.map((constraint) => { switch (constraint) { case Ability.COPY: return "copy"; case Ability.DROP: return "drop"; case Ability.STORE: return "store"; case Ability.KEY: return "key"; default: return "unknown"; } }) ?? [] })) ?? [], parameters: response.function?.parameters?.map((param) => parseNormalizedSuiMoveType(param)) ?? [], returns: response.function?.returns?.map((ret) => parseNormalizedSuiMoveType(ret)) ?? [] } }; } async getChainIdentifier(_options) { return this.cache.read(["chainIdentifier"], async () => { const { response } = await this.#client.ledgerService.getServiceInfo({}); if (!response.chainId) throw new Error("Chain identifier not found in service info"); return { chainIdentifier: response.chainId }; }); } resolveTransactionPlugin() { const client = this.#client; return async function resolveTransactionData(transactionData, options, next) { const snapshot = transactionData.snapshot(); if (!snapshot.sender) snapshot.sender = "0x0000000000000000000000000000000000000000000000000000000000000000"; const grpcTransaction = transactionDataToGrpcTransaction(snapshot); let response; try { response = (await client.transactionExecutionService.simulateTransaction({ transaction: grpcTransaction, doGasSelection: !options.onlyTransactionKind && (snapshot.gasData.budget == null || snapshot.gasData.payment == null), readMask: { paths: [ "transaction.transaction.sender", "transaction.transaction.gas_payment", "transaction.transaction.expiration", "transaction.transaction.kind", "transaction.effects.status" ] } })).response; } catch (error) { if (error instanceof Error && error.message) throw new SimulationError(decodeURIComponent(error.message), { cause: error }); throw error; } if (!options.onlyTransactionKind && response.transaction?.effects?.status && !response.transaction.effects.status.success) { const executionError = response.transaction.effects.status.error ? parseGrpcExecutionError(response.transaction.effects.status.error) : void 0; throw new SimulationError(`Transaction resolution failed: ${executionError?.message ?? "Transaction failed"}`, { executionError }); } if (!response.transaction?.transaction) throw new Error("simulateTransaction did not return resolved transaction data"); applyGrpcResolvedTransaction(transactionData, response.transaction.transaction, options); return await next(); }; } }; function mapDisplayProto(include, display) { if (!include) return void 0; if (display === void 0) return null; return { output: display.output !== void 0 ? Value.toJson(display.output) : null, errors: display.errors !== void 0 ? Value.toJson(display.errors) : null }; } function mapOwner(owner) { if (!owner) return null; if (owner.kind === Owner_OwnerKind.IMMUTABLE) return { $kind: "Immutable", Immutable: true }; if (owner.kind === Owner_OwnerKind.ADDRESS) return { AddressOwner: owner.address, $kind: "AddressOwner" }; if (owner.kind === Owner_OwnerKind.OBJECT) return { $kind: "ObjectOwner", ObjectOwner: owner.address }; if (owner.kind === Owner_OwnerKind.SHARED) return { $kind: "Shared", Shared: { initialSharedVersion: owner.version?.toString() } }; if (owner.kind === Owner_OwnerKind.CONSENSUS_ADDRESS) return { $kind: "ConsensusAddressOwner", ConsensusAddressOwner: { startVersion: owner.version?.toString(), owner: owner.address } }; throw new Error(`Unknown owner kind ${JSON.stringify(owner, (_k, v) => typeof v === "bigint" ? v.toString() : v)}`); } function parseGrpcExecutionError(error) { const message = error.description ?? "Unknown error"; const command = error.command != null ? Number(error.command) : void 0; const details = error.errorDetails; switch (details?.oneofKind) { case "abort": { const abort = details.abort; const cleverError = abort.cleverError; return { $kind: "MoveAbort", message: formatMoveAbortMessage({ command, location: abort.location, abortCode: String(abort.abortCode ?? 0n), cleverError: cleverError ? { lineNumber: cleverError.lineNumber != null ? Number(cleverError.lineNumber) : void 0, constantName: cleverError.constantName, value: cleverError.value?.oneofKind === "rendered" ? cleverError.value.rendered : void 0 } : void 0 }), command, MoveAbort: parseMoveAbort(abort) }; } case "sizeError": return { $kind: "SizeError", message, command, SizeError: { name: mapErrorName(error.kind), size: Number(details.sizeError.size ?? 0n), maxSize: Number(details.sizeError.maxSize ?? 0n) } }; case "commandArgumentError": return { $kind: "CommandArgumentError", message, command, CommandArgumentError: { argument: details.commandArgumentError.argument ?? 0, name: mapErrorName(details.commandArgumentError.kind) } }; case "typeArgumentError": return { $kind: "TypeArgumentError", message, command, TypeArgumentError: { typeArgument: details.typeArgumentError.typeArgument ?? 0, name: mapErrorName(details.typeArgumentError.kind) } }; case "packageUpgradeError": return { $kind: "PackageUpgradeError", message, command, PackageUpgradeError: { name: mapErrorName(details.packageUpgradeError.kind), packageId: details.packageUpgradeError.packageId, digest: details.packageUpgradeError.digest } }; case "indexError": return { $kind: "IndexError", message, command, IndexError: { index: details.indexError.index, subresult: details.indexError.subresult } }; case "coinDenyListError": return { $kind: "CoinDenyListError", message, command, CoinDenyListError: { name: mapErrorName(error.kind), coinType: details.coinDenyListError.coinType, address: details.coinDenyListError.address } }; case "congestedObjects": return { $kind: "CongestedObjects", message, command, CongestedObjects: { name: mapErrorName(error.kind), objects: details.congestedObjects.objects } }; case "objectId": return { $kind: "ObjectIdError", message, command, ObjectIdError: { name: mapErrorName(error.kind), objectId: details.objectId } }; default: return { $kind: "Unknown", message, command, Unknown: null }; } } function parseMoveAbort(abort) { return { abortCode: String(abort.abortCode ?? 0n), location: { ...abort.location }, cleverError: abort.cleverError ? { errorCode: abort.cleverError.errorCode != null ? Number(abort.cleverError.errorCode) : void 0, lineNumber: abort.cleverError.lineNumber != null ? Number(abort.cleverError.lineNumber) : void 0, constantName: abort.cleverError.constantName, constantType: abort.cleverError.constantType, value: abort.cleverError.value?.oneofKind === "rendered" ? abort.cleverError.value.rendered : abort.cleverError.value?.oneofKind === "raw" ? toBase64(abort.cleverError.value.raw) : void 0 } : void 0 }; } function mapErrorName(kind) { if (kind == null) return "Unknown"; const name = CommandArgumentError_CommandArgumentErrorKind[kind]; if (!name || name.endsWith("_UNKNOWN")) return "Unknown"; return name.split("_").map((word) => word.charAt(0) + word.slice(1).toLowerCase()).join(""); } function mapIdOperation(operation) { if (operation == null) return null; switch (operation) { case ChangedObject_IdOperation.CREATED: return "Created"; case ChangedObject_IdOperation.DELETED: return "Deleted"; case ChangedObject_IdOperation.NONE: case ChangedObject_IdOperation.ID_OPERATION_UNKNOWN: return "None"; default: return "Unknown"; } } function mapInputObjectState(state) { if (state == null) return null; switch (state) { case ChangedObject_InputObjectState.EXISTS: return "Exists"; case ChangedObject_InputObjectState.DOES_NOT_EXIST: return "DoesNotExist"; case ChangedObject_InputObjectState.UNKNOWN: return "Unknown"; default: return "Unknown"; } } function mapOutputObjectState(state) { if (state == null) return null; switch (state) { case ChangedObject_OutputObjectState.OBJECT_WRITE: return "ObjectWrite"; case ChangedObject_OutputObjectState.PACKAGE_WRITE: return "PackageWrite"; case ChangedObject_OutputObjectState.DOES_NOT_EXIST: return "DoesNotExist"; case ChangedObject_OutputObjectState.ACCUMULATOR_WRITE: return "AccumulatorWriteV1"; case ChangedObject_OutputObjectState.UNKNOWN: return "Unknown"; default: return "Unknown"; } } function mapUnchangedConsensusObjectKind(kind) { if (kind == null) return null; switch (kind) { case UnchangedConsensusObject_UnchangedConsensusObjectKind.UNCHANGED_CONSENSUS_OBJECT_KIND_UNKNOWN: return "Unknown"; case UnchangedConsensusObject_UnchangedConsensusObjectKind.READ_ONLY_ROOT: return "ReadOnlyRoot"; case UnchangedConsensusObject_UnchangedConsensusObjectKind.MUTATE_CONSENSUS_STREAM_ENDED: return "MutateConsensusStreamEnded"; case UnchangedConsensusObject_UnchangedConsensusObjectKind.READ_CONSENSUS_STREAM_ENDED: return "ReadConsensusStreamEnded"; case UnchangedConsensusObject_UnchangedConsensusObjectKind.CANCELED: return "Cancelled"; case UnchangedConsensusObject_UnchangedConsensusObjectKind.PER_EPOCH_CONFIG: return "PerEpochConfig"; default: return "Unknown"; } } function parseTransactionEffects({ effects }) { if (!effects) return null; const changedObjects = effects.changedObjects.map((change) => { return { objectId: change.objectId, inputState: mapInputObjectState(change.inputState), inputVersion: change.inputVersion?.toString() ?? null, inputDigest: change.inputDigest ?? null, inputOwner: mapOwner(change.inputOwner), outputState: mapOutputObjectState(change.outputState), outputVersion: change.outputVersion?.toString() ?? null, outputDigest: change.outputDigest ?? null, outputOwner: mapOwner(change.outputOwner), idOperation: mapIdOperation(change.idOperation) }; }); return { bcs: effects.bcs?.value, version: 2, status: effects.status?.success ? { success: true, error: null } : { success: false, error: parseGrpcExecutionError(effects.status.error) }, gasUsed: { computationCost: effects.gasUsed?.computationCost?.toString(), storageCost: effects.gasUsed?.storageCost?.toString(), storageRebate: effects.gasUsed?.storageRebate?.toString(), nonRefundableStorageFee: effects.gasUsed?.nonRefundableStorageFee?.toString() }, transactionDigest: effects.transactionDigest, gasObject: { objectId: effects.gasObject?.objectId, inputState: mapInputObjectState(effects.gasObject?.inputState), inputVersion: effects.gasObject?.inputVersion?.toString() ?? null, inputDigest: effects.gasObject?.inputDigest ?? null, inputOwner: mapOwner(effects.gasObject?.inputOwner), outputState: mapOutputObjectState(effects.gasObject?.outputState), outputVersion: effects.gasObject?.outputVersion?.toString() ?? null, outputDigest: effects.gasObject?.outputDigest ?? null, outputOwner: mapOwner(effects.gasObject?.outputOwner), idOperation: mapIdOperation(effects.gasObject?.idOperation) }, eventsDigest: effects.eventsDigest ?? null, dependencies: effects.dependencies, lamportVersion: effects.lamportVersion?.toString() ?? null, changedObjects, unchangedConsensusObjects: effects.unchangedConsensusObjects.map((object) => { return { kind: mapUnchangedConsensusObjectKind(object.kind), objectId: object.objectId, version: object.version?.toString() ?? null, digest: object.digest ?? null }; }), auxiliaryDataDigest: effects.auxiliaryDataDigest ?? null }; } function parseTransaction(transaction, include) { const objectTypes = {}; if (include?.objectTypes) transaction.effects?.changedObjects?.forEach((change) => { if (change.objectId && change.objectType) objectTypes[change.objectId] = change.objectType; }); let transactionData; if (include?.transaction) { const tx = transaction.transaction; if (!tx) throw new Error("Transaction data is required but missing from gRPC response"); const resolved = grpcTransactionToTransactionData(tx); transactionData = { gasData: resolved.gasData, sender: resolved.sender, expiration: resolved.expiration, commands: resolved.commands, inputs: resolved.inputs, version: resolved.version }; } const bcsBytes = include?.bcs ? transaction.transaction?.bcs?.value : void 0; const effects = include?.effects ? parseTransactionEffects({ effects: transaction.effects }) : void 0; const status = transaction.effects?.status?.success ? { success: true, error: null } : { success: false, error: transaction.effects?.status?.error ? parseGrpcExecutionError(transaction.effects.status.error) : { $kind: "Unknown", message: "Transaction failed", Unknown: null } }; const result = { digest: transaction.digest, epoch: transaction.effects?.epoch?.toString() ?? null, status, effects, objectTypes: include?.objectTypes ? objectTypes : void 0, transaction: transactionData, bcs: bcsBytes, signatures: transaction.signatures?.map((sig) => toBase64(sig.bcs?.value)) ?? [], balanceChanges: include?.balanceChanges ? transaction.balanceChanges?.map((change) => ({ coinType: change.coinType, address: change.address, amount: change.amount })) ?? [] : void 0, events: include?.events ? transaction.events?.events.map((event) => ({ packageId: normalizeSuiAddress(event.packageId), module: event.module, sender: normalizeSuiAddress(event.sender), eventType: event.eventType, bcs: event.contents?.value ?? new Uint8Array(), json: event.json ? Value.toJson(event.json) : null })) ?? [] : void 0 }; return status.success ? { $kind: "Transaction", Transaction: result } : { $kind: "FailedTransaction", FailedTransaction: result }; } function parseNormalizedSuiMoveType(type) { let reference = null; if (type.reference === OpenSignature_Reference.IMMUTABLE) reference = "immutable"; else if (type.reference === OpenSignature_Reference.MUTABLE) reference = "mutable"; return { reference, body: parseNormalizedSuiMoveTypeBody(type.body) }; } function parseNormalizedSuiMoveTypeBody(type) { switch (type.type) { case OpenSignatureBody_Type.TYPE_UNKNOWN: return { $kind: "unknown" }; case OpenSignatureBody_Type.ADDRESS: return { $kind: "address" }; case OpenSignatureBody_Type.BOOL: return { $kind: "bool" }; case OpenSignatureBody_Type.U8: return { $kind: "u8" }; case OpenSignatureBody_Type.U16: return { $kind: "u16" }; case OpenSignatureBody_Type.U32: return { $kind: "u32" }; case OpenSignatureBody_Type.U64: return { $kind: "u64" }; case OpenSignatureBody_Type.U128: return { $kind: "u128" }; case OpenSignatureBody_Type.U256: return { $kind: "u256" }; case OpenSignatureBody_Type.VECTOR: return { $kind: "vector", vector: parseNormalizedSuiMoveTypeBody(type.typeParameterInstantiation[0]) }; case OpenSignatureBody_Type.DATATYPE: return { $kind: "datatype", datatype: { typeName: type.typeName, typeParameters: type.typeParameterInstantiation.map((t) => parseNormalizedSuiMoveTypeBody(t)) } }; case OpenSignatureBody_Type.TYPE_PARAMETER: return { $kind: "typeParameter", index: type.typeParameter }; default: return { $kind: "unknown" }; } } //#endregion export { GrpcCoreClient }; //# sourceMappingURL=core.mjs.map