> For the complete documentation index, see [llms.txt](https://gotts.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gotts.gitbook.io/docs/reference/sdk.md).

# SDK

API reference for the Gotts primitive packages. These packages provide shared infrastructure for configuration, blockchain interaction, cryptography, policy management, and wallet abstraction.

## @gotts.ai/core

Config I/O, error hierarchy, and constants. Published via npm.

### Configuration

```typescript
import {
  loadConfig,
  saveConfig,
  loadConfigOrThrow,
  configExists,
  configPath,
  fetchPrivyAppId,
} from "@gotts.ai/core";
```

| Function              | Signature                                | Description                                   |
| --------------------- | ---------------------------------------- | --------------------------------------------- |
| `configPath()`        | `() => string`                           | Returns `~/.gotts/config.json` path           |
| `configExists()`      | `() => boolean`                          | Checks if config file exists                  |
| `loadConfig()`        | `() => GottsConfig \| null`              | Loads config; returns `null` if missing       |
| `loadConfigOrThrow()` | `() => GottsConfig`                      | Loads config; throws `ConfigError` if missing |
| `saveConfig()`        | `(config: GottsConfig) => void`          | Persists config with `0o600` permissions      |
| `fetchPrivyAppId()`   | `(webAppUrl: string) => Promise<string>` | Fetches Privy App ID from a Portal server     |

### Error Classes

```typescript
import { GottsError, ConfigError, AuthError } from "@gotts.ai/core";
```

| Class         | Code            | Description                                |
| ------------- | --------------- | ------------------------------------------ |
| `GottsError`  | `UNKNOWN_ERROR` | Base error with `code: ErrorCode` property |
| `ConfigError` | `CONFIG_ERROR`  | Config file missing or invalid             |
| `AuthError`   | `AUTH_ERROR`    | Authentication failure                     |

### Constants

```typescript
import {
  PRIVY_API_BASE,
  CONFIG_DIR,
  CONFIG_FILE,
  CONFIG_DIR_PERMISSIONS,
  CONFIG_FILE_PERMISSIONS,
} from "@gotts.ai/core";
```

| Constant                  | Value                    | Description               |
| ------------------------- | ------------------------ | ------------------------- |
| `PRIVY_API_BASE`          | `"https://api.privy.io"` | Privy API base URL        |
| `CONFIG_DIR`              | `~/.gotts`               | Config directory path     |
| `CONFIG_FILE`             | `~/.gotts/config.json`   | Config file path          |
| `CONFIG_DIR_PERMISSIONS`  | `0o700`                  | Directory permission mode |
| `CONFIG_FILE_PERMISSIONS` | `0o600`                  | File permission mode      |

### Types

```typescript
import type { GottsConfig, GottsMode, ErrorCode } from "@gotts.ai/core";
```

| Type          | Definition                                                                  |
| ------------- | --------------------------------------------------------------------------- |
| `GottsMode`   | `"privy" \| "local"`                                                        |
| `ErrorCode`   | `"CONFIG_ERROR" \| "AUTH_ERROR" \| "UNKNOWN_ERROR"`                         |
| `GottsConfig` | Config object — see [Configuration](/docs/getting-started/configuration.md) |

***

## @gotts.ai/chain

13-chain registry, ETH math, address utilities, and RPC client. Internal package (no build step).

### Chain Registry

```typescript
import {
  chains,
  BASE_CHAIN_ID,
  getChainById,
  getChainByName,
  getChainByCaip2,
} from "@gotts.ai/chain";
```

| Export              | Type                                    | Description                                  |
| ------------------- | --------------------------------------- | -------------------------------------------- |
| `chains`            | `Record<string, Chain>`                 | All 13 chains (11 Uniswap + Sepolia + Anvil) |
| `BASE_CHAIN_ID`     | `8453`                                  | Base chain ID constant                       |
| `getChainById()`    | `(id: ChainId) => Chain \| undefined`   | Lookup by numeric chain ID                   |
| `getChainByName()`  | `(name: string) => Chain \| undefined`  | Lookup by name (case-insensitive)            |
| `getChainByCaip2()` | `(caip2: string) => Chain \| undefined` | Lookup by CAIP-2 identifier                  |

Supported chains: Ethereum (1), Optimism (10), BNB (56), Unichain (130), Polygon (137), zkSync (324), Base (8453), Anvil (31337), Arbitrum (42161), Celo (42220), Avalanche (43114), Blast (81457), Sepolia (11155111).

### ETH Math

Pure BigInt math — no floating point.

```typescript
import {
  formatWeiToEth,
  formatHexToEth,
  parseEtherToHex,
  parseHexToWei,
} from "@gotts.ai/chain";
```

| Function            | Signature                           | Example                                                       |
| ------------------- | ----------------------------------- | ------------------------------------------------------------- |
| `formatWeiToEth()`  | `(wei: bigint \| string) => string` | `formatWeiToEth(1000000000000000000n)` → `"1.0"`              |
| `formatHexToEth()`  | `(hex: string) => string`           | `formatHexToEth("0xde0b6b3a7640000")` → `"1.0"`               |
| `parseEtherToHex()` | `(eth: string) => string`           | `parseEtherToHex("1.0")` → `"0xde0b6b3a7640000"`              |
| `parseHexToWei()`   | `(hex: string) => bigint`           | `parseHexToWei("0xde0b6b3a7640000")` → `1000000000000000000n` |

### Address Utilities

```typescript
import {
  isValidAddress,
  normalizeAddress,
  truncateAddress,
} from "@gotts.ai/chain";
```

| Function             | Signature                                      | Description                   |
| -------------------- | ---------------------------------------------- | ----------------------------- |
| `isValidAddress()`   | `(addr: string) => boolean`                    | Validates `0x` + 40 hex chars |
| `normalizeAddress()` | `(addr: string) => string`                     | Lowercase with `0x` prefix    |
| `truncateAddress()`  | `(addr: string, prefixLen?: number) => string` | `"0x1234...5678"` format      |

### RPC Client

```typescript
import { RpcClient, RpcError } from "@gotts.ai/chain";
```

| Method                  | Signature                                     | Description                |
| ----------------------- | --------------------------------------------- | -------------------------- |
| `new RpcClient()`       | `(rpcUrl: string)`                            | Create client with RPC URL |
| `RpcClient.fromChain()` | `(chain: Chain) => RpcClient`                 | Create from chain object   |
| `.getBalance()`         | `(address: string) => Promise<bigint>`        | Get ETH balance in wei     |
| `.estimateGas()`        | `(tx: TransactionRequest) => Promise<bigint>` | Estimate gas               |

### Transaction Helpers

```typescript
import { buildPrivyRpcBody } from "@gotts.ai/chain";
```

| Function              | Signature                                               | Description                             |
| --------------------- | ------------------------------------------------------- | --------------------------------------- |
| `buildPrivyRpcBody()` | `(to: string, value: string, caip2: string) => unknown` | Build Privy-format RPC transaction body |

### Types

```typescript
import type {
  Address,
  Hex,
  Chain,
  ChainId,
  NativeCurrency,
  TransactionRequest,
  JsonRpcRequest,
  JsonRpcResponse,
  PrivyRpcBody,
} from "@gotts.ai/chain";
```

| Type                 | Description                                                                     |
| -------------------- | ------------------------------------------------------------------------------- |
| `Address`            | `` `0x${string}` `` — 0x-prefixed, 40 hex chars                                 |
| `Hex`                | `` `0x${string}` `` — 0x-prefixed hex string                                    |
| `ChainId`            | Union of all 13 supported chain IDs                                             |
| `Chain`              | Chain descriptor with id, name, caip2, rpcUrl, blockExplorerUrl, nativeCurrency |
| `NativeCurrency`     | `{ name: string; symbol: string; decimals: number }`                            |
| `TransactionRequest` | Ethereum JSON-RPC transaction parameters                                        |
| `JsonRpcRequest`     | Standard JSON-RPC 2.0 request                                                   |
| `JsonRpcResponse<T>` | Standard JSON-RPC 2.0 response                                                  |

***

## @gotts.ai/crypto

P-256 cryptography for Privy authentication. Internal package. Zero workspace dependencies for auditability.

### Key Generation

```typescript
import { generateKeyPair } from "@gotts.ai/crypto";
```

| Function            | Signature       | Description                          |
| ------------------- | --------------- | ------------------------------------ |
| `generateKeyPair()` | `() => KeyPair` | Generate P-256 keypair as base64 DER |

Returns `{ publicKeyB64: string; privateKeyB64: string }` — base64-encoded SPKI (public) and PKCS8 (private).

### DER Encoding

```typescript
import {
  encodePrivateKeyToPkcs8,
  encodePublicKeyToSpki,
  extractPrivateScalar,
  derivePublicKeyFromPrivate,
} from "@gotts.ai/crypto";
```

| Function                       | Signature                                  | Description                                        |
| ------------------------------ | ------------------------------------------ | -------------------------------------------------- |
| `encodePrivateKeyToPkcs8()`    | `(scalar: Uint8Array) => string`           | 32-byte scalar → base64 PKCS8                      |
| `encodePublicKeyToSpki()`      | `(pubPoint: Uint8Array) => string`         | 65-byte point → base64 SPKI                        |
| `extractPrivateScalar()`       | `(privateKeyBase64: string) => Uint8Array` | Extract raw 32-byte scalar (strips Privy prefixes) |
| `derivePublicKeyFromPrivate()` | `(privateKeyBase64: string) => string`     | Derive public key, returns base64 SPKI             |

### Signing & Verification

```typescript
import {
  buildSigningPayload,
  buildPrivySigningPayload,
  signPayload,
  verifyPayload,
} from "@gotts.ai/crypto";
```

| Function                     | Signature                                                   | Description                                    |
| ---------------------------- | ----------------------------------------------------------- | ---------------------------------------------- |
| `buildSigningPayload()`      | `(input: SigningPayloadInput) => Uint8Array`                | Build canonical (JCS/RFC 8785) signing payload |
| `buildPrivySigningPayload()` | `(appId, walletId, rpcBody, privyApiBase?) => Uint8Array`   | Build Privy-specific signing payload           |
| `signPayload()`              | `(payload: Uint8Array, privateKeyBase64: string) => string` | Sign with P-256, returns base64 DER signature  |
| `verifyPayload()`            | `(payload, signatureBase64, publicKeyBase64) => boolean`    | Verify P-256 signature                         |

### Keychain

```typescript
import { storePrivyCredentials, loadPrivyCredentials } from "@gotts.ai/crypto";
```

| Function                  | Signature                                                     | Description                                    |
| ------------------------- | ------------------------------------------------------------- | ---------------------------------------------- |
| `storePrivyCredentials()` | `(appId, appSecret) => Promise<"keychain" \| "plaintext">`    | Store in OS keychain (falls back to plaintext) |
| `loadPrivyCredentials()`  | `() => Promise<{ appId: string; appSecret: string } \| null>` | Load from OS keychain                          |

***

## @gotts.ai/policy

Privy signing policy DSL. Internal package.

### PolicyBuilder

```typescript
import { PolicyBuilder } from "@gotts.ai/policy";

const policy = new PolicyBuilder()
  .setName("my-policy")
  .withOwner(publicKeyB64)
  .allowToMany(["0xabc...", "0xdef..."])
  .allowValue("1000000000000000000") // 1 ETH max
  .deny()
  .build();
```

| Method                                         | Returns  | Description                       |
| ---------------------------------------------- | -------- | --------------------------------- |
| `.setName(name)`                               | `this`   | Set policy name                   |
| `.withOwner(publicKeyB64)`                     | `this`   | Set owner public key              |
| `.allowTo(addr)`                               | `this`   | Allow sends to single address     |
| `.allowToMany(addrs)`                          | `this`   | Allow sends to multiple addresses |
| `.allowSendTo(addrs)`                          | `this`   | Allow ETH sends to addresses      |
| `.allowMethod(contractAddr, methodName, abi?)` | `this`   | Allow contract method calls       |
| `.allowValue(lteWei)`                          | `this`   | Max transaction value in wei      |
| `.deny(description?)`                          | `this`   | Add catch-all deny rule           |
| `.build()`                                     | `Policy` | Build the policy object           |

### Quick Builders

```typescript
import { buildSendOnlyPolicy } from "@gotts.ai/policy";

const policy = buildSendOnlyPolicy(["0xabc...", "0xdef..."]);
```

| Function                | Signature                         | Description                        |
| ----------------------- | --------------------------------- | ---------------------------------- |
| `buildSendOnlyPolicy()` | `(addresses: string[]) => Policy` | Convenience for send-only policies |

### Validators

```typescript
import { validatePolicy, wouldAllow } from "@gotts.ai/policy";
```

| Function           | Signature                                        | Description                                     |
| ------------------ | ------------------------------------------------ | ----------------------------------------------- |
| `validatePolicy()` | `(policy: unknown) => ValidationResult`          | Validate policy structure (`{ valid, errors }`) |
| `wouldAllow()`     | `(policy: Policy, toAddress: string) => boolean` | Check if policy allows sending to address       |

### Resolvers

```typescript
import {
  extractAllowedAddresses,
  extractAllowedAddressesFromRaw,
} from "@gotts.ai/policy";
```

| Function                           | Signature                      | Description                                            |
| ---------------------------------- | ------------------------------ | ------------------------------------------------------ |
| `extractAllowedAddresses()`        | `(policy: Policy) => string[]` | Extract allowed "to" addresses from typed policy       |
| `extractAllowedAddressesFromRaw()` | `(raw: unknown) => string[]`   | Extract from untyped policy (e.g., Privy SDK response) |

### Types

```typescript
import type {
  Policy,
  Rule,
  Condition,
  PolicyAction,
  ConditionOperator,
  FieldSource,
  ValidationResult,
} from "@gotts.ai/policy";
```

| Type                | Description                                             |
| ------------------- | ------------------------------------------------------- |
| `PolicyAction`      | `"ALLOW" \| "DENY"`                                     |
| `ConditionOperator` | `"eq" \| "in" \| "lt" \| "lte" \| "gt" \| "gte"`        |
| `FieldSource`       | `"ethereum_transaction" \| "ethereum_calldata"`         |
| `Condition`         | Policy condition with field, operator, value            |
| `Rule`              | Policy rule with name, method, action, conditions       |
| `Policy`            | Top-level policy with version, name, chain\_type, rules |
| `ValidationResult`  | `{ valid: boolean; errors: string[] }`                  |

***

## @gotts.ai/wallet

Wallet abstraction with Privy and local key support. Published via npm.

### GottsWallet

```typescript
import { GottsWallet } from "@gotts.ai/wallet";

// From config file
const wallet = GottsWallet.fromConfig(config);

// Manual construction
const wallet = new GottsWallet({
  mode: "privy",
  privyAppId: "...",
  privyAppSecret: "...",
  walletId: "...",
  walletAddress: "0x...",
  authPrivateKey: "...",
  allowedAddresses: ["0x..."],
  chain: chains.sepolia,
});
```

| Method                     | Signature                                                  | Description                        |
| -------------------------- | ---------------------------------------------------------- | ---------------------------------- |
| `GottsWallet.fromConfig()` | `(config: GottsConfig) => GottsWallet`                     | Create from loaded config          |
| `.getBalance()`            | `() => Promise<BalanceResult>`                             | Get ETH balance (`{ eth, wei }`)   |
| `.send()`                  | `(to: string, amountEth: string) => Promise<SendResult>`   | Send ETH (must be in allowlist)    |
| `.estimateGas()`           | `(to: string, amountEth: string) => Promise<GasEstimate>`  | Estimate gas (`{ gas, gasHex }`)   |
| `.sendRaw()`               | `(tx: { to, value?, data? }) => Promise<string>`           | Send raw transaction, returns hash |
| `.rpcCall()`               | `(method: string, params?: unknown[]) => Promise<unknown>` | Direct RPC call                    |
| `.getInfo()`               | `() => WalletInfo`                                         | Wallet metadata                    |
| `.getChainId()`            | `() => number`                                             | Numeric chain ID                   |

### EIP-1193 Provider

```typescript
import { createEIP1193Provider } from "@gotts.ai/wallet";

const provider = createEIP1193Provider(wallet);
// Use with any library that accepts an EIP-1193 provider
```

| Function                  | Signature                                  | Description                                |
| ------------------------- | ------------------------------------------ | ------------------------------------------ |
| `createEIP1193Provider()` | `(wallet: GottsWallet) => EIP1193Provider` | EIP-1193 bridge for Agent0 SDK integration |

Supports: `eth_sendTransaction`, `personal_sign`, `eth_signTypedData_v4`, `eth_chainId`, `eth_accounts`.

### Agent Registration

```typescript
import { registerAgent } from "@gotts.ai/wallet";

const result = await registerAgent({
  wallet,
  name: "my-agent",
  description: "A trading agent",
  // ...metadata
});
// result.agentId, result.method, result.txHash
```

| Function          | Signature                                                          | Description                            |
| ----------------- | ------------------------------------------------------------------ | -------------------------------------- |
| `registerAgent()` | `(config: AgentRegistrationConfig) => Promise<RegistrationResult>` | Register on ERC-8004 (3-tier fallback) |

Fallback tiers: (1) Agent0 SDK + IPFS proxy → (2) Agent0 SDK + inline URI → (3) Direct contract call via viem.

### Privy API Functions

```typescript
import {
  sendDirectToPrivy,
  createPolicy,
  createWallet,
  listWallets,
  basicAuth,
  privyHeaders,
} from "@gotts.ai/wallet";
```

| Function              | Signature                                                              | Description                         |
| --------------------- | ---------------------------------------------------------------------- | ----------------------------------- |
| `basicAuth()`         | `(appId, appSecret) => string`                                         | Encode Basic auth header            |
| `privyHeaders()`      | `(appId, appSecret) => Record<string, string>`                         | Build Privy API headers             |
| `sendDirectToPrivy()` | `(appId, appSecret, walletId, rpcBody, signature) => Promise<string>`  | Send tx via Privy API, returns hash |
| `createPolicy()`      | `(appId, appSecret, publicKey, addresses) => Promise<{ id }>`          | Create send-only policy             |
| `createWallet()`      | `(appId, appSecret, publicKey, policyIds) => Promise<{ id, address }>` | Create Privy wallet                 |
| `listWallets()`       | `(appId, appSecret) => Promise<{ id, address }[]>`                     | List all wallets                    |

### Proxy Functions

```typescript
import { sendViaProxy } from "@gotts.ai/wallet";
```

| Function         | Signature                                                      | Description                         |
| ---------------- | -------------------------------------------------------------- | ----------------------------------- |
| `sendViaProxy()` | `(webAppUrl, walletId, rpcBody, signature) => Promise<string>` | Send via Portal proxy, returns hash |

### Error Classes

```typescript
import {
  WalletError,
  AddressNotAllowedError,
  CredentialsError,
} from "@gotts.ai/wallet";
```

| Class                    | Description                              |
| ------------------------ | ---------------------------------------- |
| `WalletError`            | Base wallet error (extends `GottsError`) |
| `AddressNotAllowedError` | Send target not in allowlist             |
| `CredentialsError`       | Privy credentials missing or invalid     |

***

## @gotts.ai/testnet

Generic EVM test toolkit for Anvil-based development and testing. Published via npm. No DeFi dependencies.

### AnvilManager

```typescript
import { AnvilManager, getAnvilVersion } from "@gotts.ai/testnet";

const anvil = new AnvilManager({ port: 8545, blockTime: 1 });
await anvil.start();
// ... use anvil
await anvil.stop();

const version = await getAnvilVersion(); // { major, minor, patch, commit }
```

| Method / Function    | Signature                                  | Description                 |
| -------------------- | ------------------------------------------ | --------------------------- |
| `new AnvilManager()` | `(options?: AnvilOptions) => AnvilManager` | Create Anvil instance       |
| `.start()`           | `() => Promise<void>`                      | Start Anvil process         |
| `.stop()`            | `() => Promise<void>`                      | Stop Anvil process          |
| `getAnvilVersion()`  | `() => Promise<AnvilVersion>`              | Get installed Anvil version |

### TestnetBuilder

Fluent builder for configuring and launching test chains.

```typescript
import { TestnetBuilder } from "@gotts.ai/testnet";

const testnet = await new TestnetBuilder()
  .withPort(8545)
  .withBlockTime(1)
  .build();
```

| Method             | Returns                    | Description              |
| ------------------ | -------------------------- | ------------------------ |
| `.withPort()`      | `this`                     | Set Anvil port           |
| `.withBlockTime()` | `this`                     | Set block time (seconds) |
| `.build()`         | `Promise<TestnetInstance>` | Launch configured chain  |

### SnapshotStore

Manage named Anvil state snapshots.

```typescript
import { SnapshotStore } from "@gotts.ai/testnet";

const store = new SnapshotStore(client);
const snap = await store.take("after-deploy");
await store.revert("after-deploy");
```

| Method      | Signature                             | Description                |
| ----------- | ------------------------------------- | -------------------------- |
| `.take()`   | `(name: string) => Promise<Snapshot>` | Take a named snapshot      |
| `.revert()` | `(name: string) => Promise<void>`     | Revert to a named snapshot |
| `.list()`   | `() => NamedSnapshot[]`               | List all snapshots         |

### Presets

Pre-configured chain setups for common scenarios.

```typescript
import {
  PRESET_FRESH,
  PRESET_CI,
  PRESET_REALISTIC,
  PRESET_MAINNET_FORK,
  PRESET_BASE_FORK,
  definePreset,
  getPreset,
  listPresets,
} from "@gotts.ai/testnet";
```

| Preset                | Description                         |
| --------------------- | ----------------------------------- |
| `PRESET_FRESH`        | Clean Anvil instance, no state      |
| `PRESET_CI`           | CI-optimized (deterministic, fast)  |
| `PRESET_REALISTIC`    | Realistic gas, block time, accounts |
| `PRESET_MAINNET_FORK` | Fork from Ethereum mainnet          |
| `PRESET_BASE_FORK`    | Fork from Base                      |

| Function         | Signature                                | Description              |
| ---------------- | ---------------------------------------- | ------------------------ |
| `definePreset()` | `(name: string, preset: Preset) => void` | Register a custom preset |
| `getPreset()`    | `(name: string) => Preset \| undefined`  | Retrieve preset by name  |
| `listPresets()`  | `() => string[]`                         | List all preset names    |

### Time Travel

```typescript
import {
  timeTravel,
  mineBlocks,
  setTimestamp,
  getBlockTimestamp,
  parseDuration,
} from "@gotts.ai/testnet";

await timeTravel(client, "1h"); // Advance 1 hour
await mineBlocks(client, 10); // Mine 10 blocks
await setTimestamp(client, 1700000000n);
const ts = await getBlockTimestamp(client);
const seconds = parseDuration("30m"); // 1800
```

### Account Helpers

```typescript
import {
  ANVIL_ACCOUNTS,
  ANVIL_MNEMONIC,
  getAccount,
  generateAccounts,
  fundAccount,
  drainAccount,
} from "@gotts.ai/testnet";
```

| Export               | Type / Signature                             | Description                      |
| -------------------- | -------------------------------------------- | -------------------------------- |
| `ANVIL_ACCOUNTS`     | `TestAccount[]`                              | 10 default Anvil accounts        |
| `ANVIL_MNEMONIC`     | `string`                                     | Default Anvil HD mnemonic        |
| `getAccount()`       | `(index: number) => TestAccount`             | Get account by index             |
| `generateAccounts()` | `(count: number) => TestAccount[]`           | Generate additional accounts     |
| `fundAccount()`      | `(client, address, amount) => Promise<void>` | Fund an address with ETH         |
| `drainAccount()`     | `(client, from, to) => Promise<void>`        | Drain all ETH to another address |

### Token Helpers

```typescript
import {
  deployERC20,
  mintERC20,
  setERC20Balance,
  setERC20Allowance,
  addEthBalance,
} from "@gotts.ai/testnet";
```

| Function              | Signature                                                         | Description                    |
| --------------------- | ----------------------------------------------------------------- | ------------------------------ |
| `deployERC20()`       | `(client, options: TokenDeployOptions) => Promise<DeployedToken>` | Deploy a mock ERC-20           |
| `mintERC20()`         | `(client, token, to, amount) => Promise<void>`                    | Mint tokens to an address      |
| `setERC20Balance()`   | `(client, token, account, amount) => Promise<void>`               | Set exact token balance        |
| `setERC20Allowance()` | `(client, token, owner, spender, amount) => Promise<void>`        | Set exact allowance            |
| `addEthBalance()`     | `(client, address, amount) => Promise<void>`                      | Add ETH via `anvil_setBalance` |

### Health Checks

```typescript
import { healthCheck, assertHealthy } from "@gotts.ai/testnet";

const report = await healthCheck(rpcUrl);
// report: { healthy: boolean, checks: HealthCheckResult[] }

await assertHealthy(rpcUrl); // throws if unhealthy
```

### Test Fixtures

```typescript
import { createTestFixture, createSuiteFixture } from "@gotts.ai/testnet";

// Per-test: starts fresh Anvil, stops after each test
const useFixture = createTestFixture({ port: 0 });

// Per-suite: shared Anvil across all tests in a file, snapshot/revert between tests
const useSuiteFixture = createSuiteFixture({ port: 0 });
```

| Function               | Returns                  | Description                                   |
| ---------------------- | ------------------------ | --------------------------------------------- |
| `createTestFixture()`  | `() => Promise<Fixture>` | Per-test Anvil lifecycle (start/stop)         |
| `createSuiteFixture()` | `() => Promise<Fixture>` | Per-suite Anvil with snapshot/revert per test |

### Parallel Fixtures

```typescript
import { createAnvilPool } from "@gotts.ai/testnet";

const pool = createAnvilPool({ size: 4 });
const anvil = await pool.acquire();
// ... use anvil
await pool.release(anvil);
await pool.drain();
```

### BigInt JSON Serialization

```typescript
import {
  stringifyWithBigInt,
  parseWithBigInt,
  bigintReplacer,
  bigintReviver,
} from "@gotts.ai/testnet";

const json = stringifyWithBigInt({ value: 1000000000000000000n });
// '{"value":"1000000000000000000"}'
const obj = parseWithBigInt(json);
```

### CLI

```bash
npx @gotts.ai/testnet              # Start Anvil with defaults
npx @gotts.ai/testnet --port 8546  # Custom port
npx @gotts.ai/testnet --preset ci  # Use CI preset
```

### Types

```typescript
import type {
  AnvilInstance,
  AnvilOptions,
  AnvilVersion,
  TestAccount,
  Duration,
  DeployedToken,
  MockToken,
  TokenDeployOptions,
  NamedSnapshot,
  Snapshot,
  ChainPreset,
  Preset,
  HealthCheckName,
  HealthCheckResult,
  HealthReport,
  TestnetInstance,
  ManagedService,
  RecordedTransaction,
  AnvilPool,
  AnvilPoolOptions,
  PooledAnvil,
} from "@gotts.ai/testnet";
```
