Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add sign in with solana (EIP-4361) support #1918

Merged
merged 1 commit into from
Apr 1, 2025

Conversation

Bewinxed
Copy link
Contributor

@Bewinxed Bewinxed commented Jan 18, 2025

Adds sign in with Solana (SIWS).

Configuration

  • GOTRUE_EXTERNAL_WEB3_SOLANA_ENABLED whether the Solana web3 provider is enabled or not
  • GOTRUE_EXTERNAL_WEB3_SOLANA_MAXIMUM_VALIDITY_DURATION (default 10 minutes) how long after issue time the SIWS message is regarded as valid

API

https://ref.supabase.co/auth/v1/token?grant_type=web3

{
  "chain": "solana",
  "message": "supabase.com wants to ...",
  "signature": "base64"
}

@Bewinxed Bewinxed requested a review from a team as a code owner January 18, 2025 14:31
Copy link
Contributor

@hf hf left a comment

Choose a reason for hiding this comment

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

This is really good! Great direction!

A few general notes:

  • We need to think a bit about how the config is encoded. I get that EIP<numbers> makes a lot of sense for people deep in this matter, but it's not very descriptive for regular programmers that are self-hosting Supabase Auth. I'd say let's just do GOTRUE_EXTERNAL_WEB3_<chain> or something. If there's a new EIP later on, we'll think about its config options then.
  • Similarly POST /token?grant_type=<this should be readable by regular programmers>. siws, web3, siwe, things of this sort are better than eip<numbers>. This value will also be mapped into auth-js as well.
  • POST /token?grant_type=<web3 type> should only take in JSON, not URL forms. All APIs currently only use JSON, so this is a weird exception. Is there a particular reason we can't use JSON here?
  • utilities/siws is a weird name for a package that does eip<numbers>. Maybe just move this under /internal/web3 and it will house this and any future additions.

What is the best way to test this? Any simple test app you can host somewhere?

@Bewinxed
Copy link
Contributor Author

This is really good! Great direction!

A few general notes:

  • We need to think a bit about how the config is encoded. I get that EIP<numbers> makes a lot of sense for people deep in this matter, but it's not very descriptive for regular programmers that are self-hosting Supabase Auth. I'd say let's just do GOTRUE_EXTERNAL_WEB3_<chain> or something. If there's a new EIP later on, we'll think about its config options then.

This makes sense, originally i thought of this heirarchy:

Web3 > EIP4361 > Sign in with solana /sign in with ethereum, as there's maybe other web3 modes of auth that aren't eip4361 compliant, eth/sol go under eip4361, but what you said makes sense, I think web3 is friendly here.

  • Similarly POST /token?grant_type=<this should be readable by regular programmers>. siws, web3, siwe, things of this sort are better than eip<numbers>. This value will also be mapped into auth-js as well.
    Agreed
  • POST /token?grant_type=<web3 type> should only take in JSON, not URL forms. All APIs currently only use JSON, so this is a weird exception. Is there a particular reason we can't use JSON here?

I'm using JSON, is there something i missed?

func (a *API) EIP4361Grant(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
	db := a.db.WithContext(ctx)

	params := &Web3GrantParams{}
	if err := retrieveRequestParams(r, params); err != nil {
		return err
	}
...
  • utilities/siws is a weird name for a package that does eip<numbers>. Maybe just move this under /internal/web3 and it will house this and any future additions.
    This package is verifying Solana mainly for now, Perhaps we can do utlities/web3/[siws/siwe] ? They are both eip4361 compliant but each have different address formats, and divulge slightly in implementation.

What is the best way to test this? Any simple test app you can host somewhere?

I'll look into it and get back to you.

@hf
Copy link
Contributor

hf commented Jan 18, 2025

I'm using JSON, is there something i missed?

I saw this which caught my eye. https://github.com/supabase/auth/pull/1918/files#diff-db4fba83e08f520d74d66c9283e5dcd938e1746de1c4e7c481cce8aff142b5a1R71-R73

This package is verifying Solana mainly for now, Perhaps we can do utlities/web3/[siws/siwe] ? They are both eip4361 compliant but each have different address formats, and divulge slightly in implementation.

No need to go into utilities IMO. Just have it be toplevel under /internal.

@Bewinxed
Copy link
Contributor Author

Bewinxed commented Jan 23, 2025

Hey guys, I pushed an update a few days ago with some things I missed:

  • Added a db table for nonces, these are required to prevent Replay Attacks.
  • Added robust verifications for each part of the SIWS message.
  • I've covered the SIWS handler in the crypto package with multiple test cases.
  • I initiated the error types in the helpers to avoid initiating them inline, to prevent overhead.

Copy link
Contributor

@staaldraad staaldraad left a comment

Choose a reason for hiding this comment

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

hey @Bewinxed 👋🏼 nice work! I gave this a first pass and left some comments. The replay detection looks correct, but it would be good to have a test that ensures it stays correct.

@Bewinxed
Copy link
Contributor Author

Bewinxed commented Feb 9, 2025

hey @Bewinxed 👋🏼 nice work! I gave this a first pass and left some comments. The replay detection looks correct, but it would be good to have a test that ensures it stays correct.

Thanks for your reviews, I’ve replied to the comments and adjusted the code accordingly.

Thanks!

@Bewinxed
Copy link
Contributor Author

Hello! Just resolved all issues, please review one more time.

as per our discussion I’ve removed serverside nonce processing, in favor of a nonce that applies to all oidc providers, which will be implemented later.

@hf
Copy link
Contributor

hf commented Feb 25, 2025

Before merge remember to change title into conventional commits format.

Copy link
Contributor

@hf hf left a comment

Choose a reason for hiding this comment

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

OK we're getting very close!

Would you mind updating the openapi.yaml file with the changes to the API as well!

Also what happened with the nonce verification per the agreement to check it via the identities table? I don't think I'm able to see it in the code.

@Bewinxed
Copy link
Contributor Author

Bewinxed commented Mar 7, 2025

OK we're getting very close!

Would you mind updating the openapi.yaml file with the changes to the API as well!

Also what happened with the nonce verification per the agreement to check it via the identities table? I don't think I'm able to see it in the code.

Resolved all issues, wrt nonce verification, the team has mentioned that they're going to implement nonce verification for oidc based providers and web3 later on, so simple verification is in place for now, the team is going to implement this.

Copy link
Contributor

@hf hf left a comment

Choose a reason for hiding this comment

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

Seems good enough to go in from my POV. Still need to test E2E though and potential adjustments might come in future PRs.

Would you mind making sure the comments about validation and OpenAPI are addressed before merging?

@hf hf changed the title Implement EIP-4361 support with SIWS message handling and verification feat: add sign in with solana (EIP-4361) support Mar 11, 2025
@Bewinxed
Copy link
Contributor Author

Seems good enough to go in from my POV. Still need to test E2E though and potential adjustments might come in future PRs.

Would you mind making sure the comments about validation and OpenAPI are addressed before merging?

OpenAPI should be in already, I resolved the validation stuff as well.

@hf hf requested a review from staaldraad March 12, 2025 11:39
@burggraf
Copy link
Member

Can we get an update on this? Anything we can do to help move this one?

@hf hf force-pushed the master branch 3 times, most recently from 935e408 to 82a56d8 Compare April 1, 2025 09:58
@coveralls
Copy link

coveralls commented Apr 1, 2025

Pull Request Test Coverage Report for Build 14193551617

Details

  • 259 of 278 (93.17%) changed or added relevant lines in 9 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage increased (+0.5%) to 68.057%

Changes Missing Coverage Covered Lines Changed/Added Lines %
internal/crypto/crypto.go 9 11 81.82%
internal/models/factor.go 2 4 50.0%
internal/api/web3.go 106 121 87.6%
Totals Coverage Status
Change from base Build 14133011190: 0.5%
Covered Lines: 10489
Relevant Lines: 15412

💛 - Coveralls

@hf hf merged commit d121546 into supabase:master Apr 1, 2025
3 checks passed
hf added a commit to supabase/auth-js that referenced this pull request Apr 4, 2025
Adds `signInWithWeb3` which allows [sign in with
Solana](supabase/auth#1918).

**Example usage**

First [connect to the user's
wallet](https://solana.com/developers/courses/intro-to-solana/interact-with-wallets)
then:

```tsx
const wallet = useWallet()

<Button onClick={() => {
  await supabase.auth.signInWithWeb3({ chain: 'solana', wallet, statement: "Custom message" })
}}>
  Sign in with Solana
</Button>
```

It also works without Wallet Standard, at least with Phantom, Solflare
and Brave by reading the `window.solana` object or you can custom send a
wallet object that satisfies the `signIn()` or `signMessage()` APIs.

Additionally you can sign the message yourself and send it via the raw
API:

```typescript
await supabase.auth.signInWithWeb3({
  chain: 'solana',
  message: 'supabase.com wants you to sign in with your Solana account:\n...',
  signature: signatureUint8Array,
})
```
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.

6 participants