-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
25 changed files
with
414 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
import type { Prisma, PrismaClient } from "@prisma/client"; | ||
import type { DefaultArgs, GetFindResult, InternalArgs } from "@prisma/client/runtime/library"; | ||
|
||
import type { XBotType } from "@opentrader/types"; | ||
import { TBotState, ZDcaBotSettings } from "../../types/index.js"; | ||
import { TDcaBotSettings } from "../../types/dca-bot/index.js"; | ||
|
||
type NarrowBotType<ExtArgs extends InternalArgs, T> = Omit< | ||
Awaited<GetFindResult<Prisma.$BotPayload<ExtArgs>, T, {}>>, | ||
"settings" | "state" | ||
> & { | ||
settings: TDcaBotSettings; | ||
state: TBotState; | ||
}; | ||
|
||
const BOT_TYPE = "DcaBot" satisfies XBotType; | ||
|
||
export const dcaBotModel = <ExtArgs extends InternalArgs = DefaultArgs>(prisma: PrismaClient) => ({ | ||
async findUnique<T extends Prisma.BotFindUniqueArgs<ExtArgs>>( | ||
args: Prisma.SelectSubset<T, Prisma.BotFindUniqueArgs<ExtArgs>>, | ||
) { | ||
const bot = await prisma.bot.findUnique<T>({ | ||
...args, | ||
where: { | ||
...args.where, | ||
type: BOT_TYPE, | ||
}, | ||
}); | ||
|
||
if (!bot) return null; | ||
|
||
if ("settings" in bot) { | ||
(bot as any).settings = ZDcaBotSettings.parse(JSON.parse(bot.settings)); | ||
} | ||
if ("state" in bot) { | ||
(bot as any).state = JSON.parse(bot.state) as TBotState; | ||
} | ||
|
||
return bot as unknown as NarrowBotType<ExtArgs, T>; | ||
}, | ||
async findUniqueOrThrow<T extends Prisma.BotFindUniqueOrThrowArgs>( | ||
args: Prisma.SelectSubset<T, Prisma.BotFindUniqueOrThrowArgs>, | ||
) { | ||
const bot = await prisma.bot.findUniqueOrThrow<T>({ | ||
...args, | ||
where: { | ||
...args.where, | ||
type: BOT_TYPE, | ||
}, | ||
}); | ||
|
||
if ("settings" in bot) { | ||
(bot as any).settings = ZDcaBotSettings.parse(JSON.parse(bot.settings)); | ||
} | ||
if ("state" in bot) { | ||
(bot as any).state = JSON.parse(bot.state) as TBotState; | ||
} | ||
|
||
return bot as unknown as NarrowBotType<ExtArgs, T>; | ||
}, | ||
async findFirstOrThrow<T extends Prisma.BotFindFirstOrThrowArgs>( | ||
args: Prisma.SelectSubset<T, Prisma.BotFindFirstOrThrowArgs>, | ||
) { | ||
if (args.where) { | ||
args.where.type = BOT_TYPE; | ||
} | ||
|
||
const bot = await prisma.bot.findFirstOrThrow<T>(args); | ||
|
||
if ("settings" in bot) { | ||
(bot as any).settings = ZDcaBotSettings.parse(JSON.parse(bot.settings)); | ||
} | ||
if ("state" in bot) { | ||
(bot as any).state = JSON.parse(bot.state) as TBotState; | ||
} | ||
|
||
return bot as unknown as NarrowBotType<ExtArgs, T>; | ||
}, | ||
async findMany<T extends Prisma.BotFindManyArgs>(args: Prisma.SelectSubset<T, Prisma.BotFindManyArgs>) { | ||
if (args.where) { | ||
args.where.type = BOT_TYPE; | ||
} | ||
const bots = await prisma.bot.findMany<T>(args); | ||
|
||
return bots.map((bot) => { | ||
if ("settings" in bot) { | ||
(bot as any).settings = ZDcaBotSettings.parse(JSON.parse(bot.settings)); | ||
} | ||
if ("state" in bot) { | ||
(bot as any).state = JSON.parse(bot.state) as TBotState; | ||
} | ||
|
||
return bot as unknown as NarrowBotType<ExtArgs, T>; | ||
}); | ||
}, | ||
async create<T extends Prisma.BotCreateArgs>(args: Prisma.SelectSubset<T, Prisma.BotCreateArgs>) { | ||
ZDcaBotSettings.parse(JSON.parse(args.data.settings)); | ||
|
||
const bot = await prisma.bot.create<T>({ | ||
...args, | ||
data: { | ||
...args.data, | ||
type: BOT_TYPE, | ||
}, | ||
}); | ||
|
||
if ("settings" in bot) { | ||
(bot as any).settings = ZDcaBotSettings.parse(JSON.parse(bot.settings)); | ||
} | ||
if ("state" in bot) { | ||
(bot as any).state = JSON.parse(bot.state) as TBotState; | ||
} | ||
|
||
return bot as unknown as NarrowBotType<ExtArgs, T>; | ||
}, | ||
async update<T extends Prisma.BotUpdateArgs>(args: Prisma.SelectSubset<T, Prisma.BotUpdateArgs>) { | ||
if (typeof args.data.settings === "string") { | ||
ZDcaBotSettings.parse(JSON.parse(args.data.settings)); | ||
} | ||
|
||
const bot = await prisma.bot.update<T>({ | ||
...args, | ||
where: { | ||
...args.where, | ||
type: BOT_TYPE, | ||
}, | ||
}); | ||
|
||
if ("settings" in bot) { | ||
(bot as any).settings = ZDcaBotSettings.parse(JSON.parse(bot.settings)); | ||
} | ||
if ("state" in bot) { | ||
(bot as any).state = JSON.parse(bot.state) as TBotState; | ||
} | ||
|
||
return bot as unknown as NarrowBotType<ExtArgs, T>; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { z } from "zod"; | ||
|
||
import { zt } from "@opentrader/prisma"; | ||
import { ZBotState } from "../bot/bot-state.schema.js"; | ||
|
||
export const ZDcaBotSettings = z.any(); // @todo use `dca.schema` from @opentrader/bot-templates | ||
|
||
export const ZDcaBot = zt.BotSchema.extend({ | ||
settings: ZDcaBotSettings, | ||
state: ZBotState, | ||
}); | ||
|
||
export type TDcaBot = z.infer<typeof ZDcaBot>; | ||
export type TDcaBotSettings = z.infer<typeof ZDcaBotSettings>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from "./dca-bot.schema.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
export * from "./exchange-account/index.js"; | ||
export * from "./bot/index.js"; | ||
export * from "./grid-bot/index.js"; | ||
export * from "./dca-bot/index.js"; | ||
export * from "./bot-logs/index.js"; | ||
export * from "./order/index.js"; | ||
export * from "./smart-trade/index.js"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
63 changes: 63 additions & 0 deletions
63
packages/trpc/src/routers/private/dca-bot/create-bot/handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
import { TRPCError } from "@trpc/server"; | ||
|
||
import { XBotType } from "@opentrader/types"; | ||
import { xprisma } from "@opentrader/db"; | ||
import { dca } from "@opentrader/bot-templates"; | ||
import type { Context } from "../../../../utils/context.js"; | ||
import type { TCreateDcaBotInputSchema } from "./schema.js"; | ||
|
||
type Options = { | ||
ctx: { | ||
user: NonNullable<Context["user"]>; | ||
}; | ||
input: TCreateDcaBotInputSchema; | ||
}; | ||
|
||
export async function createDcaBot({ ctx, input }: Options) { | ||
const { exchangeAccountId, data } = input; | ||
|
||
const exchangeAccount = await xprisma.exchangeAccount.findUnique({ | ||
where: { | ||
id: exchangeAccountId, | ||
owner: { | ||
id: ctx.user.id, | ||
}, | ||
}, | ||
}); | ||
|
||
if (!exchangeAccount) { | ||
throw new TRPCError({ | ||
message: "Exchange Account doesn't exists", | ||
code: "NOT_FOUND", | ||
}); | ||
} | ||
|
||
const parsed = dca.schema.safeParse(data.settings); | ||
if (!parsed.success) { | ||
throw new TRPCError({ | ||
message: `Invalid strategy params: ${parsed.error.message}`, | ||
code: "PARSE_ERROR", | ||
}); | ||
} | ||
|
||
const bot = await xprisma.bot.dca.create({ | ||
data: { | ||
...data, | ||
settings: JSON.stringify(data.settings), | ||
type: "DcaBot" satisfies XBotType, | ||
template: "dca", | ||
exchangeAccount: { | ||
connect: { | ||
id: exchangeAccount.id, | ||
}, | ||
}, | ||
owner: { | ||
connect: { | ||
id: ctx.user.id, | ||
}, | ||
}, | ||
}, | ||
}); | ||
|
||
return bot; | ||
} |
14 changes: 14 additions & 0 deletions
14
packages/trpc/src/routers/private/dca-bot/create-bot/schema.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { z } from "zod"; | ||
|
||
import { ZDcaBot } from '@opentrader/db'; | ||
|
||
export const ZCreateDcaBotInputSchema = z.object({ | ||
exchangeAccountId: z.number(), | ||
data: ZDcaBot.pick({ | ||
name: true, | ||
symbol: true, | ||
settings: true, | ||
}), | ||
}); | ||
|
||
export type TCreateDcaBotInputSchema = z.infer<typeof ZCreateDcaBotInputSchema>; |
23 changes: 23 additions & 0 deletions
23
packages/trpc/src/routers/private/dca-bot/get-bot/handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { xprisma } from "@opentrader/db"; | ||
import type { Context } from "../../../../utils/context.js"; | ||
import type { TGetDcaBotInputSchema } from "./schema.js"; | ||
|
||
type Options = { | ||
ctx: { | ||
user: NonNullable<Context["user"]>; | ||
}; | ||
input: TGetDcaBotInputSchema; | ||
}; | ||
|
||
export async function getDcaBot({ ctx, input: id }: Options) { | ||
const bot = await xprisma.bot.dca.findUniqueOrThrow({ | ||
where: { | ||
id, | ||
owner: { | ||
id: ctx.user.id, | ||
}, | ||
}, | ||
}); | ||
|
||
return bot; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { z } from "zod"; | ||
|
||
export const ZGetDcaBotInputSchema = z.number(); | ||
|
||
export type TGetDcaBotInputSchema = z.infer<typeof ZGetDcaBotInputSchema>; |
23 changes: 23 additions & 0 deletions
23
packages/trpc/src/routers/private/dca-bot/get-bots/handler.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { xprisma } from "@opentrader/db"; | ||
import type { Context } from "../../../../utils/context.js"; | ||
|
||
type Options = { | ||
ctx: { | ||
user: NonNullable<Context["user"]>; | ||
}; | ||
}; | ||
|
||
export async function getDcaBots({ ctx }: Options) { | ||
const bots = await xprisma.bot.dca.findMany({ | ||
where: { | ||
owner: { | ||
id: ctx.user.id, | ||
}, | ||
}, | ||
orderBy: { | ||
createdAt: "desc", | ||
}, | ||
}); | ||
|
||
return bots; | ||
} |
Oops, something went wrong.