> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kynesys.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# TLSNotary API Reference

> API reference for TLSNotary cryptographic attestation in the Demos SDK

# TLSNotary API Reference

## TLSNotaryService Class

The `TLSNotaryService` class manages attestation tokens and proof storage. It provides methods for both direct execution and wallet-confirmation flows.

```typescript theme={null}
import { TLSNotaryService } from '@kynesyslabs/demosdk/tlsnotary';

const service = new TLSNotaryService(demos);
```

### Methods

#### requestAttestation()

Requests an attestation token for a target URL. Burns 1 DEM and returns a proxy URL.

```typescript theme={null}
const { proxyUrl, tokenId, expiresAt } = await service.requestAttestation({
    targetUrl: 'https://api.example.com/data'
});
```

#### requestAttestationWithConfirmation()

Same as `requestAttestation()` but allows user confirmation before broadcasting. **Recommended for wallet extension apps.**

```typescript theme={null}
const response = await service.requestAttestationWithConfirmation(
    { targetUrl: 'https://api.example.com/data' },
    {
        onConfirm: async (details) => {
            // Show transaction to user for approval
            // details.txHash, details.amount, details.description
            return await showUserConfirmDialog(details);
        }
    }
);
```

#### createTLSNotary()

Convenience method that handles the full setup: request token → get proxy → create TLSNotary instance → initialize WASM.

```typescript theme={null}
const { tlsn, tokenId, proxyUrl } = await service.createTLSNotary({
    targetUrl: 'https://api.example.com/data'
});

// Ready to attest immediately!
const result = await tlsn.attest({ url: 'https://api.example.com/data' });
```

#### createTLSNotaryWithConfirmation()

Same as `createTLSNotary()` but with user confirmation. **Recommended for wallet extension apps.**

```typescript theme={null}
const { tlsn, tokenId } = await service.createTLSNotaryWithConfirmation(
    { targetUrl: 'https://api.example.com/data' },
    {
        onConfirm: async (details) => {
            return await showUserConfirmDialog(details);
        }
    }
);
```

#### storeProof()

Stores an attestation proof on-chain or IPFS.

```typescript theme={null}
const { txHash, storageFee } = await service.storeProof(
    tokenId,
    JSON.stringify(presentation),
    { storage: 'onchain' } // or 'ipfs'
);
```

#### storeProofWithConfirmation()

Same as `storeProof()` but with user confirmation. **Recommended for wallet extension apps.**

```typescript theme={null}
const { txHash, storageFee } = await service.storeProofWithConfirmation(
    tokenId,
    JSON.stringify(presentation),
    { storage: 'onchain' },
    {
        onConfirm: async (details) => {
            return await showUserConfirmDialog(details);
        }
    }
);
```

#### calculateStorageFee()

Calculate the fee for storing a proof.

```typescript theme={null}
// Returns a bigint in OS (smallest units): 6 DEM for a 5KB proof (1 base + 1 per KB).
// Convert for display with denomination.osToDem(fee).
const fee = service.calculateStorageFee(5);
```

### Response Types

#### AttestationTokenResponse

```typescript theme={null}
interface AttestationTokenResponse {
    proxyUrl: string;      // WebSocket proxy URL for attestation
    tokenId: string;       // Unique token ID
    expiresAt: number;     // Unix timestamp when token expires
    retriesLeft: number;   // Number of retry attempts remaining
    txHash: string;        // Transaction hash of the attestation request
}
```

#### StoreProofResponse

```typescript theme={null}
interface StoreProofResponse {
    txHash: string;          // Transaction hash
    storageFee: bigint;      // Total fee burned, as a bigint in OS (smallest units)
    broadcastStatus: number; // HTTP status (200 = success)
    broadcastMessage?: string;
}
```

#### TransactionDetails (for confirmation callbacks)

```typescript theme={null}
interface TransactionDetails {
    transaction: any;      // The signed transaction object
    txHash: string;        // Transaction hash
    amount: bigint;        // Amount being burned, as a bigint in OS (smallest units)
    description: string;   // Human-readable description
    targetUrl?: string;    // For attestation requests
    tokenId?: string;      // For store transactions
}
```

### Native Transaction Types

TLSNotary uses two native transaction types:

#### tlsn\_request

Requests a TLSNotary attestation. Creates an access token for the proxy.

```typescript theme={null}
// SDK handles this internally
const tx = await demos.createTransaction({
    type: "native",
    data: ["native", {
        nativeOperation: "tlsn_request",
        args: [targetUrl]
    }]
})
```

**Cost**: 1 DEM (burned as fee)

#### tlsn\_store

Stores the proof on-chain after notarization completes.

```typescript theme={null}
// SDK handles this internally
const tx = await demos.createTransaction({
    type: "native",
    data: ["native", {
        nativeOperation: "tlsn_store",
        args: [proofId, proofData]
    }]
})
```

**Cost**: 1 DEM base + 1 DEM per KB (burned as storage fee)

### Cost Structure

| Operation      | Base Cost | Variable Cost | Notes                           |
| -------------- | --------- | ------------- | ------------------------------- |
| `tlsn_request` | 1 DEM     | -             | Initial request fee             |
| `tlsn_store`   | 1 DEM     | +1 DEM/KB     | Storage fee based on proof size |
| Gas            | Standard  | -             | Network transaction gas         |

**Example costs:**

* Small proof (1KB): 1 + 1 + 1 = 3 DEM + gas
* Medium proof (5KB): 1 + 1 + 5 = 7 DEM + gas
* Large proof (20KB): 1 + 1 + 20 = 22 DEM + gas

### Error Codes

| Code                        | Description                        | Resolution                             |
| --------------------------- | ---------------------------------- | -------------------------------------- |
| `TLSN_INVALID_URL`          | URL is not accessible or malformed | Verify URL format and accessibility    |
| `TLSN_TIMEOUT`              | Notarization timed out             | Retry or check target server           |
| `TLSN_INSUFFICIENT_BALANCE` | Not enough DEM for fees            | Top up DEM balance                     |
| `TLSN_PROOF_TOO_LARGE`      | Proof exceeds maximum size         | Reduce response size or use redactions |
| `TLSN_TOKEN_EXPIRED`        | Access token expired               | Request will auto-retry                |
| `TLSN_PROXY_UNAVAILABLE`    | No proxy available for domain      | Wait and retry                         |

## TLSNotary Class

The `TLSNotary` class performs the actual WASM-based attestation. Use it after getting a proxy URL from `TLSNotaryService`.

```typescript theme={null}
import { TLSNotary } from '@kynesyslabs/demosdk/tlsnotary';

const tlsn = new TLSNotary({
    notaryUrl: 'http://notary.example.com:7047',
    websocketProxyUrl: proxyUrl, // From TLSNotaryService
});

await tlsn.initialize(); // Load WASM

const result = await tlsn.attest({
    url: 'https://api.example.com/data',
    method: 'GET',
    headers: { 'Accept': 'application/json' },
});
```

### attest() Signature

```typescript theme={null}
attest(
    request: AttestRequest,
    commit?: CommitRanges,
    onStatus?: StatusCallback,
): Promise<AttestResult>
```

The `commit` ranges and `onStatus` callback are passed as separate positional arguments, not as fields of the `request` object.

The `request` (`AttestRequest`) fields are:

| Parameter     | Type                                              | Required | Description                                |
| ------------- | ------------------------------------------------- | -------- | ------------------------------------------ |
| `url`         | string                                            | Yes      | The target HTTPS URL to attest             |
| `method`      | `"GET" \| "POST" \| "PUT" \| "DELETE" \| "PATCH"` | No       | HTTP method (default: "GET")               |
| `headers`     | `Record<string, string>`                          | No       | Custom headers to include                  |
| `body`        | `string \| object`                                | No       | Request body for POST/PUT/PATCH requests   |
| `maxSentData` | number                                            | No       | Max sent data in bytes (default: 16384)    |
| `maxRecvData` | number                                            | No       | Max receive data in bytes (default: 16384) |

### attest() Response

```typescript theme={null}
interface AttestResult {
    presentation: PresentationJSON;     // The proof data
    verification: VerificationResult;   // Verification result (time, serverName, sent, recv, notaryKey, verifyingKey)
}
```

### verify()

Verify an attestation proof:

```typescript theme={null}
const result = await tlsn.verify(presentationJSON);
// result: { time, serverName, sent, recv, notaryKey, verifyingKey }
```

## Wallet Extension Integration

For production dApps, users connect via wallet extensions which handle key management. The SDK supports a 3-step flow for wallet extensions:

### The 3-Step Wallet Flow

1. **Generate Transaction**: Create the unsigned transaction
2. **Sign & Confirm**: Send to wallet extension for user approval and signing
3. **Broadcast**: Send the signed transaction to the network

The `WithConfirmation` methods implement this pattern:

```typescript theme={null}
// Example: Full attestation with wallet extension flow
const service = new TLSNotaryService(demos);

// Step 1 & 2: Generate and get user confirmation
const { tlsn, tokenId } = await service.createTLSNotaryWithConfirmation(
    { targetUrl: 'https://api.example.com/data' },
    {
        onConfirm: async (details) => {
            // In a dApp, this would show a modal to the user:
            // "Confirm burning 1 DEM for attestation?"
            // The wallet extension signs when user approves
            return await walletExtension.requestApproval(details.transaction);
        }
    }
);

// Step 3: Perform attestation (no blockchain interaction)
const result = await tlsn.attest({ url: 'https://api.example.com/data' });

// Step 1 & 2 again: Store proof with confirmation
await service.storeProofWithConfirmation(
    tokenId,
    JSON.stringify(result.presentation),
    { storage: 'onchain' },
    {
        onConfirm: async (details) => {
            // "Confirm burning 6 DEM to store proof?"
            return await walletExtension.requestApproval(details.transaction);
        }
    }
);
```

### Custom Headers

```typescript theme={null}
const result = await tlsn.attest({
    url: "https://api.example.com/data",
    headers: {
        "Authorization": "Bearer your-token",
        "X-Custom-Header": "value"
    }
});
```

### POST Requests

```typescript theme={null}
const result = await tlsn.attest({
    url: "https://api.example.com/submit",
    method: "POST",
    headers: {
        "Content-Type": "application/json"
    },
    body: JSON.stringify({ key: "value" })
});
```

### Commit Ranges (Selective Disclosure)

Control which parts of the request/response to include in the proof:

```typescript theme={null}
const result = await tlsn.attest(
    { url: "https://api.example.com/data" },
    {
        sent: [{ start: 0, end: 100 }],  // Include first 100 bytes of request
        recv: [{ start: 0, end: 500 }],  // Include first 500 bytes of response
    }
);
```

The `attestQuick()` method accepts an `AttestOptions` object where `commit` and `onStatus` are fields:

```typescript theme={null}
const result = await tlsn.attestQuick({
    url: "https://api.example.com/data",
    commit: {
        sent: [{ start: 0, end: 100 }],
        recv: [{ start: 0, end: 500 }],
    },
});
```

<Warning>
  Larger commit ranges result in larger proofs, which increase storage costs. Only include the data you need to prove.
</Warning>
