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
| Parameter | Type | Description |
|---|
collection | string | Collection name |
where | object | Filter to find document |
data | object | Fields to update |
paymentProof | PaymentProof | Payment 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