UNPKG

@mysten/sui

Version:
815 lines (813 loc) 29.8 kB
import { normalizeStructTag, normalizeSuiAddress } from "../utils/sui-types.mjs"; import { TypeTagSerializer } from "../bcs/type-tag-serializer.mjs"; import { bcs as suiBcs } from "../bcs/index.mjs"; import { deriveDynamicFieldID } from "../utils/dynamic-fields.mjs"; import { CoreClient } from "../client/core.mjs"; import { TransactionDataBuilder } from "../transactions/TransactionData.mjs"; import { formatMoveAbortMessage, parseTransactionBcs, parseTransactionEffectsBcs } from "../client/utils.mjs"; import { ObjectError } from "../client/errors.mjs"; import { SUI_FRAMEWORK_ADDRESS, SUI_SYSTEM_ADDRESS } from "../utils/constants.mjs"; import { coreClientResolveTransactionPlugin } from "../client/core-resolver.mjs"; import { Transaction } from "../transactions/Transaction.mjs"; import { fromBase64 } from "@mysten/bcs"; import { chunk } from "@mysten/utils"; //#region src/jsonRpc/core.ts const MAX_GAS = 5e10; function parseJsonRpcExecutionStatus(status, abortError) { if (status.status === "success") return { success: true, error: null }; const rawMessage = status.error ?? "Unknown"; if (abortError) { const commandMatch = rawMessage.match(/in command (\d+)/); const command = commandMatch ? parseInt(commandMatch[1], 10) : void 0; const instructionMatch = rawMessage.match(/instruction:\s*(\d+)/); const instruction = instructionMatch ? parseInt(instructionMatch[1], 10) : void 0; const moduleParts = abortError.module_id?.split("::") ?? []; const pkg = moduleParts[0] ? normalizeSuiAddress(moduleParts[0]) : void 0; const module = moduleParts[1]; return { success: false, error: { $kind: "MoveAbort", message: formatMoveAbortMessage({ command, location: pkg && module ? { package: pkg, module, functionName: abortError.function ?? void 0, instruction } : void 0, abortCode: String(abortError.error_code ?? 0), cleverError: abortError.line != null ? { lineNumber: abortError.line } : void 0 }), command, MoveAbort: { abortCode: String(abortError.error_code ?? 0), location: abortError.module_id ? { package: normalizeSuiAddress(abortError.module_id.split("::")[0] ?? ""), module: abortError.module_id.split("::")[1] ?? "", functionName: abortError.function ?? void 0, instruction } : void 0 } } }; } return { success: false, error: { $kind: "Unknown", message: rawMessage, Unknown: null } }; } var JSONRpcCoreClient = class extends CoreClient { #jsonRpcClient; constructor({ jsonRpcClient, mvr }) { super({ network: jsonRpcClient.network, base: jsonRpcClient, mvr }); this.#jsonRpcClient = jsonRpcClient; } async getObjects(options) { const batches = chunk(options.objectIds, 50); const results = []; for (const batch of batches) { const objects = await this.#jsonRpcClient.multiGetObjects({ ids: batch, options: { showOwner: true, showType: true, showBcs: options.include?.content || options.include?.objectBcs ? true : false, showPreviousTransaction: options.include?.previousTransaction || options.include?.objectBcs ? true : false, showStorageRebate: options.include?.objectBcs ?? false, showContent: options.include?.json ?? false, showDisplay: options.include?.display ?? false }, signal: options.signal }); for (const [idx, object] of objects.entries()) if (object.error) results.push(ObjectError.fromResponse(object.error, batch[idx])); else results.push(parseObject(object.data, options.include)); } return { objects: results }; } async listOwnedObjects(options) { let filter = null; if (options.type) { const parts = options.type.split("::"); if (parts.length === 1) filter = { Package: options.type }; else if (parts.length === 2) filter = { MoveModule: { package: parts[0], module: parts[1] } }; else filter = { StructType: options.type }; } const objects = await this.#jsonRpcClient.getOwnedObjects({ owner: options.owner, limit: options.limit, cursor: options.cursor, options: { showOwner: true, showType: true, showBcs: options.include?.content || options.include?.objectBcs ? true : false, showPreviousTransaction: options.include?.previousTransaction || options.include?.objectBcs ? true : false, showStorageRebate: options.include?.objectBcs ?? false, showContent: options.include?.json ?? false, showDisplay: options.include?.display ?? false }, filter, signal: options.signal }); return { objects: objects.data.map((result) => { if (result.error) throw ObjectError.fromResponse(result.error); return parseObject(result.data, options.include); }), hasNextPage: objects.hasNextPage, cursor: objects.nextCursor ?? null }; } async listCoins(options) { const coins = await this.#jsonRpcClient.getCoins({ owner: options.owner, coinType: options.coinType, limit: options.limit, cursor: options.cursor, signal: options.signal }); return { objects: coins.data.map((coin) => ({ objectId: coin.coinObjectId, version: coin.version, digest: coin.digest, balance: coin.balance, type: normalizeStructTag(`0x2::coin::Coin<${coin.coinType}>`), owner: { $kind: "AddressOwner", AddressOwner: options.owner } })), hasNextPage: coins.hasNextPage, cursor: coins.nextCursor ?? null }; } async getBalance(options) { const balance = await this.#jsonRpcClient.getBalance({ owner: options.owner, coinType: options.coinType, signal: options.signal }); const addressBalance = balance.fundsInAddressBalance ?? "0"; const coinBalance = String(BigInt(balance.totalBalance) - BigInt(addressBalance)); return { balance: { coinType: normalizeStructTag(balance.coinType), balance: balance.totalBalance, coinBalance, addressBalance } }; } async getCoinMetadata(options) { const coinType = (await this.mvr.resolveType({ type: options.coinType })).type; const result = await this.#jsonRpcClient.getCoinMetadata({ coinType, signal: options.signal }); if (!result) return { coinMetadata: null }; return { coinMetadata: { id: result.id ?? null, decimals: result.decimals, name: result.name, symbol: result.symbol, description: result.description, iconUrl: result.iconUrl ?? null } }; } async listBalances(options) { return { balances: (await this.#jsonRpcClient.getAllBalances({ owner: options.owner, signal: options.signal })).map((balance) => { const addressBalance = balance.fundsInAddressBalance ?? "0"; const coinBalance = String(BigInt(balance.totalBalance) - BigInt(addressBalance)); return { coinType: normalizeStructTag(balance.coinType), balance: balance.totalBalance, coinBalance, addressBalance }; }), hasNextPage: false, cursor: null }; } async getTransaction(options) { return parseTransaction(await this.#jsonRpcClient.getTransactionBlock({ digest: options.digest, options: { showRawInput: true, showEffects: true, showObjectChanges: options.include?.objectTypes ?? false, showRawEffects: options.include?.effects ?? false, showEvents: options.include?.events ?? false, showBalanceChanges: options.include?.balanceChanges ?? false }, signal: options.signal }), options.include); } async executeTransaction(options) { return parseTransaction(await this.#jsonRpcClient.executeTransactionBlock({ transactionBlock: options.transaction, signature: options.signatures, options: { showRawInput: true, showEffects: true, showRawEffects: options.include?.effects ?? false, showEvents: options.include?.events ?? false, showObjectChanges: options.include?.objectTypes ?? false, showBalanceChanges: options.include?.balanceChanges ?? false }, signal: options.signal }), options.include); } async simulateTransaction(options) { if (!(options.transaction instanceof Uint8Array)) await options.transaction.build({ client: this, onlyTransactionKind: true }); const tx = Transaction.from(options.transaction); const data = options.transaction instanceof Uint8Array ? null : TransactionDataBuilder.restore(options.transaction.getData()); const transactionBytes = data ? data.build({ overrides: { gasData: { budget: data.gasData.budget ?? String(MAX_GAS), price: data.gasData.price ?? String(await this.#jsonRpcClient.getReferenceGasPrice()), payment: data.gasData.payment ?? [] } } }) : options.transaction; const sender = tx.getData().sender ?? normalizeSuiAddress("0x0"); const checksDisabled = options.checksEnabled === false; let dryRunResult = null; try { dryRunResult = await this.#jsonRpcClient.dryRunTransactionBlock({ transactionBlock: transactionBytes, signal: options.signal }); } catch (e) { if (!checksDisabled) throw e; } let devInspectResult = null; if (options.include?.commandResults || checksDisabled) try { devInspectResult = await this.#jsonRpcClient.devInspectTransactionBlock({ sender, transactionBlock: tx, signal: options.signal }); } catch {} const dryRunFailed = !dryRunResult || dryRunResult.effects.status.status !== "success"; const effectsSource = checksDisabled && dryRunFailed && devInspectResult ? devInspectResult : dryRunResult ?? devInspectResult; if (!effectsSource) throw new Error("simulateTransaction failed: no results from dryRun or devInspect"); const { effects, objectTypes } = parseTransactionEffectsJson({ effects: effectsSource.effects, objectChanges: dryRunResult?.objectChanges ?? [] }); const transactionData = { digest: TransactionDataBuilder.getDigestFromBytes(transactionBytes), epoch: null, status: effects.status, effects: options.include?.effects ? effects : void 0, objectTypes: options.include?.objectTypes ? objectTypes : void 0, signatures: [], transaction: options.include?.transaction ? parseTransactionBcs(options.transaction instanceof Uint8Array ? options.transaction : await options.transaction.build({ client: this }).catch(() => null)) : void 0, bcs: options.include?.bcs ? transactionBytes : void 0, balanceChanges: options.include?.balanceChanges && dryRunResult ? dryRunResult.balanceChanges.map((change) => ({ coinType: normalizeStructTag(change.coinType), address: parseOwnerAddress(change.owner), amount: change.amount })) : void 0, events: options.include?.events ? effectsSource.events?.map((event) => ({ packageId: event.packageId, module: event.transactionModule, sender: event.sender, eventType: event.type, bcs: "bcs" in event ? fromBase64(event.bcs) : new Uint8Array(), json: event.parsedJson ?? null })) ?? [] : void 0 }; let commandResults; if (options.include?.commandResults && devInspectResult?.results) commandResults = devInspectResult.results.map((result) => ({ returnValues: (result.returnValues ?? []).map(([bytes]) => ({ bcs: new Uint8Array(bytes) })), mutatedReferences: (result.mutableReferenceOutputs ?? []).map(([, bytes]) => ({ bcs: new Uint8Array(bytes) })) })); return effects.status.success ? { $kind: "Transaction", Transaction: transactionData, commandResults } : { $kind: "FailedTransaction", FailedTransaction: transactionData, commandResults }; } async getReferenceGasPrice(options) { const referenceGasPrice = await this.#jsonRpcClient.getReferenceGasPrice({ signal: options?.signal }); return { referenceGasPrice: String(referenceGasPrice) }; } async getProtocolConfig(options) { const result = await this.#jsonRpcClient.getProtocolConfig({ signal: options?.signal }); const attributes = {}; for (const [key, value] of Object.entries(result.attributes)) if (value === null) attributes[key] = null; else if ("u16" in value) attributes[key] = value.u16; else if ("u32" in value) attributes[key] = value.u32; else if ("u64" in value) attributes[key] = value.u64; else if ("f64" in value) attributes[key] = value.f64; else if ("bool" in value) attributes[key] = value.bool; else { const entries = Object.entries(value); attributes[key] = entries.length === 1 ? String(entries[0][1]) : JSON.stringify(value); } return { protocolConfig: { protocolVersion: result.protocolVersion, featureFlags: { ...result.featureFlags }, attributes } }; } async getCurrentSystemState(options) { const systemState = await this.#jsonRpcClient.getLatestSuiSystemState({ signal: options?.signal }); return { systemState: { systemStateVersion: systemState.systemStateVersion, epoch: systemState.epoch, protocolVersion: systemState.protocolVersion, referenceGasPrice: systemState.referenceGasPrice?.toString() ?? null, epochStartTimestampMs: systemState.epochStartTimestampMs, safeMode: systemState.safeMode, safeModeStorageRewards: systemState.safeModeStorageRewards, safeModeComputationRewards: systemState.safeModeComputationRewards, safeModeStorageRebates: systemState.safeModeStorageRebates, safeModeNonRefundableStorageFee: systemState.safeModeNonRefundableStorageFee, parameters: { epochDurationMs: systemState.epochDurationMs, stakeSubsidyStartEpoch: systemState.stakeSubsidyStartEpoch, maxValidatorCount: systemState.maxValidatorCount, minValidatorJoiningStake: systemState.minValidatorJoiningStake, validatorLowStakeThreshold: systemState.validatorLowStakeThreshold, validatorLowStakeGracePeriod: systemState.validatorLowStakeGracePeriod }, storageFund: { totalObjectStorageRebates: systemState.storageFundTotalObjectStorageRebates, nonRefundableBalance: systemState.storageFundNonRefundableBalance }, stakeSubsidy: { balance: systemState.stakeSubsidyBalance, distributionCounter: systemState.stakeSubsidyDistributionCounter, currentDistributionAmount: systemState.stakeSubsidyCurrentDistributionAmount, stakeSubsidyPeriodLength: systemState.stakeSubsidyPeriodLength, stakeSubsidyDecreaseRate: systemState.stakeSubsidyDecreaseRate } } }; } async listDynamicFields(options) { const dynamicFields = await this.#jsonRpcClient.getDynamicFields({ parentId: options.parentId, limit: options.limit, cursor: options.cursor }); return { dynamicFields: dynamicFields.data.map((dynamicField) => { const isDynamicObject = dynamicField.type === "DynamicObject"; const fullType = isDynamicObject ? `0x2::dynamic_field::Field<0x2::dynamic_object_field::Wrapper<${dynamicField.name.type}>, 0x2::object::ID>` : `0x2::dynamic_field::Field<${dynamicField.name.type}, ${dynamicField.objectType}>`; const bcsBytes = fromBase64(dynamicField.bcsName); const derivedNameType = isDynamicObject ? `0x2::dynamic_object_field::Wrapper<${dynamicField.name.type}>` : dynamicField.name.type; return { $kind: isDynamicObject ? "DynamicObject" : "DynamicField", fieldId: deriveDynamicFieldID(options.parentId, derivedNameType, bcsBytes), type: normalizeStructTag(fullType), name: { type: dynamicField.name.type, bcs: bcsBytes }, valueType: dynamicField.objectType, childId: isDynamicObject ? dynamicField.objectId : void 0 }; }), hasNextPage: dynamicFields.hasNextPage, cursor: dynamicFields.nextCursor }; } async verifyZkLoginSignature(options) { const result = await this.#jsonRpcClient.verifyZkLoginSignature({ bytes: options.bytes, signature: options.signature, intentScope: options.intentScope, author: options.address }); return { success: result.success, errors: result.errors }; } async defaultNameServiceName(options) { return { data: { name: (await this.#jsonRpcClient.resolveNameServiceNames(options)).data[0] } }; } resolveTransactionPlugin() { return coreClientResolveTransactionPlugin; } async getMoveFunction(options) { const resolvedPackageId = (await this.mvr.resolvePackage({ package: options.packageId })).package; const result = await this.#jsonRpcClient.getNormalizedMoveFunction({ package: resolvedPackageId, module: options.moduleName, function: options.name }); return { function: { packageId: normalizeSuiAddress(resolvedPackageId), moduleName: options.moduleName, name: options.name, visibility: parseVisibility(result.visibility), isEntry: result.isEntry, typeParameters: result.typeParameters.map((abilities) => ({ isPhantom: false, constraints: parseAbilities(abilities) })), parameters: result.parameters.map((param) => parseNormalizedSuiMoveType(param)), returns: result.return.map((ret) => parseNormalizedSuiMoveType(ret)) } }; } async getChainIdentifier(_options) { return this.cache.read(["chainIdentifier"], async () => { return { chainIdentifier: (await this.#jsonRpcClient.getCheckpoint({ id: "0" })).digest }; }); } }; function serializeObjectToBcs(object) { if (object.bcs?.dataType !== "moveObject") return; try { const typeStr = normalizeStructTag(object.bcs.type); let moveObjectType; const normalizedSuiFramework = normalizeSuiAddress(SUI_FRAMEWORK_ADDRESS); const gasCoinType = normalizeStructTag(`${SUI_FRAMEWORK_ADDRESS}::coin::Coin<${SUI_FRAMEWORK_ADDRESS}::sui::SUI>`); const stakedSuiType = normalizeStructTag(`${SUI_SYSTEM_ADDRESS}::staking_pool::StakedSui`); const coinPrefix = `${normalizedSuiFramework}::coin::Coin<`; if (typeStr === gasCoinType) moveObjectType = { GasCoin: null }; else if (typeStr === stakedSuiType) moveObjectType = { StakedSui: null }; else if (typeStr.startsWith(coinPrefix)) { const innerTypeMatch = typeStr.match(/* @__PURE__ */ new RegExp(`${normalizedSuiFramework.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}::coin::Coin<(.+)>$`)); if (innerTypeMatch) moveObjectType = { Coin: TypeTagSerializer.parseFromStr(innerTypeMatch[1], true) }; else throw new Error("Failed to parse Coin type"); } else { const typeTag = TypeTagSerializer.parseFromStr(typeStr, true); if (typeof typeTag !== "object" || !("struct" in typeTag)) throw new Error("Expected struct type tag"); moveObjectType = { Other: typeTag.struct }; } const contents = fromBase64(object.bcs.bcsBytes); const owner = convertOwnerToBcs(object.owner); return suiBcs.Object.serialize({ data: { Move: { type: moveObjectType, hasPublicTransfer: object.bcs.hasPublicTransfer, version: object.bcs.version, contents } }, owner, previousTransaction: object.previousTransaction, storageRebate: object.storageRebate }).toBytes(); } catch { return; } } function parseObject(object, include) { const bcsContent = object.bcs?.dataType === "moveObject" ? fromBase64(object.bcs.bcsBytes) : void 0; const objectBcs = include?.objectBcs ? serializeObjectToBcs(object) : void 0; const type = object.type && object.type.includes("::") ? normalizeStructTag(object.type) : object.type ?? ""; const jsonContent = include?.json && object.content?.dataType === "moveObject" ? object.content.fields : include?.json ? null : void 0; const displayData = include?.display ? object.display?.data != null ? { output: object.display.data, errors: null } : null : void 0; return { objectId: object.objectId, version: object.version, digest: object.digest, type, content: include?.content ? bcsContent : void 0, owner: parseOwner(object.owner), previousTransaction: include?.previousTransaction ? object.previousTransaction ?? void 0 : void 0, objectBcs, json: jsonContent, display: displayData }; } function parseOwner(owner) { if (owner === "Immutable") return { $kind: "Immutable", Immutable: true }; if ("ConsensusAddressOwner" in owner) return { $kind: "ConsensusAddressOwner", ConsensusAddressOwner: { owner: owner.ConsensusAddressOwner.owner, startVersion: owner.ConsensusAddressOwner.start_version } }; if ("AddressOwner" in owner) return { $kind: "AddressOwner", AddressOwner: owner.AddressOwner }; if ("ObjectOwner" in owner) return { $kind: "ObjectOwner", ObjectOwner: owner.ObjectOwner }; if ("Shared" in owner) return { $kind: "Shared", Shared: { initialSharedVersion: owner.Shared.initial_shared_version } }; throw new Error(`Unknown owner type: ${JSON.stringify(owner)}`); } function convertOwnerToBcs(owner) { if (owner === "Immutable") return { Immutable: null }; if ("AddressOwner" in owner) return { AddressOwner: owner.AddressOwner }; if ("ObjectOwner" in owner) return { ObjectOwner: owner.ObjectOwner }; if ("Shared" in owner) return { Shared: { initialSharedVersion: owner.Shared.initial_shared_version } }; if (typeof owner === "object" && owner !== null && "ConsensusAddressOwner" in owner) return { ConsensusAddressOwner: { startVersion: owner.ConsensusAddressOwner.start_version, owner: owner.ConsensusAddressOwner.owner } }; throw new Error(`Unknown owner type: ${JSON.stringify(owner)}`); } function parseOwnerAddress(owner) { if (owner === "Immutable") return null; if ("ConsensusAddressOwner" in owner) return owner.ConsensusAddressOwner.owner; if ("AddressOwner" in owner) return owner.AddressOwner; if ("ObjectOwner" in owner) return owner.ObjectOwner; if ("Shared" in owner) return null; throw new Error(`Unknown owner type: ${JSON.stringify(owner)}`); } function parseTransaction(transaction, include) { const objectTypes = {}; if (include?.objectTypes) transaction.objectChanges?.forEach((change) => { if (change.type !== "published") objectTypes[change.objectId] = normalizeStructTag(change.objectType); }); let transactionData; let signatures = []; let bcsBytes; if (transaction.rawTransaction) { const parsedTx = suiBcs.SenderSignedData.parse(fromBase64(transaction.rawTransaction))[0]; signatures = parsedTx.txSignatures; if (include?.transaction || include?.bcs) { const bytes = suiBcs.TransactionData.serialize(parsedTx.intentMessage.value).toBytes(); if (include?.bcs) bcsBytes = bytes; if (include?.transaction) transactionData = { ...TransactionDataBuilder.restore({ version: 2, sender: parsedTx.intentMessage.value.V1.sender, expiration: parsedTx.intentMessage.value.V1.expiration, gasData: parsedTx.intentMessage.value.V1.gasData, inputs: parsedTx.intentMessage.value.V1.kind.ProgrammableTransaction.inputs, commands: parsedTx.intentMessage.value.V1.kind.ProgrammableTransaction.commands }) }; } } const status = transaction.effects?.status ? parseJsonRpcExecutionStatus(transaction.effects.status, transaction.effects.abortError) : { success: false, error: { $kind: "Unknown", message: "Unknown", Unknown: null } }; const effectsBytes = transaction.rawEffects ? new Uint8Array(transaction.rawEffects) : null; const result = { digest: transaction.digest, epoch: transaction.effects?.executedEpoch ?? null, status, effects: include?.effects && effectsBytes ? parseTransactionEffectsBcs(effectsBytes) : void 0, objectTypes: include?.objectTypes ? objectTypes : void 0, transaction: transactionData, bcs: bcsBytes, signatures, balanceChanges: include?.balanceChanges ? transaction.balanceChanges?.map((change) => ({ coinType: normalizeStructTag(change.coinType), address: parseOwnerAddress(change.owner), amount: change.amount })) ?? [] : void 0, events: include?.events ? transaction.events?.map((event) => ({ packageId: event.packageId, module: event.transactionModule, sender: event.sender, eventType: event.type, bcs: "bcs" in event ? fromBase64(event.bcs) : new Uint8Array(), json: event.parsedJson ?? null })) ?? [] : void 0 }; return status.success ? { $kind: "Transaction", Transaction: result } : { $kind: "FailedTransaction", FailedTransaction: result }; } function parseTransactionEffectsJson({ bytes, effects, objectChanges }) { const changedObjects = []; const unchangedConsensusObjects = []; const objectTypes = {}; objectChanges?.forEach((change) => { switch (change.type) { case "published": changedObjects.push({ objectId: change.packageId, inputState: "DoesNotExist", inputVersion: null, inputDigest: null, inputOwner: null, outputState: "PackageWrite", outputVersion: change.version, outputDigest: change.digest, outputOwner: null, idOperation: "Created" }); break; case "transferred": changedObjects.push({ objectId: change.objectId, inputState: "Exists", inputVersion: change.version, inputDigest: change.digest, inputOwner: { $kind: "AddressOwner", AddressOwner: change.sender }, outputState: "ObjectWrite", outputVersion: change.version, outputDigest: change.digest, outputOwner: parseOwner(change.recipient), idOperation: "None" }); objectTypes[change.objectId] = normalizeStructTag(change.objectType); break; case "mutated": changedObjects.push({ objectId: change.objectId, inputState: "Exists", inputVersion: change.previousVersion, inputDigest: null, inputOwner: parseOwner(change.owner), outputState: "ObjectWrite", outputVersion: change.version, outputDigest: change.digest, outputOwner: parseOwner(change.owner), idOperation: "None" }); objectTypes[change.objectId] = normalizeStructTag(change.objectType); break; case "deleted": changedObjects.push({ objectId: change.objectId, inputState: "Exists", inputVersion: change.version, inputDigest: effects.deleted?.find((d) => d.objectId === change.objectId)?.digest ?? null, inputOwner: null, outputState: "DoesNotExist", outputVersion: null, outputDigest: null, outputOwner: null, idOperation: "Deleted" }); objectTypes[change.objectId] = normalizeStructTag(change.objectType); break; case "wrapped": changedObjects.push({ objectId: change.objectId, inputState: "Exists", inputVersion: change.version, inputDigest: null, inputOwner: { $kind: "AddressOwner", AddressOwner: change.sender }, outputState: "ObjectWrite", outputVersion: change.version, outputDigest: effects.wrapped?.find((w) => w.objectId === change.objectId)?.digest ?? null, outputOwner: { $kind: "ObjectOwner", ObjectOwner: change.sender }, idOperation: "None" }); objectTypes[change.objectId] = normalizeStructTag(change.objectType); break; case "created": changedObjects.push({ objectId: change.objectId, inputState: "DoesNotExist", inputVersion: null, inputDigest: null, inputOwner: null, outputState: "ObjectWrite", outputVersion: change.version, outputDigest: change.digest, outputOwner: parseOwner(change.owner), idOperation: "Created" }); objectTypes[change.objectId] = normalizeStructTag(change.objectType); break; } }); return { objectTypes, effects: { bcs: bytes ?? null, version: 2, status: parseJsonRpcExecutionStatus(effects.status, effects.abortError), gasUsed: effects.gasUsed, transactionDigest: effects.transactionDigest, gasObject: { objectId: effects.gasObject?.reference.objectId, inputState: "Exists", inputVersion: null, inputDigest: null, inputOwner: null, outputState: "ObjectWrite", outputVersion: effects.gasObject.reference.version, outputDigest: effects.gasObject.reference.digest, outputOwner: parseOwner(effects.gasObject.owner), idOperation: "None" }, eventsDigest: effects.eventsDigest ?? null, dependencies: effects.dependencies ?? [], lamportVersion: effects.gasObject.reference.version, changedObjects, unchangedConsensusObjects, auxiliaryDataDigest: null } }; } function parseNormalizedSuiMoveType(type) { if (typeof type !== "string") { if ("Reference" in type) return { reference: "immutable", body: parseNormalizedSuiMoveTypeBody(type.Reference) }; if ("MutableReference" in type) return { reference: "mutable", body: parseNormalizedSuiMoveTypeBody(type.MutableReference) }; } return { reference: null, body: parseNormalizedSuiMoveTypeBody(type) }; } function parseNormalizedSuiMoveTypeBody(type) { switch (type) { case "Address": return { $kind: "address" }; case "Bool": return { $kind: "bool" }; case "U8": return { $kind: "u8" }; case "U16": return { $kind: "u16" }; case "U32": return { $kind: "u32" }; case "U64": return { $kind: "u64" }; case "U128": return { $kind: "u128" }; case "U256": return { $kind: "u256" }; } if (typeof type === "string") throw new Error(`Unknown type: ${type}`); if ("Vector" in type) return { $kind: "vector", vector: parseNormalizedSuiMoveTypeBody(type.Vector) }; if ("Struct" in type) return { $kind: "datatype", datatype: { typeName: `${normalizeSuiAddress(type.Struct.address)}::${type.Struct.module}::${type.Struct.name}`, typeParameters: type.Struct.typeArguments.map((t) => parseNormalizedSuiMoveTypeBody(t)) } }; if ("TypeParameter" in type) return { $kind: "typeParameter", index: type.TypeParameter }; throw new Error(`Unknown type: ${JSON.stringify(type)}`); } function parseAbilities(abilitySet) { return abilitySet.abilities.map((ability) => { switch (ability) { case "Copy": return "copy"; case "Drop": return "drop"; case "Store": return "store"; case "Key": return "key"; default: return "unknown"; } }); } function parseVisibility(visibility) { switch (visibility) { case "Public": return "public"; case "Private": return "private"; case "Friend": return "friend"; default: return "unknown"; } } //#endregion export { JSONRpcCoreClient }; //# sourceMappingURL=core.mjs.map