npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@arkiv-network/sdk

v0.8.1

Published

TypeScript client library for Arkiv's blockchains interactions

Readme

arkivjs

A TypeScript client library for Arkiv's blockchains interactions. The Arkiv SDK builds strongly on the Viem library - it extends Viem's clients with Arkiv's chain-specific features.

viem is a peer dependency: install it alongside the SDK.

Installation

npm install @arkiv-network/sdk viem
# or
pnpm install @arkiv-network/sdk viem
# or
bun add @arkiv-network/sdk viem
# or
yarn add @arkiv-network/sdk viem

Usage

Below is a tutorial to help you create simple scripts that use Arkiv to query and write data.

Prerequisites

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.

Project Setup

Create a new directory and navigate into it:

mkdir arkiv-sample
cd arkiv-sample

Create an empty read_example.ts file:

touch read_example.ts

Initialize a new JavaScript/TypeScript project:

npm init

You 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 along with its viem peer dependency using your preferred package manager:

npm install @arkiv-network/sdk viem

This command will update your package.json with a section like:

"dependencies": {
  "@arkiv-network/sdk": "^0.6.0",
  "viem": "^2.38.2"
}

It will also create a node_modules directory with all dependencies installed.

Public Client Example (Query Data)

You can now use Arkiv's public client to query data. Paste the following in read_example.ts:

import { createPublicClient } from "@arkiv-network/sdk"
import { tiramisu } from "@arkiv-network/sdk/chains"
import { eq } from "@arkiv-network/sdk/query"
import { http } from "viem"

const publicClient = createPublicClient({
  chain: tiramisu, // "tiramisu" is Arkiv's testnet
  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 select()
const result = await publicClient
  .select({ owner: true, attributes: true, payload: true })
  .where(eq('category', 'documentation'))
  .ownedBy('0x6186B0DbA9652262942d5A465d49686eb560834C')
  .limit(10)
  .fetch();

console.log('Found entities:', result.entities);

// Pagination
if (result.hasNextPage()) {
  const nextPage = await result.next();
  console.log('Next page:', nextPage.entities);
}

// Or walk every page at once
for await (const entity of publicClient
  .select({ key: true })
  .where(eq('category', 'documentation'))) {
  console.log(entity.key);
}

Selecting fields with select()

Pass nothing (or "*") to fetch everything, or pass an object to fetch only specific fields:

// All fields
await publicClient.select().where(eq("category", "docs")).fetch();

// Only the fields you need
await publicClient.select({ key: true, owner: true, payload: true }).where(eq("category", "docs")).fetch();

Select only what you need. Every selected field is fetched over the network, so requesting data you won't use makes queries slower. Narrowing the selection keeps responses small and fast.

The result type is inferred from your selection: reading a field you didn't select is a compile error. The toText() / toJson() payload helpers are available only when you select payload.

const [entity] = (
  await publicClient.select({ owner: true, payload: true }).where(eq("category", "docs")).fetch()
).entities;
entity.owner;     // ✅ Hex
entity.toJson();  // ✅ payload was selected
entity.creator;   // ❌ compile error — not selected

Footgun: pass the selection inline. A selection stored in a variable widens its true values to boolean, so the result type can't be narrowed (you get {} and a compile error on every field). If you need to reuse one, annotate it as const:

const fields = { owner: true, payload: true } as const;
await publicClient.select(fields).where(eq("category", "docs")).fetch();

Running the Example

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):

    1. Install TypeScript if you haven't already:
      npm install typescript
    2. Initialize a TypeScript config with default settings:
      npx tsc --init
      This will create a tsconfig.json file. You do not need to change its contents.
    3. Transpile your .ts files into .js:
      npx tsc --outDir dist
      This creates a dist directory containing read_example.js (the transpiled code), along with corresponding type declaration and source map files.
    4. Run the transpiled script:
      node dist/read_example.js

Wallet Client Example (Create Entity)

Now let's add storage (write) functionality.
Create a file named write_example.ts with the following content:

import { createPublicClient, createWalletClient } from "@arkiv-network/sdk"
import { dec, i32 } from "@arkiv-network/sdk/attr"
import { tiramisu } from "@arkiv-network/sdk/chains"
import { ExpirationTime, jsonToPayload } from "@arkiv-network/sdk/utils"
import { http } from "viem"
import { privateKeyToAccount } from "viem/accounts"

// Create a public client
const publicClient = createPublicClient({
  chain: tiramisu, // tiramisu is the Arkiv testnet
  transport: http(),
})
// Create a wallet client with an account
const client = createWalletClient({
  chain: tiramisu,
  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 chain wishes you all the best!"
    },
  }),
  contentType: 'application/json',
  // Attributes are keyed by name. Values carry their type: use the tagged constructors from
  // "@arkiv-network/sdk/attr" (i32, u64, u256, dec, str, addr, key, bytes32, bool), or pass a bare
  // boolean, number, bigint or string where the type is unambiguous.
  attributes: {
    category: 'documentation',   // bare string -> str
    version: i32(1),
    score: dec('4.5'),
  },
  expires: 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 on the Arkiv Tiramisu testnet.

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.

Package Distribution

This package supports multiple module formats for maximum compatibility:

  • ES Modules (dist/*.js) - For modern import statements
  • CommonJS (dist/*.cjs) - For Node.js require()
  • Type Declarations (dist/*.d.ts and dist/*.d.cts) - Full TypeScript support

The build uses tsdown to generate both ESM and CommonJS formats with proper type declarations.

Runtime Support

Node.js (ESM):

import { createPublicClient } from '@arkiv-network/sdk';  // Uses compiled ESM

Node.js (CommonJS):

const { createPublicClient } = require('@arkiv-network/sdk');  // Uses compiled CJS

Bun (TypeScript native):

import { createPublicClient } from '@arkiv-network/sdk'; // Uses *.ts directly

All formats provide full type safety and IntelliSense support when using TypeScript.

Development

To install dependencies:

bun install

To build all outputs (ESM, CommonJS, and type declarations):

bun run build

For more information about building this SDK refer to: BUILD.md

To run type checking:

bun run type-check

To lint:

bun run lint

For more information about refer to: CONTRIBUTING.md

Verbose Logging

The SDK uses debug under the hood. Set the DEBUG environment variable to view verbose logs:

DEBUG=arkiv:* bun run your-script

Adjust the namespace (for example, arkiv:rpc or arkiv:query) to target specific log sources. Unset DEBUG to silence debug output.