feat: fetch token data data from crisp server#804
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub. 2 Skipped Deployments
|
|
❌ License Header Check Failed Some files are missing the required SPDX license header. Please add the following header to the beginning of all You can run Or run |
WalkthroughAdds a new TypeScript CRISP SDK (package, formatting, build, tests) exposing token-tree fetch APIs; adds a server route to return token-holder hashes; changes server round lifecycle to initialize on Requested and start on Activated; updates deploy script to skip deleting previous deployments; includes SDK in pnpm workspace. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client as SDK Consumer
participant SDK as CRISP SDK
participant Server as CRISP Server
participant Repo as CrispE3Repository
Client->>SDK: getTreeData(serverUrl, e3Id)
SDK->>Server: POST /state/token-holders { round_id: e3Id }
Server->>Repo: get_token_holder_hashes(round_id)
Repo-->>Server: tokenHolderHashes
Server-->>SDK: 200 OK JSON (hashes)
SDK-->>Client: Parsed JSON
note right of Server: Errors return HTTP 500 with JSON message
sequenceDiagram
autonumber
actor Chain as E3 Events
participant Indexer as indexer.rs
participant Repo as CrispE3Repository
rect rgba(200,235,255,0.3)
note right of Chain: Requested Event
Chain->>Indexer: register_e3_requested
Indexer->>Repo: initialize_round()
Repo-->>Indexer: Ok
end
rect rgba(200,255,200,0.3)
note right of Chain: Activated Event
Chain->>Indexer: register_e3_activated
Indexer->>Repo: start_round()
Repo-->>Indexer: Ok
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (1)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
7f4dbfa to
0afefdf
Compare
|
❌ License Header Check Failed Some files are missing the required SPDX license header. Please add the following header to the beginning of all You can run Or run |
0afefdf to
1f91006
Compare
1f91006 to
5fe8d6f
Compare
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (8)
examples/CRISP/server/src/server/repo.rs (1)
87-112: Collapse the doublemodifyinto a single callWe mutate the same record twice in succession to bump
start_timeandstatus. Folding both field writes into onemodifykeeps the operation atomic, trims a store roundtrip, and narrows the window for racing updates.Apply this diff to combine the updates:
- self.store - .modify(&key, |e3_obj: Option<E3Crisp>| { - e3_obj.map(|mut e| { - e.start_time = start_time; - e - }) - }) - .await - .map_err(|_| eyre::eyre!("Could not update start_time for '{key}'"))?; - - self.store - .modify(&key, |e3_obj: Option<E3Crisp>| { - e3_obj.map(|mut e| { - e.status = "Active".to_string(); - e - }) - }) + self.store + .modify(&key, |e3_obj: Option<E3Crisp>| { + e3_obj.map(|mut e| { + e.start_time = start_time; + e.status = "Active".to_string(); + e + }) + }) .await - .map_err(|_| eyre::eyre!("Could not update status for '{key}'"))?; + .map_err(|_| eyre::eyre!("Could not update start_time/status for '{key}'"))?;examples/CRISP/sdk/tsconfig.json (1)
2-11: Harden SDK tsconfig for consumers (target/lib/rootDir/maps).Recommend adding explicit target/libs, rootDir, and declaration maps for better DX and browser typings.
Apply this diff:
"compilerOptions": { "composite": true, "skipLibCheck": true, "module": "ESNext", "moduleResolution": "bundler", "allowSyntheticDefaultImports": true, "strict": true, "outDir": "dist", - "declaration": true + "declaration": true, + "declarationMap": true, + "rootDir": "src", + "target": "ES2022", + "lib": ["ES2022", "DOM"] },examples/CRISP/server/src/server/indexer.rs (1)
80-92: External call resiliency to Bitquery (timeouts/backoff/pagination).The "10000" limit and TODO are noted. Please ensure the Bitquery client enforces reasonable timeouts, retries with jitter on 429/5xx, and supports pagination/chunking to avoid blocking the handler and OOM on large holder sets.
If not already present in BitqueryClient, consider:
- Request timeout (e.g., 15–30s) and retry with exponential backoff on retriable errors.
- Paginated fetch merging with streaming/chunked processing to bound memory.
examples/CRISP/server/src/server/routes/state.rs (2)
49-55: Avoid leaking internal errors in HTTP responses.Returning raw error strings exposes internals. Prefer generic messages, keep details in logs.
Apply this diff:
- Err(e) => { - info!("Failed to create contract: {:?}", e); - return HttpResponse::InternalServerError() - .json(format!("Failed to create contract: {}", e)); - } + Err(e) => { + info!("Failed to create contract: {:?}", e); + return HttpResponse::InternalServerError().body("Failed to create contract"); + }And similarly for the send transaction branch:
- Err(e) => { - error!("Failed to send transaction: {:?}", e); - return HttpResponse::InternalServerError() - .json(format!("Failed to send transaction: {}", e)); - } + Err(e) => { + error!("Failed to send transaction: {:?}", e); + return HttpResponse::InternalServerError().body("Failed to send transaction"); + }Also applies to: 58-61
171-183: Map not-found to 404 and consider GET for caching.All errors return 500. If the round or hashes are missing, return 404. Also consider making this a GET with round_id as a query param to enable HTTP caching.
Example:
- match store.e3(incoming.round_id).get_token_holder_hashes().await { - Ok(hashes) => HttpResponse::Ok().json(hashes), - Err(e) => { - error!("Error getting token holders hashes: {:?}", e); - HttpResponse::InternalServerError().body("Failed to get token holders hashes") - } - } + match store.e3(incoming.round_id).get_token_holder_hashes().await { + Ok(hashes) => HttpResponse::Ok().json(hashes), + Err(e) => { + error!("Error getting token holders hashes: {:?}", e); + // Pseudocode: adjust to your error types + if e.to_string().contains("not found") { + HttpResponse::NotFound().body("Token holder hashes not found") + } else { + HttpResponse::InternalServerError().body("Failed to get token holder hashes") + } + } + }If you stick to POST for consistency, still apply the error mapping.
examples/CRISP/sdk/src/token.ts (3)
32-35: Implement the Merkle proof generation.This function is a placeholder but directly addresses PR objective #685 (expose merkle tree data for inclusion proofs).
Would you like me to help generate an implementation for this function, or should this be tracked as a follow-up task?
37-40: Placeholder function without implementation.This function is currently a placeholder. Consider adding a TODO comment or tracking as a follow-up task if not needed for the current PR scope.
51-54: Placeholder function without implementation.Since the
IRoundDetailsinterface is already defined (lines 45-49), consider implementing this function or documenting when it will be added.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (13)
examples/CRISP/scripts/evm_deploy.sh(0 hunks)examples/CRISP/sdk/.prettierignore(1 hunks)examples/CRISP/sdk/.prettierrc(1 hunks)examples/CRISP/sdk/package.json(1 hunks)examples/CRISP/sdk/src/constants.ts(1 hunks)examples/CRISP/sdk/src/index.ts(1 hunks)examples/CRISP/sdk/src/token.ts(1 hunks)examples/CRISP/sdk/tests/token.test.ts(1 hunks)examples/CRISP/sdk/tsconfig.json(1 hunks)examples/CRISP/server/src/server/indexer.rs(2 hunks)examples/CRISP/server/src/server/repo.rs(3 hunks)examples/CRISP/server/src/server/routes/state.rs(3 hunks)pnpm-workspace.yaml(1 hunks)
💤 Files with no reviewable changes (1)
- examples/CRISP/scripts/evm_deploy.sh
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-08-25T10:28:56.174Z
Learnt from: ctrlc03
PR: gnosisguild/enclave#657
File: Cargo.toml:32-34
Timestamp: 2025-08-25T10:28:56.174Z
Learning: The examples/CRISP directory has its own Cargo.toml workspace configuration with members like "server", "wasm-crypto", "program/core", "program/client", etc. The root workspace intentionally excludes "examples/CRISP/server", "examples/CRISP/program", and "examples/CRISP/wasm-crypto" to prevent double workspace membership, which is the correct approach for self-contained example workspaces.
Applied to files:
pnpm-workspace.yaml
🧬 Code graph analysis (3)
examples/CRISP/sdk/src/token.ts (1)
examples/CRISP/sdk/src/constants.ts (1)
CRISP_SERVER_TOKEN_TREE_ENDPOINT(7-7)
examples/CRISP/server/src/server/routes/state.rs (2)
crates/evm-helpers/src/contracts.rs (1)
create_write(251-271)examples/CRISP/server/src/server/repo.rs (2)
store(35-37)store(78-80)
examples/CRISP/sdk/tests/token.test.ts (1)
examples/CRISP/sdk/src/token.ts (1)
getTreeData(14-30)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (8)
- GitHub Check: crisp_e2e
- GitHub Check: test_enclave_init
- GitHub Check: build_sdk
- GitHub Check: rust_unit
- GitHub Check: integration_prebuild
- GitHub Check: test_net
- GitHub Check: test_contracts
- GitHub Check: Build & Push Image
🔇 Additional comments (7)
pnpm-workspace.yaml (1)
6-6: SDK inclusion in workspace looks goodAdding
examples/CRISP/sdkensures the new package participates in the pnpm workspace. 👍examples/CRISP/sdk/.prettierrc (1)
1-10: Prettier config is consistentSettings line up with the rest of the repo conventions for the SDK. No concerns.
examples/CRISP/sdk/src/constants.ts (1)
1-7: Endpoint constant matches the new route
state/token-holdersaligns with the server’s token-holder hash endpoint. Looks good.examples/CRISP/server/src/server/indexer.rs (2)
139-140: Good: start round on Activated instead of re-initializing.This should prevent overwriting state written during Requested.
Please confirm start_round does not reset fields like token_holder_hashes or e3_params set earlier. If needed, add an integration test covering Requested→Activated preserving those fields.
49-52: Right move: initialize on E3Requested to fix round reset. Please verify idempotence.This aligns lifecycle with #806. Ensure initialize_round only sets baseline state and does not overwrite any fields already set later in the same handler (e.g., custom params, token-holder hashes).
Run to confirm call sites and guard against regressions:
examples/CRISP/sdk/src/index.ts (1)
7-7: LGTM: clean barrel export.examples/CRISP/sdk/src/token.ts (1)
45-49: Interface definition looks reasonable.The
IRoundDetailsinterface is well-defined. Usingstringtypes forsnapshotBlockandthresholdis appropriate for handling large numbers without precision loss.
* feat: fetch token data from crisp server * fix: server resetting data * chore: add license * chore: update package.json
* feat: fetch token data from crisp server * fix: server resetting data * chore: add license * chore: update package.json
* feat: fetch token data from crisp server * fix: server resetting data * chore: add license * chore: update package.json
* feat: fetch token data from crisp server * fix: server resetting data * chore: add license * chore: update package.json
fix #685 and fix #806
Summary by CodeRabbit
New Features
Changes
Tests
Chores