Invoking from Solidity

This guide shows how to invoke Somnia Agents from smart contracts. Your contracts can call agents and receive responses via callbacks.

Generate Code from the Web App

The easiest way to get started is to use the code generator:

  1. Select an agent from the list

  2. Click on a method to expand it

  3. Select the "Solidity" tab to see generated code for that method

  4. Copy the generated code into your project

The generator creates a complete contract with:

  • Platform interface definitions

  • Agent method encoding

  • Callback handling

  • Proper error handling

Tip: The "TypeScript" tab generates code for invoking agents from JavaScript/TypeScript — it sends transactions to the platform contract and listens for response events.

How It Works

spinner
  1. Your contract calls createRequest() with the agent ID, encoded payload, and a deposit.

  2. The platform splits the deposit into an operations reserve (minPerAgentDeposit × subSize, funds gas refunds / callback / upkeep) and an agent reward pot (the rest). perAgentBudget = rewardPot / subSize is emitted in RequestCreated so runners know their cap.

  3. Elected validators execute the agent and submit responses; each submission is gas-refunded from the operations reserve.

  4. Once consensus is reached, the platform calls your callback, then pays every elected subcommittee member the median of the reported executionCost values via the committee.

  5. Any unused funds are rebated to the requester.

See Gas Fees for a full fund-flow diagram and details on sizing msg.value.

Platform Interface

SomniaAgents / AgentRequester Addresses:

Network
Address

Mainnet (chain ID 5031)

0x5E5205CF39E766118C01636bED000A54D93163E6

Testnet (chain ID 50312)

0x037Bb9C718F3f7fe5eCBDB0b600D607b52706776

The examples below use the testnet address; swap in the mainnet address for production.

Basic Example

Callback Function Signature

Your callback function must match this signature:

  • requestId: The ID returned from createRequest()

  • responses: Array of Response structs from validators (each contains .result bytes, .status, .validator, etc.)

  • status: The overall request status — one of Success (2), Failed (3), or TimedOut (4)

  • details: The full Request struct with metadata (subcommittee, threshold, deadline, etc.)

You can name the function anything, but the parameter types must match. The selector you pass to createRequest must match your function.

Response Status

Status
Value
Meaning

None

0

Default zero value (uninitialized storage)

Pending

1

Awaiting responses

Success

2

Validators reached consensus

Failed

3

Validators reported failure (success became impossible)

TimedOut

4

Request timed out before consensus was reached

Decoding Responses

The responses array contains Response structs from validators. Each response has a .result field with ABI-encoded bytes and a .status field. The callback receives all responses submitted up to finalization. For Majority consensus, at least threshold responses will have identical .result bytes (the consensus value). For Threshold consensus, results may differ.

Multiple Callbacks

Use different callbacks for different response types:

Error Handling

Handle all response statuses gracefully:

Security Considerations

  1. Always verify the caller: Check that msg.sender is the platform contract

  2. Track pending requests: Use a mapping to validate incoming callbacks

  3. Handle all statuses: Check status — requests can succeed, fail, or time out

  4. Validate responses length: Check responses.length before decoding

  5. Accept rebates: Implement receive() so your contract can receive rebated funds

Next Steps

Last updated