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
TLSNotaryService Class
The TLSNotaryService class manages attestation tokens and proof storage. It provides methods for both direct execution and wallet-confirmation flows.
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.
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.
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.
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.
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.
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.
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.
const fee = service.calculateStorageFee(5); // 6 DEM for 5KB proof (1 base + 5 per KB)
Response Types
AttestationTokenResponse
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
}
StoreProofResponse
interface StoreProofResponse {
txHash: string; // Transaction hash
storageFee: number; // Total fee burned (in DEM)
broadcastStatus: number; // HTTP status (200 = success)
broadcastMessage?: string;
}
TransactionDetails (for confirmation callbacks)
interface TransactionDetails {
transaction: any; // The signed transaction object
txHash: string; // Transaction hash
amount: number; // Amount in DEM being burned
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.
// 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.
// 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.
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() Parameters
| Parameter | Type | Required | Description |
|---|
url | string | Yes | The target HTTPS URL to attest |
method | "GET" or "POST" | No | HTTP method (default: “GET”) |
headers | Record<string, string> | No | Custom headers to include |
body | string | No | Request body for POST requests |
commit | CommitRanges | No | Byte ranges to include in proof |
maxSentData | number | No | Max sent data in bytes (default: 16384) |
maxRecvData | number | No | Max receive data in bytes (default: 16384) |
attest() Response
interface AttestResult {
presentation: PresentationJSON; // The proof data
sent: string; // Sent request data
recv: string; // Received response data
time: number; // Attestation timestamp
serverName: string; // Server hostname
}
verify()
Verify an attestation proof:
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
- Generate Transaction: Create the unsigned transaction
- Sign & Confirm: Send to wallet extension for user approval and signing
- Broadcast: Send the signed transaction to the network
The WithConfirmation methods implement this pattern:
// 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);
}
}
);
const result = await tlsn.attest({
url: "https://api.example.com/data",
headers: {
"Authorization": "Bearer your-token",
"X-Custom-Header": "value"
}
});
POST Requests
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:
const result = await tlsn.attest({
url: "https://api.example.com/data",
commit: {
sent: [{ start: 0, end: 100 }], // Include first 100 bytes of request
recv: [{ start: 0, end: 500 }], // Include first 500 bytes of response
}
});
Larger commit ranges result in larger proofs, which increase storage costs. Only include the data you need to prove.