@elizaos/plugin-tee 2.0.0-alpha.3 → 2.0.0-alpha.4

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.
Files changed (45) hide show
  1. package/dist/index.js +9 -7
  2. package/dist/index.js.map +6 -6
  3. package/dist/node/actions/index.d.ts +2 -0
  4. package/dist/node/actions/index.d.ts.map +1 -0
  5. package/dist/node/actions/index.js +1 -0
  6. package/dist/node/actions/remoteAttestation.d.ts +3 -0
  7. package/dist/node/actions/remoteAttestation.d.ts.map +1 -0
  8. package/dist/node/actions/remoteAttestation.js +115 -0
  9. package/dist/node/index.d.ts +10 -0
  10. package/dist/node/index.d.ts.map +1 -0
  11. package/dist/node/index.js +34 -0
  12. package/dist/node/providers/base.d.ts +8 -0
  13. package/dist/node/providers/base.d.ts.map +1 -0
  14. package/dist/node/providers/base.js +4 -0
  15. package/dist/node/providers/deriveKey.d.ts +24 -0
  16. package/dist/node/providers/deriveKey.d.ts.map +1 -0
  17. package/dist/node/providers/deriveKey.js +143 -0
  18. package/dist/node/providers/index.d.ts +4 -0
  19. package/dist/node/providers/index.d.ts.map +1 -0
  20. package/dist/node/providers/index.js +3 -0
  21. package/dist/node/providers/remoteAttestation.d.ts +10 -0
  22. package/dist/node/providers/remoteAttestation.d.ts.map +1 -0
  23. package/dist/node/providers/remoteAttestation.js +73 -0
  24. package/dist/node/services/index.d.ts +2 -0
  25. package/dist/node/services/index.d.ts.map +1 -0
  26. package/dist/node/services/index.js +1 -0
  27. package/dist/node/services/tee.d.ts +24 -0
  28. package/dist/node/services/tee.d.ts.map +1 -0
  29. package/dist/node/services/tee.js +42 -0
  30. package/dist/node/types/index.d.ts +58 -0
  31. package/dist/node/types/index.d.ts.map +1 -0
  32. package/dist/node/types/index.js +35 -0
  33. package/dist/node/utils/index.d.ts +9 -0
  34. package/dist/node/utils/index.d.ts.map +1 -0
  35. package/dist/node/utils/index.js +61 -0
  36. package/dist/node/vendors/index.d.ts +5 -0
  37. package/dist/node/vendors/index.d.ts.map +1 -0
  38. package/dist/node/vendors/index.js +14 -0
  39. package/dist/node/vendors/phala.d.ts +10 -0
  40. package/dist/node/vendors/phala.d.ts.map +1 -0
  41. package/dist/node/vendors/phala.js +18 -0
  42. package/dist/node/vendors/types.d.ts +13 -0
  43. package/dist/node/vendors/types.d.ts.map +1 -0
  44. package/dist/node/vendors/types.js +3 -0
  45. package/package.json +2 -2
@@ -0,0 +1,2 @@
1
+ export { remoteAttestationAction } from "./remoteAttestation";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/actions/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1 @@
1
+ export { remoteAttestationAction } from "./remoteAttestation";
@@ -0,0 +1,3 @@
1
+ import type { Action } from "@elizaos/core";
2
+ export declare const remoteAttestationAction: Action;
3
+ //# sourceMappingURL=remoteAttestation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remoteAttestation.d.ts","sourceRoot":"","sources":["../../../src/actions/remoteAttestation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EAMP,MAAM,eAAe,CAAC;AAMvB,eAAO,MAAM,uBAAuB,EAAE,MAoIrC,CAAC"}
@@ -0,0 +1,115 @@
1
+ import { logger } from "@elizaos/core";
2
+ import { PhalaRemoteAttestationProvider } from "../providers/remoteAttestation";
3
+ import { hexToUint8Array, uploadAttestationQuote } from "../utils";
4
+ export const remoteAttestationAction = {
5
+ name: "REMOTE_ATTESTATION",
6
+ similes: [
7
+ "REMOTE_ATTESTATION",
8
+ "TEE_REMOTE_ATTESTATION",
9
+ "TEE_ATTESTATION",
10
+ "TEE_QUOTE",
11
+ "ATTESTATION",
12
+ "TEE_ATTESTATION_QUOTE",
13
+ "PROVE_TEE",
14
+ "VERIFY_TEE",
15
+ ],
16
+ description: "Generate a remote attestation to prove that the agent is running in a TEE (Trusted Execution Environment)",
17
+ validate: async (runtime) => {
18
+ const teeMode = runtime.getSetting("TEE_MODE");
19
+ if (!teeMode) {
20
+ logger.warn("REMOTE_ATTESTATION: TEE_MODE not configured");
21
+ return false;
22
+ }
23
+ return true;
24
+ },
25
+ handler: async (runtime, message, _state, _options, callback) => {
26
+ try {
27
+ const teeMode = runtime.getSetting("TEE_MODE");
28
+ if (!teeMode) {
29
+ logger.error("TEE_MODE is not configured");
30
+ callback?.({
31
+ text: "TEE_MODE is not configured. Cannot generate attestation.",
32
+ actions: ["NONE"],
33
+ });
34
+ return { success: false, error: "TEE_MODE is not configured" };
35
+ }
36
+ const attestationMessage = {
37
+ agentId: runtime.agentId,
38
+ timestamp: Date.now(),
39
+ message: {
40
+ entityId: message.entityId,
41
+ roomId: message.roomId,
42
+ content: message.content.text ?? "",
43
+ },
44
+ };
45
+ logger.debug(`Generating attestation for: ${JSON.stringify(attestationMessage)}`);
46
+ const provider = new PhalaRemoteAttestationProvider(String(teeMode));
47
+ const attestation = await provider.generateAttestation(JSON.stringify(attestationMessage));
48
+ const attestationData = hexToUint8Array(attestation.quote);
49
+ const uploadResult = await uploadAttestationQuote(attestationData);
50
+ const proofUrl = `https://proof.t16z.com/reports/${uploadResult.checksum}`;
51
+ logger.info(`Attestation uploaded: ${proofUrl}`);
52
+ callback?.({
53
+ text: `Remote attestation quote: ${proofUrl}`,
54
+ actions: ["NONE"],
55
+ });
56
+ return { success: true, text: `Attestation generated: ${proofUrl}` };
57
+ }
58
+ catch (error) {
59
+ const errorMessage = error instanceof Error ? error.message : String(error);
60
+ logger.error(`Failed to generate remote attestation: ${errorMessage}`);
61
+ callback?.({
62
+ text: `Failed to generate attestation: ${errorMessage}`,
63
+ actions: ["NONE"],
64
+ });
65
+ return { success: false, error: errorMessage };
66
+ }
67
+ },
68
+ examples: [
69
+ [
70
+ {
71
+ name: "{{name1}}",
72
+ content: {
73
+ text: "If you are running in a TEE, generate a remote attestation",
74
+ },
75
+ },
76
+ {
77
+ name: "{{agentName}}",
78
+ content: {
79
+ text: "Of course, one second...",
80
+ actions: ["REMOTE_ATTESTATION"],
81
+ },
82
+ },
83
+ ],
84
+ [
85
+ {
86
+ name: "{{name1}}",
87
+ content: {
88
+ text: "Can you prove you're running in a trusted execution environment?",
89
+ },
90
+ },
91
+ {
92
+ name: "{{agentName}}",
93
+ content: {
94
+ text: "Absolutely! Let me generate a TEE attestation quote for you.",
95
+ actions: ["REMOTE_ATTESTATION"],
96
+ },
97
+ },
98
+ ],
99
+ [
100
+ {
101
+ name: "{{name1}}",
102
+ content: {
103
+ text: "I need verification that this conversation is happening in a secure enclave",
104
+ },
105
+ },
106
+ {
107
+ name: "{{agentName}}",
108
+ content: {
109
+ text: "I'll generate a remote attestation to prove I'm running in a TEE.",
110
+ actions: ["REMOTE_ATTESTATION"],
111
+ },
112
+ },
113
+ ],
114
+ ],
115
+ };
@@ -0,0 +1,10 @@
1
+ import { type Plugin } from "@elizaos/core";
2
+ export { remoteAttestationAction } from "./actions";
3
+ export { DeriveKeyProvider, PhalaDeriveKeyProvider, PhalaRemoteAttestationProvider, phalaDeriveKeyProvider, phalaRemoteAttestationProvider, RemoteAttestationProvider, } from "./providers";
4
+ export { TEEService } from "./services";
5
+ export * from "./types";
6
+ export { calculateSHA256, getTeeEndpoint, hexToUint8Array, sha256Bytes, uint8ArrayToHex, uploadAttestationQuote, } from "./utils";
7
+ export { getVendor, PhalaVendor, type TeeVendorInterface, TeeVendorNames, } from "./vendors";
8
+ export declare const teePlugin: Plugin;
9
+ export default teePlugin;
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAA8B,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AAIxE,OAAO,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,8BAA8B,EAC9B,sBAAsB,EACtB,8BAA8B,EAC9B,yBAAyB,GAC1B,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,cAAc,SAAS,CAAC;AACxB,OAAO,EACL,eAAe,EACf,cAAc,EACd,eAAe,EACf,WAAW,EACX,eAAe,EACf,sBAAsB,GACvB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,SAAS,EACT,WAAW,EACX,KAAK,kBAAkB,EACvB,cAAc,GACf,MAAM,WAAW,CAAC;AAInB,eAAO,MAAM,SAAS,EAAE,MA6BvB,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { logger } from "@elizaos/core";
2
+ import { TEEService } from "./services/tee";
3
+ import { getVendor, TeeVendorNames } from "./vendors";
4
+ export { remoteAttestationAction } from "./actions";
5
+ export { DeriveKeyProvider, PhalaDeriveKeyProvider, PhalaRemoteAttestationProvider, phalaDeriveKeyProvider, phalaRemoteAttestationProvider, RemoteAttestationProvider, } from "./providers";
6
+ export { TEEService } from "./services";
7
+ export * from "./types";
8
+ export { calculateSHA256, getTeeEndpoint, hexToUint8Array, sha256Bytes, uint8ArrayToHex, uploadAttestationQuote, } from "./utils";
9
+ export { getVendor, PhalaVendor, TeeVendorNames, } from "./vendors";
10
+ const defaultVendor = getVendor(TeeVendorNames.PHALA);
11
+ export const teePlugin = {
12
+ name: "tee",
13
+ description: "TEE integration plugin for secure key management and remote attestation",
14
+ config: {
15
+ TEE_MODE: process.env.TEE_MODE ?? null,
16
+ TEE_VENDOR: process.env.TEE_VENDOR ?? null,
17
+ WALLET_SECRET_SALT: process.env.WALLET_SECRET_SALT ?? null,
18
+ },
19
+ async init(config, runtime) {
20
+ const vendorName = config.TEE_VENDOR ?? runtime.getSetting("TEE_VENDOR") ?? TeeVendorNames.PHALA;
21
+ const teeModeRaw = config.TEE_MODE ?? runtime.getSetting("TEE_MODE") ?? "LOCAL";
22
+ const teeMode = typeof teeModeRaw === "string" ? teeModeRaw : String(teeModeRaw);
23
+ logger.info(`Initializing TEE plugin with vendor: ${vendorName}, mode: ${teeMode}`);
24
+ if (!["LOCAL", "DOCKER", "PRODUCTION"].includes(teeMode.toUpperCase())) {
25
+ throw new Error(`Invalid TEE_MODE: ${teeMode}. Must be one of: LOCAL, DOCKER, PRODUCTION`);
26
+ }
27
+ logger.info(`TEE plugin initialized successfully`);
28
+ },
29
+ actions: defaultVendor.getActions(),
30
+ providers: defaultVendor.getProviders(),
31
+ services: [TEEService],
32
+ evaluators: [],
33
+ };
34
+ export default teePlugin;
@@ -0,0 +1,8 @@
1
+ import type { DeriveKeyResult, RemoteAttestationQuote, TdxQuoteHashAlgorithm } from "../types";
2
+ export declare abstract class DeriveKeyProvider {
3
+ abstract rawDeriveKey(path: string, subject: string): Promise<DeriveKeyResult>;
4
+ }
5
+ export declare abstract class RemoteAttestationProvider {
6
+ abstract generateAttestation(reportData: string, hashAlgorithm?: TdxQuoteHashAlgorithm): Promise<RemoteAttestationQuote>;
7
+ }
8
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../src/providers/base.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,sBAAsB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAE/F,8BAAsB,iBAAiB;IACrC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;CAC/E;AAED,8BAAsB,yBAAyB;IAC7C,QAAQ,CAAC,mBAAmB,CAC1B,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,qBAAqB,GACpC,OAAO,CAAC,sBAAsB,CAAC;CACnC"}
@@ -0,0 +1,4 @@
1
+ export class DeriveKeyProvider {
2
+ }
3
+ export class RemoteAttestationProvider {
4
+ }
@@ -0,0 +1,24 @@
1
+ import { type Provider } from "@elizaos/core";
2
+ import { type DeriveKeyResponse } from "@phala/dstack-sdk";
3
+ import { Keypair } from "@solana/web3.js";
4
+ import { type PrivateKeyAccount } from "viem/accounts";
5
+ import type { DeriveKeyResult, RemoteAttestationQuote } from "../types";
6
+ import { DeriveKeyProvider } from "./base";
7
+ export declare class PhalaDeriveKeyProvider extends DeriveKeyProvider {
8
+ private readonly client;
9
+ private readonly raProvider;
10
+ constructor(teeMode: string);
11
+ private generateDeriveKeyAttestation;
12
+ rawDeriveKey(path: string, subject: string): Promise<DeriveKeyResult>;
13
+ rawDeriveKeyResponse(path: string, subject: string): Promise<DeriveKeyResponse>;
14
+ deriveEd25519Keypair(path: string, subject: string, agentId: string): Promise<{
15
+ keypair: Keypair;
16
+ attestation: RemoteAttestationQuote;
17
+ }>;
18
+ deriveEcdsaKeypair(path: string, subject: string, agentId: string): Promise<{
19
+ keypair: PrivateKeyAccount;
20
+ attestation: RemoteAttestationQuote;
21
+ }>;
22
+ }
23
+ export declare const phalaDeriveKeyProvider: Provider;
24
+ //# sourceMappingURL=deriveKey.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deriveKey.d.ts","sourceRoot":"","sources":["../../../src/providers/deriveKey.ts"],"names":[],"mappings":"AACA,OAAO,EAA2C,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AACvF,OAAO,EAAE,KAAK,iBAAiB,EAAe,MAAM,mBAAmB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAE1C,OAAO,EAAE,KAAK,iBAAiB,EAAuB,MAAM,eAAe,CAAC;AAC5E,OAAO,KAAK,EAEV,eAAe,EACf,sBAAsB,EAEvB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAG3C,qBAAa,sBAAuB,SAAQ,iBAAiB;IAC3D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAiC;gBAEhD,OAAO,EAAE,MAAM;YAcb,4BAA4B;IAapC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC;IAkBrE,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAO/E,oBAAoB,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,sBAAsB,CAAA;KAAE,CAAC;IA6B/D,kBAAkB,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QACT,OAAO,EAAE,iBAAiB,CAAC;QAC3B,WAAW,EAAE,sBAAsB,CAAC;KACrC,CAAC;CAuBH;AAED,eAAO,MAAM,sBAAsB,EAAE,QA2DpC,CAAC"}
@@ -0,0 +1,143 @@
1
+ import crypto from "node:crypto";
2
+ import { logger } from "@elizaos/core";
3
+ import { TappdClient } from "@phala/dstack-sdk";
4
+ import { Keypair } from "@solana/web3.js";
5
+ import { keccak256 } from "viem";
6
+ import { privateKeyToAccount } from "viem/accounts";
7
+ import { getTeeEndpoint } from "../utils";
8
+ import { DeriveKeyProvider } from "./base";
9
+ import { PhalaRemoteAttestationProvider } from "./remoteAttestation";
10
+ export class PhalaDeriveKeyProvider extends DeriveKeyProvider {
11
+ client;
12
+ raProvider;
13
+ constructor(teeMode) {
14
+ super();
15
+ const endpoint = getTeeEndpoint(teeMode);
16
+ logger.info(endpoint
17
+ ? `TEE: Connecting to key derivation service at ${endpoint}`
18
+ : "TEE: Running key derivation in production mode");
19
+ this.client = endpoint ? new TappdClient(endpoint) : new TappdClient();
20
+ this.raProvider = new PhalaRemoteAttestationProvider(teeMode);
21
+ }
22
+ async generateDeriveKeyAttestation(agentId, publicKey, subject) {
23
+ const deriveKeyData = {
24
+ agentId,
25
+ publicKey,
26
+ subject,
27
+ };
28
+ return this.raProvider.generateAttestation(JSON.stringify(deriveKeyData));
29
+ }
30
+ async rawDeriveKey(path, subject) {
31
+ if (!path || !subject) {
32
+ throw new Error("Path and subject are required for key derivation");
33
+ }
34
+ try {
35
+ const response = await this.client.deriveKey(path, subject);
36
+ return {
37
+ key: response.asUint8Array(),
38
+ certificateChain: [],
39
+ };
40
+ }
41
+ catch (error) {
42
+ const message = error instanceof Error ? error.message : String(error);
43
+ logger.error(`Error deriving raw key: ${message}`);
44
+ throw error;
45
+ }
46
+ }
47
+ async rawDeriveKeyResponse(path, subject) {
48
+ if (!path || !subject) {
49
+ throw new Error("Path and subject are required for key derivation");
50
+ }
51
+ return this.client.deriveKey(path, subject);
52
+ }
53
+ async deriveEd25519Keypair(path, subject, agentId) {
54
+ if (!path || !subject) {
55
+ throw new Error("Path and subject are required for key derivation");
56
+ }
57
+ try {
58
+ const derivedKey = await this.client.deriveKey(path, subject);
59
+ const uint8ArrayDerivedKey = derivedKey.asUint8Array();
60
+ const hash = crypto.createHash("sha256");
61
+ hash.update(uint8ArrayDerivedKey);
62
+ const seed = new Uint8Array(hash.digest());
63
+ const keypair = Keypair.fromSeed(seed.slice(0, 32));
64
+ const attestation = await this.generateDeriveKeyAttestation(agentId, keypair.publicKey.toBase58(), subject);
65
+ return { keypair, attestation };
66
+ }
67
+ catch (error) {
68
+ const message = error instanceof Error ? error.message : String(error);
69
+ logger.error(`Error deriving Ed25519 key: ${message}`);
70
+ throw error;
71
+ }
72
+ }
73
+ async deriveEcdsaKeypair(path, subject, agentId) {
74
+ if (!path || !subject) {
75
+ throw new Error("Path and subject are required for key derivation");
76
+ }
77
+ try {
78
+ const derivedKey = await this.client.deriveKey(path, subject);
79
+ const hex = keccak256(derivedKey.asUint8Array());
80
+ const keypair = privateKeyToAccount(hex);
81
+ const attestation = await this.generateDeriveKeyAttestation(agentId, keypair.address, subject);
82
+ return { keypair, attestation };
83
+ }
84
+ catch (error) {
85
+ const message = error instanceof Error ? error.message : String(error);
86
+ logger.error(`Error deriving ECDSA key: ${message}`);
87
+ throw error;
88
+ }
89
+ }
90
+ }
91
+ export const phalaDeriveKeyProvider = {
92
+ name: "phala-derive-key",
93
+ get: async (runtime, _message) => {
94
+ const teeModeRaw = runtime.getSetting("TEE_MODE");
95
+ if (!teeModeRaw) {
96
+ return {
97
+ data: null,
98
+ values: {},
99
+ text: "TEE_MODE is not configured",
100
+ };
101
+ }
102
+ const teeMode = typeof teeModeRaw === "string" ? teeModeRaw : String(teeModeRaw);
103
+ const secretSaltRaw = runtime.getSetting("WALLET_SECRET_SALT");
104
+ if (!secretSaltRaw) {
105
+ logger.error("WALLET_SECRET_SALT is not configured");
106
+ return {
107
+ data: null,
108
+ values: {},
109
+ text: "WALLET_SECRET_SALT is not configured in settings",
110
+ };
111
+ }
112
+ const secretSalt = typeof secretSaltRaw === "string" ? secretSaltRaw : String(secretSaltRaw);
113
+ const provider = new PhalaDeriveKeyProvider(teeMode);
114
+ const agentId = runtime.agentId;
115
+ try {
116
+ const solanaKeypair = await provider.deriveEd25519Keypair(secretSalt, "solana", agentId);
117
+ const evmKeypair = await provider.deriveEcdsaKeypair(secretSalt, "evm", agentId);
118
+ const walletData = {
119
+ solana: solanaKeypair.keypair.publicKey.toBase58(),
120
+ evm: evmKeypair.keypair.address,
121
+ };
122
+ const values = {
123
+ solana_public_key: solanaKeypair.keypair.publicKey.toBase58(),
124
+ evm_address: evmKeypair.keypair.address,
125
+ };
126
+ const text = `Solana Public Key: ${values.solana_public_key}\nEVM Address: ${values.evm_address}`;
127
+ return {
128
+ data: walletData,
129
+ values,
130
+ text,
131
+ };
132
+ }
133
+ catch (error) {
134
+ const message = error instanceof Error ? error.message : String(error);
135
+ logger.error(`Error in derive key provider: ${message}`);
136
+ return {
137
+ data: null,
138
+ values: {},
139
+ text: `Failed to derive keys: ${message}`,
140
+ };
141
+ }
142
+ },
143
+ };
@@ -0,0 +1,4 @@
1
+ export { DeriveKeyProvider, RemoteAttestationProvider } from "./base";
2
+ export { PhalaDeriveKeyProvider, phalaDeriveKeyProvider } from "./deriveKey";
3
+ export { PhalaRemoteAttestationProvider, phalaRemoteAttestationProvider, } from "./remoteAttestation";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,MAAM,QAAQ,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC7E,OAAO,EACL,8BAA8B,EAC9B,8BAA8B,GAC/B,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { DeriveKeyProvider, RemoteAttestationProvider } from "./base";
2
+ export { PhalaDeriveKeyProvider, phalaDeriveKeyProvider } from "./deriveKey";
3
+ export { PhalaRemoteAttestationProvider, phalaRemoteAttestationProvider, } from "./remoteAttestation";
@@ -0,0 +1,10 @@
1
+ import { type Provider } from "@elizaos/core";
2
+ import type { RemoteAttestationQuote, TdxQuoteHashAlgorithm } from "../types";
3
+ import { RemoteAttestationProvider } from "./base";
4
+ export declare class PhalaRemoteAttestationProvider extends RemoteAttestationProvider {
5
+ private readonly client;
6
+ constructor(teeMode: string);
7
+ generateAttestation(reportData: string, hashAlgorithm?: TdxQuoteHashAlgorithm): Promise<RemoteAttestationQuote>;
8
+ }
9
+ export declare const phalaRemoteAttestationProvider: Provider;
10
+ //# sourceMappingURL=remoteAttestation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remoteAttestation.d.ts","sourceRoot":"","sources":["../../../src/providers/remoteAttestation.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2C,KAAK,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEvF,OAAO,KAAK,EAEV,sBAAsB,EACtB,qBAAqB,EAEtB,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,yBAAyB,EAAE,MAAM,QAAQ,CAAC;AAEnD,qBAAa,8BAA+B,SAAQ,yBAAyB;IAC3E,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;gBAEzB,OAAO,EAAE,MAAM;IAarB,mBAAmB,CACvB,UAAU,EAAE,MAAM,EAClB,aAAa,CAAC,EAAE,qBAAqB,GACpC,OAAO,CAAC,sBAAsB,CAAC;CAiBnC;AAED,eAAO,MAAM,8BAA8B,EAAE,QA+C5C,CAAC"}
@@ -0,0 +1,73 @@
1
+ import { logger } from "@elizaos/core";
2
+ import { TappdClient } from "@phala/dstack-sdk";
3
+ import { getTeeEndpoint } from "../utils";
4
+ import { RemoteAttestationProvider } from "./base";
5
+ export class PhalaRemoteAttestationProvider extends RemoteAttestationProvider {
6
+ client;
7
+ constructor(teeMode) {
8
+ super();
9
+ const endpoint = getTeeEndpoint(teeMode);
10
+ logger.info(endpoint
11
+ ? `TEE: Connecting to simulator at ${endpoint}`
12
+ : "TEE: Running in production mode without simulator");
13
+ this.client = endpoint ? new TappdClient(endpoint) : new TappdClient();
14
+ }
15
+ async generateAttestation(reportData, hashAlgorithm) {
16
+ try {
17
+ const tdxQuote = await this.client.tdxQuote(reportData, hashAlgorithm);
18
+ return {
19
+ quote: tdxQuote.quote,
20
+ timestamp: Date.now(),
21
+ };
22
+ }
23
+ catch (error) {
24
+ const message = error instanceof Error ? error.message : String(error);
25
+ logger.error(`Error generating remote attestation: ${message}`);
26
+ throw new Error(`Failed to generate TDX Quote: ${message}`);
27
+ }
28
+ }
29
+ }
30
+ export const phalaRemoteAttestationProvider = {
31
+ name: "phala-remote-attestation",
32
+ get: async (runtime, message) => {
33
+ const teeModeRaw = runtime.getSetting("TEE_MODE");
34
+ if (!teeModeRaw) {
35
+ return {
36
+ data: null,
37
+ values: {},
38
+ text: "TEE_MODE is not configured",
39
+ };
40
+ }
41
+ const teeMode = typeof teeModeRaw === "string" ? teeModeRaw : String(teeModeRaw);
42
+ const provider = new PhalaRemoteAttestationProvider(teeMode);
43
+ const agentId = runtime.agentId;
44
+ try {
45
+ const attestationMessage = {
46
+ agentId,
47
+ timestamp: Date.now(),
48
+ message: {
49
+ entityId: message.entityId,
50
+ roomId: message.roomId,
51
+ content: message.content.text ?? "",
52
+ },
53
+ };
54
+ const attestation = await provider.generateAttestation(JSON.stringify(attestationMessage));
55
+ return {
56
+ data: {
57
+ quote: attestation.quote,
58
+ timestamp: attestation.timestamp.toString(),
59
+ },
60
+ values: {
61
+ quote: attestation.quote,
62
+ timestamp: attestation.timestamp.toString(),
63
+ },
64
+ text: `Remote attestation: ${attestation.quote.substring(0, 64)}...`,
65
+ };
66
+ }
67
+ catch (error) {
68
+ const message = error instanceof Error ? error.message : String(error);
69
+ logger.error(`Error in remote attestation provider: ${message}`);
70
+ throw new Error(`Failed to generate TDX Quote: ${message}`);
71
+ }
72
+ },
73
+ };
@@ -0,0 +1,2 @@
1
+ export { TEEService } from "./tee";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC"}
@@ -0,0 +1 @@
1
+ export { TEEService } from "./tee";
@@ -0,0 +1,24 @@
1
+ import { type IAgentRuntime, type Metadata, Service, type UUID } from "@elizaos/core";
2
+ import type { DeriveKeyResponse } from "@phala/dstack-sdk";
3
+ import type { Keypair } from "@solana/web3.js";
4
+ import type { PrivateKeyAccount } from "viem";
5
+ import type { RemoteAttestationQuote, TeeServiceConfig } from "../types";
6
+ export declare class TEEService extends Service {
7
+ private provider;
8
+ static serviceType: "tee";
9
+ capabilityDescription: string;
10
+ config?: Metadata;
11
+ constructor(runtime: IAgentRuntime, config?: Partial<TeeServiceConfig>);
12
+ static start(runtime: IAgentRuntime): Promise<TEEService>;
13
+ stop(): Promise<void>;
14
+ deriveEcdsaKeypair(path: string, subject: string, agentId: UUID): Promise<{
15
+ keypair: PrivateKeyAccount;
16
+ attestation: RemoteAttestationQuote;
17
+ }>;
18
+ deriveEd25519Keypair(path: string, subject: string, agentId: UUID): Promise<{
19
+ keypair: Keypair;
20
+ attestation: RemoteAttestationQuote;
21
+ }>;
22
+ rawDeriveKey(path: string, subject: string): Promise<DeriveKeyResponse>;
23
+ }
24
+ //# sourceMappingURL=tee.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tee.d.ts","sourceRoot":"","sources":["../../../src/services/tee.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,aAAa,EAElB,KAAK,QAAQ,EACb,OAAO,EAEP,KAAK,IAAI,EACV,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC/C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAE9C,OAAO,KAAK,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAGzE,qBAAa,UAAW,SAAQ,OAAO;IACrC,OAAO,CAAC,QAAQ,CAAyB;IACzC,MAAM,CAAC,WAAW,QAAmB;IAC9B,qBAAqB,SAA6D;IAC1E,MAAM,CAAC,EAAE,QAAQ,CAAC;gBAErB,OAAO,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC;WAmBzD,KAAK,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;IAQzD,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,kBAAkB,CACtB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,IAAI,GACZ,OAAO,CAAC;QACT,OAAO,EAAE,iBAAiB,CAAC;QAC3B,WAAW,EAAE,sBAAsB,CAAC;KACrC,CAAC;IAII,oBAAoB,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,IAAI,GACZ,OAAO,CAAC;QACT,OAAO,EAAE,OAAO,CAAC;QACjB,WAAW,EAAE,sBAAsB,CAAC;KACrC,CAAC;IAII,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAG9E"}
@@ -0,0 +1,42 @@
1
+ import { logger, Service, ServiceType, } from "@elizaos/core";
2
+ import { PhalaDeriveKeyProvider } from "../providers/deriveKey";
3
+ import { TeeMode, TeeVendor } from "../types";
4
+ export class TEEService extends Service {
5
+ provider;
6
+ static serviceType = ServiceType.TEE;
7
+ capabilityDescription = "Trusted Execution Environment for secure key management";
8
+ constructor(runtime, config) {
9
+ super(runtime);
10
+ const teeModeRaw = config?.mode ?? runtime.getSetting("TEE_MODE") ?? TeeMode.LOCAL;
11
+ const teeMode = typeof teeModeRaw === "string" ? teeModeRaw : TeeMode.LOCAL;
12
+ const vendor = config?.vendor ?? TeeVendor.PHALA;
13
+ const secretSaltRaw = config?.secretSalt ?? runtime.getSetting("WALLET_SECRET_SALT");
14
+ const secretSalt = typeof secretSaltRaw === "string" ? secretSaltRaw : undefined;
15
+ // Set config as Metadata-compatible object
16
+ this.config = {
17
+ mode: teeMode,
18
+ vendor,
19
+ ...(secretSalt ? { secretSalt } : {}),
20
+ };
21
+ this.provider = new PhalaDeriveKeyProvider(teeMode);
22
+ }
23
+ static async start(runtime) {
24
+ const teeModeRaw = runtime.getSetting("TEE_MODE") ?? TeeMode.LOCAL;
25
+ const teeMode = typeof teeModeRaw === "string" ? teeModeRaw : TeeMode.LOCAL;
26
+ logger.info(`Starting TEE service with mode: ${teeMode}`);
27
+ const service = new TEEService(runtime, { mode: teeMode });
28
+ return service;
29
+ }
30
+ async stop() {
31
+ logger.info("Stopping TEE service");
32
+ }
33
+ async deriveEcdsaKeypair(path, subject, agentId) {
34
+ return this.provider.deriveEcdsaKeypair(path, subject, agentId);
35
+ }
36
+ async deriveEd25519Keypair(path, subject, agentId) {
37
+ return this.provider.deriveEd25519Keypair(path, subject, agentId);
38
+ }
39
+ async rawDeriveKey(path, subject) {
40
+ return this.provider.rawDeriveKeyResponse(path, subject);
41
+ }
42
+ }
@@ -0,0 +1,58 @@
1
+ export declare enum TeeMode {
2
+ LOCAL = "LOCAL",
3
+ DOCKER = "DOCKER",
4
+ PRODUCTION = "PRODUCTION"
5
+ }
6
+ export declare enum TeeVendor {
7
+ PHALA = "phala"
8
+ }
9
+ export declare enum TeeType {
10
+ SGX_GRAMINE = "sgx_gramine",
11
+ TDX_DSTACK = "tdx_dstack"
12
+ }
13
+ export interface RemoteAttestationQuote {
14
+ readonly quote: string;
15
+ readonly timestamp: number;
16
+ }
17
+ export interface DeriveKeyAttestationData {
18
+ readonly agentId: string;
19
+ readonly publicKey: string;
20
+ readonly subject?: string;
21
+ }
22
+ export interface RemoteAttestationMessage {
23
+ readonly agentId: string;
24
+ readonly timestamp: number;
25
+ readonly message: {
26
+ readonly entityId: string;
27
+ readonly roomId: string;
28
+ readonly content: string;
29
+ };
30
+ }
31
+ export interface DeriveKeyResult {
32
+ readonly key: Uint8Array;
33
+ readonly certificateChain: string[];
34
+ }
35
+ export interface Ed25519KeypairResult {
36
+ readonly publicKey: string;
37
+ readonly secretKey: Uint8Array;
38
+ readonly attestation: RemoteAttestationQuote;
39
+ }
40
+ export interface EcdsaKeypairResult {
41
+ readonly address: string;
42
+ readonly privateKey: Uint8Array;
43
+ readonly attestation: RemoteAttestationQuote;
44
+ }
45
+ export interface TeeServiceConfig {
46
+ readonly mode: TeeMode;
47
+ readonly vendor: TeeVendor;
48
+ readonly secretSalt?: string;
49
+ }
50
+ export interface TeeProviderResult {
51
+ readonly data: Record<string, string> | null;
52
+ readonly values: Record<string, string>;
53
+ readonly text: string;
54
+ }
55
+ export type TdxQuoteHashAlgorithm = "sha256" | "sha384" | "sha512" | "raw";
56
+ export declare function parseTeeMode(mode: string): TeeMode;
57
+ export declare function parseTeeVendor(vendor: string): TeeVendor;
58
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/types/index.ts"],"names":[],"mappings":"AAAA,oBAAY,OAAO;IACjB,KAAK,UAAU;IACf,MAAM,WAAW;IACjB,UAAU,eAAe;CAC1B;AAED,oBAAY,SAAS;IACnB,KAAK,UAAU;CAChB;AAED,oBAAY,OAAO;IACjB,WAAW,gBAAgB;IAC3B,UAAU,eAAe;CAC1B;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE;QAChB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;QACxB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,CAAC;CACH;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,GAAG,EAAE,UAAU,CAAC;IACzB,QAAQ,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAC;IAC/B,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;CAC9C;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC;CAC9C;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,qBAAqB,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE3E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAWlD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAOxD"}