Skip to content

Commit d5a56c9

Browse files
authored
Merge pull request elizaOS#1369 from artela-network/ai16zPR/tee-verifiable-log-api-from-develop
feat: RP for plugin-tee-verifiable-log
2 parents 64b4174 + 104202d commit d5a56c9

23 files changed

+1968
-390
lines changed

.env.example

+33
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,39 @@ ZEROG_FLOW_ADDRESS=
365365
TEE_MODE=OFF # LOCAL | DOCKER | PRODUCTION
366366
WALLET_SECRET_SALT= # ONLY define if you want to use TEE Plugin, otherwise it will throw errors
367367

368+
369+
# TEE Verifiable Log Configuration
370+
VLOG= # true/false; if you want to use TEE Verifiable Log, set this to "true"
371+
372+
# Galadriel Configuration
373+
GALADRIEL_API_KEY=gal-* # Get from https://dashboard.galadriel.com/
374+
375+
# Venice Configuration
376+
VENICE_API_KEY= # generate from venice settings
377+
SMALL_VENICE_MODEL= # Default: llama-3.3-70b
378+
MEDIUM_VENICE_MODEL= # Default: llama-3.3-70b
379+
LARGE_VENICE_MODEL= # Default: llama-3.1-405b
380+
IMAGE_VENICE_MODEL= # Default: fluently-xl
381+
382+
# Akash Chat API Configuration docs: https://chatapi.akash.network/documentation
383+
AKASH_CHAT_API_KEY= # Get from https://chatapi.akash.network/
384+
SMALL_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-2-3B-Instruct
385+
MEDIUM_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-3-70B-Instruct
386+
LARGE_AKASH_CHAT_API_MODEL= # Default: Meta-Llama-3-1-405B-Instruct-FP8
387+
388+
# fal.ai Configuration
389+
FAL_API_KEY=
390+
FAL_AI_LORA_PATH=
391+
392+
# Web search API Configuration
393+
TAVILY_API_KEY=
394+
395+
# WhatsApp Cloud API Configuration
396+
WHATSAPP_ACCESS_TOKEN= # Permanent access token from Facebook Developer Console
397+
WHATSAPP_PHONE_NUMBER_ID= # Phone number ID from WhatsApp Business API
398+
WHATSAPP_BUSINESS_ACCOUNT_ID= # Business Account ID from Facebook Business Manager
399+
WHATSAPP_WEBHOOK_VERIFY_TOKEN= # Custom string for webhook verification
400+
WHATSAPP_API_VERSION=v17.0 # WhatsApp API version (default: v17.0)
368401
ENABLE_TEE_LOG=false # Set to true to enable TEE logging, only available when running eliza in TEE
369402

370403
# Flow Blockchain Configuration

agent/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
"@elizaos/plugin-letzai": "workspace:*",
8484
"@elizaos/plugin-thirdweb": "workspace:*",
8585
"@elizaos/plugin-genlayer": "workspace:*",
86+
"@elizaos/plugin-tee-verifiable-log": "workspace:*",
8687
"@elizaos/plugin-depin": "workspace:*",
8788
"@elizaos/plugin-open-weather": "workspace:*",
8889
"@elizaos/plugin-obsidian": "workspace:*",

agent/src/index.ts

+4
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ import net from "net";
101101
import path from "path";
102102
import { fileURLToPath } from "url";
103103
import yargs from "yargs";
104+
import { verifiableLogPlugin } from "@elizaos/plugin-tee-verifiable-log";
104105
import createNFTCollectionsPlugin from "@elizaos/plugin-nft-collections";
105106

106107
const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
@@ -798,6 +799,9 @@ export async function createAgent(
798799
]
799800
: []),
800801
...(teeMode !== TEEMode.OFF && walletSecretSalt ? [teePlugin] : []),
802+
(teeMode !== TEEMode.OFF && walletSecretSalt &&getSecret(character,"VLOG")
803+
? verifiableLogPlugin
804+
: null),
801805
getSecret(character, "SGX") ? sgxPlugin : null,
802806
getSecret(character, "ENABLE_TEE_LOG") &&
803807
((teeMode !== TEEMode.OFF && walletSecretSalt) ||

packages/client-direct/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
"dependencies": {
2222
"@elizaos/core": "workspace:*",
2323
"@elizaos/plugin-image-generation": "workspace:*",
24+
"@elizaos/plugin-tee-verifiable-log": "workspace:*",
2425
"@elizaos/plugin-tee-log": "workspace:*",
2526
"@types/body-parser": "1.19.5",
2627
"@types/cors": "2.8.17",

packages/client-direct/src/README.md

+128-1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,133 @@ curl -X GET "http://localhost:3000/fine-tune/8566c47a-ada8-441c-95bc-7bb07656c4c
4444
-H "Authorization: Bearer jvBpxrTNqGqhnfQhSEqCdsG6aTSP8IBL".
4545
```
4646

47+
48+
49+
## Verifiable Attestations
50+
51+
This function relies on [plugin-tee-verifiable-log](../../plugin-tee-verifiable-log/README.md)
52+
53+
Enable Verifiable Logs, Configuration variables in .env
54+
```shell
55+
TEE_MODE="DOCKER" # LOCAL | DOCKER | PRODUCTION
56+
WALLET_SECRET_SALT= "<your wallet secret salt>" # ONLY define if you want to use TEE Plugin, otherwise it will throw errors
57+
VLOG="true"
58+
```
59+
### APIs
60+
### 1. Get verifiable agents
61+
```shell
62+
curl -X GET --location "http://localhost:3000/verifiable/agents"
63+
```
64+
* Response success result
65+
```shell
66+
{
67+
"success": true,
68+
"message": "Successfully get Agents",
69+
"data": [
70+
{
71+
"id": "c4598810-61a2-4ac8-ab85-b746402692c4",
72+
"created_at": 1734526797906,
73+
"agent_id": "9c321604-e69e-0e4c-ab84-bec6fd6baf92",
74+
"agent_name": "Capila",
75+
"agent_keypair_path": "/keys/verifiable_key",
76+
"agent_keypair_vlog_pk": "0x045b51a28c3b071104f3094b1934343eb831b8d56f16fc6..."
77+
}
78+
]
79+
}
80+
```
81+
* Response failure result
82+
```shell
83+
{
84+
"error": "failed to get agents registered ",
85+
"details": "Cannot read properties of undefined (reading 'getService')",
86+
"stack": "TypeError: Cannot read ..."
87+
}
88+
```
89+
90+
### 2.Query verifiable logs
91+
```bash
92+
93+
curl -X POST --location "http://localhost:3000/verifiable/logs" \
94+
-H "Content-Type: application/json" \
95+
-d '{
96+
"query": {
97+
"contLike": "Twinkletwinkle"
98+
},
99+
"page": 1,
100+
"pageSize": 10
101+
}'
102+
```
103+
The query body that can be queried are:
104+
>* idEq: string;
105+
>* agentIdEq: string;
106+
>* roomIdEq: string;
107+
>* userIdEq: string;
108+
>* typeEq: string;
109+
>* contLike: string;
110+
>* signatureEq: string;
111+
112+
* Response success result
113+
```shell
114+
{
115+
"success": true,
116+
"message": "Successfully retrieved logs",
117+
"data": {
118+
"page": 1,
119+
"pageSize": 10,
120+
"total": 1,
121+
"data": [
122+
{
123+
"id": "b9ac4b2f-ecb5-4c5c-a981-d282b831e878",
124+
"created_at": 1734526805664,
125+
"agent_id": "9c321604-e69e-0e4c-ab84-bec6fd6baf92",
126+
"room_id": "8c54580d-2c56-01e8-81e4-4160a02f3ee5",
127+
"user_id": "9c321604-e69e-0e4c-ab84-bec6fd6baf92",
128+
"type": "post tweet",
129+
"content": "{\"text\":\"Twinkletwinkle, it's time to unlock your artistic values!\\n\\n My NFTs are here to bring the chill vibes to Web3.\\n\\n Let's wagmi and make this a day to remember!\",\"url\":\"https://twitter.com/....\"}",
130+
"signature": "0x9ac77cfef9374bff3b41f96d0b0a8d61bfcf88e3a01f7bc20653494145ff31ef118a2a3cd94437481000a13500c6ed6714d8802bf2572a7da4de2e81a688d0b41c"
131+
}
132+
]
133+
}
134+
}
135+
```
136+
* Response failure result
137+
```shell
138+
139+
{
140+
"error": "Failed to Get Verifiable Logs",
141+
"details": "Cannot read properties of undefined (reading 'getService')",
142+
"stack": "TypeError: Cannot read ..."
143+
}
144+
```
145+
146+
147+
### 3.Get Tee Attestation
148+
```shell
149+
curl -X POST --location "http://localhost:3000/verifiable/attestation" \
150+
-H "Content-Type: application/json" \
151+
-d '{
152+
"agentId": "9c321604-e69e-0e4c-ab84-bec6fd6baf92",
153+
"publicKey": "0x045b51a28c3b071104f3094b1934343eb831b8d56f16fc6e9a3304e9f051b24e584d806b20769b05eeade3a6c792db96f57b26cc38037907dd920e9be9f41f6184"
154+
}'
155+
```
156+
* Response success result
157+
```shell
158+
{
159+
"success": true,
160+
"message": "Successfully get Attestation",
161+
"data": "{\"quote\":\"0x04000300810000000e934d64208ed62112d13060cf062a398f78a9516b9f884ee7ad145e875b59592b09598ce02e4d4983ae4decab71f5147acd16a26326e01075a8d5b709727224bba449c9cd7fc2b490ea23d9e01cd932221d8b86a0a8a7be25c25571bceef0427131860fe0cb295b0d25e5ed1488d9a122c24ba4c1494c2a2578535c556752850c6bbd60c2482b5bb10b5157fe5f42b637457262fd4d8a92575b307f5453c1982a841b46cd60858a3f8ced7ca2ba1c02cf9fec3f23b30bbe8e30378e116bea58b4068bf0379964b6adcb2f680f4646b26a21bed6f8ac06f468cc356db0b2769638a02a7d6e0b69ae297304c62a1fd800703e8bfd340901b6ad412d9433eee04b67ab86311ebb4ee2f3a758ea3fda0e89f45c7ec9ca28e2d525fab6d3e62c3e2b6788dd9dec6e367975c0ac5f6c2aad436e14c75dd99a94c51d882efc0ea44ca8c251e3384b24a88af39ab070b65387ee5e0fd11212852663248c6f24a646c163273348ea03f99d028022b08e09b0b992d9b49c61246b298c3ec827af4973a57bc017a35e0f22750922f2cae660ed70797695c5c65104339f912e1da35a7c625e5fa470764228efe80309762e33ea295b8fd6bae7ef9e7f9a4210deaac322d26acf4e003aded3099c90d6f5c1caa6fb9d84e4f70da3ea1fbfd76c2c7bb544375f566a5182e142da67718a4db7b373ff7e8b4e14bf5a752c5cf88002555020a2a4938978849c1774810456a8fe89769a595676eb0fdadda83540d353efdd40a3efcfb80283abc942e9348d3fe04109fd9999ed6fae17b5d8de88dcd80e5d57cd576ffb7a21780bd6064b4e61f83d1ff1088e836f2a8aa4cdee685aa02303cb809a6e45997532d372b5b519d3ae03f08cb162020000f5672ea83d7b1e145824622fea621381d7b6a110b1b0fdda4e4e2c3565431d099e74829267a01345a2780d0387173419e23bdb72ea57294c696e14ac8198e0967e30dc93a361465d109c1a54f47c117adcba95fdc2cecbd2b35ba3fc7443d80f56e16499d4a85ae2970428848487f963c9366898b34ebbb349dc162d2127f2800000dc010000149f9a1f60ae565575037121aac4f9a10cf6d6e884df2aac1c2bb83f8cad17d0d27f7d4264bdb78a9fe056aba38ff666b22642a9471f351f04afa7ad727f80a1ecab742174c46b33f034fc43cdef08afde65b93aeb94db20b705b379407e50a648db3a3f5958ac29f9bcc32a46a3ea36be27bc049a1409e8543467926afce68eed7488c7120ff3bd6d79c61078111d285e13fc365c82da04469a77101e067bc24f0c4fd27c361430292b8af92f07ac2687532e36377a9c67fa65a17a1dedba2aabac079d3ee691fcdf3e10bf7a479ee58e27085f5ac700a2252899cd88ba13ab00b1cf12cbfca3bcdacaf870e904191bdf2e7426c86b092380fbb523086c294aaf64f3931c96ec7292e4a0aee03f4b0f0eb757d1dc96c7fd07dcad6d51622060e5db55cae0c45aab399caa785665302fff467b1caa98e4ef2bac9a02911388a44b69cf7f21bf3c2ce2da95f323ea3717eddfe97f486beb90dc7ff88377211dd8a89d2b77d044fae1423904839ad8b4662d8df7a414c9aec2c234c0df878093fc31714d2fee3c400cfbee9df0ee82df7d7361d53a7ce91b01e80d3dc9702eebb8dafa1cb3e2a5032fd64ded06e5f1bacd9c275604cedabbea82cec2cfa32384790a000000000000000000000078c50a00000000000000000000000000\",\"timestamp\":1734626127589}"
162+
}
163+
```
164+
165+
* Response failure result
166+
```shell
167+
168+
{
169+
"error": "Failed to Get Verifiable Logs",
170+
"details": "Cannot read properties of undefined (reading 'getService')",
171+
"stack": "TypeError: Cannot read ..."
172+
}
173+
```
47174
# TEE Logging
48175

49176
TEE Logging is a feature that allows you to log the activities of your agents. Through these logs, you can verify that the actions of the agents are protected by the TEE and that they are executed autonomously by Eliza, without any third-party interference.
@@ -187,4 +314,4 @@ Example response when error:
187314
{
188315
"error": "Failed to get TEE logs"
189316
}
190-
```
317+
```

packages/client-direct/src/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
import { createApiRouter } from "./api.ts";
2626
import * as fs from "fs";
2727
import * as path from "path";
28+
import { createVerifiableLogApiRouter } from "./verifiable-log-api.ts";
2829
import OpenAI from "openai";
2930

3031
const storage = multer.diskStorage({
@@ -135,6 +136,10 @@ export class DirectClient {
135136
const apiRouter = createApiRouter(this.agents, this);
136137
this.app.use(apiRouter);
137138

139+
140+
const apiLogRouter = createVerifiableLogApiRouter(this.agents);
141+
this.app.use(apiLogRouter);
142+
138143
// Define an interface that extends the Express Request interface
139144
interface CustomRequest extends ExpressRequest {
140145
file?: Express.Multer.File;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import express from "express";
2+
import bodyParser from "body-parser";
3+
import cors from "cors";
4+
5+
import { AgentRuntime, elizaLogger, ServiceType } from "@elizaos/core";
6+
import {
7+
VerifiableLogService,
8+
VerifiableLogQuery,
9+
} from "@elizaos/plugin-tee-verifiable-log";
10+
11+
export function createVerifiableLogApiRouter(
12+
agents: Map<string, AgentRuntime>
13+
) {
14+
const router = express.Router();
15+
router.use(cors());
16+
router.use(bodyParser.json());
17+
router.use(bodyParser.urlencoded({ extended: true }));
18+
19+
router.get(
20+
"/verifiable/agents",
21+
async (req: express.Request, res: express.Response) => {
22+
try {
23+
// call the listAgent method
24+
const agentRuntime: AgentRuntime | undefined = agents.values().next().value;
25+
const pageQuery = await agentRuntime
26+
.getService<VerifiableLogService>(
27+
ServiceType.VERIFIABLE_LOGGING
28+
)
29+
.listAgent();
30+
31+
res.json({
32+
success: true,
33+
message: "Successfully get Agents",
34+
data: pageQuery,
35+
});
36+
} catch (error) {
37+
elizaLogger.error("Detailed error:", error);
38+
res.status(500).json({
39+
error: "failed to get agents registered ",
40+
details: error.message,
41+
stack: error.stack,
42+
});
43+
}
44+
}
45+
);
46+
router.post(
47+
"/verifiable/attestation",
48+
async (req: express.Request, res: express.Response) => {
49+
try {
50+
const query = req.body || {};
51+
52+
const verifiableLogQuery = {
53+
agentId: query.agentId || "",
54+
publicKey: query.publicKey || "",
55+
};
56+
const agentRuntime: AgentRuntime | undefined = agents.values().next().value;
57+
const pageQuery = await agentRuntime
58+
.getService<VerifiableLogService>(
59+
ServiceType.VERIFIABLE_LOGGING
60+
)
61+
.generateAttestation(verifiableLogQuery);
62+
63+
res.json({
64+
success: true,
65+
message: "Successfully get Attestation",
66+
data: pageQuery,
67+
});
68+
} catch (error) {
69+
elizaLogger.error("Detailed error:", error);
70+
res.status(500).json({
71+
error: "Failed to Get Attestation",
72+
details: error.message,
73+
stack: error.stack,
74+
});
75+
}
76+
}
77+
);
78+
router.post(
79+
"/verifiable/logs",
80+
async (req: express.Request, res: express.Response) => {
81+
try {
82+
const query = req.body.query || {};
83+
const page = parseInt(req.body.page) || 1;
84+
const pageSize = parseInt(req.body.pageSize) || 10;
85+
86+
const verifiableLogQuery: VerifiableLogQuery = {
87+
idEq: query.idEq || "",
88+
agentIdEq: query.agentIdEq || "",
89+
roomIdEq: query.roomIdEq || "",
90+
userIdEq: query.userIdEq || "",
91+
typeEq: query.typeEq || "",
92+
contLike: query.contLike || "",
93+
signatureEq: query.signatureEq || "",
94+
};
95+
const agentRuntime: AgentRuntime | undefined = agents.values().next().value;
96+
const pageQuery = await agentRuntime
97+
.getService<VerifiableLogService>(
98+
ServiceType.VERIFIABLE_LOGGING
99+
)
100+
.pageQueryLogs(verifiableLogQuery, page, pageSize);
101+
102+
res.json({
103+
success: true,
104+
message: "Successfully retrieved logs",
105+
data: pageQuery,
106+
});
107+
} catch (error) {
108+
elizaLogger.error("Detailed error:", error);
109+
res.status(500).json({
110+
error: "Failed to Get Verifiable Logs",
111+
details: error.message,
112+
stack: error.stack,
113+
});
114+
}
115+
}
116+
);
117+
118+
return router;
119+
}

packages/core/src/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1428,6 +1428,7 @@ export enum ServiceType {
14281428
AWS_S3 = "aws_s3",
14291429
BUTTPLUG = "buttplug",
14301430
SLACK = "slack",
1431+
VERIFIABLE_LOGGING = "verifiable_logging",
14311432
IRYS = "irys",
14321433
TEE_LOG = "tee_log",
14331434
GOPLUS_SECURITY = "goplus_security",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*
2+
3+
!dist/**
4+
!package.json
5+
!readme.md
6+
!tsup.config.ts

0 commit comments

Comments
 (0)