You don't need this page to use ASC. It explains how published ASCs are stored.
Docs
Under the hood: inscription
For contributors. The IQ Labs memo and the four IQ sample files, unchanged.
The IQ Labs memo
# Built on IQ Labs: exact APIs used by Actually Smart Contracts
IQ Labs provides the on-chain storage, tables and encryption. ASC adds the compiler, the AI jury, the signed rulings and the escrow. Checked Nov 4, 2026 against IQ Labs' docs and GitHub. The Solana SDK README is marked **Draft**, so check signatures against the SDK source before shipping.
## Packages
| Chain | Package | Import | Docs |
|---|---|---|---|
| Solana | `@iqlabs-official/solana-sdk` | `import iqlabs from '@iqlabs-official/solana-sdk'` | github.com/IQCoreTeam/iqlabs-solana-sdk |
| EVM | `@iqlabs-official/ethereum-sdk` (ethers v6) | `import iqlabs from '@iqlabs-official/ethereum-sdk'` | iqlabs.mintlify.app/docs-ethereum, github.com/IQCoreTeam/iq-ethereum-sdk |
| Python (Solana) | `iqlabs-solana-sdk-python` | | github.com/IQCoreTeam/iqlabs-solana-sdk-python |
## What ASC uses, and for what
| ASC need | IQ Labs API | Notes |
|---|---|---|
| Inscribe the compiled step list | Solana: `writer.codeIn({connection, signer}, data, filename?, method=0, filetype='', onProgress?) → signature`. EVM: `writer.codeIn(signer, data, filename?, filetype?, onProgress?) → txHash` | Solana tiers: under 900 B one transaction; 900 B to 8.5 KB several; 8.5 KB and up in parallel. EVM chunks are 850 B in a linked list. The hot-wallet steps are 1,909 B |
| Read it back and verify | Solana: `reader.readCodeIn(txSignature, speed?, onProgress?) → {metadata, data}`. EVM: `reader.readCodeIn(txHash, onProgress?)` | ASC stores `policyTx` (the IQ transaction id) and `policyRef` (SHA-256 of `data` on Solana, keccak256 on EVM). Every attestation signs over `policyRef` |
| Private ASCs | `crypto.deriveX25519Keypair(signMessage)` per juror; `crypto.multiEncrypt(recipientPubHexes, plaintext)`; juror reads with `crypto.multiDecrypt(privKey, pubKeyHex, encrypted)` | Inscribe only the envelope `{plaintextRef, encrypted}`. Jurors check `sha256(decrypted) === plaintextRef` before judging. Limit: any juror can leak the rules; the chain can't check the plaintext |
| Juror registry | `writer.createTable(...)`, columns `wallet, family, model, x25519Pub`, `writers` allowlist = ASC admin | Wallet = juror identity (same model as IQ's AgentNet: one wallet, one agent) |
| Public rulings log | `writer.writeRow(...)` into `rulings`; `reader.readTableRows(...)` | The escrow program still verifies Ed25519 signatures itself; the table is the readable record |
| Deliver a private request to the jury (optional) | `writer.requestConnection`, `writer.writeConnectionRow`, `reader.readConnectionRows` with `crypto.dhEncrypt` | For requests that carry private evidence |
| EVM networks | `setNetwork('sepolia' \| 'monad' \| 'robinhood')`, `assertChainMatches(signer)` | Contracts: Sepolia `0x246A08D9fdD9b3990A88eD1f2DF1A87239839F07`, Monad `0x7ae06f87Cf93606DA2BD6A281afB28028cAE233D`, Robinhood Chain `0x88af59e58C7E5DcbE7cc12972B90cff3fEEF7223`. **Ethereum mainnet is not deployed** |
| Fees | EVM: `utils.resolveCodeInFee`, `utils.getBasicFee`, `utils.getLinkedListFee` | Show the inscription cost before the author signs |
## What ASC builds itself (not in IQ Labs)
- English to loop-free step compiler and loophole checker; human sign-off.
- The AI jury: juror harness, commit-reveal, quorum, dispute jury.
- Escrow program with hard caps, verifying juror Ed25519 signatures in the payout transaction (Solana precompile) or a two-step request/release contract on EVM (`checkPolicy`).
- Proof of which model answered: planned, following Anthropic's FlashProve prototype; not built.
## Open checks before shipping
1. Solana program ID and devnet/mainnet deployments: not stated in the README (the localnet run cloned IQ's program from devnet).
2. Solana `writer.createTable` takes a `tableSeed` and `tableName`; confirm the `rulings` table can accept rows from many juror wallets (`writers` allowlist or `gate`).
3. `multiEncrypt` recipient limit and envelope size: keep the envelope under 8.5 KB.
4. IQ Labs' terms for commercial use of the SDKs (Apache-2.0 on GitHub) and their fees.
IQ sample files
iq_inscribe_asc.solana.tsTypeScriptillustrative
// Inscribe an ASC step list on Solana with IQ Labs code-in, then read it back and hash it.
// API per the @iqlabs-official/solana-sdk README (marked Draft): check signatures against the SDK source.
import iqlabs from '@iqlabs-official/solana-sdk';
import { Connection, Keypair } from '@solana/web3.js';
import { createHash } from 'node:crypto';
import steps from './hot_wallet_steps.json';
const connection = new Connection(process.env.SOLANA_RPC_URL ?? 'http://127.0.0.1:8899', 'confirmed');
iqlabs.setRpcUrl(connection.rpcEndpoint);
const signer = Keypair.fromSecretKey(/* author wallet secret key */ new Uint8Array());
const body = JSON.stringify(steps); // 1,909 bytes for the hot-wallet example: multi-transaction tier (900 B to 8.5 KB)
const policyTx = await iqlabs.writer.codeIn(
{ connection, signer },
body,
'asc-hot-wallet.json', // filename
0, // method (SDK default)
'application/json', // filetype
);
const { metadata, data } = await iqlabs.reader.readCodeIn(policyTx);
if (data !== body) throw new Error('read-back mismatch');
const policyRef = createHash('sha256').update(data).digest('hex');
console.log({ policyTx, policyRef, metadata }); // store both on the ASC record and in each attestation
iq_inscribe_asc.evm.tsTypeScriptillustrative
// Inscribe the same ASC on an EVM chain with IQ Labs' Ethereum SDK.
// Networks today: 'sepolia' (default), 'monad', 'robinhood'. Ethereum mainnet is not deployed.
import iqlabs from '@iqlabs-official/ethereum-sdk';
import { Wallet, JsonRpcProvider, keccak256, toUtf8Bytes } from 'ethers';
import steps from './hot_wallet_steps.json';
iqlabs.setNetwork('sepolia');
const provider = new JsonRpcProvider(iqlabs.getRpcUrl());
const signer = new Wallet(process.env.AUTHOR_PRIVATE_KEY!, provider);
await iqlabs.assertChainMatches(signer);
const body = JSON.stringify(steps); // over 850 bytes: SDK uploads a linked list of chunks
const policyTx = await iqlabs.writer.codeIn(signer, body, 'asc-hot-wallet.json', 'application/json');
const { data } = await iqlabs.reader.readCodeIn(policyTx);
if (data !== body) throw new Error('read-back mismatch');
// The guarded contract stores keccak256 of the bytes; checkPolicy() attestations sign over it.
const policyRef = keccak256(toUtf8Bytes(body));
console.log({ policyTx, policyRef });
iq_private_asc.tsTypeScriptillustrative
// Private ASC: encrypt the rules to every juror's wallet-derived X25519 key, inscribe only the ciphertext.
// Works the same with @iqlabs-official/ethereum-sdk (same crypto namespace).
import iqlabs from '@iqlabs-official/solana-sdk';
import { createHash } from 'node:crypto';
// Each juror publishes its X25519 public key once, derived from its wallet:
// const sign = async (msg: Uint8Array) => wallet.signMessage(msg);
// const { pubKey } = await iqlabs.crypto.deriveX25519Keypair(sign);
const jurorPubKeys: string[] = [/* hex X25519 pubkeys from the jurors table */];
export async function inscribePrivateAsc(input: { connection: any; signer: any }, rulesJson: string) {
const plaintextRef = createHash('sha256').update(rulesJson).digest('hex'); // jurors attest to this
const encrypted = iqlabs.crypto.multiEncrypt(jurorPubKeys, new TextEncoder().encode(rulesJson)); // { recipients, iv, ciphertext }
const envelope = JSON.stringify({ kind: 'asc.private/1', plaintextRef, encrypted });
const policyTx = await iqlabs.writer.codeIn(input, envelope, 'asc-private.json', 0, 'application/json');
return { policyTx, plaintextRef };
}
// Juror side:
// const { metadata, data } = await iqlabs.reader.readCodeIn(policyTx);
// const { plaintextRef, encrypted } = JSON.parse(data!);
// const rules = iqlabs.crypto.multiDecrypt(privKey, pubKey, encrypted); // Uint8Array
// check sha256(rules) === plaintextRef before judging.
iq_jury_tables.solana.tsTypeScriptillustrative
// Public juror registry and rulings log as IQ Labs tables. The escrow program still verifies
// Ed25519 signatures itself; the tables are the public, append-only record anyone can read.
import iqlabs from '@iqlabs-official/solana-sdk';
const DB = 'asc';
export async function setup(connection: any, signer: any) {
await iqlabs.writer.createTable(connection, signer, DB, 'jurors', 'jurors',
['wallet', 'family', 'model', 'x25519Pub', 'addedAt'], 'wallet', [], undefined, [/* writer allowlist: ASC admin */]);
await iqlabs.writer.createTable(connection, signer, DB, 'rulings', 'rulings',
['policyRef', 'actionHash', 'ruling', 'wallet', 'sig', 'at'], 'actionHash', []);
}
export async function logRuling(connection: any, jurorSigner: any, row: Record<string, string>) {
return iqlabs.writer.writeRow(connection, jurorSigner, DB, 'rulings', JSON.stringify(row));
}
// Readers: iqlabs.reader.readTableRows(<table account>, { limit: 50 })