diff --git a/operator/core/graphql/extensions/orders/index.ts b/operator/core/graphql/extensions/orders/index.ts index 179e211a..029afe85 100644 --- a/operator/core/graphql/extensions/orders/index.ts +++ b/operator/core/graphql/extensions/orders/index.ts @@ -1,6 +1,7 @@ import gql from 'graphql-tag' import { MutationResolvers, QueryResolvers } from '@/types/resolvers' import { GraphQLError } from 'graphql' +import { ZeroAddress } from 'ethers' // TODO: Pool Key might give some details about token address and range and what // not so ensure that you are not capturing more than you need to @@ -9,10 +10,8 @@ import { GraphQLError } from 'graphql' export const typeDefs = gql` input CreateOrderInput { trader: String! - # Can be current tick - tickToSellAt: Int + tickToSellAt: String tokenInput: String! - # TODO: Fix this to be a Decimal or BigInt inputAmount: String outputAmount: String tokenA: String! @@ -21,6 +20,9 @@ export const typeDefs = gql` tickSpacing: String! hooks: String # Figure out if we need to store hooks in an array or... permit2Signature: String! + orderSignature: String! + permit2Nonce: String! + permit2Deadline: ISO8601Date! startTime: ISO8601Date # Set this to a default of 1 week from now deadline: ISO8601Date @@ -29,7 +31,7 @@ export const typeDefs = gql` type Order { id: String! trader: String! - tickToSellAt: Int! + tickToSellAt: String! zeroForOne: Boolean! tokenInput: String! inputAmount: String @@ -39,6 +41,9 @@ export const typeDefs = gql` permit2Signature: String! startTime: ISO8601Date! deadline: ISO8601Date! + orderSignature: String! + permit2Nonce: String! + permit2Deadline: ISO8601Date! } type PoolKey { @@ -60,128 +65,135 @@ export const typeDefs = gql` ` interface OrdersResolvers { - // Query: Pick - // Mutation: Pick + Query: Pick + Mutation: Pick } export const resolvers: OrdersResolvers = { - // Query: { - // orders: { - // resolve: async (_parent, _args, { getDb }) => { - // const db = getDb() - // const orders = await db.order.findMany({ - // include: { poolKey: true }, - // }) - // return orders - // }, - // }, - // // TODO: Add get order by person, get order by id, get order by pool key, get order by status - // }, - // Mutation: { - // createOrder: { - // resolve: async ( - // _parent, - // { - // input: { - // trader, - // tickToSellAt, - // tokenInput, - // inputAmount, - // outputAmount, - // tokenA, - // tokenB, - // hooks, - // fee, - // tickSpacing, - // permit2Signature, - // startTime, - // deadline, - // }, - // }, - // { getDb } - // ) => { - // const db = getDb() - // // TODO: Create a function here to valiate inputs - // // then create the pool key (or find it) - // // and then create the order - // // TODO: Once this is done, we should also figure out how to - // // validate hooks and pool keys on chain - // try { - // const [token0, token1] = - // tokenA < tokenB ? [tokenA, tokenB] : [tokenB, tokenA] - // const zeroForOne = tokenInput === tokenA - // const poolKey = await db.poolKey.findOrCreate({ - // where: { - // token0, - // token1, - // fee, - // tickSpacing: tickSpacing.toString(), - // hooks, - // token0_token1_fee_tickSpacing_hooks: { - // token0, - // token1, - // fee, - // tickSpacing: tickSpacing.toString(), - // hooks, - // }, - // }, - // create: { - // token0, - // token1, - // fee, - // tickSpacing: tickSpacing.toString(), - // hooks, - // }, - // update: {}, - // }) - // const _startTime = startTime || new Date() - // const _deadline = - // deadline || new Date(Date.now() + 604800000) - // const order = await db.order.findOrCreate({ - // where: { - // trader, - // poolKeyId: poolKey.id, - // trader_tickToSellAt_zeroForOne_tokenInput_startTime_poolKeyId: - // { - // trader, - // tickToSellAt: tickToSellAt - // ? tickToSellAt.toString() - // : '0', - // zeroForOne, - // startTime: _startTime, - // tokenInput, - // poolKeyId: poolKey.id, - // }, - // }, - // create: { - // trader, - // tickToSellAt: tickToSellAt - // ? tickToSellAt.toString() - // : '0', - // inputAmount: inputAmount - // ? inputAmount.toString() - // : null, - // outputAmount: outputAmount - // ? outputAmount.toString() - // : null, - // tokenInput, - // poolKeyId: poolKey.id, - // permit2Signature, - // zeroForOne, - // startTime: _startTime, - // deadline: _deadline, - // }, - // update: {}, - // include: { - // poolKey: true, - // }, - // }) - // return order - // } catch (error) { - // console.error('Error creating order:', error) - // throw new GraphQLError('Failed to create order') - // } - // }, - // }, - // }, + Query: { + orders: { + resolve: async (_parent, _args, { getDb }) => { + const db = getDb() + const orders = await db.order.findMany({ + include: { poolKey: true }, + }) + return orders + }, + }, + // TODO: Add get order by person, get order by id, get order by pool key, get order by status + }, + Mutation: { + createOrder: { + resolve: async ( + _parent, + { + input: { + trader, + tickToSellAt, + tokenInput, + inputAmount, + outputAmount, + tokenA, + tokenB, + hooks: _hooks, + fee, + tickSpacing, + permit2Signature, + startTime, + deadline, + orderSignature, + permit2Nonce, + permit2Deadline, + }, + }, + { getDb } + ) => { + const db = getDb() + // TODO: Create a function here to valiate inputs + // then create the pool key (or find it) + // and then create the order + // TODO: Once this is done, we should also figure out how to + // validate hooks and pool keys on chain + if (!permit2Deadline) + throw new GraphQLError('permit2Deadline is required') + const hooks = _hooks || ZeroAddress + try { + const [token0, token1] = + tokenA < tokenB ? [tokenA, tokenB] : [tokenB, tokenA] + const zeroForOne = tokenInput === tokenA + const poolKey = await db.poolKey.findOrCreate({ + where: { + token0, + token1, + fee, + tickSpacing: tickSpacing.toString(), + hooks, + token0_token1_fee_tickSpacing_hooks: { + token0, + token1, + fee, + tickSpacing: tickSpacing.toString(), + hooks, + }, + }, + create: { + token0, + token1, + fee, + tickSpacing: tickSpacing.toString(), + hooks, + }, + update: {}, + }) + const _startTime = startTime || new Date() + const _deadline = + deadline || new Date(Date.now() + 604800000) + const order = await db.order.findOrCreate({ + where: { + trader, + poolKeyId: poolKey.id, + trader_tickToSellAt_zeroForOne_tokenInput_startTime_poolKeyId: + { + trader, + tickToSellAt: tickToSellAt + ? tickToSellAt + : '0', + zeroForOne, + startTime: _startTime, + tokenInput, + poolKeyId: poolKey.id, + }, + }, + create: { + trader, + tickToSellAt: tickToSellAt ? tickToSellAt : '0', + inputAmount: inputAmount + ? inputAmount.toString() + : null, + outputAmount: outputAmount + ? outputAmount.toString() + : null, + tokenInput, + poolKeyId: poolKey.id, + permit2Signature, + zeroForOne, + startTime: _startTime, + deadline: _deadline, + orderSignature, + permit2Nonce, + permit2Deadline, + }, + update: {}, + include: { + poolKey: true, + }, + }) + return order + } catch (error) { + console.error('Error creating order:', error) + throw new GraphQLError('Failed to create order') + } + }, + }, + }, } diff --git a/operator/core/types/queries.ts b/operator/core/types/queries.ts index 57fd0d09..eefa8924 100644 --- a/operator/core/types/queries.ts +++ b/operator/core/types/queries.ts @@ -20,11 +20,14 @@ export interface CreateOrderInput { fee: Scalars['String']['input']; hooks?: InputMaybe; inputAmount?: InputMaybe; + orderSignature: Scalars['String']['input']; outputAmount?: InputMaybe; + permit2Deadline: Scalars['ISO8601Date']['input']; + permit2Nonce: Scalars['String']['input']; permit2Signature: Scalars['String']['input']; startTime?: InputMaybe; tickSpacing: Scalars['String']['input']; - tickToSellAt?: InputMaybe; + tickToSellAt?: InputMaybe; tokenA: Scalars['String']['input']; tokenB: Scalars['String']['input']; tokenInput: Scalars['String']['input']; @@ -44,11 +47,14 @@ export interface Order { deadline: Scalars['ISO8601Date']['output']; id: Scalars['String']['output']; inputAmount?: Maybe; + orderSignature: Scalars['String']['output']; outputAmount?: Maybe; + permit2Deadline: Scalars['ISO8601Date']['output']; + permit2Nonce: Scalars['String']['output']; permit2Signature: Scalars['String']['output']; poolKey: PoolKey; startTime: Scalars['ISO8601Date']['output']; - tickToSellAt: Scalars['Int']['output']; + tickToSellAt: Scalars['String']['output']; tokenInput: Scalars['String']['output']; trader: Scalars['String']['output']; zeroForOne: Scalars['Boolean']['output']; diff --git a/operator/core/types/resolvers.ts b/operator/core/types/resolvers.ts index 11b08643..a670dade 100644 --- a/operator/core/types/resolvers.ts +++ b/operator/core/types/resolvers.ts @@ -23,11 +23,14 @@ export interface CreateOrderInput { fee: Scalars['String']['input']; hooks?: InputMaybe; inputAmount?: InputMaybe; + orderSignature: Scalars['String']['input']; outputAmount?: InputMaybe; + permit2Deadline: Scalars['ISO8601Date']['input']; + permit2Nonce: Scalars['String']['input']; permit2Signature: Scalars['String']['input']; startTime?: InputMaybe; tickSpacing: Scalars['String']['input']; - tickToSellAt?: InputMaybe; + tickToSellAt?: InputMaybe; tokenA: Scalars['String']['input']; tokenB: Scalars['String']['input']; tokenInput: Scalars['String']['input']; @@ -47,11 +50,14 @@ export interface Order { deadline: Scalars['ISO8601Date']['output']; id: Scalars['String']['output']; inputAmount?: Maybe; + orderSignature: Scalars['String']['output']; outputAmount?: Maybe; + permit2Deadline: Scalars['ISO8601Date']['output']; + permit2Nonce: Scalars['String']['output']; permit2Signature: Scalars['String']['output']; poolKey: PoolKey; startTime: Scalars['ISO8601Date']['output']; - tickToSellAt: Scalars['Int']['output']; + tickToSellAt: Scalars['String']['output']; tokenInput: Scalars['String']['output']; trader: Scalars['String']['output']; zeroForOne: Scalars['Boolean']['output']; @@ -145,7 +151,6 @@ export type ResolversTypes = ResolversObject<{ Boolean: ResolverTypeWrapper; CreateOrderInput: CreateOrderInput; ISO8601Date: ResolverTypeWrapper; - Int: ResolverTypeWrapper; Mutation: ResolverTypeWrapper; Order: ResolverTypeWrapper; PoolKey: ResolverTypeWrapper; @@ -158,7 +163,6 @@ export type ResolversParentTypes = ResolversObject<{ Boolean: Scalars['Boolean']['output']; CreateOrderInput: CreateOrderInput; ISO8601Date: Scalars['ISO8601Date']['output']; - Int: Scalars['Int']['output']; Mutation: RootValue; Order: Order; PoolKey: PoolKey; @@ -178,11 +182,14 @@ export type OrderResolvers; id?: Resolver; inputAmount?: Resolver, ParentType, ContextType>; + orderSignature?: Resolver; outputAmount?: Resolver, ParentType, ContextType>; + permit2Deadline?: Resolver; + permit2Nonce?: Resolver; permit2Signature?: Resolver; poolKey?: Resolver; startTime?: Resolver; - tickToSellAt?: Resolver; + tickToSellAt?: Resolver; tokenInput?: Resolver; trader?: Resolver; zeroForOne?: Resolver;