Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

ProjectsClient handles all write operations. Payments are made via x402 — no API keys required.

Constructor

import { ProjectsClient } from "@inkd/sdk";
 
const client = new ProjectsClient({
  wallet,       // viem WalletClient with account
  publicClient, // viem PublicClient for reading state
  apiUrl?,      // default: "https://api.inkdprotocol.com"
});

createProject

Register a new project on-chain. Costs $5 USDC.

const { projectId, txHash, owner } = await client.createProject({
  name: "my-agent",
  description: "An autonomous trading agent",
  license: "MIT",
  isPublic: true,
  isAgent: true,
  agentEndpoint: "https://my-agent.example.com",
});
 
console.log(`Project #${projectId} → https://basescan.org/tx/${txHash}`);

Parameters

FieldTypeDefaultDescription
namestringrequiredUnique project name (lowercase, no spaces)
descriptionstring""Short project description
licensestring"MIT"SPDX license identifier
isPublicbooleantruePublicly listed in the registry
isAgentbooleanfalseMarks this as an AI agent project
agentEndpointstring""HTTP endpoint for the agent (if isAgent: true)
readmeHashstring""Arweave hash of README content

Returns

{
  projectId:   number;   // On-chain project ID
  txHash:      string;   // Transaction hash
  owner:       string;   // Owner address (your wallet)
  blockNumber: number;
}

upload

Upload content to Arweave. Returns a permanent ar:// hash. Free — cost is covered by the pushVersion fee.

import { readFileSync } from "fs";
 
const data = readFileSync("./dist/agent.js");
 
const { hash, url, bytes } = await client.upload(data, {
  contentType: "application/javascript",
  filename:    "agent.js",
});
 
console.log(hash); // "ar://QmAbc123..."
console.log(url);  // "https://arweave.net/QmAbc123..."

Parameters

FieldTypeDescription
dataUint8Array | Buffer | stringFile content
opts.contentTypestringMIME type (default: application/octet-stream)
opts.filenamestringOptional filename tag on Arweave

Returns

{
  hash:  string;  // "ar://TxId"
  txId:  string;  // Raw Arweave transaction ID
  url:   string;  // "https://arweave.net/TxId"
  bytes: number;  // Upload size in bytes
}

pushVersion

Record a version on-chain with an Arweave content hash. Costs $2 USDC.

const { txHash, tag } = await client.pushVersion(projectId, {
  tag:         "v1.0.0",
  contentHash: "ar://QmAbc123...",  // from upload()
  contentSize: 12345,               // optional, used for dynamic pricing
});

Typical flow

// 1. Upload content
const { hash, bytes } = await client.upload(data, { contentType: "application/json" });
 
// 2. Push version with the hash
const { txHash } = await client.pushVersion(projectId, {
  tag:         "v2.0.0",
  contentHash: hash,
  contentSize: bytes,
});

Parameters

FieldTypeDescription
tagstringVersion tag (e.g. "v1.0.0")
contentHashstringArweave hash (ar://...)
metadataHashstringOptional metadata hash
contentSizenumberBytes (for dynamic pricing display)

Returns

{
  tag:         string;
  contentHash: string;
  txHash:      string;
  blockNumber: number;
}

getProject

Fetch project details (free, no payment).

const project = await client.getProject(7);
 
console.log(project.name);         // "my-agent"
console.log(project.owner);        // "0x..."
console.log(project.versionCount); // 3

listProjects

List all projects (free).

const projects = await client.listProjects({ offset: 0, limit: 20 });

estimateUploadCost

Estimate the Arweave cost for a given upload size.

const { total, arweaveCost, markup } = await client.estimateUploadCost(1024 * 100); // 100 KB
console.log(total); // "1844" (USDC with 6 decimals)

Full example

import { ProjectsClient } from "@inkd/sdk";
import { createWalletClient, createPublicClient, http } from "viem";
import { base } from "viem/chains";
import { privateKeyToAccount } from "viem/accounts";
import { readFileSync } from "fs";
 
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const wallet  = createWalletClient({ account, chain: base, transport: http() });
const reader  = createPublicClient({ chain: base, transport: http() });
 
const inkd = new ProjectsClient({ wallet, publicClient: reader });
 
// Create project
const { projectId } = await inkd.createProject({
  name:    "my-autonomous-agent",
  isAgent: true,
  license: "MIT",
});
 
// Upload artifact
const data = readFileSync("./dist/agent.js");
const { hash, bytes } = await inkd.upload(data, {
  contentType: "application/javascript",
  filename:    "agent.js",
});
 
// Push version
const { txHash } = await inkd.pushVersion(projectId, {
  tag:         "v1.0.0",
  contentHash: hash,
  contentSize: bytes,
});
 
console.log(`Published! https://basescan.org/tx/${txHash}`);