|
1 | | ---- |
2 | | -title: Create and Deploy an iApp |
3 | | -description: |
4 | | - How to create a confidential iExec application and deploy it on iExec protocol |
5 | | ---- |
6 | | - |
7 | | -# Create and Deploy an iApp |
8 | | - |
9 | | -iApps (iExec Applications) are decentralized applications that run on the iExec |
10 | | -network. They leverage confidential computing to ensure data privacy and |
11 | | -security while providing scalable off-chain computation. |
12 | | - |
13 | | -## About iApp Generator |
14 | | - |
15 | | -Bootstrap TEE-compatible applications in minutes without any hardcoding skills, |
16 | | -iApp Generator handles all the low-level complexity for you. |
17 | | - |
18 | | -- **Select your project mode & language** - Get started with either a basic or |
19 | | - advanced setup, depending on your experience with the iExec framework. You can |
20 | | - use Python or JavaScript—whichever you prefer! |
21 | | -- **Develop your iApp effortlessly** - Write your application logic using |
22 | | - familiar programming languages while the generator handles all TEE-specific |
23 | | - configurations. |
24 | | -- **Access to TEEs easily** - No need to dive into low-level requirements, |
25 | | - create iApps that connect to TEEs in minutes. |
26 | | -- **Check and deploy iApps quickly** - iApp Generator checks that your iApp |
27 | | - complies with the iExec Framework and streamlines its deployment. |
28 | | - |
29 | | -## Prerequisites |
30 | | - |
31 | | -Before getting started, make sure you have the following installed: |
32 | | - |
33 | | -- **Node.js** (version 18 or higher) - [Download here](https://nodejs.org/) |
34 | | -- **Docker** - [Download here](https://www.docker.com/get-started) |
35 | | -- **Docker Hub account** - [Sign up here](https://hub.docker.com/) (required for |
36 | | - deployment) |
37 | | - |
38 | | -## Installation |
39 | | - |
40 | | -First, install the iApp Generator CLI tool using your preferred package manager: |
41 | | - |
42 | | -::: code-group |
43 | | - |
44 | | -```sh [npm] |
45 | | -npm install -g @iexec/iapp |
46 | | -``` |
47 | | - |
48 | | -```sh [yarn] |
49 | | -yarn global add @iexec/iapp |
50 | | -``` |
51 | | - |
52 | | -```sh [pnpm] |
53 | | -pnpm add -g @iexec/iapp |
54 | | -``` |
55 | | - |
56 | | -```sh [bun] |
57 | | -bun add -g @iexec/iapp |
58 | | -``` |
59 | | - |
60 | | -::: |
61 | | - |
62 | | -## Quick Start |
63 | | - |
64 | | -Once installed, you can create and deploy your first iApp. The CLI will guide |
65 | | -you through an interactive setup process to configure your project name, |
66 | | -programming language, and template: |
67 | | - |
68 | | -<CLIDemo |
69 | | - initialCommand="iapp init" |
70 | | - asciiText="iApp" |
71 | | - :steps="[ |
72 | | - { |
73 | | - showAt: 2, |
74 | | - completeAt: 4, |
75 | | - question: 'What is your project name? (A folder with this name will be created)', |
76 | | - answer: 'hello-world', |
77 | | - showTyping: true, |
78 | | - isComplete: false |
79 | | - }, |
80 | | - { |
81 | | - showAt: 4, |
82 | | - completeAt: 6, |
83 | | - question: 'Which language do you want to use?', |
84 | | - answer: 'JavaScript', |
85 | | - options: [ |
86 | | - { label: 'JavaScript', selected: true }, |
87 | | - { label: 'Python', selected: false } |
88 | | - ], |
89 | | - highlighted: false, |
90 | | - isComplete: false |
91 | | - }, |
92 | | - { |
93 | | - showAt: 6, |
94 | | - completeAt: 8, |
95 | | - question: 'What kind of project do you want to init?', |
96 | | - answer: 'Hello World', |
97 | | - options: [ |
98 | | - { label: 'Hello World - iapp quick start', selected: true }, |
99 | | - { label: 'advanced', selected: false } |
100 | | - ], |
101 | | - highlighted: false, |
102 | | - isComplete: false |
103 | | - } |
104 | | - ]" |
105 | | - :completionStep="8" |
106 | | - :completionMessage="'Generating your iApp...'" |
107 | | - :completionItems="[ |
108 | | - '📁 Created hello-world/', |
109 | | - '📄 Added package.json', |
110 | | - '🐳 Added Dockerfile', |
111 | | - '⚙️ Added iExec configuration' |
112 | | - ]" |
113 | | - :successMessage="'Your iApp is ready!'" |
114 | | -/> |
115 | | - |
116 | | -After the interactive setup, continue with development and deployment: |
117 | | - |
118 | | -## Development and Testing |
119 | | - |
120 | | -Navigate to your project and run tests locally to simulate the TEE environment. |
121 | | -The CLI will build a Docker image, run your app, and show you the results: |
122 | | - |
123 | | -<CLIDemo |
124 | | - initialCommand="iapp test" |
125 | | - :steps="[ |
126 | | - { |
127 | | - showAt: 2, |
128 | | - question: 'No app secret is configured (from iapp.config.json)', |
129 | | - answer: '', |
130 | | - showTyping: false, |
131 | | - isComplete: true |
132 | | - }, |
133 | | - { |
134 | | - showAt: 3, |
135 | | - question: 'App docker image built (sha256:9cc0de820aaaf8f86700a3ec4082fe69b9e9a48a117ebb0ade0d82d0879cbe41)', |
136 | | - answer: '', |
137 | | - showTyping: false, |
138 | | - isComplete: true |
139 | | - }, |
140 | | - { |
141 | | - showAt: 4, |
142 | | - question: 'App docker image ran and exited successfully.', |
143 | | - answer: '', |
144 | | - showTyping: false, |
145 | | - isComplete: true |
146 | | - }, |
147 | | - { |
148 | | - showAt: 5, |
149 | | - completeAt: 6, |
150 | | - question: 'Would you like to see the app logs? (12 lines)', |
151 | | - answer: 'no', |
152 | | - options: [ |
153 | | - { label: 'yes', selected: false }, |
154 | | - { label: 'no', selected: true } |
155 | | - ], |
156 | | - highlighted: false, |
157 | | - showTyping: false, |
158 | | - isComplete: false |
159 | | - }, |
160 | | - { |
161 | | - showAt: 7, |
162 | | - question: 'Checked app output', |
163 | | - answer: '', |
164 | | - showTyping: false, |
165 | | - isComplete: true |
166 | | - }, |
167 | | - { |
168 | | - showAt: 8, |
169 | | - completeAt: 10, |
170 | | - question: 'Would you like to see the result? (View ./output/)', |
171 | | - answer: 'yes', |
172 | | - options: [ |
173 | | - { label: 'yes', selected: true }, |
174 | | - { label: 'no', selected: false } |
175 | | - ], |
176 | | - highlighted: false, |
177 | | - showTyping: false, |
178 | | - isComplete: false |
179 | | - } |
180 | | - ]" |
181 | | - :completionStep="11" |
182 | | - :completionMessage="'📁 output directory content:'" |
183 | | - :completionItems="[ |
184 | | - '└ computed.json', |
185 | | - '└ result.txt' |
186 | | - ]" |
187 | | - :successMessage="'hello world'" |
188 | | - :autoRestart="true" |
189 | | -/> |
190 | | - |
191 | | -## Deployment |
192 | | - |
193 | | -After your tests pass and the package is built, you can deploy your iApp to a |
194 | | -supported network. During deployment, you'll enter your DockerHub credentials, |
195 | | -specify your app version, and push both standard and TEE-compatible images: |
196 | | - |
197 | | -<CLIDemo |
198 | | - initialCommand="iapp deploy" |
199 | | - asciiText="Deploy" |
200 | | - :steps="[ |
201 | | - { |
202 | | - showAt: 2, |
203 | | - question: 'Using chain bellecour', |
204 | | - answer: '', |
205 | | - showTyping: false, |
206 | | - isComplete: true |
207 | | - }, |
208 | | - { |
209 | | - showAt: 3, |
210 | | - question: 'Using saved walletPrivateKey (from iapp.config.json)', |
211 | | - answer: '', |
212 | | - showTyping: false, |
213 | | - isComplete: true |
214 | | - }, |
215 | | - { |
216 | | - showAt: 4, |
217 | | - completeAt: 6, |
218 | | - question: 'What is your username on DockerHub? (It will be used to properly tag the Docker image)', |
219 | | - answer: 'bob', |
220 | | - showTyping: true, |
221 | | - isComplete: false |
222 | | - }, |
223 | | - { |
224 | | - showAt: 6, |
225 | | - completeAt: 8, |
226 | | - question: 'What is your DockerHub access token?', |
227 | | - answer: '**********************', |
228 | | - showTyping: true, |
229 | | - isComplete: false |
230 | | - }, |
231 | | - { |
232 | | - showAt: 8, |
233 | | - completeAt: 10, |
234 | | - question: 'What is the version of your iApp?', |
235 | | - answer: '0.0.1', |
236 | | - showTyping: true, |
237 | | - isComplete: false |
238 | | - }, |
239 | | - { |
240 | | - showAt: 10, |
241 | | - question: 'Docker image built (sha256:a53fc4c480f482c384a13266ea2cb6cc5572733c866c44a5f604f4bfab3a744a) and tagged bob/hello-world:0.0.1', |
242 | | - answer: '', |
243 | | - showTyping: false, |
244 | | - isComplete: true |
245 | | - }, |
246 | | - { |
247 | | - showAt: 11, |
248 | | - question: 'Pushed image bob/hello-world:0.0.1 on dockerhub', |
249 | | - answer: '', |
250 | | - showTyping: false, |
251 | | - isComplete: true |
252 | | - }, |
253 | | - { |
254 | | - showAt: 12, |
255 | | - question: 'Pushed TEE image bob/hello-world:0.0.1-tee-scone-5.9.1-v16-debug-ce3a01d9c5d7 on dockerhub', |
256 | | - answer: '', |
257 | | - showTyping: false, |
258 | | - isComplete: true |
259 | | - }, |
260 | | - { |
261 | | - showAt: 13, |
262 | | - question: 'TEE app deployed', |
263 | | - answer: '', |
264 | | - showTyping: false, |
265 | | - isComplete: true |
266 | | - } |
267 | | - ]" |
268 | | - :completionStep="14" |
269 | | - :completionMessage="'Deployment of your iApp completed successfully:'" |
270 | | - :completionItems="[ |
271 | | - '└ Docker image: bob/hello-world:0.0.1-tee-scone-5.9.1-v16-debug-ce3a01d9c5d7', |
272 | | - '└ iApp address: 0x1f80DCebc2EAAff0Db7156413C43B7e88D189923' |
273 | | - ]" |
274 | | - :successMessage="'Run iapp run 0x1f80DCebc2EAAff0Db7156413C43B7e88D189923 to execute your iApp on an iExec TEE worker'" |
275 | | - :autoRestart="true" |
276 | | -/> |
277 | | - |
278 | | -## Real Examples |
279 | | - |
280 | | -Here are some real-world examples of iApps to help you understand how they work |
281 | | -in practice. |
282 | | - |
283 | | -### Email Notification iApp |
284 | | - |
285 | | -This iApp lets you send updates to your contacts without ever seeing their email |
286 | | -addresses, privacy is preserved by design. |
287 | | - |
288 | | -::: code-group |
289 | | - |
290 | | -```js [Node.js] |
291 | | -/* User runs: "Send updates to my contacts about my project" */ |
292 | | -const contacts = loadProtectedData(); // User's protected contact list |
293 | | -contacts.forEach((contact) => { |
294 | | - sendEmail(contact, projectUpdateMessage); |
295 | | -}); |
296 | | -// → Emails sent directly, you never see the addresses |
297 | | -``` |
298 | | - |
299 | | -```python [Python] |
300 | | -# User runs: "Send updates to my contacts about my project" |
301 | | -contacts = load_protecteddata() # User's protected contact list |
302 | | -for contact in contacts: |
303 | | - send_email(contact, project_update_message) |
304 | | -# → Emails sent directly, you never see the addresses |
305 | | -``` |
306 | | - |
307 | | -::: |
308 | | - |
309 | | -### Oracle Update iApp |
310 | | - |
311 | | -This iApp securely updates a price oracle using private trading data, ensuring |
312 | | -sensitive information stays confidential. |
313 | | - |
314 | | -::: code-group |
315 | | - |
316 | | -```js [Node.js] |
317 | | -// User runs: "Update price oracle with my private trading data" |
318 | | -const tradingData = loadProtectedData(); // User's protected trading history |
319 | | -const averagePrice = calculateWeightedAverage(tradingData); |
320 | | -updateOracleContract(averagePrice); |
321 | | -// → Oracle updated with real data, trading history stays private |
322 | | -``` |
323 | | - |
324 | | -```python [Python] |
325 | | -# User runs: "Update price oracle with my private trading data" |
326 | | -trading_data = load_protecteddata() # User's protected trading history |
327 | | -average_price = calculate_weighted_average(trading_data) |
328 | | -update_oracle_contract(average_price) |
329 | | -# → Oracle updated with real data, trading history stays private |
330 | | -``` |
331 | | - |
332 | | -::: |
333 | | - |
334 | | -### Automated Transactions iApp |
335 | | - |
336 | | -This iApp automates monthly payments using protected payment details, so |
337 | | -financial information remains private. |
338 | | - |
339 | | -::: code-group |
340 | | - |
341 | | -```js [Node.js] |
342 | | -// User runs: "Automate payments every month" |
343 | | -const paymentInfo = loadProtectedData(); // User's payment details |
344 | | -for (let month = 0; month < 12; month++) { |
345 | | - processPayment(paymentInfo); |
346 | | -} |
347 | | -// → Payments processed, payment details stay private |
348 | | -``` |
349 | | - |
350 | | -```python [Python] |
351 | | -# User runs: "Automate payments every month" |
352 | | -payment_info = load_protecteddata() # User's payment details |
353 | | -for month in range(12): |
354 | | - process_payment(payment_info) |
355 | | -# → Payments processed, payment details stay private |
356 | | -``` |
357 | | - |
358 | | -::: |
359 | | - |
360 | | -<script setup> |
361 | | -import CLIDemo from '../../components/CLIDemo.vue'; |
362 | | -</script> |
0 commit comments