|
1 | | -# atlantic-sdk |
| 1 | +# Atlantic SDK |
| 2 | + |
| 3 | +TypeScript SDK and CLI for the Herodotus Atlantic API. |
| 4 | + |
| 5 | +This package provides two surfaces: |
| 6 | + |
| 7 | +- A typed SDK for direct Atlantic API calls and higher-level workflow helpers. |
| 8 | +- A JSON-first CLI that delegates to the SDK so terminal usage and library usage share behavior. |
| 9 | + |
| 10 | +## Installation |
| 11 | + |
| 12 | +```bash |
| 13 | +bun add @herodotus_dev/atlantic-sdk |
| 14 | +``` |
| 15 | + |
| 16 | +```bash |
| 17 | +npm install @herodotus_dev/atlantic-sdk |
| 18 | +``` |
| 19 | + |
| 20 | +Install the CLI globally: |
| 21 | + |
| 22 | +```bash |
| 23 | +npm install -g @herodotus_dev/atlantic-sdk |
| 24 | +``` |
| 25 | + |
| 26 | +## SDK quickstart |
| 27 | + |
| 28 | +```ts |
| 29 | +import { AtlanticClient, submitAndWait } from '@herodotus_dev/atlantic-sdk'; |
| 30 | + |
| 31 | +const client = new AtlanticClient({ |
| 32 | + apiKey: process.env.ATLANTIC_API_KEY, |
| 33 | +}); |
| 34 | + |
| 35 | +const result = await submitAndWait(client, { |
| 36 | + declaredJobSize: 'S', |
| 37 | + pieFile: './pie.zip', |
| 38 | +}); |
| 39 | + |
| 40 | +console.log(result.atlanticQuery.id, result.atlanticQuery.status); |
| 41 | +``` |
| 42 | + |
| 43 | +## Direct API usage |
| 44 | + |
| 45 | +```ts |
| 46 | +import { AtlanticClient } from '@herodotus_dev/atlantic-sdk'; |
| 47 | + |
| 48 | +const client = new AtlanticClient({ |
| 49 | + apiKey: process.env.ATLANTIC_API_KEY, |
| 50 | +}); |
| 51 | + |
| 52 | +const submitted = await client.submitQuery({ |
| 53 | + declaredJobSize: 'S', |
| 54 | + pieFile: './pie.zip', |
| 55 | + layout: 'dynamic', |
| 56 | +}); |
| 57 | + |
| 58 | +const details = await client.getQuery(submitted.atlanticQueryId); |
| 59 | + |
| 60 | +console.log(details.atlanticQuery.status, details.metadataUrls); |
| 61 | +``` |
| 62 | + |
| 63 | +## CLI quickstart |
| 64 | + |
| 65 | +```bash |
| 66 | +ATLANTIC_API_KEY=... bunx atlantic submit-query \ |
| 67 | + --pie-file ./pie.zip \ |
| 68 | + --declared-job-size S |
| 69 | +``` |
| 70 | + |
| 71 | +Every CLI command prints JSON so agents and shell scripts can chain outputs without scraping prose. |
| 72 | + |
| 73 | +Common commands: |
| 74 | + |
| 75 | +```bash |
| 76 | +atlantic get-query-details <query-id> |
| 77 | +atlantic get-my-queries --limit 20 --offset 0 |
| 78 | +atlantic retry-if-retriable <query-id> |
| 79 | +atlantic list-buckets |
| 80 | +atlantic create-bucket --aggregator-version STONE |
| 81 | +atlantic close-bucket <bucket-id> |
| 82 | +``` |
| 83 | + |
| 84 | +## SDK reference |
| 85 | + |
| 86 | +### Client |
| 87 | + |
| 88 | +- `new AtlanticClient(options)`: Creates a typed Atlantic API client. Configure `baseUrl`, `apiKey`, optional `fetch`, and optional x402 `paymentAdapter`. |
| 89 | +- `healthCheck()`: Checks whether Atlantic is reachable. Returns `{ alive }`. |
| 90 | +- `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. |
| 91 | +- `getQuery(atlanticQueryId)`: Fetches query details plus metadata URLs. |
| 92 | +- `getQueryByDedupId(dedupId)`: Fetches a query by dedup ID. Use API-key flow; anonymous x402 does not support dedup IDs. |
| 93 | +- `listQueries({ limit, offset })`: Lists submitted queries with pagination. |
| 94 | +- `getQueryStats()`: Fetches query statistics for the configured API key. |
| 95 | +- `getQueryJobs(atlanticQueryId)`: Fetches job lifecycle details for a query. |
| 96 | +- `retryQuery(atlanticQueryId)`: Requests an API retry for a failed query. Branch on structured errors for wrong state, max retries, not found, and forbidden outcomes. |
| 97 | +- `listBuckets({ limit, offset })`: Lists Applicative Recursion buckets. |
| 98 | +- `createBucket(input)`: Creates an Applicative Recursion bucket. |
| 99 | +- `getBucket(bucketId)`: Fetches a bucket and associated queries. |
| 100 | +- `closeBucket(bucketId)`: Closes a bucket. |
| 101 | + |
| 102 | +### Workflow helpers |
| 103 | + |
| 104 | +- `submitAndReturnId(client, input)`: Submit and return the query ID immediately. |
| 105 | +- `waitForQuery(client, atlanticQueryId, options)`: Poll until terminal status or timeout. Returns observed statuses and final query details. |
| 106 | +- `submitAndWait(client, input, options)`: Submit and wait in one helper while preserving the original submit result. |
| 107 | +- `retryIfRetriable(client, atlanticQueryId)`: Fetches current query details and retries only when the query is failed and retriable. |
| 108 | +- `getQueryWithJobs(client, atlanticQueryId)`: Fetches query details and query jobs together. |
| 109 | +- `submitToBucket(client, input)`: Submits a query into an existing bucket with explicit job index. |
| 110 | +- `createBucketAndSubmit(client, input)`: Creates a bucket and submits indexed queries into it. |
| 111 | + |
| 112 | +## x402 |
| 113 | + |
| 114 | +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`. |
| 115 | + |
| 116 | +### Private-key adapter |
| 117 | + |
| 118 | +For server-side scripts, CI, or agents with a dedicated payment key, use the built-in private-key adapter: |
| 119 | + |
| 120 | +```ts |
| 121 | +import { AtlanticClient, createPrivateKeyPaymentAdapter } from '@herodotus_dev/atlantic-sdk'; |
| 122 | + |
| 123 | +const paymentAdapter = createPrivateKeyPaymentAdapter({ |
| 124 | + privateKey: process.env.WALLET_PRIVATE_KEY as `0x${string}`, |
| 125 | +}); |
| 126 | + |
| 127 | +const client = new AtlanticClient({ |
| 128 | + apiKey: process.env.ATLANTIC_API_KEY, |
| 129 | + paymentAdapter, |
| 130 | +}); |
| 131 | + |
| 132 | +const result = await client.submitQuery({ |
| 133 | + declaredJobSize: 'S', |
| 134 | + pieFile: './pie.zip', |
| 135 | +}); |
| 136 | + |
| 137 | +console.log(result.atlanticQueryId, result.payment); |
| 138 | +``` |
| 139 | + |
| 140 | +The adapter reads the x402 requirement returned by Atlantic, verifies that `accepts[].network` is Base mainnet (`eip155:8453`) and `accepts[].extra.name` is `USD Coin`, signs an EIP-3009 `transferWithAuthorization`, and returns the `PAYMENT-SIGNATURE` payload. |
| 141 | + |
| 142 | +### Custom wallet adapter |
| 143 | + |
| 144 | +Use a custom adapter when signing should happen through another wallet, custody service, browser wallet, or agent wallet. |
| 145 | + |
| 146 | +```ts |
| 147 | +import { |
| 148 | + AtlanticClient, |
| 149 | + type X402PaymentAdapter, |
| 150 | + type X402PaymentPayload, |
| 151 | +} from '@herodotus_dev/atlantic-sdk'; |
| 152 | + |
| 153 | +const paymentAdapter: X402PaymentAdapter = { |
| 154 | + async createPayment({ requirement }): Promise<X402PaymentPayload> { |
| 155 | + const authorization = { |
| 156 | + from: '0xYourWallet', |
| 157 | + to: requirement.payTo, |
| 158 | + value: requirement.amount, |
| 159 | + validAfter: '0', |
| 160 | + validBefore: String(Math.floor(Date.now() / 1000) + (requirement.maxTimeoutSeconds ?? 300)), |
| 161 | + nonce: '0x...32-bytes', |
| 162 | + }; |
| 163 | + |
| 164 | + const signature = await signTransferWithAuthorization({ |
| 165 | + requirement, |
| 166 | + authorization, |
| 167 | + }); |
| 168 | + |
| 169 | + return { |
| 170 | + x402Version: 2, |
| 171 | + accepted: requirement, |
| 172 | + payload: { |
| 173 | + signature, |
| 174 | + authorization, |
| 175 | + }, |
| 176 | + }; |
| 177 | + }, |
| 178 | +}; |
| 179 | + |
| 180 | +const client = new AtlanticClient({ paymentAdapter }); |
| 181 | +``` |
| 182 | + |
| 183 | +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. |
0 commit comments