# Deep-Dive Analysis: @vaultfire/sdk

**Analyzed at:** April 2025  
**Repo path:** `/home/user/workspace/vaultfire-sdk/`  
**Package version:** 1.0.0  
**Author:** Ghostkey316  
**License:** MIT  

---

## 1. Repository Overview

The `@vaultfire/sdk` is the official TypeScript SDK for the Vaultfire Protocol — described as a "trust and accountability layer for AI agents." It provides on-chain belief attestation via two smart contracts (`DilithiumAttestor` and `BeliefVerifier`) deployed on Base (chain ID 8453) and Avalanche C-Chain (chain ID 43114). The core premise is CRYSTALS-Dilithium post-quantum attestation and ERC-8004 identity.

### File Tree (non-git, non-node_modules, non-dist)

```
.gitignore
API_REFERENCE.md
LICENSE
README.md
SAFE_DEFAULTS.md
examples/
  defi-trading.ts
  governance-dao.ts
  privacy-preserving-express.ts
  privacy-preserving-nextjs-route.ts
jest.config.js
package-lock.json
package.json
src/
  index.ts         (barrel export file, 40 lines)
  safe.ts          (VaultfireSafeSDK — privacy wrapper, 127 lines)
  vaultfire.ts     (VaultfireSDK — core class, 438 lines)
tests/
  vaultfire.test.ts  (36 tests, 379 lines)
tsconfig.json
```

Total source: **3 source files**, **605 lines** of TypeScript source.  
Built dist/ is already present (4 files: index.js, vaultfire.js, safe.js + their .d.ts counterparts).

---

## 2. TypeScript Compilation

**Result: PASS — zero errors.**

```
npx tsc --noEmit   →  exit code 0, no output (clean)
```

Configuration (`tsconfig.json`):
- `target: ES2020`, `module: CommonJS`
- `strict: true` (full strict mode)
- `declaration: true` — generates `.d.ts` files
- `outDir: dist`
- `moduleResolution: Node`
- `esModuleInterop: true`, `forceConsistentCasingInFileNames: true`, `skipLibCheck: true`
- **Note:** `examples/` and `tests/` are excluded from the TypeScript compilation (`include` only covers `src/**/*.ts`)

---

## 3. Test Results

**Result: ALL 36 TESTS PASS.**

```
Test Suites: 1 passed, 1 total
Tests:       36 passed, 36 total
Time:        2.109 s
```

Test runner: `jest` with `ts-jest` preset, `node` environment.  
Test file: `tests/vaultfire.test.ts`

### Test Coverage Areas

| Test Suite | Tests | Description |
|---|---|---|
| VaultfireSDK constructor | 4 | Instantiation with default/explicit/avalanche/base-sepolia chains |
| createVaultfireSDK helper | 2 | Factory function for base and avalanche |
| Chain Configuration | 5 | Contract addresses, custom RPC, custom contracts |
| hashBelief | 6 | Hex format, determinism, collisions, byte length, empty string, unicode |
| getModules | 4 | Count (8), all ModuleType IDs present, all enabled, all have name+description |
| ModuleType | 1 | Numeric values 0–7 |
| verifyBelief without signer | 1 | Throws 'SDK not connected' |
| isSovereign | 1 | Returns false gracefully on network error |
| estimateGas | 1 | Returns fallback BigInt(61000) on network error |
| VaultfireSafeSDK | 11 | Constructor, hashStatement (determinism/salts/normalize), unsafeRaw, factory functions |
| Type exports | 1 | Compile-time type check |

**Missing test coverage:**
- No tests for `getAttestations()` (mocked or real)
- No integration tests with a mock/local blockchain
- No tests for `verifyStatement()` with a mocked signer
- No tests for error paths in `getAttestations()` 
- No tests validating `beliefHash` format checking in `verifyBelief()`
- No snapshot tests for chain config structure

---

## 4. Exported Functions and Classes

### From `src/index.ts` (barrel file — clean, well-structured)

**Classes:**
- `VaultfireSDK` — core SDK class
- `VaultfireSafeSDK` — privacy-preserving wrapper

**Factory functions:**
- `createVaultfireSDK(chain?: ChainId): VaultfireSDK`
- `createVaultfireSafeSDK(config?: VaultfireSafeConfig): VaultfireSafeSDK`
- `createVaultfireSafeSDKForChain(chain?: ChainId, config?: Omit<VaultfireSafeConfig, 'chain'>): VaultfireSafeSDK`

**Enums:**
- `ModuleType` (0–7)

**Types (exported):**
- `ChainId`, `VaultfireConfig`, `BeliefAttestation`, `VerificationResult`, `Attestation`, `ModuleInfo`
- `VaultfireSafeConfig`, `VerifyStatementRequest`

### VaultfireSDK Public Methods

| Method | Signature | Notes |
|---|---|---|
| `connect` | `(signer: Signer): void` | Connects signer for write operations |
| `verifyBelief` | `(attestation: BeliefAttestation): Promise<VerificationResult>` | Submits belief hash on-chain |
| `isSovereign` | `(beliefHash: string): Promise<boolean>` | Read-only check |
| `getAttestations` | `(address: string, limit?: number): Promise<Attestation[]>` | Event log query |
| `getModules` | `(): Promise<ModuleInfo[]>` | Returns hardcoded module list |
| `hashBelief` | `(statement: string): string` | keccak256 hash utility |
| `getChainConfig` | `(): { chain, chainId, contracts }` | Current chain state |
| `estimateGas` | `(attestation: BeliefAttestation): Promise<bigint>` | Gas estimation |

### VaultfireSafeSDK Public Methods

| Method | Signature | Notes |
|---|---|---|
| `connect` | `(signer: Signer): void` | Delegates to underlying SDK |
| `verifyStatement` | `(request: VerifyStatementRequest): Promise<VerificationResult>` | Hashes locally, then calls verifyBelief |
| `hashStatement` | `(statement: string): string` | Salted + normalized hash |
| `isSovereign` | `(beliefHash: string): Promise<boolean>` | Passthrough |
| `getModules` | `(): Promise<ModuleInfo[]>` | Passthrough |
| `getChainConfig` | `(): object` | Passthrough |
| `unsafeRaw` | `(): VaultfireSDK` | Escape hatch to core SDK |

---

## 5. Chain Support

| Chain | Chain ID | Status | DilithiumAttestor | BeliefVerifier | Notes |
|---|---|---|---|---|---|
| `base` | 8453 | Live | `0xBBC0EFdEE23854e7cb7C4c0f56fF7670BB0530A4` | `0xa5CEC47B48999EB398707838E3A18dd20A1ae272` | Mainnet |
| `avalanche` | 43114 | Live | `0x211554bd46e3D4e064b51a31F61927ae9c7bCF1f` | `0xb3d8063e67bdA1a869721D0F6c346f1Af0469D2F` | Mainnet |
| `base-sepolia` | 84532 | Testnet | `0x000...000` (zero address) | `0x000...000` (zero address) | Contracts NOT deployed |
| `base-goerli` | 84531 | Deprecated | `0x000...000` (zero address) | `0x000...000` (zero address) | Goerli deprecated; contracts NOT deployed |

**Chain support is solid for the two live networks.** The SDK correctly resolves RPC URLs and contract addresses by chain name at construction time.

**Issues:**
- `base-sepolia` and `base-goerli` have zero-address contracts — any write operation on these chains will silently target the zero address (will fail with a contract call error, but no defensive warning is thrown).
- `API_REFERENCE.md` makes **zero mention** of Avalanche, even though the SDK and README fully support it. The API reference only describes Base.
- No Avalanche Fuji testnet support (`fuji`, chain ID 43113).

---

## 6. Feature Analysis

### 6a. Bond Support (Accountability / Partnership)

**NOT PRESENT.** Despite `bonds`, `accountability`, and `partnership` appearing as npm keywords in `package.json`, there is **zero implementation** of any bond mechanism in the codebase. No `Bond`, `AccountabilityBond`, `PartnershipBond` classes, interfaces, ABIs, or contract interactions exist anywhere in `src/`.

The keywords in `package.json` are purely aspirational/marketing. No bond feature is referenced in the documentation either.

### 6b. Trust Verification

**Partially implemented.** Trust verification is the core feature:
- `verifyBelief()` submits a `beliefHash` + optional ZK proof to the `DilithiumAttestor` contract
- `isSovereign()` checks if a belief has been attested
- `getAttestations()` fetches historical attestations for an address

However, the implementation has gaps (see Issues section).

### 6c. x402 Payment Features

**NOT PRESENT.** Despite appearing as a keyword search candidate (from the task description), there is no x402 payment protocol support anywhere in the source code. The grep for `x402`, `payment`, or `pay` in `src/` returned no matches. The `payment` match that was initially flagged was a false positive — it matched "message" substrings in comments.

### 6d. XMTP Messaging Features

**NOT PRESENT.** No XMTP integration exists in the source. The grep match for "message" in `src/vaultfire.ts` was only in JSDoc comments (`error.message`, `console.log('TX:...')`). No XMTP client, conversation, or messaging API exists.

### 6e. VNS (Vaultfire Name Service) Features

**NOT PRESENT.** No VNS module, name resolution, or name registration features exist anywhere in the SDK.

### 6f. Privacy Mode

**Implemented — well-designed.** `VaultfireSafeSDK` in `src/safe.ts` provides:
- Local statement hashing before any on-chain interaction (raw plaintext never transmitted)
- Optional `privacySalt` to prevent dictionary/rainbow-table attacks
- Statement normalization (trim + collapse whitespace) — enabled by default, can be disabled
- Analytics disabled by default
- `metadata` parameter intentionally excluded from `verifyStatement()` to prevent accidental leakage
- Named `unsafeRaw()` escape hatch to discourage casual raw-SDK usage
- Documented in `SAFE_DEFAULTS.md` with clear logging guidance

This is the strongest feature implementation in the SDK.

---

## 7. Error Handling Patterns

### Pattern 1: Throw on pre-condition failure
```typescript
// verifyBelief — throws when no signer connected
if (!this.signer) {
  throw new Error('SDK not connected. Call connect(signer) first.');
}
// Also throws on invalid beliefHash format
if (!attestation.beliefHash || !attestation.beliefHash.startsWith('0x')) {
  throw new Error('Invalid beliefHash format');
}
```
This is correct behavior for developer misconfiguration.

### Pattern 2: Result-type error return (catch-and-return)
```typescript
// verifyBelief — blockchain errors become result.error
try {
  // ...contract call...
} catch (error) {
  return {
    verified: false,
    error: error instanceof Error ? error.message : 'Unknown error',
  };
}
```

### Pattern 3: Silent fallback (swallow exception)
```typescript
// isSovereign — network errors silently return false
async isSovereign(beliefHash: string): Promise<boolean> {
  try {
    return await this.contract.isBeliefSovereign(beliefHash);
  } catch {
    return false;
  }
}

// getAttestations — network errors silently return []
} catch {
  return [];
}

// estimateGas — fails silently, returns hardcoded 61000
} catch {
  return BigInt(61000);
}
```

**Issues with error handling:**
1. **Silent catch blocks** in `isSovereign`, `getAttestations`, and `estimateGas` swallow all errors without any indication of failure or error reporting mechanism. A caller has no way to distinguish "no attestations found" from "RPC call failed" from `getAttestations()`.
2. **No custom error classes** — all errors are plain `Error` instances or string-encoded in result objects. There is no `VaultfireError`, `ChainError`, `AttestationError`, etc. that consumers could `instanceof`-check.
3. **beliefHash validation is incomplete** — it only checks for `0x` prefix, not that the hash is exactly 66 characters (32 bytes = 64 hex chars + `0x`). A partial hash like `0x1234` would pass validation and fail on-chain.
4. **`verifyBelief` throws before catching** for some errors but catches-and-returns for others — inconsistent error surface for callers.

---

## 8. Type Definitions Completeness

**Rating: Good, with minor gaps.**

| Type/Interface | Status | Notes |
|---|---|---|
| `ChainId` | ✅ Complete | String literal union |
| `VaultfireConfig` | ✅ Complete | All optional fields |
| `VaultfireSafeConfig` | ✅ Complete | Extends VaultfireConfig |
| `BeliefAttestation` | ✅ Complete | All fields documented |
| `VerificationResult` | ✅ Complete | Optional fields for partial failures |
| `Attestation` | ✅ Complete | All return fields typed |
| `ModuleInfo` | ✅ Complete | Basic info type |
| `VerifyStatementRequest` | ✅ Complete | Narrows BeliefAttestation |
| `ModuleType` enum | ✅ Complete | 8 values, 0–7 |
| `getChainConfig()` return type | ⚠️ Inline only | Not exported as a named type |
| Contract ABI types | ⚠️ Minimal ABI | Only `attestBelief`, `isBeliefSovereign`, `BeliefAttested` event — BeliefVerifier contract has no ABI at all |
| Error types | ❌ Missing | No custom error classes or error discriminant union |
| Event types | ❌ Missing | No typed event object exported |

**Specific type issue:** `getChainConfig()` returns an inline `{ chain: ChainId; chainId: number; contracts: { dilithiumAttestor?: string; beliefVerifier?: string } }` — the `contracts` subtype has optional fields, but in practice they're always present. This mismatch creates unnecessary null-check burden for callers.

**`moduleId` typed as `number`** in `BeliefAttestation` and `Attestation` interfaces — should ideally be `ModuleType` enum (or `ModuleType | number` for extensibility). Passing `99` as a moduleId would compile without error.

---

## 9. Documentation Quality

### JSDoc Coverage
- All exported classes have `@example` blocks ✅
- All public methods have `@param`, `@returns` JSDoc ✅  
- Constructor and config options documented ✅
- `@packageDocumentation` on both `src/index.ts` and `src/vaultfire.ts` ✅

### Markdown Docs
- `README.md` — well-structured, covers quick start, feature matrix, chain table, API reference overview, architecture diagram ✅
- `API_REFERENCE.md` — detailed REST API reference, TypeScript method docs, error codes, rate limits ✅
- `SAFE_DEFAULTS.md` — excellent privacy model documentation with logging guidance ✅

### Documentation Issues
- `API_REFERENCE.md` **completely omits Avalanche** — chain table, constructor docs, and all examples are Base-only despite the SDK fully supporting Avalanche
- `API_REFERENCE.md` describes `chain` as `'base' | 'base-sepolia' | 'base-goerli'` — missing `'avalanche'` from the constructor parameter docs
- `README.md` references `examples/` directory but two of the four example files have broken import paths (see Broken Imports section)
- No CHANGELOG or CONTRIBUTING docs
- No `typedoc` or automated docs generation configured

---

## 10. SDK Best Practices Assessment

### ✅ Present

| Practice | Notes |
|---|---|
| Barrel file (`index.ts`) | Clean, well-organized re-exports |
| Type-safe API | Full TypeScript, strict mode, declaration files |
| Configuration options | `VaultfireConfig` with optional overrides for RPC, contracts, API key |
| Factory functions | `createVaultfireSDK`, `createVaultfireSafeSDK`, `createVaultfireSafeSDKForChain` |
| `package.json` `files` field | Only ships `dist/`, docs, examples — not `src/` or test files |
| `engines` field | Specifies `node >= 18.0.0` |
| `prepublishOnly` build step | Ensures dist is built before publish |
| Privacy-preserving mode | Solid VaultfireSafeSDK design |
| JSDoc on all public APIs | Good coverage |
| `const` ABI | `as const` for type-safe ABI |
| Minimal dependencies | Only `ethers` v6 as runtime dep |

### ❌ Missing

| Practice | Impact | Notes |
|---|---|---|
| **Retry logic** | High | No exponential backoff, no retry on transient RPC failures |
| **Logging/observability support** | Medium | No logger injection (`console.log` only in examples), no debug mode |
| **Custom error classes** | High | No `VaultfireError`, `ChainError` etc. — callers can't programmatically distinguish error types |
| **Source maps** | Medium | `dist/` has no `.map` files — harder to debug in consuming projects |
| **ESM build** | Medium | `package.json` sets both `main` and `module` to the same CJS file — no actual ESM output |
| **`exports` field** | Medium | No `package.json` `"exports"` map — modern bundlers prefer this over `main`/`module` |
| **Version/changelog** | Low | No CHANGELOG.md; version is hardcoded `1.0.0` |
| **Rate limiting / throttle** | Medium | `getAttestations` could overwhelm RPC providers — no configurable block range limit |
| **Provider management** | Medium | No way to re-configure provider after instantiation; no connection health check |
| **`disconnect` method** | Low | No way to remove a signer once set |
| **Event subscriptions** | Low | No `on('BeliefAttested', callback)` subscription API |
| **Pagination** | Medium | `getAttestations` only queries last 10,000 blocks (`-10000`) — older attestations are silently omitted |

---

## 11. Broken Imports and References

### Critical: Example files have wrong import paths

Three of four example files import from a non-existent path:

```typescript
// examples/defi-trading.ts — BROKEN
import { VaultfireSDK, ModuleType } from '../vaultfire';

// examples/governance-dao.ts — BROKEN
import { VaultfireSDK, ModuleType } from '../vaultfire';

// examples/privacy-preserving-express.ts — BROKEN
import { VaultfireSafeSDK, ModuleType } from '../vaultfire';
```

The file `vaultfire.ts` does not exist at the root level — it lives in `src/vaultfire.ts`. Running these examples with `ts-node` (as documented in `package.json` scripts) would fail with a module not found error.

The correct import should be either:
- `'../src/vaultfire'` (relative path to source), or
- `'@vaultfire/sdk'` (package import, as used correctly in `privacy-preserving-nextjs-route.ts`)

**Only `examples/privacy-preserving-nextjs-route.ts` has the correct import path (`@vaultfire/sdk`).**

### Minor: Double re-export of `VaultfireSafeSDK`

`src/vaultfire.ts` ends with:
```typescript
export { VaultfireSafeSDK, createVaultfireSafeSDK, createVaultfireSafeSDKForChain } from './safe';
```

This means the Safe SDK is exported from both `src/vaultfire.ts` AND re-exported again from `src/index.ts`. This is redundant but not broken — TypeScript handles this cleanly and the compiled output is deduplicated. Still, it's unnecessary architectural noise.

### Minor: `BeliefVerifier` contract declared but never used

The `CHAIN_CONFIG` stores `beliefVerifier` addresses for all chains, and `VaultfireConfig` exposes `contracts.beliefVerifier`, but:
- No `BeliefVerifier` ABI is defined
- No `Contract` instance for `BeliefVerifier` is created
- The contract address is stored and retrievable via `getChainConfig()` but never interacted with

This suggests the `BeliefVerifier` integration is incomplete — it may be the intended destination for `verifyBelief()` write operations (vs. the currently used `DilithiumAttestor`), or it may be a future feature not yet implemented.

---

## 12. Implementation Quality Issues

### Issue 1: `getAttestations` — inefficient and incomplete address filtering

```typescript
const filter = this.contract.filters.BeliefAttested(null, null, null);
```

The `prover` argument in the `BeliefAttested` event is **NOT indexed** (confirmed from ABI: `indexed: false`). This means it cannot be used as a bloom-filter topic in an eth_getLogs call. As a result:
1. The filter fetches **all** `BeliefAttested` events from the last 10,000 blocks
2. Address filtering happens in JavaScript after fetching everything
3. With any significant protocol activity, this will be slow and may hit RPC payload limits

The correct approach would be to either (a) request the contract to index the `prover` address, or (b) use a dedicated indexer/API for historical attestation queries.

### Issue 2: `getAttestations` — `moduleId` always returns `0`

```typescript
moduleId: 0, // TODO: Extract from event
```

The `BeliefAttested` event ABI does not include `moduleId` as a field:
```
BeliefAttested(bytes32 beliefHash, address prover, bool zkVerified)
```

So `moduleId` cannot be recovered from the event log. The `Attestation` interface promises a valid `moduleId`, but `getAttestations()` always returns `0` (GENERIC) for every attestation regardless of what module was actually used. This is a **data integrity bug** — callers building reputation scores or governance systems that filter by `a.moduleId === ModuleType.GOVERNANCE` will get incorrect results.

### Issue 3: `getAttestations` — only last 10,000 blocks

`queryFilter(filter, -10000, 'latest')` hard-codes a window of ~10,000 blocks (~33 hours on Base at ~1 block/3.3s). Any attestations older than this are silently omitted with no indication. The `limit` parameter only caps the number of returned results, not the block range.

### Issue 4: `analytics` and `apiKey` config fields are never used

Both `analytics` and `apiKey` are stored in the config but never referenced in any actual operation:
- No HTTP calls use the API key as a header
- Analytics is stored but no tracking/telemetry code exists

These fields are effectively dead configuration options.

### Issue 5: `beliefHash` validation allows short hashes

The validation only checks `startsWith('0x')`:
```typescript
if (!attestation.beliefHash || !attestation.beliefHash.startsWith('0x')) {
  throw new Error('Invalid beliefHash format');
}
```

A value like `'0x'` or `'0x1234'` would pass validation but fail on-chain because the contract expects `bytes32`. A proper check should be: `/^0x[0-9a-fA-F]{64}$/.test(attestation.beliefHash)`.

### Issue 6: `verifyBelief` inconsistent error behavior

The method both **throws** (for missing signer, invalid hash format) AND **returns an error result** (for contract call failures). Callers must handle both `try/catch` and `result.error` checks — inconsistent API contract.

### Issue 7: No ESM build despite `"module"` field in package.json

The `package.json` declares `"module": "dist/index.js"` (the `module` field is a hint to bundlers for ESM), but `tsconfig.json` compiles to `CommonJS`. The actual `dist/index.js` is a CJS file with `require()` calls, not an ESM module with `import`. Tree-shaking in bundlers will not work as intended.

---

## 13. Missing Features vs. SDK Task Requirements

| Feature | Present? | Notes |
|---|---|---|
| Bond support (Accountability) | ❌ | Keywords only, no implementation |
| Bond support (Partnership) | ❌ | Keywords only, no implementation |
| Trust verification | ✅ Partial | Core feature, but `moduleId` bug and block range limit |
| x402 payment features | ❌ | No implementation |
| XMTP messaging features | ❌ | No implementation |
| VNS (Vaultfire Name Service) | ❌ | No implementation |
| Privacy mode | ✅ Complete | `VaultfireSafeSDK` is well-designed |
| Multi-chain (Base) | ✅ | Live mainnet |
| Multi-chain (Avalanche) | ✅ | Live mainnet |
| Testnet support | ⚠️ | base-sepolia configured but zero-address contracts |
| Retry logic | ❌ | Not implemented |
| Logging support | ❌ | No logger interface |
| Custom error types | ❌ | Not implemented |
| Pagination for attestations | ❌ | Block range hard-coded to 10k |
| Event subscriptions | ❌ | Not implemented |
| ESM build | ❌ | CJS only despite `module` field |
| Source maps | ❌ | Not generated |

---

## 14. Summary Assessment

### Strengths

1. **Clean, minimal codebase** — focused scope, easy to understand
2. **TypeScript strict mode** — compiles cleanly with zero errors
3. **All 36 tests pass** — good baseline test coverage for the implemented features
4. **`VaultfireSafeSDK` is well-designed** — privacy model is thoughtful, salted hashing, normalization, explicit unsafe escape hatch
5. **JSDoc on all public APIs** — good in-code documentation
6. **Multi-chain support works** — Base and Avalanche correctly configured
7. **Minimal dependencies** — only `ethers` v6 at runtime
8. **Barrel file is well-organized** — clean `index.ts` with clear sections

### Weaknesses / Bugs

1. **Three of four example files have broken import paths** — `'../vaultfire'` does not resolve; examples will not run
2. **`getAttestations()` always returns `moduleId: 0`** — silent data integrity bug, `// TODO` left in production code
3. **`getAttestations()` only queries last 10,000 blocks** — silently drops older attestations
4. **`BeliefVerifier` contract is configured but never used** — unclear if this is intentional
5. **`analytics` and `apiKey` config fields are inert** — stored but never acted upon
6. **No custom error classes** — callers can't distinguish error types
7. **No retry/backoff logic** — transient RPC failures cause silent `false`/`[]` returns
8. **`beliefHash` validation too loose** — accepts any `0x`-prefixed string
9. **No ESM build** despite `"module"` field in package.json
10. **Bond/x402/XMTP/VNS features advertised in keywords but absent** — `package.json` keywords are misleading
11. **`API_REFERENCE.md` omits Avalanche entirely**
12. **No source maps in dist**
13. **`prover` field in event not indexed** — makes `getAttestations()` inherently inefficient at scale

### Priority Fixes

| Priority | Issue |
|---|---|
| P0 | Fix example import paths (`'../vaultfire'` → `'../src/vaultfire'` or `'@vaultfire/sdk'`) |
| P0 | Fix `moduleId: 0` hardcode in `getAttestations()` — either add to ABI/event or document the limitation |
| P1 | Add custom error classes (`VaultfireError`, `NotConnectedError`, etc.) |
| P1 | Fix `beliefHash` validation regex to require full 32-byte hex |
| P1 | Standardize error surface — throw or return, not both |
| P1 | Update `API_REFERENCE.md` to include Avalanche chain docs |
| P2 | Remove `analytics` and `apiKey` dead fields or implement them |
| P2 | Add configurable `fromBlock` parameter to `getAttestations()` |
| P2 | Add ESM build output to tsconfig/package.json |
| P2 | Add source maps to tsconfig (`sourceMap: true`) |
| P3 | Add retry/backoff wrapper for RPC calls |
| P3 | Add logger injection support |
| P3 | Add `"exports"` field to package.json |
| P3 | Implement Bond, x402, XMTP, VNS if these are intended features |
