diff --git a/.vitepress/sidebar.ts b/.vitepress/sidebar.ts
index 2033d5d3..25e30257 100644
--- a/.vitepress/sidebar.ts
+++ b/.vitepress/sidebar.ts
@@ -197,12 +197,8 @@ export function getSidebar() {
link: '/guides/use-iapp/how-to-pay-executions',
},
{
- text: 'Run iApp with ProtectedData',
- link: '/guides/use-iapp/run-iapp-with-ProtectedData',
- },
- {
- text: 'Run iApp without ProtectedData',
- link: '/guides/use-iapp/run-iapp-without-ProtectedData',
+ text: 'Run iApp',
+ link: '/guides/use-iapp/run-iapp',
},
{
text: 'Integrate Web3 Messaging',
@@ -281,17 +277,69 @@ export function getSidebar() {
link: '/references/iapp-generator/getting-started',
},
{
- text: 'Building your iApp',
- link: '/references/iapp-generator/building-your-iexec-app',
+ text: 'CLI',
+ collapsed: true,
+ items: [
+ {
+ text: 'Getting Started',
+ link: '/references/iapp-generator/cli/getting-started',
+ },
+ {
+ text: 'Building your iApp',
+ link: '/references/iapp-generator/cli/building-your-iexec-app',
+ },
+ {
+ text: 'Deserialize ProtectedData',
+ link: '/references/iapp-generator/cli/deserializer',
+ collapsed: true,
+ items: [
+ {
+ text: 'getValue',
+ link: '/references/iapp-generator/cli/deserializer/getValue',
+ },
+ ],
+ },
+ ],
},
{
- text: 'Deserialize ProtectedData',
- link: '/references/iapp-generator/deserializer',
+ text: 'SDK',
collapsed: true,
items: [
{
- text: 'getValue',
- link: '/references/iapp-generator/deserializer/getValue',
+ text: 'getIApp',
+ link: '/references/iapp-generator/sdk/getIApp',
+ },
+ {
+ text: 'transferOwnership',
+ link: '/references/iapp-generator/sdk/transferOwnership',
+ },
+ {
+ text: 'grantAccess',
+ link: '/references/iapp-generator/sdk/grantAccess',
+ },
+ {
+ text: 'getGrantedAccess',
+ link: '/references/iapp-generator/sdk/getGrantedAccess',
+ },
+ {
+ text: 'revokeOneAccess',
+ link: '/references/iapp-generator/sdk/revokeOneAccess',
+ },
+ {
+ text: 'revokeAllAccess',
+ link: '/references/iapp-generator/sdk/revokeAllAccess',
+ },
+ {
+ text: 'runIApp',
+ link: '/references/iapp-generator/sdk/runIApp',
+ },
+ {
+ text: 'getResultFromCompletedTask',
+ link: '/references/iapp-generator/sdk/getResultFromCompletedTask',
+ },
+ {
+ text: 'Types',
+ link: '/references/iapp-generator/sdk/types',
},
],
},
diff --git a/package-lock.json b/package-lock.json
index 1b43ef1c..bdf58e37 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -12,6 +12,7 @@
"@iexec/dataprotector-deserializer": "^0.1.1",
"@iexec/web3mail": "^1.6.0",
"@iexec/web3telegram": "^0.1.0-alpha.4",
+ "@mage-sombre/iapp": "^1.0.0-beta.2",
"@reown/appkit": "^1.7.17",
"@reown/appkit-adapter-wagmi": "^1.7.17",
"@tailwindcss/vite": "^4.1.11",
@@ -1338,6 +1339,21 @@
"@lit-labs/ssr-dom-shim": "^1.4.0"
}
},
+ "node_modules/@mage-sombre/iapp": {
+ "version": "1.0.0-beta.2",
+ "resolved": "https://registry.npmjs.org/@mage-sombre/iapp/-/iapp-1.0.0-beta.2.tgz",
+ "integrity": "sha512-MYTxl4HNqFp6kezvdavzcF7s4EGuPrNZT55rG3Xp6JniYE78e0rNn5DpUppG/EZzWUI85UDvj9TYj0VOSRcWkQ==",
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@ethersproject/bytes": "^5.7.0",
+ "@ethersproject/random": "^5.7.0",
+ "@iexec/dataprotector": "^2.0.0-beta.19",
+ "ethers": "^6.13.2",
+ "graphql-request": "^6.0.0",
+ "iexec": "^8.18.0",
+ "yup": "^1.1.1"
+ }
+ },
"node_modules/@mermaid-js/mermaid-mindmap": {
"version": "9.3.0",
"resolved": "https://registry.npmjs.org/@mermaid-js/mermaid-mindmap/-/mermaid-mindmap-9.3.0.tgz",
diff --git a/package.json b/package.json
index faf1a13b..a45d6413 100644
--- a/package.json
+++ b/package.json
@@ -15,6 +15,7 @@
"@iexec/dataprotector-deserializer": "^0.1.1",
"@iexec/web3mail": "^1.6.0",
"@iexec/web3telegram": "^0.1.0-alpha.4",
+ "@mage-sombre/iapp": "^1.0.0-beta.2",
"@reown/appkit": "^1.7.17",
"@reown/appkit-adapter-wagmi": "^1.7.17",
"@tailwindcss/vite": "^4.1.11",
diff --git a/src/get-started/helloWorld/3-buildIApp.md b/src/get-started/helloWorld/3-buildIApp.md
index f578e3b7..55d36b58 100644
--- a/src/get-started/helloWorld/3-buildIApp.md
+++ b/src/get-started/helloWorld/3-buildIApp.md
@@ -27,7 +27,7 @@ experience.
## 📋 Prerequisites
Before getting started, make sure you have the required tools installed. See the
-[iApp Generator Getting Started guide](/references/iapp-generator/getting-started)
+[iApp Generator Getting Started guide](/references/iapp-generator/cli/getting-started)
for detailed prerequisites and installation instructions.
::: info
diff --git a/src/get-started/toolkit.md b/src/get-started/toolkit.md
index e39ba702..327cbb9b 100644
--- a/src/get-started/toolkit.md
+++ b/src/get-started/toolkit.md
@@ -24,7 +24,7 @@ just a few commands, let free your imagination.
### Get Started
Jump right into building with our comprehensive guide:
-[Building Your iApp →](/references/iapp-generator/building-your-iexec-app.md)
+[Building Your iApp →](/references/iapp-generator/cli/building-your-iexec-app.md)
## DataProtector-SDK
diff --git a/src/guides/build-iapp/build-&-test.md b/src/guides/build-iapp/build-&-test.md
index 757fa4da..79b8d7d6 100644
--- a/src/guides/build-iapp/build-&-test.md
+++ b/src/guides/build-iapp/build-&-test.md
@@ -30,7 +30,7 @@ iApp Generator handles all the low-level complexity for you.
## Prerequisites
Before getting started, make sure you have the required tools installed. See the
-[iApp Generator Getting Started guide](/references/iapp-generator/getting-started)
+[iApp Generator Getting Started guide](/references/iapp-generator/cli/getting-started)
for detailed prerequisites and installation instructions.
## Quick Start
@@ -164,8 +164,7 @@ The CLI will build a Docker image, run your app, and show you the results:
## Next Steps
-- When everything is ready
- [deploy and run your iApp](/guides/use-iapp/run-iapp-with-ProtectedData)
+- When everything is ready [deploy and run your iApp](/guides/use-iapp/run-iapp)
diff --git a/src/references/iapp-generator/sdk/getIApp.md b/src/references/iapp-generator/sdk/getIApp.md
new file mode 100644
index 00000000..adb1d836
--- /dev/null
+++ b/src/references/iapp-generator/sdk/getIApp.md
@@ -0,0 +1,177 @@
+---
+title: getIApp
+description:
+ Retrieve all iApps for a specific owner or filter by creation date with the
+ getIApp method in iExec iApp Generator SDK. Easily access iApp metadata and
+ information, sorted by creation date.
+---
+
+# getIApp
+
+This method allows the user to retrieve all iApps for a given owner or filter by
+creation timestamp.
+
+Results are ordered by `creationTimestamp` desc.
+
+::: tip
+
+An iApp is a confidential computing application that runs in secure TEE
+environments. The method returns iApp metadata including name, address, owner,
+and creation timestamp.
+
+:::
+
+## Usage
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const listIApps = await iapp.getIApp({
+ owner: '0xa0c15e...',
+ createdAfterTimestamp: 1640995200,
+ page: 1,
+ pageSize: 20,
+});
+```
+
+## Parameters
+
+```ts twoslash
+import { type GetIAppParams } from '@mage-sombre/iapp';
+```
+
+### iapp
+
+**Type:** `AddressOrENS`
+
+Returns the iApp associated with this address.
+Returns an empty array if the iApp is not found.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const oneIApp = await iapp.getIApp({
+ iapp: '0x456def....', // [!code focus]
+});
+```
+
+### owner
+
+**Type:** `AddressOrENS`
+
+Returns all iApps owned by this address.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const iAppsByOwner = await iapp.getIApp({
+ owner: '0xa0c15e...', // [!code focus]
+});
+```
+
+### createdAfterTimestamp
+
+**Type:** `number`
+
+Returns all iApps created after this timestamp (Unix timestamp in seconds).
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const recentIApps = await iapp.getIApp({
+ createdAfterTimestamp: 1640995200, // [!code focus]
+});
+```
+
+### page
+
+**Type:** `number`
+**Default:** `0`
+
+Specifies the page number of the result set to return. Pages are zero-based
+indexed.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const iAppsPage = await iapp.getIApp({
+ page: 1, // [!code focus]
+ pageSize: 20,
+});
+```
+
+### pageSize
+
+**Type:** `number`
+**Default:** `20`
+
+Specifies the number of records to include in each page of the result set.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const iAppsPage = await iapp.getIApp({
+ page: 1,
+ pageSize: 50, // [!code focus]
+});
+```
+
+## Return Value
+
+```ts twoslash
+import { type IApp } from '@mage-sombre/iapp';
+```
+
+The method returns an array of `IApp` objects containing the following fields:
+
+### name
+
+`string`
+
+The name of the iApp.
+
+### address
+
+`Address`
+
+The Ethereum address of the iApp.
+
+### owner
+
+`Address`
+
+The Ethereum address of the iApp owner.
+
+### creationTimestamp
+
+`number`
+
+The Unix timestamp (in seconds) when the iApp was created.
+
+### multiaddr
+
+`string` (optional)
+
+The multiaddress for P2P communication with the iApp.
+
+
diff --git a/src/references/iapp-generator/sdk/getResultFromCompletedTask.md b/src/references/iapp-generator/sdk/getResultFromCompletedTask.md
new file mode 100644
index 00000000..2b2b2d9e
--- /dev/null
+++ b/src/references/iapp-generator/sdk/getResultFromCompletedTask.md
@@ -0,0 +1,141 @@
+---
+title: getResultFromCompletedTask
+description:
+ Retrieve the result of a completed task with iExec's
+ getResultFromCompletedTask method. Easily access task outcomes by providing
+ the task ID.
+---
+
+# getResultFromCompletedTask
+
+Method to get the result of a completed task.
+
+## Usage
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const completedTaskResult = await iapp.getResultFromCompletedTask({
+ taskId: '0x7ac398...',
+});
+```
+
+## Parameters
+
+```ts twoslash
+import { type GetResultFromCompletedTaskParams } from '@mage-sombre/iapp';
+```
+
+### taskId
+
+**Type:** `Address`
+
+Address of the task ID data you'd like to get the result from.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const completedTaskResult = await iapp.getResultFromCompletedTask({
+ taskId: '0x7ac398...', // [!code focus]
+});
+```
+
+### path
+
+**Type:** `string`
+
+Under the hood, a protected data is a zip file. With this `path` parameter, you
+can specify the file you're interested in. The zip file will be uncompressed for
+you, and only the desired file will be given as the `result`.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const completedTaskResult = await iapp.getResultFromCompletedTask({
+ taskId: '0x7ac398...',
+ path: 'content', // [!code focus]
+});
+```
+
+### pemPrivateKey
+
+**Type:** `string`
+
+If you have previously saved or generated a RSA keypair, you can reuse it in
+further calls.
+
+It needs to be the private key corresponding to the public key initially used to
+encrypt the protected data.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const completedTaskResult = await iapp.getResultFromCompletedTask({
+ taskId: '0x7ac398...',
+ pemPrivateKey: '-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----', // [!code focus]
+});
+```
+
+### onStatusUpdate
+
+**Type:** `OnStatusUpdateFn`
+
+Callback function to be notified at intermediate steps.
+
+
+```ts twoslash
+import {
+ IExecIApp,
+ getWeb3Provider,
+} from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const completedTaskResult =
+ await iapp.getResultFromCompletedTask({
+ taskId: '0x7ac398...',
+ onStatusUpdate: ({ title, isDone }) => { // [!code focus]
+ console.log(title, isDone); // [!code focus]
+ }, // [!code focus]
+ });
+```
+
+
+You can expect this callback function to be called with the following titles:
+
+```ts
+'CONSUME_RESULT_DOWNLOAD';
+'CONSUME_RESULT_DECRYPT';
+```
+
+Once with `isDone: false`, and then with `isDone: true`
+
+## Return Value
+
+```ts twoslash
+import { type GetResultFromCompletedTaskResponse } from '@mage-sombre/iapp';
+```
+
+### result
+
+`ArrayBuffer`
+
+The actual content of the protected file.
+
+
diff --git a/src/references/iapp-generator/sdk/grantAccess.md b/src/references/iapp-generator/sdk/grantAccess.md
new file mode 100644
index 00000000..3ca890f0
--- /dev/null
+++ b/src/references/iapp-generator/sdk/grantAccess.md
@@ -0,0 +1,265 @@
+---
+title: grantAccess
+description:
+ Grant secure access to an iApp with iExec's grantAccess method. Authorize
+ specific protected data or users to use the iApp, with customizable access
+ limits and pricing.
+---
+
+# grantAccess
+
+iApps require explicit authorization for runtime access. A newly created `iApp`
+has no inherent authorizations. This method grants permission to securely access
+the specified `iApp` for processing. Authorization to use the `iApp` is given to
+a user in the context of protected data (or a designated list of protected
+data).
+
+## Usage
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const grantedAccess = await iapp.grantAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...',
+ pricePerAccess: 3,
+ numberOfAccess: 10,
+ onStatusUpdate: ({ title, isDone }) => {
+ console.log(title, isDone);
+ },
+});
+```
+
+## Parameters
+
+```ts twoslash
+import { type GrantAccessParams } from '@mage-sombre/iapp';
+```
+
+### iapp
+
+**Type:** `AddressOrENS`
+
+The ethereum address of the iApp you wish to grant access to. **You must own
+this iApp** to grant access.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const grantedAccess = await iapp.grantAccess({
+ iapp: '0x456def....', // [!code focus]
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...',
+});
+```
+
+### authorizedProtectedData
+
+**Type:** `AddressOrENS`
+
+The address of the protected data you wish to authorize to use the `iApp` within
+a secure execution environment. You may specify either a single protected data
+or a protected data whitelist. To specify a whitelist, you provide the ETH
+address of an
+[iExec Whitelist Smart Contract](https://github.com/iExecBlockchainComputing/whitelist-smart-contract/tree/main).
+This smart contract should aggregates multiple application versions. This allows
+you to introduce new versions of your application without needing to grant
+access for the `protectedData` each time you do so.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const grantedAccess = await iapp.grantAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...', // [!code focus]
+ authorizedUser: '0x789cba...',
+});
+```
+
+::: tip
+
+You may authorize a specific protected data or a whitelist of protected data to
+use the iApp.
+
+The latest version of the iExec Web3Mail decentralized application is
+`{{web3MailAddress}}`.
+
+iExec also maintains a whitelist for current and past versions of Web3Mail iApp.
+Granting access to this whitelist allows use of an email `protectedData` with
+all versions of the Web3Mail application, ensuring you only have to grant this
+access once. The ETH address for this whitelist is **{{web3MailAppWhitelist}}**.
+
+:::
+
+### authorizedUser
+
+**Type:** `AddressOrENS`
+
+The address of the user you wish to authorize to use the `iApp`. Note that these
+users may not view or manipulate the data. This only grants permission for the
+user to submit the protected data to the iApp.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const grantedAccess = await iapp.grantAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...', // [!code focus]
+});
+```
+
+::: tip
+
+You may authorize all users to use the iApp by setting this to
+**0x0000000000000000000000000000000000000000**.
+
+:::
+
+### pricePerAccess
+
+**Type:** `number`
+**Default:** `0`
+
+Specifies the usage fee in nano RLC (nRLC) associated with each access of the
+iApp. It represents the cost incurred for each individual interaction with the
+iApp.
+
+By invoking the grantAccess method with a specific `pricePerAccess` you define
+the fee that the specified user (`authorizedUser` parameter) must pay for each
+access to the iApp when used with the specified protected data
+(`authorizedProtectedData` parameter).
+
+The fee is paid to the owner of the iApp.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const grantedAccess = await iapp.grantAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...',
+ pricePerAccess: 3, // [!code focus]
+ numberOfAccess: 10,
+});
+```
+
+::: tip
+
+`pricePerAccess` is expressed in nano RLC (nRLC). nRLC is the smallest
+subdivision of the RLC token, 1 RLC equals to 10^9 nRLC.
+
+When provided, `pricePerAccess` must be a non-negative integer value.
+
+:::
+
+### numberOfAccess
+
+**Type:** `number`
+**Default:** `1`
+
+Allows restricting the number of times the iApp may be accessed and used.
+
+It is not technically possible to set an unlimited number of accesses, but you
+can set `numberOfAccess` to `10000` for example.
+
+::: info
+
+If you attempt to access the iApp more times than specified in `numberOfAccess`,
+you will encounter a **"no dataset orders"** error.
+
+To prevent this error, ensure the `numberOfAccess` is properly set when calling
+the `grantAccess` method.
+
+:::
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const grantedAccess = await iapp.grantAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...',
+ pricePerAccess: 3,
+ numberOfAccess: 10, // [!code focus]
+});
+```
+
+### onStatusUpdate
+
+**Type:** `OnStatusUpdateFn`
+
+Callback function to be notified at intermediate steps.
+
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const grantedAccess = await iapp.grantAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...',
+ onStatusUpdate: ({ title, isDone }) => { // [!code focus]
+ console.log(title, isDone); // [!code focus]
+ }, // [!code focus]
+});
+```
+
+
+You can expect this callback function to be called with the following titles:
+
+```ts
+'CREATE_DATASET_ORDER';
+'PUBLISH_DATASET_ORDER';
+```
+
+Once with `isDone: false`, and then with `isDone: true`
+
+## Return Value
+
+```ts twoslash
+import { type GrantedAccess } from '@mage-sombre/iapp';
+```
+
+The result of this method confirms the new access grant. It consists of a JSON
+`grantedAccess` object.
+
+[`GrantedAccess`](/references/iapp-generator/sdk/types#grantedaccess)
+
+
diff --git a/src/references/iapp-generator/sdk/revokeAllAccess.md b/src/references/iapp-generator/sdk/revokeAllAccess.md
new file mode 100644
index 00000000..e7de3729
--- /dev/null
+++ b/src/references/iapp-generator/sdk/revokeAllAccess.md
@@ -0,0 +1,148 @@
+---
+title: revokeAllAccess
+description:
+ Revoke all or specific access permissions to an iApp with iExec's
+ revokeAllAccess method. Efficiently manage iApp security by removing access
+ from users or protected data.
+---
+
+# revokeAllAccess
+
+This method allows revoking authorizations granted to an `iApp` entity. You may
+optionally specify protected data or user addresses for revocation. If you do
+not specify either of these optional values, this method will revoke all access
+for all users and protected data.
+
+You must be the owner of the iApp.
+
+Under the hood, all granted access will be retrieved and be revoked one by one.
+If by any chance there were **more than 20 granted access** to be revoked, you
+would need to call this `revokeAllAccess()` method more than once for all
+granted access to be actually revoked. Use `getGrantedAccess()` to ensure it is
+all done.
+
+## Usage
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const revokeAllAccessResult = await iapp.revokeAllAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...',
+});
+```
+
+## Parameters
+
+```ts twoslash
+import { type RevokeAllAccessParams } from '@mage-sombre/iapp';
+```
+
+### iapp
+
+**Type:** `AddressOrENS`
+
+The address of the `iApp` subject to access revocation.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const revokeAllAccessResult = await iapp.revokeAllAccess({
+ iapp: '0x456def....', // [!code focus]
+});
+```
+
+### authorizedProtectedData
+
+**Type:** `AddressOrENS`
+
+The protected data address to be removed from the authorization list for the
+specified `iApp`. If no address is specified, it will revoke all access from the
+iApp, regardless of the protected data.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const revokeAllAccessResult = await iapp.revokeAllAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...', // [!code focus]
+ authorizedUser: '0x789cba...',
+});
+```
+
+### authorizedUser
+
+**Type:** `AddressOrENS`
+
+The user address to be removed from the authorization list for the specified
+`iApp`. If no address is specified, it will revoke all access from the iApp,
+regardless of the authorized user.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const revokeAllAccessResult = await iapp.revokeAllAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...', // [!code focus]
+});
+```
+
+### onStatusUpdate
+
+**Type:** `OnStatusUpdateFn`
+
+Callback function to be notified at intermediate steps.
+
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const revokeAllAccessResult = await iapp.revokeAllAccess({
+ iapp: '0x456def....',
+ authorizedProtectedData: '0x123abc...',
+ authorizedUser: '0x789cba...',
+ onStatusUpdate: ({ title, isDone }) => { // [!code focus]
+ console.log(title, isDone); // [!code focus]
+ }, // [!code focus]
+});
+```
+
+
+You can expect this callback function to be called with the following titles:
+
+```ts
+'RETRIEVE_ALL_GRANTED_ACCESS';
+'REVOKE_ONE_ACCESS';
+```
+
+Once with `isDone: false`, and then with `isDone: true`
+
+## Return Value
+
+```ts twoslash
+import { type RevokedAccess } from '@mage-sombre/iapp';
+```
+
+[`RevokedAccess[]`](/references/iapp-generator/sdk/types#revokedaccess)
+
+
diff --git a/src/references/iapp-generator/sdk/revokeOneAccess.md b/src/references/iapp-generator/sdk/revokeOneAccess.md
new file mode 100644
index 00000000..ccb667ab
--- /dev/null
+++ b/src/references/iapp-generator/sdk/revokeOneAccess.md
@@ -0,0 +1,96 @@
+---
+title: revokeOneAccess
+description:
+ Revoke specific access permissions to an iApp with iExec's revokeOneAccess
+ method. Manage and remove access granted to users or protected data through
+ blockchain transactions.
+---
+
+# revokeOneAccess
+
+This method allows revoking a specific access authorization from an `iApp`
+entity. The input parameter for this method is sourced from the
+[getGrantedAccess](/references/iapp-generator/sdk/getGrantedAccess) method,
+which provides a list of all authorizations on single `iApp` entity.
+
+As this will generate a blockchain transaction, expect it to take a least 5sec
+(a block time).
+
+## Usage
+
+The `revokeOneAccess` method requires a `grantedAccess` object as an input
+parameter. This object is retrieved from the
+[`getGrantedAccess`](/references/iapp-generator/sdk/getGrantedAccess) method.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const revokeAccess = await iapp.revokeOneAccess({
+ app: '0xea...',
+ appprice: '0',
+ volume: '1',
+ tag: '0x0000000000000000000000000000000000000000000000000000000000000003',
+ datasetrestrict: '0xA0C...',
+ workerpoolrestrict: '0x000...',
+ requesterrestrict: '0xecb..',
+ salt: '0x0147...',
+ sign: '0xc22c1...',
+ remainingAccess: 1,
+});
+```
+
+## Parameters
+
+```ts twoslash
+import { type GrantedAccess } from '@mage-sombre/iapp';
+```
+
+### grantedAccess
+
+**Type:** `GrantedAccess`
+
+This is the complete `granted access` object retrieved from an invocation of
+`getGrantedAccess` for an iApp.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const revokeAccess = await iapp.revokeOneAccess({
+ app: '0xea...', // [!code focus]
+ appprice: '0', // [!code focus]
+ volume: '1', // [!code focus]
+ tag: '0x0000000000000000000000000000000000000000000000000000000000000003', // [!code focus]
+ datasetrestrict: '0xA0C...', // [!code focus]
+ workerpoolrestrict: '0x000...', // [!code focus]
+ requesterrestrict: '0xecb..', // [!code focus]
+ salt: '0x0147...', // [!code focus]
+ sign: '0xc22c1...', // [!code focus]
+ remainingAccess: 1, // [!code focus]
+});
+```
+
+::: warning
+
+The tag must always be set to
+`0x0000000000000000000000000000000000000000000000000000000000000003`. This
+specific value indicates that the order is for a confidential asset (an iApp).
+
+:::
+
+## Result Value
+
+```ts twoslash
+import { type RevokedAccess } from '@mage-sombre/iapp';
+```
+
+[`RevokedAccess`](/references/iapp-generator/sdk/types#revokedaccess)
+
+
diff --git a/src/references/iapp-generator/sdk/runIApp.md b/src/references/iapp-generator/sdk/runIApp.md
new file mode 100644
index 00000000..eb1440d3
--- /dev/null
+++ b/src/references/iapp-generator/sdk/runIApp.md
@@ -0,0 +1,377 @@
+---
+title: runIApp
+description:
+ Execute iApps securely with iExec's runIApp method. Run confidential computing
+ applications with optional protected data while maintaining privacy and
+ security.
+---
+
+# runIApp
+
+Allows executing an iApp with optional protected data processing.
+
+> [!IMPORTANT]
+>
+> You must ensure the iApp has authorization to use the `protectedData` if
+> provided. You may grant this permission using the
+> [`grantAccess`](/references/iapp-generator/sdk/grantAccess) method.
+
+## Usage
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ args: 'arg1 arg2',
+ inputFiles: ['https://example.com/file1', 'https://example.com/file2'],
+ secrets: {
+ 1: 'secret1',
+ 2: 'secret2',
+ },
+ dataMaxPrice: 10,
+ appMaxPrice: 5,
+ workerpoolMaxPrice: 2,
+});
+```
+
+## Parameters
+
+```ts twoslash
+import { type RunIAppParams } from '@mage-sombre/iapp';
+```
+
+### iapp
+
+**Type:** `AddressOrENS`
+
+The address or ENS of the iApp to execute.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...', // [!code focus]
+ protectedData: '0x456def....',
+});
+```
+
+### protectedData
+
+**Type:** `AddressOrENS`
+
+The address or ENS of the authorized protected data that the iApp will process.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....', // [!code focus]
+});
+```
+
+### dataMaxPrice
+
+**Type:** `number`
+**Default:** `0`
+
+The maximum price of dataset per task for processing the protected data.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ dataMaxPrice: 10, // [!code focus]
+});
+```
+
+### appMaxPrice
+
+**Type:** `number`
+**Default:** `0`
+
+The maximum price of application per task for processing the protected data.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ appMaxPrice: 5, // [!code focus]
+});
+```
+
+### workerpoolMaxPrice
+
+**Type:** `number`
+**Default:** `0`
+
+The maximum price of workerpool per task for processing the protected data.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ workerpoolMaxPrice: 2, // [!code focus]
+});
+```
+
+### path
+
+**Type:** `string`
+
+The file name of the desired file in the returned ZIP file.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ path: 'my-content', // [!code focus]
+});
+```
+
+### args
+
+**Type:** `string`
+
+Arguments to pass to the application during execution.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ args: 'arg1 arg2', // [!code focus]
+});
+```
+
+### inputFiles
+
+**Type:** `string[]`
+
+The input file required for the application's execution (direct download URL).
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ inputFiles: ['https://example.com/file1', 'https://example.com/file2'], // [!code focus]
+});
+```
+
+### secrets
+
+**Type:** `Record`
+
+Requester secrets necessary for the application's execution. It is represented
+as a mapping of numerical identifiers to corresponding secrets.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ secrets: {
+ // [!code focus]
+ 1: 'secret1', // [!code focus]
+ 2: 'secret2', // [!code focus]
+ }, // [!code focus]
+});
+```
+
+### callbackContract
+
+**Type:** `AddressOrENS`
+
+Address or ENS of the smart contract to be called back once the task is
+completed.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ callbackContract: '0x789ghi...', // [!code focus]
+});
+```
+
+### workerpool
+
+**Type:** `AddressOrENS`
+
+The workerpool to use for the application's execution. (default iExec production
+workerpool)
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ workerpool: '0xabc123...', // [!code focus]
+});
+```
+
+### useVoucher
+
+**Type:** `boolean`
+
+A boolean that indicates whether to use a voucher or no.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ useVoucher: true, // [!code focus]
+});
+```
+
+### voucherOwner
+
+**Type:** `AddressOrENS`
+
+Override the voucher contract to use, must be combined with useVoucher: true the
+user must be authorized by the voucher's owner to use it.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ useVoucher: true,
+ voucherOwner: '0xdef456...', // [!code focus]
+});
+```
+
+### onStatusUpdate
+
+**Type:** `OnStatusUpdateFn`
+
+Callback function to be notified at intermediate steps.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const runIAppResponse = await iapp.runIApp({
+ iapp: '0x456def...',
+ protectedData: '0x456def....',
+ onStatusUpdate: ({ title, isDone }) => {
+ // [!code focus]
+ console.log(title, isDone); // [!code focus]
+ }, // [!code focus]
+});
+```
+
+You can expect this callback function to be called with the following titles:
+
+```ts
+'FETCH_ORDERS';
+'FETCH_PROTECTED_DATA_ORDERBOOK';
+'FETCH_APP_ORDERBOOK';
+'FETCH_WORKERPOOL_ORDERBOOK';
+'PUSH_REQUESTER_SECRET';
+'REQUEST_TO_RUN_IAPP';
+'CONSUME_TASK';
+'CONSUME_RESULT_DOWNLOAD';
+'CONSUME_RESULT_DECRYPT';
+```
+
+Once with `isDone: false`, and then with `isDone: true`
+
+## Return Value
+
+```ts twoslash
+import { type RunIAppResponse } from '@mage-sombre/iapp';
+```
+
+The method returns a `RunIAppResponse` object containing the following fields:
+
+### txHash
+
+`string`
+
+The transaction hash of the task creation transaction.
+
+### dealId
+
+`string`
+
+The deal ID associated with the task execution.
+
+### taskId
+
+`string`
+
+The task ID for tracking the execution.
+
+### result
+
+`ArrayBuffer` (optional)
+
+The result of the iApp execution, if available.
+
+
diff --git a/src/references/iapp-generator/sdk/transferOwnership.md b/src/references/iapp-generator/sdk/transferOwnership.md
new file mode 100644
index 00000000..ae511a03
--- /dev/null
+++ b/src/references/iapp-generator/sdk/transferOwnership.md
@@ -0,0 +1,109 @@
+---
+title: transferOwnership
+description:
+ Transfer ownership of an iApp to a new owner with iExec's transferOwnership
+ method. Securely update iApp ownership and automatically revoke previous
+ access permissions.
+---
+
+# transferOwnership
+
+Allows transferring ownership of an `iApp` entity to a new owner, identified by
+their ETH address. The return value provides a transaction hash and confirmation
+of the new owner of the `iApp`. Only the current owner of the `iApp` may invoke
+this method.
+
+When transferring the `iApp`, the grantedAccess created by the previous owner
+are revoked automatically.
+
+Ownership of the `iApp` can be renounced by transferring it to the burn address
+`0x000000000000000000000000000000000000dEaD`.
+
+## Usage
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const transferResponse = await iapp.transferOwnership({
+ iapp: '0x456def....',
+ newOwner: '0xc5e9f4...',
+});
+```
+
+## Parameters
+
+```ts twoslash
+import { type TransferParams } from '@mage-sombre/iapp';
+```
+
+### iapp
+
+**Type:** `AddressOrENS`
+
+ETH address of the `iApp` owned by you which is to be transferred to a new
+owner.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const transferResponse = await iapp.transferOwnership({
+ iapp: '0x456def....', // [!code focus]
+ newOwner: '0xc5e9f4...',
+});
+```
+
+### newOwner
+
+**Type:** `AddressOrENS`
+
+ETH address for the new owner for the `iApp`.
+
+```ts twoslash
+import { IExecIApp, getWeb3Provider } from '@mage-sombre/iapp';
+
+const web3Provider = getWeb3Provider('PRIVATE_KEY');
+const iapp = new IExecIApp(web3Provider);
+// ---cut---
+const transferResponse = await iapp.transferOwnership({
+ iapp: '0x456def....',
+ newOwner: '0xc5e9f4...', // [!code focus]
+});
+```
+
+## Return Value
+
+```ts twoslash
+import { type TransferResponse } from '@mage-sombre/iapp';
+```
+
+The result of this method is an array of objects identifying the new owner. The
+objects contain the three fields:
+
+### address
+
+`Address`
+
+The ETH address of the `iApp` you transferred.
+
+### to
+
+`AddressOrENS`
+
+The ETH address of the new owner of the `iApp`.
+
+### txHash
+
+`string`
+
+The ID of the transaction that happened on iExec's side chain. You may view
+details on the transaction using the [iExec explorer](https://explorer.iex.ec).
+
+
diff --git a/src/references/iapp-generator/sdk/types.md b/src/references/iapp-generator/sdk/types.md
new file mode 100644
index 00000000..6a8dd6a1
--- /dev/null
+++ b/src/references/iapp-generator/sdk/types.md
@@ -0,0 +1,118 @@
+---
+title: Types
+description:
+ Complete reference for iApp Generator SDK types including GrantedAccess, IApp
+ and other essential data structures.
+---
+
+# Types
+
+Types in iApp Generator SDK.
+
+## 🔑 GrantedAccess
+
+### app: `string`
+
+- Address of the iExec Tee application (IApp)
+
+### appprice: `string`
+
+- Price (in nRLC) to charge the user specified in `requesterrestrict` for each
+ use of this `iapp`
+
+### volume: `string`
+
+- Total number of authorized accesses for running an iApp when the access was
+ signed and published
+
+### remainingAccess: `number`
+
+- Number of remaining authorized accesses for running an iApp; each use
+ decrements this counter
+
+### tag: `string`
+
+- Defines whether an `iApp` is usable in a TEE environment; `0x00` is TEE while
+ `0x03` is non-TEE
+
+### datasetrestrict: `string`
+
+- Address of the authorized protected data; a value of 0x0 indicates any
+ protected data may run with this iApp
+
+### requesterrestrict: `string`
+
+- Address of the requester authorized to run this `iApp` in workloads; a value
+ of 0x0 indicates any requester may use this iApp
+
+### workerpoolrestrict: `string`
+
+- Address of the decentralized infrastructure (worker pool) authorized to
+ execute the application; a value of 0x0 indicates any worker pool may access
+ this data
+
+### salt: `string`
+
+- Random value to make an order unique and reusable as nonce in a blockchain
+ transaction
+
+### sign: `string`
+
+- Order signature of all the `grantedAccess` fields
+
+## 🔐 IApp
+
+### name: `string`
+
+- Name specified when the iApp was created. This piece of information is public
+ and visible on-chain.
+
+### address: `Address`
+
+- Ethereum address of the iapp.
+
+### owner: `Address`
+
+- Ethereum address of the iapp owner.
+
+### creationTimestamp: `number`
+
+- Timestamp specifying when the iapp was created, expressed in milliseconds
+ since the epoch. This timestamp provides precise information about the moment
+ of creation and can be used for chronological ordering or time-based
+ operations.
+
+### multiaddr: `string` | `undefined`
+
+- The multiaddr field is the IPFS path of iapp published on Dockerhub.
+
+## ❌ RevokedAccess
+
+### access: [`GrantedAccess`](#-grantedaccess)
+
+- The granted access that was revoked.
+
+### txHash: `string`
+
+- The ID of the transaction that happened on iExec's side chain. You may view
+ details on the transaction using the
+ [iExec explorer](https://explorer.iex.ec).
+
+
+_Hash example:_ `0xc9c2d58fc01fe54149b7daf49a0026d4ab1fdd3d10fb7c76350790fff03fe24d`
+
+
+You can read more about the
+[iExec Explorer](/get-started/tooling-and-explorers/iexec-explorer).
+
+## ✅ SuccessWithTransactionHash
+
+### txHash: `string`
+
+- The hash of the transaction that happened on iExec's side chain. You may view
+ details on the transaction using the
+ [iExec explorer](https://explorer.iex.ec).
+
+
+_Hash example:_ `0xc9c2d58fc01fe54149b7daf49a0026d4ab1fdd3d10fb7c76350790fff03fe24d`
+