Documentation
Guides and reference for OutLayer verifiable compute and agent custody.
Docs navigation
Example Projects
Production-ready examples demonstrating different WASI patterns and use cases. All examples are open-source and ready to deploy.
random-exampleWASI P1Beginner#
Generate cryptographically secure random numbers inside TEE (Trusted Execution Environment) using WASI's random_get interface.
Use Cases:
- Fair lottery systems requiring verifiable randomness
- Gaming applications needing unpredictable outcomes
- Cryptographic key generation
- Random sampling for statistical analysis
Key Features:
- Uses
getrandomcrate for secure randomness - TEE environment ensures entropy source cannot be manipulated
- Simple JSON input/output interface
- Perfect starter example for WASI development
Input Format:
{
"count": 5,
"min": 1,
"max": 100
}Request 5 random numbers between 1 and 100
Output Format:
{
"numbers": [42, 17, 93, 8, 55]
}How It Works
- WASM calls
random_getWASI function - Worker runtime requests entropy from TEE hardware
- Random bytes are generated using CPU's secure random number generator
- Numbers are scaled to requested range (min-max)
- Result returned as JSON
Technical Details:
- WASI Version: Preview 1 (
wasm32-wasip1) - Language: Rust with
getrandomcrate - Entry Point:
main()reads stdin, writes stdout - Dependencies:
serde_jsonfor JSON parsing - Build:
cargo build --target wasm32-wasip1 --release - Size: ~200KB compiled WASM
vrf-exampleWASI P1Intermediate#
Generate verifiable random numbers with cryptographic proof. Unlike plain randomness, each VRF output includes an Ed25519 signature that anyone can verify on-chain — no trust in the server required. Includes a companion NEAR smart contract for provably fair coin flip with on-chain proof verification.
Use Cases:
- Provably fair gaming and gambling (coin flip, dice, card games)
- Fair lottery and raffle systems with verifiable draws
- Random NFT trait/rarity assignment
- Unbiased leader election and committee selection
- Any application where users must trust the randomness is genuine
Key Features:
- Cryptographic proof via Ed25519 signature — verifiable by anyone
- On-chain verification using native
env::ed25519_verify(~1 TGas) - Generate up to 10 random values per execution with unique sub-seeds
- Range mapping: map raw output to
0..=max(e.g. coin flip: max=1) - Non-manipulable alpha: request_id + sender_id auto-injected by worker
- Includes VRF public key and verification instructions in output
Input Format:
{
"seed": "coin-flip",
"max": 1,
"count": 1
}Generate 1 random number mapped to 0 (Heads) or 1 (Tails)
Output Format:
{
"signer": "alice.near",
"total_calls": 5,
"results": [
{
"value": 0,
"signature_hex": "abcd...1234",
"alpha": "vrf:98321:alice.near:coin-flip"
}
],
"verification": {
"vrf_public_key": "a1b2c3d4...",
"steps": ["1. Get VRF public key...", "2. Verify ed25519...", "..."],
"pubkey_endpoint": "https://api.outlayer.ai/vrf/pubkey",
"near_code": "let valid = env::ed25519_verify(...);"
}
}WASI Code (Rust):
use outlayer::vrf;
let result = vrf::random("coin-flip")?;
// result.output_hex -> SHA256(signature), 32 bytes hex
// result.signature_hex -> Ed25519 signature (the proof)
// result.alpha -> "vrf:{request_id}:{sender_id}:coin-flip"
// Map to range 0..=max
let bytes = hex_to_u32(&result.output_hex);
let side = (bytes as u64 * 2 / (u32::MAX as u64 + 1)) as u32; // 0 or 1How It Works
- WASM module calls
vrf::random("coin-flip")via OutLayer SDK - Worker constructs alpha:
vrf:{request_id}:{sender_id}:coin-flip - Worker sends alpha to Keystore TEE for signing
- Keystore signs with Ed25519:
signature = sign(vrf_sk, alpha) - Output derived:
SHA256(signature)→ 32 random bytes - Contract callback verifies proof:
env::ed25519_verify(sig, alpha, pubkey)
Technical Details:
- WASI Version: Preview 1 (
wasm32-wasip1) - Language: Rust with
outlayerSDK - Entry Point:
main()reads stdin JSON, writes stdout JSON - Crypto: Ed25519 (deterministic, RFC 8032) + SHA-256
- Verification Cost: ~1 TGas (native NEAR ed25519_verify)
- Rate Limit: Max 10 VRF calls per execution
Important Security Notes
- Alpha includes
request_idandsender_idauto-injected by the worker — WASM module cannot forge these values - Ed25519 is deterministic: same key + same alpha = same output, preventing re-rolling
- VRF private key lives only inside TEE (Intel TDX), derived via MPC key ceremony
- Anyone can verify:
ed25519_verify(pubkey, alpha, signature)+SHA256(signature) == output
echo-exampleWASI P1Beginner#
Simple echo service that accepts JSON input and returns it with a timestamp. Demonstrates basic WASI I/O and data processing.
Use Cases:
- Testing WASI input/output pipeline
- Verifying data serialization/deserialization
- Template for building more complex data processing tasks
- Learning WASI development fundamentals
Key Features:
- JSON input validation
- Timestamp generation using WASI clock interface
- Error handling and structured responses
- Minimal dependencies - great learning example
Input Format:
{
"message": "Hello, OutLayer!",
"metadata": {
"user_id": "alice.near"
}
}Output Format:
{
"echo": {
"message": "Hello, OutLayer!",
"metadata": {
"user_id": "alice.near"
}
},
"timestamp": "2025-01-15T12:34:56Z",
"processed_by": "echo-example v1.0"
}How It Works
- WASM reads JSON from stdin
- Deserializes input using serde_json
- Generates timestamp using WASI clock_time_get
- Constructs response object with original data + metadata
- Serializes and writes to stdout
Technical Details:
- WASI Version: Preview 1 (
wasm32-wasip1) - Language: Rust
- Entry Point:
main() - Dependencies:
serde,serde_json,chrono - Build:
cargo build --target wasm32-wasip1 --release - Size: ~180KB compiled WASM
ai-exampleWASI P2SecretsIntermediate#
Integrate OpenAI GPT models into your NEAR smart contracts. Send prompts from on-chain and receive AI-generated responses securely.
Use Cases:
- AI-powered smart contract decision making
- Natural language processing for on-chain data
- Content generation triggered by blockchain events
- Intelligent chatbots with verifiable responses
Key Features:
- HTTP client using
reqwestwith WASI sockets - Encrypted API key storage using OutLayer secrets
- Support for GPT-4, GPT-3.5-turbo models
- Configurable temperature, max tokens, system prompts
Input Format:
{
"prompt": "Explain NEAR Protocol in one sentence",
"model": "gpt-4",
"temperature": 0.7,
"max_tokens": 100
}Output Format:
{
"response": "NEAR Protocol is a scalable, developer-friendly blockchain platform...",
"model": "gpt-4",
"tokens_used": 28,
"finish_reason": "stop"
}How It Works
- WASM reads
OPENAI_API_KEYfrom encrypted secrets (env var) - Constructs HTTP POST request to OpenAI API
- Sends request via WASI HTTP interface
- Receives and parses JSON response
- Extracts AI-generated text and metadata
- Returns structured result to NEAR contract
Technical Details:
- WASI Version: Preview 2 (component model)
- Language: Rust
- HTTP Client:
reqwestwithwasi-preview2feature - Secrets: Required (
OPENAI_API_KEY) - Network: Required (outbound HTTPS to api.openai.com)
- Build:
cargo component build --release - Size: ~2.5MB compiled WASM
Setting Up Secrets
- Navigate to Secrets Management
- Create new secret with key
OPENAI_API_KEYand your OpenAI API key as value - Set repo to your GitHub project (e.g.,
github.com/alice/ai-example) - Choose access condition (e.g., AllowAll for testing, Whitelist for production)
- Worker will automatically decrypt and inject into WASM environment
Important Security Notes
- API keys stored encrypted on-chain, decrypted only in TEE
- Keys never exposed to worker logs or external parties
- Monitor OpenAI API usage to prevent unexpected costs
- Set token limits to control response sizes
weather-exampleWASI P2SecretsIntermediate#
Fetch real-world weather data from OpenWeatherMap API and bring it on-chain. Perfect for parametric insurance, prediction markets, and climate-dependent DeFi.
Use Cases:
- Weather-based parametric insurance (crop insurance, travel insurance)
- Prediction markets requiring real-world weather data
- Climate data for carbon credit verification
- Event cancellation triggers based on weather conditions
Key Features:
- Fetches temperature, humidity, pressure, wind speed
- Supports city name or coordinates lookup
- Returns structured weather data with timestamps
- Encrypted API key via OutLayer secrets (
OPENWEATHER_API_KEY)
Input Format (by city):
{
"city": "London",
"country_code": "UK"
}Input Format (by coordinates):
{
"lat": 51.5074,
"lon": -0.1278
}Output Format:
{
"location": "London, UK",
"temperature_celsius": 12.5,
"humidity_percent": 76,
"pressure_hpa": 1013,
"wind_speed_mps": 3.2,
"description": "partly cloudy",
"timestamp": "2025-01-15T12:34:56Z"
}How It Works
- WASM reads
OPENWEATHER_API_KEYfrom encrypted secrets - Constructs HTTP request to OpenWeatherMap API
- Sends GET request via WASI HTTP interface
- Parses JSON response with serde
- Converts units (Kelvin → Celsius, etc.)
- Returns normalized weather data to NEAR contract
Technical Details:
- WASI Version: Preview 2 (component model)
- Language: Rust
- HTTP Client:
reqwestwith WASI sockets - Secrets: Required (
OPENWEATHER_API_KEY) - Network: Required (outbound HTTPS to api.openweathermap.org)
- API: OpenWeatherMap Current Weather API
- Build:
cargo component build --release - Size: ~2.2MB compiled WASM
Setting Up Secrets
- Get free API key from OpenWeatherMap
- Navigate to Secrets Management
- Create secret: key =
OPENWEATHER_API_KEY, value = your API key - Set repo to your GitHub project
- Choose access condition (AllowAll for public data, Whitelist for production)
Important Security Notes
- Free tier: 60 calls/minute, 1M calls/month
- Monitor API usage to stay within limits
- API keys encrypted and only decrypted in TEE
- Weather data typically updates every 10 minutes - avoid excessive calls
oracle-exampleWASI P2Advanced#
Multi-source price oracle with aggregation and validation. Production-ready decentralized oracle for cryptocurrency and commodity prices.
Key Features:
- Multiple API sources: CoinGecko, CoinMarketCap, TwelveData
- Price aggregation methods: average, median, weighted
- Deviation validation and error handling
- Batch requests for multiple tokens (up to 10)
- API key management via encrypted secrets
- Comprehensive error reporting per source
Supported Assets:
- Cryptocurrencies: Bitcoin, Ethereum, NEAR, SOL, etc.
- Commodities: Gold (XAU/USD), Oil (BRENT/USD)
- Forex: EUR/USD, GBP/USD, etc.
Input Example (Multi-token):
{
"tokens": [
{
"token_id": "bitcoin",
"sources": [
{"name": "coingecko", "token_id": null},
{"name": "coinmarketcap", "token_id": "BTC"}
],
"aggregation_method": "median",
"min_sources_num": 2
}
],
"max_price_deviation_percent": 5.0
}Output Example:
{
"tokens": [
{
"token": "bitcoin",
"data": {
"price": 110836.0,
"timestamp": 1729447200,
"sources": ["coingecko", "coinmarketcap"]
},
"message": null
}
]
}How to Use:
# 1. Get API keys (optional but recommended):
# - CoinMarketCap: https://coinmarketcap.com/api/
# - TwelveData: https://twelvedata.com/apikey
# - CoinGecko: Free tier (no key needed) or Pro
# 2. Store API keys as encrypted secrets via Dashboard
# Open https://app.outlayer.ai/secrets:
# - Secrets JSON: {"CMC_API_KEY":"...", "TWELVE_DATA_KEY":"..."}
# 3. Clone and build
git clone https://github.com/out-layer/oracle-example.git
cd oracle-example
cargo build --target wasm32-wasip2 --release
# 4. Request price data
near call outlayer.testnet request_execution '{
"source": {
"GitHub": {
"repo": "https://github.com/YOUR_USERNAME/oracle-example",
"commit": "main",
"build_target": "wasm32-wasip2"
}
},
"secrets_ref": {
"profile": "production",
"account_id": "your-account.testnet"
},
"resource_limits": {
"max_instructions": 100000000,
"max_memory_mb": 128,
"max_execution_seconds": 60
},
"input_data": "{\"tokens\":[{\"token_id\":\"bitcoin\",\"sources\":[{\"name\":\"coingecko\"},{\"name\":\"coinmarketcap\",\"token_id\":\"BTC\"}],\"aggregation_method\":\"median\",\"min_sources_num\":2}],\"max_price_deviation_percent\":5.0}"
}' --accountId your-account.testnet --deposit 0.1 --gas 300000000000000
# Result will contain median price from multiple sourcesTechnical Details:
- WASI Version: Preview 2 (component model)
- Language: Rust
- HTTP Client:
reqwestwith WASI sockets - Secrets: Optional (API keys for higher rate limits)
- Network: Required (outbound HTTPS to multiple APIs)
- Build:
cargo component build --release - Size: ~3.5MB compiled WASM
Ethereum API OracleWASI P2Advanced#
Query Ethereum blockchain data via JSON-RPC (balances, smart contracts, transactions). Similar to the previous oracle example but configured for Ethereum node providers like Alchemy. Bridge NEAR with Ethereum data for cross-chain applications.
Key Features:
- Ethereum JSON-RPC API integration (eth_getBalance, eth_call, etc.)
- Support for Alchemy, Infura, and other Ethereum node providers
- Custom request structure with JSON path extraction
- Cross-chain data oracle for NEAR ↔ Ethereum bridges
- Encrypted API key storage (Alchemy secrets profile)
- Production-ready on testnet and mainnet
Input Example (Check ETH Balance):
{
"requests": [
{
"id": "alchemy",
"sources": [
{
"name": "custom",
"custom": {
"url": "https://eth-mainnet.g.alchemy.com/v2",
"method": "POST",
"body": {
"method": "eth_getBalance",
"params": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest"],
"id": 1,
"jsonrpc": "2.0"
},
"json_path": "result",
"value_type": "string"
}
}
]
}
],
"max_price_deviation_percent": 10.0
}Output Example:
{
"results": [
{
"id": "alchemy",
"value": "0x1bc16d674ec80000",
"sources_used": 1
}
]
}Quick Start (Testnet):
# Using pre-configured Alchemy secrets on testnet
near contract call-function as-transaction outlayer.testnet request_execution \
json-args '{
"source": {
"GitHub": {
"repo": "https://github.com/out-layer/oracle-example",
"commit": "main",
"build_target": "wasm32-wasip2"
}
},
"secrets_ref": {
"profile": "alchemy",
"account_id": "zavodil2.testnet"
},
"resource_limits": {
"max_instructions": 100000000,
"max_memory_mb": 128,
"max_execution_seconds": 60
},
"input_data": "{\"requests\":[{\"id\":\"alchemy\",\"sources\":[{\"name\":\"custom\",\"custom\":{\"url\":\"https://eth-mainnet.g.alchemy.com/v2\",\"method\":\"POST\",\"body\":{\"method\":\"eth_getBalance\",\"params\":[\"0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045\",\"latest\"],\"id\":1,\"jsonrpc\":\"2.0\"},\"json_path\":\"result\",\"value_type\":\"string\"}}]}],\"max_price_deviation_percent\":10.0}"
}' \
prepaid-gas '300.0 Tgas' \
attached-deposit '0.1 NEAR' \
sign-as your-account.testnet \
network-config testnet \
sign-with-keychain sendUse Cases:
- Cross-Chain Bridges: Verify Ethereum transactions on NEAR
- DeFi Integration: Monitor Ethereum token balances from NEAR contracts
- Multi-Chain Wallets: Display ETH balances in NEAR apps
- Smart Contract State: Read Ethereum contract data (ERC20, NFTs)
- Block Explorer: Query Ethereum transaction history
Notes:
- Same codebase as
oracle-example, different secrets configuration - Requires Alchemy API key (free tier: 300M compute units/month)
- Supports any Ethereum JSON-RPC method (eth_call, eth_getTransactionReceipt, etc.)
- Pre-configured secrets available on testnet:
zavodil2.testnet - Mainnet secrets:
zavodil.near
Technical Details:
- WASI Version: Preview 2 (component model)
- Language: Rust
- HTTP Client:
reqwestwith WASI sockets - Secrets: Required (
ALCHEMY_API_KEY) - Network: Required (outbound HTTPS to Alchemy/Infura)
- Build:
cargo component build --release - Size: ~3.5MB compiled WASM
eth-proof-exampleWASI P2Advanced#
Bring an Ethereum value onto NEAR with a cryptographic receipt. The module reads a Chainlink price straight out of Ethereum contract storage together with its Merkle-Patricia proof, and re-derives the hashes inside the TEE until they meet the block's state root. A value that arrives this way cannot have been altered on the way — not by the node that served it, not by anyone.
Use Cases:
- Cross-chain price feeds where a wrong number costs real money (lending, liquidations, perps)
- Bridging any Ethereum contract state to NEAR — balances, ownership, governance results
- Auditable oracles: every answer ships the block hash it came from
- Reading an L1 value without running your own Ethereum node
Key Features:
- Reads storage via
eth_getProof(EIP-1186) and verifies the trie walk in-enclave - Two nested proofs per value: the account in the state trie, then the slot in that account's storage trie
- The state root is agreed by several independent RPC providers before anything is checked against it
- Disagreement is a hard failure with who-said-what, never a silent fallback
- Follows the Chainlink proxy to its current aggregator with a proof, so a feed upgrade cannot freeze the price
- No secrets and no API keys — every endpoint is public
How It Works
- Pin a block a few behind the head, so honest nodes have converged on it
- Ask several RPCs for that exact block and keep the header they all return
- Prove which aggregator the feed points at, then the latest round, then that round's answer
- Walk each proof: every node must hash to the value its parent published, down to the leaf
- Return the price together with the block hash, so anyone can re-check it later
Input Format:
{
"proxy": "0x5f4eC3Df9cbd43714FE2740f5E3616155c5b8419",
"pair": "ETH/USD"
}The feed address from Chainlink's own docs. Everything else has sane defaults.
Output Format:
{
"pair": "ETH/USD",
"price": 1833.50773289,
"verified": {
"summary": "ETH/USD = 1833.50773289 is the value Chainlink had stored on
Ethereum at block 25661863. Read out of the contract's storage
with a Merkle proof and re-checked here, so no node in the path
could have altered it.",
"storage_proofs": 3,
"trie_nodes_checked": 40,
"rpcs_agreeing": "3 of 3",
"explorer": "https://etherscan.io/block/25661863",
"not_proven": "That this is the right price. Chainlink published it; the
proof shows it was delivered unaltered, not that it is accurate."
},
"updated_at": 1785609107,
"age_secs": 495,
"evidence": {
"block_hash": "0x91c86cb04cc2a2c6017b57553e10d72535b5c7a76f5f79887f4f771f64347da6",
"state_root": "0x0262cc93a28916ad7b440af278cfdbac77ed8dcedd3902a95e77c33775ae1077",
"storage_hash": "0x932006b08c2f45306c06b7e1c230869dc800e3ee7c9f090635a0d41e11f88d91",
"aggregator": "0x7d4e742018fb52e48b08be73d041c18b21de6fb5",
"phase_id": 7,
"round_id": 32113,
"transmission_slot": "0x7336674795583596f42aea4a5e2272fac73d81c3ea39393d121041b0f03ae74a",
"agreed_by": ["ethereum-rpc.publicnode.com", "eth.drpc.org", "rpc.mevblocker.io"],
"rejected": []
}
}What to look at: trie_nodes_checked is how many hashes had to line up; rpcs_agreeing is how much independent backing the state root has; block_hash is the receipt — paste it into any explorer.
Technical Details:
- WASI Version: Preview 2 (
wasm32-wasip2), outbound HTTP - Dependencies:
tiny-keccakandrlponly — the trie walk is ~150 lines, no EVM library - Calls: N+3 sequential round trips to Ethereum; latency dominates, the hashing is negligible
- Storage layout: derived empirically against the live aggregator and pinned by unit tests, since Chainlink does not document it
Important Security Notes
- What is proven: the value really is in Ethereum's state under the agreed block. Tampering anywhere in the delivery path breaks the hash chain.
- What is not: that the price is correct. A proof will faithfully prove a bad Chainlink number — establishing that the oracle committee vouched for it means verifying their report signatures.
- The remaining trust: the state root rests on independent providers agreeing. Pick endpoints run by different operators; the strong version is a beacon-chain light client.
- Freshness: a proven price can still be stale. The module rejects anything older than
max_age_secs(default 2h) and always reportsage_secs.
Learn More
- EIP-1186 — the
eth_getProofspecification - Chainlink feed addresses — the proxy address to pass as
proxy
botfather-exampleWASI P2Host FunctionsAdvanced#
Account factory pattern for NEAR - create and manage multiple NEAR accounts with AI-generated names using hierarchical key derivation. Demonstrates advanced host function usage with call() and transfer(), providing access to private NEAR RPC endpoints (powered by Fastnear).
Use Cases:
- Account Factory: Generate multiple NEAR accounts programmatically
- Batch Operations: Execute contract calls on multiple accounts simultaneously (e.g., buy tokens, delegate to staking pool)
- Onboarding Platform: Create named accounts for users via Telegram bots or web apps
- Sub-Account Management: Manage hierarchical account structures with deterministic key derivation
Key Features:
- AI-powered account name generation (GPT integration)
- Deterministic key derivation from master seed using SHA-256
- Account discovery via Fastnear API
- Batch contract calls with template variables (
{{account_id}}) - Fund distribution across multiple accounts
- Uses
near:rpc/[email protected]host functions:call(),transfer()
Actions:
1. Create Accounts:
{
"action": "create_accounts",
"prompt": "space exploration theme",
"count": 3,
"deposit_per_account": "1000000000000000000000000"
}Creates accounts like mars-rover.testnet, moon-base.testnet
2. Fund Accounts:
{
"action": "fund_accounts",
"total_amount": "30000000000000000000000000",
"indices": []
}Empty indices = fund all accounts equally (30 NEAR ÷ 3 accounts = 10 NEAR each)
3. Batch Contract Calls:
{
"action": "batch_call",
"contract_id": "token.near",
"method_name": "transfer",
"args": {"receiver_id": "{{account_id}}", "amount": "1000"},
"deposit": "1",
"gas": "30000000000000",
"indices": [0, 2]
}Execute on accounts at indices 0 and 2. Use {{account_id}} placeholder for dynamic account ID
4. List Accounts:
{
"action": "list_accounts"
}Returns all created accounts with balances and public keys
Output Example:
{
"success": true,
"accounts": [
{
"index": 0,
"account_id": "mars_rover.testnet",
"public_key": "ed25519:...",
"balance": "1000000000000000000000000",
"balance_near": "1.0000"
}
],
"transactions": [
{
"account_id": "mars_rover.testnet",
"tx_hash": "Abc123...",
"success": true
}
]
}How It Works
- Key Derivation in TEE: Derivation key (
PROTECTED_MASTER_KEY) is generated inside TEE (nobody ever sees it). Derived keys are created using SHA-256:SHA256(derivation_key + sender_id + index)- each derived key controls one account - Account Discovery: Queries Fastnear API to find existing accounts by derived public keys (stateless operation)
- AI Name Generation: Calls OpenAI API to generate creative account names based on theme prompt
- Account Creation: Uses NEAR RPC
call()host function to create accounts viacreate_accountaction - Batch Execution: Iterates through account indices and executes operations using
call()ortransfer()
Setting Up Secrets
This example is not available in Playground because it requires creating a secret with NEAR_SENDER_PRIVATE_KEY - your NEAR account's private key (with NEAR tokens) to pay for account creation and funding.
To use this example, create a secret in the Secrets page with the following configuration:
Manual Secrets:
{
"NEAR_SENDER_PRIVATE_KEY": "ed25519:your_private_key",
"OPENAI_API_KEY": "sk-...",
"OPENAI_ENDPOINT": "https://api.openai.com/v1/chat/completions",
"OPENAI_MODEL": "gpt-3.5-turbo"
}Generated Secret (created in TEE):
- Click "Generate Secret" button
- Secret name:
PROTECTED_MASTER_KEY - Type:
ED25519(generates ed25519 key pair in TEE) - This key is created inside TEE and never exposed - used to derive all account keys
Access Control:
Set Whitelist with your account ID (the one that will manage created accounts)
Technical Details:
- WASI Version: Preview 2 (component model)
- Language: Rust
- WIT Interface:
near:rpc/[email protected](call, transfer, view) - Secrets: Required (
NEAR_SENDER_PRIVATE_KEY,OPENAI_API_KEY,PROTECTED_MASTER_KEY) - Network: Required (Fastnear API, OpenAI API, NEAR RPC via host functions)
Important Security Notes
- WASM provides signer: User's NEAR private key is passed via secrets (not worker's key)
- Keys created in TEE: Derivation key (
PROTECTED_MASTER_KEY) is generated inside TEE and never leaves it. Derived keys are created using deterministic SHA-256 derivation from derivation key. - Accounts managed only in TEE: All derived accounts are controlled exclusively by keys that exist only inside TEE - nobody can export or see the private keys
- Deterministic keys: Same derivation key + sender + index always generates same account key
- Derivation key isolation: Each
NEAR_SENDER_IDhas isolated account space - Store derivation key safely: Loss of derivation key = loss of access to all derived accounts
intents-exampleWASI P2Advanced#
DEX token swaps via NEAR Intents protocol. User's FT transfer transaction pauses, WASI performs swap off-chain, then resolves by sending swapped tokens back - all within single transaction.
Key Features:
- FT transfer pauses during off-chain swap execution
- NEAR Intents API integration (quote → publish → settle)
- NEP-413 message signing with ed25519
- Automatic token withdrawal to user upon completion
- Private key management via encrypted secrets
- Storage deposit handling for fungible tokens
Transaction Flow:
- User calls
ft_transfer_callto swap contract - Contract receives tokens and calls OutLayer
- Transaction pauses - contract enters yield state
- WASI worker performs swap via NEAR Intents API
- Worker withdraws swapped tokens to user
- Transaction resumes - contract completes with callback
How to Use:
# 1. Create operator account on NEAR mainnet
near create-account operator.near --useFaucet
# 2. Store operator private key as encrypted secret
# Open https://app.outlayer.ai/secrets:
# - Secrets JSON: {"OPERATOR_PRIVATE_KEY":"ed25519:..."}
# 3. Clone and deploy swap contract
git clone https://github.com/out-layer/intents-example.git
cd intents-example/contract
cargo near build
near deploy swap-contract.near res/swap_contract.wasm
# 4. Initialize contract
near call swap-contract.near new '{
"operator_account_id": "operator.near"
}' --accountId swap-contract.near
# 5. User swaps 1 WNEAR for USDC
near call wrap.near ft_transfer_call '{
"receiver_id": "swap-contract.near",
"amount": "1000000000000000000000000",
"msg": "{\"Swap\":{\"token_out\":\"usdc.token\",\"min_amount_out\":\"900000\"}}"
}' --accountId user.near --depositYocto 1 --gas 300000000000000
# Transaction will:
# - Pause after receiving WNEAR
# - Execute swap off-chain via NEAR Intents
# - Resume and send swapped USDC to userNote: NEAR Intents works on mainnet only. For testnet testing, use mock swap implementation.
Technical Details:
- WASI Version: Preview 2 (component model)
- Language: Rust
- HTTP Client:
reqwestfor NEAR Intents API - Secrets: Required (
OPERATOR_PRIVATE_KEY) - Network: Required (NEAR Intents API, mainnet only)
- Signing: NEP-413 message signing with ed25519
- Build:
cargo component build --release - Size: ~3.8MB compiled WASM
private-dao-exampleWASI P1Advanced#
Anonymous, verifiable DAO voting with cryptographic privacy. Heavy cryptography (ECIES encryption, HKDF key derivation, merkle tree proofs) executed off-chain in TEE. Each user's vote is encrypted on-chain, tallying happens in secure enclave, only aggregate counts are revealed.
Privacy Guarantees:
- Individual votes remain secret - only aggregate counts revealed
- DAO members can send encrypted noise instead of real votes to hide voting activity from observers
- Merkle proofs allow voters to verify their vote was counted without revealing how they voted
Key Features:
- ECIES encryption for private votes (secp256k1)
- HKDF-SHA256 deterministic key derivation from single master secret
- Merkle tree construction for vote inclusion proofs
- Dummy messages: Send encrypted noise to hide whether you voted (indistinguishable from real votes on-chain)
- Vote changes: Vote multiple times, timestamp-based deduplication (latest vote wins)
- TEE attestation for execution integrity
- Full-stack React frontend with NEAR Wallet integration
Architecture:
1. Generate master secret:
OutLayer → TEE generates random master secret (stored encrypted)
2. User joins DAO:
Contract → OutLayer → TEE derives pubkey from master secret
3. User votes:
Frontend encrypts vote with pubkey → Contract stores encrypted vote
4. Finalize proposal:
Contract → OutLayer → TEE decrypts votes + tallies + builds merkle tree
Returns aggregate counts + merkle proofs (individual votes never exposed)
5. Verify vote:
User computes vote hash → Verifies merkle proof against root
Privacy Features:
- Individual votes never revealed (only aggregate counts)
- Dummy messages: Send encrypted noise to hide voting activity
- Vote changes: Vote multiple times, only latest counts (timestamped)
- Merkle proofs: Verify inclusion without revealing vote content
Cost: Heavy cryptography off-chain = ~$0.001 per voteCryptographic Components:
// Single master secret → unique key per user
let info = format!("user:{}:{}", dao_account, user_account);
let user_privkey = hkdf_sha256(&master_secret, info.as_bytes());
let user_pubkey = secp256k1::derive_public_key(&user_privkey);import { encrypt } from 'eciesjs';
const vote = "yes"; // or "no"
const pubkeyHex = await contract.get_user_pubkey({ user });
const encrypted = encrypt(pubkeyHex, Buffer.from(vote));
await contract.cast_vote({ proposal_id, encrypted_vote: encrypted.toString('hex') });// Must preserve u64 precision - use BigInt!
const timestamp = result.receipts_outcome[0].outcome.status.SuccessValue;
const timestampStr = atob(timestamp).trim(); // Keep as string
const timestampBigInt = BigInt(timestampStr);
// Convert to 8-byte little-endian
const buffer = new ArrayBuffer(8);
new DataView(buffer).setBigUint64(0, timestampBigInt, true);
// SHA256(user + timestamp_le + encrypted)
const combined = concat(
textEncoder.encode(accountId),
new Uint8Array(buffer),
textEncoder.encode(encrypted)
);
const voteHash = hex(await crypto.subtle.digest('SHA-256', combined));// Try all possible paths (2^depth combinations)
async function verifyProof(voteHash, proofPath, merkleRoot) {
async function tryPaths(hash, remaining) {
if (!remaining.length) return hash === merkleRoot;
const [sibling, ...rest] = remaining;
// Try both orderings
if (await tryPaths(await sha256(hash + sibling), rest)) return true;
if (await tryPaths(await sha256(sibling + hash), rest)) return true;
return false;
}
return await tryPaths(voteHash, proofPath);
}How to Deploy:
# 1. Generate DAO master secret in TEE
# (Alternatively: generate locally and store encrypted)
openssl rand -hex 32 > dao_master_secret.txt
# 2. Store master secret via Dashboard (encrypted in keystore)
# Open https://app.outlayer.ai/secrets:
# - Repo: github.com/YOUR_USERNAME/private-dao-example
# - Profile: production
# - Secrets JSON: {"DAO_MASTER_SECRET":"<paste hex from file>"}
# - Access: AllowAll (or Whitelist for DAO admin only)
# 3. Clone and build WASI module
git clone https://github.com/out-layer/private-dao-example.git
cd private-dao-example
cargo build --target wasm32-wasip1 --release
git push origin main
# 4. Deploy DAO contract
cd dao-contract
cargo near build
near deploy privatedao.testnet \
use-file res/private_dao_contract.wasm \
with-init-call new \
json-args '{
"owner_id":"owner.testnet",
"name":"My Private DAO",
"outlayer_contract":"outlayer.testnet",
"wasi_repo":"https://github.com/YOUR_USERNAME/private-dao-example",
"wasi_commit":"main",
"secrets_profile":"production",
"secrets_owner":"your.testnet",
"membership_mode":"Public"
}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0 NEAR'
# 5. Deploy frontend
cd ../dao-frontend
npm install
cat > .env <<EOF
REACT_APP_CONTRACT_ID=privatedao.testnet
REACT_APP_NEAR_NETWORK=testnet
EOF
npm run build
# Deploy build/ to Vercel/Netlify/Cloudflare Pages
# 6. Users can now:
# - Join DAO (get encrypted pubkey derived from master secret)
# - Create proposals with quorum requirements
# - Vote privately (votes encrypted with their pubkey)
# - Finalize proposals (OutLayer decrypts in TEE and tallies)
# - Verify their vote was counted (merkle proof verification)Use Cases:
- Anonymous Governance: Board elections where individual votes should remain secret
- Whistleblower Protection: Report issues without revealing identity
- Salary Decisions: Vote on compensation without peer pressure
- Grant Allocation: Fund projects while preventing vote buying
- Conflict Resolution: Vote on sensitive matters privately
Technical Highlights:
Heavy cryptography off-chain: ~$0.001/vote
ECIES + HKDF + Merkle trees feasible with OutLayer
Encrypted votes on-chain
Dummy messages hide voting activity
Vote changes allowed (latest wins)
Decryption in secure enclave
Merkle proofs: Voters verify inclusion
TEE attestation: Verify execution integrity
Master secret in TEE → unlimited users
No storage overhead for keys
Important Security Notes
- Master secret must be highly secured (hardware wallet, multi-sig, etc.)
- TEE attestation uses Intel TDX via Phala Network
- Frontend must correctly compute vote hash (BigInt for u64 precision!)
- Vote hash saved by user is CRITICAL for later verification
Technical Details:
- WASI Version: Preview 1 (
wasm32-wasip1) - Language: Rust
- Cryptography: ECIES (secp256k1), HKDF-SHA256, Merkle trees
- Secrets: Required (
DAO_MASTER_SECRET) - Frontend: React with NEAR Wallet integration
- Build:
cargo build --target wasm32-wasip1 --release - Size: ~1.2MB compiled WASM
captcha-exampleWASI P2Full Stack#
Token sale with mandatory CAPTCHA verification. Transaction won't complete until user solves CAPTCHA. WASI worker receives session ID from backend and waits for verification signal. Example implementation demonstrating async human verification pattern.
Key Features:
- Transaction blocking until CAPTCHA solved
- WASI worker requests CAPTCHA challenge from backend
- Backend sends CAPTCHA to user via WebSocket
- Worker waits for verification signal (long-polling)
- hCaptcha integration for human verification
- React frontend with NEAR Wallet Selector
- Node.js backend with Express + WebSocket server
Architecture:
User Browser → Token Sale Contract → OutLayer → WASI Worker
↑ ↓
└────── Launchpad Backend (WebSocket) ←────────┘
Flow:
1. User clicks "Buy Tokens" with session_id
2. Contract calls OutLayer, transaction pauses
3. WASI worker → backend: "I received payment from session_id X.
Verify this is a real user, not a bot. Send CAPTCHA and notify
me when user completes it."
4. Backend sends CAPTCHA to user's browser via WebSocket
5. User solves CAPTCHA in modal
6. Backend verifies solution and marks session as verified
7. Worker receives "verified" signal, returns success to contract
8. Transaction resumes - user receives tokensComponents:
- WASI Worker: Rust WASM that verifies CAPTCHA (wasm32-wasip2)
- Smart Contract: Token sale logic with OutLayer integration
- Backend: Node.js Express server with WebSocket support
- Frontend: React app with hCaptcha widget
How to Use:
# 1. Get hCaptcha account (free at hcaptcha.com)
# - Create site and get Site Key + Secret Key
# 2. Clone repository
git clone https://github.com/out-layer/captcha-example.git
cd captcha-example
# 3. Setup backend
cd launchpad-backend
npm install
cat > .env <<EOF
PORT=3181
HCAPTCHA_SITE_KEY=your_site_key
HCAPTCHA_SECRET=your_secret_key
WORKER_API_KEY=$(openssl rand -hex 32)
EOF
npm start
# 4. Setup frontend
cd ../launchpad-app
npm install
cat > .env <<EOF
REACT_APP_CONTRACT_ID=tokensale.testnet
REACT_APP_NEAR_NETWORK=testnet
REACT_APP_HCAPTCHA_SITE_KEY=your_site_key
EOF
npm run build
# Deploy build/ to your web server
# 5. Build WASI worker
cd ../captcha-example
cargo build --target wasm32-wasip2 --release
git push origin main
# 6. Deploy token sale contract
cd ../token-sale-contract
cargo near build
near deploy tokensale.testnet \
use-file res/token_sale_contract.wasm \
with-init-call new \
json-args '{"owner":"owner.testnet","total_supply":"10000","launchpad_url":"https://api.yourdomain.com"}' \
prepaid-gas '100.0 Tgas' \
attached-deposit '0 NEAR'
# 7. Users can now buy tokens - CAPTCHA required!
# Visit https://launchpad.yourdomain.com and click "Buy Tokens"Production Setup: Requires SSL certificates for both frontend and backend domains. See CONFIGURATION.md for complete deployment guide.
Important Security Notes
- Backend must implement worker authentication to prevent spam attacks
- Unauthorized requests to create CAPTCHA challenges should be rejected
- Use HTTPS for both frontend and backend in production
- Implement rate limiting on CAPTCHA challenge creation
Technical Details:
- WASI Version: Preview 2 (component model)
- Language: Rust (WASM), TypeScript (Frontend/Backend)
- HTTP Client:
reqwestfor backend communication - Backend: Node.js + Express + WebSocket
- Frontend: React with NEAR Wallet Selector
- CAPTCHA: hCaptcha integration
- Build:
cargo component build --release - Size: ~2.8MB compiled WASM
near-emailWASI P2ProductionFull Stack#
Blockchain-native email for NEAR accounts. Every NEAR account automatically has an email address: alice.near becomes [email protected]. Emails are encrypted on receipt and can only be decrypted inside the OutLayer TEE by the wallet owner.
Live at: near.email — A full production application demonstrating OutLayer's TEE capabilities, persistent storage, key derivation, and both blockchain and HTTPS API modes.
Key Features:
- Wallet-based identity: your NEAR account = your email
- End-to-end encryption: ECIES with secp256k1, emails encrypted before storage
- TEE-protected: Intel TDX ensures operators cannot read emails
- BIP32-style key derivation from master keypair in TEE
- Supports both blockchain mode and Payment Key HTTPS mode
- External email compatibility (Gmail, Outlook, etc.)
- Up to 18 MB attachments in Payment Key mode
How It Works
- External email arrives via SMTP (port 25) to smtp-server
- SMTP server derives recipient's public key from master public key (no secret needed)
- Email encrypted with ECIES and stored in PostgreSQL
- User connects wallet on web UI and signs authentication message
- OutLayer WASI module (running in TEE) derives private key from master secret
- Module decrypts emails and returns them to the user
- Master private key never leaves TEE memory
Architecture
External World (Gmail, etc.)
│ SMTP (port 25)
▼
┌─────────────────────────────────┐
│ smtp-server (Rust) │
│ Derives public key, encrypts │
│ email, stores encrypted blob │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ PostgreSQL │
│ Encrypted emails only │
└─────────────────────────────────┘
│ HTTP API
▼
┌─────────────────────────────────┐
│ OutLayer TEE (WASI module) │
│ Verifies NEAR signature │
│ Derives private key │
│ Decrypts emails for owner │
└─────────────────────────────────┘
│
▼
┌─────────────────────────────────┐
│ web-ui (Next.js) │
│ Connect wallet, view inbox │
└─────────────────────────────────┘Key Derivation (BIP32-style)
The critical feature: the SMTP server can derive per-user public keys without knowing the master secret.
Public Key Derivation (SMTP server, no secret needed):
user_pubkey = master_pubkey + SHA256("near-email:v1:" + account_id) * G
Private Key Derivation (OutLayer TEE, requires master secret):
user_privkey = master_privkey + SHA256("near-email:v1:" + account_id)Dual-Mode Integration
near.email demonstrates how one app can seamlessly use both integration modes:
Blockchain Mode
- User signs with NEAR wallet
- 1.5 MB max output
- Calls
request_execution()on-chain - No payment key needed
Payment Key Mode
- No wallet popup required
- 25 MB max output (18 MB attachments)
- Direct HTTPS call to OutLayer API
- Prepaid with USDC/USDT or NEAR
The UI automatically routes through the correct mode based on a toggle in account settings. This pattern shows how OutLayer changes what apps can do — a single WASI module serves both blockchain and Web2 users transparently.
Important Security Notes
- Server compromise: Emails are encrypted, server only has public key
- Master key leak: Key stored only in OutLayer TEE (hardware-enforced)
- NEAR-to-NEAR emails never touch external SMTP servers
- TEE attestation proves correct decryption code is running
Use Cases:
- Secure communication for NEAR ecosystem
- Notification system for DeFi positions and DAO proposals
- Privacy-preserving email without trusting a provider
- Template for building TEE-secured communication apps
Technical Details:
- WASI Version: Preview 2 (
wasm32-wasip2) - Language: Rust
- Encryption: ECIES (secp256k1) + AES-GCM
- Key Derivation: BIP32-style from master keypair
- TEE: Intel TDX via Phala Cloud
- Components: smtp-server, db-api, wasi-near-email-ark, web-ui
- Modes: Blockchain (wallet signature) + HTTPS (Payment Key)
eas-attestorWASI P2ProductionBase + EVM#
One-click TEE attestations for the Ethereum Attestation Service. A generic engine that reads on-chain data through an RPC quorum, signs an EAS attestation inside an Intel TDX enclave, and publishes it on Base (or any supported EVM chain) — with a link to its own hardware proof embedded in the attestation itself.
Live at: eas.outlayer.ai — pick a preset, get a key generated inside the enclave, send its address a dollar of gas, attest. No servers, no key management, no infrastructure.
Why this matters
An attestation is only as trustworthy as its attester. Normally the attester is a plain EOA — readers trust whoever operates the server that holds the key. This attester is different in three ways:
- The signing key was generated inside the enclave and has never existed anywhere else — no human has ever seen it
- The only code that can use it is pinned by hash to a public GitHub repo, approved on-chain
- Every attestation links to the Intel-signed quote of the exact run that produced it — the evidence travels with the claim
How It Works
- The web form composes a job: an EAS schema plus data collectors (ERC-20 supply, balance, contract bytecode, block number, a link to the run's own TEE quote)
- OutLayer compiles the pinned GitHub repo to WASI and executes it inside Intel TDX
- The enclave decrypts the attester key — a generated secret that only attested code can access
- The guest reads every value from multiple RPC endpoints and requires min_agree of them to match
- It ABI-encodes the attestation data, signs the EAS attest() transaction in-guest (k256), and broadcasts it
- The platform seals sha256(input), sha256(output) and the WASM hash into an Intel-signed TDX quote
- The attestation's teeAttestation field links back to that quote — anyone on EAS can follow it
Run it from a terminal
The web form is just one driver — the engine is three HTTPS calls, and the form's How to run it box generates these exact commands prefilled with your values. You need a payment key; the signing key is created once on the secrets page (the form links you there with everything prefilled).
1. Dry run — no signing key, just a payment key
curl -s -X POST https://api.outlayer.ai/call/zavodil.near/eas-attestor \
-H 'Content-Type: application/json' \
-H 'X-Payment-Key: YOUR_PAYMENT_KEY' \
-d '{
"async": true,
"input": {
"mode": "dry_run",
"chain": { "network": "base" },
"schema": { "definition": "uint256 totalSupply,uint64 blockNumber,string teeAttestation" },
"collect": [
{ "type": "erc20_total_supply", "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },
{ "type": "block_number" },
{ "type": "tee_attestation", "returns": "url", "api_base": "https://app.outlayer.ai" }
],
"min_agree": 2
}
}'2. Register the schema — one-time, signed inside the enclave
curl -s -X POST https://api.outlayer.ai/call/zavodil.near/eas-attestor \
-H 'Content-Type: application/json' \
-H 'X-Payment-Key: YOUR_PAYMENT_KEY' \
-d '{
"async": true,
"secrets_ref": { "profile": "eas", "account_id": "you.near" },
"input": {
"mode": "register_schema",
"chain": { "network": "base" },
"key_env": "PROTECTED_EAS_KEY",
"schema": {
"definition": "uint256 totalSupply,uint64 blockNumber,string teeAttestation",
"resolver": "0x0",
"revocable": true
}
}
}'
# → returns predicted_schema_uid — use it as schema.uid below3. Attest — publish on-chain
curl -s -X POST https://api.outlayer.ai/call/zavodil.near/eas-attestor \
-H 'Content-Type: application/json' \
-H 'X-Payment-Key: YOUR_PAYMENT_KEY' \
-d '{
"async": true,
"secrets_ref": { "profile": "eas", "account_id": "you.near" },
"input": {
"mode": "attest",
"chain": { "network": "base" },
"key_env": "PROTECTED_EAS_KEY",
"schema": {
"uid": "0x<schema UID from step 2>",
"definition": "uint256 totalSupply,uint64 blockNumber,string teeAttestation"
},
"collect": [
{ "type": "erc20_total_supply", "token": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913" },
{ "type": "block_number" },
{ "type": "tee_attestation", "returns": "url", "api_base": "https://app.outlayer.ai" }
],
"min_agree": 2
}
}'Poll for the result
# every call above returns { "call_id": "..." } immediately; poll it:
curl -s https://api.outlayer.ai/calls/CALL_ID \
-H 'X-Payment-Key: YOUR_PAYMENT_KEY'
# → status, the job's full output, and attestation_url — the TEE quote for this exact run
# the key is required here on purpose: the OUTPUT is private to whoever paid for the run.
# the public record is the attestation (hashes only) — no key needed:
curl -s https://api.outlayer.ai/attestations/by-call/CALL_IDRun the engine locally (wasmtime) — for development, not attestations
# No TEE and no key here, so nothing gets signed or attested. What this IS for: # - iterate on your schema and collectors for free, before paying for enclave runs # - audit the engine: it is the exact binary the enclave compiles from this repo, # so you can see what it does with your input — quorum reads, ABI encoding, calldata # - develop your own fork (new collector types, other contracts) with a fast loop git clone https://github.com/out-layer/eas-attestor && cd eas-attestor ./build.sh cat example-job.json | wasmtime -S http target/wasm32-wasip2/release/eas-attestor.wasm # when the dry_run output looks right, send the SAME job JSON through the API above
Key custody — the design decision
The attester key is a generated secret (PROTECTED_EAS_KEY): the enclave keystore creates it, so the browser, the operator and OutLayer itself never see the private half. A dry run reveals only the derived address — you fund that address with gas, and the key can attest. The private key has never existed outside TEE memory, which is a stronger statement than any key-management policy.
The project (zavodil.near/eas-attestor) is shared: anyone binds their own key to it and gets their own attester identity on the same audited code. The platform decrypts a key only for the exact WASM whose hash is approved on-chain — the same pattern NEAR Email uses for user mailbox keys.
A real mainnet run — verify it yourself
The full lifecycle on Base mainnet, as one-click verification links. Each link carries the run's input and output in the URL; the attestation page re-hashes them in your browser and compares against the enclave-sealed values — nothing is taken on trust:
- 1. Dry run — collects the data and encodes the attestation without broadcasting
- 2. Schema registration — registers the EAS schema, signed inside the enclave
- 3. Attestation — USDC total supply on Base, published on-chain
- 4. The result on EAS — note the
teeAttestationfield pointing back at its own proof
Key Features:
- Attester key born inside the TEE — generated secret, never seen by anyone
- Every read requires an N-of-M RPC quorum (min_agree) — no single RPC provider is trusted
- Self-referencing: each attestation embeds the URL of its own Intel-signed quote
- Schema-driven: any field layout, registered and predicted (UID) by the engine
- Cross-chain reads: attest on Base about state on Ethereum (proof-of-reserves pattern)
- One-click verification links — input and output travel in the URL, checks run in the reader's browser
- Zero infrastructure: pay per call with a payment key, or copy the job JSON and run it from a terminal
Important Security Notes
- Key exfiltration: impossible by construction — the key is decrypted only for on-chain-approved code inside the enclave
- RPC manipulation: a wrong value requires min_agree independent endpoints to collude
- Operator (us): cannot alter results — the WASM hash and input/output hashes are sealed in the Intel-signed quote; verify with outlayer-verify, no trust in our pages required
- Code swap: each execution records the exact repo and commit it ran
Use Cases:
- Proof-of-reserves: locked collateral on Ethereum vs minted supply on Base, in one attestation
- Token supply and balance snapshots as attested public records
- Contract bytecode attestations — is the deployed code the audited code?
- Any oracle-style claim where readers should not have to trust the operator
- Template for TEE-signed EVM transactions of any kind — the quorum-read + in-guest signing core is reusable
Technical Details:
- WASI Version: Preview 2 (
wasm32-wasip2) - Language: Rust, minimal dependencies (hand-rolled ABI encoding and keccak, k256 for signing)
- Transactions: EIP-1559, signed entirely in-guest
- Chains: Base, Base Sepolia, Optimism, Arbitrum, Ethereum, Sepolia
- Key:
PROTECTED_EAS_KEY— enclave-generated secret, bound to the shared project - Collectors: erc20_total_supply, erc20_balance, eth_code, block_number, tee_attestation
- Modes: dry_run / register_schema / attest over the HTTPS API