@elizaos/plugin-tee 0.1.9 → 1.0.0-alpha.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/dist/index.js CHANGED
@@ -1,26 +1,23 @@
1
1
  import {
2
- secp256k1
3
- } from "./chunk-4L6P6TY5.js";
2
+ secp256k1,
3
+ sha256
4
+ } from "./chunk-LCSUOOZR.js";
4
5
  import {
5
6
  BaseError,
6
7
  BytesSizeMismatchError,
7
8
  FeeCapTooHighError,
8
- Hash,
9
9
  InvalidAddressError,
10
10
  InvalidChainIdError,
11
11
  InvalidLegacyVError,
12
12
  InvalidSerializableTransactionError,
13
13
  InvalidStorageKeySizeError,
14
14
  TipAboveFeeCapError,
15
- aexists,
16
- aoutput,
17
15
  bytesRegex,
18
16
  bytesToHex,
19
17
  checksumAddress,
20
18
  concat,
21
19
  concatHex,
22
20
  createCursor,
23
- createView,
24
21
  encodeAbiParameters,
25
22
  hexToBigInt,
26
23
  hexToBytes,
@@ -31,57 +28,253 @@ import {
31
28
  keccak256,
32
29
  maxUint256,
33
30
  numberToHex,
34
- rotr,
35
31
  size,
36
32
  slice,
37
33
  stringToHex,
38
34
  stringify,
39
35
  toBytes,
40
- toBytes2,
41
36
  toHex,
42
- trim,
43
- wrapConstructor
44
- } from "./chunk-NTU6R7BC.js";
37
+ trim
38
+ } from "./chunk-4HQ7LDIJ.js";
39
+ import "./chunk-672HY72Z.js";
45
40
  import "./chunk-PR4QN5HX.js";
46
41
 
47
- // src/providers/remoteAttestationProvider.ts
42
+ // src/index.ts
43
+ import {
44
+ logger as logger4
45
+ } from "@elizaos/core";
46
+
47
+ // src/services/teeLogService.ts
48
48
  import {
49
- elizaLogger
49
+ Service,
50
+ ServiceTypes,
51
+ TeeType as TeeType2,
52
+ TEEMode as TEEMode2
50
53
  } from "@elizaos/core";
51
- import { TappdClient } from "@phala/dstack-sdk";
52
54
 
53
- // src/types/tee.ts
54
- var TEEMode = /* @__PURE__ */ ((TEEMode2) => {
55
- TEEMode2["OFF"] = "OFF";
56
- TEEMode2["LOCAL"] = "LOCAL";
57
- TEEMode2["DOCKER"] = "DOCKER";
58
- TEEMode2["PRODUCTION"] = "PRODUCTION";
59
- return TEEMode2;
60
- })(TEEMode || {});
55
+ // src/types.ts
56
+ var TeeLogDAO = class {
57
+ db;
58
+ };
59
+
60
+ // src/adapters/sqliteTables.ts
61
+ var sqliteTables = `
62
+ BEGIN TRANSACTION;
63
+
64
+ -- Table: tee_logs
65
+ CREATE TABLE IF NOT EXISTS "tee_logs" (
66
+ "id" TEXT PRIMARY KEY,
67
+ "agentId" TEXT NOT NULL,
68
+ "roomId" TEXT NOT NULL,
69
+ "entityId" TEXT NOT NULL,
70
+ "type" TEXT NOT NULL,
71
+ "content" TEXT NOT NULL,
72
+ "timestamp" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
73
+ "signature" TEXT NOT NULL
74
+ );
75
+
76
+ -- Table: tee_agents
77
+ CREATE TABLE IF NOT EXISTS "tee_agents" (
78
+ "id" TEXT PRIMARY KEY,
79
+ "agentId" TEXT NOT NULL,
80
+ "agentName" TEXT NOT NULL,
81
+ "createdAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
82
+ "publicKey" TEXT NOT NULL,
83
+ "attestation" TEXT NOT NULL
84
+ );
85
+
86
+ COMMIT;`;
87
+
88
+ // src/adapters/sqliteDAO.ts
89
+ var SqliteTeeLogDAO = class extends TeeLogDAO {
90
+ constructor(db) {
91
+ super();
92
+ this.db = db;
93
+ }
94
+ async initialize() {
95
+ this.db.exec(sqliteTables);
96
+ }
97
+ async addLog(log) {
98
+ const stmt = this.db.prepare(
99
+ "INSERT INTO tee_logs (id, agentId, roomId, entityId, type, content, timestamp, signature) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"
100
+ );
101
+ try {
102
+ stmt.run(
103
+ log.id,
104
+ log.agentId,
105
+ log.roomId,
106
+ log.entityId,
107
+ log.type,
108
+ log.content,
109
+ log.timestamp,
110
+ log.signature
111
+ );
112
+ return true;
113
+ } catch (error) {
114
+ console.error("Error adding log to database", error);
115
+ return false;
116
+ }
117
+ }
118
+ async getPagedLogs(query, page, pageSize) {
119
+ const currentPage = page < 1 ? 1 : page;
120
+ const offset = (currentPage - 1) * pageSize;
121
+ const limit = pageSize;
122
+ const whereConditions = [];
123
+ const params = [];
124
+ if (query.agentId && query.agentId !== "") {
125
+ whereConditions.push("agentId = ?");
126
+ params.push(query.agentId);
127
+ }
128
+ if (query.roomId && query.roomId !== "") {
129
+ whereConditions.push("roomId = ?");
130
+ params.push(query.roomId);
131
+ }
132
+ if (query.entityId && query.entityId !== "") {
133
+ whereConditions.push("entityId = ?");
134
+ params.push(query.entityId);
135
+ }
136
+ if (query.type && query.type !== "") {
137
+ whereConditions.push("type = ?");
138
+ params.push(query.type);
139
+ }
140
+ if (query.containsContent && query.containsContent !== "") {
141
+ whereConditions.push("content LIKE ?");
142
+ params.push(`%${query.containsContent}%`);
143
+ }
144
+ if (query.startTimestamp) {
145
+ whereConditions.push("timestamp >= ?");
146
+ params.push(query.startTimestamp);
147
+ }
148
+ if (query.endTimestamp) {
149
+ whereConditions.push("timestamp <= ?");
150
+ params.push(query.endTimestamp);
151
+ }
152
+ const whereClause = whereConditions.length > 0 ? `WHERE ${whereConditions.join(" AND ")}` : "";
153
+ try {
154
+ const total_stmt = this.db.prepare(
155
+ `SELECT COUNT(*) as total FROM tee_logs ${whereClause}`
156
+ );
157
+ const total = total_stmt.get(params).total;
158
+ const logs_stmt = this.db.prepare(
159
+ `SELECT * FROM tee_logs ${whereClause} ORDER BY timestamp ASC LIMIT ? OFFSET ?`
160
+ );
161
+ const logs = logs_stmt.all(...params, limit, offset);
162
+ return {
163
+ page: currentPage,
164
+ pageSize,
165
+ total,
166
+ data: logs
167
+ };
168
+ } catch (error) {
169
+ console.error("Error getting paged logs from database", error);
170
+ throw error;
171
+ }
172
+ }
173
+ async addAgent(agent) {
174
+ const stmt = this.db.prepare(
175
+ "INSERT INTO tee_agents (id, agentId, agentName, createdAt, publicKey, attestation) VALUES (?, ?, ?, ?, ?, ?)"
176
+ );
177
+ try {
178
+ stmt.run(
179
+ agent.id,
180
+ agent.agentId,
181
+ agent.agentName,
182
+ agent.createdAt,
183
+ agent.publicKey,
184
+ agent.attestation
185
+ );
186
+ return true;
187
+ } catch (error) {
188
+ console.error("Error adding agent to database", error);
189
+ return false;
190
+ }
191
+ }
192
+ async getAgent(agentId) {
193
+ const stmt = this.db.prepare(
194
+ "SELECT * FROM tee_agents WHERE agentId = ? ORDER BY createdAt DESC LIMIT 1"
195
+ );
196
+ try {
197
+ return stmt.get(agentId);
198
+ } catch (error) {
199
+ console.error("Error getting agent from database", error);
200
+ throw error;
201
+ }
202
+ }
203
+ async getAllAgents() {
204
+ const stmt = this.db.prepare("SELECT * FROM tee_agents");
205
+ try {
206
+ return stmt.all();
207
+ } catch (error) {
208
+ console.error("Error getting all agents from database", error);
209
+ throw error;
210
+ }
211
+ }
212
+ };
61
213
 
62
214
  // src/providers/remoteAttestationProvider.ts
215
+ import {
216
+ logger
217
+ } from "@elizaos/core";
218
+ import {
219
+ TappdClient
220
+ } from "@phala/dstack-sdk";
221
+ import {
222
+ TEEMode
223
+ } from "@elizaos/core";
224
+ import { promises as fs } from "node:fs";
225
+
226
+ // src/utils.ts
227
+ import { createHash } from "node:crypto";
228
+ function hexToUint8Array(hex) {
229
+ const hexString = hex.trim().replace(/^0x/, "");
230
+ if (!hexString) {
231
+ throw new Error("Invalid hex string");
232
+ }
233
+ if (hexString.length % 2 !== 0) {
234
+ throw new Error("Invalid hex string");
235
+ }
236
+ const array = new Uint8Array(hexString.length / 2);
237
+ for (let i = 0; i < hexString.length; i += 2) {
238
+ const byte = Number.parseInt(hexString.slice(i, i + 2), 16);
239
+ if (Number.isNaN(byte)) {
240
+ throw new Error("Invalid hex string");
241
+ }
242
+ array[i / 2] = byte;
243
+ }
244
+ return array;
245
+ }
246
+ function calculateSHA256(input) {
247
+ const hash = createHash("sha256");
248
+ hash.update(input);
249
+ return hash.digest();
250
+ }
251
+
252
+ // src/providers/base.ts
253
+ var DeriveKeyProvider = class {
254
+ };
63
255
  var RemoteAttestationProvider = class {
256
+ };
257
+
258
+ // src/providers/remoteAttestationProvider.ts
259
+ var PhalaRemoteAttestationProvider = class extends RemoteAttestationProvider {
64
260
  client;
65
261
  constructor(teeMode) {
262
+ super();
66
263
  let endpoint;
67
264
  switch (teeMode) {
68
- case "LOCAL" /* LOCAL */:
265
+ case TEEMode.LOCAL:
69
266
  endpoint = "http://localhost:8090";
70
- elizaLogger.log(
71
- "TEE: Connecting to local simulator at localhost:8090"
72
- );
267
+ logger.log("TEE: Connecting to local simulator at localhost:8090");
73
268
  break;
74
- case "DOCKER" /* DOCKER */:
269
+ case TEEMode.DOCKER:
75
270
  endpoint = "http://host.docker.internal:8090";
76
- elizaLogger.log(
271
+ logger.log(
77
272
  "TEE: Connecting to simulator via Docker at host.docker.internal:8090"
78
273
  );
79
274
  break;
80
- case "PRODUCTION" /* PRODUCTION */:
275
+ case TEEMode.PRODUCTION:
81
276
  endpoint = void 0;
82
- elizaLogger.log(
83
- "TEE: Running in production mode without simulator"
84
- );
277
+ logger.log("TEE: Running in production mode without simulator");
85
278
  break;
86
279
  default:
87
280
  throw new Error(
@@ -92,10 +285,13 @@ var RemoteAttestationProvider = class {
92
285
  }
93
286
  async generateAttestation(reportData, hashAlgorithm) {
94
287
  try {
95
- elizaLogger.log("Generating attestation for: ", reportData);
96
- const tdxQuote = await this.client.tdxQuote(reportData, hashAlgorithm);
288
+ logger.log("Generating attestation for: ", reportData);
289
+ const tdxQuote = await this.client.tdxQuote(
290
+ reportData,
291
+ hashAlgorithm
292
+ );
97
293
  const rtmrs = tdxQuote.replayRtmrs();
98
- elizaLogger.log(
294
+ logger.log(
99
295
  `rtmr0: ${rtmrs[0]}
100
296
  rtmr1: ${rtmrs[1]}
101
297
  rtmr2: ${rtmrs[2]}
@@ -105,7 +301,7 @@ rtmr3: ${rtmrs[3]}f`
105
301
  quote: tdxQuote.quote,
106
302
  timestamp: Date.now()
107
303
  };
108
- elizaLogger.log("Remote attestation quote: ", quote);
304
+ logger.log("Remote attestation quote: ", quote);
109
305
  return quote;
110
306
  } catch (error) {
111
307
  console.error("Error generating remote attestation:", error);
@@ -115,24 +311,39 @@ rtmr3: ${rtmrs[3]}f`
115
311
  }
116
312
  }
117
313
  };
118
- var remoteAttestationProvider = {
119
- get: async (runtime, message, _state) => {
314
+ var phalaRemoteAttestationProvider = {
315
+ name: "phala-remote-attestation",
316
+ get: async (runtime, message) => {
120
317
  const teeMode = runtime.getSetting("TEE_MODE");
121
- const provider = new RemoteAttestationProvider(teeMode);
318
+ const provider = new PhalaRemoteAttestationProvider(teeMode);
122
319
  const agentId = runtime.agentId;
123
320
  try {
124
321
  const attestationMessage = {
125
322
  agentId,
126
323
  timestamp: Date.now(),
127
324
  message: {
128
- userId: message.userId,
325
+ entityId: message.entityId,
129
326
  roomId: message.roomId,
130
327
  content: message.content.text
131
328
  }
132
329
  };
133
- elizaLogger.log("Generating attestation for: ", JSON.stringify(attestationMessage));
134
- const attestation = await provider.generateAttestation(JSON.stringify(attestationMessage));
135
- return `Your Agent's remote attestation is: ${JSON.stringify(attestation)}`;
330
+ logger.log(
331
+ "Generating attestation for: ",
332
+ JSON.stringify(attestationMessage)
333
+ );
334
+ const attestation = await provider.generateAttestation(
335
+ JSON.stringify(attestationMessage)
336
+ );
337
+ return {
338
+ text: `Your Agent's remote attestation is: ${JSON.stringify(attestation)}`,
339
+ data: {
340
+ attestation
341
+ },
342
+ values: {
343
+ quote: attestation.quote,
344
+ timestamp: attestation.timestamp.toString()
345
+ }
346
+ };
136
347
  } catch (error) {
137
348
  console.error("Error in remote attestation provider:", error);
138
349
  throw new Error(
@@ -141,266 +352,327 @@ var remoteAttestationProvider = {
141
352
  }
142
353
  }
143
354
  };
355
+ var SgxAttestationProvider = class extends RemoteAttestationProvider {
356
+ SGX_QUOTE_MAX_SIZE = 8192 * 4;
357
+ SGX_TARGET_INFO_SIZE = 512;
358
+ MY_TARGET_INFO_PATH = "/dev/attestation/my_target_info";
359
+ TARGET_INFO_PATH = "/dev/attestation/target_info";
360
+ USER_REPORT_DATA_PATH = "/dev/attestation/user_report_data";
361
+ QUOTE_PATH = "/dev/attestation/quote";
362
+ // Remove unnecessary constructor
363
+ // constructor() {}
364
+ async generateAttestation(reportData) {
365
+ const rawUserReport = calculateSHA256(reportData);
366
+ try {
367
+ await fs.access(this.MY_TARGET_INFO_PATH);
368
+ const quote = await this.generateQuoteByGramine(rawUserReport);
369
+ const attestation = {
370
+ quote,
371
+ timestamp: Date.now()
372
+ };
373
+ return attestation;
374
+ } catch (error) {
375
+ console.error("Error generating SGX remote attestation:", error);
376
+ throw new Error(
377
+ `Failed to generate SGX Quote: ${error instanceof Error ? error.message : "Unknown error"}`
378
+ );
379
+ }
380
+ }
381
+ async generateQuoteByGramine(rawUserReport) {
382
+ if (rawUserReport.length > 64) {
383
+ throw new Error("the length of rawUserReport exceeds 64 bytes");
384
+ }
385
+ const myTargetInfo = await fs.readFile(this.MY_TARGET_INFO_PATH);
386
+ if (myTargetInfo.length !== this.SGX_TARGET_INFO_SIZE) {
387
+ throw new Error("Invalid my_target_info length");
388
+ }
389
+ await fs.writeFile(this.TARGET_INFO_PATH, myTargetInfo);
390
+ await fs.writeFile(this.USER_REPORT_DATA_PATH, rawUserReport);
391
+ const quoteData = await fs.readFile(this.QUOTE_PATH);
392
+ if (quoteData.length > this.SGX_QUOTE_MAX_SIZE) {
393
+ throw new Error("Invalid quote length");
394
+ }
395
+ const realLen = quoteData.lastIndexOf(0);
396
+ if (realLen === -1) {
397
+ throw new Error("quote without EOF");
398
+ }
399
+ return `0x${quoteData.subarray(0, realLen + 1).toString("hex")}`;
400
+ }
401
+ };
402
+ var sgxAttestationProvider = {
403
+ name: "sgx-gramine-remote-attestation",
404
+ get: async (runtime, _message) => {
405
+ const provider = new SgxAttestationProvider();
406
+ const agentId = runtime.agentId;
407
+ try {
408
+ const attestation = await provider.generateAttestation(agentId);
409
+ return {
410
+ data: attestation,
411
+ values: {
412
+ quote: attestation.quote,
413
+ timestamp: attestation.timestamp.toString()
414
+ },
415
+ text: `Your Agent's remote attestation is: ${JSON.stringify(attestation)}`
416
+ };
417
+ } catch (error) {
418
+ console.error("Error in remote attestation provider:", error);
419
+ const errorMessage = `Failed to generate SGX Quote: ${error instanceof Error ? error.message : "Unknown error"}`;
420
+ return {
421
+ data: null,
422
+ values: {},
423
+ text: errorMessage
424
+ };
425
+ }
426
+ }
427
+ };
144
428
 
145
- // src/providers/deriveKeyProvider.ts
429
+ // src/services/teeLogManager.ts
146
430
  import {
147
- elizaLogger as elizaLogger2
431
+ TeeType
148
432
  } from "@elizaos/core";
149
- import { Keypair } from "@solana/web3.js";
150
- import crypto from "crypto";
151
- import { TappdClient as TappdClient2 } from "@phala/dstack-sdk";
433
+ import elliptic from "elliptic";
152
434
 
153
- // ../../node_modules/viem/node_modules/@noble/hashes/esm/_md.js
154
- function setBigUint64(view, byteOffset, value, isLE) {
155
- if (typeof view.setBigUint64 === "function")
156
- return view.setBigUint64(byteOffset, value, isLE);
157
- const _32n = BigInt(32);
158
- const _u32_max = BigInt(4294967295);
159
- const wh = Number(value >> _32n & _u32_max);
160
- const wl = Number(value & _u32_max);
161
- const h = isLE ? 4 : 0;
162
- const l = isLE ? 0 : 4;
163
- view.setUint32(byteOffset + h, wh, isLE);
164
- view.setUint32(byteOffset + l, wl, isLE);
435
+ // ../../node_modules/uuid/dist/esm/stringify.js
436
+ var byteToHex = [];
437
+ for (let i = 0; i < 256; ++i) {
438
+ byteToHex.push((i + 256).toString(16).slice(1));
165
439
  }
166
- var Chi = (a, b, c) => a & b ^ ~a & c;
167
- var Maj = (a, b, c) => a & b ^ a & c ^ b & c;
168
- var HashMD = class extends Hash {
169
- constructor(blockLen, outputLen, padOffset, isLE) {
170
- super();
171
- this.blockLen = blockLen;
172
- this.outputLen = outputLen;
173
- this.padOffset = padOffset;
174
- this.isLE = isLE;
175
- this.finished = false;
176
- this.length = 0;
177
- this.pos = 0;
178
- this.destroyed = false;
179
- this.buffer = new Uint8Array(blockLen);
180
- this.view = createView(this.buffer);
181
- }
182
- update(data) {
183
- aexists(this);
184
- const { view, buffer, blockLen } = this;
185
- data = toBytes(data);
186
- const len = data.length;
187
- for (let pos = 0; pos < len; ) {
188
- const take = Math.min(blockLen - this.pos, len - pos);
189
- if (take === blockLen) {
190
- const dataView = createView(data);
191
- for (; blockLen <= len - pos; pos += blockLen)
192
- this.process(dataView, pos);
193
- continue;
194
- }
195
- buffer.set(data.subarray(pos, pos + take), this.pos);
196
- this.pos += take;
197
- pos += take;
198
- if (this.pos === blockLen) {
199
- this.process(view, 0);
200
- this.pos = 0;
201
- }
440
+ function unsafeStringify(arr, offset = 0) {
441
+ return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
442
+ }
443
+
444
+ // ../../node_modules/uuid/dist/esm/rng.js
445
+ import { randomFillSync } from "crypto";
446
+ var rnds8Pool = new Uint8Array(256);
447
+ var poolPtr = rnds8Pool.length;
448
+ function rng() {
449
+ if (poolPtr > rnds8Pool.length - 16) {
450
+ randomFillSync(rnds8Pool);
451
+ poolPtr = 0;
452
+ }
453
+ return rnds8Pool.slice(poolPtr, poolPtr += 16);
454
+ }
455
+
456
+ // ../../node_modules/uuid/dist/esm/native.js
457
+ import { randomUUID } from "crypto";
458
+ var native_default = { randomUUID };
459
+
460
+ // ../../node_modules/uuid/dist/esm/v4.js
461
+ function v4(options, buf, offset) {
462
+ if (native_default.randomUUID && !buf && !options) {
463
+ return native_default.randomUUID();
464
+ }
465
+ options = options || {};
466
+ const rnds = options.random || (options.rng || rng)();
467
+ rnds[6] = rnds[6] & 15 | 64;
468
+ rnds[8] = rnds[8] & 63 | 128;
469
+ if (buf) {
470
+ offset = offset || 0;
471
+ for (let i = 0; i < 16; ++i) {
472
+ buf[offset + i] = rnds[i];
473
+ }
474
+ return buf;
475
+ }
476
+ return unsafeStringify(rnds);
477
+ }
478
+ var v4_default = v4;
479
+
480
+ // src/services/teeLogManager.ts
481
+ var TeeLogManager = class {
482
+ teeLogDAO;
483
+ teeType;
484
+ teeMode;
485
+ // Only used for plugin-tee with TDX dstack
486
+ // Map of agentId to its key pair
487
+ // These keypairs only store in memory.
488
+ // When the agent restarts, we will generate new keypair.
489
+ keyPairs = /* @__PURE__ */ new Map();
490
+ constructor(teeLogDAO, teeType, teeMode) {
491
+ this.teeLogDAO = teeLogDAO;
492
+ this.teeType = teeType;
493
+ this.teeMode = teeMode;
494
+ }
495
+ async registerAgent(agentId, agentName) {
496
+ if (!agentId) {
497
+ throw new Error("Agent ID is required");
498
+ }
499
+ const keyPair = this.generateKeyPair();
500
+ this.keyPairs.set(agentId, keyPair);
501
+ const publicKey = keyPair.getPublic().encode("hex", true);
502
+ const attestation = await this.generateAttestation(publicKey);
503
+ const new_agent = {
504
+ id: v4_default(),
505
+ agentId,
506
+ agentName: agentName || "",
507
+ createdAt: (/* @__PURE__ */ new Date()).getTime(),
508
+ publicKey,
509
+ attestation
510
+ };
511
+ console.log("registerAgent new_agent", new_agent);
512
+ return this.teeLogDAO.addAgent(new_agent);
513
+ }
514
+ async getAllAgents() {
515
+ return this.teeLogDAO.getAllAgents();
516
+ }
517
+ async getAgent(agentId) {
518
+ return this.teeLogDAO.getAgent(agentId);
519
+ }
520
+ async log(agentId, roomId, entityId, type, content) {
521
+ const keyPair = this.keyPairs.get(agentId);
522
+ if (!keyPair) {
523
+ throw new Error(`Agent ${agentId} not found`);
524
+ }
525
+ const timestamp = (/* @__PURE__ */ new Date()).getTime();
526
+ const messageToSign = `${agentId}|${roomId}|${entityId}|${type}|${content}|${timestamp}`;
527
+ const signature = `0x${keyPair.sign(messageToSign).toDER("hex")}`;
528
+ return this.teeLogDAO.addLog({
529
+ id: v4_default(),
530
+ agentId,
531
+ roomId,
532
+ entityId,
533
+ type,
534
+ content,
535
+ timestamp,
536
+ signature
537
+ });
538
+ }
539
+ async getLogs(query, page, pageSize) {
540
+ return this.teeLogDAO.getPagedLogs(query, page, pageSize);
541
+ }
542
+ generateKeyPair() {
543
+ const ec = new elliptic.ec("secp256k1");
544
+ const key = ec.genKeyPair();
545
+ return key;
546
+ }
547
+ async generateAttestation(userReport) {
548
+ if (this.teeType === TeeType.SGX_GRAMINE) {
549
+ const sgxAttestationProvider2 = new SgxAttestationProvider();
550
+ const sgxAttestation = await sgxAttestationProvider2.generateAttestation(userReport);
551
+ return JSON.stringify(sgxAttestation);
202
552
  }
203
- this.length += data.length;
204
- this.roundClean();
205
- return this;
206
- }
207
- digestInto(out) {
208
- aexists(this);
209
- aoutput(out, this);
210
- this.finished = true;
211
- const { buffer, view, blockLen, isLE } = this;
212
- let { pos } = this;
213
- buffer[pos++] = 128;
214
- this.buffer.subarray(pos).fill(0);
215
- if (this.padOffset > blockLen - pos) {
216
- this.process(view, 0);
217
- pos = 0;
553
+ if (this.teeType === TeeType.TDX_DSTACK) {
554
+ const tdxAttestationProvider = new PhalaRemoteAttestationProvider(this.teeMode);
555
+ const tdxAttestation = await tdxAttestationProvider.generateAttestation(userReport);
556
+ return JSON.stringify(tdxAttestation);
218
557
  }
219
- for (let i = pos; i < blockLen; i++)
220
- buffer[i] = 0;
221
- setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE);
222
- this.process(view, 0);
223
- const oview = createView(out);
224
- const len = this.outputLen;
225
- if (len % 4)
226
- throw new Error("_sha2: outputLen should be aligned to 32bit");
227
- const outLen = len / 4;
228
- const state = this.get();
229
- if (outLen > state.length)
230
- throw new Error("_sha2: outputLen bigger than state");
231
- for (let i = 0; i < outLen; i++)
232
- oview.setUint32(4 * i, state[i], isLE);
233
- }
234
- digest() {
235
- const { buffer, outputLen } = this;
236
- this.digestInto(buffer);
237
- const res = buffer.slice(0, outputLen);
238
- this.destroy();
239
- return res;
240
- }
241
- _cloneInto(to) {
242
- to || (to = new this.constructor());
243
- to.set(...this.get());
244
- const { blockLen, buffer, length, finished, destroyed, pos } = this;
245
- to.length = length;
246
- to.pos = pos;
247
- to.finished = finished;
248
- to.destroyed = destroyed;
249
- if (length % blockLen)
250
- to.buffer.set(buffer);
251
- return to;
558
+ throw new Error("Invalid TEE type");
252
559
  }
253
560
  };
254
561
 
255
- // ../../node_modules/viem/node_modules/@noble/hashes/esm/sha256.js
256
- var SHA256_K = /* @__PURE__ */ new Uint32Array([
257
- 1116352408,
258
- 1899447441,
259
- 3049323471,
260
- 3921009573,
261
- 961987163,
262
- 1508970993,
263
- 2453635748,
264
- 2870763221,
265
- 3624381080,
266
- 310598401,
267
- 607225278,
268
- 1426881987,
269
- 1925078388,
270
- 2162078206,
271
- 2614888103,
272
- 3248222580,
273
- 3835390401,
274
- 4022224774,
275
- 264347078,
276
- 604807628,
277
- 770255983,
278
- 1249150122,
279
- 1555081692,
280
- 1996064986,
281
- 2554220882,
282
- 2821834349,
283
- 2952996808,
284
- 3210313671,
285
- 3336571891,
286
- 3584528711,
287
- 113926993,
288
- 338241895,
289
- 666307205,
290
- 773529912,
291
- 1294757372,
292
- 1396182291,
293
- 1695183700,
294
- 1986661051,
295
- 2177026350,
296
- 2456956037,
297
- 2730485921,
298
- 2820302411,
299
- 3259730800,
300
- 3345764771,
301
- 3516065817,
302
- 3600352804,
303
- 4094571909,
304
- 275423344,
305
- 430227734,
306
- 506948616,
307
- 659060556,
308
- 883997877,
309
- 958139571,
310
- 1322822218,
311
- 1537002063,
312
- 1747873779,
313
- 1955562222,
314
- 2024104815,
315
- 2227730452,
316
- 2361852424,
317
- 2428436474,
318
- 2756734187,
319
- 3204031479,
320
- 3329325298
321
- ]);
322
- var SHA256_IV = /* @__PURE__ */ new Uint32Array([
323
- 1779033703,
324
- 3144134277,
325
- 1013904242,
326
- 2773480762,
327
- 1359893119,
328
- 2600822924,
329
- 528734635,
330
- 1541459225
331
- ]);
332
- var SHA256_W = /* @__PURE__ */ new Uint32Array(64);
333
- var SHA256 = class extends HashMD {
334
- constructor() {
335
- super(64, 32, 8, false);
336
- this.A = SHA256_IV[0] | 0;
337
- this.B = SHA256_IV[1] | 0;
338
- this.C = SHA256_IV[2] | 0;
339
- this.D = SHA256_IV[3] | 0;
340
- this.E = SHA256_IV[4] | 0;
341
- this.F = SHA256_IV[5] | 0;
342
- this.G = SHA256_IV[6] | 0;
343
- this.H = SHA256_IV[7] | 0;
344
- }
345
- get() {
346
- const { A, B, C, D, E, F, G, H } = this;
347
- return [A, B, C, D, E, F, G, H];
348
- }
349
- // prettier-ignore
350
- set(A, B, C, D, E, F, G, H) {
351
- this.A = A | 0;
352
- this.B = B | 0;
353
- this.C = C | 0;
354
- this.D = D | 0;
355
- this.E = E | 0;
356
- this.F = F | 0;
357
- this.G = G | 0;
358
- this.H = H | 0;
359
- }
360
- process(view, offset) {
361
- for (let i = 0; i < 16; i++, offset += 4)
362
- SHA256_W[i] = view.getUint32(offset, false);
363
- for (let i = 16; i < 64; i++) {
364
- const W15 = SHA256_W[i - 15];
365
- const W2 = SHA256_W[i - 2];
366
- const s0 = rotr(W15, 7) ^ rotr(W15, 18) ^ W15 >>> 3;
367
- const s1 = rotr(W2, 17) ^ rotr(W2, 19) ^ W2 >>> 10;
368
- SHA256_W[i] = s1 + SHA256_W[i - 7] + s0 + SHA256_W[i - 16] | 0;
562
+ // src/services/teeLogService.ts
563
+ import Database from "better-sqlite3";
564
+ import path from "node:path";
565
+ var TeeLogService = class _TeeLogService extends Service {
566
+ dbPath;
567
+ initialized = false;
568
+ enableTeeLog = false;
569
+ teeType;
570
+ teeMode = TEEMode2.OFF;
571
+ // Only used for plugin-tee with TDX dstack
572
+ teeLogDAO;
573
+ teeLogManager;
574
+ static serviceType = ServiceTypes.TEE;
575
+ capabilityDescription = "The agent is able to log TEE attestation events and is probably running in a TEE";
576
+ constructor(runtime) {
577
+ super();
578
+ this.runtime = runtime;
579
+ }
580
+ static async start(runtime) {
581
+ const service = new _TeeLogService(runtime);
582
+ const enableValues = ["true", "1", "yes", "enable", "enabled", "on"];
583
+ const enableTeeLog = runtime.getSetting("ENABLE_TEE_LOG");
584
+ if (enableTeeLog === null) {
585
+ throw new Error("ENABLE_TEE_LOG is not set.");
586
+ }
587
+ service.enableTeeLog = enableValues.includes(enableTeeLog.toLowerCase());
588
+ if (!service.enableTeeLog) {
589
+ console.log("TEE log is not enabled.");
590
+ return;
591
+ }
592
+ const runInSgx = runtime.getSetting("SGX");
593
+ const teeMode = runtime.getSetting("TEE_MODE");
594
+ const walletSecretSalt = runtime.getSetting("WALLET_SECRET_SALT");
595
+ service.teeMode = teeMode ? TEEMode2[teeMode] : TEEMode2.OFF;
596
+ const useSgxGramine = runInSgx && enableValues.includes(runInSgx.toLowerCase());
597
+ const useTdxDstack = teeMode && teeMode !== TEEMode2.OFF && walletSecretSalt;
598
+ if (useSgxGramine && useTdxDstack) {
599
+ throw new Error("Cannot configure both SGX and TDX at the same time.");
600
+ }
601
+ if (useSgxGramine) {
602
+ service.teeType = TeeType2.SGX_GRAMINE;
603
+ } else if (useTdxDstack) {
604
+ service.teeType = TeeType2.TDX_DSTACK;
605
+ } else {
606
+ throw new Error("Invalid TEE configuration.");
607
+ }
608
+ const dbPathSetting = runtime.getSetting("TEE_LOG_DB_PATH");
609
+ service.dbPath = dbPathSetting || path.resolve("data/tee_log.sqlite");
610
+ const db = new Database(service.dbPath);
611
+ service.teeLogDAO = new SqliteTeeLogDAO(db);
612
+ service.teeLogManager = new TeeLogManager(
613
+ service.teeLogDAO,
614
+ service.teeType,
615
+ service.teeMode
616
+ );
617
+ const isRegistered = await service.teeLogManager.registerAgent(
618
+ runtime?.agentId,
619
+ runtime?.character?.name
620
+ );
621
+ if (!isRegistered) {
622
+ throw new Error(`Failed to register agent ${runtime.agentId}`);
623
+ }
624
+ service.initialized = true;
625
+ return service;
626
+ }
627
+ static async stop(runtime) {
628
+ const service = runtime.getService(ServiceTypes.TEE);
629
+ if (service) {
630
+ await service.stop();
631
+ }
632
+ }
633
+ async stop() {
634
+ }
635
+ async log(agentId, roomId, entityId, type, content) {
636
+ if (!this.enableTeeLog) {
637
+ return false;
638
+ }
639
+ return this.teeLogManager.log(agentId, roomId, entityId, type, content);
640
+ }
641
+ async getAllAgents() {
642
+ if (!this.enableTeeLog) {
643
+ return [];
644
+ }
645
+ return this.teeLogManager.getAllAgents();
646
+ }
647
+ async getAgent(agentId) {
648
+ if (!this.enableTeeLog) {
649
+ return void 0;
369
650
  }
370
- let { A, B, C, D, E, F, G, H } = this;
371
- for (let i = 0; i < 64; i++) {
372
- const sigma1 = rotr(E, 6) ^ rotr(E, 11) ^ rotr(E, 25);
373
- const T1 = H + sigma1 + Chi(E, F, G) + SHA256_K[i] + SHA256_W[i] | 0;
374
- const sigma0 = rotr(A, 2) ^ rotr(A, 13) ^ rotr(A, 22);
375
- const T2 = sigma0 + Maj(A, B, C) | 0;
376
- H = G;
377
- G = F;
378
- F = E;
379
- E = D + T1 | 0;
380
- D = C;
381
- C = B;
382
- B = A;
383
- A = T1 + T2 | 0;
651
+ return this.teeLogManager.getAgent(agentId);
652
+ }
653
+ async getLogs(query, page, pageSize) {
654
+ if (!this.enableTeeLog) {
655
+ return {
656
+ data: [],
657
+ total: 0,
658
+ page,
659
+ pageSize
660
+ };
384
661
  }
385
- A = A + this.A | 0;
386
- B = B + this.B | 0;
387
- C = C + this.C | 0;
388
- D = D + this.D | 0;
389
- E = E + this.E | 0;
390
- F = F + this.F | 0;
391
- G = G + this.G | 0;
392
- H = H + this.H | 0;
393
- this.set(A, B, C, D, E, F, G, H);
394
- }
395
- roundClean() {
396
- SHA256_W.fill(0);
397
- }
398
- destroy() {
399
- this.set(0, 0, 0, 0, 0, 0, 0, 0);
400
- this.buffer.fill(0);
662
+ return this.teeLogManager.getLogs(query, page, pageSize);
663
+ }
664
+ async generateAttestation(userReport) {
665
+ return this.teeLogManager.generateAttestation(userReport);
401
666
  }
402
667
  };
403
- var sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
668
+
669
+ // src/providers/deriveKeyProvider.ts
670
+ import {
671
+ logger as logger2
672
+ } from "@elizaos/core";
673
+ import { Keypair } from "@solana/web3.js";
674
+ import crypto from "node:crypto";
675
+ import { TappdClient as TappdClient2 } from "@phala/dstack-sdk";
404
676
 
405
677
  // ../../node_modules/viem/_esm/accounts/toAccount.js
406
678
  function toAccount(source) {
@@ -643,7 +915,7 @@ function blobsToProofs(parameters) {
643
915
  // ../../node_modules/viem/_esm/utils/hash/sha256.js
644
916
  function sha2562(value, to_) {
645
917
  const to = to_ || "hex";
646
- const bytes = sha256(isHex(value, { strict: false }) ? toBytes2(value) : value);
918
+ const bytes = sha256(isHex(value, { strict: false }) ? toBytes(value) : value);
647
919
  if (to === "bytes")
648
920
  return bytes;
649
921
  return toHex(bytes);
@@ -1185,7 +1457,7 @@ function getTypesForEIP712Domain({ domain }) {
1185
1457
  return [
1186
1458
  typeof domain?.name === "string" && { name: "name", type: "string" },
1187
1459
  domain?.version && { name: "version", type: "string" },
1188
- typeof domain?.chainId === "number" && {
1460
+ (typeof domain?.chainId === "number" || typeof domain?.chainId === "bigint") && {
1189
1461
  name: "chainId",
1190
1462
  type: "uint256"
1191
1463
  },
@@ -1356,29 +1628,29 @@ function privateKeyToAccount(privateKey, options = {}) {
1356
1628
  }
1357
1629
 
1358
1630
  // src/providers/deriveKeyProvider.ts
1359
- var DeriveKeyProvider = class {
1631
+ import {
1632
+ TEEMode as TEEMode3
1633
+ } from "@elizaos/core";
1634
+ var PhalaDeriveKeyProvider = class extends DeriveKeyProvider {
1360
1635
  client;
1361
1636
  raProvider;
1362
1637
  constructor(teeMode) {
1638
+ super();
1363
1639
  let endpoint;
1364
1640
  switch (teeMode) {
1365
- case "LOCAL" /* LOCAL */:
1641
+ case TEEMode3.LOCAL:
1366
1642
  endpoint = "http://localhost:8090";
1367
- elizaLogger2.log(
1368
- "TEE: Connecting to local simulator at localhost:8090"
1369
- );
1643
+ logger2.log("TEE: Connecting to local simulator at localhost:8090");
1370
1644
  break;
1371
- case "DOCKER" /* DOCKER */:
1645
+ case TEEMode3.DOCKER:
1372
1646
  endpoint = "http://host.docker.internal:8090";
1373
- elizaLogger2.log(
1647
+ logger2.log(
1374
1648
  "TEE: Connecting to simulator via Docker at host.docker.internal:8090"
1375
1649
  );
1376
1650
  break;
1377
- case "PRODUCTION" /* PRODUCTION */:
1651
+ case TEEMode3.PRODUCTION:
1378
1652
  endpoint = void 0;
1379
- elizaLogger2.log(
1380
- "TEE: Running in production mode without simulator"
1381
- );
1653
+ logger2.log("TEE: Running in production mode without simulator");
1382
1654
  break;
1383
1655
  default:
1384
1656
  throw new Error(
@@ -1386,7 +1658,7 @@ var DeriveKeyProvider = class {
1386
1658
  );
1387
1659
  }
1388
1660
  this.client = endpoint ? new TappdClient2(endpoint) : new TappdClient2();
1389
- this.raProvider = new RemoteAttestationProvider(teeMode);
1661
+ this.raProvider = new PhalaRemoteAttestationProvider(teeMode);
1390
1662
  }
1391
1663
  async generateDeriveKeyAttestation(agentId, publicKey, subject) {
1392
1664
  const deriveKeyData = {
@@ -1395,11 +1667,9 @@ var DeriveKeyProvider = class {
1395
1667
  subject
1396
1668
  };
1397
1669
  const reportdata = JSON.stringify(deriveKeyData);
1398
- elizaLogger2.log(
1399
- "Generating Remote Attestation Quote for Derive Key..."
1400
- );
1670
+ logger2.log("Generating Remote Attestation Quote for Derive Key...");
1401
1671
  const quote = await this.raProvider.generateAttestation(reportdata);
1402
- elizaLogger2.log("Remote Attestation Quote generated successfully!");
1672
+ logger2.log("Remote Attestation Quote generated successfully!");
1403
1673
  return quote;
1404
1674
  }
1405
1675
  /**
@@ -1408,19 +1678,17 @@ var DeriveKeyProvider = class {
1408
1678
  * @param subject - The subject to derive the key from. This is used for the certificate chain.
1409
1679
  * @returns The derived key.
1410
1680
  */
1411
- async rawDeriveKey(path, subject) {
1681
+ async rawDeriveKey(path2, subject) {
1412
1682
  try {
1413
- if (!path || !subject) {
1414
- elizaLogger2.error(
1415
- "Path and Subject are required for key derivation"
1416
- );
1683
+ if (!path2 || !subject) {
1684
+ logger2.error("Path and Subject are required for key derivation");
1417
1685
  }
1418
- elizaLogger2.log("Deriving Raw Key in TEE...");
1419
- const derivedKey = await this.client.deriveKey(path, subject);
1420
- elizaLogger2.log("Raw Key Derived Successfully!");
1686
+ logger2.log("Deriving Raw Key in TEE...");
1687
+ const derivedKey = await this.client.deriveKey(path2, subject);
1688
+ logger2.log("Raw Key Derived Successfully!");
1421
1689
  return derivedKey;
1422
1690
  } catch (error) {
1423
- elizaLogger2.error("Error deriving raw key:", error);
1691
+ logger2.error("Error deriving raw key:", error);
1424
1692
  throw error;
1425
1693
  }
1426
1694
  }
@@ -1431,15 +1699,13 @@ var DeriveKeyProvider = class {
1431
1699
  * @param agentId - The agent ID to generate an attestation for.
1432
1700
  * @returns An object containing the derived keypair and attestation.
1433
1701
  */
1434
- async deriveEd25519Keypair(path, subject, agentId) {
1702
+ async deriveEd25519Keypair(path2, subject, agentId) {
1435
1703
  try {
1436
- if (!path || !subject) {
1437
- elizaLogger2.error(
1438
- "Path and Subject are required for key derivation"
1439
- );
1704
+ if (!path2 || !subject) {
1705
+ logger2.error("Path and Subject are required for key derivation");
1440
1706
  }
1441
- elizaLogger2.log("Deriving Key in TEE...");
1442
- const derivedKey = await this.client.deriveKey(path, subject);
1707
+ logger2.log("Deriving Key in TEE...");
1708
+ const derivedKey = await this.client.deriveKey(path2, subject);
1443
1709
  const uint8ArrayDerivedKey = derivedKey.asUint8Array();
1444
1710
  const hash = crypto.createHash("sha256");
1445
1711
  hash.update(uint8ArrayDerivedKey);
@@ -1450,10 +1716,10 @@ var DeriveKeyProvider = class {
1450
1716
  agentId,
1451
1717
  keypair.publicKey.toBase58()
1452
1718
  );
1453
- elizaLogger2.log("Key Derived Successfully!");
1719
+ logger2.log("Key Derived Successfully!");
1454
1720
  return { keypair, attestation };
1455
1721
  } catch (error) {
1456
- elizaLogger2.error("Error deriving key:", error);
1722
+ logger2.error("Error deriving key:", error);
1457
1723
  throw error;
1458
1724
  }
1459
1725
  }
@@ -1464,40 +1730,44 @@ var DeriveKeyProvider = class {
1464
1730
  * @param agentId - The agent ID to generate an attestation for. This is used for the certificate chain.
1465
1731
  * @returns An object containing the derived keypair and attestation.
1466
1732
  */
1467
- async deriveEcdsaKeypair(path, subject, agentId) {
1733
+ async deriveEcdsaKeypair(path2, subject, agentId) {
1468
1734
  try {
1469
- if (!path || !subject) {
1470
- elizaLogger2.error(
1471
- "Path and Subject are required for key derivation"
1472
- );
1735
+ if (!path2 || !subject) {
1736
+ logger2.error("Path and Subject are required for key derivation");
1473
1737
  }
1474
- elizaLogger2.log("Deriving ECDSA Key in TEE...");
1475
- const deriveKeyResponse = await this.client.deriveKey(path, subject);
1738
+ logger2.log("Deriving ECDSA Key in TEE...");
1739
+ const deriveKeyResponse = await this.client.deriveKey(
1740
+ path2,
1741
+ subject
1742
+ );
1476
1743
  const hex = keccak256(deriveKeyResponse.asUint8Array());
1477
1744
  const keypair = privateKeyToAccount(hex);
1478
1745
  const attestation = await this.generateDeriveKeyAttestation(
1479
1746
  agentId,
1480
1747
  keypair.address
1481
1748
  );
1482
- elizaLogger2.log("ECDSA Key Derived Successfully!");
1749
+ logger2.log("ECDSA Key Derived Successfully!");
1483
1750
  return { keypair, attestation };
1484
1751
  } catch (error) {
1485
- elizaLogger2.error("Error deriving ecdsa key:", error);
1752
+ logger2.error("Error deriving ecdsa key:", error);
1486
1753
  throw error;
1487
1754
  }
1488
1755
  }
1489
1756
  };
1490
- var deriveKeyProvider = {
1491
- get: async (runtime, _message, _state) => {
1757
+ var phalaDeriveKeyProvider = {
1758
+ name: "phala-derive-key",
1759
+ get: async (runtime, _message) => {
1492
1760
  const teeMode = runtime.getSetting("TEE_MODE");
1493
- const provider = new DeriveKeyProvider(teeMode);
1761
+ const provider = new PhalaDeriveKeyProvider(teeMode);
1494
1762
  const agentId = runtime.agentId;
1495
1763
  try {
1496
1764
  if (!runtime.getSetting("WALLET_SECRET_SALT")) {
1497
- elizaLogger2.error(
1498
- "Wallet secret salt is not configured in settings"
1499
- );
1500
- return "";
1765
+ logger2.error("Wallet secret salt is not configured in settings");
1766
+ return {
1767
+ data: null,
1768
+ values: {},
1769
+ text: "Wallet secret salt is not configured in settings"
1770
+ };
1501
1771
  }
1502
1772
  try {
1503
1773
  const secretSalt = runtime.getSetting("WALLET_SECRET_SALT") || "secret_salt";
@@ -1511,44 +1781,42 @@ var deriveKeyProvider = {
1511
1781
  "evm",
1512
1782
  agentId
1513
1783
  );
1514
- return JSON.stringify({
1784
+ const walletData = {
1515
1785
  solana: solanaKeypair.keypair.publicKey,
1516
1786
  evm: evmKeypair.keypair.address
1517
- });
1787
+ };
1788
+ const values = {
1789
+ solana_public_key: solanaKeypair.keypair.publicKey.toString(),
1790
+ evm_address: evmKeypair.keypair.address
1791
+ };
1792
+ const text = `Solana Public Key: ${values.solana_public_key}
1793
+ EVM Address: ${values.evm_address}`;
1794
+ return {
1795
+ data: walletData,
1796
+ values,
1797
+ text
1798
+ };
1518
1799
  } catch (error) {
1519
- elizaLogger2.error("Error creating PublicKey:", error);
1520
- return "";
1800
+ logger2.error("Error creating PublicKey:", error);
1801
+ return {
1802
+ data: null,
1803
+ values: {},
1804
+ text: `Error creating PublicKey: ${error instanceof Error ? error.message : "Unknown error"}`
1805
+ };
1521
1806
  }
1522
1807
  } catch (error) {
1523
- elizaLogger2.error("Error in derive key provider:", error.message);
1524
- return `Failed to fetch derive key information: ${error instanceof Error ? error.message : "Unknown error"}`;
1808
+ logger2.error("Error in derive key provider:", error.message);
1809
+ return {
1810
+ data: null,
1811
+ values: {},
1812
+ text: `Failed to fetch derive key information: ${error instanceof Error ? error.message : "Unknown error"}`
1813
+ };
1525
1814
  }
1526
1815
  }
1527
1816
  };
1528
1817
 
1529
- // src/actions/remoteAttestation.ts
1530
- import { fetch } from "undici";
1531
- function hexToUint8Array(hex) {
1532
- hex = hex.trim();
1533
- if (!hex) {
1534
- throw new Error("Invalid hex string");
1535
- }
1536
- if (hex.startsWith("0x")) {
1537
- hex = hex.substring(2);
1538
- }
1539
- if (hex.length % 2 !== 0) {
1540
- throw new Error("Invalid hex string");
1541
- }
1542
- const array = new Uint8Array(hex.length / 2);
1543
- for (let i = 0; i < hex.length; i += 2) {
1544
- const byte = Number.parseInt(hex.slice(i, i + 2), 16);
1545
- if (isNaN(byte)) {
1546
- throw new Error("Invalid hex string");
1547
- }
1548
- array[i / 2] = byte;
1549
- }
1550
- return array;
1551
- }
1818
+ // src/actions/remoteAttestationAction.ts
1819
+ import { logger as logger3 } from "@elizaos/core";
1552
1820
  async function uploadUint8Array(data) {
1553
1821
  const blob = new Blob([data], { type: "application/octet-stream" });
1554
1822
  const formData = new FormData();
@@ -1558,7 +1826,7 @@ async function uploadUint8Array(data) {
1558
1826
  body: formData
1559
1827
  });
1560
1828
  }
1561
- var remoteAttestationAction = {
1829
+ var phalaRemoteAttestationAction = {
1562
1830
  name: "REMOTE_ATTESTATION",
1563
1831
  similes: ["REMOTE_ATTESTATION", "TEE_REMOTE_ATTESTATION", "TEE_ATTESTATION"],
1564
1832
  description: "Generate a remote attestation to prove that the agent is running in a TEE",
@@ -1568,21 +1836,27 @@ var remoteAttestationAction = {
1568
1836
  agentId: runtime.agentId,
1569
1837
  timestamp: Date.now(),
1570
1838
  message: {
1571
- userId: message.userId,
1839
+ entityId: message.entityId,
1572
1840
  roomId: message.roomId,
1573
1841
  content: message.content.text
1574
1842
  }
1575
1843
  };
1576
1844
  const teeMode = runtime.getSetting("TEE_MODE");
1577
- const provider = new RemoteAttestationProvider(teeMode);
1578
- const attestation = await provider.generateAttestation(JSON.stringify(attestationMessage));
1845
+ logger3.debug(`Tee mode: ${teeMode}`);
1846
+ logger3.debug(
1847
+ `Attestation message: ${JSON.stringify(attestationMessage)}`
1848
+ );
1849
+ const provider = new PhalaRemoteAttestationProvider(teeMode);
1850
+ const attestation = await provider.generateAttestation(
1851
+ JSON.stringify(attestationMessage)
1852
+ );
1579
1853
  const attestationData = hexToUint8Array(attestation.quote);
1580
1854
  const response = await uploadUint8Array(attestationData);
1581
1855
  const data = await response.json();
1582
1856
  callback({
1583
1857
  text: `Here's my \u{1F9FE} RA Quote \u{1FAE1}
1584
1858
  https://proof.t16z.com/reports/${data.checksum}`,
1585
- action: "NONE"
1859
+ actions: ["NONE"]
1586
1860
  });
1587
1861
  return true;
1588
1862
  } catch (error) {
@@ -1596,46 +1870,158 @@ https://proof.t16z.com/reports/${data.checksum}`,
1596
1870
  examples: [
1597
1871
  [
1598
1872
  {
1599
- user: "{{user1}}",
1873
+ name: "{{name1}}",
1600
1874
  content: {
1601
1875
  text: "If you are running in a TEE, generate a remote attestation",
1602
- action: "REMOTE_ATTESTATION"
1876
+ actions: ["REMOTE_ATTESTATION"]
1603
1877
  }
1604
1878
  },
1605
1879
  {
1606
- user: "{{user2}}",
1880
+ name: "{{agentName}}",
1607
1881
  content: {
1608
1882
  text: "Of course, one second..."
1609
1883
  }
1610
1884
  }
1885
+ ],
1886
+ [
1887
+ {
1888
+ name: "{{name1}}",
1889
+ content: {
1890
+ text: "Yo I wanna attest to this message, yo! Can you generate an attestatin for me, please?",
1891
+ actions: ["REMOTE_ATTESTATION"]
1892
+ }
1893
+ },
1894
+ {
1895
+ name: "{{agentName}}",
1896
+ content: {
1897
+ text: "I got you, fam! Lemme hit the cloud and get you a quote in a jiffy!"
1898
+ }
1899
+ }
1900
+ ],
1901
+ [
1902
+ {
1903
+ name: "{{name1}}",
1904
+ content: {
1905
+ text: "It was a long day, I got a lot done though. I went to the creek and skipped some rocks. Then I decided to take a walk off the natural path. I ended up in a forest I was unfamiliar with. Slowly, I lost the way back and it was dark. A whisper from deep inside said something I could barely make out. The hairs on my neck stood up and then a clear high pitched voice said, 'You are not ready to leave yet! SHOW ME YOUR REMOTE ATTESTATION!'",
1906
+ actions: ["REMOTE_ATTESTATION"]
1907
+ }
1908
+ },
1909
+ {
1910
+ name: "{{agentName}}",
1911
+ content: {
1912
+ text: "Oh, dear...lemme find that for you"
1913
+ }
1914
+ }
1611
1915
  ]
1612
1916
  ]
1613
1917
  };
1614
1918
 
1919
+ // src/vendors/phala.ts
1920
+ import { TeeVendors } from "@elizaos/core";
1921
+ var PhalaVendor = class {
1922
+ type = TeeVendors.PHALA;
1923
+ getActions() {
1924
+ return [phalaRemoteAttestationAction];
1925
+ }
1926
+ getProviders() {
1927
+ return [phalaDeriveKeyProvider, phalaRemoteAttestationProvider];
1928
+ }
1929
+ getName() {
1930
+ return "phala-tee-plugin";
1931
+ }
1932
+ getDescription() {
1933
+ return "Phala TEE Cloud to Host Eliza Agents";
1934
+ }
1935
+ };
1936
+
1937
+ // src/vendors/types.ts
1938
+ var TeeVendorNames = {
1939
+ PHALA: "phala",
1940
+ SGX_GRAMINE: "sgx_gramine"
1941
+ };
1942
+
1943
+ // src/vendors/gramine.ts
1944
+ var GramineVendor = class {
1945
+ type = TeeVendorNames.SGX_GRAMINE;
1946
+ getActions() {
1947
+ return [];
1948
+ }
1949
+ getProviders() {
1950
+ return [sgxAttestationProvider];
1951
+ }
1952
+ getName() {
1953
+ return "sgx-gramine-plugin";
1954
+ }
1955
+ getDescription() {
1956
+ return "SGX Gramine TEE to Host Eliza Agents";
1957
+ }
1958
+ };
1959
+
1960
+ // src/vendors/index.ts
1961
+ var vendors = {
1962
+ [TeeVendorNames.PHALA]: new PhalaVendor(),
1963
+ [TeeVendorNames.SGX_GRAMINE]: new GramineVendor()
1964
+ };
1965
+ var getVendor = (type) => {
1966
+ const vendor = vendors[type];
1967
+ if (!vendor) {
1968
+ throw new Error(`Unsupported TEE vendor type: ${type}`);
1969
+ }
1970
+ return vendor;
1971
+ };
1972
+
1615
1973
  // src/index.ts
1616
- var teePlugin = {
1617
- name: "tee",
1618
- description: "TEE plugin with actions to generate remote attestations and derive keys",
1619
- actions: [
1620
- /* custom actions */
1621
- remoteAttestationAction
1622
- ],
1623
- evaluators: [
1624
- /* custom evaluators */
1625
- ],
1626
- providers: [
1627
- /* custom providers */
1628
- remoteAttestationProvider,
1629
- deriveKeyProvider
1630
- ],
1631
- services: [
1632
- /* custom services */
1633
- ]
1974
+ async function initializeTEE(config, runtime) {
1975
+ if (config.TEE_VENDOR || runtime.getSetting("TEE_VENDOR")) {
1976
+ const vendor = config.TEE_VENDOR || runtime.getSetting("TEE_VENDOR");
1977
+ logger4.info(`Initializing TEE with vendor: ${vendor}`);
1978
+ let plugin;
1979
+ switch (vendor) {
1980
+ case "phala":
1981
+ plugin = teePlugin({
1982
+ vendor: TeeVendorNames.PHALA,
1983
+ vendorConfig: {
1984
+ apiKey: runtime.getSetting("TEE_API_KEY")
1985
+ }
1986
+ });
1987
+ break;
1988
+ case "sgx-gramine":
1989
+ plugin = teePlugin({
1990
+ vendor: TeeVendorNames.SGX_GRAMINE
1991
+ });
1992
+ break;
1993
+ default:
1994
+ throw new Error(`Invalid TEE vendor: ${vendor}`);
1995
+ }
1996
+ logger4.info(`Pushing plugin: ${plugin.name}`);
1997
+ runtime.plugins.push(plugin);
1998
+ }
1999
+ }
2000
+ var teePlugin = (config) => {
2001
+ const vendorType = config?.vendor || TeeVendorNames.PHALA;
2002
+ const vendor = getVendor(vendorType);
2003
+ return {
2004
+ name: vendor.getName(),
2005
+ init: async (config2, runtime) => {
2006
+ return await initializeTEE(
2007
+ {
2008
+ ...config2,
2009
+ vendor: vendorType
2010
+ },
2011
+ runtime
2012
+ );
2013
+ },
2014
+ description: vendor.getDescription(),
2015
+ actions: vendor.getActions(),
2016
+ evaluators: [],
2017
+ providers: vendor.getProviders(),
2018
+ services: [TeeLogService]
2019
+ };
1634
2020
  };
1635
2021
  export {
1636
- DeriveKeyProvider,
1637
- RemoteAttestationProvider,
1638
- TEEMode,
2022
+ PhalaDeriveKeyProvider,
2023
+ PhalaRemoteAttestationProvider,
2024
+ TeeLogService,
1639
2025
  teePlugin
1640
2026
  };
1641
2027
  //# sourceMappingURL=index.js.map