Skip to content

Commit

Permalink
Merge pull request #177 from napse-invest/feature/bot
Browse files Browse the repository at this point in the history
Feature/bot
  • Loading branch information
Xenepix authored Jan 20, 2024
2 parents d08509e + 1bfafa7 commit 0996ad5
Show file tree
Hide file tree
Showing 11 changed files with 166 additions and 36 deletions.
16 changes: 15 additions & 1 deletion desktop-app/renderer/api/bots/bots.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Order } from '@/api/orders/orders'
import { Wallet } from '@/api/wallets/wallets'
import { request } from 'api/request'
import { AxiosResponse } from 'axios'
import { useSearchParams } from 'next/navigation'

export interface Bot {
name: string
uuid: string
Expand All @@ -12,9 +13,22 @@ export interface Bot {
exchangeAccount: string
}

export interface RetrievedBot extends Bot {
wallet: Wallet
orders: Order[]
}

export async function listBot(
searchParams: ReturnType<typeof useSearchParams>
): Promise<AxiosResponse<Bot[]>> {
const response = await request(searchParams, 'GET', `/api/bot/`)
return response as AxiosResponse<Bot[]>
}

export async function retrieveBot(
searchParams: ReturnType<typeof useSearchParams>,
uuid: string
): Promise<AxiosResponse<RetrievedBot>> {
const response = await request(searchParams, 'GET', `/api/bot/${uuid}/`)
return response as AxiosResponse<RetrievedBot>
}
11 changes: 7 additions & 4 deletions desktop-app/renderer/api/exchangeAccounts/exchangeAccount.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import { convertInterfaceToSnakeCaseDict } from '@/api/request'
import { request } from 'api/request'
import { AxiosResponse } from 'axios'
import { useSearchParams } from 'next/navigation'

export interface ExchangeAccount {
export interface BaseExchangeAccount {
name: string
description: string
exchange: string
testing: boolean
}
export interface RetreivedExchangeAccount extends ExchangeAccount {
export interface ExchangeAccount extends BaseExchangeAccount {
uuid: string
}
export interface RetreivedExchangeAccount extends ExchangeAccount {}

export async function getExchangeAccount(
searchParams: ReturnType<typeof useSearchParams>,
Expand All @@ -33,13 +35,14 @@ export async function listExchangeAccount(

export async function createExchangeAccount(
searchParams: ReturnType<typeof useSearchParams>,
data: ExchangeAccount
data: BaseExchangeAccount
): Promise<AxiosResponse<RetreivedExchangeAccount>> {
const formatedData = convertInterfaceToSnakeCaseDict(data)
const response = await request(
searchParams,
'POST',
'/api/exchange_account/',
data
formatedData
)
return response as AxiosResponse<RetreivedExchangeAccount>
}
Expand Down
11 changes: 9 additions & 2 deletions desktop-app/renderer/api/fleets/fleets.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { convertInterfaceToSnakeCaseDict } from '@/api/request'
import { Bot } from 'api/bots/bots'
import { request } from 'api/request'
import { Wallet } from 'api/wallets/wallets'
Expand Down Expand Up @@ -57,8 +58,14 @@ export async function retrieveFleet(

export async function createFleet(
searchParams: ReturnType<typeof useSearchParams>,
fleet: BaseFleet
data: BaseFleet
): Promise<AxiosResponse<Fleet>> {
const response = await request(searchParams, 'POST', `/api/fleet/`, fleet)
const formatedData = convertInterfaceToSnakeCaseDict(data)
const response = await request(
searchParams,
'POST',
`/api/fleet/`,
formatedData
)
return response as AxiosResponse<Fleet>
}
23 changes: 23 additions & 0 deletions desktop-app/renderer/api/orders/orders.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export interface Order {
side: string
completed: boolean
spent: {
ticker: string
amount: number
price: number
value: number
}
received: {
ticker: string
amount: number
price: number
value: number
}
fees: {
ticker: string
amount: number
price: number
value: number
}
created_at: string
}
16 changes: 16 additions & 0 deletions desktop-app/renderer/api/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,19 @@ export function request(
data: data || {}
})
}

export function convertInterfaceToSnakeCaseDict(obj: any) {
// from camelCase to snake_case for REST API communication

return Object.entries(obj).reduce(
(acc, [key, value]) => {
const newKey = key.replace(
/[A-Z]/g,
(letter) => `_${letter.toLowerCase()}`
)
acc[newKey] = value
return acc
},
{} as Record<string, unknown>
)
}
17 changes: 12 additions & 5 deletions desktop-app/renderer/api/spaces/spaces.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ExchangeAccount } from '@/api/exchangeAccounts/exchangeAccount'
import { convertInterfaceToSnakeCaseDict } from '@/api/request'
import { Fleet } from 'api/fleets/fleets'
import { request } from 'api/request'
import { Wallet } from 'api/wallets/wallets'
import { AxiosResponse } from 'axios'
import { useSearchParams } from 'next/navigation'

interface Statistics {
[key: string]: number
}
Expand Down Expand Up @@ -36,9 +37,9 @@ export interface RetrievedNapseSpace extends BaseNapseSpace {

export async function getPossibleExchangeAccounts(
searchParams: ReturnType<typeof useSearchParams>
): Promise<AxiosResponse<string[]>> {
): Promise<AxiosResponse<ExchangeAccount[]>> {
const response = await request(searchParams, 'GET', '/api/exchange_account/')
return response as AxiosResponse<string[]>
return response as AxiosResponse<ExchangeAccount[]>
}

export async function listSpace(
Expand All @@ -62,8 +63,14 @@ export async function retrieveSpace(

export async function createSpace(
searchParams: ReturnType<typeof useSearchParams>,
data: BaseNapseSpace
space: BaseNapseSpace
): Promise<AxiosResponse<NapseSpace>> {
const response = await request(searchParams, 'POST', '/api/space/', data)
const formated_space = convertInterfaceToSnakeCaseDict(space)
const response = await request(
searchParams,
'POST',
'/api/space/',
formated_space
)
return response as AxiosResponse<NapseSpace>
}
23 changes: 13 additions & 10 deletions desktop-app/renderer/components/custom/selectedObject/inputs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ export interface InputType<T extends Object> {
value?: string | number | boolean
description?: string
disabled?: boolean
possibilities?: string[]
// possibilities?: string[]
possibilities?: { [key: string]: string }
}

function defaultValue(input: InputType<any>) {
Expand Down Expand Up @@ -120,15 +121,17 @@ export default function CustomForm<T extends Object>({
</SelectTrigger>
</FormControl>
<SelectContent>
{input.possibilities?.map((possibility) => (
<SelectItem
key={possibility}
value={possibility}
disabled={input.disabled}
>
{possibility}
</SelectItem>
))}
{Object.entries(input.possibilities ?? []).map(
([name, value]) => (
<SelectItem
key={name}
value={value}
disabled={input.disabled}
>
{name}
</SelectItem>
)
)}
</SelectContent>
</Select>
) : (
Expand Down
34 changes: 34 additions & 0 deletions desktop-app/renderer/pages/bots/[slug]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,41 @@
import { RetrievedBot, retrieveBot } from '@/api/bots/bots'
import ContextHeader from '@/components/layout/contextHeader'
import DefaultPageLayout from '@/components/layout/defaultPageLayout'
import { standardUrlPartial } from '@/lib/queryParams'
import { useRouter, useSearchParams } from 'next/navigation'
import { useEffect, useState } from 'react'

export default function Bot(): JSX.Element {
const searchParams = useSearchParams()
const router = useRouter()

const botID: string = searchParams.get('bot') || ''
const [bot, setBot] = useState<RetrievedBot>()

useEffect(() => {
async function fetchBot() {
try {
const response = await retrieveBot(searchParams, botID)
setBot(response.data)
} catch (error) {
console.error(error)
// go to the previous page
router.push(
standardUrlPartial(
'/bots/',
null,
{ space: '', fleet: '', bot: '' },
searchParams
)
)
}
}

if (searchParams.get('server')) {
fetchBot()
}
}, [botID, searchParams, router])
console.log(bot)
return (
<ContextHeader isBot>
<DefaultPageLayout
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { DialogClose } from '@radix-ui/react-dialog'
import { PlusIcon } from '@radix-ui/react-icons'
import {
ExchangeAccount,
BaseExchangeAccount,
RetreivedExchangeAccount,
createExchangeAccount,
getPossibleExchanges
Expand All @@ -21,7 +21,7 @@ import { useSearchParams } from 'next/navigation'
import { useEffect, useState } from 'react'
import { z } from 'zod'

const defaultExchangeAccount: ExchangeAccount = {
const defaultExchangeAccount: BaseExchangeAccount = {
name: 'My Exchange Account',
description: 'My Exchange Account Description',
testing: true,
Expand All @@ -41,7 +41,7 @@ export default function CreateExchangeAccountDialog({
}): JSX.Element {
const searchParams = useSearchParams()
const [possibleExchanges, setPossibleExchanges] = useState<string[]>([])
const [exchangeAccount, setExchangeAccount] = useState<ExchangeAccount>(
const [exchangeAccount, setExchangeAccount] = useState<BaseExchangeAccount>(
defaultExchangeAccount
)
useEffect(() => {
Expand All @@ -60,6 +60,14 @@ export default function CreateExchangeAccountDialog({
}
}, [searchParams])

const ExchangePossibilitiesSelection = possibleExchanges.reduce(
(obj, name) => {
obj[name] = name
return obj
},
{} as { [key: string]: string }
)

return (
<Dialog>
<DialogTrigger asChild>
Expand All @@ -80,7 +88,7 @@ export default function CreateExchangeAccountDialog({
provide the server name and the server URL.
</DialogDescription>
</DialogHeader>
<CustomForm<ExchangeAccount>
<CustomForm<BaseExchangeAccount>
inputs={[
{
label: 'Name',
Expand All @@ -100,7 +108,7 @@ export default function CreateExchangeAccountDialog({
label: 'Exchange',
key: 'exchange',
type: 'select',
possibilities: possibleExchanges,
possibilities: ExchangePossibilitiesSelection,
zod: z.string(),
default: defaultExchangeAccount.exchange
},
Expand Down
15 changes: 11 additions & 4 deletions desktop-app/renderer/pages/fleets/createFleetDialog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ export default function CreateFleetDialog({
}
}, [searchParams])

const SpacePossibilitiesSelection = possibleSpaces.reduce(
(obj, item) => {
obj[item.name] = item.uuid
return obj
},
{} as { [key: string]: string }
)

return (
<Dialog>
<DialogTrigger asChild>
Expand Down Expand Up @@ -95,11 +103,10 @@ export default function CreateFleetDialog({
{
label: 'Space',
key: 'space',
// type: 'select',
// possibilities: possibleSpaces,
type: 'input',
type: 'select',
possibilities: SpacePossibilitiesSelection,
zod: z.string(),
default: defaultFleet.space
default: Object.values(SpacePossibilitiesSelection)[0]
}
// TODO: add & custom clusters
]}
Expand Down
18 changes: 13 additions & 5 deletions desktop-app/renderer/pages/spaces/createSpaceDialog.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ExchangeAccount } from '@/api/exchangeAccounts/exchangeAccount'
import CustomForm from '@/components/custom/selectedObject/inputs'
import { Button } from '@/components/ui/button'
import {
Expand Down Expand Up @@ -38,7 +39,7 @@ export default function CreateSpaceDialog({
}): JSX.Element {
const searchParams = useSearchParams()
const [possibleExchangeAccounts, setPossibleExchangeAccounts] = useState<
string[]
ExchangeAccount[]
>([])
const [space, setSpace] = useState<BaseNapseSpace>(defaultSpace)

Expand All @@ -57,6 +58,14 @@ export default function CreateSpaceDialog({
}
}, [searchParams])

const ExchangeAccountPossibilitiesSelection = possibleExchangeAccounts.reduce(
(obj, item) => {
obj[item.name] = item.uuid
return obj
},
{} as { [key: string]: string }
)

return (
<Dialog>
<DialogTrigger asChild>
Expand Down Expand Up @@ -96,11 +105,10 @@ export default function CreateSpaceDialog({
{
label: 'Exchange',
key: 'exchangeAccount',
// type: 'select',
// possibilities: possibleExchangeAccounts,
type: 'input',
type: 'select',
possibilities: ExchangeAccountPossibilitiesSelection,
zod: z.string(),
default: defaultSpace.exchangeAccount
default: Object.values(ExchangeAccountPossibilitiesSelection)[0]
}
]}
onSubmit={async (values) => {
Expand Down

0 comments on commit 0996ad5

Please sign in to comment.