Skip to content

Commit

Permalink
create initial schema
Browse files Browse the repository at this point in the history
  • Loading branch information
decartesol committed Feb 8, 2024
1 parent 28ac1cc commit 4b9e628
Showing 1 changed file with 65 additions and 2 deletions.
67 changes: 65 additions & 2 deletions packages/database/lib/schema.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,68 @@
import { pgTable, text } from 'drizzle-orm/pg-core';
import { bigint, index, pgTable, primaryKey, smallint, smallserial, varchar } from 'drizzle-orm/pg-core';

// TODO: index order book

// https://docs.rs/solana-program/latest/src/solana_program/pubkey.rs.html#24
const MAX_PUBKEY_B58_STR_LEN = 44;
const pubkey = (columnName: string) => varchar(columnName, {length: MAX_PUBKEY_B58_STR_LEN});

const MAX_TRANSACTION_B58_STR_LEN = 88;
const transaction = (columnName: string) => varchar(columnName, {length: MAX_TRANSACTION_B58_STR_LEN});

const tokenAmount = (columnName: string) => bigint(columnName, {mode: 'bigint'});

const timestamp = (columnName: string) => bigint(columnName, {mode: 'bigint'});

export const proposals = pgTable('proposals', {
id: text('id').primaryKey(),
proposalId: pubkey('proposal_id').primaryKey(),
autocratVersion: smallint('autocrat_version').notNull()
});

export enum MarketType {
OPEN_BOOK = 'OPEN_BOOK'
}

type NonEmptyList<E> = [E, ...E[]];

export const markets = pgTable('markets', {
marketId: pubkey('market_id').primaryKey(),
marketType: varchar('market_type', {enum: Object.values(MarketType) as NonEmptyList<MarketType>}).notNull(),
baseCurrencyMint: pubkey('base_currency_mint').references(() => tokens.tokenMint).notNull(),
quoteCurrencyMint: pubkey('quote_currency_mint').references(() => tokens.tokenMint).notNull(),
});

export const tokens = pgTable('tokens', {
tokenMint: pubkey('token_mint').primaryKey(),
name: varchar('name', {length: 30}).notNull(),
symbol: varchar('symbol', {length: 10}).notNull(),
decimals: smallserial('decimals').notNull()
});

export const trades = pgTable('trades', {
transactionId: transaction('transaction_id').primaryKey(),
slot: bigint('slot', {mode: 'bigint'}).notNull(),
block: bigint('block', {mode: 'bigint'}).notNull(),
time: timestamp('time').notNull(),
marketId: pubkey('market_id').references(() => markets.marketId).notNull(),
takerId: pubkey('taker_id').notNull(),
baseAmount: tokenAmount('base_amount').notNull(),
quotePrice: tokenAmount('quote_price').notNull(),
}, table => ({
slotIdx: index('slot_index').on(table.marketId, table.slot),
blockIdx: index('block_index').on(table.marketId, table.block),
timeIdx: index('time_index').on(table.marketId, table.time)
}));

export const candles = pgTable('candles', {
marketId: pubkey('market_id').references(() => markets.marketId).notNull(),
// increments by minute
timestamp: timestamp('timestamp').notNull(),
high: tokenAmount('high'),
low: tokenAmount('low'),
close: tokenAmount('close'),
volume: tokenAmount('volume').notNull(),
// time-weighted average
average: tokenAmount('average'),
}, table => ({
pk: primaryKey(table.marketId, table.timestamp)
}));

0 comments on commit 4b9e628

Please sign in to comment.