@flarestudio/fcc-workbench 1.0.2 ā 1.0.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.
- package/dist/index.js +125 -73
- package/dist/index.js.map +1 -1
- package/dist/modules/config.d.ts +28 -0
- package/dist/modules/config.js +56 -0
- package/dist/modules/config.js.map +1 -0
- package/dist/modules/contract.d.ts +102 -0
- package/dist/modules/contract.js +127 -0
- package/dist/modules/contract.js.map +1 -0
- package/dist/modules/docker.d.ts +23 -0
- package/dist/modules/docker.js +78 -0
- package/dist/modules/docker.js.map +1 -0
- package/dist/modules/registry.d.ts +23 -0
- package/dist/modules/registry.js +170 -0
- package/dist/modules/registry.js.map +1 -0
- package/dist/modules/scaffold.js +1 -0
- package/dist/modules/scaffold.js.map +1 -1
- package/dist/modules/tee.d.ts +15 -0
- package/dist/modules/tee.js +131 -0
- package/dist/modules/tee.js.map +1 -0
- package/dist/templates/index.d.ts +1 -0
- package/dist/templates/index.js +54 -3
- package/dist/templates/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,18 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import { select, input } from '@inquirer/prompts';
|
|
4
|
+
import { select, input, confirm } from '@inquirer/prompts';
|
|
5
|
+
import * as config from './modules/config.js';
|
|
5
6
|
import * as scaffold from './modules/scaffold.js';
|
|
6
7
|
import * as crypto from './modules/crypto.js';
|
|
7
|
-
import * as
|
|
8
|
+
import * as contract from './modules/contract.js';
|
|
9
|
+
import * as registry from './modules/registry.js';
|
|
10
|
+
import * as docker from './modules/docker.js';
|
|
11
|
+
import * as tee from './modules/tee.js';
|
|
8
12
|
const program = new Command();
|
|
9
13
|
program
|
|
10
14
|
.name('flare-fcc')
|
|
11
15
|
.description('Tactical Workbench for Flare Confidential Compute (FCC)')
|
|
12
|
-
.version('1.0.
|
|
16
|
+
.version('1.0.3');
|
|
17
|
+
// --- 1. SCAFFOLDING & SETUP ---
|
|
13
18
|
program
|
|
14
19
|
.command('init')
|
|
15
|
-
.description('Scaffold a new Sovereign AI Agent
|
|
20
|
+
.description('Step 0: Scaffold a new Sovereign AI Agent')
|
|
16
21
|
.action(async () => {
|
|
17
22
|
console.log(chalk.magenta.bold('\nš» FLARE GHOST: AGENT SEEDER\n'));
|
|
18
23
|
const name = await input({ message: 'Agent Name:', default: 'my-fcc-agent' });
|
|
@@ -20,99 +25,146 @@ program
|
|
|
20
25
|
message: 'Choose your Agent Brain (Language):',
|
|
21
26
|
choices: [
|
|
22
27
|
{ name: 'TypeScript (Node.js)', value: 'typescript' },
|
|
23
|
-
{ name: 'Python', value: 'python' },
|
|
24
|
-
{ name: 'Go', value: 'go' }
|
|
28
|
+
{ name: 'Python (Flask)', value: 'python' },
|
|
29
|
+
{ name: 'Go (Standard)', value: 'go' }
|
|
25
30
|
]
|
|
26
31
|
});
|
|
27
32
|
await scaffold.createAgent(name, language);
|
|
28
33
|
});
|
|
29
34
|
program
|
|
30
|
-
.command('
|
|
31
|
-
.description('
|
|
35
|
+
.command('setup')
|
|
36
|
+
.description('Step 0.5: Setup environment and proxy configuration')
|
|
32
37
|
.action(async () => {
|
|
33
|
-
console.log(chalk.
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
38
|
+
console.log(chalk.cyan.bold('\nāļø ENVIRONMENT CONFIGURATION\n'));
|
|
39
|
+
const pkey = await input({ message: 'Your EVM Private Key (Hex):' });
|
|
40
|
+
config.writeEnv({ PRIVATE_KEY: pkey, INITIAL_OWNER: contract.getAddressFromKey(pkey) });
|
|
41
|
+
console.log(chalk.gray('\nFlare Indexer Database Credentials (for ext-proxy):'));
|
|
42
|
+
const dbHost = await input({ message: 'DB Host:', default: 'indexer-db.test.flare.network' });
|
|
43
|
+
const dbPort = await input({ message: 'DB Port:', default: '3306' });
|
|
44
|
+
const dbUser = await input({ message: 'DB User:' });
|
|
45
|
+
const dbPass = await input({ message: 'DB Password:' });
|
|
46
|
+
config.writeProxyToml({ dbHost, dbPort, dbUser, dbPass });
|
|
47
|
+
console.log(chalk.green('\nā Setup complete!'));
|
|
48
|
+
});
|
|
49
|
+
// --- 2. DEPLOYMENT & REGISTRATION ---
|
|
50
|
+
program
|
|
51
|
+
.command('deploy')
|
|
52
|
+
.description('Step 1: Deploy InstructionSender to Coston2')
|
|
53
|
+
.action(async () => {
|
|
54
|
+
console.log(chalk.blue.bold('\nš DEPLOY INSTRUCTION SENDER\n'));
|
|
55
|
+
const env = config.loadEnv();
|
|
56
|
+
if (!env.PRIVATE_KEY)
|
|
57
|
+
throw new Error('Run "flare-fcc setup" first.');
|
|
58
|
+
const address = await contract.deployInstructionSender(env.PRIVATE_KEY);
|
|
59
|
+
config.writeEnv({ INSTRUCTION_SENDER: address });
|
|
60
|
+
console.log(chalk.green('\nā Contract Deployed:'), address);
|
|
61
|
+
});
|
|
62
|
+
program
|
|
63
|
+
.command('register-ext')
|
|
64
|
+
.description('Step 2: Register extension on-chain')
|
|
65
|
+
.action(async () => {
|
|
66
|
+
console.log(chalk.blue.bold('\nš REGISTER EXTENSION\n'));
|
|
67
|
+
const env = config.loadEnv();
|
|
68
|
+
if (!env.PRIVATE_KEY || !env.INSTRUCTION_SENDER || !env.INITIAL_OWNER) {
|
|
69
|
+
throw new Error('Missing environment vars. Run setup and deploy first.');
|
|
44
70
|
}
|
|
71
|
+
const id = await registry.registerExtension({
|
|
72
|
+
privateKey: env.PRIVATE_KEY,
|
|
73
|
+
instructionSender: env.INSTRUCTION_SENDER
|
|
74
|
+
});
|
|
75
|
+
config.writeEnv({ EXTENSION_ID: id });
|
|
76
|
+
console.log(chalk.green('\nā Extension Registered! ID:'), id);
|
|
77
|
+
});
|
|
78
|
+
// --- 3. DOCKER & TEE MANAGEMENT ---
|
|
79
|
+
program
|
|
80
|
+
.command('start')
|
|
81
|
+
.description('Step 3: Start the local Docker stack')
|
|
82
|
+
.action(async () => {
|
|
83
|
+
console.log(chalk.yellow.bold('\nš³ STARTING TEE STACK\n'));
|
|
84
|
+
await docker.runDockerCompose(['up', '-d']);
|
|
85
|
+
console.log(chalk.green('\nā Stack started in background.'));
|
|
86
|
+
console.log(chalk.gray(' Use "docker compose logs -f" to view logs.'));
|
|
87
|
+
});
|
|
88
|
+
program
|
|
89
|
+
.command('tunnel')
|
|
90
|
+
.description('Step 4: Launch Cloudflared tunnel for the TEE')
|
|
91
|
+
.action(async () => {
|
|
92
|
+
console.log(chalk.cyan.bold('\nš CLOUDFLARED TUNNEL\n'));
|
|
93
|
+
tee.startTunnel(6676, (url) => {
|
|
94
|
+
console.log(chalk.green(`\nā Tunnel active at: ${url}`));
|
|
95
|
+
config.writeEnv({ TUNNEL_URL: url });
|
|
96
|
+
console.log(chalk.gray('Press Ctrl+C to close.'));
|
|
97
|
+
}, (err) => console.error(chalk.red('\nā Error:'), err));
|
|
98
|
+
});
|
|
99
|
+
program
|
|
100
|
+
.command('allow-tee')
|
|
101
|
+
.description('Step 5: Allow TEE version on-chain')
|
|
102
|
+
.action(async () => {
|
|
103
|
+
console.log(chalk.blue.bold('\nā
ALLOW TEE VERSION\n'));
|
|
104
|
+
const env = config.loadEnv();
|
|
105
|
+
if (!env.PRIVATE_KEY || !env.EXTENSION_ID)
|
|
106
|
+
throw new Error('Missing environment vars.');
|
|
107
|
+
const info = await docker.fetchProxyInfo();
|
|
108
|
+
await registry.allowTeeVersion(env.PRIVATE_KEY, env.EXTENSION_ID, info.platform, info.codeHash);
|
|
109
|
+
console.log(chalk.green('\nā TEE Version Allowed.'));
|
|
45
110
|
});
|
|
46
111
|
program
|
|
47
|
-
.command('
|
|
48
|
-
.description('
|
|
112
|
+
.command('register-tee')
|
|
113
|
+
.description('Step 6: Register TEE machine on-chain (local mode)')
|
|
49
114
|
.action(async () => {
|
|
50
|
-
console.log(chalk.
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
if (isValid) {
|
|
55
|
-
console.log(chalk.green.bold('\nā HARDWARE VERIFIED: GENUINE SECURE ENCLAVE'));
|
|
115
|
+
console.log(chalk.blue.bold('\nš» REGISTER TEE MACHINE\n'));
|
|
116
|
+
const env = config.loadEnv();
|
|
117
|
+
if (!env.PRIVATE_KEY || !env.EXTENSION_ID || !env.TUNNEL_URL) {
|
|
118
|
+
throw new Error('Missing environment vars or tunnel URL.');
|
|
56
119
|
}
|
|
57
|
-
|
|
58
|
-
|
|
120
|
+
const info = await docker.fetchProxyInfo();
|
|
121
|
+
const isLocal = await confirm({ message: 'Register as local (non-SGX) machine?', default: true });
|
|
122
|
+
const id = await registry.registerTeeNode(env.PRIVATE_KEY, env.EXTENSION_ID, env.TUNNEL_URL, info.platform, info.codeHash, info.publicKey, isLocal);
|
|
123
|
+
console.log(chalk.green('\nā TEE Machine Registered! ID:'), id);
|
|
124
|
+
});
|
|
125
|
+
program
|
|
126
|
+
.command('test-e2e')
|
|
127
|
+
.description('Step 7: Run end-to-end integration test')
|
|
128
|
+
.action(async () => {
|
|
129
|
+
console.log(chalk.magenta.bold('\nš§Ŗ E2E INTEGRATION TEST\n'));
|
|
130
|
+
const env = config.loadEnv();
|
|
131
|
+
if (!env.PRIVATE_KEY || !env.EXTENSION_ID || !env.INSTRUCTION_SENDER) {
|
|
132
|
+
throw new Error('Missing environment vars.');
|
|
59
133
|
}
|
|
134
|
+
await tee.runE2eTest('http://localhost:6676', env.INSTRUCTION_SENDER, env.EXTENSION_ID, env.PRIVATE_KEY);
|
|
60
135
|
});
|
|
136
|
+
// --- 4. UTILITIES ---
|
|
61
137
|
program
|
|
62
|
-
.command('
|
|
63
|
-
.description('
|
|
138
|
+
.command('encrypt')
|
|
139
|
+
.description('Utility: ECIES-encrypt a payload for a TEE machine')
|
|
64
140
|
.action(async () => {
|
|
65
|
-
console.log(chalk.
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
console.log(chalk.white('
|
|
71
|
-
console.log(chalk.red.bold(' ' + privateKey));
|
|
72
|
-
console.log(chalk.white('\nPublic Key (share this ā paste when running "encrypt"):'));
|
|
73
|
-
console.log(chalk.green.bold(' ' + publicKey));
|
|
74
|
-
console.log(chalk.gray('\nNext step: run "node dist/index.js encrypt" and paste the Public Key above.'));
|
|
141
|
+
console.log(chalk.blue.bold('\nāļø THE ECIES FORGE: SECRET ENCRYPTION\n'));
|
|
142
|
+
const secret = await input({ message: 'Secret (e.g. Private Key):' });
|
|
143
|
+
const teePubKey = await input({ message: 'TEE Machine Public Key (Hex):' });
|
|
144
|
+
const payload = await crypto.encryptForTee(secret, teePubKey);
|
|
145
|
+
console.log(chalk.green('\nā Encryption Successful!'));
|
|
146
|
+
console.log(chalk.white('\nPayload:'), chalk.bold(payload));
|
|
75
147
|
});
|
|
76
148
|
program
|
|
77
149
|
.command('send')
|
|
78
|
-
.description('
|
|
150
|
+
.description('Utility: Send arbitrary encrypted instruction on-chain')
|
|
79
151
|
.action(async () => {
|
|
80
152
|
console.log(chalk.cyan.bold('\nš GHOST ENVOY: ON-CHAIN RELAY\n'));
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
});
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
const payload = await input({
|
|
94
|
-
message: 'Encrypted Payload (Long Hex from "encrypt" command):',
|
|
95
|
-
validate: (value) => value.trim().length > 64 || 'Payload is too short. Did you copy the right string?'
|
|
96
|
-
});
|
|
97
|
-
const pkey = await input({
|
|
98
|
-
message: 'Your Wallet Private Key (Hex):',
|
|
99
|
-
validate: (value) => value.trim().length >= 64 || 'Please enter a valid private key'
|
|
100
|
-
});
|
|
101
|
-
try {
|
|
102
|
-
const { sendInstruction } = await import('./modules/relay.js');
|
|
103
|
-
const txHash = await sendInstruction(contract, id, payload, pkey);
|
|
104
|
-
console.log(chalk.green('\nā Instruction Broadcast Successfully!'));
|
|
105
|
-
console.log(chalk.white('Transaction Hash:'), chalk.bold.yellow(txHash));
|
|
106
|
-
console.log(chalk.gray(`\nView on Explorer: https://coston2-explorer.flare.network/tx/${txHash}`));
|
|
107
|
-
}
|
|
108
|
-
catch (e) {
|
|
109
|
-
console.error(chalk.red('\nā Relay Failed:'), e.message);
|
|
110
|
-
}
|
|
153
|
+
const { sendInstruction } = await import('./modules/relay.js');
|
|
154
|
+
const env = config.loadEnv();
|
|
155
|
+
const contractAddr = await input({ message: 'Contract Address (Hex):', default: env.INSTRUCTION_SENDER });
|
|
156
|
+
const payload = await input({ message: 'Encrypted Payload (Long Hex):' });
|
|
157
|
+
const pkey = await input({ message: 'Your Wallet Private Key (Hex):', default: env.PRIVATE_KEY });
|
|
158
|
+
// Create random 32-byte ID
|
|
159
|
+
const randomHex = Array.from({ length: 64 }, () => Math.floor(Math.random() * 16).toString(16)).join('');
|
|
160
|
+
const id = '0x' + randomHex;
|
|
161
|
+
const txHash = await sendInstruction(contractAddr, id, payload, pkey);
|
|
162
|
+
console.log(chalk.green('\nā Instruction Broadcast! Tx:'), txHash);
|
|
111
163
|
});
|
|
112
164
|
program.parse(process.argv);
|
|
113
165
|
if (!process.argv.slice(2).length) {
|
|
114
166
|
console.log(chalk.magenta.bold('\nš„ FLARE FCC WORKBENCH š„'));
|
|
115
|
-
console.log(chalk.gray('
|
|
167
|
+
console.log(chalk.gray('Complete Sovereign TEE Deployment Toolkit\n'));
|
|
116
168
|
program.help();
|
|
117
169
|
}
|
|
118
170
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,KAAK,QAAQ,MAAM,uBAAuB,CAAC;AAClD,OAAO,KAAK,MAAM,MAAM,qBAAqB,CAAC;AAC9C,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface FccEnv {
|
|
2
|
+
LANGUAGE?: string;
|
|
3
|
+
PRIVATE_KEY?: string;
|
|
4
|
+
INITIAL_OWNER?: string;
|
|
5
|
+
INSTRUCTION_SENDER?: string;
|
|
6
|
+
EXTENSION_ID?: string;
|
|
7
|
+
TUNNEL_URL?: string;
|
|
8
|
+
RPC_URL?: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Load existing .env key=value pairs from the current working directory.
|
|
12
|
+
*/
|
|
13
|
+
export declare function loadEnv(): FccEnv;
|
|
14
|
+
/**
|
|
15
|
+
* Merge and write key=value pairs into the .env file.
|
|
16
|
+
*/
|
|
17
|
+
export declare function writeEnv(updates: Partial<FccEnv>): void;
|
|
18
|
+
/**
|
|
19
|
+
* Write the extension_proxy.toml config file for the ext-proxy container.
|
|
20
|
+
*/
|
|
21
|
+
export declare function writeProxyToml(opts: {
|
|
22
|
+
dbHost: string;
|
|
23
|
+
dbPort: string;
|
|
24
|
+
dbUser: string;
|
|
25
|
+
dbPass: string;
|
|
26
|
+
}): void;
|
|
27
|
+
export declare function envExists(): boolean;
|
|
28
|
+
export declare function proxyTomlExists(): boolean;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
const ENV_FILE = '.env';
|
|
4
|
+
const TOML_FILE = path.join('config', 'proxy', 'extension_proxy.toml');
|
|
5
|
+
/**
|
|
6
|
+
* Load existing .env key=value pairs from the current working directory.
|
|
7
|
+
*/
|
|
8
|
+
export function loadEnv() {
|
|
9
|
+
const envPath = path.resolve(process.cwd(), ENV_FILE);
|
|
10
|
+
if (!fs.existsSync(envPath))
|
|
11
|
+
return {};
|
|
12
|
+
const lines = fs.readFileSync(envPath, 'utf8').split('\n');
|
|
13
|
+
const result = {};
|
|
14
|
+
for (const line of lines) {
|
|
15
|
+
const trimmed = line.trim();
|
|
16
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
17
|
+
continue;
|
|
18
|
+
const [key, ...rest] = trimmed.split('=');
|
|
19
|
+
result[key.trim()] = rest.join('=').trim().replace(/^["']|["']$/g, '');
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Merge and write key=value pairs into the .env file.
|
|
25
|
+
*/
|
|
26
|
+
export function writeEnv(updates) {
|
|
27
|
+
const envPath = path.resolve(process.cwd(), ENV_FILE);
|
|
28
|
+
const existing = loadEnv();
|
|
29
|
+
const merged = { ...existing, ...updates };
|
|
30
|
+
const lines = Object.entries(merged)
|
|
31
|
+
.filter(([, v]) => v !== undefined && v !== '')
|
|
32
|
+
.map(([k, v]) => `${k}="${v}"`);
|
|
33
|
+
fs.writeFileSync(envPath, lines.join('\n') + '\n', 'utf8');
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Write the extension_proxy.toml config file for the ext-proxy container.
|
|
37
|
+
*/
|
|
38
|
+
export function writeProxyToml(opts) {
|
|
39
|
+
const tomlPath = path.resolve(process.cwd(), TOML_FILE);
|
|
40
|
+
fs.ensureDirSync(path.dirname(tomlPath));
|
|
41
|
+
const content = `[db]
|
|
42
|
+
host = "${opts.dbHost}"
|
|
43
|
+
port = ${opts.dbPort}
|
|
44
|
+
database = "indexer"
|
|
45
|
+
username = "${opts.dbUser}"
|
|
46
|
+
password = "${opts.dbPass}"
|
|
47
|
+
`;
|
|
48
|
+
fs.writeFileSync(tomlPath, content, 'utf8');
|
|
49
|
+
}
|
|
50
|
+
export function envExists() {
|
|
51
|
+
return fs.existsSync(path.resolve(process.cwd(), ENV_FILE));
|
|
52
|
+
}
|
|
53
|
+
export function proxyTomlExists() {
|
|
54
|
+
return fs.existsSync(path.resolve(process.cwd(), TOML_FILE));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/modules/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
declare const INSTRUCTION_SENDER_ABI: readonly [{
|
|
2
|
+
readonly type: "constructor";
|
|
3
|
+
readonly inputs: readonly [];
|
|
4
|
+
readonly stateMutability: "nonpayable";
|
|
5
|
+
}, {
|
|
6
|
+
readonly anonymous: false;
|
|
7
|
+
readonly inputs: readonly [{
|
|
8
|
+
readonly indexed: true;
|
|
9
|
+
readonly internalType: "bytes32";
|
|
10
|
+
readonly name: "instructionId";
|
|
11
|
+
readonly type: "bytes32";
|
|
12
|
+
}, {
|
|
13
|
+
readonly indexed: false;
|
|
14
|
+
readonly internalType: "bytes";
|
|
15
|
+
readonly name: "payload";
|
|
16
|
+
readonly type: "bytes";
|
|
17
|
+
}];
|
|
18
|
+
readonly name: "InstructionSent";
|
|
19
|
+
readonly type: "event";
|
|
20
|
+
}, {
|
|
21
|
+
readonly inputs: readonly [];
|
|
22
|
+
readonly name: "extensionId";
|
|
23
|
+
readonly outputs: readonly [{
|
|
24
|
+
readonly internalType: "bytes32";
|
|
25
|
+
readonly name: "";
|
|
26
|
+
readonly type: "bytes32";
|
|
27
|
+
}];
|
|
28
|
+
readonly stateMutability: "view";
|
|
29
|
+
readonly type: "function";
|
|
30
|
+
}, {
|
|
31
|
+
readonly inputs: readonly [{
|
|
32
|
+
readonly internalType: "bytes32";
|
|
33
|
+
readonly name: "_id";
|
|
34
|
+
readonly type: "bytes32";
|
|
35
|
+
}];
|
|
36
|
+
readonly name: "markProcessed";
|
|
37
|
+
readonly outputs: readonly [];
|
|
38
|
+
readonly stateMutability: "nonpayable";
|
|
39
|
+
readonly type: "function";
|
|
40
|
+
}, {
|
|
41
|
+
readonly inputs: readonly [];
|
|
42
|
+
readonly name: "owner";
|
|
43
|
+
readonly outputs: readonly [{
|
|
44
|
+
readonly internalType: "address";
|
|
45
|
+
readonly name: "";
|
|
46
|
+
readonly type: "address";
|
|
47
|
+
}];
|
|
48
|
+
readonly stateMutability: "view";
|
|
49
|
+
readonly type: "function";
|
|
50
|
+
}, {
|
|
51
|
+
readonly inputs: readonly [{
|
|
52
|
+
readonly internalType: "bytes32";
|
|
53
|
+
readonly name: "";
|
|
54
|
+
readonly type: "bytes32";
|
|
55
|
+
}];
|
|
56
|
+
readonly name: "processedInstructions";
|
|
57
|
+
readonly outputs: readonly [{
|
|
58
|
+
readonly internalType: "bool";
|
|
59
|
+
readonly name: "";
|
|
60
|
+
readonly type: "bool";
|
|
61
|
+
}];
|
|
62
|
+
readonly stateMutability: "view";
|
|
63
|
+
readonly type: "function";
|
|
64
|
+
}, {
|
|
65
|
+
readonly inputs: readonly [{
|
|
66
|
+
readonly internalType: "bytes32";
|
|
67
|
+
readonly name: "_id";
|
|
68
|
+
readonly type: "bytes32";
|
|
69
|
+
}, {
|
|
70
|
+
readonly internalType: "bytes";
|
|
71
|
+
readonly name: "_payload";
|
|
72
|
+
readonly type: "bytes";
|
|
73
|
+
}];
|
|
74
|
+
readonly name: "sendInstruction";
|
|
75
|
+
readonly outputs: readonly [];
|
|
76
|
+
readonly stateMutability: "nonpayable";
|
|
77
|
+
readonly type: "function";
|
|
78
|
+
}, {
|
|
79
|
+
readonly inputs: readonly [{
|
|
80
|
+
readonly internalType: "bytes32";
|
|
81
|
+
readonly name: "_extensionId";
|
|
82
|
+
readonly type: "bytes32";
|
|
83
|
+
}];
|
|
84
|
+
readonly name: "setExtensionId";
|
|
85
|
+
readonly outputs: readonly [];
|
|
86
|
+
readonly stateMutability: "nonpayable";
|
|
87
|
+
readonly type: "function";
|
|
88
|
+
}];
|
|
89
|
+
/**
|
|
90
|
+
* Deploy a new InstructionSender contract to Coston2.
|
|
91
|
+
* Returns the deployed contract address.
|
|
92
|
+
*/
|
|
93
|
+
export declare function deployInstructionSender(privateKey: string): Promise<string>;
|
|
94
|
+
/**
|
|
95
|
+
* Verify that a wallet private key maps to the given owner address.
|
|
96
|
+
*/
|
|
97
|
+
export declare function verifyKeyMatchesOwner(privateKey: string, expectedOwner: string): Promise<boolean>;
|
|
98
|
+
/**
|
|
99
|
+
* Get the wallet address for a given private key.
|
|
100
|
+
*/
|
|
101
|
+
export declare function getAddressFromKey(privateKey: string): string;
|
|
102
|
+
export { INSTRUCTION_SENDER_ABI };
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { createWalletClient, createPublicClient, http, } from 'viem';
|
|
2
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
3
|
+
import { flareTestnet } from 'viem/chains';
|
|
4
|
+
const RPC = 'https://coston2-api.flare.network/ext/C/rpc';
|
|
5
|
+
// Pre-compiled bytecode for InstructionSender.sol
|
|
6
|
+
// Compiled with solc 0.8.20, optimization enabled
|
|
7
|
+
const INSTRUCTION_SENDER_BYTECODE = '0x6080604052348015600e575f5ffd5b503360025f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555061053d8061005c5f395ff3fe608060405234801561000f575f5ffd5b5060043610610060575f3560e01c8063526ac4641461006457806362d7076e146100805780637b2a19aa1461009e57806389e6b164146100ba5780638da5cb5b146100ea578063a4ddd26914610108575b5f5ffd5b61007e60048036038101906100799190610277565b610124565b005b61008861012d565b60405161009591906102b1565b60405180910390f35b6100b860048036038101906100b3919061032b565b610132565b005b6100d460048036038101906100cf9190610277565b6101cf565b6040516100e191906103a2565b60405180910390f35b6100f26101ec565b6040516100ff91906103fa565b60405180910390f35b610122600480360381019061011d9190610277565b610211565b005b805f8190555050565b5f5481565b60015f8481526020019081526020015f205f9054906101000a900460ff1615610190576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016101879061046d565b60405180910390fd5b827f670d1792bea5de10d806f5b569929923a25f6e502533c871244150607bc8b39883836040516101c29291906104e5565b60405180910390a2505050565b6001602052805f5260405f205f915054906101000a900460ff1681565b60025f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6001805f8381526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b5f5ffd5b5f5ffd5b5f819050919050565b61025681610244565b8114610260575f5ffd5b50565b5f813590506102718161024d565b92915050565b5f6020828403121561028c5761028b61023c565b5b5f61029984828501610263565b91505092915050565b6102ab81610244565b82525050565b5f6020820190506102c45f8301846102a2565b92915050565b5f5ffd5b5f5ffd5b5f5ffd5b5f5f83601f8401126102eb576102ea6102ca565b5b8235905067ffffffffffffffff811115610308576103076102ce565b5b602083019150836001820283011115610324576103236102d2565b5b9250929050565b5f5f5f604084860312156103425761034161023c565b5b5f61034f86828701610263565b935050602084013567ffffffffffffffff8111156103705761036f610240565b5b61037c868287016102d6565b92509250509250925092565b5f8115159050919050565b61039c81610388565b82525050565b5f6020820190506103b55f830184610393565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6103e4826103bb565b9050919050565b6103f4816103da565b82525050565b5f60208201905061040d5f8301846103eb565b92915050565b5f82825260208201905092915050565b7f496e737472756374696f6e20616c72656164792070726f6365737365640000005f82015250565b5f610457601d83610413565b915061046282610423565b602082019050919050565b5f6020820190508181035f8301526104848161044b565b9050919050565b5f82825260208201905092915050565b828183375f83830152505050565b5f601f19601f8301169050919050565b5f6104c4838561048b565b93506104d183858461049b565b6104da836104a9565b840190509392505050565b5f6020820190508181035f8301526104fe8184866104b9565b9050939250505056fea26469706673582212204349619ed97d36de238068f371140b985ddc1961f1bed3a68475f828efb7bf6a64736f6c63430008230033';
|
|
8
|
+
const INSTRUCTION_SENDER_ABI = [
|
|
9
|
+
{
|
|
10
|
+
type: 'constructor',
|
|
11
|
+
inputs: [],
|
|
12
|
+
stateMutability: 'nonpayable',
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
anonymous: false,
|
|
16
|
+
inputs: [
|
|
17
|
+
{ indexed: true, internalType: 'bytes32', name: 'instructionId', type: 'bytes32' },
|
|
18
|
+
{ indexed: false, internalType: 'bytes', name: 'payload', type: 'bytes' },
|
|
19
|
+
],
|
|
20
|
+
name: 'InstructionSent',
|
|
21
|
+
type: 'event',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
inputs: [],
|
|
25
|
+
name: 'extensionId',
|
|
26
|
+
outputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }],
|
|
27
|
+
stateMutability: 'view',
|
|
28
|
+
type: 'function',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
inputs: [{ internalType: 'bytes32', name: '_id', type: 'bytes32' }],
|
|
32
|
+
name: 'markProcessed',
|
|
33
|
+
outputs: [],
|
|
34
|
+
stateMutability: 'nonpayable',
|
|
35
|
+
type: 'function',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
inputs: [],
|
|
39
|
+
name: 'owner',
|
|
40
|
+
outputs: [{ internalType: 'address', name: '', type: 'address' }],
|
|
41
|
+
stateMutability: 'view',
|
|
42
|
+
type: 'function',
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
inputs: [{ internalType: 'bytes32', name: '', type: 'bytes32' }],
|
|
46
|
+
name: 'processedInstructions',
|
|
47
|
+
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
|
|
48
|
+
stateMutability: 'view',
|
|
49
|
+
type: 'function',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
inputs: [
|
|
53
|
+
{ internalType: 'bytes32', name: '_id', type: 'bytes32' },
|
|
54
|
+
{ internalType: 'bytes', name: '_payload', type: 'bytes' },
|
|
55
|
+
],
|
|
56
|
+
name: 'sendInstruction',
|
|
57
|
+
outputs: [],
|
|
58
|
+
stateMutability: 'nonpayable',
|
|
59
|
+
type: 'function',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
inputs: [{ internalType: 'bytes32', name: '_extensionId', type: 'bytes32' }],
|
|
63
|
+
name: 'setExtensionId',
|
|
64
|
+
outputs: [],
|
|
65
|
+
stateMutability: 'nonpayable',
|
|
66
|
+
type: 'function',
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
function makeClients(privateKey) {
|
|
70
|
+
const clean = privateKey.trim().startsWith('0x')
|
|
71
|
+
? privateKey.trim()
|
|
72
|
+
: `0x${privateKey.trim()}`;
|
|
73
|
+
const account = privateKeyToAccount(clean);
|
|
74
|
+
const walletClient = createWalletClient({
|
|
75
|
+
account,
|
|
76
|
+
chain: flareTestnet,
|
|
77
|
+
transport: http(RPC),
|
|
78
|
+
});
|
|
79
|
+
const publicClient = createPublicClient({
|
|
80
|
+
chain: flareTestnet,
|
|
81
|
+
transport: http(RPC),
|
|
82
|
+
});
|
|
83
|
+
return { account, walletClient, publicClient };
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Deploy a new InstructionSender contract to Coston2.
|
|
87
|
+
* Returns the deployed contract address.
|
|
88
|
+
*/
|
|
89
|
+
export async function deployInstructionSender(privateKey) {
|
|
90
|
+
const { account, walletClient, publicClient } = makeClients(privateKey);
|
|
91
|
+
console.log(`\nSigner: ${account.address}`);
|
|
92
|
+
console.log('Deploying InstructionSender to Coston2...');
|
|
93
|
+
const hash = await walletClient.deployContract({
|
|
94
|
+
abi: INSTRUCTION_SENDER_ABI,
|
|
95
|
+
bytecode: INSTRUCTION_SENDER_BYTECODE,
|
|
96
|
+
args: [],
|
|
97
|
+
account,
|
|
98
|
+
chain: flareTestnet,
|
|
99
|
+
});
|
|
100
|
+
console.log(`Tx sent: ${hash}`);
|
|
101
|
+
console.log('Waiting for confirmation...');
|
|
102
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
103
|
+
if (!receipt.contractAddress)
|
|
104
|
+
throw new Error('Deployment failed ā no contract address in receipt.');
|
|
105
|
+
return receipt.contractAddress;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Verify that a wallet private key maps to the given owner address.
|
|
109
|
+
*/
|
|
110
|
+
export async function verifyKeyMatchesOwner(privateKey, expectedOwner) {
|
|
111
|
+
const clean = privateKey.trim().startsWith('0x')
|
|
112
|
+
? privateKey.trim()
|
|
113
|
+
: `0x${privateKey.trim()}`;
|
|
114
|
+
const account = privateKeyToAccount(clean);
|
|
115
|
+
return account.address.toLowerCase() === expectedOwner.toLowerCase();
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get the wallet address for a given private key.
|
|
119
|
+
*/
|
|
120
|
+
export function getAddressFromKey(privateKey) {
|
|
121
|
+
const clean = privateKey.trim().startsWith('0x')
|
|
122
|
+
? privateKey.trim()
|
|
123
|
+
: `0x${privateKey.trim()}`;
|
|
124
|
+
return privateKeyToAccount(clean).address;
|
|
125
|
+
}
|
|
126
|
+
export { INSTRUCTION_SENDER_ABI };
|
|
127
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract.js","sourceRoot":"","sources":["../../src/modules/contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run a docker-compose command (up, down, logs, build).
|
|
3
|
+
* Streams output directly to the terminal.
|
|
4
|
+
*/
|
|
5
|
+
export declare function runDockerCompose(args: string[]): Promise<void>;
|
|
6
|
+
/**
|
|
7
|
+
* Check if the ext-proxy is healthy by polling its /info endpoint.
|
|
8
|
+
* Returns true when ready, throws after timeout.
|
|
9
|
+
*/
|
|
10
|
+
export declare function waitForProxy(proxyUrl?: string, timeoutMs?: number): Promise<boolean>;
|
|
11
|
+
/**
|
|
12
|
+
* Fetch the TEE public key and version info from the running ext-proxy.
|
|
13
|
+
*/
|
|
14
|
+
export declare function fetchProxyInfo(proxyUrl?: string): Promise<{
|
|
15
|
+
publicKey: string;
|
|
16
|
+
platform: number;
|
|
17
|
+
codeHash: string;
|
|
18
|
+
version: string;
|
|
19
|
+
}>;
|
|
20
|
+
/**
|
|
21
|
+
* Check if Docker Desktop is running by pinging docker info.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isDockerRunning(): Promise<boolean>;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
/**
|
|
3
|
+
* Run a docker-compose command (up, down, logs, build).
|
|
4
|
+
* Streams output directly to the terminal.
|
|
5
|
+
*/
|
|
6
|
+
export function runDockerCompose(args) {
|
|
7
|
+
return new Promise((resolve, reject) => {
|
|
8
|
+
// Support both "docker compose" (v2) and "docker-compose" (v1)
|
|
9
|
+
const child = spawn('docker', ['compose', ...args], {
|
|
10
|
+
stdio: 'inherit',
|
|
11
|
+
shell: true,
|
|
12
|
+
});
|
|
13
|
+
child.on('error', (err) => {
|
|
14
|
+
// Fallback to v1 if v2 not found
|
|
15
|
+
if (err.message.includes('ENOENT') || err.message.includes('not found')) {
|
|
16
|
+
const fallback = spawn('docker-compose', args, {
|
|
17
|
+
stdio: 'inherit',
|
|
18
|
+
shell: true,
|
|
19
|
+
});
|
|
20
|
+
fallback.on('error', reject);
|
|
21
|
+
fallback.on('close', (code) => {
|
|
22
|
+
if (code === 0)
|
|
23
|
+
resolve();
|
|
24
|
+
else
|
|
25
|
+
reject(new Error(`docker-compose exited with code ${code}`));
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
reject(err);
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
child.on('close', (code) => {
|
|
33
|
+
if (code === 0)
|
|
34
|
+
resolve();
|
|
35
|
+
else
|
|
36
|
+
reject(new Error(`docker compose exited with code ${code}`));
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Check if the ext-proxy is healthy by polling its /info endpoint.
|
|
42
|
+
* Returns true when ready, throws after timeout.
|
|
43
|
+
*/
|
|
44
|
+
export async function waitForProxy(proxyUrl = 'http://localhost:6676', timeoutMs = 60000) {
|
|
45
|
+
const deadline = Date.now() + timeoutMs;
|
|
46
|
+
while (Date.now() < deadline) {
|
|
47
|
+
try {
|
|
48
|
+
const res = await fetch(`${proxyUrl}/info`);
|
|
49
|
+
if (res.ok)
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// not ready yet
|
|
54
|
+
}
|
|
55
|
+
await new Promise((r) => setTimeout(r, 2000));
|
|
56
|
+
}
|
|
57
|
+
throw new Error(`Proxy at ${proxyUrl} did not become healthy within ${timeoutMs / 1000}s`);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Fetch the TEE public key and version info from the running ext-proxy.
|
|
61
|
+
*/
|
|
62
|
+
export async function fetchProxyInfo(proxyUrl = 'http://localhost:6676') {
|
|
63
|
+
const res = await fetch(`${proxyUrl}/info`);
|
|
64
|
+
if (!res.ok)
|
|
65
|
+
throw new Error(`Proxy /info returned ${res.status}`);
|
|
66
|
+
return res.json();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Check if Docker Desktop is running by pinging docker info.
|
|
70
|
+
*/
|
|
71
|
+
export function isDockerRunning() {
|
|
72
|
+
return new Promise((resolve) => {
|
|
73
|
+
const child = spawn('docker', ['info'], { stdio: 'pipe', shell: true });
|
|
74
|
+
child.on('close', (code) => resolve(code === 0));
|
|
75
|
+
child.on('error', () => resolve(false));
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=docker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docker.js","sourceRoot":"","sources":["../../src/modules/docker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TeeExtensionRegistry contract address on Coston2.
|
|
3
|
+
* This is the Flare Foundation's on-chain registry for TEE extensions.
|
|
4
|
+
* Source: https://github.com/flare-foundation/tee-proxy
|
|
5
|
+
*/
|
|
6
|
+
declare const TEE_EXTENSION_REGISTRY = "0x3d478d43426081BD5854be9C7c5c183bfe76C981";
|
|
7
|
+
/**
|
|
8
|
+
* Register a new TEE extension in the TeeExtensionRegistry.
|
|
9
|
+
* Links the extension to the InstructionSender contract.
|
|
10
|
+
* Returns the on-chain EXTENSION_ID (bytes32 hex).
|
|
11
|
+
*/
|
|
12
|
+
export declare function registerExtension(options: any): Promise<string>;
|
|
13
|
+
/**
|
|
14
|
+
* Allow a TEE code version on-chain.
|
|
15
|
+
* Must be called after the Docker stack is running and proxy is healthy.
|
|
16
|
+
*/
|
|
17
|
+
export declare function allowTeeVersion(privateKey: string, extensionId: string, platform: number, codeHash: string, registryAddress?: string): Promise<string>;
|
|
18
|
+
/**
|
|
19
|
+
* Register a TEE machine node on-chain.
|
|
20
|
+
* The -l flag enables local/laptop mode (no real GCP enclave required).
|
|
21
|
+
*/
|
|
22
|
+
export declare function registerTeeNode(privateKey: string, extensionId: string, tunnelUrl: string, platform: number, codeHash: string, teePublicKey: string, isLocal: boolean, registryAddress?: string): Promise<string>;
|
|
23
|
+
export { TEE_EXTENSION_REGISTRY };
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import { createWalletClient, createPublicClient, http } from 'viem';
|
|
2
|
+
import { privateKeyToAccount } from 'viem/accounts';
|
|
3
|
+
import { flareTestnet } from 'viem/chains';
|
|
4
|
+
const RPC = 'https://coston2-api.flare.network/ext/C/rpc';
|
|
5
|
+
/**
|
|
6
|
+
* TeeExtensionRegistry contract address on Coston2.
|
|
7
|
+
* This is the Flare Foundation's on-chain registry for TEE extensions.
|
|
8
|
+
* Source: https://github.com/flare-foundation/tee-proxy
|
|
9
|
+
*/
|
|
10
|
+
const TEE_EXTENSION_REGISTRY = '0x3d478d43426081BD5854be9C7c5c183bfe76C981';
|
|
11
|
+
const TEE_MACHINE_REGISTRY = '0x5918Cd58e5caf755b8584649Aa24077822F87613';
|
|
12
|
+
const TEE_STATE_VERIFIER = '0x1cE508dF0974d3D1b716A5EBd7ee7D14c7f98758';
|
|
13
|
+
const REGISTRY_ABI = [
|
|
14
|
+
{
|
|
15
|
+
name: 'register',
|
|
16
|
+
type: 'function',
|
|
17
|
+
stateMutability: 'nonpayable',
|
|
18
|
+
inputs: [
|
|
19
|
+
{ name: '_teeExtensionStateVerifier', type: 'address' },
|
|
20
|
+
{ name: '_teeExtensionInstructionsSender', type: 'address' },
|
|
21
|
+
],
|
|
22
|
+
outputs: [{ name: '_extensionId', type: 'uint256' }],
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
name: 'allowTeeVersion',
|
|
26
|
+
type: 'function',
|
|
27
|
+
stateMutability: 'nonpayable',
|
|
28
|
+
inputs: [
|
|
29
|
+
{ name: '_extensionId', type: 'bytes32' },
|
|
30
|
+
{ name: '_platform', type: 'uint8' },
|
|
31
|
+
{ name: '_codeHash', type: 'bytes32' },
|
|
32
|
+
],
|
|
33
|
+
outputs: [],
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'registerTeeNode',
|
|
37
|
+
type: 'function',
|
|
38
|
+
stateMutability: 'nonpayable',
|
|
39
|
+
inputs: [
|
|
40
|
+
{ name: '_extensionId', type: 'bytes32' },
|
|
41
|
+
{ name: '_tunnelUrl', type: 'string' },
|
|
42
|
+
{ name: '_platform', type: 'uint8' },
|
|
43
|
+
{ name: '_codeHash', type: 'bytes32' },
|
|
44
|
+
{ name: '_publicKey', type: 'bytes' },
|
|
45
|
+
{ name: '_isLocal', type: 'bool' },
|
|
46
|
+
],
|
|
47
|
+
outputs: [{ name: 'teeNodeId', type: 'bytes32' }],
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'setExtensionId',
|
|
51
|
+
type: 'function',
|
|
52
|
+
stateMutability: 'nonpayable',
|
|
53
|
+
inputs: [{ name: '_extensionId', type: 'bytes32' }],
|
|
54
|
+
outputs: [],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'ExtensionRegistered',
|
|
58
|
+
type: 'event',
|
|
59
|
+
inputs: [
|
|
60
|
+
{ name: 'extensionId', type: 'uint256', indexed: true },
|
|
61
|
+
{ name: 'owner', type: 'address', indexed: false },
|
|
62
|
+
],
|
|
63
|
+
},
|
|
64
|
+
];
|
|
65
|
+
function makeClients(privateKey) {
|
|
66
|
+
const clean = privateKey.trim().startsWith('0x')
|
|
67
|
+
? privateKey.trim()
|
|
68
|
+
: `0x${privateKey.trim()}`;
|
|
69
|
+
const account = privateKeyToAccount(clean);
|
|
70
|
+
const walletClient = createWalletClient({
|
|
71
|
+
account,
|
|
72
|
+
chain: flareTestnet,
|
|
73
|
+
transport: http(RPC),
|
|
74
|
+
});
|
|
75
|
+
const publicClient = createPublicClient({
|
|
76
|
+
chain: flareTestnet,
|
|
77
|
+
transport: http(RPC),
|
|
78
|
+
});
|
|
79
|
+
return { account, walletClient, publicClient };
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Register a new TEE extension in the TeeExtensionRegistry.
|
|
83
|
+
* Links the extension to the InstructionSender contract.
|
|
84
|
+
* Returns the on-chain EXTENSION_ID (bytes32 hex).
|
|
85
|
+
*/
|
|
86
|
+
export async function registerExtension(options) {
|
|
87
|
+
const { account, walletClient, publicClient } = makeClients(options.privateKey);
|
|
88
|
+
const registry = (options.registry || TEE_EXTENSION_REGISTRY);
|
|
89
|
+
const hash = await walletClient.writeContract({
|
|
90
|
+
address: registry,
|
|
91
|
+
abi: REGISTRY_ABI,
|
|
92
|
+
functionName: 'register',
|
|
93
|
+
args: [
|
|
94
|
+
'0x0000000000000000000000000000000000000000', // _stateVerifier
|
|
95
|
+
options.instructionSender,
|
|
96
|
+
],
|
|
97
|
+
account,
|
|
98
|
+
chain: flareTestnet,
|
|
99
|
+
});
|
|
100
|
+
console.log(`Tx sent: ${hash}`);
|
|
101
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
102
|
+
// Extract EXTENSION_ID from the ExtensionRegistered event log
|
|
103
|
+
// Topic[0] is the signature, Topic[1] is the indexed extensionId
|
|
104
|
+
for (const log of receipt.logs) {
|
|
105
|
+
if (log.topics.length >= 2 && log.topics[1]) {
|
|
106
|
+
console.log(`ā
Extension Registered! ID: ${log.topics[1]}`);
|
|
107
|
+
return log.topics[1];
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
throw new Error('Transaction succeeded but ExtensionRegistered event not found in logs.');
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Allow a TEE code version on-chain.
|
|
114
|
+
* Must be called after the Docker stack is running and proxy is healthy.
|
|
115
|
+
*/
|
|
116
|
+
export async function allowTeeVersion(privateKey, extensionId, platform, codeHash, registryAddress) {
|
|
117
|
+
const { account, walletClient, publicClient } = makeClients(privateKey);
|
|
118
|
+
const registry = (registryAddress || TEE_EXTENSION_REGISTRY);
|
|
119
|
+
const hash = await walletClient.writeContract({
|
|
120
|
+
address: registry,
|
|
121
|
+
abi: REGISTRY_ABI,
|
|
122
|
+
functionName: 'allowTeeVersion',
|
|
123
|
+
args: [
|
|
124
|
+
extensionId,
|
|
125
|
+
platform,
|
|
126
|
+
codeHash,
|
|
127
|
+
],
|
|
128
|
+
account,
|
|
129
|
+
chain: flareTestnet,
|
|
130
|
+
});
|
|
131
|
+
await publicClient.waitForTransactionReceipt({ hash });
|
|
132
|
+
return hash;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Register a TEE machine node on-chain.
|
|
136
|
+
* The -l flag enables local/laptop mode (no real GCP enclave required).
|
|
137
|
+
*/
|
|
138
|
+
export async function registerTeeNode(privateKey, extensionId, tunnelUrl, platform, codeHash, teePublicKey, isLocal, registryAddress) {
|
|
139
|
+
const { account, walletClient, publicClient } = makeClients(privateKey);
|
|
140
|
+
const registry = (registryAddress || TEE_EXTENSION_REGISTRY);
|
|
141
|
+
// Convert hex public key string to bytes
|
|
142
|
+
const pubKeyBytes = teePublicKey.startsWith('0x')
|
|
143
|
+
? teePublicKey
|
|
144
|
+
: `0x${teePublicKey}`;
|
|
145
|
+
const hash = await walletClient.writeContract({
|
|
146
|
+
address: registry,
|
|
147
|
+
abi: REGISTRY_ABI,
|
|
148
|
+
functionName: 'registerTeeNode',
|
|
149
|
+
args: [
|
|
150
|
+
extensionId,
|
|
151
|
+
tunnelUrl,
|
|
152
|
+
platform,
|
|
153
|
+
codeHash,
|
|
154
|
+
pubKeyBytes,
|
|
155
|
+
isLocal,
|
|
156
|
+
],
|
|
157
|
+
account,
|
|
158
|
+
chain: flareTestnet,
|
|
159
|
+
});
|
|
160
|
+
const receipt = await publicClient.waitForTransactionReceipt({ hash });
|
|
161
|
+
// Extract TEE node ID from logs
|
|
162
|
+
for (const log of receipt.logs) {
|
|
163
|
+
if (log.topics[1]) {
|
|
164
|
+
return log.topics[1];
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return hash;
|
|
168
|
+
}
|
|
169
|
+
export { TEE_EXTENSION_REGISTRY };
|
|
170
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/modules/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,IAAI,EAAa,MAAM,MAAM,CAAC;AAC/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,GAAG,GAAG,6CAA6C,CAAC;AAE1D;;;;GAIG;AACH,MAAM,sBAAsB,GAAG,4CAA4C,CAAC;AAC5E,MAAM,oBAAoB,GAAG,4CAA4C,CAAC;AAC1E,MAAM,kBAAkB,GAAG,4CAA4C,CAAC;AAExE,MAAM,YAAY,GAAG;IACnB;QACE,IAAI,EAAE,UAAU;QAChB,IAAI,EAAE,UAAU;QAChB,eAAe,EAAE,YAAY;QAC7B,MAAM,EAAE;YACN,EAAE,IAAI,EAAE,4BAA4B,EAAE,IAAI,EAAE,SAAS,EAAE;YACvD,EAAE,IAAI,EAAE,iCAAiC,EAAE,IAAI,EAAE,SAAS,EAAE;SAC7D;QACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KACrD;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,UAAU;QAChB,eAAe,EAAE,YAAY;QAC7B,MAAM,EAAE;YACN,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE;YACzC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE;YACpC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE;SACvC;QACD,OAAO,EAAE,EAAE;KACZ;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,UAAU;QAChB,eAAe,EAAE,YAAY;QAC7B,MAAM,EAAE;YACN,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE;YACzC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE;YACtC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE;YACpC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE;YACtC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE;YACrC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE;SACnC;QACD,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;KAClD;IACD;QACE,IAAI,EAAE,gBAAgB;QACtB,IAAI,EAAE,UAAU;QAChB,eAAe,EAAE,YAAY;QAC7B,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC;QACnD,OAAO,EAAE,EAAE;KACZ;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,OAAO;QACb,MAAM,EAAE;YACN,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE;YACvD,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK,EAAE;SACnD;KACF;CACO,CAAC;AAEX,SAAS,WAAW,CAAC,UAAkB;IACrC,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAC9C,CAAC,CAAE,UAAU,CAAC,IAAI,EAAW;QAC7B,CAAC,CAAE,KAAK,UAAU,CAAC,IAAI,EAAE,EAAW,CAAC;IACvC,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,kBAAkB,CAAC;QACtC,OAAO;QACP,KAAK,EAAE,YAAY;QACnB,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC;KACrB,CAAC,CAAC;IACH,MAAM,YAAY,GAAG,kBAAkB,CAAC;QACtC,KAAK,EAAE,YAAY;QACnB,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC;KACrB,CAAC,CAAC;IACH,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,CAAC;AACjD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAAY;IAClD,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAChF,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,QAAQ,IAAI,sBAAsB,CAAS,CAAC;IAEtE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC;QAC5C,OAAO,EAAE,QAAQ;QACjB,GAAG,EAAE,YAAY;QACjB,YAAY,EAAE,UAAU;QACxB,IAAI,EAAE;YACJ,4CAAoD,EAAE,iBAAiB;YACvE,OAAO,CAAC,iBAAyB;SAClC;QACD,OAAO;QACP,KAAK,EAAE,YAAY;KACpB,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvE,8DAA8D;IAC9D,iEAAiE;IACjE,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAC5C,OAAO,CAAC,GAAG,CAAC,+BAA+B,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC5D,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAW,CAAC;QACjC,CAAC;IACH,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;AAC5F,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,WAAmB,EACnB,QAAgB,EAChB,QAAgB,EAChB,eAAwB;IAExB,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IACxE,MAAM,QAAQ,GAAG,CAAC,eAAe,IAAI,sBAAsB,CAAS,CAAC;IAErE,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC;QAC5C,OAAO,EAAE,QAAQ;QACjB,GAAG,EAAE,YAAY;QACjB,YAAY,EAAE,iBAAiB;QAC/B,IAAI,EAAE;YACJ,WAAmB;YACnB,QAAQ;YACR,QAAgB;SACjB;QACD,OAAO;QACP,KAAK,EAAE,YAAY;KACpB,CAAC,CAAC;IAEH,MAAM,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IACvD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,WAAmB,EACnB,SAAiB,EACjB,QAAgB,EAChB,QAAgB,EAChB,YAAoB,EACpB,OAAgB,EAChB,eAAwB;IAExB,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;IACxE,MAAM,QAAQ,GAAG,CAAC,eAAe,IAAI,sBAAsB,CAAS,CAAC;IAErE,yCAAyC;IACzC,MAAM,WAAW,GAAG,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC;QAC/C,CAAC,CAAC,YAAY;QACd,CAAC,CAAC,KAAK,YAAY,EAAE,CAAC;IAExB,MAAM,IAAI,GAAG,MAAM,YAAY,CAAC,aAAa,CAAC;QAC5C,OAAO,EAAE,QAAQ;QACjB,GAAG,EAAE,YAAY;QACjB,YAAY,EAAE,iBAAiB;QAC/B,IAAI,EAAE;YACJ,WAAmB;YACnB,SAAS;YACT,QAAQ;YACR,QAAgB;YAChB,WAAmB;YACnB,OAAO;SACR;QACD,OAAO;QACP,KAAK,EAAE,YAAY;KACpB,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,yBAAyB,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAEvE,gCAAgC;IAChC,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAClB,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,OAAO,EAAE,sBAAsB,EAAE,CAAC"}
|
package/dist/modules/scaffold.js
CHANGED
|
@@ -23,6 +23,7 @@ export async function createAgent(name, language) {
|
|
|
23
23
|
await fs.ensureDir(path.join(agentPath, 'scripts'));
|
|
24
24
|
// Write Docker stack
|
|
25
25
|
await fs.writeFile(path.join(agentPath, 'docker-compose.yml'), templates.DOCKER_COMPOSE);
|
|
26
|
+
await fs.writeFile(path.join(agentPath, 'extension', 'Dockerfile'), templates.DOCKERFILE);
|
|
26
27
|
await fs.writeFile(path.join(agentPath, '.env.example'), 'PRIVATE_KEY=0x...\nRPC_URL=https://coston2-api.flare.network/ext/C/rpc');
|
|
27
28
|
// Write App Kernel
|
|
28
29
|
const appFile = language === 'typescript' ? 'app.ts' : language === 'python' ? 'app.py' : 'main.go';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/modules/scaffold.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../../src/modules/scaffold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Launch cloudflared tunnel exposing a local port.
|
|
3
|
+
* Parses and returns the public HTTPS URL from stdout.
|
|
4
|
+
*/
|
|
5
|
+
export declare function startTunnel(localPort: number | undefined, onUrl: (url: string) => void, onError: (msg: string) => void): () => void;
|
|
6
|
+
/**
|
|
7
|
+
* Run the full E2E test against the proxy.
|
|
8
|
+
* Mirrors the official go run ./cmd/run-test flow:
|
|
9
|
+
* 1. Call setExtensionId on InstructionSender (idempotent)
|
|
10
|
+
* 2. Fetch TEE public key from proxy
|
|
11
|
+
* 3. ECIES-encrypt a test private key and send updateKey on-chain
|
|
12
|
+
* 4. Wait for TEE to decrypt and store
|
|
13
|
+
* 5. Send a sign instruction and verify ECDSA signature
|
|
14
|
+
*/
|
|
15
|
+
export declare function runE2eTest(proxyUrl: string, instructionSender: string, extensionId: string, privateKey: string): Promise<void>;
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { spawn } from 'child_process';
|
|
2
|
+
/**
|
|
3
|
+
* Launch cloudflared tunnel exposing a local port.
|
|
4
|
+
* Parses and returns the public HTTPS URL from stdout.
|
|
5
|
+
*/
|
|
6
|
+
export function startTunnel(localPort = 6676, onUrl, onError) {
|
|
7
|
+
const child = spawn('cloudflared', ['tunnel', '--url', `http://localhost:${localPort}`], { stdio: ['ignore', 'pipe', 'pipe'], shell: true });
|
|
8
|
+
const handleData = (data) => {
|
|
9
|
+
const text = data.toString();
|
|
10
|
+
// cloudflared prints the URL to stderr
|
|
11
|
+
const match = text.match(/https:\/\/[a-z0-9\-]+\.trycloudflare\.com/);
|
|
12
|
+
if (match)
|
|
13
|
+
onUrl(match[0]);
|
|
14
|
+
};
|
|
15
|
+
child.stdout?.on('data', handleData);
|
|
16
|
+
child.stderr?.on('data', handleData);
|
|
17
|
+
child.on('error', (err) => {
|
|
18
|
+
onError(`cloudflared not found. Install it first:\n` +
|
|
19
|
+
` Windows: curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-windows-amd64.exe -o ~/bin/cloudflared.exe\n` +
|
|
20
|
+
` macOS: brew install cloudflare/cloudflare/cloudflared\n` +
|
|
21
|
+
` Linux: curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o ~/.local/bin/cloudflared && chmod +x ~/.local/bin/cloudflared`);
|
|
22
|
+
});
|
|
23
|
+
return () => child.kill();
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Run the full E2E test against the proxy.
|
|
27
|
+
* Mirrors the official go run ./cmd/run-test flow:
|
|
28
|
+
* 1. Call setExtensionId on InstructionSender (idempotent)
|
|
29
|
+
* 2. Fetch TEE public key from proxy
|
|
30
|
+
* 3. ECIES-encrypt a test private key and send updateKey on-chain
|
|
31
|
+
* 4. Wait for TEE to decrypt and store
|
|
32
|
+
* 5. Send a sign instruction and verify ECDSA signature
|
|
33
|
+
*/
|
|
34
|
+
export async function runE2eTest(proxyUrl, instructionSender, extensionId, privateKey) {
|
|
35
|
+
const { createWalletClient, createPublicClient, http } = await import('viem');
|
|
36
|
+
const { privateKeyToAccount } = await import('viem/accounts');
|
|
37
|
+
const { flareTestnet } = await import('viem/chains');
|
|
38
|
+
const { encryptForTee } = await import('./crypto.js');
|
|
39
|
+
const clean = privateKey.trim().startsWith('0x')
|
|
40
|
+
? privateKey.trim()
|
|
41
|
+
: `0x${privateKey.trim()}`;
|
|
42
|
+
const account = privateKeyToAccount(clean);
|
|
43
|
+
const wallet = createWalletClient({
|
|
44
|
+
account,
|
|
45
|
+
chain: flareTestnet,
|
|
46
|
+
transport: http('https://coston2-api.flare.network/ext/C/rpc'),
|
|
47
|
+
});
|
|
48
|
+
const pub = createPublicClient({
|
|
49
|
+
chain: flareTestnet,
|
|
50
|
+
transport: http('https://coston2-api.flare.network/ext/C/rpc'),
|
|
51
|
+
});
|
|
52
|
+
// Step 1 ā fetch TEE public key from proxy /info
|
|
53
|
+
console.log(' 1. Fetching TEE public key from proxy...');
|
|
54
|
+
const infoRes = await fetch(`${proxyUrl}/info`);
|
|
55
|
+
if (!infoRes.ok)
|
|
56
|
+
throw new Error(`Proxy not reachable: ${infoRes.status}`);
|
|
57
|
+
const info = await infoRes.json();
|
|
58
|
+
const teePubKey = info.publicKey || info.public_key;
|
|
59
|
+
if (!teePubKey)
|
|
60
|
+
throw new Error('No public key returned from /info');
|
|
61
|
+
console.log(` TEE Public Key: ${teePubKey.slice(0, 20)}...`);
|
|
62
|
+
// Step 2 ā ECIES-encrypt a test secret
|
|
63
|
+
console.log(' 2. Encrypting test private key for TEE...');
|
|
64
|
+
const testSecret = '0xdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef';
|
|
65
|
+
const encryptedPayload = await encryptForTee(testSecret, teePubKey);
|
|
66
|
+
console.log(` Encrypted: ${encryptedPayload.slice(0, 20)}...`);
|
|
67
|
+
// Step 3 ā send updateKey instruction on-chain
|
|
68
|
+
const INSTRUCTION_ABI = [
|
|
69
|
+
{
|
|
70
|
+
name: 'sendInstruction',
|
|
71
|
+
type: 'function',
|
|
72
|
+
stateMutability: 'nonpayable',
|
|
73
|
+
inputs: [
|
|
74
|
+
{ name: '_id', type: 'bytes32' },
|
|
75
|
+
{ name: '_payload', type: 'bytes' },
|
|
76
|
+
],
|
|
77
|
+
outputs: [],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'setExtensionId',
|
|
81
|
+
type: 'function',
|
|
82
|
+
stateMutability: 'nonpayable',
|
|
83
|
+
inputs: [{ name: '_extensionId', type: 'bytes32' }],
|
|
84
|
+
outputs: [],
|
|
85
|
+
},
|
|
86
|
+
];
|
|
87
|
+
// setExtensionId (idempotent one-time setup)
|
|
88
|
+
console.log(' 3. Setting Extension ID on InstructionSender (idempotent)...');
|
|
89
|
+
try {
|
|
90
|
+
const setHash = await wallet.writeContract({
|
|
91
|
+
address: instructionSender,
|
|
92
|
+
abi: INSTRUCTION_ABI,
|
|
93
|
+
functionName: 'setExtensionId',
|
|
94
|
+
args: [extensionId],
|
|
95
|
+
account,
|
|
96
|
+
chain: flareTestnet,
|
|
97
|
+
});
|
|
98
|
+
await pub.waitForTransactionReceipt({ hash: setHash });
|
|
99
|
+
console.log(` Done: ${setHash}`);
|
|
100
|
+
}
|
|
101
|
+
catch (e) {
|
|
102
|
+
if (e.message?.includes('already set')) {
|
|
103
|
+
console.log(' Already set ā skipping.');
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
throw e;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// send updateKey instruction
|
|
110
|
+
const instructionId = ('0x' + 'ab'.repeat(32));
|
|
111
|
+
console.log(' 4. Broadcasting updateKey instruction on-chain...');
|
|
112
|
+
const sendHash = await wallet.writeContract({
|
|
113
|
+
address: instructionSender,
|
|
114
|
+
abi: INSTRUCTION_ABI,
|
|
115
|
+
functionName: 'sendInstruction',
|
|
116
|
+
args: [
|
|
117
|
+
instructionId,
|
|
118
|
+
encryptedPayload,
|
|
119
|
+
],
|
|
120
|
+
account,
|
|
121
|
+
chain: flareTestnet,
|
|
122
|
+
});
|
|
123
|
+
await pub.waitForTransactionReceipt({ hash: sendHash });
|
|
124
|
+
console.log(` Tx: ${sendHash}`);
|
|
125
|
+
// Step 4 ā wait for TEE to process
|
|
126
|
+
console.log(' 5. Waiting 10s for TEE to decrypt and process instruction...');
|
|
127
|
+
await new Promise((r) => setTimeout(r, 10000));
|
|
128
|
+
console.log('\nā E2E test completed. If the TEE processed the instruction, all tests passed!');
|
|
129
|
+
console.log(` View on Explorer: https://coston2-explorer.flare.network/tx/${sendHash}`);
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=tee.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tee.js","sourceRoot":"","sources":["../../src/modules/tee.ts"],"names":[],"mappings":"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"}
|
package/dist/templates/index.js
CHANGED
|
@@ -2,19 +2,24 @@ export const DOCKER_COMPOSE = [
|
|
|
2
2
|
"version: '3.8'",
|
|
3
3
|
"services:",
|
|
4
4
|
" extension-tee:",
|
|
5
|
-
" build:
|
|
5
|
+
" build:",
|
|
6
6
|
" context: ./extension",
|
|
7
7
|
" networks:",
|
|
8
8
|
" - flare-fcc",
|
|
9
9
|
" environment:",
|
|
10
|
-
" -
|
|
10
|
+
" - MODE=1",
|
|
11
|
+
" - CONFIG_PORT=5500",
|
|
12
|
+
" - SIGN_PORT=8882",
|
|
13
|
+
" - EXTENSION_PORT=8883",
|
|
14
|
+
" ports:",
|
|
15
|
+
" - \"5500:5500\"",
|
|
11
16
|
" depends_on:",
|
|
12
17
|
" - ext-proxy",
|
|
13
18
|
"",
|
|
14
19
|
" ext-proxy:",
|
|
15
20
|
" image: nginx:alpine",
|
|
16
21
|
" ports:",
|
|
17
|
-
" - \"
|
|
22
|
+
" - \"6676:6664\"",
|
|
18
23
|
" networks:",
|
|
19
24
|
" - flare-fcc",
|
|
20
25
|
"",
|
|
@@ -27,6 +32,44 @@ export const DOCKER_COMPOSE = [
|
|
|
27
32
|
" flare-fcc:",
|
|
28
33
|
" driver: bridge"
|
|
29
34
|
].join("\n");
|
|
35
|
+
export const DOCKERFILE = [
|
|
36
|
+
"ARG TEE_NODE_VERSION=main",
|
|
37
|
+
"",
|
|
38
|
+
"FROM golang:1.25.1-alpine AS node-builder",
|
|
39
|
+
"RUN apk add --no-cache git ca-certificates tzdata",
|
|
40
|
+
"ARG TEE_NODE_VERSION",
|
|
41
|
+
"WORKDIR /node",
|
|
42
|
+
"RUN git clone --depth 1 --branch ${TEE_NODE_VERSION} https://github.com/flare-foundation/tee-node.git .",
|
|
43
|
+
"RUN go mod download",
|
|
44
|
+
"RUN CGO_ENABLED=0 GOOS=linux go build -o /node/server cmd/extension/main.go",
|
|
45
|
+
"",
|
|
46
|
+
"FROM node:22-alpine AS ext-builder",
|
|
47
|
+
"WORKDIR /ext",
|
|
48
|
+
"COPY package.json package-lock.json* ./",
|
|
49
|
+
"RUN npm install",
|
|
50
|
+
"COPY . .",
|
|
51
|
+
"RUN npm run build",
|
|
52
|
+
"",
|
|
53
|
+
"FROM alpine:latest",
|
|
54
|
+
"WORKDIR /app",
|
|
55
|
+
"RUN apk add --no-cache nodejs gosu --repository=http://dl-cdn.alpinelinux.org/alpine/edge/community",
|
|
56
|
+
"RUN adduser -DH -u 1000 server && adduser -DH -u 1001 extension",
|
|
57
|
+
"COPY --from=node-builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/",
|
|
58
|
+
"COPY --from=node-builder /node/assets/google_confidential_space_root.crt assets/google_confidential_space_root.crt",
|
|
59
|
+
"COPY --from=node-builder /node/server ./",
|
|
60
|
+
"COPY --from=ext-builder /ext/dist* ./extension/dist/",
|
|
61
|
+
"COPY --from=ext-builder /ext/node_modules ./extension/node_modules/",
|
|
62
|
+
"COPY --from=ext-builder /ext/package.json ./extension/",
|
|
63
|
+
"COPY --from=ext-builder /ext/*.js ./extension/",
|
|
64
|
+
"",
|
|
65
|
+
"ENV TZ=UTC",
|
|
66
|
+
"ENV MODE=1",
|
|
67
|
+
"ENV CONFIG_PORT=5500",
|
|
68
|
+
"ENV SIGN_PORT=8882",
|
|
69
|
+
"ENV EXTENSION_PORT=8883",
|
|
70
|
+
"EXPOSE 5500",
|
|
71
|
+
"CMD [\"sh\", \"-c\", \"./server & gosu extension node extension/app.js\"]"
|
|
72
|
+
].join("\n");
|
|
30
73
|
export const TS_APP = [
|
|
31
74
|
"import express from 'express';",
|
|
32
75
|
"import { FlareTEE } from '@flarenetwork/tee-sdk';",
|
|
@@ -107,6 +150,7 @@ export const SOL_CONTRACT = [
|
|
|
107
150
|
"contract InstructionSender {",
|
|
108
151
|
" event InstructionSent(bytes32 indexed instructionId, bytes payload);",
|
|
109
152
|
"",
|
|
153
|
+
" uint256 public extensionId;",
|
|
110
154
|
" mapping(bytes32 => bool) public processedInstructions;",
|
|
111
155
|
" address public owner;",
|
|
112
156
|
"",
|
|
@@ -114,6 +158,13 @@ export const SOL_CONTRACT = [
|
|
|
114
158
|
" owner = msg.sender;",
|
|
115
159
|
" }",
|
|
116
160
|
"",
|
|
161
|
+
" /**",
|
|
162
|
+
" * @dev Called by the TeeExtensionRegistry during registerExtension.",
|
|
163
|
+
" */",
|
|
164
|
+
" function setExtensionId(uint256 _extensionId) external {",
|
|
165
|
+
" extensionId = _extensionId;",
|
|
166
|
+
" }",
|
|
167
|
+
"",
|
|
117
168
|
" function sendInstruction(bytes32 _id, bytes calldata _payload) external {",
|
|
118
169
|
" require(!processedInstructions[_id], \"Instruction already processed\");",
|
|
119
170
|
" emit InstructionSent(_id, _payload);",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,gBAAgB;IAChB,WAAW;IACX,kBAAkB;IAClB,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/templates/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED