Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Primus zkTLS plugin to fully verify agent activities #2086

Merged
merged 28 commits into from
Jan 11, 2025
Merged
Show file tree
Hide file tree
Changes from 25 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
3b16a4c
add primus plugin
WuEcho Jan 6, 2025
b6eae8d
update primus zktls core sdk invoke
fksyuan Jan 6, 2025
de6b982
fix model name bug and update primus attestation decode
fksyuan Jan 6, 2025
1a098b4
Proof provider and action for twitter-plugin
xudean Jan 7, 2025
b750bfb
update readme log
fksyuan Jan 7, 2025
d8df612
update README in plugin-twitter-primus
xudean Jan 7, 2025
e00f5ea
Merge remote-tracking branch 'origin/develop' into develop
xudean Jan 7, 2025
adb2374
Merge remote-tracking branch 'upstream/develop' into develop
xudean Jan 8, 2025
e2e9063
update npm package 'zktls-core-sdk'
xudean Jan 8, 2025
0563ed5
update README in plugin-primus and plugin-twitter-plugin
xudean Jan 8, 2025
e33cead
get tweet by UserScreenName
xudean Jan 9, 2025
02ef838
refactor plugin-primus
xudean Jan 9, 2025
8266043
refine readme in plugin-primus
xiangxiecrypto Jan 9, 2025
d05c974
fix format
xiangxiecrypto Jan 9, 2025
d8d3ce7
update readme in plugin-primus
xudean Jan 9, 2025
adfd2be
Merge remote-tracking branch 'origin/develop' into develop
xudean Jan 9, 2025
d389b22
Merge remote-tracking branch 'upstream/develop' into develop
xudean Jan 9, 2025
8122abc
fix readme format
xudean Jan 9, 2025
c8500cd
fix code error
xudean Jan 9, 2025
4f08094
update readme in plugin-primus
xudean Jan 9, 2025
14fe671
update import
xudean Jan 9, 2025
ff931a9
update import
xudean Jan 9, 2025
730b929
refine readme
xiangxiecrypto Jan 9, 2025
b6818ec
chore: refine readme
xiangxiecrypto Jan 10, 2025
d55da5f
Merge branch 'develop' into develop
xudean Jan 10, 2025
3a3a9f2
Merge remote-tracking branch 'upstream/develop' into develop
xudean Jan 11, 2025
9bf45e0
Merge remote-tracking branch 'upstream/develop' into develop
xudean Jan 11, 2025
d90f838
resolve conversions problems
xudean Jan 11, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions agent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"@elizaos/plugin-near": "workspace:*",
"@elizaos/plugin-zksync-era": "workspace:*",
"@elizaos/plugin-twitter": "workspace:*",
"@elizaos/plugin-primus": "workspace:*",
"@elizaos/plugin-cronoszkevm": "workspace:*",
"@elizaos/plugin-3d-generation": "workspace:*",
"@elizaos/plugin-fuel": "workspace:*",
Expand Down
17 changes: 17 additions & 0 deletions agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { SlackClientInterface } from "@elizaos/client-slack";
import { TelegramClientInterface } from "@elizaos/client-telegram";
import { TwitterClientInterface } from "@elizaos/client-twitter";
// import { ReclaimAdapter } from "@elizaos/plugin-reclaim";
import { DirectClient } from "@elizaos/client-direct";
import { PrimusAdapter } from "@elizaos/plugin-primus";

import {
AgentRuntime,
CacheManager,
Expand Down Expand Up @@ -94,6 +97,7 @@ import net from "net";
import path from "path";
import { fileURLToPath } from "url";
import yargs from "yargs";
import {dominosPlugin} from "@elizaos/plugin-dominos";

const __filename = fileURLToPath(import.meta.url); // get the resolved path to the file
const __dirname = path.dirname(__filename); // get the name of the directory
Expand Down Expand Up @@ -594,6 +598,19 @@ export async function createAgent(
elizaLogger.log("modelProvider", character.modelProvider);
elizaLogger.log("token", token);
}
if (
process.env.PRIMUS_APP_ID &&
process.env.PRIMUS_APP_SECRET &&
process.env.VERIFIABLE_INFERENCE_ENABLED === "true"){
verifiableInferenceAdapter = new PrimusAdapter({
appId: process.env.PRIMUS_APP_ID,
appSecret: process.env.PRIMUS_APP_SECRET,
attMode: "proxytls",
modelProvider: character.modelProvider,
token,
});
elizaLogger.log("Verifiable inference primus adapter initialized");
}

return new AgentRuntime({
databaseAdapter: db,
Expand Down
2 changes: 2 additions & 0 deletions packages/core/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1424,7 +1424,9 @@ export interface ISlackService extends Service {
* Available verifiable inference providers
*/
export enum VerifiableInferenceProvider {
RECLAIM = "reclaim",
OPACITY = "opacity",
PRIMUS = "primus",
}

/**
Expand Down
6 changes: 6 additions & 0 deletions packages/plugin-primus/.npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
*

!dist/**
!package.json
!readme.md
!tsup.config.ts
202 changes: 202 additions & 0 deletions packages/plugin-primus/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# @elizaos/plugin-primus

A plugin to fully verify agent activities, including LLM access, actions, and interactions with external providers,
powered by Primus' zkTLS protocol.

## Overview

In the Eliza framework, an agent consists of three key components: a brain (accessing an LLM), actions (the tasks the
agent performs), and perception (gathering external information from providers). To fully verify agent activities, it's
essential to ensure that the agent's thoughts, actions, and external information requests are all verifiable. This
plugin enables full verification of these activities.
wtfsayo marked this conversation as resolved.
Show resolved Hide resolved

The current plugin includes:

- Verification of inference from OpenAI's LLM.
- An example for verifying actions, such as posting a tweet (this can be extended to any other actions).
- An example to verify that the Bitcoin price is accurately fetched from Binance (this can be extended to any other data
providers).

## Usage
### LLM inference verification (PrimusAdapter)
`PrimusAdapter` implements `IVerifiableInferenceAdapter` and can be used as follows.
```typescript
import {PrimusAdapter} from "@elizaos/plugin-primus";
import {VerifiableInferenceOptions} from '@elizaos/core';

// Initialize primus adapter
const primusAdatper = new PrimusAdapter({
appId: process.env.PRIMUS_APP_ID,
appSecret: process.env.PRIMUS_APP_SECRET,
// Choose MPC-TLS or Proxy-TLS
attMode: "proxytls",
modelProvider: character.modelProvider,
token,
});

interface PrimusOptions {
appId: string;
appSecret: string;
attMode: string;
modelProvider?: ModelProviderName;
token?: string;
}

// The options for generating an attestation
const options: VerifiableInferenceOptions = {
// Optional: Override the default endpoint
endpoint: "https://api.openapi.com/chat/completions",
// Optional: Add custom headers
headers: {
"Content-Type": "application/json",
"Authorization": "bearer Token",
},
// Optional: Provider-specific options
providerOptions: {
temperature: 0.7,
},
};

// Generate an attestation for a network request.
const result = await primusAdapter.generateText(context, "gpt-4o", options);
// Verify the validity of the attestation.
const isValid = await primusAdapter.verifyProof(result.proof);
```

The core functions in `PrimusAdatper` are the following, which are also used in Actions and Providers.
```typescript
// Generate a zkTLS proof.
generateProof = async (
// The target endpoint of the network request.
endpoint: string,
// The HTTP method of the request, such as 'GET', 'POST', etc.
method: string,
// A record containing the headers of the request.
headers: Record<string, any>,
// The body of the request. It should be a string.
body: string,
//A [JSONPath](https://datatracker.ietf.org/doc/rfc9535/) expression to locate the specific field in the response you want to attest.
responseParsePath: string
): Promise<any>

// Verify the proof.
verifyProof = async (attestation: any): Promise<boolean>

```

### Verify the interaction with Providers

Here’s an example showcasing how to verify the validity of the BTC price retrieved from Binance. Developers can easily customize this process for other providers.

```typescript
const tokenPriceProvider: Provider = {
get: async (runtime: IAgentRuntime, message: Memory, _state?: State) => {
// Set the URL
const url = "https://api.binance.com/api/v3/ticker/price?symbol=BTCUSDT";
const method = 'GET';
const headers = {
'Accept ': '*/*',
};
// Generate the proof
const attestation = await generateProof(url, method, headers, "", "$.price");
// Verify the proof.
const valid = await verifyProof(attestation);
if (!valid) {
throw new Error("Invalid price attestation");
}
......
},
};
```

### Verify the Actions
Below is an example showcasing how to post price information from the [tokenPriceProvider](./src/providers/tokenPriceProvider.ts) to Twitter. Developers can easily adapt this process for other providers.

Note that you need to configure the `.env` file correctly to post tweets.
```typescript
export const postTweetAction: Action = {
description: "",
examples: [],
handler: async (
runtime: IAgentRuntime,
message: Memory,
state?: State
): Promise<boolean> => {
const contentYouWantToPost = await tokenPriceProvider.get(runtime, message, state);
const endpoint = 'https://twitter.com/i/api/graphql/a1p9RWpkYKBjWv_I3WzS-A/CreateTweet';
const method = 'POST';
const attestation = await generateProof(endpoint,method,headers,bodyStr,"$.data.create_tweet.tweet_results.result.rest_id");
elizaLogger.info(
"Tweet posting proof generated successfully:",
attestation
);
const verifyResult = verifyProof(attestation);
if (!verifyResult) {
throw new Error(
"Attestation verify failed, data from source is illegality"
);
}

},
name: "",
similes: [],
validate: async (
runtime: IAgentRuntime,
message: Memory,
state?: State
) => {},
};
wtfsayo marked this conversation as resolved.
Show resolved Hide resolved
```

## Installation

```bash
pnpm add @elizaos/plugin-primus
```

## Configuration

Add the following environment variables to your .env file:

```
PRIMUS_APP_ID=your_app_id
PRIMUS_APP_SECRET=your_app_secret
VERIFIABLE_INFERENCE_ENABLED=true
VERIFIABLE_INFERENCE_PROVIDER=primus
```

***How to get PRIMUS_APP_ID and PRIMUS_APP_SECRET***

1. Visit the [Primus Developer Hub](https://dev.primuslabs.xyz/).
2. Create a new project
3. Save your 'Application ID(PRIMUS_APP_ID)' and 'Secret Key(PRIMUS_APP_SECRET)'

To use the plugin, add `@elizaos/plugin-primus` to the plugins field in your character file. Here's an example of how your character file might look after the update:

```json
{
"name": "trump",
"modelProvider": "openai",
// just support openai now
"plugins": [
"@elizaos/plugin-primus"
],
// other fields
.....
}
```

## Run

```bash
# Start the server
pnpm start --characters="characters/xxx.character.json"
```

```bash
# Start the client
pnpm start:client
```

You can ask the agent: "Get the BTC price and tweet."

32 changes: 32 additions & 0 deletions packages/plugin-primus/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{
"name": "@elizaos/plugin-primus",
"version": "0.1.7",
"type": "module",
"main": "dist/index.js",
"module": "dist/index.js",
"types": "dist/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"import": {
"@elizaos/source": "./src/index.ts",
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
}
},
"files": [
"dist"
],
"dependencies": {
"@elizaos/core": "workspace:*",
"agent-twitter-client": "0.0.18",
"@primuslabs/zktls-core-sdk": "^0.1.0",
"tsup": "8.3.5"
},
"scripts": {
"build": "tsup --format esm --dts",
"dev": "tsup --format esm --dts --watch",
"test": "vitest run"
}
}
Loading
Loading