Skip to content

Commit

Permalink
Merge pull request #6 from artela-network/ai16zPR/tee-verifiable-log
Browse files Browse the repository at this point in the history
Ai16z pr/tee verifiable log
  • Loading branch information
gene-zhan authored Dec 19, 2024
2 parents 86005ad + b50f4a0 commit ba52182
Show file tree
Hide file tree
Showing 13 changed files with 858 additions and 0 deletions.
1 change: 1 addition & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1214,6 +1214,7 @@ export enum ServiceType {
AWS_S3 = "aws_s3",
BUTTPLUG = "buttplug",
SLACK = "slack",
VERIFIABLE_LOGGING = "verifiable_logging",
}

export enum LoggingLevel {
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-tee-verifiable-log/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*

!dist/**
!package.json
!readme.md
!tsup.config.ts
33 changes: 33 additions & 0 deletions packages/plugin-tee-verifiable-log/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
## Build
Execute the following command to build the code.
```
pnpm clean
pnpm install or pnpm install --no-frozen-lockfile
pnpm build
```

## Configuration

To get a TEE simulator for local testing, use the following commands:
```shell
docker pull phalanetwork/tappd-simulator:latest
# by default the simulator is available in localhost:8090
docker run --rm -p 8090:8090 phalanetwork/tappd-simulator:latest
```

When using the provider through the runtime environment, ensure the following settings are configured:
```shell

# Optional, for simulator purposes if testing on mac or windows. Leave empty for Linux x86 machines.
DSTACK_SIMULATOR_ENDPOINT="http://host.docker.internal:8090"
VLOG="true"
```

## Test

Test files are located in the `test` folder. To run the tests, execute the following command:

```shell
pnpm test

```
3 changes: 3 additions & 0 deletions packages/plugin-tee-verifiable-log/eslint.config.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import eslintGlobalConfig from "../../eslint.config.mjs";

export default [...eslintGlobalConfig];
30 changes: 30 additions & 0 deletions packages/plugin-tee-verifiable-log/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "@ai16z/plugin-tee-verifiable-log",
"version": "0.1.4-alpha.3",
"main": "dist/index.js",
"type": "module",
"types": "dist/index.d.ts",
"dependencies": {
"@ai16z/eliza": "workspace:*",
"@ai16z/plugin-tee": "workspace:*",
"dompurify": "3.2.2",
"elliptic": "^6.6.1",
"ethereum-cryptography": "^3.0.0",
"tsup": "8.3.5",
"uuid": "11.0.3",
"vitest": "2.1.5"
},
"scripts": {
"build": "tsup --format esm --dts",
"test": "vitest run",
"test:watch": "vitest",
"lint": "eslint . --fix"
},
"devDependencies": {
"@types/dompurify": "3.2.0",
"ts-node": "^10.9.2"
},
"peerDependencies": {
"whatwg-url": "7.1.0"
}
}
209 changes: 209 additions & 0 deletions packages/plugin-tee-verifiable-log/src/adapters/sqliteVerifiableDAO.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
import { Database } from "better-sqlite3";
import { v4 as uuidv4 } from "uuid";
import {
VerifiableLog,
VerifiableAgent,
VerifiableDAO,
VerifiableLogQuery,
PageQuery,
} from "../types/logTypes.ts";

export class SQLite3VerifiableDAO extends VerifiableDAO<Database> {
constructor(db: Database) {
super();
this.db = db;
// load(db);
// check if the tables exist, if not create them
const tables = db
.prepare(
"SELECT name FROM sqlite_master WHERE type='table' AND name IN ('verifiable-logs', 'verifiable-agents');"
)
.all();
if (tables.length !== 2) {
this.initializeSchema();
}
}

async initializeSchema(): Promise<void> {
this.db.exec(`
CREATE TABLE IF NOT EXISTS "tee_verifiable_logs"
(
"id" TEXT PRIMARY KEY,
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"agent_id" TEXT NOT NULL,
"room_id" TEXT NOT NULL,
"user_id" TEXT,
"type" TEXT,
"content" TEXT NOT NULL,
"signature" TEXT NOT NULL
);
`);

this.db.exec(`
CREATE TABLE IF NOT EXISTS "tee_verifiable_agents"
(
"id" TEXT PRIMARY KEY,
"created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
"agent_id" TEXT NOT NULL,
"agent_name" TEXT,
"agent_keypair_path" TEXT NOT NULL,
"agent_keypair_vlog_pk" TEXT NOT NULL,
UNIQUE ("agent_id")
);
`);
}

async addLog(log: VerifiableLog): Promise<boolean> {
const sql = `
INSERT INTO "tee_verifiable_logs" ("id", "created_at", "agent_id", "room_id", "user_id", "type", "content",
"signature")
VALUES (?, ?, ?, ?, ?, ?, ?, ?);
`;
try {
this.db
.prepare(sql)
.run(
log.id || uuidv4(),
log.created_at || new Date().getTime(),
log.agent_id,
log.room_id,
log.user_id,
log.type,
log.content,
log.signature
);
return true;
} catch (error) {
console.error("SQLite3 Error adding log:", error);
return false;
}
}

async pageQueryLogs(
query: VerifiableLogQuery,
page: number,
pageSize: number
): Promise<PageQuery<VerifiableLog[]>> {
const conditions: string[] = [];
const params: any[] = [];

if (query.idEq) {
conditions.push(`id = ?`);
params.push(query.idEq);
}
if (query.agentIdEq) {
conditions.push(`agent_id = ?`);
params.push(query.agentIdEq);
}
if (query.roomIdEq) {
conditions.push(`room_id = ?`);
params.push(query.roomIdEq);
}
if (query.userIdEq) {
conditions.push(`user_id = ?`);
params.push(query.userIdEq);
}
if (query.typeEq) {
conditions.push(`type = ?`);
params.push(query.typeEq);
}
if (query.contLike) {
conditions.push(`content LIKE ?`);
params.push(`%${query.contLike}%`);
}
if (query.signatureEq) {
conditions.push(`signature = ?`);
params.push(query.signatureEq);
}

const whereClause =
conditions.length > 0 ? `WHERE ${conditions.join(" AND ")}` : "";

if (page < 1) {
page = 1;
}
const offset = (page - 1) * pageSize;
const limit = pageSize;


try {
const totalQuery = `SELECT COUNT(*) AS total
FROM tee_verifiable_logs ${whereClause}`;
const stmt = this.db.prepare(totalQuery);
const totalResult = stmt.get(params);
const total = totalResult.total;

const dataQuery = `
SELECT *
FROM tee_verifiable_logs ${whereClause}
ORDER BY created_at DESC
LIMIT ? OFFSET ?
`;
const dataResult = this.db
.prepare(dataQuery)
.all(...params, limit, offset);

return {
page: page,
pageSize: pageSize,
total: total,
data: dataResult,
} as PageQuery<VerifiableLog[]>;
} catch (error) {
console.error("Error querying tee_verifiable_logs:", error);
throw error;
}
}

async addAgent(agent: VerifiableAgent): Promise<boolean> {
const sql = `
INSERT INTO "tee_verifiable_agents" ("id", "created_at", "agent_id","agent_name","agent_keypair_path", "agent_keypair_vlog_pk")
VALUES (?, ?, ?, ?, ?,?);
`;
try {
this.db
.prepare(sql)
.run(
agent.id || uuidv4(),
agent.created_at || new Date().getTime(),
agent.agent_id,
agent.agent_name||"agent bot",
agent.agent_keypair_path,
agent.agent_keypair_vlog_pk
);
return true;
} catch (error) {
console.error("SQLite3 Error adding agent:", error);
return false;
}
}

async getAgent(agentId: string): Promise<VerifiableAgent> {
const sql = `SELECT *
FROM "tee_verifiable_agents"
WHERE agent_id = ?`;
try {
const agent = this.db.prepare(sql).get(agentId);
if (agent) {
return agent as VerifiableAgent;
} else {
return null;
}
} catch (error) {
console.error("SQLite3 Error getting agent:", error);
throw error;
}
}

async listAgent(): Promise<VerifiableAgent[]> {
const sql = `SELECT *
FROM "tee_verifiable_agents"`;
try {
const agents = this.db.prepare(sql).all();
return agents as VerifiableAgent[];
} catch (error) {
console.error("SQLite3 Error listing agent:", error);
throw error;
}
}
}
Loading

0 comments on commit ba52182

Please sign in to comment.