diff --git a/.vitepress/sidebar.ts b/.vitepress/sidebar.ts index e27784e4..e77aac5f 100644 --- a/.vitepress/sidebar.ts +++ b/.vitepress/sidebar.ts @@ -192,17 +192,13 @@ export function getSidebar() { text: 'Different Ways to Execute an iApp', link: '/guides/use-iapp/different-ways-to-execute', }, - { - text: 'Add Inputs to the Execution', - link: '/guides/use-iapp/add-inputs-to-execution', - }, { text: 'Use iApp with Protected Data', link: '/guides/use-iapp/use-iapp-with-protected-data', }, { - text: 'Find iApps to Use', - link: '/guides/use-iapp/find-iapps', + text: 'Add Inputs to the Execution', + link: '/guides/use-iapp/add-inputs-to-execution', }, { text: 'How to Pay the Executions', diff --git a/README.md b/README.md index 96b44dc9..cedd359a 100644 --- a/README.md +++ b/README.md @@ -139,6 +139,25 @@ Fork this repository and ensure you're working on the `main` branch: > - All pull requests are reviewed by our team before being merged > - Feel free to ask questions in the pull request if you need clarification +### Some conventions + +In order to keep the documentation consistent, we have some naming conventions +for input parameters: + +- `protectedData`: '0x123abc...', +- `protectedDataAddress`: '0x123abc...', +- `authorizedApp`: '0x456def...', +- `authorizedUser`: '0x789cba...', +- `userAddress`: '0x789cba...', +- `appWhitelist`: '0xba46d6...', +- `owner`: '0xa0c15e...', +- `newOwner`: '0xc5e9f4...', +- `voucherOwner`: '0x5714eB...', +- `renterAddress`: '0x246bdf...' +- `subscriberAddress`: '0x246bdf...' +- `workerpool`: '0xa5de76...' +- `taskId`: '0x7ac398...' + ## 🆘 Support - 📖 [Documentation](https://docs.iex.ec) diff --git a/package-lock.json b/package-lock.json index e84543e2..22226739 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "@wagmi/vue": "^0.1.24", "clsx": "^2.1.1", "figlet": "^1.8.2", + "iexec": "^8.18.0", "pinia": "^3.0.3", "reka-ui": "^2.4.1", "tailwind-merge": "^3.3.1", diff --git a/package.json b/package.json index 10d5c266..461cd501 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "@wagmi/vue": "^0.1.24", "clsx": "^2.1.1", "figlet": "^1.8.2", + "iexec": "^8.18.0", "pinia": "^3.0.3", "reka-ui": "^2.4.1", "tailwind-merge": "^3.3.1", diff --git a/src/assets/use-iapp/iexec-actors-diagram.svg b/src/assets/use-iapp/iexec-actors-diagram.svg new file mode 100644 index 00000000..31fc8b1e --- /dev/null +++ b/src/assets/use-iapp/iexec-actors-diagram.svg @@ -0,0 +1,103 @@ + +

Results

iExec Network

Workerpool

Application & Data

Requester

👤 Requester

📱 iApp

🔐 Protected Data

👨‍💻 iApp Developer

👤 Data Provider

🏭 Workerpool Manager

⚙️ Worker

💰 PoCo

📋 Deal

📤 Results

\ No newline at end of file diff --git a/src/guides/use-iapp/add-inputs-to-execution.md b/src/guides/use-iapp/add-inputs-to-execution.md index 0965928e..79469175 100644 --- a/src/guides/use-iapp/add-inputs-to-execution.md +++ b/src/guides/use-iapp/add-inputs-to-execution.md @@ -1,10 +1,338 @@ --- -title: Add Inputs to the Execution -description: Add inputs to the execution +title: Add Inputs to iApp Execution +description: + Learn how to provide arguments, files, secrets, and other inputs to iApp + executions --- -# Add Inputs to the Execution +# 📥 Add Inputs to iApp Execution -This page is under development. +iApps can accept various types of inputs to customize their behavior and provide +necessary data for processing. This guide covers all the different ways to add +inputs to your iApp executions using various iExec tools and SDKs. - +## Types of Inputs + +iExec supports several types of inputs for iApp executions: + +1. **Arguments**: Command-line arguments passed to the application +2. **Input Files**: URLs to public files that the app can download +3. **Secrets**: Sensitive data like API keys stored securely +4. **Protected Data**: Encrypted data processed within the TEE + +## Method 1: Adding Command-Line Arguments + +Command-line arguments are passed as a string to the iApp and are visible on the +blockchain. + +### Using SDK Library + +```ts twoslash +import { IExec, utils } from 'iexec'; + +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +// ---cut--- +// Basic arguments +const requestorderToSign = await iexec.order.createRequestorder({ + app: '0x456def...', + category: 0, + appmaxprice: 10, + workerpool: '0xa5de76...', // ENS address for iExec's debug workerpool + params: 'arg1 arg2 arg3', // Command-line arguments + // Other parameters have default values +}); +const requestOrder = await iexec.order.signRequestorder(requestorderToSign); + +// Fetch app orders +const appOrders = await iexec.orderbook.fetchAppOrderbook( + '0x456def...' // Filter by specific app +); +if (appOrders.orders.length === 0) { + throw new Error('No app orders found for the specified app'); +} + +// Fetch workerpool orders +const workerpoolOrders = await iexec.orderbook.fetchWorkerpoolOrderbook({ + workerpool: '0xa5de76...', // Filter by specific workerpool +}); +if (workerpoolOrders.orders.length === 0) { + throw new Error('No workerpool orders found for the specified workerpool'); +} + +// Execute the task +const taskId = await iexec.order.matchOrders({ + requestorder: requestOrder, + apporder: appOrders.orders[0].order, + workerpoolorder: workerpoolOrders.orders[0].order, +}); +``` + +### Using SDK CLI + +```bash +# Basic arguments +iexec app run 0x456def... --protectedData 0x123abc... --args "arg1 arg2" + +# Complex arguments with spaces +iexec app run 0x456def... --protectedData 0x123abc... --args "--input-file data.csv --output-format json" + +# Arguments with quotes (escape properly) +iexec app run 0x456def... --protectedData 0x123abc... --args "--message \"Hello World\" --config '{\"key\": \"value\"}'" +``` + +### Using DataProtector + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Process protected data with arguments +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + args: '--input-path data/input.csv --output-format json --verbose', +}); +``` + +## Method 2: Adding Input Files + +Input files are URLs to public files that the iApp can download during +execution. + +### Using SDK Library + +```ts twoslash +import { IExec, utils } from 'iexec'; + +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +// ---cut--- +// Single input file +const requestorderToSign = await iexec.order.createRequestorder({ + app: '0x456def...', + category: 0, // Required: category for the request + appmaxprice: 10, + workerpool: '0xa5de76...', // ENS address for iExec's debug workerpool + params: { + iexec_input_files: [ + 'https://example.com/config.json', + 'https://example.com/template.html', + 'https://example.com/data.csv', + ], + }, +}); +const requestOrder = await iexec.order.signRequestorder(requestorderToSign); + +// Fetch app orders +const appOrders = await iexec.orderbook.fetchAppOrderbook( + '0x456def...' // Filter by specific app +); +if (appOrders.orders.length === 0) { + throw new Error('No app orders found for the specified app'); +} + +// Fetch workerpool orders +const workerpoolOrders = await iexec.orderbook.fetchWorkerpoolOrderbook({ + workerpool: '0xa5de76...', // Filter by specific workerpool +}); +if (workerpoolOrders.orders.length === 0) { + throw new Error('No workerpool orders found for the specified workerpool'); +} + +// Execute the task +const taskId = await iexec.order.matchOrders({ + requestorder: requestOrder, + apporder: appOrders.orders[0].order, + workerpoolorder: workerpoolOrders.orders[0].order, +}); +``` + +### Using SDK CLI + +```bash +# Single input file +iexec app run 0x456def... --protectedData 0x123abc... --inputFiles "https://example.com/config.json" + +# Multiple input files (comma-separated) +iexec app run 0x456def... --protectedData 0x123abc... --inputFiles "https://example.com/config.json,https://example.com/template.html" + +# Multiple input files (space-separated) +iexec app run 0x456def... --protectedData 0x123abc... --inputFiles "https://example.com/config.json" --inputFiles "https://example.com/template.html" +``` + +### Using DataProtector + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Process protected data with input files +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + inputFiles: [ + 'https://raw.githubusercontent.com/user/repo/main/config.json', + 'https://example.com/public-data.csv', + ], +}); +``` + +## Method 3: Adding Secrets + +Secrets are sensitive data like API keys, passwords, or tokens that are stored +securely and made available to the iApp as environment variables. + +### Using SDK Library + +```ts twoslash [Browser] +// @errors: 2345 2739 7053 2339 +import { IExec, utils } from 'iexec'; + +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +// ---cut--- +// Basic secrets +const requestorderToSign = await iexec.order.createRequestorder({ + app: '0x456def...', + category: 0, // Required: category for the request + appmaxprice: 10, + workerpool: '0xa5de76...', // ENS address for iExec's debug workerpool + params: { + iexec_secrets: { + 1: 'api-key-12345', + 2: 'database-password', + }, + }, +}); +const requestOrder = await iexec.order.signRequestorder(requestorderToSign); + +// Fetch app orders +const appOrders = await iexec.orderbook.fetchAppOrderbook( + '0x456def...' // Filter by specific app +); +if (appOrders.orders.length === 0) { + throw new Error('No app orders found for the specified app'); +} + +// Fetch workerpool orders +const workerpoolOrders = await iexec.orderbook.fetchWorkerpoolOrderbook({ + workerpool: '0xa5de76...', // Filter by specific workerpool +}); +if (workerpoolOrders.orders.length === 0) { + throw new Error('No workerpool orders found for the specified workerpool'); +} + +// Execute the task +const taskId = await iexec.order.matchOrders({ + requestorder: requestOrder, + apporder: appOrders.orders[0].order, + workerpoolorder: workerpoolOrders.orders[0].order, +}); +``` + +### Using SDK CLI + +```bash +# Note: CLI doesn't support secrets directly for security reasons +# Use the SDK for secret management + +# Alternative: Use environment variables (less secure) +export IEXEC_SECRET_1="api-key-12345" +export IEXEC_SECRET_2="database-password" +iexec app run 0x456def... --protectedData 0x123abc... +``` + +### Using DataProtector + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Process protected data with secrets +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + secrets: { + 1: 'openai-api-key', + 2: 'database-password', + }, +}); +``` + +## Method 4: Specifying File Paths in Protected Data + +When working with protected data that contains multiple files, you can specify +which file to process. + +### Using DataProtector + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Process protected data with specific path +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + path: 'data/input.csv', +}); + +// Get result with specific path +const taskResult = await dataProtectorCore.getResultFromCompletedTask({ + taskId: '0x7ac398...', + path: 'output/analysis.json', +}); +``` + +You can combine different types of inputs for complex executions. + +## How Secrets Work in iApps + +Inside the iApp, secrets are available as environment variables: + +```python +# Python iApp example +import os + +api_key = os.environ.get('IEXEC_SECRET_1') # 'api-key-12345' +db_password = os.environ.get('IEXEC_SECRET_2') # 'database-password' +``` + +```javascript +// JavaScript iApp example +const apiKey = process.env.IEXEC_SECRET_1; // 'api-key-12345' +const dbPassword = process.env.IEXEC_SECRET_2; // 'database-password' +``` + +## Next Steps + +Now that you understand how to add inputs to iApp executions: + +- Learn about + [Using iApps with Protected Data](./use-iapp-with-protected-data.md) +- Explore [Different Ways to Execute](./different-ways-to-execute.md) iApps +- Check out our [How to Pay for Executions](./how-to-pay-executions.md) guide diff --git a/src/guides/use-iapp/different-ways-to-execute.md b/src/guides/use-iapp/different-ways-to-execute.md index a2efbf89..c9fbd30c 100644 --- a/src/guides/use-iapp/different-ways-to-execute.md +++ b/src/guides/use-iapp/different-ways-to-execute.md @@ -1,10 +1,114 @@ --- -title: Different Ways to Execute an iApp -description: Different ways to execute an iApp +title: Different Ways to Execute iApps +description: + Learn about various methods for executing iApps on the iExec network --- -# Different Ways to Execute an iApp +# ⚡ Different Ways to Execute iApps -This page is under development. +There are multiple ways to execute iApps on the iExec network. This guide covers +the basic execution methods. For advanced features like protected data, +arguments, and input files, see the dedicated guides. - +::: tip ENS Addresses + +**ENS (Ethereum Name Service)** is a naming system for Ethereum addresses that +allows you to use human-readable names instead of long hexadecimal addresses. +For example, instead of using `0x1234567890abcdef...`, you can use +`debug-v8-learn.main.pools.iexec.eth`. + +In the examples below, we use `debug-v8-learn.main.pools.iexec.eth` which is +iExec's official debug workerpool ENS address. This workerpool is specifically +designed for testing and development purposes on the Bellecour testnet. + +::: + +## Method 1: Using the iExec SDK Library + +The iExec SDK provides a modular JavaScript interface for executing iApps. + +```ts twoslash +import { IExec, utils } from 'iexec'; + +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +// ---cut--- +// Create & Sign a request order +const requestorderToSign = await iexec.order.createRequestorder({ + app: '0x456def...', // The iApp address + category: 0, +}); +const requestOrder = await iexec.order.signRequestorder(requestorderToSign); + +// Fetch app orders +const appOrders = await iexec.orderbook.fetchAppOrderbook( + '0x456def...' // Filter by specific app +); +if (appOrders.orders.length === 0) { + throw new Error('No app orders found for the specified app'); +} + +// Fetch workerpool orders +const workerpoolOrders = await iexec.orderbook.fetchWorkerpoolOrderbook({ + workerpool: '0xa5de76...', // Filter by specific workerpool +}); +if (workerpoolOrders.orders.length === 0) { + throw new Error('No workerpool orders found for the specified workerpool'); +} + +// Execute the task +const taskId = await iexec.order.matchOrders({ + requestorder: requestOrder, + apporder: appOrders.orders[0].order, + workerpoolorder: workerpoolOrders.orders[0].order, +}); +``` + +## Method 2: Using the iExec CLI + +The iExec CLI is perfect for quick executions and automation scripts. + +```bash +# Execute an iApp +iexec app run 0x456def... +``` + +## Method 3: Using the iApp Generator CLI + +The iApp Generator CLI provides a streamlined way to execute iApps, especially +for developers who have built their own iApps. + +> **Note**: For installation instructions, see the +> [iApp Generator Getting Started guide](/references/iapp-generator/getting-started). + +### Basic Execution + +```bash +# Execute a deployed iApp +iapp run 0x456def... +``` + +### Testing Before Execution + +```bash +# Test the iApp locally first +iapp test +``` + +## When to Use Each Method + +- **iExec Library**: For JavaScript applications and web3 integration +- **iExec CLI**: For quick testing and automation scripts +- **iApp Generator CLI**: For developers who have built their own iApps + +## Next Steps + +- Learn how to + [use iApps with protected data](./use-iapp-with-protected-data.md) +- Discover how to [add inputs to execution](./add-inputs-to-execution.md) +- Understand [how to pay for executions](./how-to-pay-executions.md) diff --git a/src/guides/use-iapp/find-iapps.md b/src/guides/use-iapp/find-iapps.md deleted file mode 100644 index 2353eed1..00000000 --- a/src/guides/use-iapp/find-iapps.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Find iApps to Use -description: Find iApps to Use ---- - -# Find iApps to Use - -This page is under development. - - diff --git a/src/guides/use-iapp/getting-started.md b/src/guides/use-iapp/getting-started.md index f0604249..cbd9667e 100644 --- a/src/guides/use-iapp/getting-started.md +++ b/src/guides/use-iapp/getting-started.md @@ -1,11 +1,96 @@ --- title: Getting Started with iApps description: - Your first steps to discover and execute existing iApps on the iExec platform + Learn the basics of finding and executing iApps on the iExec network --- -# 🚀 Getting Started +# 🚀 Getting Started with iApps -This page is under development. +Welcome to the world of secure, privacy-preserving computation! This guide gives +you a high-level overview of how to use iApps on the iExec network. - +## Prerequisites + +Before you begin, make sure you have: + +- A Web3 wallet (MetaMask, WalletConnect, etc.) +- Some RLC tokens for paying computation fees (or access to free vouchers + through learning programs) - [Learn about RLC tokens](/get-started/rlc) and + [how to bridge them](/get-started/tooling-and-explorers/bridge) + - **Note**: On Arbitrum, you'll need AETH (Arbitrum ETH) instead of RLC +- Basic understanding of blockchain transactions +- iExec SDK installed + +::: code-group + +```sh [npm] +npm install -g iexec +``` + +```sh [yarn] +yarn global add iexec +``` + +```sh [pnpm] +pnpm add -g iexec +``` + +```sh [bun] +bun add -g iexec +``` + +::: + +Ready to dive in? Let's get started with finding and executing your first iApp! + +## Overview: How to Use iApps + +Using iApps involves these main steps: + +1. **Find iApps** - Browse available applications in the + [iExec Explorer](/get-started/tooling-and-explorers/iexec-explorer) +2. **Prepare Data** - Set up any required protected data or inputs +3. **Execute** - Run the iApp +4. **Get Results** - Retrieve your computation results + +### Understanding Orders + +iApps are executed through a marketplace system where different actors publish +orders: + +- **App orders** - Published by developers with pricing and availability +- **Workerpool orders** - Published by computation providers with capacity and + pricing +- **Dataset orders** - Published by data owners with access conditions and + pricing + +When you execute an iApp, the system matches your request with available orders +from all three categories. For a deeper understanding of how orders work and how +to manage them, see the +[Build & Deploy guide](/build-iapp/guides/build-&-deploy) in the Build iApp +section. + +## Detailed Guides + +For step-by-step instructions, check out these guides: + +- **[Different Ways to Execute](./different-ways-to-execute.md)** - iExec cli, + lib, and other execution methods +- **[Use iApps with Protected Data](./use-iapp-with-protected-data.md)** - + Working with sensitive data securely +- **[Add Inputs to Execution](./add-inputs-to-execution.md)** - How to provide + data and parameters to iApps +- **[How to Pay for Executions](./how-to-pay-executions.md)** - Understanding + costs and payment options + +## Quick Start + +Ready to jump in? Follow the execution guides for detailed instructions on how +to use iApps. + + diff --git a/src/guides/use-iapp/how-to-pay-executions.md b/src/guides/use-iapp/how-to-pay-executions.md index 68a42d82..db41b230 100644 --- a/src/guides/use-iapp/how-to-pay-executions.md +++ b/src/guides/use-iapp/how-to-pay-executions.md @@ -1,10 +1,495 @@ --- -title: How to Pay the Executions -description: How to pay for executions +title: How to Pay for iApp Executions +description: + Learn about payment methods, pricing, and cost management for iApp executions --- -# How to Pay the Executions +# 💰 How to Pay for iApp Executions -This page is under development. +Understanding how to pay for iApp executions is crucial for using the iExec +network effectively. This guide covers all payment methods, pricing structures, +and cost management strategies. - +## Payment Methods Overview + +iExec supports multiple payment methods for executing iApps: + +1. **RLC Tokens**: Direct payment using RLC (Request Compute Language) tokens +2. **Vouchers**: Pre-funded vouchers for simplified payment +3. **Mixed Payment**: Combination of RLC and vouchers + +## Method 1: Paying with RLC Tokens + +RLC tokens are the native currency of the iExec network. You need to have RLC in +your wallet to pay for executions. + +### Setting Up RLC Payment + +#### Step 1: Get RLC Tokens + +You can obtain RLC tokens from various exchanges: + +- **Centralized Exchanges**: Binance, Coinbase, Kraken +- **Decentralized Exchanges**: Uniswap, SushiSwap +- **Direct Purchase**: Through iExec's official channels + +#### Step 2: Transfer to iExec Sidechain + +RLC tokens need to be on the iExec sidechain (Bellecour) for payments: + +```ts twoslash +import { IExec, utils } from 'iexec'; + +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +// ---cut--- +// Check your balance +const balance = await iexec.account.checkBalance('0xa0c15e...'); +console.log('Nano RLC staked:', balance.stake.toString()); +console.log('Nano RLC locked:', balance.locked.toString()); + +// Deposit RLC to the sidechain +await iexec.account.deposit(1_000_000_000); // Deposit 1 RLC +``` + +#### Step 3: Execute with RLC Payment + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Execute with RLC payment (default) +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + useVoucher: false, // Explicitly use RLC payment +}); +``` + +### Using CLI with RLC + +```bash +# Execute with RLC payment +iexec app run 0x456def... --protectedData 0xa0c15e... + +# Check your balance +iexec account show + +# Deposit RLC +iexec account deposit 100 +``` + +## Method 2: Paying with Vouchers + +Vouchers are pre-funded payment instruments that simplify the payment process +and can be shared with others. + +### Understanding Vouchers + +Vouchers are ERC-20 tokens that represent pre-funded computation credits on the +iExec network. They offer several advantages: + +- **Simplified Payment**: No need to manage RLC transfers +- **Sharing**: Can be shared with team members or users +- **Budget Control**: Set spending limits +- **Automated Top-up**: Can be configured to automatically refill + +### Using Vouchers for Payment + +#### Basic Voucher Usage + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + useVoucher: true, // Use voucher for payment +}); +``` + +::: tip + +If your voucher doesn't have enough xRLC to cover the deal, the SDK will +automatically get the required amount to your iExec account. Ensure that your +voucher is authorized to access your iExec account and that your account has +sufficient funds for this transfer to proceed. + +::: + +#### Using Someone Else's Voucher + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + useVoucher: true, + voucherOwner: '0x5714eB...', // Voucher owner's address +}); +``` + +::: warning + +Make sure the voucher's owner has authorized you to use it. This parameter must +be used in combination with `useVoucher: true`. + +::: + +#### CLI with Vouchers + +```bash +# Use your own voucher +iexec app run 0x456def... --protectedData 0xa0c15e... --useVoucher + +# Use someone else's voucher +iexec app run 0x456def... --protectedData 0xa0c15e... --useVoucher --voucherOwner 0x5714eB... +``` + +## Understanding Pricing + +### Cost Components + +iApp execution costs consist of several components: + +1. **Application Fee**: Paid to the app developer +2. **Data Fee**: Paid to the data owner (if using protected data) +3. **Workerpool Fee**: Paid to the computation provider +4. **Gas Fees**: Blockchain transaction costs + +### Setting Maximum Prices + +You can control costs by setting maximum prices for each component: + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + dataMaxPrice: 5, // Maximum amount (in nRLC) to pay the protected data owner + appMaxPrice: 3, // Maximum amount (in nRLC) to pay the iApp provider + workerpoolMaxPrice: 2, // Maximum amount (in nRLC) to pay the workerpool provider +}); +``` + +::: info + +All price parameters are in **nRLC** (nano RLC). The default value for all price +parameters is `0`, which means no maximum price limit is set. + +::: + +## Cost Management Strategies + +### 1. Monitor Your Balance + +Regularly check your RLC balance and voucher status: + +```ts twoslash +import { IExec, utils } from 'iexec'; + +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +const protectedDataAddress = '0x123abc...'; +// ---cut--- +// Check your balance +const balance = await iexec.account.checkBalance('0xa0c15e...'); +console.log('Nano RLC staked:', balance.stake.toString()); +console.log('Nano RLC locked:', balance.locked.toString()); + +// Check voucher balance (if applicable) +const myVoucher = await iexec.voucher.showUserVoucher('0xa0c15e...'); +console.log('Voucher info:', myVoucher); +``` + +### 2. Set Reasonable Price Limits + +Always set maximum prices to avoid unexpected costs: + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Good practice: Set explicit price limits +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + dataMaxPrice: 5, // Maximum for data access + appMaxPrice: 3, // Maximum for app usage + workerpoolMaxPrice: 2, // Maximum for computation +}); +``` + +### 3. Use Vouchers for Regular Usage + +For frequent executions, consider using vouchers: + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Use vouchers for regular operations +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + useVoucher: true, // Simplify payment process +}); +``` + +### 4. Batch Operations + +Group multiple executions to optimize costs: + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Execute multiple tasks efficiently +const tasks = [ + { protectedData: '0x123abc...', app: '0x456def...' }, + { protectedData: '0x124abc...', app: '0x456def...' }, +]; + +const results = await Promise.all( + tasks.map((task) => + dataProtectorCore.processProtectedData({ + ...task, + dataMaxPrice: 5, + appMaxPrice: 3, + workerpoolMaxPrice: 2, + useVoucher: true, + }) + ) +); +``` + +## Payment Troubleshooting + +### Insufficient Balance + +If you encounter insufficient balance errors: + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; +import { IExec, utils } from 'iexec'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +// ---cut--- +try { + const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + }); +} catch (error) { + if ( + error instanceof Error && + error.message.includes('insufficient balance') + ) { + console.log('Please add more RLC to your account'); + // Check balance and deposit more if needed + const balance = await iexec.account.checkBalance('0xa0c15e...'); + console.log('Nano RLC staked:', balance.stake.toString()); + console.log('Nano RLC locked:', balance.locked.toString()); + } +} +``` + +### Voucher Authorization Issues + +If voucher payment fails: + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +try { + const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + useVoucher: true, + voucherOwner: '0x5714eB...', + }); +} catch (error) { + if (error instanceof Error && error.message.includes('voucher')) { + console.log('Voucher authorization failed. Check voucher permissions.'); + } +} +``` + +### Price Too High Errors + +If execution fails due to price constraints: + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +try { + const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + dataMaxPrice: 2, // Low price limit + appMaxPrice: 1, + workerpoolMaxPrice: 1, + }); +} catch (error) { + if (error instanceof Error && error.message.includes('price')) { + console.log('Increase price limits or wait for lower prices'); + // Retry with higher prices + const retryResult = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + dataMaxPrice: 8, // Higher price limit + appMaxPrice: 5, + workerpoolMaxPrice: 3, + }); + } +} +``` + +## Best Practices + +### 1. Always Set Price Limits + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Never execute without price limits +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + dataMaxPrice: 5, // Always set price limits + appMaxPrice: 3, + workerpoolMaxPrice: 2, +}); +``` + +### 2. Use Vouchers for Production + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Use vouchers for production applications +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + useVoucher: true, // More reliable for production +}); +``` + +### 3. Monitor Costs Regularly + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; +import { IExec, utils } from 'iexec'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +// ---cut--- +// Check costs before and after execution +const balanceBefore = await iexec.account.checkBalance('0xa0c15e...'); +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + dataMaxPrice: 5, + appMaxPrice: 3, + workerpoolMaxPrice: 2, +}); +const balanceAfter = await iexec.account.checkBalance('0xa0c15e...'); +console.log( + 'Cost:', + balanceBefore.stake.toString(), + '->', + balanceAfter.stake.toString() +); +``` + +### 4. Handle Payment Errors Gracefully + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +const executeWithPaymentRetry = async (params: any, maxRetries = 3) => { + for (let i = 0; i < maxRetries; i++) { + try { + return await dataProtectorCore.processProtectedData(params); + } catch (error) { + if ( + error instanceof Error && + error.message.includes('insufficient balance') + ) { + console.log('Insufficient balance, please add more RLC'); + break; + } + if (i === maxRetries - 1) throw error; + console.log(`Payment retry ${i + 1}/${maxRetries}`); + await new Promise((resolve) => setTimeout(resolve, 1000)); + } + } +}; +``` + +## Next Steps + +Now that you understand payment methods: + +- Learn about [Adding Inputs to Execution](./add-inputs-to-execution.md) +- Explore [Using iApps with Protected Data](./use-iapp-with-protected-data.md) +- Review the pricing information above for detailed cost analysis diff --git a/src/guides/use-iapp/introduction.md b/src/guides/use-iapp/introduction.md index 3434e4f6..223cf203 100644 --- a/src/guides/use-iapp/introduction.md +++ b/src/guides/use-iapp/introduction.md @@ -1,12 +1,84 @@ --- title: Introduction to Using iApps description: - Learn how to discover, execute, and interact with iExec applications for - privacy-preserving computation + Learn how to use iExec Applications (iApps) to securely process protected data + in a privacy-safe environment --- -# 📝 Introduction +# 📝 Introduction to Using iApps -This page is under development. +In the iExec network, multiple actors work together in a coordinated process to +ensure secure, decentralized computation. Here's how the ecosystem operates: - +### Key Actors in the Network + +- **👤 Requesters**: Users who need computation performed on protected data +- **🏭 Workerpool Managers**: Operators who manage groups of workers and + coordinate task execution +- **⚙️ Workers**: Individual machines that execute the actual computations +- **👨‍💻 iApp Developers**: Developers who create and deploy applications to the + iExec marketplace +- **🔐 Data Providers**: Users who own and protect the data being processed + +### Network Assets + +- **📱 iApps**: Applications that process the data securely +- **💾 Data**: Protected information that needs to be processed +- **⚡ Computational Power**: Processing resources provided by workers +- **💰 PoCo**: Proof of Contribution system that matches all actors through + marketplace + +### Network Coordination + +The iExec network coordinates all actors through the PoCo (Proof of +Contribution) system, which automatically matches requesters with the +appropriate applications, data, and computational resources based on +availability, requirements, and pricing. + +### Deal Execution Flow + +When a deal is triggered, the following sequence occurs: + +1. **Request Creation**: Requester submits a computation request with parameters +2. **Resource Matching**: PoCo system matches the request with available + applications, data, and computational resources +3. **Deal Creation**: When compatible resources are found, a deal is created + containing multiple tasks +4. **Task Distribution**: Selected workerpool manager distributes tasks to their + workers +5. **Secure Execution**: Workers download the iApp and execute it in TEE + environments +6. **Data Processing**: iApp processes protected data without accessing raw + content +7. **Result Generation**: Computation results are generated +8. **Result Delivery**: Results are returned to the requester through the + network +9. **Payment Settlement**: RLC tokens are distributed to all participants + +### Network Architecture Diagram + +![iExec Network Actors](/assets/use-iapp/iexec-actors-diagram.svg) + +### Detailed Interaction Flow + +1. **Request Submission**: Requester creates a request specifying the iApp, + Protected Data, etc. +2. **PoCo Processing**: PoCo system validates the request and matches resources +3. **Deal Creation**: When resources are matched, PoCo creates a deal +4. **Secure Environment Setup**: Workers initialize TEE environments and + download the iApp +5. **Data Access**: iApp requests access to protected data through secure + channels +6. **Computation**: iApp processes data within the TEE, maintaining privacy +7. **Payment Distribution**: RLC tokens are distributed to all participants + based on completed tasks + +This decentralized architecture ensures that no single entity has control over +the entire process, while the use of TEEs guarantees that sensitive data remains +protected throughout the computation. + +## Getting Started + +Ready to start using iApps? Check out our +[Getting Started Guide](./getting-started.md) to learn how to find, execute, and +interact with iApps on the iExec network. diff --git a/src/guides/use-iapp/use-iapp-with-protected-data.md b/src/guides/use-iapp/use-iapp-with-protected-data.md index 74467330..1b7ea5d9 100644 --- a/src/guides/use-iapp/use-iapp-with-protected-data.md +++ b/src/guides/use-iapp/use-iapp-with-protected-data.md @@ -1,10 +1,460 @@ --- -title: Use iApp with Protected Data -description: Use iApp with Protected Data +title: Use iApps with Protected Data +description: + Learn how to securely process protected data using iApps on the iExec network --- -# Use iApp with Protected Data +# 🔒 Use iApps with Protected Data -This page is under development. +Protected data is the cornerstone of privacy-preserving computation on iExec. +This guide shows you how to use iApps with protected data, from granting access +to processing and retrieving results. - +## Understanding Protected Data and iApps + +Protected data is encrypted information that can only be processed by authorized +iApps within Trusted Execution Environments (TEEs). The data remains +confidential throughout the entire computation process. + +### The Workflow + +1. **Protect Your Data**: Encrypt sensitive information using the Data Protector +2. **Grant Access**: Authorize specific iApps to process your data +3. **Execute iApp**: Run the iApp with your protected data +4. **Retrieve Results**: Get the computation results while data remains private + +## Step 1: Protect Your Data + +Before using an iApp, you need to protect your sensitive data. + +### Basic Data Protection + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Protect your data +const { address: protectedDataAddress } = await dataProtectorCore.protectData({ + name: 'My Sensitive Data', + data: { + email: 'user@example.com', + apiKey: 'secret-api-key-12345', + preferences: { + theme: 'dark', + notifications: true, + }, + }, +}); +``` + +### Protecting Different Data Types + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Protect contact list for email applications +const { address: contactListAddress } = await dataProtectorCore.protectData({ + name: 'Email Contact List', + data: { + contacts: { + '0x123abc...': 'john@example.com', + '0x456def...': 'jane@example.com', + '0x789ghi...': 'bob@example.com', + }, + }, +}); + +// Protect trading data for oracle applications +const { address: tradingDataAddress } = await dataProtectorCore.protectData({ + name: 'Trading History', + data: { + trades: { + '2024-01-01': { price: 50000, volume: 100 }, + '2024-01-02': { price: 51000, volume: 150 }, + '2024-01-03': { price: 49000, volume: 200 }, + }, + }, +}); + +// Protect financial data for payment applications +const { address: paymentDataAddress } = await dataProtectorCore.protectData({ + name: 'Payment Information', + data: { + bankAccount: '1234567890', + routingNumber: '987654321', + accountHolder: 'John Doe', + }, +}); +``` + +## Step 2: Grant Access to iApps + +iApps need explicit authorization to access your protected data. + +### Grant Access to a Specific iApp + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Grant access to an iApp +const grantedAccess = await dataProtectorCore.grantAccess({ + protectedData: '0x123abc...', + authorizedApp: '0x456def...', // The iApp address + authorizedUser: '0x789abc...', // Your wallet address + pricePerAccess: 5, // Price per access in nRLC + numberOfAccess: 10, // Number of allowed accesses +}); +``` + +### Check Granted Access + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Check what access you've granted +const grantedAccessList = await dataProtectorCore.getGrantedAccess({ + protectedData: '0x123abc...', + authorizedApp: '0x456def...', + authorizedUser: '0x789abc...', +}); +``` + +## Step 3: Execute iApp with Protected Data + +Once access is granted, you can execute the iApp with your protected data. + +### Using DataProtector + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Execute iApp with protected data +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', // The iApp address +}); +``` + +### Using SDK Library + +```ts twoslash +import { IExec, utils } from 'iexec'; + +const ethProvider = utils.getSignerFromPrivateKey( + 'bellecour', // blockchain node URL + 'PRIVATE_KEY' +); +const iexec = new IExec({ + ethProvider, +}); +const protectedDataAddress = '0x123abc...'; +// ---cut--- +// Create & Sign a request order with protected data +const requestorderToSign = await iexec.order.createRequestorder({ + app: '0x456def...', // The iApp address + category: 0, + appmaxprice: 10, // Maximum price in nRLC + dataset: protectedDataAddress, // Protected data address + datasetmaxprice: 5, // Maximum price for dataset access + workerpool: '0xa5de76...', // ENS address for iExec's debug workerpool +}); +const requestOrder = await iexec.order.signRequestorder(requestorderToSign); + +// Fetch app orders +const appOrders = await iexec.orderbook.fetchAppOrderbook( + '0x456def...' // Filter by specific app +); +if (appOrders.orders.length === 0) { + throw new Error('No app orders found for the specified app'); +} + +// Fetch protected data orders +const datasetOrders = await iexec.orderbook.fetchDatasetOrderbook( + protectedDataAddress // Filter by specific dataset +); +if (datasetOrders.orders.length === 0) { + throw new Error( + 'No protectedData orders found for the specified protectedData' + ); +} + +// Fetch workerpool orders +const workerpoolOrders = await iexec.orderbook.fetchWorkerpoolOrderbook({ + workerpool: '0xa5de76...', // Filter by specific workerpool +}); +if (workerpoolOrders.orders.length === 0) { + throw new Error('No workerpool orders found for the specified workerpool'); +} + +// Execute the task +const taskId = await iexec.order.matchOrders({ + requestorder: requestOrder, + apporder: appOrders.orders[0].order, + datasetorder: datasetOrders.orders[0].order, + workerpoolorder: workerpoolOrders.orders[0].order, +}); +``` + +### Using iExec CLI with Protected Data + +```bash +# Execute with protected data +iexec app run 0x456def... --dataset 0x123abc... +``` + +## Step 4: Retrieve Results + +After execution completes, retrieve the results from the task. + +### Using DataProtector + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +const taskId = '0x7ac398...'; + +// ---cut--- +// Retrieve the result +const taskResult = await dataProtectorCore.getResultFromCompletedTask({ + taskId: taskId, +}); +``` + +### Using iExec CLI + +```bash +# Get the task ID from the execution result +TASK_ID="0x7ac398..." + +# Retrieve the result +iexec task show $TASK_ID + +# Retrieve a specific file from the result +iexec task show $TASK_ID --path "computed.json" +``` + +## Real-World Examples + +### Example 1: Data Analysis System + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// 1. Protect sensitive dataset +const { address: datasetAddress } = await dataProtectorCore.protectData({ + name: 'Customer Analytics Data', + data: { + customers: { + '0': { id: 1, purchases: 1500, category: 'premium' }, + '1': { id: 2, purchases: 800, category: 'standard' }, + '2': { id: 3, purchases: 2200, category: 'premium' }, + }, + }, +}); + +// 2. Grant access to analytics iApp +await dataProtectorCore.grantAccess({ + protectedData: datasetAddress, + authorizedApp: '0xanalytics...', // Analytics iApp address + authorizedUser: '0x789abc...', + pricePerAccess: 3, + numberOfAccess: 50, +}); + +// 3. Execute data analysis +const analysisResult = await dataProtectorCore.processProtectedData({ + protectedData: datasetAddress, + app: '0xanalytics...', + args: '--analyze-customer-segments --output-format json', + appMaxPrice: 10, +}); +``` + +### Example 2: Oracle Price Update + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// 1. Protect trading data +const { address: tradingDataAddress } = await dataProtectorCore.protectData({ + name: 'Trading Data', + data: { + trades: { + '2024-01-01': { price: 50000, volume: 100 }, + '2024-01-02': { price: 51000, volume: 150 }, + }, + }, +}); + +// 2. Grant access to oracle iApp +await dataProtectorCore.grantAccess({ + protectedData: tradingDataAddress, + authorizedApp: '0xoracle...', // Oracle iApp address + authorizedUser: '0x789abc...', + pricePerAccess: 5, + numberOfAccess: 100, +}); + +// 3. Execute oracle update +const oracleResult = await dataProtectorCore.processProtectedData({ + protectedData: tradingDataAddress, + app: '0xoracle...', + args: '--update-price-feed --asset ETH', + appMaxPrice: 10, +}); +``` + +### Example 3: Automated Payment Processing + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// 1. Protect payment data +const { address: paymentDataAddress } = await dataProtectorCore.protectData({ + name: 'Payment Data', + data: { + bankAccount: '1234567890', + routingNumber: '987654321', + accountHolder: 'John Doe', + monthlyAmount: 1000, + }, +}); + +// 2. Grant access to payment iApp +await dataProtectorCore.grantAccess({ + protectedData: paymentDataAddress, + authorizedApp: '0xpayment...', // Payment iApp address + authorizedUser: '0x789abc...', + pricePerAccess: 2, + numberOfAccess: 12, // Monthly payments +}); + +// 3. Execute payment processing +const paymentResult = await dataProtectorCore.processProtectedData({ + protectedData: paymentDataAddress, + app: '0xpayment...', + args: '--process-monthly-payment', + secrets: { + 1: 'bank-api-key', + }, + appMaxPrice: 8, +}); +``` + +## Best Practices + +### 1. Always Grant Access Before Execution + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +const protectedDataAddress = '0x123abc...'; +// ---cut--- +// Grant access first +await dataProtectorCore.grantAccess({ + protectedData: protectedDataAddress, + authorizedApp: '0x456def...', + authorizedUser: '0x789abc...', + pricePerAccess: 5, + numberOfAccess: 10, +}); + +const result = await dataProtectorCore.processProtectedData({ + protectedData: protectedDataAddress, + app: '0x456def...', + appMaxPrice: 10, +}); +``` + +### 2. Monitor Access Usage + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Check access usage regularly +const grantedAccess = await dataProtectorCore.getGrantedAccess({ + protectedData: '0x123abc...', + authorizedApp: '0x456def...', + authorizedUser: '0x789abc...', +}); + +console.log('Remaining access:', grantedAccess.count); +``` + +### 3. Use Appropriate Price Limits + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Set reasonable price limits +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + appMaxPrice: 10, // Set appropriate limit +}); +``` + +### 4. Handle Results Properly + +```ts twoslash +import { IExecDataProtectorCore, getWeb3Provider } from '@iexec/dataprotector'; + +const web3Provider = getWeb3Provider('PRIVATE_KEY'); +const dataProtectorCore = new IExecDataProtectorCore(web3Provider); +// ---cut--- +// Store task ID and retrieve results later +const result = await dataProtectorCore.processProtectedData({ + protectedData: '0x123abc...', + app: '0x456def...', + appMaxPrice: 10, +}); + +// Store task ID for later retrieval +const taskId = result.taskId; + +// Later, retrieve the result +const taskResult = await dataProtectorCore.getResultFromCompletedTask({ + taskId: taskId, +}); +``` + +## Next Steps + +Now that you understand how to use iApps with protected data: + +- Learn about [Different Ways to Execute](./different-ways-to-execute.md) iApps +- Explore [How to Pay for Executions](./how-to-pay-executions.md) +- Check out our [Add Inputs to Execution](./add-inputs-to-execution.md) guide