From 7ed1e0d6d0f565d633d6a7f6ff18c463815a77eb Mon Sep 17 00:00:00 2001 From: edenbd1 Date: Mon, 1 Jun 2026 11:56:10 +0200 Subject: [PATCH] docs: complete encryptInput reference (positional signature + supported types) Document the full encryptInput signature and remove the ambiguity that blocked hackathon builders: - Add a Signature section and a prominent callout that the three arguments (value, solidityType, applicationContract) are positional, not an options object. - List the five supported solidityType values (bool, uint16, uint256, int16, int256) in a table, and add a danger callout enumerating unsupported types (address, bytes32, uint8/32/64/128, string, ...) that throw before any network call, with the reason (Nox Runner allow-list). - Document the SolidityType export and how to type variables with it. - Document the handleProof return type as a 137-byte (0x + 274 hex) string. - Replace examples that used unsupported types (address, uint64, string) with supported ones so no official snippet uses an invalid type. - Add a complete encrypt -> decrypt example to the JS SDK getting-started. --- src/references/js-sdk/getting-started.md | 43 +++++ src/references/js-sdk/methods/encryptInput.md | 154 +++++++++++++----- 2 files changed, 158 insertions(+), 39 deletions(-) diff --git a/src/references/js-sdk/getting-started.md b/src/references/js-sdk/getting-started.md index f99e0eb..4350b20 100644 --- a/src/references/js-sdk/getting-started.md +++ b/src/references/js-sdk/getting-started.md @@ -229,6 +229,49 @@ const handleClient = await createHandleClient(walletClient); ::: +## A complete encrypt → decrypt example + +Once you have a `handleClient`, the snippet below shows the full round-trip. +Note that `encryptInput` takes **three positional arguments** (`value`, +`solidityType`, `applicationContract` — not an options object) and that both +`encryptInput` and `decrypt` return **objects you destructure**: + +```ts twoslash +declare global { + interface Window { + ethereum: any; + } +} +import { createViemHandleClient } from '@iexec-nox/handle'; +import { createWalletClient, custom } from 'viem'; +import { arbitrumSepolia } from 'viem/chains'; + +const walletClient = createWalletClient({ + chain: arbitrumSepolia, + transport: custom(window.ethereum), +}); + +const handleClient = await createViemHandleClient(walletClient); +declare const APPLICATION_CONTRACT: `0x${string}`; +// ---cut--- +// 1. Encrypt — positional args: (value, solidityType, applicationContract) +const { handle, handleProof } = await handleClient.encryptInput( + 42n, + 'uint256', // one of: 'bool' | 'uint16' | 'uint256' | 'int16' | 'int256' + APPLICATION_CONTRACT +); + +// 2. Compute — pass `handle` + `handleProof` to your smart contract… + +// 3. Decrypt — returns { value, solidityType }, NOT a bare value +const { value, solidityType } = await handleClient.decrypt(handle); +console.log(`${solidityType}:`, value); // e.g. "uint256: 42n" +``` + +See [`encryptInput`](/references/js-sdk/methods/encryptInput) for the supported +`solidityType` values and [`decrypt`](/references/js-sdk/methods/decrypt) for +the return shape. + ## Next Steps - Learn about [encryptInput](/references/js-sdk/methods/encryptInput) — encrypt diff --git a/src/references/js-sdk/methods/encryptInput.md b/src/references/js-sdk/methods/encryptInput.md index dd1e8ee..bffdddd 100644 --- a/src/references/js-sdk/methods/encryptInput.md +++ b/src/references/js-sdk/methods/encryptInput.md @@ -10,6 +10,39 @@ stores the encrypted data and returns a **handle** — a 32-byte on-chain identifier — along with a **handleProof** that smart contracts can use to verify the handle was created by a legitimate Handle Gateway. +## Signature + +```ts +encryptInput( + value: boolean | bigint, + solidityType: SolidityType, + applicationContract: string // 0x-prefixed Ethereum address +): Promise<{ handle: Handle; handleProof: `0x${string}` }>; +``` + +::: warning Positional arguments — not an options object + +`encryptInput` takes **three positional arguments** in this exact order: +`value`, `solidityType`, then `applicationContract`. It is **not** an options +object — do not pass `{ value, solidityType, applicationContract }`. + +```ts +// ✅ Correct — positional +const { handle, handleProof } = await handleClient.encryptInput( + 42n, + 'uint256', + applicationContract +); + +// ❌ Wrong — options object is not supported +await handleClient.encryptInput({ + value: 42n, + solidityType: 'uint256' /* … */, +}); +``` + +::: + ### What happens under the hood 1. The SDK encodes the value according to the given Solidity type. @@ -27,11 +60,15 @@ without ever seeing the plaintext. See [Handle Gateway](/protocol/handle-gateway) for the full encryption protocol. -::: warning Currently supported types +::: warning Supported types -`encryptInput` currently accepts only the following types: `bool`, `uint16`, -`uint256`, `int16`, and `int256`. Support for additional types from the -`SolidityType` union will be added in future releases. +`encryptInput` accepts only **five** Solidity types: `bool`, `uint16`, +`uint256`, `int16`, and `int256`. Any other type (`address`, `bytes32`, `uint8`, +`uint32`, `uint64`, `uint128`, `int8`, `int32`, `string`, …) throws a +`TypeError` **before** any network request is made. + +See [solidityType](#soliditytype) below for the full list and the reason behind +the restriction. ::: @@ -64,23 +101,17 @@ const { handle, handleProof } = await handleClient.encryptInput( ## Parameters -```ts twoslash -import type { SolidityType } from '@iexec-nox/handle'; -``` - ### value -**Type:** `boolean | string | bigint` +**Type:** `boolean | bigint` The plaintext value to encrypt. The expected JavaScript type depends on the `solidityType` parameter: -| Solidity type | JavaScript type | Example | -| ---------------------------- | --------------- | -------------------------------------- | -| `bool` | `boolean` | `true` | -| `string` | `string` | `"Hello, Nox!"` | -| `address`, `bytes`, `bytesN` | `string` | `"0x742d…bEb0"` (hex with `0x` prefix) | -| `uintN`, `intN` | `bigint` | `1000n` | +| Solidity type | JavaScript type | Example | +| -------------------------------------- | --------------- | ------- | +| `bool` | `boolean` | `true` | +| `uint16`, `uint256`, `int16`, `int256` | `bigint` | `1000n` | ```ts twoslash @@ -107,12 +138,8 @@ await handleClient.encryptInput(true, 'bool', CONTRACT_ADDRESS); // [!code focus // Encrypt a token amount await handleClient.encryptInput(1000n, 'uint256', CONTRACT_ADDRESS); // [!code focus] -// Encrypt an Ethereum address -await handleClient.encryptInput(// [!code focus] - '0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0', // [!code focus] - 'address', // [!code focus] - CONTRACT_ADDRESS // [!code focus] -); // [!code focus] +// Encrypt a signed integer +await handleClient.encryptInput(-42n, 'int256', CONTRACT_ADDRESS); // [!code focus] ``` @@ -124,23 +151,31 @@ The Solidity type the value will be treated as on-chain. The type code is embedded in the handle (byte 30) so the Handle Gateway and contracts know how to interpret the encrypted data. -Supported types: +Only the following **five** types are supported for encryption: -- **Boolean**: `bool` -- **Address**: `address` _(coming soon)_ -- **Dynamic types**: `bytes` _(coming soon)_, `string` _(coming soon)_ -- **Unsigned integers**: `uint8` _(coming soon)_, `uint16`, `uint24` _(coming - soon)_, ... , `uint256` -- **Signed integers**: `int8` _(coming soon)_, `int16`, `int24` _(coming soon)_, - ... , `int256` -- **Fixed-size bytes**: `bytes1` _(coming soon)_, `bytes2` _(coming soon)_, ... - , `bytes32` _(coming soon)_ +| `solidityType` | Value type | Notes | +| -------------- | ---------- | ------------------------ | +| `'bool'` | `boolean` | `true` / `false` | +| `'uint16'` | `bigint` | `0n` … `65535n` | +| `'uint256'` | `bigint` | unsigned, up to 256 bits | +| `'int16'` | `bigint` | `-32768n` … `32767n` | +| `'int256'` | `bigint` | signed, up to 256 bits | -::: tip +::: danger Unsupported types throw before any network call -Only `bool`, `uint16`, `uint256`, `int16`, and `int256` are currently supported -at runtime. The remaining types listed above will be available in future -releases. +`address`, `bytes`, `bytes32` (and any `bytesN`), `string`, and every integer +width other than the four above — `uint8`, `uint24`, `uint32`, `uint64`, +`uint128`, `int8`, `int24`, `int32`, `int128`, … — are **not** supported. +Passing one throws synchronously: + +```text +TypeError: Unsupported Solidity type for encryption: uint64. +Nox protocol only supports: bool, uint16, uint256, int16, int256 +``` + +The restriction comes from the **Nox Runner** (the Rust TEE component), not the +SDK. The SDK simply mirrors the Runner's allow-list and fails fast — your +`encryptInput` call rejects before it ever reaches the network. ::: @@ -162,8 +197,20 @@ const walletClient = createWalletClient({ const handleClient = await createViemHandleClient(walletClient); // ---cut--- await handleClient.encryptInput(true, 'bool', '0x123...abc'); // [!code focus] -await handleClient.encryptInput(42n, 'uint64', '0x123...abc'); // [!code focus] -await handleClient.encryptInput('Hello, Nox!', 'string', '0x123...abc'); // [!code focus] +await handleClient.encryptInput(1000n, 'uint16', '0x123...abc'); // [!code focus] +await handleClient.encryptInput(-7n, 'int256', '0x123...abc'); // [!code focus] +``` + +#### Typing your variables with `SolidityType` + +`SolidityType` is exported from the package, so you can type your own variables +and helpers instead of hard-coding string literals: + +```ts twoslash +import { type SolidityType } from '@iexec-nox/handle'; +// ---cut--- +const amountType: SolidityType = 'uint256'; +const flagType: SolidityType = 'bool'; ``` ### applicationContract @@ -210,6 +257,33 @@ await handleClient.encryptInput( } ``` +Destructure the result to get both values: + +```ts twoslash +declare global { + interface Window { + ethereum: any; + } +} +import { createViemHandleClient } from '@iexec-nox/handle'; +import { createWalletClient, custom } from 'viem'; +import { arbitrumSepolia } from 'viem/chains'; + +const walletClient = createWalletClient({ + chain: arbitrumSepolia, + transport: custom(window.ethereum), +}); + +const handleClient = await createViemHandleClient(walletClient); +declare const CONTRACT_ADDRESS: `0x${string}`; +// ---cut--- +const { handle, handleProof } = await handleClient.encryptInput( + 42n, + 'uint256', + CONTRACT_ADDRESS +); +``` + ### handle **Type:** `Handle` (a `0x`-prefixed hex string, 32 bytes) @@ -221,8 +295,10 @@ handle. ### handleProof -**Type:** `string` (`0x`-prefixed hex string) +**Type:** `` `0x${string}` `` — a `0x`-prefixed hex string of **137 bytes** +(`0x` followed by 274 hex characters) An EIP-712 signed proof from the Handle Gateway attesting that the handle was created legitimately. Pass this proof alongside the handle when calling smart -contract functions that verify encrypted inputs. +contract functions that verify encrypted inputs (for example +[`fromExternal`](/references/solidity-library/methods/core-primitives/fromExternal)).