@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/README.md +97 -191
- package/dist/{_esm-FVHF6KDD.js → _esm-L4OBJJWB.js} +5 -5
- package/dist/_esm-L4OBJJWB.js.map +1 -0
- package/dist/{ccip-MMGH6DXX.js → ccip-BIZHB2Z3.js} +3 -2
- package/dist/{chunk-NTU6R7BC.js → chunk-4HQ7LDIJ.js} +137 -191
- package/dist/chunk-4HQ7LDIJ.js.map +1 -0
- package/dist/chunk-672HY72Z.js +139 -0
- package/dist/chunk-672HY72Z.js.map +1 -0
- package/dist/{chunk-4L6P6TY5.js → chunk-LCSUOOZR.js} +54 -134
- package/dist/chunk-LCSUOOZR.js.map +1 -0
- package/dist/index.d.ts +67 -14
- package/dist/index.js +785 -399
- package/dist/index.js.map +1 -1
- package/dist/{secp256k1-QUTB2QC2.js → secp256k1-ARCYQQLX.js} +3 -2
- package/package.json +16 -30
- package/tsup.config.ts +28 -0
- package/dist/_esm-FVHF6KDD.js.map +0 -1
- package/dist/chunk-4L6P6TY5.js.map +0 -1
- package/dist/chunk-NTU6R7BC.js.map +0 -1
- /package/dist/{ccip-MMGH6DXX.js.map → ccip-BIZHB2Z3.js.map} +0 -0
- /package/dist/{secp256k1-QUTB2QC2.js.map → secp256k1-ARCYQQLX.js.map} +0 -0
package/dist/index.js
CHANGED
|
@@ -1,26 +1,23 @@
|
|
|
1
1
|
import {
|
|
2
|
-
secp256k1
|
|
3
|
-
|
|
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
|
-
|
|
44
|
-
|
|
37
|
+
trim
|
|
38
|
+
} from "./chunk-4HQ7LDIJ.js";
|
|
39
|
+
import "./chunk-672HY72Z.js";
|
|
45
40
|
import "./chunk-PR4QN5HX.js";
|
|
46
41
|
|
|
47
|
-
// src/
|
|
42
|
+
// src/index.ts
|
|
43
|
+
import {
|
|
44
|
+
logger as logger4
|
|
45
|
+
} from "@elizaos/core";
|
|
46
|
+
|
|
47
|
+
// src/services/teeLogService.ts
|
|
48
48
|
import {
|
|
49
|
-
|
|
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
|
|
54
|
-
var
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
|
265
|
+
case TEEMode.LOCAL:
|
|
69
266
|
endpoint = "http://localhost:8090";
|
|
70
|
-
|
|
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
|
|
269
|
+
case TEEMode.DOCKER:
|
|
75
270
|
endpoint = "http://host.docker.internal:8090";
|
|
76
|
-
|
|
271
|
+
logger.log(
|
|
77
272
|
"TEE: Connecting to simulator via Docker at host.docker.internal:8090"
|
|
78
273
|
);
|
|
79
274
|
break;
|
|
80
|
-
case
|
|
275
|
+
case TEEMode.PRODUCTION:
|
|
81
276
|
endpoint = void 0;
|
|
82
|
-
|
|
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
|
-
|
|
96
|
-
const tdxQuote = await this.client.tdxQuote(
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
119
|
-
|
|
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
|
|
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
|
-
|
|
325
|
+
entityId: message.entityId,
|
|
129
326
|
roomId: message.roomId,
|
|
130
327
|
content: message.content.text
|
|
131
328
|
}
|
|
132
329
|
};
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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/
|
|
429
|
+
// src/services/teeLogManager.ts
|
|
146
430
|
import {
|
|
147
|
-
|
|
431
|
+
TeeType
|
|
148
432
|
} from "@elizaos/core";
|
|
149
|
-
import
|
|
150
|
-
import crypto from "crypto";
|
|
151
|
-
import { TappdClient as TappdClient2 } from "@phala/dstack-sdk";
|
|
433
|
+
import elliptic from "elliptic";
|
|
152
434
|
|
|
153
|
-
// ../../node_modules/
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
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.
|
|
204
|
-
|
|
205
|
-
|
|
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
|
-
|
|
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
|
-
//
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
this.
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
this.
|
|
342
|
-
|
|
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
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
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
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
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
|
-
|
|
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 }) ?
|
|
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
|
-
|
|
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
|
|
1641
|
+
case TEEMode3.LOCAL:
|
|
1366
1642
|
endpoint = "http://localhost:8090";
|
|
1367
|
-
|
|
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
|
|
1645
|
+
case TEEMode3.DOCKER:
|
|
1372
1646
|
endpoint = "http://host.docker.internal:8090";
|
|
1373
|
-
|
|
1647
|
+
logger2.log(
|
|
1374
1648
|
"TEE: Connecting to simulator via Docker at host.docker.internal:8090"
|
|
1375
1649
|
);
|
|
1376
1650
|
break;
|
|
1377
|
-
case
|
|
1651
|
+
case TEEMode3.PRODUCTION:
|
|
1378
1652
|
endpoint = void 0;
|
|
1379
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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(
|
|
1681
|
+
async rawDeriveKey(path2, subject) {
|
|
1412
1682
|
try {
|
|
1413
|
-
if (!
|
|
1414
|
-
|
|
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
|
-
|
|
1419
|
-
const derivedKey = await this.client.deriveKey(
|
|
1420
|
-
|
|
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
|
-
|
|
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(
|
|
1702
|
+
async deriveEd25519Keypair(path2, subject, agentId) {
|
|
1435
1703
|
try {
|
|
1436
|
-
if (!
|
|
1437
|
-
|
|
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
|
-
|
|
1442
|
-
const derivedKey = await this.client.deriveKey(
|
|
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
|
-
|
|
1719
|
+
logger2.log("Key Derived Successfully!");
|
|
1454
1720
|
return { keypair, attestation };
|
|
1455
1721
|
} catch (error) {
|
|
1456
|
-
|
|
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(
|
|
1733
|
+
async deriveEcdsaKeypair(path2, subject, agentId) {
|
|
1468
1734
|
try {
|
|
1469
|
-
if (!
|
|
1470
|
-
|
|
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
|
-
|
|
1475
|
-
const deriveKeyResponse = await this.client.deriveKey(
|
|
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
|
-
|
|
1749
|
+
logger2.log("ECDSA Key Derived Successfully!");
|
|
1483
1750
|
return { keypair, attestation };
|
|
1484
1751
|
} catch (error) {
|
|
1485
|
-
|
|
1752
|
+
logger2.error("Error deriving ecdsa key:", error);
|
|
1486
1753
|
throw error;
|
|
1487
1754
|
}
|
|
1488
1755
|
}
|
|
1489
1756
|
};
|
|
1490
|
-
var
|
|
1491
|
-
|
|
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
|
|
1761
|
+
const provider = new PhalaDeriveKeyProvider(teeMode);
|
|
1494
1762
|
const agentId = runtime.agentId;
|
|
1495
1763
|
try {
|
|
1496
1764
|
if (!runtime.getSetting("WALLET_SECRET_SALT")) {
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1524
|
-
return
|
|
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/
|
|
1530
|
-
import {
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
1578
|
-
|
|
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
|
-
|
|
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
|
-
|
|
1873
|
+
name: "{{name1}}",
|
|
1600
1874
|
content: {
|
|
1601
1875
|
text: "If you are running in a TEE, generate a remote attestation",
|
|
1602
|
-
|
|
1876
|
+
actions: ["REMOTE_ATTESTATION"]
|
|
1603
1877
|
}
|
|
1604
1878
|
},
|
|
1605
1879
|
{
|
|
1606
|
-
|
|
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
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
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
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
2022
|
+
PhalaDeriveKeyProvider,
|
|
2023
|
+
PhalaRemoteAttestationProvider,
|
|
2024
|
+
TeeLogService,
|
|
1639
2025
|
teePlugin
|
|
1640
2026
|
};
|
|
1641
2027
|
//# sourceMappingURL=index.js.map
|