# Sidera purchase client

This Node.js client runs one purchase from selected session logs to verified delivery:

```text
prepare → estimate → submit (create + upload + formal quote)
        → pay (review, then approve once) → resume (status + download + receipt)
```

Use **Node.js 22.23.1 or newer**. The client creates its own Zstandard-compressed tar archive; no separate `zstd` installation is needed. It uses an existing Base USDC wallet for x402 payment.

## 1. Download and install

Download [sidera-memory-client-1.0.0.tgz](https://shadowharness.com/sidera/client/sidera-memory-client-1.0.0.tgz). The bundle contains the client, an existing-wallet RPC adapter, this guide and locked dependencies. `tar` is used only to unpack the downloaded bundle.

macOS / Linux:

```bash
mkdir sidera-client
cd sidera-client
curl -fL https://shadowharness.com/sidera/client/sidera-memory-client-1.0.0.tgz -o client.tgz
tar -xzf client.tgz --strip-components=1
npm ci --ignore-scripts
node sidera-client.mjs --help
```

Windows PowerShell:

```powershell
New-Item -ItemType Directory -Path sidera-client | Out-Null
Set-Location sidera-client
curl.exe -fL https://shadowharness.com/sidera/client/sidera-memory-client-1.0.0.tgz -o client.tgz
tar.exe -xzf client.tgz --strip-components=1
npm.cmd ci --ignore-scripts
node.exe sidera-client.mjs --help
```

The locked payment dependencies are `@x402/core` and `@x402/evm` 2.28.0, and `viem` 2.56.3. The client follows the [official x402 buyer SDK interface](https://docs.x402.org/getting-started/quickstart-for-buyers), using `x402Client.createPaymentPayload()` with a guarded signer. It sends the signed payment request once.

## 2. Prepare selected logs locally

Replace the input paths below with the project sessions you selected. Source flags accept a file or directory and can be repeated or combined. Keep the same `--state` path for the entire purchase:

```bash
node sidera-client.mjs prepare --state ../sidera-private/order.json --claude /path/to/selected/claude-sessions --codex /path/to/selected/codex-sessions
```

Use `--grok` or `--gemini` for their native JSONL logs. Alternatively, pass `--raw /path/to/raw` for an existing tree containing `claude/`, `ext-codex/`, `ext-grok/` and/or `ext-gemini/`.

`prepare` reads and checks every selected file, counts its conversation text, preserves its bytes in one archive, and writes a SHA-256 input manifest. It accepts 1–10,000 files and gives colliding filenames distinct archive names. It makes no HTTP requests.

| Source | Supported conversation records |
| --- | --- |
| Claude Code | Native `type: user` with `promptSource: typed` or `queued` and `message.content`; `type: assistant` with text in `message.content`. |
| Codex | Native `event_msg` with `payload.type: user_message` / `agent_message`, or `item_completed` whose item is `UserMessage` / `AgentMessage` with text content. CLI versions below 0.147 use the former layer; versions above 0.147 use the latter. At 0.147 or without a version, the item layer is used when present, otherwise the message layer. |
| Grok CLI | Native `type: user` / `assistant` with text content; user text inside `user_query` is supported. |
| Gemini CLI | Native `type: user` / `gemini` text records, including JSONL `$set.messages` snapshots. Repeated snapshot messages are deduplicated. |

Codex `response_item`-only exports, prompt-only history, settings and credentials are outside the conversation input format. A file with no supported conversation text stops preparation before an order is created. Select complete native session logs. See [where to find them](https://shadowharness.com/sidera/ordering/#0-locate-and-select-your-logs).

The state, manifest and input archive contain your selected paths and order credentials. Files are restricted to the current user (and SYSTEM on Windows). Keep them outside public folders and source control. The client prints summaries without your email, request key, order token or payment signature.

## 3. Estimate, create and measure

```bash
node sidera-client.mjs estimate --state ../sidera-private/order.json
node sidera-client.mjs submit --state ../sidera-private/order.json --email buyer@example.com
```

Replace `buyer@example.com` with your confirmation address. To avoid placing the address in shell history, use `--email-file /path/to/private/email.txt` instead; the file contains only that address. Email is required for creation and saved privately, so later commands need no email argument.

The free estimate saves the API's `estimate_id`. `submit` carries that same ID into creation, generates and saves a secret request key, uploads the prepared archive with its Bearer token, and prints the **formal amount**, change from the estimate, adjustment reason, approximate duration, expiry, Base recipient and quote hash. The formal quote is valid for 60 minutes. Upload must finish within 60 minutes of creation.

An estimate is a guide; the formal `pricing.amount_micro_usdc` determines payment. Decimal MB is 1,000,000 original JSONL bytes, rounded up once for the order. If the price increases, review the reason and decide your cap before approving.

## 4. Review, connect an existing wallet and approve once

Review the latest quote without a signature or paid request:

```bash
node sidera-client.mjs pay --state ../sidera-private/order.json
```

Use your existing wallet's local signer module. Replace the module path, cap and `QUOTE_HASH_FROM_PAY_OUTPUT` with the values you approved:

```bash
node sidera-client.mjs pay --state ../sidera-private/order.json --max-usdc 0.02 --approve-quote QUOTE_HASH_FROM_PAY_OUTPUT --signer-module /absolute/path/to/existing-wallet-signer.mjs
```

The client selects **USDC on Base (`eip155:8453`)**, checks the measured input, amount, terms hash and expiry, and permits one EIP-3009 typed-data signature followed by one HTTP payment send. A changed quote hash, price above the cap, mismatched signature terms or expired quote stops that approval. Ensure your existing wallet holds enough USDC on Base.

### Local signer module interface

The module exports this function; connect it to the wallet's existing approval/signing capability. `getSigner` obtains the account without signing. `signTypedData` is called once after the purchase attempt is saved:

```javascript
export async function getSigner({
  network, amountMicroUSDC, payTo, termsSha256, maxTimeoutSeconds, orderId
}) {
  return {
    address: existingAccountAddress,
    signTypedData: async ({ domain, types, message, primaryType }) => {
      return existingWallet.signTypedData({ domain, types, message, primaryType });
    }
  };
}
```

`amountMicroUSDC` is an integer string; `termsSha256` is the approved hash. The module returns a hex signature privately to the client. Do not print it or include keys in the module. `--wallet-adapter` is an alias for `--signer-module`.

For an existing wallet RPC that exposes `eth_accounts` and `eth_signTypedData_v4`, the included `existing-wallet-rpc.mjs` module is ready to use. Set `WALLET_RPC_URL` to that wallet's endpoint through your existing private configuration; optionally set `WALLET_ADDRESS` to one of its accounts. Then use `--signer-module ./existing-wallet-rpc.mjs`. An ordinary read-only blockchain RPC cannot approve wallet signatures.

If you already hold the wallet key in a private environment variable, `--private-key-env VARIABLE_NAME` is also supported. Supply only the variable name, keep the value in your existing secret storage, and do not echo it or pass it as a command argument. The client does not create a wallet or key.

### Interruptions and uncertain results

The state is locked against parallel commands. The signature attempt is saved before calling the wallet and the original payment payload is saved before sending. After an attempted signature, repeating `pay` is blocked, including after a rejected prompt, timeout, lost response or interrupted process. Use `resume` with the same state. Keep that state for support if payment remains under review; never approve a second signature for the same order.

If creation's response is lost, repeat `submit` with the same state to recover the same order. If an upload response is lost, use `resume` first; it checks whether measurement completed before suggesting another upload.

## 5. Resume to verified delivery

```bash
node sidera-client.mjs resume --state ../sidera-private/order.json --wait --output ../sidera-private/delivery
```

`resume` never signs or sends payment. It polls at the API's interval, downloads **both `memory.md` and `raw.tar.zst`**, checks each exact size and SHA-256 against the manifest, and only then sends the two verified hashes to acknowledge delivery. The final summary lists your saved files and receipt confirmation. Repeating `resume` uses the same files and state.

Complete delivery within 24 hours after processing ends. Keep both files and use the [memory and source-reference guide](https://shadowharness.com/sidera/usage/). The [ordering guide](https://shadowharness.com/sidera/ordering/) covers data handling, cancellation, refunds and seven-day recovery. Support: **shadowharness@gmail.com** with the order ID and transaction ID; keep order tokens and signatures private.

Public API: [discovery](https://shadowharness.com/v1/sidera/discovery) and [OpenAPI](https://shadowharness.com/openapi.json). This client uses only these documented public purchase endpoints.
