Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
edfb8fe
Move aws wallets to @thirdweb-dev/wallets
adam-maj Dec 11, 2022
f0b93c1
Restructure exports for auth
adam-maj Dec 12, 2022
33ebb7f
Completely remove auth from sdk
adam-maj Dec 13, 2022
e1ba1c4
Add changeset
adam-maj Dec 13, 2022
8c7c81b
Propagate context into token
adam-maj Dec 13, 2022
dc4f6e5
Pass options into verify
adam-maj Dec 13, 2022
f45f470
Merge branch 'main' into am/auth
adam-maj Dec 13, 2022
76c71f2
Update auth exports
adam-maj Dec 13, 2022
ef69398
Add private key wallet
adam-maj Dec 13, 2022
5985969
Use new auth core in next-auth
adam-maj Dec 13, 2022
25448e5
Remove sdk.auth from plugins
adam-maj Dec 13, 2022
0f759f6
Update Next.js framework support
adam-maj Dec 14, 2022
276313f
Update express package
adam-maj Dec 14, 2022
92106b1
Update to get token from bearer or cookies
adam-maj Dec 15, 2022
13a875a
change names of user context and data callbacks
adam-maj Dec 16, 2022
ebf0e93
Update react
adam-maj Dec 16, 2022
ff4a118
Update auth support in react
adam-maj Dec 16, 2022
daae8ca
Add changeset
adam-maj Dec 16, 2022
960f484
Update auth package
adam-maj Dec 17, 2022
53825fe
Merge branch 'main' into am/auth
adam-maj Dec 17, 2022
d4171a2
Update errors
adam-maj Dec 17, 2022
12e633e
Add wallets to Solana
adam-maj Dec 18, 2022
bb229c3
Update auth core
adam-maj Dec 18, 2022
7285538
Remove auth from Solana
adam-maj Dec 18, 2022
90c1f1f
Update wallets and auth
adam-maj Dec 18, 2022
d9f1c52
Update auth
adam-maj Dec 24, 2022
2fc1913
Merge branch 'main' into am/auth
adam-maj Jan 9, 2023
ff76523
Update user types
adam-maj Jan 9, 2023
8d05280
Fix build
adam-maj Jan 10, 2023
b30955e
Update test
adam-maj Jan 10, 2023
92e694c
Merge branch 'main' into am/auth
adam-maj Jan 10, 2023
c848304
Passing auth test cases
adam-maj Jan 10, 2023
a725176
Update magic wagmi import
adam-maj Jan 12, 2023
48761cc
Change callback functions for enhancing token and user
adam-maj Jan 17, 2023
dad2c2a
Update wallet requirement
adam-maj Jan 17, 2023
6d7c593
Update wallet requirement
adam-maj Jan 17, 2023
5023698
Fix @wagmi/chains import bug
adam-maj Jan 18, 2023
7415f25
Add fromSigner and fromPrivateKey to auth
adam-maj Jan 18, 2023
88c7ffe
Merge branch 'main' into am/auth
adam-maj Jan 18, 2023
f2f41f2
Add wallets as a peerDependency
adam-maj Jan 18, 2023
f7adaf5
Add /evm and /solana entrypoints with optional peer dependencies
adam-maj Jan 19, 2023
1356657
Update dependencies
adam-maj Jan 19, 2023
0f81ae3
Update
adam-maj Jan 19, 2023
944c2d0
Merge branch 'main' into am/auth
adam-maj Jan 19, 2023
fcebc8f
Remove experimental loader
adam-maj Jan 19, 2023
bf59ddf
Update changeset
adam-maj Jan 19, 2023
380ed10
Update unity bridge
adam-maj Jan 19, 2023
f4fc2c9
Update user endpoint in next
adam-maj Jan 19, 2023
a15a6b6
Update turbo.json
adam-maj Jan 19, 2023
cef258d
Remove auth
adam-maj Jan 19, 2023
544cd16
Update react hook inputs and return types
adam-maj Jan 19, 2023
3fd19ab
Remove @thirdweb-dev/wallets from @thirdweb-dev/react peerDependencies
adam-maj Jan 20, 2023
8a64c8c
Expose auth middleware from express auth
adam-maj Jan 20, 2023
0dea730
Change logout to POST
adam-maj Jan 20, 2023
656b6c9
Don't log secret on error in aws-secrets-manager wallet
adam-maj Jan 20, 2023
5eca31c
Update core auth with full EIP4361 spec and add solana testing
adam-maj Jan 20, 2023
66b9e2b
Update configuration on auth frameworks
adam-maj Jan 20, 2023
54e4713
Update express auth
adam-maj Jan 21, 2023
84834d9
Merge branch 'main' into am/auth
adam-maj Jan 21, 2023
00b4048
Add ethers as optional dependency of auth
adam-maj Jan 22, 2023
81b5deb
Add support for EIP1271
adam-maj Jan 23, 2023
6fa83b4
Use verifySignature
adam-maj Jan 23, 2023
2a846c2
Merge branch 'main' into am/auth
adam-maj Jan 24, 2023
00e8d4a
Add support for solana wallet adapter
adam-maj Jan 24, 2023
3b17f13
Make aws config optional
adam-maj Jan 24, 2023
9144c7c
Fix wallets dependencies
adam-maj Jan 24, 2023
f72eb38
Remove body-parser dependency
adam-maj Jan 24, 2023
0b2d9e1
Fix magic package versions
adam-maj Jan 24, 2023
c12fbf0
Fix sdk.fromWallet
adam-maj Jan 24, 2023
ec136e4
Add signMessage to gnosis safe connector
adam-maj Jan 24, 2023
432a835
Update wallet naming and verify signature
adam-maj Jan 25, 2023
c59ac74
Auth working with Gnosis Safe
adam-maj Jan 25, 2023
fd98544
Update wallet implementations
adam-maj Jan 25, 2023
e271b76
Standardize signature verification
adam-maj Jan 25, 2023
26e16f1
Update auth on express and next
adam-maj Jan 27, 2023
97ad1f6
Merge branch 'main' into am/auth
adam-maj Jan 27, 2023
60be790
Update auth test cases
adam-maj Jan 27, 2023
d26f500
Merge branch 'main' into am/auth
adam-maj Jan 27, 2023
b0a7631
Update gnosis in wallets
adam-maj Jan 27, 2023
30f8903
Merge branch 'am/auth' of https://github.com/thirdweb-dev/js into am/…
adam-maj Jan 27, 2023
48641bc
Add changesets
adam-maj Jan 27, 2023
9b8dd09
Merge branch 'main' into am/auth
jnsdls Jan 27, 2023
dab343b
Update changesets
adam-maj Jan 27, 2023
20a467d
Merge branch 'am/auth' of https://github.com/thirdweb-dev/js into am/…
adam-maj Jan 27, 2023
016d433
Update wallets
adam-maj Jan 27, 2023
729e813
Update wallets
adam-maj Jan 27, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Completely remove auth from sdk
  • Loading branch information
adam-maj committed Dec 13, 2022
commit 33ebb7f2b65d6ef6a1a3110095a700433faf1cb1
12 changes: 10 additions & 2 deletions packages/auth/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@
"format": "prettier --write 'src/**/*'",
"lint": "eslint src/",
"fix": "eslint src/ --fix",
"clean": "rm -rf dist/ && rm -rf node_modules/"
"clean": "rm -rf dist/ && rm -rf node_modules/",
"test": "mocha --config './test/evm/.mocharc.json' --timeout 30000 --parallel './test/evm/**/*.test.ts'"
},
"preconstruct": {
"entrypoints": [
Expand All @@ -62,12 +63,16 @@
"@microsoft/api-extractor": "^7.29.2",
"@microsoft/tsdoc": "^0.14.1",
"@preconstruct/cli": "^2.2.1",
"@swc-node/register": "^1.5.4",
"@thirdweb-dev/sdk": "*",
"@types/chai": "^4.3.4",
"@types/cookie": "^0.5.1",
"@types/cookie-parser": "^1.4.3",
"@types/express": "^4.17.13",
"@types/mocha": "^10.0.1",
"@typescript-eslint/eslint-plugin": "^5.33.0",
"@typescript-eslint/parser": "^5.33.0",
"chai": "^4.3.7",
"eslint": "^8.21.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.26.0",
Expand All @@ -76,6 +81,7 @@
"eslint-plugin-tsdoc": "^0.2.16",
"ethers": "^5.7.2",
"express": "^4.18.1",
"mocha": "^10.2.0",
"next": "^12.2.0",
"next-auth": "^4.10.3",
"prettier": "^2.7.1",
Expand Down Expand Up @@ -103,6 +109,8 @@
},
"dependencies": {
"cookie": "^0.5.0",
"cookie-parser": "^1.4.6"
"cookie-parser": "^1.4.6",
"uuid": "^9.0.0",
"zod": "^3.20.2"
}
}
106 changes: 13 additions & 93 deletions packages/auth/src/evm/core/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,64 +15,21 @@ import { WalletSigner } from "./signer";
import { isBrowser } from "./utils";
import { MinimalWallet } from "@thirdweb-dev/wallets";

/**
* Wallet Authenticator
* @remarks The wallet authenticator enables server-side applications to securely identify the
* connected wallet address of users on the client-side, and also enables users to authenticate
* to any backend using just their wallet. It implements the JSON Web Token (JWT) authentication
* standard.
*
* @example
* ```javascript
* // We specify the domain of the application to authenticate to
* const domain = "example.com"
*
* // On the client side, we can generate a payload for the connected wallet to login
* const loginPayload = await sdk.auth.login(domain);
*
* // Then on the server side, we can securely verify the connected client-side address
* const address = sdk.auth.verify(domain, loginPayload);
*
* // And we can also generate an authentication token to send to the client
* const token = sdk.auth.generate(domain, loginPayload);
*
* // Finally, the token can be send from the client to the server to make authenticated requests
* // And the server can use the following function to authenticate a token and verify the associated address
* const address = sdk.auth.authenticate(domain, token);
* ```
* @public
*/
export class ThirdwebAuth {
private wallet: WalletSigner;

constructor(wallet: MinimalWallet) {
this.wallet = new WalletSigner(wallet);
export class ThirdwebAuth extends WalletSigner {
private domain: string;

constructor(wallet: MinimalWallet, domain: string) {
super(wallet);
this.domain = domain;
}

/**
* Login With Connected Wallet
* @remarks Client-side function that allows the connected wallet to login to a server-side application.
* Generates a login payload that can be sent to the server-side for verification or authentication.
*
* @param domain - The domain of the server-side application to login to
* @param options - Optional configuration options for the login request
* @returns Login payload that can be used on the server-side to verify the login request or authenticate
*
* @example
* ```javascript
* // Add the domain of the application users will login to, this will be used throughout the login process
* const domain = "example.com";
* // Generate a signed login payload for the connected wallet to authenticate with
* const loginPayload = await sdk.auth.login(domain);
* ```
*/
public async login(
domain: string,
options?: LoginOptions,
): Promise<LoginPayload> {
const parsedOptions = LoginOptionsSchema.parse(options);

const signerAddress = await this.wallet.getAddress();
const signerAddress = await this.getAddress();
const expirationTime =
parsedOptions?.expirationTime || new Date(Date.now() + 1000 * 60 * 5);
const payloadData = LoginPayloadDataSchema.parse({
Expand All @@ -84,32 +41,14 @@ export class ThirdwebAuth {
});

const message = this.generateMessage(payloadData);
const signature = await this.wallet.sign(message);
const signature = await this.sign(message);

return {
payload: payloadData,
signature,
};
}

/**
* Verify Logged In Address
* @remarks Server-side function to securely verify the address of the logged in client-side wallet
* by validating the provided client-side login request.
*
* @param domain - The domain of the server-side application to verify the login request for
* @param payload - The login payload to verify
* @returns Address of the logged in wallet
*
* @example
* ```javascript
* const domain = "example.com";
* const loginPayload = await sdk.auth.login(domain);
*
* // Verify the login request
* const address = sdk.auth.verify(domain, loginPayload);
* ```
*/
public verify(
domain: string,
payload: LoginPayload,
Expand Down Expand Up @@ -142,7 +81,7 @@ export class ThirdwebAuth {

// Check that the signing address is the claimed wallet address
const message = this.generateMessage(payload.payload);
const userAddress = this.wallet.recoverAddress(message, payload.signature);
const userAddress = this.recoverAddress(message, payload.signature);
if (userAddress.toLowerCase() !== payload.payload.address.toLowerCase()) {
throw new Error(
`Signer address '${userAddress.toLowerCase()}' does not match payload address '${payload.payload.address.toLowerCase()}'`,
Expand All @@ -152,25 +91,6 @@ export class ThirdwebAuth {
return userAddress;
}

/**
* Generate Authentication Token
* @remarks Server-side function that generates a JWT token from the provided login request that the
* client-side wallet can use to authenticate to the server-side application.
*
* @param domain - The domain of the server-side application to authenticate to
* @param payload - The login payload to authenticate with
* @param options - Optional configuration options for the authentication request
* @returns A authentication token that can be used by the client to make authenticated requests
*
* @example
* ```javascript
* const domain = "example.com";
* const loginPayload = await sdk.auth.login(domain);
*
* // Generate a JWT token that can be sent to the client-side wallet and used for authentication
* const token = await sdk.auth.generateAuthToken(domain, loginPayload);
* ```
*/
public async generateAuthToken(
domain: string,
payload: LoginPayload,
Expand All @@ -185,7 +105,7 @@ export class ThirdwebAuth {
const parsedOptions = AuthenticationOptionsSchema.parse(options);

const userAddress = this.verify(domain, payload);
const adminAddress = await this.wallet.getAddress();
const adminAddress = await this.getAddress();
const payloadData = AuthenticationPayloadDataSchema.parse({
iss: adminAddress,
sub: userAddress,
Expand All @@ -198,7 +118,7 @@ export class ThirdwebAuth {
});

const message = JSON.stringify(payloadData);
const signature = await this.wallet.sign(message);
const signature = await this.sign(message);

// Header used for JWT token specifying hash algorithm
const header = {
Expand Down Expand Up @@ -277,15 +197,15 @@ export class ThirdwebAuth {
}

// Check that the connected wallet matches the token issuer
const connectedAddress = await this.wallet.getAddress();
const connectedAddress = await this.getAddress();
if (connectedAddress.toLowerCase() !== payload.iss.toLowerCase()) {
throw new Error(
`Expected the connected wallet address '${connectedAddress}' to match the token issuer address '${payload.iss}'`,
);
}

// Check that the connected wallet signed the token
const adminAddress = this.wallet.recoverAddress(
const adminAddress = this.recoverAddress(
JSON.stringify(payload),
signature,
);
Expand Down
2 changes: 1 addition & 1 deletion packages/auth/src/evm/core/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { WalletAuthenticator } from "./auth";
export { ThirdwebAuth } from "./auth";
17 changes: 14 additions & 3 deletions packages/auth/src/evm/core/signer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,25 @@ export class WalletSigner {
return ethers.utils.recoverAddress(messageHashBytes, signature);
}

public updateWallet(wallet: MinimalWallet): void {
this.wallet = wallet;
this.signer = undefined;
}

// Signer should only be accessed with this function
async getSigner(): Promise<ethers.Signer> {
private async getSigner(): Promise<ethers.Signer> {
// First check for the cached signer
if (this.signer) {
if (!!this.signer) {
return this.signer;
}

// Otherwise newly instantiate it and return
return (this.signer = await this.wallet.getSigner());
this.signer = await this.wallet.getSigner();

if (!this.signer) {
throw new Error("Unable to get a signer!");
}

return this.signer;
}
}
8 changes: 8 additions & 0 deletions packages/auth/test/evm/.mocharc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"extension": [
"ts"
],
"require": [
"@swc-node/register"
]
}
Loading