[PR #6685] [CLOSED] feat(siwe): allow linking SIWE wallets to existing accounts #6824

Closed
opened 2026-03-13 13:12:59 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/better-auth/better-auth/pull/6685
Author: @META-DREAMER
Created: 12/11/2025
Status: Closed

Base: canaryHead: feat/siwe-wallet-linking


📝 Commits (10+)

  • 30f741b feat(siwe): allow linking SIWE wallets to existing accounts
  • d3f98c2 fix(siwe): include session token in wallet linking responses
  • 857b80d chore(siwe): standardize error codes + refactor and improve tests
  • c975f09 fix(siwe): update error message for wallet linking and enhance validation
  • 1fb3164 feat(siwe): implement cascading deletion of wallet addresses on account unlinking
  • 6ced1e1 docs(siwe): Add docs on wallet account linking
  • b8377d8 chore(siwe): add SESSION_CREATION_FAILED error code and refactor error handling
  • 7b20502 fix(siwe): enforce email requirement when anonymous option is disabled
  • 5a4ffd6 chore(siwe): update tests to use proper error code for WALLET_ALREADY_LINKED
  • 3d3e701 Merge branch 'canary' into feat/siwe-wallet-linking

📊 Changes

4 files changed (+1705 additions, -829 deletions)

View changed files

📝 docs/content/docs/plugins/siwe.mdx (+38 -0)
packages/better-auth/src/plugins/siwe/error-codes.ts (+8 -0)
📝 packages/better-auth/src/plugins/siwe/index.ts (+250 -174)
📝 packages/better-auth/src/plugins/siwe/siwe.test.ts (+1409 -655)

📄 Description

Summary

Adds support for linking SIWE wallets to existing authenticated user accounts, with cross-chain wallet identity protection.

Changes

  • Account Linking Support: Respects accountLinking.enabled and accountLinking.trustedProviders configuration. When authenticated and linking is enabled (with siwe in trusted providers), wallets are linked to the existing account instead of creating a new user.
    • Creates new users when not authenticated (original behaviour preserved)
    • Returns success if wallet is already linked to current user (idempotent)
    • Throws WALLET_ALREADY_LINKED error if wallet belongs to another user
    • Cascades deletion of walletAddress when account is unlinked
  • Cross-Chain Identity Protection: Prevents different users from linking the same wallet address on different chains. A wallet address represents the same key pair across all chains, so linking 0x123... on Ethereum should not be allowed if it's already linked to another user on Polygon.

Test plan

  • Added test: links wallet when accountLinking.trustedProviders includes siwe
  • Added test: links wallet when trustedProviders is undefined (default behavior)
  • Added test: does NOT link when trustedProviders is set but doesn't include siwe
  • Added test: does NOT link when accountLinking.enabled is false
  • Added test: returns success if wallet already linked to current user (idempotent)
  • Added test: verify ENS lookup functionality correctly sets user name / photo on account creation
  • Added test: rejects if wallet already linked to another user
  • Added test: Rejects linking if wallet exists on another chain for a different user (Same user can link same wallet on multiple chains)
  • Added test: creates new user when not authenticated (no session)
  • Added test: ensure walletAddress records are deleted when account is unlinked from user
  • All existing SIWE tests continue to pass (40 tests total)

Summary by cubic

Enables linking SIWE wallets to an authenticated user's existing account when account linking is enabled and SIWE is trusted. Keeps the original behavior for unauthenticated users and adds safeguards for idempotency and cross-chain conflicts.

  • New Features

    • Link wallet to the current session user when accountLinking.enabled is true and trustedProviders includes siwe (or is unset/empty).
    • Return success if the wallet is already linked to the current user (idempotent).
    • Throw WALLET_ALREADY_LINKED when the wallet belongs to another user, including if the same address exists on a different chain for another user.
    • Preserve existing flow: create a new user when no session.
    • Include the current session token in successful wallet linking responses.
    • Create an account record for each verified wallet (including linked wallets).
    • Cascade delete the corresponding walletAddress when a SIWE account is unlinked or the user is deleted.
  • Refactors

    • Extract shared walletAddress and chainId schemas.
    • Add session detection via getSessionFromCtx.
    • Streamline nonce handling; standardize SIWE error codes and wallet account ID construction.

Written for commit 3d3e701ad6. Summary will update on new commits.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/better-auth/better-auth/pull/6685 **Author:** [@META-DREAMER](https://github.com/META-DREAMER) **Created:** 12/11/2025 **Status:** ❌ Closed **Base:** `canary` ← **Head:** `feat/siwe-wallet-linking` --- ### 📝 Commits (10+) - [`30f741b`](https://github.com/better-auth/better-auth/commit/30f741beac850198639874e1bf894b8f800a5491) feat(siwe): allow linking SIWE wallets to existing accounts - [`d3f98c2`](https://github.com/better-auth/better-auth/commit/d3f98c2c5566e43dbff5eee701f1d63d1bf30588) fix(siwe): include session token in wallet linking responses - [`857b80d`](https://github.com/better-auth/better-auth/commit/857b80d6df50cbfbd537bc55b8b15ef567445d8d) chore(siwe): standardize error codes + refactor and improve tests - [`c975f09`](https://github.com/better-auth/better-auth/commit/c975f097a9a5f3fe705e7be8c59455001413fc21) fix(siwe): update error message for wallet linking and enhance validation - [`1fb3164`](https://github.com/better-auth/better-auth/commit/1fb3164578023731134b37727044630f76ef80b0) feat(siwe): implement cascading deletion of wallet addresses on account unlinking - [`6ced1e1`](https://github.com/better-auth/better-auth/commit/6ced1e16b661e5e56c97984a8847f8b969ce879d) docs(siwe): Add docs on wallet account linking - [`b8377d8`](https://github.com/better-auth/better-auth/commit/b8377d83693d97af36152567479789a44525fda1) chore(siwe): add SESSION_CREATION_FAILED error code and refactor error handling - [`7b20502`](https://github.com/better-auth/better-auth/commit/7b2050279f3c78905afa297eb5ca0d3e7e31f665) fix(siwe): enforce email requirement when anonymous option is disabled - [`5a4ffd6`](https://github.com/better-auth/better-auth/commit/5a4ffd6f7fc4e45984056f3bc19ebfa205db0a2d) chore(siwe): update tests to use proper error code for WALLET_ALREADY_LINKED - [`3d3e701`](https://github.com/better-auth/better-auth/commit/3d3e701ad63e9aa24846dc115f4b2edb41e17b1b) Merge branch 'canary' into feat/siwe-wallet-linking ### 📊 Changes **4 files changed** (+1705 additions, -829 deletions) <details> <summary>View changed files</summary> 📝 `docs/content/docs/plugins/siwe.mdx` (+38 -0) ➕ `packages/better-auth/src/plugins/siwe/error-codes.ts` (+8 -0) 📝 `packages/better-auth/src/plugins/siwe/index.ts` (+250 -174) 📝 `packages/better-auth/src/plugins/siwe/siwe.test.ts` (+1409 -655) </details> ### 📄 Description ## Summary Adds support for linking SIWE wallets to existing authenticated user accounts, with cross-chain wallet identity protection. ## Changes - **Account Linking Support:** Respects accountLinking.enabled and accountLinking.trustedProviders configuration. When authenticated and linking is enabled (with siwe in trusted providers), wallets are linked to the existing account instead of creating a new user. - Creates new users when not authenticated (original behaviour preserved) - Returns success if wallet is already linked to current user (idempotent) - Throws `WALLET_ALREADY_LINKED` error if wallet belongs to another user - Cascades deletion of walletAddress when account is unlinked - **Cross-Chain Identity Protection:** Prevents different users from linking the same wallet address on different chains. A wallet address represents the same key pair across all chains, so linking 0x123... on Ethereum should not be allowed if it's already linked to another user on Polygon. ## Test plan - [x] Added test: links wallet when `accountLinking.trustedProviders` includes `siwe` - [x] Added test: links wallet when `trustedProviders` is undefined (default behavior) - [x] Added test: does NOT link when `trustedProviders` is set but doesn't include `siwe` - [x] Added test: does NOT link when `accountLinking.enabled` is `false` - [x] Added test: returns success if wallet already linked to current user (idempotent) - [x] Added test: verify ENS lookup functionality correctly sets user name / photo on account creation - [x] Added test: rejects if wallet already linked to another user - [x] Added test: Rejects linking if wallet exists on another chain for a different user (Same user can link same wallet on multiple chains) - [x] Added test: creates new user when not authenticated (no session) - [x] Added test: ensure walletAddress records are deleted when account is unlinked from user - [x] All existing SIWE tests continue to pass (40 tests total) <!-- This is an auto-generated description by cubic. --> --- ## Summary by cubic Enables linking SIWE wallets to an authenticated user's existing account when account linking is enabled and SIWE is trusted. Keeps the original behavior for unauthenticated users and adds safeguards for idempotency and cross-chain conflicts. - **New Features** - Link wallet to the current session user when accountLinking.enabled is true and trustedProviders includes siwe (or is unset/empty). - Return success if the wallet is already linked to the current user (idempotent). - Throw WALLET_ALREADY_LINKED when the wallet belongs to another user, including if the same address exists on a different chain for another user. - Preserve existing flow: create a new user when no session. - Include the current session token in successful wallet linking responses. - Create an account record for each verified wallet (including linked wallets). - Cascade delete the corresponding walletAddress when a SIWE account is unlinked or the user is deleted. - **Refactors** - Extract shared walletAddress and chainId schemas. - Add session detection via getSessionFromCtx. - Streamline nonce handling; standardize SIWE error codes and wallet account ID construction. <sup>Written for commit 3d3e701ad63e9aa24846dc115f4b2edb41e17b1b. Summary will update on new commits.</sup> <!-- End of auto-generated description by cubic. --> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-03-13 13:12:59 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/better-auth#6824