Skip to content

Commit 9050577

Browse files
authored
Add chain ID to dApp (#277)
* feat: add chainid column * feat: create db migrations * chore: refactor `fromString` to `from` for better object interface * fix: fake the right event name * fix: this is not a constructor * feat: define chain * feat: add chain id to dapp as a number * feat: enable chain selection * fix: broken tests * fix: broken tests * fix: chain id type * chore: fix submodule version
1 parent 49e34c2 commit 9050577

140 files changed

Lines changed: 1652 additions & 568 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- Remove chainId
2+
ALTER TABLE "Dapp" DROP COLUMN IF EXISTS "chainId";
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "Dapp" ADD COLUMN IF NOT EXISTS "chainId" INTEGER;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
-- Remove ForeignKey
2+
ALTER TABLE "Dapp" DROP CONSTRAINT IF EXISTS "Dapp_chainId_fkey";
3+
4+
-- Delete table
5+
DELETE TABLE IF EXISTS "Chain";
6+
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
-- CreateTable
2+
CREATE TABLE IF NOT EXISTS "Chain" (
3+
"id" INTEGER NOT NULL,
4+
"name" TEXT NOT NULL,
5+
"description" TEXT,
6+
"enabled" BOOLEAN NOT NULL DEFAULT false,
7+
8+
CONSTRAINT "Chain_pkey" PRIMARY KEY ("id")
9+
);
10+
11+
-- Note: there is no `ADD CONSTRAINT IF NOT EXISTS` because there is no way to assume its
12+
-- properties. So, you should drop it if exists, and add again
13+
ALTER TABLE "Dapp" DROP CONSTRAINT IF EXISTS "Dapp_chainId_fkey";
14+
-- AddForeignKey
15+
ALTER TABLE "Dapp" ADD CONSTRAINT "Dapp_chainId_fkey" FOREIGN KEY ("chainId") REFERENCES "Chain"("id") ON DELETE SET NULL ON UPDATE CASCADE;
16+
17+
-- Seed DB
18+
INSERT INTO "Chain" ("id", "name", "description")
19+
VALUES
20+
('1', 'Mainnet', 'Ethereum Mainnet'),
21+
('11155111', 'Sepolia', 'Ethereum Sepolia'),
22+
('123456', 'Local Testnet', NULL)
23+
ON CONFLICT("id") DO NOTHING;
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
# Please do not edit this file manually
22
# It should be added in your version-control system (e.g., Git)
3-
provider = "postgresql"
3+
provider = "postgresql"

apps/back/prisma/schema.prisma

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ model Team {
6666
model Dapp {
6767
id String @id
6868
name String
69+
chainId Int?
70+
chain Chain? @relation(fields: [chainId], references: [id])
6971
address String?
7072
status DappStatus @default(DRAFT)
7173
teamId String
@@ -77,6 +79,14 @@ model Dapp {
7779
ApiKey ApiKey[]
7880
}
7981

82+
model Chain {
83+
id Int @id
84+
name String
85+
description String?
86+
enabled Boolean @default(false)
87+
Dapp Dapp[]
88+
}
89+
8090
model DappStat {
8191
id String @id
8292
name String

apps/back/src/app.module.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import commonConfig from '#config/common.config.js'
1515
import { MS_NAME } from '#constants.js'
1616
import { RestModule } from '#infra/rest/rest.module.js'
1717
import httpzConfig from '#config/httpz.config.js'
18+
import { ChainsModule } from '#chains/infra/chains.module.js'
1819
import { RedisModule } from '#infra/redis/redis.module.js'
1920
import { FeatureFlagModule } from '#feature-flag/feature-flag.module.js'
2021
import { EnvFeatureFlagHandler } from '#infra/env-feature-flag.handler.js'
@@ -65,6 +66,7 @@ export const configModule = ConfigModule.forRoot({
6566
RestModule,
6667
SqsConsumerModule,
6768
SqsProducerModule,
69+
ChainsModule,
6870
RedisModule,
6971
FeatureFlagModule.register({
7072
global: true,

apps/back/src/auth/use-cases/login.use-case.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ export class LogIn
1919
private readonly jwtService: JwtService,
2020
) {}
2121

22-
execute(input: {
22+
execute = (input: {
2323
email: string
2424
password: string
25-
}): Task<{ user: UserProps; token: string }, AppError> {
25+
}): Task<{ user: UserProps; token: string }, AppError> => {
2626
return (
2727
this.userRepository
2828
.findByEmail(input.email)

apps/back/src/auth/use-cases/signup.use-case.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ export class SignUp
3131
private readonly jwtService: JwtService,
3232
) {}
3333

34-
execute(
34+
execute = (
3535
input: SignupInput,
36-
): Task<{ user: UserProps; token: string }, AppError> {
36+
): Task<{ user: UserProps; token: string }, AppError> => {
3737
return this.uow.exec(
3838
Task.all<AppError, Invitation, ValidatedPassword>([
3939
// Note: we check the invitation token and validate the password at
@@ -70,8 +70,8 @@ export class SignUp
7070
}
7171

7272
private validateInvitation(token: string): Task<Invitation, AppError> {
73-
return this.invitationRepository
74-
.findByToken(Token.from(token))
73+
return Token.from(token)
74+
.asyncChain(this.invitationRepository.findByToken)
7575
.chain<Invitation>(invitation =>
7676
invitation.isValid
7777
? Task.of(invitation)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {
2+
AppError,
3+
Entity,
4+
fail,
5+
ok,
6+
Result,
7+
Unbrand,
8+
validationError,
9+
} from 'utils'
10+
import { z } from 'zod'
11+
import { ChainId } from './value-objects.js'
12+
13+
const schema = z.object({
14+
id: ChainId.schema,
15+
name: z.string(),
16+
description: z.string().nullish(),
17+
})
18+
19+
export type ChainProps = Unbrand<z.infer<typeof schema>>
20+
21+
export class Chain
22+
extends Entity<ChainProps>
23+
implements Readonly<Omit<ChainProps, 'id'> & { id: ChainId }>
24+
{
25+
static parse(data: unknown): Result<Chain, AppError> {
26+
if (!data) return fail(validationError('data is undefined'))
27+
const check = schema.safeParse(data)
28+
return check.success
29+
? ok(new Chain(check.data))
30+
: fail(validationError(check.error.message))
31+
}
32+
33+
get id() {
34+
return new ChainId(this.get('id'))
35+
}
36+
37+
get name() {
38+
return this.get('name')
39+
}
40+
41+
get description() {
42+
return this.get('description')
43+
}
44+
}

0 commit comments

Comments
 (0)