Start with the TypeScript SDK¶
The TypeScript SDK allows you to write TypeScript code that interfaces with one of the Golem DB chain. You can use it to store entities, update them, and delete them.
In the following instructions, we will:
- Set up your environment using the Bun runtime.
- Create TypeScript code that performs typical CRUD operations on Golem DB.
- Add funds from a "faucet" for our test network, Kaolin.
- Optionally run the code (unless you already have a private key with funds).
This will provide an easy starting point that you can build on for your own applications.
Configure the TypeScript environment¶
We recommend bun
as the runtime environment to simplify the example as much as possible. bun
interprets TypeScript directly—no transpilation, no tsconfig
needed. If you don't have bun
yet, you can install it following the instructions at bun.sh. Assuming you have bun
installed:
Then add the dependencies:
This will install the required modules and create a package.json for later updates and installs.
Finally, create a file (e.g., crud.ts
). Open your favorite editor and define some initial variables that we’ll use in the next steps:
import { createClient, AccountData, Tagged, GolemBaseCreate, Annotation, GolemBaseUpdate } from 'golem-base-sdk'
import { randomUUID } from 'crypto'
const key: AccountData = new Tagged(
"privatekey",
Buffer.from('<YOUR_PRIVATE_KEY>', 'hex')
) // TODO: replace with your private key, this variable will be used in the mutations operations
const chainId = 60138453025 // ID of the chain of our public testnet - Kaolin
const rpcUrl = "https://kaolin.holesky.golemdb.io/rpc" // RPC URL of the chain
const wsUrl = "wss://kaolin.holesky.golemdb.io/rpc/ws" // WebSocket URL of the chain
// TextEncoder and TextDecoder are used to encode and decode data from text into bytes and vice versa
const encoder = new TextEncoder()
const decoder = new TextDecoder()
CRUD operations on Golem DB¶
To perform any operation on Golem DB, we need to create a connected client first:
// Create a client to interact with the GolemDB API
const client = await createClient(
chainId,
key,
rpcUrl,
wsUrl,
);
Adding new entity¶
Once the client is ready, we can create an example entity and store it in Golem DB chain:
// Create a new entity with annotations
const id = randomUUID()
const creates = [
{
data: encoder.encode("Test entity"),
btl: 600,
stringAnnotations: [new Annotation("testTextAnnotation", "demo"), new Annotation("id", id)],
numericAnnotations: [new Annotation("version", 1)]
} as GolemBaseCreate]
const createReceipt = await client.createEntities(creates);
console.log('Receipt', createReceipt)
client.createEntities: This function sends a transaction to the chain containing a properly constructed data
field and metadata that allows Golem DB to interpret it correctly.
It takes a list of GolemBaseCreate objects, each with 4 fields (you can include multiple entities in one transaction if desired):
- data: Payload in bytes
- btl: Block-To-Live, the number of blocks the entity will exist (each block is created every ~2 seconds, so BTL can be translated into an expiration time)
- stringAnnotations: List of text annotations used for querying data
- numericAnnotations: List of numeric annotations used for querying data
If successful, you should receive a receipt of the transaction containing this storage operation.
Query the entity by annotations¶
As entities are unstructured payloads, annotations are used to query them. To query the previously created entity:
// Query the entity by annotations
let entities = await client.queryEntities(`id = "${id}" && version = 1`)
let entityKey: `0x${string}` | null = null
for (const entity of entities) {
console.log('Entity value', decoder.decode(entity.storageValue))
entityKey = entity.entityKey
}
client.queryEntities: This function takes a query string where annotations can be used with the equality (=
) predicate. The <
and >
operators are also supported, and multiple predicates can be combined using &&
and ||
.
Updating the entity¶
Updating an entity is very similar to creating one, with one extra parameter — the entityKey of the entity to update.
// Update the entity
const updateReceipt = await client.updateEntities([{
entityKey: createReceipt[0].entityKey,
data: encoder.encode("Updated entity"),
btl: 1200,
stringAnnotations: [new Annotation("id", id)],
numericAnnotations: [new Annotation("version", 2)]
} as GolemBaseUpdate])
console.log('Update', updateReceipt)
Updating an entity overrides all of its elements, including the payload, annotations, and BTL.
Deleting the entity¶
To delete an entity, call client.deleteEntities and provide the hex-encoded hash (entity key) of the entity you want to remove:
// Delete the entity
const deleteReceipt = await client.deleteEntities([entityKey as `0x${string}`])
console.log('Delete', deleteReceipt)
Adding Funds¶
To run the examples above, you need to provide a private key with some funds (to pay the transaction fees for mutation operations).
There are many ways to create a private key—for example, you can use MetaMask. Once you have the private key for your account, you must top up its balance on the selected DBChain—in our case, Kaolin.
The easiest way to get test funds is to use the Kaolin faucet:
https://kaolin.holesky.golemdb.io/faucet/
Paste your account address and click Request Funds. After a short while, your account will receive some ETH on the testnet.
Run the code¶
Once you have completed the crud.ts
file with the examples above and funded your private key, you can run it with:
The complete example (which also includes watching chain event logs) can be found here:
👉 https://github.com/Golem-Base/golemdb-sdk-demos/tree/main/ts