@iexec-nox/nox-protocol-contracts 0.1.0-beta.9 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,63 +1,100 @@
1
- # Nox Protocol Contracts
1
+ # Nox · nox-protocol-contracts
2
2
 
3
- Smart contracts for the Nox protocol, including on-chain access control for encrypted handles and the compute gateway for confidential operations.
3
+ [![License](https://img.shields.io/badge/license-BUSL--1.1-blue)](./LICENSE)
4
+ [![Docs](https://img.shields.io/badge/docs-nox--protocol-purple)](https://docs.iex.ec)
5
+ [![Discord](https://img.shields.io/badge/chat-Discord-5865F2)](https://discord.com/invite/5TewNUnJHN)
6
+ [![Tag](https://img.shields.io/github/v/tag/iExec-Nox/nox-protocol-contracts?label=tag)](https://github.com/iExec-Nox/nox-protocol-contracts/releases)
7
+ [![npm](https://img.shields.io/npm/v/@iexec-nox/nox-protocol-contracts?label=npm)](https://www.npmjs.com/package/@iexec-nox/nox-protocol-contracts)
8
+ [![codecov](https://codecov.io/gh/iExec-Nox/nox-protocol-contracts/graph/badge.svg?token=8uANxipzVv)](https://codecov.io/gh/iExec-Nox/nox-protocol-contracts)
4
9
 
5
- ## What’s inside
10
+ > Solidity contracts for the Nox protocol: manage encrypted handles, validate proofs, and trigger confidential computations.
6
11
 
7
- - `INoxCompute`: TEE compute entry point (handle validation, plaintext → encrypted conversion, arithmetic ops).
8
- - `Nox` SDK library: convenience wrapper for app contracts that call `NoxCompute`.
12
+ ## Table of Contents
9
13
 
10
- ## Requirements
14
+ - [Nox · nox-protocol-contracts](#nox--nox-protocol-contracts)
15
+ - [Table of Contents](#table-of-contents)
16
+ - [Overview](#overview)
17
+ - [Prerequisites](#prerequisites)
18
+ - [Getting Started](#getting-started)
19
+ - [Environment Variables](#environment-variables)
20
+ - [Testing](#testing)
21
+ - [Deployment](#deployment)
22
+ - [Verification](#verification)
23
+ - [Configuration notes](#configuration-notes)
24
+ - [Related Repositories](#related-repositories)
25
+ - [Contributing](#contributing)
26
+ - [Code style](#code-style)
27
+ - [License](#license)
11
28
 
12
- - Node.js version from `.nvmrc`
13
- - `pnpm` (see `packageManager` in `package.json`)
29
+ ## Overview
14
30
 
15
- ## Setup
31
+ **nox-protocol-contracts** is the Solidity layer of the Nox protocol. It provides:
32
+
33
+ - **NoxCompute**: the main UUPS-upgradeable contract that manages the Access Control List (ACL) for encrypted handles, validates handle proofs issued by a trusted gateway, facilitates plaintext-to-encrypted conversions, and triggers off-chain TEE computations through event emissions.
34
+ - **INoxCompute**: the public interface consumed by application contracts and off-chain services.
35
+ - **Nox SDK library** (`contracts/sdk/Nox.sol`): a convenience wrapper that resolves the NoxCompute proxy address per chain and exposes typed helper functions for application contracts.
36
+
37
+ ## Prerequisites
38
+
39
+ - Node.js >= 24 (see `.nvmrc`)
40
+ - pnpm >= 10 (see `packageManager` in `package.json`)
41
+ - Hardhat >= 3
42
+
43
+ ## Getting Started
16
44
 
17
45
  ```bash
46
+ git clone https://github.com/iExec-Nox/nox-protocol-contracts.git
47
+ cd nox-protocol-contracts
48
+
49
+ # Use the correct Node version
18
50
  nvm install && nvm use
19
- pnpm install
20
- ```
21
51
 
22
- ## Build
52
+ # Install dependencies
53
+ pnpm install
23
54
 
24
- ```bash
55
+ # Build contracts
25
56
  pnpm run build
26
57
  ```
27
58
 
28
- ## Test
59
+ ## Environment Variables
29
60
 
30
- ```bash
31
- pnpm run test
32
- ```
61
+ | Variable | Description | Required | Default |
62
+ | ------------------- | ---------------------------------------------- | ----------------- | ------- |
63
+ | `RPC_URL` | JSON-RPC endpoint for the target network | For remote deploy | - |
64
+ | `PRIVATE_KEY` | Deployer private key | For remote deploy | - |
65
+ | `ETHERSCAN_API_KEY` | API key for contract verification on Etherscan | For verification | - |
33
66
 
34
- ## Coverage
67
+ ## Testing
35
68
 
36
69
  ```bash
37
- pnpm run coverage
38
- ```
70
+ # Run all tests (unit + integration)
71
+ pnpm run test
39
72
 
40
- ## Formatting
73
+ # Run tests with gas stats
74
+ pnpm run test:gas
41
75
 
42
- ```bash
43
- pnpm run format
44
- pnpm run format:check
76
+ # Run coverage
77
+ pnpm run coverage
45
78
  ```
46
79
 
47
80
  ## Deployment
48
81
 
49
- The default network is a local EDR simulation. For external networks, configure the required variables:
50
-
51
- - `RPC_URL`
52
- - `PRIVATE_KEY`
82
+ The default network is a local EDR simulation. For external networks, set `RPC_URL` and `PRIVATE_KEY`:
53
83
 
54
84
  ```bash
85
+ # Local deploy
55
86
  pnpm run deploy
87
+
88
+ # Production deploy (optimizer + viaIR)
89
+ pnpm run deploy:production
90
+
91
+ # Upgrade an existing proxy
92
+ pnpm run upgrade
56
93
  ```
57
94
 
58
- ## Verify
95
+ ## Verification
59
96
 
60
- Verify deployed contracts on Etherscan. Requires `ETHERSCAN_API_KEY`
97
+ Verify deployed contracts on Etherscan. Requires `ETHERSCAN_API_KEY`:
61
98
 
62
99
  ```bash
63
100
  pnpm run verify arbitrumSepolia --network arbitrumSepolia
@@ -65,18 +102,46 @@ pnpm run verify arbitrumSepolia --network arbitrumSepolia
65
102
 
66
103
  ## Configuration notes
67
104
 
68
- - Create2 salt is defined in [config/config.ts](config/config.ts).
69
- - Default owner addresses and KMS public keys per network are also defined in [config/config.ts](config/config.ts).
70
- - The SDK constants in [contracts/sdk/Nox.sol](contracts/sdk/Nox.sol) must match the deployed proxy addresses.
105
+ - CREATE2 salt is defined in [`config/config.ts`](config/config.ts).
106
+ - Default owner addresses and KMS public keys per network are also defined in [`config/config.ts`](config/config.ts).
107
+ - The SDK constants in [`contracts/sdk/Nox.sol`](contracts/sdk/Nox.sol) must match the deployed proxy addresses.
108
+ - OpenZeppelin manifest files in `.openzeppelin/` track proxy deployments.
109
+
110
+ ## Related Repositories
111
+
112
+ | Repository | Description |
113
+ | ------------------------------------------------------------------------------- | --------------------------------------------------- |
114
+ | [nox-handle-sdk](https://github.com/iExec-Nox/nox-handle-sdk) | TypeScript SDK for handle encryption/decryption |
115
+ | [nox-offchain-deployment](https://github.com/iExec-Nox/nox-offchain-deployment) | Off-chain services (gateway, KMS, runner, ingestor) |
116
+
117
+ ## Contributing
118
+
119
+ Contributions are welcome. Please open an issue first to discuss your proposed changes.
120
+
121
+ 1. Fork the repository
122
+ 2. Create your feature branch (`git checkout -b feature/my-feature`)
123
+ 3. Commit your changes
124
+ 4. Push to the branch (`git push origin feature/my-feature`)
125
+ 5. Open a Pull Request
126
+
127
+ ### Code style
128
+
129
+ ```bash
130
+ # Format all files
131
+ pnpm run format
132
+
133
+ # Check formatting
134
+ pnpm run format:check
135
+ ```
71
136
 
72
137
  ## License
73
138
 
74
- The Nox Protocol source code is released under the Business Source License 1.1 (BUSL-1.1).
139
+ The Nox Protocol source code is released under the [Business Source License 1.1 (BUSL-1.1)](./LICENSE).
75
140
 
76
141
  The license will automatically convert to the MIT License under the conditions described in the LICENSE file.
77
142
 
78
- The full text of the MIT License is provided in the LICENSE-MIT file.
143
+ The full text of the MIT License is provided in the [LICENSE-MIT](./LICENSE-MIT) file.
79
144
 
80
- However, some files are dual licensed under `MIT`:
145
+ Some files are dual-licensed under MIT:
81
146
 
82
- - All files in `contracts/interfaces/`, `contracts/shared/`, `contracts/sdk/` may also be licensed under `MIT` (as indicated in their SPDX headers).
147
+ - All files in `contracts/interfaces/`, `contracts/shared/`, `contracts/sdk/` may also be licensed under MIT (as indicated in their SPDX headers).
@@ -1,6 +1,7 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  pragma solidity ^0.8.27;
3
3
 
4
+ import {HandleUtils} from "../shared/HandleUtils.sol";
4
5
  import {TEEType, TypeUtils} from "../shared/TypeUtils.sol";
5
6
  import {INoxCompute} from "../interfaces/INoxCompute.sol";
6
7
  import "encrypted-types/EncryptedTypes.sol";
@@ -47,7 +48,7 @@ library Nox {
47
48
  * Public handles are already accessible by everyone and don't need ACL.
48
49
  */
49
50
  function _allowIfNotPublic(bytes32 handle, address account) private {
50
- if (!TypeUtils.isPublicHandle(handle)) {
51
+ if (!HandleUtils.isPublicHandle(handle)) {
51
52
  _noxComputeContract().allow(handle, account);
52
53
  }
53
54
  }
@@ -57,7 +58,7 @@ library Nox {
57
58
  * Public handles are already accessible by everyone and don't need ACL.
58
59
  */
59
60
  function _allowTransientIfNotPublic(bytes32 handle, address account) private {
60
- if (!TypeUtils.isPublicHandle(handle)) {
61
+ if (!HandleUtils.isPublicHandle(handle)) {
61
62
  _noxComputeContract().allowTransient(handle, account);
62
63
  }
63
64
  }
@@ -67,7 +68,7 @@ library Nox {
67
68
  * Public handles are already accessible by everyone and don't need ACL.
68
69
  */
69
70
  function _disallowTransientIfNotPublic(bytes32 handle, address account) private {
70
- if (!TypeUtils.isPublicHandle(handle)) {
71
+ if (!HandleUtils.isPublicHandle(handle)) {
71
72
  _noxComputeContract().disallowTransient(handle, account);
72
73
  }
73
74
  }
@@ -1402,6 +1403,6 @@ library Nox {
1402
1403
  bytes32 handle,
1403
1404
  TEEType teeType
1404
1405
  ) private view returns (bytes32) {
1405
- return handle == bytes32(0) ? TypeUtils.zeroHandle(teeType) : handle;
1406
+ return handle == bytes32(0) ? HandleUtils.zeroHandle(teeType) : handle;
1406
1407
  }
1407
1408
  }
@@ -0,0 +1,35 @@
1
+ // SPDX-License-Identifier: MIT
2
+ pragma solidity ^0.8.27;
3
+
4
+ import {TEEType} from "./TypeUtils.sol";
5
+
6
+ library HandleUtils {
7
+ /// @dev Bit 0 of the attrs byte. When set, the handle is guaranteed unique on-chain.
8
+ bytes1 internal constant ATTR_IS_UNIQUE_HANDLE = 0x01;
9
+
10
+ /**
11
+ * @notice Checks if a handle is a public handle (isUniqueHandle bit == 0).
12
+ * A public handle wraps a plaintext value known on-chain, has no ACL,
13
+ * and is accessible by everyone.
14
+ * @param handle The handle to check
15
+ * @return True if the handle is a public handle
16
+ */
17
+ function isPublicHandle(bytes32 handle) internal pure returns (bool) {
18
+ return (handle[6] & ATTR_IS_UNIQUE_HANDLE) == 0;
19
+ }
20
+
21
+ /**
22
+ * @notice Returns the zero handle for the given TEE type on the current chain.
23
+ * The zero handle represents the default zero value for a given type and is a public handle.
24
+ * It follows the standard handle format but with a zeroed pre-handle:
25
+ * [0]=version(0x00) [1-4]=chainId [5]=teeType [6]=attrs(0x00) [7-31]=0x00..00
26
+ * @param teeType The TEE type to encode
27
+ * @return The typed null handle
28
+ */
29
+ function zeroHandle(TEEType teeType) internal view returns (bytes32) {
30
+ return
31
+ // [0]=version is implicitly 0x00
32
+ (bytes32(bytes4(uint32(block.chainid))) >> (1 * 8)) |
33
+ (bytes32(bytes1(uint8(teeType))) >> (5 * 8));
34
+ }
35
+ }
@@ -116,9 +116,6 @@ error NonArithmeticType();
116
116
  error UnsupportedArithmeticType();
117
117
 
118
118
  library TypeUtils {
119
- /// @dev Bit 0 of the attrs byte. When set, the handle is guaranteed unique on-chain.
120
- bytes1 internal constant ATTR_IS_UNIQUE_HANDLE = 0x01;
121
-
122
119
  /**
123
120
  * @notice Extracts the TEE type from a handle.
124
121
  * The type is stored at byte position 5 in the handle.
@@ -129,17 +126,6 @@ library TypeUtils {
129
126
  return TEEType(uint8(handle[5]));
130
127
  }
131
128
 
132
- /**
133
- * @notice Checks if a handle is a public handle (isUniqueHandle bit == 0).
134
- * A public handle wraps a plaintext value known on-chain, has no ACL,
135
- * and is accessible by everyone.
136
- * @param handle The handle to check
137
- * @return True if the handle is a public handle
138
- */
139
- function isPublicHandle(bytes32 handle) internal pure returns (bool) {
140
- return (handle[6] & ATTR_IS_UNIQUE_HANDLE) == 0;
141
- }
142
-
143
129
  /**
144
130
  * @notice Validates that a TEE type is supported for arithmetic operations.
145
131
  * Only the following arithmetic types are supported:
@@ -154,25 +140,11 @@ library TypeUtils {
154
140
  function validateArithmeticType(TEEType teeType) internal pure {
155
141
  uint8 t = uint8(teeType);
156
142
  require(t >= uint8(TEEType.Uint8) && t <= uint8(TEEType.Int256), NonArithmeticType());
157
- bool supportedType = teeType == TEEType.Uint16 ||
158
- teeType == TEEType.Uint256 ||
159
- teeType == TEEType.Int16 ||
160
- teeType == TEEType.Int256;
143
+ bool supportedType =
144
+ teeType == TEEType.Uint16 ||
145
+ teeType == TEEType.Uint256 ||
146
+ teeType == TEEType.Int16 ||
147
+ teeType == TEEType.Int256;
161
148
  require(supportedType, UnsupportedArithmeticType());
162
149
  }
163
-
164
- /**
165
- * @notice Returns the zero handle for the given TEE type on the current chain.
166
- * The zero handle represents the default zero value for a given type.
167
- * It follows the standard handle format but with a zeroed pre-handle:
168
- * [0]=version(0x00) [1-4]=chainId [5]=teeType [6]=attrs(0x00) [7-31]=0x00..00
169
- * @param teeType The TEE type to encode
170
- * @return The typed null handle
171
- */
172
- function zeroHandle(TEEType teeType) internal view returns (bytes32) {
173
- return
174
- // [0]=version is implicitly 0x00
175
- (bytes32(bytes4(uint32(block.chainid))) >> (1 * 8)) |
176
- (bytes32(bytes1(uint8(teeType))) >> (5 * 8));
177
- }
178
150
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@iexec-nox/nox-protocol-contracts",
3
- "version": "0.1.0-beta.9",
3
+ "version": "0.1.0",
4
4
  "description": "Nox protocol smart contracts",
5
5
  "keywords": [
6
6
  "Nox",
@@ -26,8 +26,8 @@
26
26
  "deploy:production": "pnpm hardhat run scripts/deploy.ts --build-profile production",
27
27
  "set-gateway": "pnpm hardhat run scripts/set-gateway.ts",
28
28
  "set-kms-public-key": "pnpm hardhat run scripts/set-kms-public-key.ts",
29
- "upgrade": "pnpm hardhat run scripts/upgrade.ts",
30
- "upgrade:production": "pnpm hardhat run scripts/upgrade.ts --build-profile production",
29
+ "upgrade": "bash scripts/upgrade.sh",
30
+ "upgrade:production": "bash scripts/upgrade.sh --build-profile production",
31
31
  "verify": "pnpm hardhat ignition verify",
32
32
  "format": "pnpm prettier --write .",
33
33
  "format:check": "pnpm prettier --check ."
@@ -44,19 +44,19 @@
44
44
  },
45
45
  "devDependencies": {
46
46
  "@nomicfoundation/hardhat-ethers": "^4.0.6",
47
- "@nomicfoundation/hardhat-ignition": "^3.0.9",
48
- "@nomicfoundation/hardhat-toolbox-viem": "^5.0.2",
47
+ "@nomicfoundation/hardhat-ignition": "^3.1.0",
48
+ "@nomicfoundation/hardhat-toolbox-viem": "^5.0.3",
49
49
  "@openzeppelin/hardhat-upgrades": "4.0.0-alpha.0",
50
- "@types/node": "^22.19.13",
50
+ "@types/node": "^25.5.0",
51
51
  "ethers": "^6.16.0",
52
52
  "forge-std": "github:foundry-rs/forge-std#v1.15.0",
53
- "hardhat": "^3.1.11",
53
+ "hardhat": "^3.2.0",
54
54
  "husky": "^9.1.7",
55
- "lint-staged": "^16.3.1",
55
+ "lint-staged": "^16.4.0",
56
56
  "prettier": "^3.8.1",
57
- "prettier-plugin-solidity": "^2.2.1",
58
- "typescript": "^5.9.3",
59
- "viem": "^2.46.3"
57
+ "prettier-plugin-solidity": "^2.3.1",
58
+ "typescript": "^6.0.2",
59
+ "viem": "^2.47.6"
60
60
  },
61
61
  "homepage": "https://github.com/iExec-Nox/nox-protocol-contracts#readme",
62
62
  "repository": {