feat(examples): migrate examples to updated SDK API#301
feat(examples): migrate examples to updated SDK API#301
Conversation
…1271,6492) (#294) * feat: move erc7824 documentation to nitrolite (#272) * feat: move erc7824 documentation to nitrolite * feat: move GH actions to common scope * fix: comment GITHUB_TOKEN * feat(custody): add EIP-191, EIP-712 signature support (#257) * feat(custody): add EIP-191, EIP-712 support * feat(custody): correct EIP-712 sig impl * feat(utils): add POLA principle comment * feat(contract): add EIP712AdjudicatorBase * feat(contract): integrate EIP712AdjudicatorBase to supported adjs * fix(contract): tests with updated adjs * test(contract): EIP712AdjudicatorBase * test(contract): SimpleConsensus EIP191, EIP712 sigs * test(contract): Utils signatures * test(contract): Custody, SimpleConsensus integration tests for sigs * refactor(contract): migrate sig to bytes (#279) * refactor(Types): replace Signature{v,r,s} with bytes * style(contract): add empty lines at the end * refactor(clearnode): replace Signature{r,s,v} with []byte (#283) * refactor(sdk): migrate `Signature{r,s,v}` to `Hex` (#284) * refactor(sdk): replace Signature{r,s,v} with Hex * fix(NitroliteService): perform convertStateFromContract correctly * fix(rpc): expect updated signature type from rpc * style(sdk/rpc): remove ServerSignatureSchema var * feat(sdk/rpc): add empty signatures array by default * feat(sdk): add build:force command * feat(sdk): remove npm build:force * refactor(clearnode): define `Signature []byte` type (#287) * refactor(clearnode): define `Signature []byte` type * refactor(clearnode::RPCEntry): replace sig `[]string` with `[]Signature` * feat(clearnode/nitrolite): add Sigs2Strings, Strings2Sigs helpers * fix(integration): tests sig migration (#289) * feat(docker-compose): add ability to pass logger visibility to clearnode * fix(clearnode): raw ECDSA sign and verify * fix(clearnode): try to extract req id on ummarshal error * fix(integration): update sig to new type * feat(sdk): change type of sig array to contain only Hex * refactor(clearnode): remove check on nil Req, zero-init instead * fix(clearnode:nitrolite): remove unintended side-effect of sig param modif * feat(custody): add note about ephemeral final state * style(contract): run forge fmt * fix(clearnode/docs): remove legacy signature format * feat(custody): eip-1271, eip-6492 sigs support (#293) * feat(contract): add ERC-1271,6492 support * test(contract/Utils.sol): add ERC-1271, 6492 tests * refactor(contract:Utils.t.sol): separate tests into contracts * refactor(UtilsHarness): do NOT expose constants * fix(contracts/adjudicators): use verifyStateSignature instead of just EOA sig * test(contract/Custody): add ERC-1271, 6492 sig to integration test * test(contract/Custody): add challenge with EIP-712, EIP-1271 tests * refactor(contract/Utils): reorder recoverStateEIP712Signer params for consistency * test(contract): remove console.logs * feat(contract): clarify Utils comments * refactor(contract): optimize Custody and Utils sig verification functions * style(contract): run forge fmt * feat: replace `stateHash` with `packedState` in message signing (#295) * feat(contract): replace stateHash with packedState in signing * test(contract): migrate to getPackedState * feat(contract): remove getStateHash * feat(clearnode): remove state_hash, rename EncodeState to Pack * feat(sdk): remove state_hash, add getPackedState * refactor(sdk): supply channelId and state to signState * docs(website): migrate Sig to Hex, add supported signature formats --------- Co-authored-by: MaxMoskalenko <mx.msklnk@gmail.com>
There was a problem hiding this comment.
Pull Request Overview
This PR migrates examples to use the updated SDK API, transitioning from array-based parameters to object-based parameters for RPC methods, updating import paths for renamed and refactored parser functions, and modernizing type imports with the type keyword.
Key changes include:
- Replace
rpcResponseParserwith individual named parser functions - Convert array-wrapped parameters to direct object parameters for RPC methods
- Update import paths and add
typekeyword for type-only imports
Reviewed Changes
Copilot reviewed 76 out of 79 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| sdk/test/unit/rpc/utils.test.ts | Updates test imports and response parsing to use new individual parser functions |
| sdk/test/unit/rpc/nitrolite.test.ts | Updates test parameter structure from arrays to objects and removes deprecated parseResponse tests |
| sdk/test/unit/rpc/api.test.ts | Converts RPC method parameters from array format to object format throughout tests |
| sdk/src/utils/state.ts | Adds type keyword to imports for better type safety |
| sdk/src/rpc/types/response.ts | Major refactor consolidating response types and removing redundant type definitions |
| sdk/src/rpc/types/request.ts | Restructures request parameter types from array-based to object-based format |
| sdk/src/rpc/types/index.ts | Updates core type definitions and consolidates common types |
| sdk/src/rpc/types/filters.ts | New file defining filter interfaces for RPC methods |
| sdk/src/rpc/types/common.ts | New file consolidating common RPC types and enums |
| sdk/src/rpc/parse/parse.ts | Replaces rpcResponseParser object with individual named parser functions |
| Integration and example files | Updates to use new API structure with object parameters and new parser functions |
Comments suppressed due to low confidence (4)
sdk/src/rpc/nitrolite.ts:32
- [nitpick] The parameter name
signaturesis inconsistent with the actual property namesigused in the message structure. Consider renaming tosigfor consistency.
signatures = [],
sdk/src/rpc/types/request.ts:367
- The type name
GetRPCHistoryParamsis inconsistent with the pattern used by other similar types which end withRequestParams. Should beGetRPCHistoryRequestParams.
export type GetRPCHistoryParams = GetRPCHistoryRequest['params'];
sdk/test/unit/rpc/api.test.ts:437
- The expected signature value has changed but there's no comment explaining why this signature is different from the previous one. This suggests the signing logic may have changed and should be documented or verified.
'0x7263178cbb9b9820491b3add77f83ebbab7df700fc30734a659b69bf0268073a2494ccbcf0ee3e98a9321f88385013a88aabe6a640d6411cda19fbbc197d38ac1c',
integration/tests/challenge_channel.test.ts:12
- The test suite is skipped with a TODO comment mentioning it could stuck anvil. This test should either be fixed to prevent hanging or properly removed if it's no longer needed.
describe.skip('Close channel', () => {
| * Represents the allocation of assets within an application session. | ||
| * This structure is used to define the initial allocation of assets among participants. | ||
| * It includes the participant's address, the asset (usdc, usdt, etc) being allocated, and the amount. | ||
| */ | ||
| export interface RPCAppSessionAllocation { | ||
| /** The symbol of the asset (e.g., "USDC", "USDT", "ETH"). */ | ||
| asset: string; | ||
| /** The amount of the asset. Must be a positive number. */ | ||
| amount: string; | ||
| /** The Ethereum address of the participant receiving the allocation. */ | ||
| participant: Address; | ||
| } | ||
|
|
||
| /** | ||
| * Represents the allocation of assets for an RPC transfer. | ||
| * This structure is used to define the asset and amount being transferred to a specific destination address. | ||
| */ | ||
| export interface RPCChannelAllocation { | ||
| /** The destination address for the allocation. */ | ||
| destination: Address; | ||
| /** The token contract address for the asset being allocated. */ | ||
| token: Address; | ||
| /** The amount of the asset being allocated. */ | ||
| amount: bigint; | ||
| } | ||
|
|
||
| /** | ||
| * Represents the allocation of assets for an RPC transfer. | ||
| * This structure is used to define the asset and amount being transferred. | ||
| */ | ||
| export interface RPCTransferAllocation { | ||
| /** The symbol of the asset (e.g., "USDC", "USDT", "ETH"). */ | ||
| asset: string; | ||
| /** The amount of the asset being transferred. */ | ||
| amount: string; | ||
| } |
There was a problem hiding this comment.
There are multiple allocation types defined (RPCAppSessionAllocation, RPCChannelAllocation, RPCTransferAllocation) with overlapping fields. Consider consolidating these into a unified allocation type hierarchy as suggested by the TODO comment.
| * Represents the allocation of assets within an application session. | |
| * This structure is used to define the initial allocation of assets among participants. | |
| * It includes the participant's address, the asset (usdc, usdt, etc) being allocated, and the amount. | |
| */ | |
| export interface RPCAppSessionAllocation { | |
| /** The symbol of the asset (e.g., "USDC", "USDT", "ETH"). */ | |
| asset: string; | |
| /** The amount of the asset. Must be a positive number. */ | |
| amount: string; | |
| /** The Ethereum address of the participant receiving the allocation. */ | |
| participant: Address; | |
| } | |
| /** | |
| * Represents the allocation of assets for an RPC transfer. | |
| * This structure is used to define the asset and amount being transferred to a specific destination address. | |
| */ | |
| export interface RPCChannelAllocation { | |
| /** The destination address for the allocation. */ | |
| destination: Address; | |
| /** The token contract address for the asset being allocated. */ | |
| token: Address; | |
| /** The amount of the asset being allocated. */ | |
| amount: bigint; | |
| } | |
| /** | |
| * Represents the allocation of assets for an RPC transfer. | |
| * This structure is used to define the asset and amount being transferred. | |
| */ | |
| export interface RPCTransferAllocation { | |
| /** The symbol of the asset (e.g., "USDC", "USDT", "ETH"). */ | |
| asset: string; | |
| /** The amount of the asset being transferred. */ | |
| amount: string; | |
| } | |
| * Represents the base allocation structure shared across different allocation types. | |
| */ | |
| export interface RPCBaseAllocation { | |
| /** The symbol of the asset (e.g., "USDC", "USDT", "ETH"). */ | |
| asset: string; | |
| /** The amount of the asset. Must be a positive number. */ | |
| amount: bigint; | |
| } | |
| /** | |
| * Represents the allocation of assets within an application session. | |
| * Extends the base allocation structure with a participant field. | |
| */ | |
| export interface RPCAppSessionAllocation extends RPCBaseAllocation { | |
| /** The Ethereum address of the participant receiving the allocation. */ | |
| participant: Address; | |
| } | |
| /** | |
| * Represents the allocation of assets for an RPC transfer. | |
| * Extends the base allocation structure with a destination and token field. | |
| */ | |
| export interface RPCChannelAllocation extends RPCBaseAllocation { | |
| /** The destination address for the allocation. */ | |
| destination: Address; | |
| /** The token contract address for the asset being allocated. */ | |
| token: Address; | |
| } | |
| /** | |
| * Represents the allocation of assets for an RPC transfer. | |
| * Uses the base allocation structure without additional fields. | |
| */ | |
| export type RPCTransferAllocation = RPCBaseAllocation; |
There was a problem hiding this comment.
Summary of Changes
Hello @maxpushka, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces a fundamental change to the RPC API by standardizing parameter passing to use direct objects instead of array-wrapped structures. This refactoring aims to improve API consistency and developer experience. The changes are propagated across the entire stack, from the Go backend and TypeScript SDK to all example applications, ensuring a unified and updated interface. Additionally, internal notification mechanisms have been centralized for better maintainability.
Highlights
- RPC API Parameter Restructuring: The core RPC API has been updated to pass parameters as direct objects (
{...}) instead of array-wrapped objects ([{...}]) in both requests and responses. This significantly streamlines the API interface. - Enhanced Type Safety in Go Backend: The internal WebSocket notifier's callback signature in Go has been refined from a generic
...anyto a more specificRPCDataParams, improving type safety and clarity in backend communication. - Centralized Notification Management: A new Go file (
rpc_router_callback.go) has been introduced to consolidate and standardize the logic for sending various WebSocket notifications (e.g., balance updates, channel updates) to clients. - Comprehensive Documentation Updates: The API documentation (
API.md,Clearnode.protocol.md) has been thoroughly revised to accurately reflect the new RPC parameter structures, response formats, and the inclusion of pagination metadata for relevant endpoints. - SDK and Example Application Migration: The TypeScript SDK and all example applications (Snake, TicTacToe, Viper Duel) have been fully migrated to align with the updated RPC API, ensuring seamless compatibility and demonstrating correct usage of the new parameter structures.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments or fill out our survey to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Code Review
This pull request migrates examples to the updated SDK API. The changes are extensive and consistently applied across the codebase, significantly improving the API's clarity and structure. Key improvements include transitioning from array-based to object-based RPC parameters and introducing dedicated response structs, which enhances type safety and developer experience. The documentation has been thoroughly updated to reflect these API changes.
| { | ||
| "asset": "usdc", | ||
| "amount": "100.0" | ||
| } |
| // TODO: ensure that it accepts only structs or maps, and prevent passing primitive (and other DS) types | ||
| type RPCDataParams = any |
There was a problem hiding this comment.
Consider adding a comment explaining why RPCDataParams is defined as any. What are the implications of using any here, and how should developers use this type?
| // TODO: ensure that it accepts only structs or maps, and prevent passing primitive (and other DS) types | |
| type RPCDataParams = any | |
| // RPCDataParams represents the type for RPC parameters. It is defined as `any` to allow for flexibility in the types of parameters that can be used in RPC calls. Ensure that the parameters passed are properly validated in the handler functions. |
|
|
||
| // NewTransferNotification creates a notification for a transfer event | ||
| func NewTransferNotification(wallet string, transferredAllocations []TransactionResponse) *Notification { | ||
| func NewTransferNotification(wallet string, transferredAllocations TransferResponse) *Notification { |
There was a problem hiding this comment.
The function NewTransferNotification accepts TransferResponse as a parameter, but the comment above suggests it accepts []TransactionResponse. Consider updating the comment to reflect the actual parameter type.
// NewTransferNotification creates a notification for a transfer event
func NewTransferNotification(wallet string, transferredAllocations TransferResponse) *Notification {a0f86b7 to
ac68712
Compare
6edf152 to
2290bb2
Compare
|
Closed as example apps were extracted from this repo. |
This PR updates Nitrolite examples based on changes provided in #285