Overview
Sui is deprecating its JSON-RPC interface in favor of gRPC. As a result, there are some changes to thesui.raw data.
Cutover timeline
1
Mainnet cutover — 19 August 2026
sui.raw.* switches to the gRPC source. Update affected queries beforehand.Summary of Changes
Look up the table(s) you query. If a table isn’t listed, there are no changes.checkpoints
No action required. One field becomes richer:checkpoint_commitments— previously always an empty array ([]); now populated with the per-checkpoint commitment digest.
checkpoints is unchanged.
transactions
Thetransaction column holds a single Programmable Transaction Block (PTB) command, surfaced through transaction_key (the command name) and transaction_value (the command body). Both change shape.
What changes
- Command key casing — command names are camelCase instead of PascalCase, so
transaction_key’s value changes:MoveCall→moveCall,SplitCoins→splitCoins,TransferObjects→transferObjects,MergeCoins→mergeCoins,MakeMoveVec→makeMoveVector,Publish→publish,Upgrade→upgrade. - Field naming inside the command —
type_arguments→typeArguments. - Argument shape — arguments carry an explicit
kindand use different key names.
package, module, and function values inside a command are unchanged.
What to do
- Make
transaction_keyfilters case-insensitive:LOWER(transaction_key) = 'movecall'(instead of= 'MoveCall'). An exact= 'MoveCall'match will silently return zero rows after cutover. - Update
transaction_valuepath reads:type_arguments→typeArguments; adjust for the new argument encoding.package/module/functionneed no change.
transaction_value — old vs new shape
transaction_value — old vs new shape
Old (JSON-RPC):New (gRPC):The
package, module, function, and type-argument values are unchanged — only the keys (MoveCall→moveCall, type_arguments→typeArguments) and the argument wrapper differ.Example: updating a MoveCall filter
Example: updating a MoveCall filter
Before:After:
transaction_blocks
This is the most affected table. The nestedtransaction and effects objects move to the native gRPC shape, and the top-level columns derived from them change accordingly.
What to do
- If you read the
transactionVARIANT:data.sender→sender,data.gasData→gasPayment,data.transaction.transactions→kind.programmableTransaction.commands(plus the PTB command changes from transactions). - If you read the
effectsVARIANT:statusflips to{ "success": true/false };executedEpoch→epoch;messageVersion→version; andmutated/created/sharedObjects/modifiedAtVersionsare derived fromchangedObjects+unchangedConsensusObjects. - If you read the flattened top-level columns: check the column table below — most values are unchanged, but
message_version,kind, andtx_signatureschange.
transaction envelope — old vs new shape
transaction envelope — old vs new shape
Old (JSON-RPC) — sender, gas, and the PTB live under a New (gRPC) — flattened: Key path changes:
data object, with txSignatures alongside:sender, gasPayment, kind at the top level, no data wrapper, and a version/digest/bcs/expiration set:data.sender → sender; data.gasData → gasPayment (and payment → objects); data.transaction.kind → kind.kind (value ProgrammableTransaction → PROGRAMMABLE_TRANSACTION); data.transaction.transactions → kind.programmableTransaction.commands; data.messageVersion: "v1" → top-level version: 1.effects — key set and status shape
effects — key set and status shape
status (execution result):effects keys:To reconstruct the old
mutated / created / sharedObjects / modifiedAtVersions arrays, derive them from changedObjects (grouped by id-operation / input-output state) and unchangedConsensusObjects.Flattened top-level columns — what changes
Flattened top-level columns — what changes
Several top-level columns are extracted from inside
transaction / effects. They remain populated across the cutover (Allium reads both the old and new source paths), but a few carry different values or nested shapes for gRPC rows:raw_transaction / raw_effects — BCS envelope change
raw_transaction / raw_effects — BCS envelope change
These are the BCS-serialized transaction and effects. The gRPC and JSON-RPC APIs serialize them with different BCS envelopes / type versions, so the base64 bytes differ even though they decode to equivalent data.
raw_transaction— gRPC emits the innerTransactionDataBCS; JSON-RPC emitted the fullSenderSignedDataenvelope (transaction + signatures).raw_effects— gRPC emitsTransactionEffectsin a newer BCS variant; the byte layout differs from the JSON-RPC form.
sui.rpc.v2) types.events
Onlyparsed_json is affected, and only where an event’s Move type contains certain field kinds. Scalar fields, addresses, and numeric-string fields are unchanged. The event’s bcs field is byte-identical on both sources, so the underlying data is unchanged — only the parsed_json rendering differs.
What changes
vector<u8>(byte vectors) — a JSON array of byte integers under JSON-RPC, a base64 string under gRPC. Affected event types skew toward bridge / oracle events (e.g. WormholeTransferRedeemed, PythPriceFeedUpdateEvent) that carry raw byte payloads.- Single-field wrapper structs inside a vector — flattened by gRPC (
[{ "name": "X" }]→[ "X" ]).
- If you read a
vector<u8>field, base64-decode the string to recover the bytes. - Watch for flattened single-field wrapper structs.
vector<u8> — old vs new rendering
vector<u8> — old vs new rendering
A byte-vector field (e.g. a Wormhole emitter address, a Pyth price-feed id, a payload):
single-field wrapper struct in a vector — old vs new
single-field wrapper struct in a vector — old vs new
object_changes
No action required. The changes here are additive or preserved:- Additive rows — a small number of additional object changes are surfaced: object-owned (dynamic-field) mutations, plus rare
publishedrows that now carry a populatedobject_id/object_typewhere they were previously null. Row counts may be slightly higher on affected transactions (roughly ~1 in 100k rows);object_changes_countontransaction_blocksreflects this. No existing row’s values change. owner— preserved. At the gRPC source, consensus-owned objects report{ "AddressOwner": "0x…" }(dropping the ownership variant and itsstart_version). Allium restores the JSON-RPC form{ "ConsensusAddressOwner": { "owner": "0x…", "start_version": … } }during ingestion. Theownerfield is unchanged for all ownership types (AddressOwner,ObjectOwner,Shared,ConsensusAddressOwner,Immutable).
balance_changes
sui.raw.balance_changes is unchanged — no action required.