Skip to main content

Understanding Updates in Append-Only Storage

OnchainDB uses append-only storage. Updates do NOT modify existing data. Instead, a NEW record with the same ID and a newer timestamp is appended. The SDK’s findUnique() and findMany() automatically return the latest version.

updateDocument

Update an existing document by appending a new version.
const updated = await client.updateDocument(
  'users',
  { email: 'alice@example.com' }, // where
  { name: 'Alice Smith', active: false }, // data to update
  {
    payment_tx_hash: 'tx_hash',
    user_address: 'celestia1...',
    broker_address: 'celestia1broker...',
    amount_utia: 50000
  }
);

if (updated) {
  console.log('Updated user:', updated.name);
} else {
  console.log('User not found');
}

Parameters

ParameterTypeDescription
collectionstringCollection name
whereobjectFilter to find document
dataobjectFields to update
paymentProofPaymentProofPayment information

Return Value

Returns T | null - the updated document if found, or null if not found.

upsertDocument

Create if not exists, update if exists.
const user = await client.upsertDocument(
  'users',
  { email: 'bob@example.com' }, // where
  { email: 'bob@example.com', name: 'Bob', active: true }, // create
  { active: true }, // update
  paymentProof
);

console.log('User upserted:', user.id);

How Updates Work

Original Record (Block 100):
{ id: "user_1", name: "Alice", email: "alice@example.com", updatedAt: "2024-01-01" }

After updateDocument (Block 101):
{ id: "user_1", name: "Alice Smith", email: "alice@example.com", updatedAt: "2024-01-02" }

Both records exist on-chain, but queries return the latest (Block 101)

Examples

Update Single Field

const updated = await client.updateDocument(
  'users',
  { id: 'user_123' },
  { lastLoginAt: new Date().toISOString() },
  paymentProof
);

Conditional Update Pattern

const user = await client.findUnique('users', { id: 'user_123' });

if (user && user.active) {
  await client.updateDocument(
    'users',
    { id: 'user_123' },
    { lastActiveAt: new Date().toISOString() },
    paymentProof
  );
}

Historical Data

Since updates append new records, you can query historical versions:
const allVersions = await client.queryBuilder()
  .collection('users')
  .whereField('id').equals('user_123')
  .includeHistory()
  .execute();

// Sort by updatedAt to see history
const history = allVersions.records.sort(
  (a, b) => new Date(a.updatedAt).getTime() - new Date(b.updatedAt).getTime()
);

Next Steps