Track a Sui coin object through a split and merge

An indexer that treats each coin ID as a permanent account misreads merges as losses. Coin objects carry value, and a move of value can create or delete an object identity.

Follow the surviving objects

Assume source starts at 100 and target at 20 base units of the same coin type. Splitting 30 leaves 70 in source. Joining the new coin into target raises target to 50. The temporary payment_id no longer identifies a live coin after the join.

let payment = sui::coin::split(&mut source, 30, ctx);
let payment_id = object::id(&payment);
sui::coin::join(&mut target, payment);
assert!(sui::coin::value(&target) == 50, 0);

Reconcile quantities at the owner and type level

The two final balances add to the initial 120. Attribute any ownership changes separately from object creation or deletion. If the currency is SUI and one of the objects pays gas, incorporate the transaction’s gas effects before testing conservation across wallet holdings. The calculation above assumes separate gas payment.

Sources