[ ARKIV DOCS ]

Everything you need to build with Arkiv. From quick start guides to comprehensive API documentation.

Last updated: February 2026 ยท SDK v0.6.0

๐Ÿ“š

SDKs & Libraries

TypeScript and Python SDKs

TypeScript SDK

Installation

bashExample
1bun add @arkiv-network/sdk
2# or
3npm install @arkiv-network/sdk

Browser Usage with MetaMask

Connect to Arkiv from browser applications using MetaMask or other Web3 wallets:

typescriptExample
1import { createWalletClient, createPublicClient, custom, http } from "@arkiv-network/sdk"
2import { kaolin } from "@arkiv-network/sdk/chains"
3import { ExpirationTime, jsonToPayload } from "@arkiv-network/sdk/utils"
4
5if (typeof window.ethereum !== 'undefined') {
6	await window.ethereum.request({ method: 'eth_requestAccounts' })
7}
8
9const walletClient = createWalletClient({
10	chain: kaolin,
11	transport: custom(window.ethereum),
12})
13
14const { entityKey, txHash } = await walletClient.createEntity({
15	payload: jsonToPayload({ message: 'Hello from MetaMask!' }),
16	contentType: 'application/json',
17	attributes: [{ key: 'type', value: 'greeting' }],
18	expiresIn: ExpirationTime.fromMinutes(30),
19})
20
21console.log('Created entity:', entityKey)
22
23const publicClient = createPublicClient({
24	chain: kaolin,
25	transport: http(),
26})
27
28const entity = await publicClient.getEntity(entityKey)
29console.log('Entity data:', JSON.parse(entity.payload))

Adding Arkiv Network to MetaMask

Users need to add Arkiv network to MetaMask before using your dApp:

typescriptExample
1async function addArkivNetwork() {
2	try {
3		await window.ethereum.request({
4			method: 'wallet_addEthereumChain',
5			params: [{
6				chainId: '0xe0087f821',
7				chainName: 'Arkiv Kaolin Testnet',
8				nativeCurrency: {
9					name: 'ETH',
10					symbol: 'ETH',
11					decimals: 18
12				},
13				rpcUrls: ['https://kaolin.hoodi.arkiv.network/rpc'],
14				blockExplorerUrls: ['https://explorer.kaolin.hoodi.arkiv.network']
15			}]
16		})
17	} catch (error) {
18		console.error('Failed to add network:', error)
19	}
20}
21
22await addArkivNetwork()

React Hook Example

typescriptExample
1import { useState, useEffect } from 'react'
2import { createWalletClient, createPublicClient, custom, http } from "@arkiv-network/sdk"
3import { kaolin } from "@arkiv-network/sdk/chains"
4
5export function useArkiv() {
6	const [walletClient, setWalletClient] = useState(null)
7	const [account, setAccount] = useState(null)
8	const [isConnected, setIsConnected] = useState(false)
9
10	const publicClient = createPublicClient({
11		chain: kaolin,
12		transport: http(),
13	})
14
15	const connect = async () => {
16		if (typeof window.ethereum === 'undefined') {
17			alert('Please install MetaMask!')
18			return
19		}
20
21		try {
22			const accounts = await window.ethereum.request({
23				method: 'eth_requestAccounts'
24			})
25
26			const client = createWalletClient({
27				chain: kaolin,
28				transport: custom(window.ethereum),
29			})
30
31			setWalletClient(client)
32			setAccount(accounts[0])
33			setIsConnected(true)
34		} catch (error) {
35			console.error('Failed to connect:', error)
36		}
37	}
38
39	const disconnect = () => {
40		setWalletClient(null)
41		setAccount(null)
42		setIsConnected(false)
43	}
44
45	useEffect(() => {
46		if (typeof window.ethereum !== 'undefined') {
47			window.ethereum.on('accountsChanged', (accounts) => {
48				if (accounts.length === 0) {
49					disconnect()
50				} else {
51					setAccount(accounts[0])
52				}
53			})
54		}
55	}, [])
56
57	return {
58		walletClient,
59		publicClient,
60		account,
61		isConnected,
62		connect,
63		disconnect
64	}
65}

Node.js / Backend Usage

For server-side or backend applications, use private key authentication:

typescriptExample
1import { createWalletClient, http } from "@arkiv-network/sdk"
2import { privateKeyToAccount } from "@arkiv-network/sdk/accounts"
3import { kaolin } from "@arkiv-network/sdk/chains"
4import { ExpirationTime, jsonToPayload } from "@arkiv-network/sdk/utils"
5
6const walletClient = createWalletClient({
7	chain: kaolin,
8	transport: http(),
9	account: privateKeyToAccount(process.env.PRIVATE_KEY),
10})
11
12const { entityKey } = await walletClient.createEntity({
13	payload: jsonToPayload({ message: 'Hello from Node.js!' }),
14	contentType: 'application/json',
15	attributes: [{ key: 'type', value: 'server' }],
16	expiresIn: ExpirationTime.fromHours(24),
17})

Quickstart

typescriptExample
1import { createWalletClient, http } from "@arkiv-network/sdk"
2import { privateKeyToAccount } from "@arkiv-network/sdk/accounts"
3import { kaolin } from "@arkiv-network/sdk/chains"
4import { ExpirationTime, jsonToPayload } from "@arkiv-network/sdk/utils"
5
6const walletClient = createWalletClient({
7	chain: kaolin,
8	transport: http(),
9	account: privateKeyToAccount(process.env.PRIVATE_KEY),
10})
11
12const noteData = { title: "My Note", content: "Hello Arkiv!" }
13const { entityKey, txHash } = await walletClient.createEntity({
14	payload: jsonToPayload(noteData),
15	contentType: 'application/json',
16	attributes: [
17		{ key: 'type', value: 'note' },
18		{ key: 'id', value: crypto.randomUUID() },
19		{ key: 'created', value: Date.now() }
20	],
21	expiresIn: ExpirationTime.fromHours(12),
22})
23
24console.log('Entity created:', entityKey)

Read-Only Client

For applications that only need to query data without writing, use createPublicClient:

typescriptExample
1import { createPublicClient, http } from "@arkiv-network/sdk"
2import { kaolin } from "@arkiv-network/sdk/chains"
3import { eq } from "@arkiv-network/sdk/query"
4
5const publicClient = createPublicClient({
6	chain: kaolin,
7	transport: http(),
8})
9
10const query = publicClient.buildQuery()
11const publicData = await query
12	.where(eq('type', 'public'))
13	.withAttributes(true)
14	.withPayload(true)
15	.fetch()
16
17const unwatch = publicClient.watchEntities({
18	onCreated: (event) => console.log("New entity:", event.entityKey),
19	pollingInterval: 2000
20})

Benefits:

  • No private key required
  • Safe for frontend/public use
  • Prevents accidental writes
  • Ideal for analytics and monitoring

Query Data

typescriptExample
1import { gt } from "@arkiv-network/sdk/query"
2
3const query = publicClient.buildQuery()
4const notes = await query
5	.where(eq('type', 'note'))
6	.where(gt('created', 1672531200))
7	.withPayload(true)
8	.fetch()
9
10for (const entity of notes) {
11	const data = JSON.parse(entity.payload)
12	console.log(`Note: ${data.title} - ${data.content}`)
13}

Update Data

typescriptExample
1const updatedData = {
2	title: "Updated Note",
3	content: "This note has been updated"
4}
5
6const { txHash } = await walletClient.updateEntity({
7	entityKey: entityKey,
8	payload: jsonToPayload(updatedData),
9	contentType: 'application/json',
10	attributes: [
11		{ key: 'type', value: 'note' },
12		{ key: 'updated', value: Date.now() }
13	],
14	expiresIn: ExpirationTime.fromHours(24),
15})
16
17console.log('Updated, tx:', txHash)

Delete Data

typescriptExample
1const { txHash } = await walletClient.deleteEntity({
2	entityKey: entityKey
3})
4
5console.log('Entity deleted, tx:', txHash)

Real-time Events

typescriptExample
1const unwatch = publicClient.watchEntities({
2	onCreated: (event) => console.log("Created:", event.entityKey),
3	onUpdated: (event) => console.log("Updated:", event.entityKey),
4	onDeleted: (event) => console.log("Deleted:", event.entityKey),
5	pollingInterval: 2000
6})

Batch Operations

typescriptExample
1const createPromises = Array.from({ length: 5 }, (_, i) =>
2	walletClient.createEntity({
3		payload: jsonToPayload({ content: `Batch item ${i}` }),
4		contentType: 'application/json',
5		attributes: [
6			{ key: 'type', value: 'batch' },
7			{ key: 'index', value: i }
8		],
9		expiresIn: ExpirationTime.fromMinutes(30),
10	})
11)
12
13const results = await Promise.all(createPromises)
14console.log(`Created ${results.length} entities`)

Expires In Management

typescriptExample
1const { txHash } = await walletClient.extendEntity({
2	entityKey: entityKey,
3	additionalTime: ExpirationTime.fromHours(24)
4})
5
6console.log('Extended, tx:', txHash)

Python SDK

pythonExample
1from arkiv_sdk import create_client, Tagged, Annotation
2from arkiv_sdk.types import AccountData, ArkivCreate
3import os
4
5raw_key = os.getenv('PRIVATE_KEY', '')
6hex_key = raw_key[2:] if raw_key.startswith('0x') else raw_key
7key: AccountData = Tagged("privatekey", bytes.fromhex(hex_key))
8
9client = await create_client(
10		60138453056,
11		key,
12		"https://mendoza.hoodi.arkiv.network/rpc",
13		"wss://mendoza.hoodi.arkiv.network/rpc/ws"
14)
15
16creates = [
17		ArkivCreate(
18				data=b"Hello from Python!",
19				expires_in=43200,
20				string_annotations=[
21						Annotation("type", "greeting"),
22						Annotation("language", "python")
23				],
24				numeric_annotations=[]
25		)
26]
27
28receipts = await client.create_entities(creates)
29print(f"Created entity: {receipts[0].entity_key}")
30
31from arkiv_sdk import create_ro_client
32
33ro_client = await create_ro_client(
34		60138453056,
35		"https://mendoza.hoodi.arkiv.network/rpc",
36		"wss://mendoza.hoodi.arkiv.network/rpc/ws"
37)
38
39entities = await ro_client.query_entities('type = "greeting"')
40for entity in entities:
41		print(f"Entity: {entity.entity_key}")

SDK Comparison

FeatureTypeScriptPython
StatusProductionProduction
CRUD OperationsFull SupportFull Support
Real-time EventsWebSocketWebSocket
Batch OperationsSupportedSupported
Type SafetyTypeScriptType Hints
Use CasesWeb, APIs, Node.jsData Science, Backend

Resources: Getting Started โ€” NPM Package โ€” GitHub โ€” Discord