Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
161 changes: 115 additions & 46 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,38 +1,81 @@
# Atlantic SDK
# hcloud

TypeScript SDK and CLI for the Herodotus Atlantic API.
TypeScript SDK and CLI for [Herodotus Cloud](https://herodotus.cloud).

This package provides two surfaces:
This package gives you a single entrypoint to every Herodotus Cloud service. Each
service is reached through its own namespace on `HcloudClient`.

- A typed SDK for direct Atlantic API calls and higher-level workflow helpers.
- A JSON-first CLI that delegates to the SDK so terminal usage and library usage share behavior.
Today the package ships:

- `client.atlantic.*` — Atlantic proving service (queries, buckets, x402 payments).
- `client.auth.*` — programmatic wallet authentication (EIP-712 → bearer session → API key).

## Installation

```bash
bun add @herodotus_dev/atlantic-sdk
bun add @herodotus_dev/hcloud
```

```bash
npm install @herodotus_dev/atlantic-sdk
npm install @herodotus_dev/hcloud
```

Install the CLI globally:

```bash
npm install -g @herodotus_dev/atlantic-sdk
npm install -g @herodotus_dev/hcloud
```

## Two ways to authenticate

You can either pass an API key directly, or have the SDK obtain one through the
programmatic wallet auth flow. Either path produces the same `client.atlantic.*`
behavior; pick whichever fits your environment.

### Wallet auth (no manual API key)

```ts
import { HcloudClient, privateKeySigner } from '@herodotus_dev/hcloud';

const client = new HcloudClient();

await client.auth.login({
signer: privateKeySigner(process.env.WALLET_PRIVATE_KEY as `0x${string}`),
});

// API key is now persisted at ~/.hcloud/credentials.json (mode 0600).
// Atlantic and future services will use it automatically.
const health = await client.atlantic.healthCheck();
```

`client.auth.login` runs the full EIP-712 challenge → bearer session → API key
flow against `auth-billing` and writes the result to disk. Subsequent runs from
any process on the same machine pick the key up automatically — no re-login
required to keep using Atlantic.

### Explicit API key

```ts
import { HcloudClient } from '@herodotus_dev/hcloud';

const client = new HcloudClient({
apiKey: process.env.HCLOUD_API_KEY,
});
```

Explicit keys win over env vars and persisted credentials. `HCLOUD_API_KEY`
(alias: `ATLANTIC_API_KEY`) is read automatically when no explicit key is passed.

## SDK quickstart

```ts
import { AtlanticClient, submitAndWait } from '@herodotus_dev/atlantic-sdk';
import { HcloudClient, submitAndWait } from '@herodotus_dev/hcloud';

const client = new AtlanticClient({
apiKey: process.env.ATLANTIC_API_KEY,
const client = new HcloudClient({
apiKey: process.env.HCLOUD_API_KEY,
});

const result = await submitAndWait(client, {
const result = await submitAndWait(client.atlantic, {
declaredJobSize: 'S',
pieFile: './pie.zip',
});
Expand All @@ -43,93 +86,119 @@ console.log(result.atlanticQuery.id, result.atlanticQuery.status);
## Direct API usage

```ts
import { AtlanticClient } from '@herodotus_dev/atlantic-sdk';
import { HcloudClient } from '@herodotus_dev/hcloud';

const client = new AtlanticClient({
apiKey: process.env.ATLANTIC_API_KEY,
const client = new HcloudClient({
apiKey: process.env.HCLOUD_API_KEY,
});

const submitted = await client.submitQuery({
const submitted = await client.atlantic.submitQuery({
declaredJobSize: 'S',
pieFile: './pie.zip',
layout: 'dynamic',
});

const details = await client.getQuery(submitted.atlanticQueryId);
const details = await client.atlantic.getQuery(submitted.atlanticQueryId);

console.log(details.atlanticQuery.status, details.metadataUrls);
```

## CLI quickstart

```bash
ATLANTIC_API_KEY=... bunx atlantic submit-query \
--pie-file ./pie.zip \
--declared-job-size S
# One-time wallet auth (writes ~/.hcloud/credentials.json)
WALLET_PRIVATE_KEY=0x... hcloud auth login

# After that, Atlantic commands just work:
hcloud atlantic submit-query --pie-file ./pie.zip --declared-job-size S
```

Every CLI command prints JSON so agents and shell scripts can chain outputs without scraping prose.
You can skip the wallet auth and pass an API key directly:

```bash
HCLOUD_API_KEY=... hcloud atlantic submit-query --pie-file ./pie.zip --declared-job-size S
```

Common commands:
CLI structure is `hcloud <service> <command>`. List service groups with `hcloud --help`,
list commands with `hcloud <service> --help`. Every CLI command prints JSON so agents and
shell scripts can chain outputs without scraping prose.

Common Atlantic commands:

```bash
atlantic get-query-details <query-id>
atlantic get-my-queries --limit 20 --offset 0
atlantic retry-if-retriable <query-id>
atlantic list-buckets
atlantic create-bucket --aggregator-version STONE
atlantic close-bucket <bucket-id>
hcloud atlantic get-query-details <query-id>
hcloud atlantic get-my-queries --limit 20 --offset 0
hcloud atlantic retry-if-retriable <query-id>
hcloud atlantic list-buckets
hcloud atlantic create-bucket --aggregator-version STONE
hcloud atlantic close-bucket <bucket-id>
```

## SDK reference
Common auth commands:

```bash
hcloud auth login --private-key 0x... # or set WALLET_PRIVATE_KEY
hcloud auth whoami # masks api key by default
hcloud auth list # all stored wallets
hcloud auth use 0xabc... # switch active wallet
hcloud auth api-keys list
hcloud auth api-keys create --type-name agent --type-color "#0a0"
hcloud auth refresh # rotate bearer pair
hcloud auth logout --all # wipe credentials
```

### Client
## Atlantic SDK reference

### Service surface

Reached as `client.atlantic` on `HcloudClient`.

- `new AtlanticClient(options)`: Creates a typed Atlantic API client. Configure `baseUrl`, `apiKey`, optional `fetch`, and optional x402 `paymentAdapter`.
- `healthCheck()`: Checks whether Atlantic is reachable. Returns `{ alive }`.
- `submitQuery(input, options)`: Submits a proving query. Accepts program/input/PIE/proof files, Cairo options, result target, declared job size, dedup/external IDs, and bucket fields. Returns the durable `atlanticQueryId` and optional x402 settlement data.
- `getQuery(atlanticQueryId)`: Fetches query details plus metadata URLs.
- `getQueryByDedupId(dedupId)`: Fetches a query by dedup ID. Use API-key flow; anonymous x402 does not support dedup IDs.
- `listQueries({ limit, offset })`: Lists submitted queries with pagination.
- `getQueryStats()`: Fetches query statistics for the configured API key.
- `getQueryJobs(atlanticQueryId)`: Fetches job lifecycle details for a query.
- `retryQuery(atlanticQueryId)`: Requests an API retry for a failed query. Branch on structured errors for wrong state, max retries, not found, and forbidden outcomes.
- `retryQuery(atlanticQueryId)`: Requests an API retry for a failed query.
- `listBuckets({ limit, offset })`: Lists Applicative Recursion buckets.
- `createBucket(input)`: Creates an Applicative Recursion bucket.
- `getBucket(bucketId)`: Fetches a bucket and associated queries.
- `closeBucket(bucketId)`: Closes a bucket.

### Workflow helpers

- `submitAndReturnId(client, input)`: Submit and return the query ID immediately.
- `waitForQuery(client, atlanticQueryId, options)`: Poll until terminal status or timeout. Returns observed statuses and final query details.
- `submitAndWait(client, input, options)`: Submit and wait in one helper while preserving the original submit result.
- `retryIfRetriable(client, atlanticQueryId)`: Fetches current query details and retries only when the query is failed and retriable.
- `getQueryWithJobs(client, atlanticQueryId)`: Fetches query details and query jobs together.
- `submitToBucket(client, input)`: Submits a query into an existing bucket with explicit job index.
- `createBucketAndSubmit(client, input)`: Creates a bucket and submits indexed queries into it.
Free functions that take `client.atlantic` and compose lifecycle behavior.

- `submitAndReturnId(service, input)`: Submit and return the query ID immediately.
- `waitForQuery(service, atlanticQueryId, options)`: Poll until terminal status or timeout. Returns observed statuses and final query details.
- `submitAndWait(service, input, options)`: Submit and wait in one helper while preserving the original submit result.
- `retryIfRetriable(service, atlanticQueryId)`: Fetches current query details and retries only when the query is failed and retriable.
- `getQueryWithJobs(service, atlanticQueryId)`: Fetches query details and query jobs together.
- `submitToBucket(service, input)`: Submits a query into an existing bucket with explicit job index.
- `createBucketAndSubmit(service, input)`: Creates a bucket and submits indexed queries into it.

## x402

The SDK supports Atlantic's x402 flow through a caller-provided payment adapter. It waits for a real `402` challenge, signs the server-provided payment requirement, retries the original submit request with `PAYMENT-SIGNATURE`, and parses `PAYMENT-RESPONSE`.
The Atlantic service supports Atlantic's x402 flow through a caller-provided payment adapter. It waits for a real `402` challenge, signs the server-provided payment requirement, retries the original submit request with `PAYMENT-SIGNATURE`, and parses `PAYMENT-RESPONSE`.

### Private-key adapter

For server-side scripts, CI, or agents with a dedicated payment key, use the built-in private-key adapter:

```ts
import { AtlanticClient, createPrivateKeyPaymentAdapter } from '@herodotus_dev/atlantic-sdk';
import { HcloudClient, createPrivateKeyPaymentAdapter } from '@herodotus_dev/hcloud';

const paymentAdapter = createPrivateKeyPaymentAdapter({
privateKey: process.env.WALLET_PRIVATE_KEY as `0x${string}`,
});

const client = new AtlanticClient({
apiKey: process.env.ATLANTIC_API_KEY,
const client = new HcloudClient({
apiKey: process.env.HCLOUD_API_KEY,
paymentAdapter,
});

const result = await client.submitQuery({
const result = await client.atlantic.submitQuery({
declaredJobSize: 'S',
pieFile: './pie.zip',
});
Expand All @@ -144,7 +213,7 @@ The adapter reads the x402 requirement returned by Atlantic, verifies that `acce
Use a custom adapter when signing should happen through another wallet, custody service, browser wallet, or agent wallet.

```ts
import { AtlanticClient, type X402PaymentAdapter, type X402PaymentPayload } from '@herodotus_dev/atlantic-sdk';
import { HcloudClient, type X402PaymentAdapter, type X402PaymentPayload } from '@herodotus_dev/hcloud';

const paymentAdapter: X402PaymentAdapter = {
async createPayment({ requirement }): Promise<X402PaymentPayload> {
Expand Down Expand Up @@ -173,7 +242,7 @@ const paymentAdapter: X402PaymentAdapter = {
},
};

const client = new AtlanticClient({ paymentAdapter });
const client = new HcloudClient({ paymentAdapter });
```

Preserve the `requirement` object from `accepts[]` verbatim. Atlantic currently accepts USD Coin on Base mainnet; do not hardcode `payTo`, `asset`, `network`, or `amount`, because Atlantic may rotate the receiver or change the required payment amount.
6 changes: 3 additions & 3 deletions examples/buckets.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AtlanticClient, createBucketAndSubmit } from '../src';
import { HcloudClient, createBucketAndSubmit } from '../src';

const client = new AtlanticClient(process.env.ATLANTIC_API_KEY ? { apiKey: process.env.ATLANTIC_API_KEY } : {});
const client = new HcloudClient(process.env.HCLOUD_API_KEY ? { apiKey: process.env.HCLOUD_API_KEY } : {});

const result = await createBucketAndSubmit(client, {
const result = await createBucketAndSubmit(client.atlantic, {
bucket: {
aggregatorVersion: 'STONE',
},
Expand Down
6 changes: 3 additions & 3 deletions examples/submit-and-wait.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { AtlanticClient, submitAndWait } from '../src';
import { HcloudClient, submitAndWait } from '../src';

const client = new AtlanticClient(process.env.ATLANTIC_API_KEY ? { apiKey: process.env.ATLANTIC_API_KEY } : {});
const client = new HcloudClient(process.env.HCLOUD_API_KEY ? { apiKey: process.env.HCLOUD_API_KEY } : {});

const result = await submitAndWait(
client,
client.atlantic,
{
declaredJobSize: 'S',
pieFile: './pie.zip',
Expand Down
6 changes: 3 additions & 3 deletions examples/submit-query.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { AtlanticClient } from '../src';
import { HcloudClient } from '../src';

const client = new AtlanticClient(process.env.ATLANTIC_API_KEY ? { apiKey: process.env.ATLANTIC_API_KEY } : {});
const client = new HcloudClient(process.env.HCLOUD_API_KEY ? { apiKey: process.env.HCLOUD_API_KEY } : {});

const result = await client.submitQuery({
const result = await client.atlantic.submitQuery({
declaredJobSize: 'S',
pieFile: './pie.zip',
layout: 'dynamic',
Expand Down
6 changes: 3 additions & 3 deletions examples/x402-submit.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { AtlanticClient, type X402PaymentAdapter } from '../src';
import { HcloudClient, type X402PaymentAdapter } from '../src';

const paymentAdapter: X402PaymentAdapter = {
async createPayment({ requirement }) {
Expand All @@ -8,9 +8,9 @@ const paymentAdapter: X402PaymentAdapter = {
},
};

const client = new AtlanticClient({ paymentAdapter });
const client = new HcloudClient({ paymentAdapter });

const result = await client.submitQuery(
const result = await client.atlantic.submitQuery(
{
declaredJobSize: 'S',
pieFile: './pie.zip',
Expand Down
16 changes: 10 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"name": "@herodotus_dev/atlantic-sdk",
"version": "1.0.0",
"description": "TypeScript SDK and CLI for submitting, tracking, retrying, and paying for Herodotus Atlantic proofs.",
"name": "@herodotus_dev/hcloud",
"version": "0.1.0",
"description": "TypeScript SDK and CLI for Herodotus Cloud — wallet auth, Atlantic proving, and future services.",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"bin": {
"atlantic": "./dist/cli/index.js"
"hcloud": "./dist/cli/index.js"
},
"exports": {
".": {
Expand All @@ -32,14 +32,18 @@
"examples"
],
"keywords": [
"atlantic",
"herodotus",
"hcloud",
"atlantic",
"storage-proof",
"data-processor",
"sharp",
"stwo",
"stone",
"proof generation",
"proof verification",
"trace generation"
"wallet auth",
"eip-712"
],
"author": "Herodotus Dev Ltd",
"license": "MIT",
Expand Down
Loading
Loading