Smart Contract
InferenceOracle
A.91d0a5b7c9832a8b.InferenceOracle
1// InferenceOracle.cdc
2// The bridge between on-chain agent state and off-chain LLM inference.
3// Authorized relays listen for InferenceRequested events, call the provider,
4// and post results back via completeInference transactions.
5// Each account authorizes their own relay keys — nobody else can post to your sessions.
6
7import AgentRegistry from 0x91d0a5b7c9832a8b
8import AgentSession from 0x91d0a5b7c9832a8b
9
10access(all) contract InferenceOracle {
11
12 // -----------------------------------------------------------------------
13 // Events
14 // -----------------------------------------------------------------------
15 access(all) event RelayRegistered(relayAddress: Address, owner: Address)
16 access(all) event RelayRevoked(relayAddress: Address, owner: Address)
17 access(all) event InferenceRelayed(requestId: UInt64, relayAddress: Address)
18 access(all) event InferenceFailed(requestId: UInt64, reason: String)
19 access(all) event ToolExecutionRequested(
20 requestId: UInt64,
21 sessionId: UInt64,
22 toolName: String,
23 inputHash: String,
24 owner: Address
25 )
26 access(all) event ToolExecutionCompleted(
27 requestId: UInt64,
28 toolName: String,
29 outputHash: String
30 )
31
32 // -----------------------------------------------------------------------
33 // Paths
34 // -----------------------------------------------------------------------
35 access(all) let OracleConfigStoragePath: StoragePath
36
37 // -----------------------------------------------------------------------
38 // Entitlements
39 // -----------------------------------------------------------------------
40 access(all) entitlement ManageRelays
41 access(all) entitlement Relay
42
43 // -----------------------------------------------------------------------
44 // RelayAuthorization — proof that a relay is allowed to post for an account
45 // -----------------------------------------------------------------------
46 access(all) struct RelayAuth {
47 access(all) let relayAddress: Address
48 access(all) let authorizedAt: UFix64
49 access(all) let label: String // human-readable label
50 access(all) var isActive: Bool
51
52 init(relayAddress: Address, label: String) {
53 self.relayAddress = relayAddress
54 self.authorizedAt = getCurrentBlock().timestamp
55 self.label = label
56 self.isActive = true
57 }
58 }
59
60 // -----------------------------------------------------------------------
61 // ToolCall — represents a tool invocation from an LLM response
62 // -----------------------------------------------------------------------
63 access(all) struct ToolCall {
64 access(all) let toolCallId: String
65 access(all) let toolName: String
66 access(all) let input: String // JSON-encoded input
67 access(all) let inputHash: String
68
69 init(toolCallId: String, toolName: String, input: String, inputHash: String) {
70 self.toolCallId = toolCallId
71 self.toolName = toolName
72 self.input = input
73 self.inputHash = inputHash
74 }
75 }
76
77 // -----------------------------------------------------------------------
78 // OracleConfig — per-account relay management
79 // -----------------------------------------------------------------------
80 access(all) resource OracleConfig {
81 access(self) var authorizedRelays: {Address: RelayAuth}
82 access(self) var completedRequests: {UInt64: Bool} // dedup tracking
83
84 init() {
85 self.authorizedRelays = {}
86 self.completedRequests = {}
87 }
88
89 // --- Manage relays ---
90 access(ManageRelays) fun authorizeRelay(relayAddress: Address, label: String) {
91 self.authorizedRelays[relayAddress] = RelayAuth(
92 relayAddress: relayAddress,
93 label: label
94 )
95 emit RelayRegistered(relayAddress: relayAddress, owner: self.owner!.address)
96 }
97
98 access(ManageRelays) fun revokeRelay(relayAddress: Address) {
99 self.authorizedRelays.remove(key: relayAddress)
100 emit RelayRevoked(relayAddress: relayAddress, owner: self.owner!.address)
101 }
102
103 access(all) fun isRelayAuthorized(relayAddress: Address): Bool {
104 if let relayAuth = self.authorizedRelays[relayAddress] {
105 return relayAuth.isActive
106 }
107 return false
108 }
109
110 access(all) fun getAuthorizedRelays(): {Address: RelayAuth} {
111 return self.authorizedRelays
112 }
113
114 // --- Deduplication ---
115 access(Relay) fun markRequestCompleted(requestId: UInt64) {
116 self.completedRequests[requestId] = true
117 }
118
119 access(all) fun isRequestCompleted(requestId: UInt64): Bool {
120 return self.completedRequests[requestId] ?? false
121 }
122 }
123
124 // -----------------------------------------------------------------------
125 // Public factory
126 // -----------------------------------------------------------------------
127 access(all) fun createOracleConfig(): @OracleConfig {
128 return <- create OracleConfig()
129 }
130
131 // -----------------------------------------------------------------------
132 // Init
133 // -----------------------------------------------------------------------
134 init() {
135 self.OracleConfigStoragePath = /storage/FlowClawOracleConfig
136 }
137}
138