Skip to content

Nightfall Celo Sepolia: correct withdraw examples and fill gaps#2174

Merged
jcortejoso merged 1 commit intomainfrom
jcortejoso/nightfall-sepolia-docs-fixes
Apr 18, 2026
Merged

Nightfall Celo Sepolia: correct withdraw examples and fill gaps#2174
jcortejoso merged 1 commit intomainfrom
jcortejoso/nightfall-sepolia-docs-fixes

Conversation

@jcortejoso
Copy link
Copy Markdown
Member

Summary

Based on an end-to-end run of the documented Celo Sepolia flow (deposit → private transfer → withdraw → de-escrow) with both CELO and USDT, a few places in the guide either didn't work as written or left users without enough information to finish the last step. This PR corrects those and fills in the missing context.

What changed in build-on-celo/nightfall.mdx

Corrections — following the old docs literally did not complete a withdraw

  • recipientAddress on /v1/withdraw and /v1/de-escrow must be 32-byte left-padded hex, no 0x prefix. The examples previously showed a 20-byte 0x… form that the API does not accept. Replaced with an explicit derivation snippet (L1_PADDED="000000000000000000000000${L1_ADDR#0x}") and a parameter note.
  • withdraw_fund_salt is returned in the client stdout log (and webhook payload), not in /v1/request/$WITHDRAW_ID. The old "the withdrawal response will include withdrawFundSalt" instruction leads to a dead end. Replaced with a docker logs … | grep … | sed … extraction snippet.
  • tokenId encoding is inconsistent across endpoints ("0x00" for /v1/transfer, full 64-zero form everywhere else). Surfaced inline at each endpoint instead of only mentioning it in the footer.

Additions — new material that isn't elsewhere in the guide

  • "One nightfall_client instance per user identity" warning. A single client tracks exactly one ZKP key pair; deriveKey does not re-scan past L2 blocks, so swapping mnemonics on a running client silently hides the new identity's funds. Dropping the client's MongoDB to force a re-scan permanently loses commitment preimages for funds already owned. Users attempting a sender → recipient flow need two independent stacks — new Warning block explains this and points to the playbook.
  • Amount Encoding table (CELO 18-decimals, USDT 6-decimals) with "1 whole unit" and common-fraction reference strings, so non-CELO tokens don't require manual math.
  • Diagnostic Endpoints table (/v1/health, /v1/balance, /v1/commitments, /v1/proposers, /v1/request). These were previously undocumented but essential for operating the client.
  • Funding note clarified: CLIENT_ADDRESS needs CELO for gas and a balance of whichever token is being deposited; approve() + transferFrom() are handled automatically by the client.
  • Withdraw Step 4 (wait for L2 inclusion) now uses the commitment status (PendingSpendSpent with nullifier == withdraw_fund_salt) as the source of truth, sidestepping a known status-tracking issue that can leave /v1/request/$WITHDRAW_ID stuck at Submitted in some client builds. Links the fix commit on celo-org/nightfall_4_CE@celo.
  • Timing guidance refined: with a healthy proposer, L2 confirmations are typically ~30 minutes per operation (proposer batches for 120 s, then generates the rollup proof); up to ~1 h under adverse conditions, at which point GET /v1/proposers is worth checking.
  • Cross-links to the new doc/celo_sepolia_client_playbook.md on the celo branch for a worked example.

What did NOT change

  • Introductory sections (Overview, What is Nightfall?, Architecture, Use Cases, Prerequisites, Transaction Flow diagrams, Integration Steps, Resources, About EY Nightfall).
  • The Deposit and Transfer curl examples themselves — only their parameter notes gained cross-links.

Test plan

  • Followed the new withdraw+de-escrow instructions end-to-end on Celo Sepolia with CELO (0.1 unit) — deposit, transfer, withdraw, de-escrow all completed, L1 recipient balance increased as expected.
  • Repeated with USDT (0xd077A400968890Eacc75cdc901F0356c943e4fDb, 6 decimals) using 1 whole-unit — full roundtrip including withdrawal to a fresh L1 address.
  • Verified recipientAddress padding requirement by submitting both forms against the running client.
  • Verified withdraw_fund_salt does not appear in /v1/request/$uuid response in the client build tested, but does appear in the stdout log as written.
  • All MDX tag pairs balanced (<Warning>, <Note>, <Tip>, <Info>).

Diff stats

+132 / −46 in one file.

…gaps

Improvements based on an end-to-end run of the documented flow
(deposit → transfer → withdraw → de-escrow) against Celo Sepolia.

Corrections (following the docs as-is did not work):

- recipientAddress on /v1/withdraw and /v1/de-escrow must be 32-byte
  left-padded hex, no 0x prefix. Replaced the 20-byte 0x-prefixed
  examples with a derivation snippet and explicit parameter note.
- withdraw_fund_salt is returned in the client stdout log (and webhook
  payload), not in /v1/request/$WITHDRAW_ID. Replaced the "the
  withdrawal response will include withdrawFundSalt" instruction with
  a docker logs extraction snippet.
- tokenId encoding is inconsistent across endpoints ("0x00" for
  transfer, full 64-zero form elsewhere). Called out inline at each
  relevant endpoint instead of only in the footer.

Additions:

- Warning block explaining that a single nightfall_client instance
  tracks one ZKP key pair, that deriveKey does not re-scan past L2
  blocks, and that dropping the client MongoDB while holding unspent
  commitments permanently strands the underlying L1 escrow. Suggests
  running two independent client+MongoDB stacks for a sender→recipient
  flow.
- Amount Encoding table (CELO 18-decimals, USDT 6-decimals) with
  common "1 whole unit" and "0.1 token" reference strings.
- Diagnostic Endpoints table (/v1/health, /v1/balance, /v1/commitments,
  /v1/proposers, /v1/request) — previously undocumented but essential
  for debugging.
- Funding note clarified: the client address needs CELO *for gas* and
  *also* a balance of whichever token is being deposited (approvals
  are handled automatically).
- Withdraw step 4: use the commitment status (PendingSpend → Spent
  with nullifier == withdraw_fund_salt) as the source of truth for
  "landed on L2". This sidesteps a known status-tracking issue that
  can leave /v1/request/$WITHDRAW_ID stuck at Submitted.
- Timing guidance refined: with a healthy proposer, confirmations are
  typically ~30 min per operation (proposer batches for 120 s, then
  generates the rollup proof); up to ~1 h under adverse conditions,
  after which /v1/proposers is worth checking.
- Cross-links to [Amount Encoding], and to the end-to-end
  [celo_sepolia_client_playbook.md] on the celo branch.

No change to the introductory architecture or prerequisites sections.
@jcortejoso jcortejoso requested a review from a team as a code owner April 18, 2026 12:11
@mintlify
Copy link
Copy Markdown
Contributor

mintlify Bot commented Apr 18, 2026

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
celo-docs 🟢 Ready View Preview Apr 18, 2026, 12:11 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@jcortejoso jcortejoso merged commit e73e073 into main Apr 18, 2026
5 checks passed
@jcortejoso jcortejoso deleted the jcortejoso/nightfall-sepolia-docs-fixes branch April 18, 2026 15:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant