A TypeScript client library for Arkiv's blockchains interactions. The Arkiv SDK base strongly on Viem (Viem)[https://github.com/wevm/viem] library - it can be treated as Viem replacement extended of Arkiv's chains specific features.
npm install @arkiv-network/sdk
# or
pnpm install @arkiv-network/sdk
# or
bun add @arkiv-network/sdk
# or
yarn add @arkiv-network/sdkBelow is a tutorial to help you create simple scripts that use Arkiv to query and write data.
For this tutorial, we recommend using Node.js version 22.10.0 or newer (see nodejs.org).
Alternatively, you can use bun, a JavaScript/TypeScript runtime and package manager that natively supports TypeScript without transpilation.
Create a new directory and navigate into it:
mkdir arkiv-sample
cd arkiv-sampleCreate an empty read_example.ts file:
touch read_example.tsInitialize a new JavaScript/TypeScript project:
npm initYou can accept all the default options by pressing Enter at each prompt.
After this step, a package.json file will be created with content similar to:
{
"name": "arkiv-sample",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "",
"type": "commonjs",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
}Modify the "main" entry to "read_example.ts" and set "type" to "module" so your package.json looks like this:
{
"name": "arkiv-sample",
"version": "1.0.0",
"description": "",
"license": "ISC",
"author": "",
"type": "module",
"main": "read_example.ts",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
}
}Install @arkiv-network/sdk using your preferred package manager:
npm install @arkiv-network/sdkThis command will update your package.json with a section like:
"dependencies": {
"@arkiv-network/sdk": "^0.4.4"
}It will also create a node_modules directory with all dependencies installed.
You can now use Arkiv's public client to query data. Paste the following in read_example.ts:
import { createPublicClient, http } from "@arkiv-network/sdk"
import { mendoza } from "@arkiv-network/sdk/chains"
import { eq } from "@arkiv-network/sdk/query"
const publicClient = createPublicClient({
chain: mendoza, // "mendoza" is Arkiv's testnet, used during hackathons at DevConnect 2025 in Buenos Aires
transport: http(),
});
// Get chain ID
const chainId = await publicClient.getChainId();
console.log('Chain ID:', chainId);
// Get entity by key
const entity = await publicClient.getEntity('0xcadb830a3414251d65e5c92cd28ecb648d9e73d85f2203eff631839d5421f9d7');
console.log('Entity:', entity);
// Build and execute a query using QueryBuilder
const query = publicClient.buildQuery();
const result = await query
.where(eq('category', 'documentation'))
.ownedBy('0x6186B0DbA9652262942d5A465d49686eb560834C')
.withAttributes(true)
.withPayload(true)
.limit(10)
.fetch();
console.log('Found entities:', result.entities);
// Pagination - fetch next page
if (result.hasNextPage()) {
await result.next();
console.log('Next page:', result.entities);
}You have several options to run your TypeScript sample:
-
With Node.js (using experimental TypeScript support):
node --experimental-strip-types read_example.ts
-
With Bun (native TypeScript support):
bun read_example.ts
-
Classic Node.js (using transpilation to JavaScript):
- Install TypeScript if you haven't already:
npm install typescript
- Initialize a TypeScript config with default settings:
This will create a
npx tsc --init
tsconfig.jsonfile. You do not need to change its contents. - Transpile your
.tsfiles into.js:This creates anpx tsc --outDir dist
distdirectory containingread_example.js(the transpiled code), along with corresponding type declaration and source map files. - Run the transpiled script:
node dist/read_example.js
- Install TypeScript if you haven't already:
Now let's add storage (write) functionality.
Create a file named write_example.ts with the following content:
import { createPublicClient, createWalletClient, http } from "@arkiv-network/sdk"
import { privateKeyToAccount } from "@arkiv-network/sdk/accounts"
import { mendoza } from "@arkiv-network/sdk/chains"
import { ExpirationTime, jsonToPayload } from "@arkiv-network/sdk/utils"
// Create a public client
const publicClient = createPublicClient({
chain: mendoza, // mendoza is the Arkiv testnet for the purposes of hackathons organized in Buenos Aires during devconnect 2025
transport: http(),
})
// Create a wallet client with an account
const client = createWalletClient({
chain: mendoza,
transport: http(),
account: privateKeyToAccount('0x...'), // Replace with your private key
});
// Create an entity
const { entityKey, txHash } = await client.createEntity({
payload: jsonToPayload({
entity: {
entityType: 'document',
entityId: 'doc-123',
entityContent: "Hello from DevConnect Hackathon 2025! Arkiv Mendoza chain wishes you all the best!"
},
}),
contentType: 'application/json',
attributes: [
{ key: 'category', value: 'documentation' },
{ key: 'version', value: '1.0' },
],
expiresIn: ExpirationTime.fromDays(30), // Entity expires in 30 days
});
console.log('Created entity:', entityKey);
console.log('Transaction hash:', txHash);
const newEntity = await publicClient.getEntity(entityKey);
console.log('Entity:', newEntity);Now you can run it in the same way as in the previous example:
-
With Node.js (using experimental TypeScript support):
node --experimental-strip-types write_example.ts
-
With Bun (native TypeScript support):
bun write_example.ts
-
Classic Node.js (using transpilation to JavaScript):
npx tsc --outDir dist node dist/write_example.js
Note:
You must provide your own private key with a minimum balance on the Arkiv L3 network.
You can generate a private key using any tool, for example: https://vanity-eth.tk/
Once you have a key, you can paste it into the example above and fund its address using the Arkiv Mendoza testnet faucet at:
https://mendoza.hoodi.arkiv.network/faucet/
For quick testing, you may use this example key:
0x3d05798f7d11bb1c10b83fed8d3b4d76570c31cd66c8e0a8d8d991434c6d7a5e
However, funds may not always be available for this key.
Sample code can also be found in the sample directory of this repository.
This package supports multiple module formats for maximum compatibility:
- ES Modules (
dist/*.js) - For modernimportstatements - CommonJS (
dist/*.cjs) - For Node.jsrequire() - Type Declarations (
dist/*.d.tsanddist/*.d.cts) - Full TypeScript support
The build uses tsdown to generate both ESM and CommonJS formats with proper type declarations.
Node.js (ESM):
import { createPublicClient } from '@arkiv-network/sdk'; // Uses compiled ESMNode.js (CommonJS):
const { createPublicClient } = require('@arkiv-network/sdk'); // Uses compiled CJSBun (TypeScript native):
import { createPublicClient } from '@arkiv-network/sdk'; // Uses *.ts directlyAll formats provide full type safety and IntelliSense support when using TypeScript.
To install dependencies:
bun installTo build all outputs (ESM, CommonJS, and type declarations):
bun run buildFor more information about building this SDK refer to: BUILD.md
To run type checking:
bun run type-checkTo lint:
bun run lintFor more information about refer to: CONTRIBUTING.md
The SDK uses debug under the hood. Set the DEBUG environment variable to view verbose logs:
DEBUG=arkiv:* bun run your-scriptAdjust the namespace (for example, arkiv:rpc or arkiv:query) to target specific log sources. Unset DEBUG to silence debug output.