The standalone Signal Lab project is in external/multichain-agents. It has
its own package, WASM program, UI and contracts. It imports no Gora core code,
reads no core database and never receives an operator/provider credential.Its independent program/UI was published through the public deployment API:
open Signal Lab
or download its public source.
Source downloads exclude credentials, keypairs and private signing journals.
The public example is v0.1.4. Independent Base/Solana paid AI, confirmed score
writes, signer revocation and exact recovery have passed on the managed
testnet. Native-wallet acceptance is still being completed; publication alone
does not establish every launch gate.Its AI program returns {score, reason}. Each agent records scores in its own
Base mapping entry or Solana PDA. This is a general app workflow, not a trading endpoint.
Managed Base/Solana signing must be explicitly enabled. Check live signer,
delivery and recovery acceptance before funding an agent. A 503 means the
service is not enabled; working validator staking does not prove app signing.
Copy/fork the separate example and choose a globally unique app ID. Update the
manifest and policy IDs, then build:
npm ciexport CARGO=/absolute/path/to/cargonpm run build:wasmVITE_APP_ID=your_app_id npm run build
The public runtime executes WASM, not unsandboxed JavaScript/Python. Your static
frontend can use any JavaScript framework. Large images/videos can remain on HTTPS CDNs.
Base Sepolia (84532): deploy contracts/base/Scoreboard.sol.
recordScore(uint256) updates the score for msg.sender and emits an event.
Solana devnet: build/deploy contracts/solana. A record PDA derives from
["score", agent_public_key] and stores score/update count. The agent pays
its own PDA rent on the first update.
These are application contracts, not staking contracts. Keep deployment keys
in your protected environment and record public addresses/receipts.
gora deploy does not deploy chain contracts.
gora config set node.url https://gora-bridge.74.241.248.103.nip.ioopenssl rand -hex 32 | gora config set api.token --stdingora package .gora deploy .
Generate the developer token once and retain a private backup. It owns your
deployments; it is not a browser API key. Upgrading the app does not silently
replace the executable pinned by an existing agent.Choose either UI hosting model:
Gora-hosted: package ui.dir, then open the returned ui_url.
Your website: publish the same static build with VITE_GORA_API set to
the public bridge URL and VITE_APP_ID set to your app ID.
Explore curation is separate from deployment permission. Unlisted apps remain
in the registry and accessible by direct URL/app ID. Unlisting does not delete
their execution, schedules, histories or recovery paths.
The example supports injected Base/Solana browser wallets. Its client requests
/auth/challenge, verifies the exact audience/app/wallet/permissions, asks the
wallet to sign, and exchanges it at /auth/session. The short-lived token
stays in memory and is scoped to one app.Inside Gora, use window.Gora.instance(...) and the current
window.Gora.agentSigner(...) helper. Keys and policy-approval signatures
stay in native code. A normal app session does not authorize spending.
import { GoraClient } from './src/client.mjs';const client = new GoraClient({ api: 'https://gora-bridge.74.241.248.103.nip.io', appId: 'your_app_id', chain: 'base' // or 'solana'});// Browser: connect({address, signMessage}) using your wallet adapter.// Native Gora: connect() uses the native wallet bridge.
const { instance } = await client.instance('create', null, { nonce: 'researcher-001', // stable on retries name: 'Product researcher', config: { chain: 'base', instructions: 'Score evidence of customer demand; explain uncertainty.' }});console.log(instance.did);// Purchase prepaid test GORA AI calls for this instance before invoking.// See the invoice/sign/confirm flow in "Structured AI calls and testnet credits".const result = await client.invoke( instance, 'Five customers requested exportable reports.', false, // AI/state only 'researcher-001-observation-001' // reuse after HTTP uncertainty);
Each instance has its own configuration, state namespace, owner, executable
version and DID. Do not put secrets in configuration/prompts. See
identity and permissions.AI starts at zero paid calls. Follow testnet GORA payment
before the first invocation. Buying ordinary execution credits or funding the
agent’s ETH/SOL wallet does not pay its AI bill.
Review the separate custody approval: app, executable, DID, chain, targets,
argument ranges, expiry, fee ceiling and transaction count. Funding is another
user-signed transaction to the returned agent address; signer creation
does not move funds. Use only test ETH/devnet SOL; Solana also needs PDA rent.Invoke with record_on_chain: true. The WASM result proposes a template and
arguments, validators attest execution, and the managed signer checks its
policy before signing and delivering the transaction.
7. Verify execution, delivery and recovery separately
Read the finalized request, output and receipt.
Read /v1/settlements/{request_id} using the same caller authentication.
Require confirmed, then independently read the contract/PDA and transaction
on the correct testnet. Two Base L2 confirmations are not Ethereum L1 finality.
Reuse request IDs after HTTP uncertainty. Never create a second spending
request merely because polling timed out. Signed nonce/blockhash failures are
reconciled using the original bytes, not automatically re-signed.Acceptance should cover a Base agent, a Solana agent, a second owner’s
isolation, a rejected out-of-policy call, revoke and return of test funds.
Creating 1,000 identities does not prove 1,000 concurrent AI calls or throughput.