Repository navigation
Conversation
Starting point for the deposit address example. Same code as examples/access-control/with-delegated/client-side, renamed, with the tsconfig path adjusted for the new depth. CHANGELOG.md and the unused Next.js boilerplate SVGs are left out.
Replace the delegated-access playground with one button. From the user's session it creates the non-root delegated user and one policy that lets it send ETH, or USDC via transfer(), only to the treasury. The address is shown as text and a QR code, and the sub-org panel checks that the user is the sole root and that there is exactly one policy.
register-webhook subscribes the parent org's BALANCE_CONFIRMED_UPDATES to /api/webhooks/balances, reusing an existing subscription if present. The route checks the Ed25519 signature against Turnkey's JWKS, drops repeated event ids, and maps the address to its sub-org through a JSON registry. The dashboard registers the address once the sub-org shows it enabled; the server checks with the delegated key that the key's user is in that sub-org, is not root, and that the address belongs to it.
On a confirmed ETH or USDC deposit the webhook queues a sweep. The server reads the balance and sends all of it to the treasury from the deposit address with sponsor: true, signed by the delegated key. Sweeps for one address run in order. Any failure, including a policy denial, is logged and recorded; nothing is retried and no other address is tried. The dashboard polls /api/sweeps and links each sweep hash. Setting SWEEP_ENABLED=false leaves deposits in place.
The withdraw panel sends ETH or USDC from the deposit address with the user's own session, sponsored, so it works without the platform key. pnpm validate signs, without broadcasting, as the delegated key: a send to the treasury (allowed), a send elsewhere (denied) and a raw payload (denied), plus the USDC pair. It first checks the key authenticates and is not root, so a bad key cannot pass as a denial.
Setup, env vars, the custody model, how a platform adds destinations later, a common failures table, and the example's limits.
Records what was checked offline and what still needs a live run.
cylon56
marked this pull request as ready for review
November 4, 2026 15:13
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
examples/transaction-management/with-deposit-address, a Next.js example of the universal deposit address flow on Base Sepolia, for ETH and USDC:transferABI to the sub-org,fetchOrCreateP256ApiKeyUseradds a non-root delegated user, andfetchOrCreatePoliciesadds two policies limiting that user to the destination.BALANCE_CONFIRMED_UPDATESwebhook hits/api/webhooks/balances. The route verifies the signature, de-duplicates by event id and maps the address to its sub-org. The delegated key then sends the full balance withsponsor: true. A denial is logged and never retried.pnpm validate: send to destination allowed; send elsewhere, raw payload and USDCtransferto the wrong recipient denied. A control confirms USDC to the right recipient is allowed.The policies:
These are two policies because the engine does not short-circuit a condition. A single condition joined with
||errors oneth.tx.function_namefor a plain ETH send, and the send is denied.The README covers setup, who controls what, adding destinations later, what the policy can and can't see, login options for a platform with no login of its own, and common failures.
STATUS.mdhas the full results.No new packages. The lockfile change is limited to this example's entries.
Checked live on Base Sepolia
pnpm validatereturns the expected result on all five checks.pnpm typecheck, prettier andnext buildare clean.Known issues
Failed to refresh session, and the user is sent back to the login page. A passkey re-login also failed once. Neither cause is known yet.🤖 Generated with Claude Code