Skip to content

[grid] fix Global Account HPKE docs#564

Merged
DhruvPareek merged 1 commit into
mainfrom
dp/fix-global-account-hpke-docs
Jun 10, 2026
Merged

[grid] fix Global Account HPKE docs#564
DhruvPareek merged 1 commit into
mainfrom
dp/fix-global-account-hpke-docs

Conversation

@DhruvPareek

@DhruvPareek DhruvPareek commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Document the Turnkey HPKE credential-bundle parameters used by Grid: info = "turnkey_hpke" and AAD over the uncompressed encapsulated key plus recipient public key.
  • Update the frontend sample decrypt path to use the same Turnkey HPKE info/AAD contract.
  • Clarify that encryptedWalletCredentials is a signed Turnkey export envelope, not the base58check session-bundle format.

Validation

  • npm run build in samples/frontend
  • make build at the stack tip

@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
grid-flow-builder Ignored Ignored Preview Jun 10, 2026 6:25pm

Request Review

@greptile-apps

greptile-apps Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes the HPKE decryption contract for Global Account session keys by documenting and implementing the two previously-missing parameters: info = "turnkey_hpke" (UTF-8) and AAD = encappedPublicUncompressed ∥ recipientPublicKeyUncompressed. It also corrects the wallet-export example to show a real signed Turnkey envelope instead of the old stub base58check string.

  • client-keys.mdx + AuthenticateAndSign.tsx: All three platform snippets (TypeScript, Kotlin, Swift) now decompress the 33-byte wire enc to 65-byte SEC1 form before handing it to the HPKE library, set info to \"turnkey_hpke\", and pass the concatenated uncompressed keys as AES-GCM AAD; the sandbox note is updated to reflect that real session bundles are now decryptable in sandbox.
  • exporting-wallet.mdx: Replaces the placeholder base58check value with a realistic signed Turnkey envelope JSON and clarifies that encryptedWalletCredentials is a distinct format from encryptedSessionSigningKey, fixing a misleading cross-reference that previously pointed readers to the wrong decrypt path.

Confidence Score: 5/5

Safe to merge — the crypto changes correctly align the sample and docs with Turnkey's HPKE contract.

All three platform code snippets and the live TypeScript sample now consistently decompress the encapsulated key, set the correct info string, and build the right AAD. The only discrepancy is the doc snippet's unnecessary @hpke/dhkem-p256 install line, which does not affect runtime correctness.

No files require special attention beyond the minor doc/package inconsistency in client-keys.mdx.

Important Files Changed

Filename Overview
mintlify/snippets/global-accounts/client-keys.mdx Adds Turnkey HPKE info/AAD contract to docs and code snippets (all three platforms); minor inconsistency between doc's @hpke/dhkem-p256 import and the actual sample that uses @hpke/core only.
mintlify/snippets/global-accounts/exporting-wallet.mdx Replaces stub base58check example with a realistic signed Turnkey envelope JSON and clarifies that encryptedWalletCredentials is a different format from the session bundle.
samples/frontend/src/steps/embeddedWallet/AuthenticateAndSign.tsx Correctly adds enc decompression (33→65 bytes), TURNKEY_HPKE_INFO constant, AAD construction (uncompressed enc ∥ recipient pub), and threads recipientPublicKey through the call site.

Sequence Diagram

sequenceDiagram
    participant C as Client
    participant G as Grid

    C->>C: generateKeyPair() → (privateKey, rawPublicKey[65 bytes])
    C->>G: "POST /challenge { clientPublicKey: hex(rawPublicKey) }"
    G-->>C: "{ challenge, requestId }"
    C->>G: "POST /verify { WebAuthn assertion }"
    G-->>C: "{ encryptedSessionSigningKey (base58check) }"
    Note over C: decode base58check → payload
    C->>C: "compressedEnc = payload[0:33]"
    C->>C: "enc = decompress(compressedEnc) → 65-byte SEC1"
    C->>C: "ciphertext = payload[33:]"
    C->>C: "aad = enc ∥ rawPublicKey"
    C->>C: "HPKE.open(enc, info=turnkey_hpke, aad) → sessionKey[32 bytes]"
    C->>C: sign(payloadToSign, sessionKey) → stamp
    C->>G: signed action + Grid-Wallet-Signature: stamp
Loading
Prompt To Fix All With AI
Fix the following 1 code review issue. Work through them one at a time, proposing concise fixes.

---

### Issue 1 of 1
mintlify/snippets/global-accounts/client-keys.mdx:178-181
**Doc install command references unused package**

The install comment tells readers to `npm i @hpke/dhkem-p256` and imports `DhkemP256HkdfSha256` from that package, but the actual working sample (`AuthenticateAndSign.tsx`) imports the same class directly from `@hpke/core` and `package.json` lists no `@hpke/dhkem-p256` dependency. In `@hpke/core@1.9.x`, `DhkemP256HkdfSha256` is already bundled, so the separate package is unnecessary. A developer copying the doc snippet would install a redundant package and use a slightly different import path from what the reference implementation demonstrates.

Reviews (3): Last reviewed commit: "[grid] fix Global Account HPKE docs" | Re-trigger Greptile

Comment on lines 69 to 73
<Step title="Decrypt on the client">
`encryptedWalletCredentials` uses the same base58check/HPKE format as `encryptedSessionSigningKey`. Decrypt with the export private key that matches the `clientPublicKey` you sent on both export requests — see <a href="client-keys#3-decrypt-the-session-signing-key">decrypt the session signing key</a> for code.
`encryptedWalletCredentials` is a signed Turnkey export envelope, not the base58check session-bundle format used by `encryptedSessionSigningKey`. Parse the envelope, verify `dataSignature` against `enclaveQuorumPublic`, decode the hex `data` JSON to get `encappedPublic` and `ciphertext`, then decrypt with the export private key that matches the `clientPublicKey` you sent on both export requests.

The plaintext is a BIP-39 mnemonic (the wallet's master seed).
</Step>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Wallet-export decrypt step omits HPKE parameters

The updated text describes four manual steps (parse, verify signature, hex-decode, decrypt) but does not say what HPKE info and AAD to use for the inner AES-GCM layer inside Turnkey's export envelope. Developers who attempt to decrypt encappedPublic/ciphertext by hand (mirroring the session-key pattern) will be missing the critical parameters. Even a forward reference to Turnkey's decrypt SDK or an explicit "use @turnkey/iframe-stamper / @turnkey/sdk-browser's injectCredentialBundle" would close the gap; right now the step ends right at the hardest part.

Prompt To Fix With AI
This is a comment left during a code review.
Path: mintlify/snippets/global-accounts/exporting-wallet.mdx
Line: 69-73

Comment:
**Wallet-export decrypt step omits HPKE parameters**

The updated text describes four manual steps (parse, verify signature, hex-decode, decrypt) but does not say what HPKE `info` and AAD to use for the inner AES-GCM layer inside Turnkey's export envelope. Developers who attempt to decrypt `encappedPublic`/`ciphertext` by hand (mirroring the session-key pattern) will be missing the critical parameters. Even a forward reference to Turnkey's decrypt SDK or an explicit "use `@turnkey/iframe-stamper` / `@turnkey/sdk-browser`'s `injectCredentialBundle`" would close the gap; right now the step ends right at the hardest part.

How can I resolve this? If you propose a fix, please make it concise.

@DhruvPareek DhruvPareek force-pushed the dp/fix-global-account-frontend-auth-sample branch 2 times, most recently from 50c9215 to 060c68b Compare June 10, 2026 17:08
@DhruvPareek DhruvPareek force-pushed the dp/fix-global-account-hpke-docs branch from 78c963c to a6cf246 Compare June 10, 2026 17:08
carsonp6
carsonp6 previously approved these changes Jun 10, 2026
@DhruvPareek DhruvPareek changed the base branch from dp/fix-global-account-frontend-auth-sample to graphite-base/564 June 10, 2026 18:24
@DhruvPareek DhruvPareek force-pushed the dp/fix-global-account-hpke-docs branch from a6cf246 to 8c57d07 Compare June 10, 2026 18:25

@restamp-bot restamp-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8c57d07 is a pure rebase onto 46611d1. Approving based on @carsonp6's previous approval of a6cf246.

restamp-bot[bot]
restamp-bot Bot previously approved these changes Jun 10, 2026

@restamp-bot restamp-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8c57d07 is a pure rebase onto 46611d1. Approving based on @carsonp6's previous approval of a6cf246.

@graphite-app graphite-app Bot changed the base branch from graphite-base/564 to main June 10, 2026 18:25
@graphite-app graphite-app Bot dismissed stale reviews from restamp-bot[bot] and carsonp6 June 10, 2026 18:25

The base branch was changed.

@DhruvPareek DhruvPareek force-pushed the dp/fix-global-account-hpke-docs branch from 8c57d07 to 93849f9 Compare June 10, 2026 18:25

@restamp-bot restamp-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

8c57d07 is a pure rebase onto 46611d1. Approving based on @carsonp6's previous approval of a6cf246.

@restamp-bot restamp-bot Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

93849f9 is a pure rebase onto 46611d1. Approving based on @carsonp6's previous approval of a6cf246.

@DhruvPareek DhruvPareek merged commit 34cacac into main Jun 10, 2026
10 checks passed

Copy link
Copy Markdown
Contributor Author

Merge activity

@DhruvPareek DhruvPareek deleted the dp/fix-global-account-hpke-docs branch June 10, 2026 18:27
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.

2 participants