Skip to content

Commit 2ec3633

Browse files
authored
Merge pull request #56 from GeneralMagicio/rf6-staging
Rf6 staging
2 parents 950c9bb + 309e770 commit 2ec3633

File tree

20 files changed

+277744
-169376
lines changed

20 files changed

+277744
-169376
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
/src/ai-summary
88
/src/rf6-data-import
99
src/rf6-data-import
10+
src/ai-summary-rf5
1011

1112
# Envs
1213

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,14 @@
4444
"mathjs": "^11.9.1",
4545
"ml-matrix": "^6.10.5",
4646
"node-cron": "^3.0.3",
47+
"openai": "^4.68.4",
4748
"prisma": "^5.0.0",
4849
"reflect-metadata": "^0.1.13",
4950
"rxjs": "^7.8.1",
5051
"siwe": "^2.3.2",
51-
"viem": "^2.21.5"
52+
"thirdweb": "^5.64.2",
53+
"viem": "^2.21.5",
54+
"zod": "^3.23.8"
5255
},
5356
"devDependencies": {
5457
"@nestjs/cli": "^10.0.0",
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");
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
-- CreateTable
2+
CREATE TABLE "UserBudgetAttestation" (
3+
"user_id" INTEGER NOT NULL,
4+
"attestation_id" TEXT NOT NULL,
5+
"created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
6+
"updated_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
7+
8+
CONSTRAINT "UserBudgetAttestation_pkey" PRIMARY KEY ("user_id")
9+
);
10+
11+
-- CreateIndex
12+
CREATE UNIQUE INDEX "UserBudgetAttestation_attestation_id_key" ON "UserBudgetAttestation"("attestation_id");
13+
14+
-- AddForeignKey
15+
ALTER TABLE "UserBudgetAttestation" ADD CONSTRAINT "UserBudgetAttestation_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;

prisma/schema.prisma

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ generator client {
99
}
1010

1111
model User {
12-
id Int @id @default(autoincrement())
13-
budget Int @default(2000000) // 2M In OP
14-
address String @unique()
15-
smartaddress String? @unique()
16-
ballotSuccess Int? @map("ballot_success")
17-
opAddress String? @unique() @map("op_address")
18-
createdAt DateTime @default(now()) @map("created_at")
19-
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
12+
id Int @id @default(autoincrement())
13+
budget Int @default(2000000) // 2M In OP
14+
address String @unique()
15+
smartaddress String? @unique()
16+
ballotSuccess Int? @map("ballot_success")
17+
opAddress String? @unique() @map("op_address")
18+
createdAt DateTime @default(now()) @map("created_at")
19+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
2020
identity Json? // Ideally should be unique except {} and null values but Prisma doesn't support partial
2121
// unique constraints
2222
badges Json?
@@ -29,6 +29,7 @@ model User {
2929
finishedCollection UserCollectionFinish[]
3030
shares Share[]
3131
attestations UserAttestation[]
32+
budgetAttestations UserBudgetAttestation[]
3233
projectStars ProjectStar[]
3334
cois ProjectCoI[]
3435
}
@@ -201,16 +202,27 @@ model UserCollectionFinish {
201202
}
202203

203204
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])
205+
userId Int @map("user_id")
206+
collectionId Int @map("collection_id")
207+
attestationId String @unique() @map("attestation_id")
208+
createdAt DateTime @default(now()) @map("created_at")
209+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
210+
user User @relation(fields: [userId], references: [id])
211+
collection Project @relation(fields: [collectionId], references: [id])
210212
211213
@@id([userId, collectionId])
212214
}
213215

216+
model UserBudgetAttestation {
217+
userId Int @map("user_id")
218+
attestationId String @unique() @map("attestation_id")
219+
createdAt DateTime @default(now()) @map("created_at")
220+
updatedAt DateTime @default(now()) @updatedAt @map("updated_at")
221+
user User @relation(fields: [userId], references: [id])
222+
223+
@@id([userId])
224+
}
225+
214226
enum DelegationPlatform {
215227
FARCASTER
216228
TWITTER

src/auth/auth.controller.ts

Lines changed: 41 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,46 @@ export class AuthController {
125125
res.status(200).send({ token, isNewUser });
126126
}
127127

128+
@UseGuards(AuthGuard)
129+
@ApiResponse({ status: 200, description: 'Gets the sa address of a user' })
130+
@Get('/thirdweb/sa-address')
131+
async getSaAddress(@Req() { userId }: AuthedReq) {
132+
const res = await this.prismaService.user.findUnique({
133+
select: { smartaddress: true },
134+
where: {
135+
id: userId,
136+
},
137+
});
138+
139+
return res?.smartaddress || null;
140+
}
141+
142+
@UseGuards(AuthGuard)
143+
@ApiResponse({ status: 200, description: 'Sets an auth cookie' })
144+
@Post('/thirdweb/login')
145+
async loginWithThirdweb(
146+
@Req() { userId }: AuthedReq,
147+
@Body() { message, signature, address }: ThirdwebLoginDTO,
148+
) {
149+
const isAuthentic = await this.authService.verifyThirdwebUser(
150+
message,
151+
signature,
152+
address,
153+
);
154+
if (!isAuthentic) throw new UnauthorizedException('Invalid signature');
155+
156+
await this.prismaService.user.update({
157+
where: {
158+
id: userId,
159+
},
160+
data: {
161+
smartaddress: address,
162+
},
163+
});
164+
165+
return 'Success';
166+
}
167+
128168
// @ApiResponse({
129169
// status: 200,
130170
// 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+
});

src/cronJobs.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { schedule } from 'node-cron';
2-
import { sendCastsFor12Hours } from './neynar/utils';
2+
import { sendDailyCasts } from './neynar/utils';
33

4-
const sendCastsCronJobTime = '21 21 0,12 * * *'; // at 00:21 and 12:21 every day
4+
const sendCastsCronJobTime = '21 1 17 * * *'; // at 17:01 every day
55

66
export const initializeCronJobs = () => {
77
sendCastsCronJob();
@@ -10,7 +10,7 @@ export const initializeCronJobs = () => {
1010
const sendCastsCronJob = () => {
1111
schedule(sendCastsCronJobTime, async () => {
1212
try {
13-
await sendCastsFor12Hours();
13+
await sendDailyCasts();
1414
} catch (e) {
1515
console.error('sendCastsCronJob error', e);
1616
}

0 commit comments

Comments
 (0)