nebula-ai-core 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/identity/erc8004-trust.ts +248 -0
- package/src/identity/erc8004.ts +1 -0
- package/src/identity/index.ts +16 -0
- package/src/index.ts +12 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nebula-ai-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The SDK for nebula, a Mantle-native policy-aware AI treasury assistant: brain, local memory + storage, the policy/approval engine, EOA identity, and the ERC-8004 identity client",
|
|
6
6
|
"license": "MIT",
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ERC-8004 ("Trustless Agents") Reputation + Validation Registry clients.
|
|
3
|
+
*
|
|
4
|
+
* Thin viem wrappers over `NebulaReputationRegistry` (feedback/scores per agent)
|
|
5
|
+
* and `NebulaValidationRegistry` (request/respond validation), both bound to the
|
|
6
|
+
* Identity Registry. Together with erc8004.ts this is the full 3-registry
|
|
7
|
+
* ERC-8004 surface. Addresses resolve from env → baked-in deployment.
|
|
8
|
+
*/
|
|
9
|
+
import type { Address, Hex, PublicClient, WalletClient } from 'viem'
|
|
10
|
+
import type { NebulaNetwork } from '../config'
|
|
11
|
+
|
|
12
|
+
// ─── Reputation ──────────────────────────────────────────────────────────────
|
|
13
|
+
export const REPUTATION_REGISTRY_ABI = [
|
|
14
|
+
{
|
|
15
|
+
type: 'function',
|
|
16
|
+
name: 'giveFeedback',
|
|
17
|
+
stateMutability: 'nonpayable',
|
|
18
|
+
inputs: [
|
|
19
|
+
{ name: 'agentId', type: 'uint256' },
|
|
20
|
+
{ name: 'score', type: 'uint8' },
|
|
21
|
+
{ name: 'tag', type: 'string' },
|
|
22
|
+
{ name: 'uri', type: 'string' },
|
|
23
|
+
],
|
|
24
|
+
outputs: [],
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
type: 'function',
|
|
28
|
+
name: 'getReputation',
|
|
29
|
+
stateMutability: 'view',
|
|
30
|
+
inputs: [{ name: 'agentId', type: 'uint256' }],
|
|
31
|
+
outputs: [
|
|
32
|
+
{ name: 'count', type: 'uint256' },
|
|
33
|
+
{ name: 'averageScore', type: 'uint256' },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
type: 'function',
|
|
38
|
+
name: 'getFeedback',
|
|
39
|
+
stateMutability: 'view',
|
|
40
|
+
inputs: [
|
|
41
|
+
{ name: 'agentId', type: 'uint256' },
|
|
42
|
+
{ name: 'index', type: 'uint256' },
|
|
43
|
+
],
|
|
44
|
+
outputs: [
|
|
45
|
+
{ name: 'rater', type: 'address' },
|
|
46
|
+
{ name: 'score', type: 'uint8' },
|
|
47
|
+
{ name: 'tag', type: 'string' },
|
|
48
|
+
{ name: 'uri', type: 'string' },
|
|
49
|
+
{ name: 'timestamp', type: 'uint64' },
|
|
50
|
+
],
|
|
51
|
+
},
|
|
52
|
+
] as const
|
|
53
|
+
|
|
54
|
+
// ─── Validation ──────────────────────────────────────────────────────────────
|
|
55
|
+
export const VALIDATION_REGISTRY_ABI = [
|
|
56
|
+
{
|
|
57
|
+
type: 'function',
|
|
58
|
+
name: 'requestValidation',
|
|
59
|
+
stateMutability: 'nonpayable',
|
|
60
|
+
inputs: [
|
|
61
|
+
{ name: 'agentId', type: 'uint256' },
|
|
62
|
+
{ name: 'dataHash', type: 'bytes32' },
|
|
63
|
+
{ name: 'uri', type: 'string' },
|
|
64
|
+
],
|
|
65
|
+
outputs: [{ name: 'requestId', type: 'uint256' }],
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'function',
|
|
69
|
+
name: 'respondValidation',
|
|
70
|
+
stateMutability: 'nonpayable',
|
|
71
|
+
inputs: [
|
|
72
|
+
{ name: 'requestId', type: 'uint256' },
|
|
73
|
+
{ name: 'passed', type: 'bool' },
|
|
74
|
+
{ name: 'score', type: 'uint8' },
|
|
75
|
+
{ name: 'uri', type: 'string' },
|
|
76
|
+
],
|
|
77
|
+
outputs: [],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
type: 'function',
|
|
81
|
+
name: 'getValidation',
|
|
82
|
+
stateMutability: 'view',
|
|
83
|
+
inputs: [{ name: 'requestId', type: 'uint256' }],
|
|
84
|
+
outputs: [
|
|
85
|
+
{
|
|
86
|
+
type: 'tuple',
|
|
87
|
+
components: [
|
|
88
|
+
{ name: 'agentId', type: 'uint256' },
|
|
89
|
+
{ name: 'requester', type: 'address' },
|
|
90
|
+
{ name: 'dataHash', type: 'bytes32' },
|
|
91
|
+
{ name: 'requestUri', type: 'string' },
|
|
92
|
+
{ name: 'validator', type: 'address' },
|
|
93
|
+
{ name: 'responded', type: 'bool' },
|
|
94
|
+
{ name: 'passed', type: 'bool' },
|
|
95
|
+
{ name: 'score', type: 'uint8' },
|
|
96
|
+
{ name: 'responseUri', type: 'string' },
|
|
97
|
+
{ name: 'requestedAt', type: 'uint64' },
|
|
98
|
+
{ name: 'respondedAt', type: 'uint64' },
|
|
99
|
+
],
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
type: 'function',
|
|
105
|
+
name: 'totalValidations',
|
|
106
|
+
stateMutability: 'view',
|
|
107
|
+
inputs: [],
|
|
108
|
+
outputs: [{ name: '', type: 'uint256' }],
|
|
109
|
+
},
|
|
110
|
+
] as const
|
|
111
|
+
|
|
112
|
+
export const NEBULA_REPUTATION_REGISTRY: Partial<Record<NebulaNetwork, Address>> = {
|
|
113
|
+
'mantle-mainnet': '0x56b11a8f34eCb20899BD4E1eA539E194F007F361',
|
|
114
|
+
'mantle-testnet': '0x0DA4162BdFaFd0b5a6Da4151E0415aEaBd87B521',
|
|
115
|
+
}
|
|
116
|
+
export const NEBULA_VALIDATION_REGISTRY: Partial<Record<NebulaNetwork, Address>> = {
|
|
117
|
+
'mantle-mainnet': '0x4A222ec3D7e656ADFE28583219Bed3462973DECD',
|
|
118
|
+
'mantle-testnet': '0x5eDa2Be8c2c24039952751C817a7E9C8E018628e',
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function resolveReputationRegistry(
|
|
122
|
+
network: NebulaNetwork,
|
|
123
|
+
override?: string,
|
|
124
|
+
): Address | null {
|
|
125
|
+
const c =
|
|
126
|
+
override || process.env.NEBULA_REPUTATION_REGISTRY || NEBULA_REPUTATION_REGISTRY[network]
|
|
127
|
+
return c ? (c as Address) : null
|
|
128
|
+
}
|
|
129
|
+
export function resolveValidationRegistry(
|
|
130
|
+
network: NebulaNetwork,
|
|
131
|
+
override?: string,
|
|
132
|
+
): Address | null {
|
|
133
|
+
const c =
|
|
134
|
+
override || process.env.NEBULA_VALIDATION_REGISTRY || NEBULA_VALIDATION_REGISTRY[network]
|
|
135
|
+
return c ? (c as Address) : null
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// ─── Reputation client ──
|
|
139
|
+
export async function giveFeedback(opts: {
|
|
140
|
+
walletClient: WalletClient
|
|
141
|
+
publicClient: PublicClient
|
|
142
|
+
registry: Address
|
|
143
|
+
agentId: bigint
|
|
144
|
+
score: number
|
|
145
|
+
tag: string
|
|
146
|
+
uri: string
|
|
147
|
+
}): Promise<{ txHash: Hex }> {
|
|
148
|
+
const account = opts.walletClient.account
|
|
149
|
+
if (!account) throw new Error('walletClient has no account')
|
|
150
|
+
const { request } = await opts.publicClient.simulateContract({
|
|
151
|
+
address: opts.registry,
|
|
152
|
+
abi: REPUTATION_REGISTRY_ABI,
|
|
153
|
+
functionName: 'giveFeedback',
|
|
154
|
+
args: [opts.agentId, opts.score, opts.tag, opts.uri],
|
|
155
|
+
account,
|
|
156
|
+
})
|
|
157
|
+
const txHash = await opts.walletClient.writeContract(request)
|
|
158
|
+
await opts.publicClient.waitForTransactionReceipt({ hash: txHash })
|
|
159
|
+
return { txHash }
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export async function getReputation(opts: {
|
|
163
|
+
publicClient: PublicClient
|
|
164
|
+
registry: Address
|
|
165
|
+
agentId: bigint
|
|
166
|
+
}): Promise<{ count: bigint; averageScore: bigint }> {
|
|
167
|
+
const [count, averageScore] = (await opts.publicClient.readContract({
|
|
168
|
+
address: opts.registry,
|
|
169
|
+
abi: REPUTATION_REGISTRY_ABI,
|
|
170
|
+
functionName: 'getReputation',
|
|
171
|
+
args: [opts.agentId],
|
|
172
|
+
})) as [bigint, bigint]
|
|
173
|
+
return { count, averageScore }
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ─── Validation client ──
|
|
177
|
+
export async function requestValidation(opts: {
|
|
178
|
+
walletClient: WalletClient
|
|
179
|
+
publicClient: PublicClient
|
|
180
|
+
registry: Address
|
|
181
|
+
agentId: bigint
|
|
182
|
+
dataHash: Hex
|
|
183
|
+
uri: string
|
|
184
|
+
}): Promise<{ requestId: bigint; txHash: Hex }> {
|
|
185
|
+
const account = opts.walletClient.account
|
|
186
|
+
if (!account) throw new Error('walletClient has no account')
|
|
187
|
+
const { request, result } = await opts.publicClient.simulateContract({
|
|
188
|
+
address: opts.registry,
|
|
189
|
+
abi: VALIDATION_REGISTRY_ABI,
|
|
190
|
+
functionName: 'requestValidation',
|
|
191
|
+
args: [opts.agentId, opts.dataHash, opts.uri],
|
|
192
|
+
account,
|
|
193
|
+
})
|
|
194
|
+
const txHash = await opts.walletClient.writeContract(request)
|
|
195
|
+
await opts.publicClient.waitForTransactionReceipt({ hash: txHash })
|
|
196
|
+
return { requestId: result as bigint, txHash }
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export async function respondValidation(opts: {
|
|
200
|
+
walletClient: WalletClient
|
|
201
|
+
publicClient: PublicClient
|
|
202
|
+
registry: Address
|
|
203
|
+
requestId: bigint
|
|
204
|
+
passed: boolean
|
|
205
|
+
score: number
|
|
206
|
+
uri: string
|
|
207
|
+
}): Promise<{ txHash: Hex }> {
|
|
208
|
+
const account = opts.walletClient.account
|
|
209
|
+
if (!account) throw new Error('walletClient has no account')
|
|
210
|
+
const { request } = await opts.publicClient.simulateContract({
|
|
211
|
+
address: opts.registry,
|
|
212
|
+
abi: VALIDATION_REGISTRY_ABI,
|
|
213
|
+
functionName: 'respondValidation',
|
|
214
|
+
args: [opts.requestId, opts.passed, opts.score, opts.uri],
|
|
215
|
+
account,
|
|
216
|
+
})
|
|
217
|
+
const txHash = await opts.walletClient.writeContract(request)
|
|
218
|
+
await opts.publicClient.waitForTransactionReceipt({ hash: txHash })
|
|
219
|
+
return { txHash }
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export interface ValidationRecord {
|
|
223
|
+
agentId: bigint
|
|
224
|
+
requester: Address
|
|
225
|
+
dataHash: Hex
|
|
226
|
+
requestUri: string
|
|
227
|
+
validator: Address
|
|
228
|
+
responded: boolean
|
|
229
|
+
passed: boolean
|
|
230
|
+
score: number
|
|
231
|
+
responseUri: string
|
|
232
|
+
requestedAt: bigint
|
|
233
|
+
respondedAt: bigint
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
export async function getValidation(opts: {
|
|
237
|
+
publicClient: PublicClient
|
|
238
|
+
registry: Address
|
|
239
|
+
requestId: bigint
|
|
240
|
+
}): Promise<ValidationRecord> {
|
|
241
|
+
const v = (await opts.publicClient.readContract({
|
|
242
|
+
address: opts.registry,
|
|
243
|
+
abi: VALIDATION_REGISTRY_ABI,
|
|
244
|
+
functionName: 'getValidation',
|
|
245
|
+
args: [opts.requestId],
|
|
246
|
+
})) as ValidationRecord
|
|
247
|
+
return v
|
|
248
|
+
}
|
package/src/identity/erc8004.ts
CHANGED
|
@@ -91,6 +91,7 @@ export const IDENTITY_REGISTRY_ABI = [
|
|
|
91
91
|
* NEBULA_IDENTITY_REGISTRY. Mainnet pending a funded deploy.
|
|
92
92
|
*/
|
|
93
93
|
export const NEBULA_IDENTITY_REGISTRY: Partial<Record<NebulaNetwork, Address>> = {
|
|
94
|
+
'mantle-mainnet': '0x00a818451dC072d449e92a21d02d6B68fc703588',
|
|
94
95
|
'mantle-testnet': '0x529ae7B0e8A8191c0307b918AA62f1Fc6557a621',
|
|
95
96
|
}
|
|
96
97
|
|
package/src/identity/index.ts
CHANGED
|
@@ -27,3 +27,19 @@ export {
|
|
|
27
27
|
buildAgentCard,
|
|
28
28
|
cardToDataUri,
|
|
29
29
|
} from './agent-card'
|
|
30
|
+
|
|
31
|
+
// ERC-8004 Reputation + Validation registries
|
|
32
|
+
export {
|
|
33
|
+
REPUTATION_REGISTRY_ABI,
|
|
34
|
+
VALIDATION_REGISTRY_ABI,
|
|
35
|
+
NEBULA_REPUTATION_REGISTRY,
|
|
36
|
+
NEBULA_VALIDATION_REGISTRY,
|
|
37
|
+
resolveReputationRegistry,
|
|
38
|
+
resolveValidationRegistry,
|
|
39
|
+
giveFeedback,
|
|
40
|
+
getReputation,
|
|
41
|
+
requestValidation,
|
|
42
|
+
respondValidation,
|
|
43
|
+
getValidation,
|
|
44
|
+
type ValidationRecord,
|
|
45
|
+
} from './erc8004-trust'
|
package/src/index.ts
CHANGED
|
@@ -225,6 +225,18 @@ export {
|
|
|
225
225
|
DEFAULT_AGENT_SKILLS,
|
|
226
226
|
buildAgentCard,
|
|
227
227
|
cardToDataUri,
|
|
228
|
+
REPUTATION_REGISTRY_ABI,
|
|
229
|
+
VALIDATION_REGISTRY_ABI,
|
|
230
|
+
NEBULA_REPUTATION_REGISTRY,
|
|
231
|
+
NEBULA_VALIDATION_REGISTRY,
|
|
232
|
+
resolveReputationRegistry,
|
|
233
|
+
resolveValidationRegistry,
|
|
234
|
+
giveFeedback,
|
|
235
|
+
getReputation,
|
|
236
|
+
requestValidation,
|
|
237
|
+
respondValidation,
|
|
238
|
+
getValidation,
|
|
239
|
+
type ValidationRecord,
|
|
228
240
|
} from './identity'
|
|
229
241
|
|
|
230
242
|
export {
|