From cedf15003d63d7ead8321c6fcfee392ff4de52ce Mon Sep 17 00:00:00 2001 From: nksazonov Date: Mon, 28 Jul 2025 16:15:38 +0300 Subject: [PATCH] docs: update raw ECDSA and EIP-191 sig mentions --- docs/erc-7824.md | 31 ++++++++++---------- docs/nitrolite_client/types.md | 10 ++----- docs/quick_start/connect_to_the_clearnode.md | 2 +- 3 files changed, 19 insertions(+), 24 deletions(-) diff --git a/docs/erc-7824.md b/docs/erc-7824.md index 2a6ae42..501bc8b 100644 --- a/docs/erc-7824.md +++ b/docs/erc-7824.md @@ -49,12 +49,6 @@ The Nitrolite protocol defines the following core data structures: #### Basic Types ```solidity -struct Signature { - uint8 v; - bytes32 r; - bytes32 s; -} - struct Amount { address token; // ERC-20 token address (address(0) for native tokens) uint256 amount; // Token amount @@ -86,7 +80,7 @@ struct State { uint256 version; // State version incremental number to compare most recent bytes data; // Application data encoded, decoded by the adjudicator Allocation[] allocations; // Asset allocation and destination for each participant - Signature[] sigs; // stateHash signatures from participants + bytes[] sigs; // stateHash signatures from participants } enum StateIntent { @@ -132,14 +126,15 @@ For signature verification, the state hash is computed as: bytes32 stateHash = keccak256( abi.encode( channelId, - state.data, + state.intent, state.version, + state.data, state.allocations ) ); ``` -Note: The stateHash is bare signed without EIP-191 since the protocol is intended to be chain-agnostic. +Note: The smart contract supports all popular signature formats, specifically: raw ECDSA, EIP-191, EIP-712, EIP-1271, and EIP-6492. ### Interfaces @@ -218,7 +213,7 @@ interface IChannel { * @param sig Signature of the participant on the funding state * @return channelId Unique identifier for the joined channel */ - function join(bytes32 channelId, uint256 index, Signature calldata sig) + function join(bytes32 channelId, uint256 index, bytes calldata sig) external returns (bytes32); /** @@ -253,11 +248,13 @@ interface IChannel { * @param channelId Unique identifier for the channel * @param candidate The state being submitted as the latest valid state * @param proofs Additional states required by the adjudicator + * @param challengerSig Signature of the challenger on the candidate state. Must be signed by one of the participants */ function challenge( bytes32 channelId, State calldata candidate, - State[] calldata proofs + State[] calldata proofs, + bytes calldata challengerSig ) external; /** @@ -284,25 +281,27 @@ interface IDeposit { /** * @notice Deposits tokens into the contract * @dev For native tokens, the value should be sent with the transaction + * @param wallet Address of the account whose ledger is changed * @param token Token address (use address(0) for native tokens) * @param amount Amount of tokens to deposit */ - function deposit(address token, uint256 amount) external payable; + function deposit(address wallet, address token, uint256 amount) external payable; /** * @notice Withdraws tokens from the contract * @dev Can only withdraw available (not locked in channels) funds + * @param wallet Address of the account whose ledger is changed * @param token Token address (use address(0) for native tokens) * @param amount Amount of tokens to withdraw */ - function withdraw(address token, uint256 amount) external; + function withdraw(address wallet, address token, uint256 amount) external; } ``` ### Channel Lifecycle -1. **Creation**: Creator constructs channel config and signs initial state with `StateIntent.INITIALIZE` -2. **Joining**: Participants verify the channel and sign the same funding state +1. **Creation**: Creator constructs channel config and signs initial state with `StateIntent.INITIALIZE`. Second participant are able to join a channel immediately by providing a signature over initial state, and funds will be deducted from their account, if available. +2. **Joining**: Participants verify the channel and sign the same funding state. This step can be omitted by providing a signature over the initial state when creating the channel. Note, however, that this means that funds will be locked from the participant's balance, while `join(...)` allows to fund the channel from external account. 3. **Active**: Once fully funded, the channel transitions to active state for off-chain operation 4. **Off-chain Updates**: Participants exchange and sign state updates according to application logic 5. **Resolution**: @@ -456,7 +455,7 @@ No backward compatibility issues found. This ERC is designed to coexist with exi ### On-Chain Security -- **Signature Verification**: All state transitions require valid signatures from participants. The protocol uses bare signatures (without EIP-191) for chain agnosticism. +- **Signature Verification**: All state transitions require valid signatures from participants. The protocol supports signatures of all popular formats, including EIP-191 and EIP-712. - **Challenge Period**: The configurable challenge duration provides time for honest participants to respond to invalid states. - **Adjudicator Validation**: Custom adjudicators must be carefully audited as they control state transition rules. - **Reentrancy Protection**: Implementation should follow checks-effects-interactions pattern, especially in fund distribution. diff --git a/docs/nitrolite_client/types.md b/docs/nitrolite_client/types.md index 607f5e0..74baa04 100644 --- a/docs/nitrolite_client/types.md +++ b/docs/nitrolite_client/types.md @@ -30,14 +30,10 @@ A hash of a channel state, represented as a hexadecimal string. ### Signature ```typescript -interface Signature { - v: number; // Recovery value - r: Hex; // First 32 bytes of the signature - s: Hex; // Second 32 bytes of the signature -} +type Signature = Hex; ``` -Represents a cryptographic signature used for signing state channel states. +Represents a cryptographic signature used for signing state channel states as a hexadecimal string. ### Allocation @@ -85,7 +81,7 @@ interface State { version: bigint; // Version number, incremented for each update data: Hex; // Application data encoded as hex allocations: [Allocation, Allocation]; // Asset allocation for each participant - sigs: Signature[]; // State hash signatures + sigs: Signature[]; // State hash signatures } ``` diff --git a/docs/quick_start/connect_to_the_clearnode.md b/docs/quick_start/connect_to_the_clearnode.md index 4a410ff..390866c 100644 --- a/docs/quick_start/connect_to_the_clearnode.md +++ b/docs/quick_start/connect_to_the_clearnode.md @@ -554,7 +554,7 @@ const messageSigner = async (payload: RequestData | ResponsePayload): Promise