Skip to content

feat: support multiple session key grants in single request#1055

Open
avataraad wants to merge 1 commit into
ithacaxyz:mainfrom
avataraad:feat/multi-session-key-grants
Open

feat: support multiple session key grants in single request#1055
avataraad wants to merge 1 commit into
ithacaxyz:mainfrom
avataraad:feat/multi-session-key-grants

Conversation

@avataraad

Copy link
Copy Markdown

Summary

Apps that need multiple session keys (e.g. server-side automation keys + local biometric-gated key) currently require N separate passkey prompts — one per grantPermissions call. This PR allows batching multiple permission grants into a single wallet_connect call, so all session keys are registered atomically in one passkey prompt.

  • grantPermissions capability now accepts Request | readonly Request[] (backward compatible — single objects still work)
  • New PermissionsRequest.toKeys() batch helper for parallel key generation
  • Relay mode createAccount, loadAccounts, and prepareUpgradeAccount normalize permissions to arrays and spread all session keys into authorizeKeys
  • Dialog mode updated with the same array normalization pattern
  • Bug fix: Pass webAuthn config to Key.sign() in relay grantPermissions handler (prevents crash in React Native WebAuthn environments)

Motivation

Our wallet creates 3 distinct session keys at account creation:

  1. Server-side vault operations (P256, server-held private key)
  2. Server-side reward claiming (P256, server-held private key)
  3. Local user transactions (P256, biometric-gated on device)

Today this requires 3 passkey prompts — terrible UX. With this change:

const response = await WalletActions.connect(walletClient, {
  createAccount: { label: 'My Wallet' },
  grantPermissions: [
    { expiry, key: key1, permissions: perms1, feeToken },
    { expiry, key: key2, permissions: perms2, feeToken },
    { expiry, key: key3, permissions: perms3, feeToken },
  ],
})
// 1 passkey prompt → 3 session keys registered atomically

Why this works

The relay infrastructure already supports this — authorizeKeys: Key[] is an array at every layer:

  • relay/schema/capabilities.tsauthorizeKeys = z.readonly(z.array(Key.WithPermissions))
  • RelayActions.prepareCalls()authorizeKeys?: readonly Key.Key[]
  • createAccount already sends [adminKey, ...adminKeys, sessionKey] today

This PR just removes the artificial singular constraint at the SDK TypeScript/schema layer.

Files changed (5)

File Change
schema/capabilities.ts grantPermissions.Request accepts Request | readonly Request[]
permissionsRequest.ts New toKeys() batch helper
mode.ts permissions param accepts arrays on 3 actions
modes/relay.ts Array normalization in 3 handlers + webAuthn bug fix
modes/dialog.ts Array normalization in 3 locations

Test plan

  • tsc --noEmit passes with zero type errors
  • Biome check passes
  • Existing tests pass (single permission still works — union accepts both forms)
  • Manual test: wallet_connect with array of 3 permission requests creates account with 3 session keys

🤖 Generated with Claude Code

Allow `grantPermissions` to accept an array of permission requests,
enabling apps to register multiple session keys in a single passkey
prompt via `wallet_connect`. The relay infrastructure already supports
`authorizeKeys: Key[]`, so this change is purely at the SDK layer.

Changes:
- `grantPermissions.Request` schema accepts `Request | readonly Request[]`
- `PermissionsRequest.toKeys()` batch helper for parallel key generation
- `createAccount`, `loadAccounts`, `prepareUpgradeAccount` mode actions
  accept array permissions and spread all session keys into authorizeKeys
- Dialog mode updated with same array normalization pattern
- Fix: pass `webAuthn` config to `Key.sign()` in relay `grantPermissions`
  (prevents crash on React Native WebAuthn environments)

Backward compatible — single permission objects still accepted everywhere.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Feb 19, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 1cca67d

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercel Bot commented Feb 19, 2026

Copy link
Copy Markdown

@avataraad is attempting to deploy a commit to the Tempo Team on Vercel.

A member of the Team first needs to authorize it.

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