Skip to content

Commit a11e256

Browse files
committed
Add thirdweb login
1 parent a47d0ed commit a11e256

File tree

8 files changed

+2221
-29
lines changed

8 files changed

+2221
-29
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
"reflect-metadata": "^0.1.13",
4949
"rxjs": "^7.8.1",
5050
"siwe": "^2.3.2",
51+
"thirdweb": "^5.64.2",
5152
"viem": "^2.21.5"
5253
},
5354
"devDependencies": {
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
Warnings:
3+
4+
- A unique constraint covering the columns `[attestation_id]` on the table `UserAttestation` will be added. If there are existing duplicate values, this will fail.
5+
- Added the required column `attestation_id` to the `UserAttestation` table without a default value. This is not possible if the table is not empty.
6+
7+
*/
8+
-- AlterTable
9+
ALTER TABLE "UserAttestation" ADD COLUMN "attestation_id" TEXT NOT NULL;
10+
11+
-- CreateIndex
12+
CREATE UNIQUE INDEX "UserAttestation_attestation_id_key" ON "UserAttestation"("attestation_id");

prisma/schema.prisma

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -201,12 +201,13 @@ model UserCollectionFinish {
201201
}
202202

203203
model UserAttestation {
204-
userId Int @map("user_id")
205-
collectionId Int @map("collection_id")
206-
createdAt DateTime @default(now()) @map("created_at")
207-
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
208-
user User @relation(fields: [userId], references: [id])
209-
collection Project @relation(fields: [collectionId], references: [id])
204+
userId Int @map("user_id")
205+
collectionId Int @map("collection_id")
206+
attestationId String @unique() @map("attestation_id")
207+
createdAt DateTime @default(now()) @map("created_at")
208+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
209+
user User @relation(fields: [userId], references: [id])
210+
collection Project @relation(fields: [collectionId], references: [id])
210211
211212
@@id([userId, collectionId])
212213
}

src/auth/auth.controller.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import { PrismaService } from 'src/prisma.service';
1616
import { Response } from 'express';
1717
import { UsersService } from 'src/user/users.service';
1818
import { AuthGuard } from './auth.guard';
19-
import { LoginDTO } from './dto/login.dto';
19+
import { LoginDTO, ThirdwebLoginDTO } from './dto/login.dto';
2020
import { ApiResponse } from '@nestjs/swagger';
2121
import { AuthedReq } from 'src/utils/types/AuthedReq.type';
2222
import { STAGING_API, generateRandomString } from 'src/utils';
@@ -125,6 +125,32 @@ export class AuthController {
125125
res.status(200).send({ token, isNewUser });
126126
}
127127

128+
@UseGuards(AuthGuard)
129+
@ApiResponse({ status: 200, description: 'Sets an auth cookie' })
130+
@Post('/thirdweb/login')
131+
async loginWithThirdweb(
132+
@Req() { userId }: AuthedReq,
133+
@Body() { message, signature, address }: ThirdwebLoginDTO,
134+
) {
135+
const isAuthentic = await this.authService.verifyThirdwebUser(
136+
message,
137+
signature,
138+
address,
139+
);
140+
if (!isAuthentic) throw new UnauthorizedException('Invalid signature');
141+
142+
await this.prismaService.user.update({
143+
where: {
144+
id: userId,
145+
},
146+
data: {
147+
smartaddress: address,
148+
},
149+
});
150+
151+
return 'Success';
152+
}
153+
128154
// @ApiResponse({
129155
// status: 200,
130156
// type: String,

src/auth/auth.service.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { generateRandomString } from 'src/utils';
33
import { PrismaService } from 'src/prisma.service';
44
import { SiweMessage } from 'siwe';
55
import { verifyMessage } from 'viem';
6+
import { chain, thirdwebClient } from './thirdweb';
7+
import { verifySignature } from 'thirdweb/auth';
68
// import { chain, thirdwebClient } from 'src/thirdweb';
79

810
@Injectable()
@@ -140,6 +142,22 @@ export class AuthService {
140142
return user;
141143
};
142144

145+
verifyThirdwebUser = async (
146+
message: string,
147+
signature: string,
148+
address: string,
149+
) => {
150+
const isValid = await verifySignature({
151+
message,
152+
signature,
153+
address,
154+
client: thirdwebClient,
155+
chain,
156+
});
157+
158+
return isValid;
159+
};
160+
143161
verifyUser = async (
144162
message: string,
145163
signature: `0x${string}`,

src/auth/dto/login.dto.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { ApiProperty } from '@nestjs/swagger';
2-
import { SiweMessage } from 'siwe';
32

43
export class SiweMessageClass {
54
@ApiProperty({
@@ -86,3 +85,13 @@ export class LoginDTO {
8685
@ApiProperty()
8786
address: string;
8887
}
88+
export class ThirdwebLoginDTO {
89+
@ApiProperty()
90+
message: string;
91+
92+
@ApiProperty()
93+
signature: string;
94+
95+
@ApiProperty()
96+
address: string;
97+
}

src/auth/thirdweb.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { createThirdwebClient } from 'thirdweb';
2+
import { optimism, optimismSepolia } from 'thirdweb/chains';
3+
4+
const secretKey = process.env.SECRET_KEY;
5+
6+
if (!secretKey) throw new Error('No Third Web Secret Key');
7+
8+
export const chain =
9+
process.env.ACTIVE_CHAIN === 'optimism' ? optimism : optimismSepolia;
10+
11+
export const thirdwebClient = createThirdwebClient({
12+
secretKey,
13+
});

0 commit comments

Comments
 (0)