Skip to content

Commit

Permalink
Improve api specs
Browse files Browse the repository at this point in the history
  • Loading branch information
prevostc committed Jun 22, 2024
1 parent 4f28ce7 commit d673557
Show file tree
Hide file tree
Showing 12 changed files with 168 additions and 147 deletions.
14 changes: 0 additions & 14 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
"async-lock": "^1.4.1",
"decimal.js": "^10.4.3",
"fastify": "^4.26.2",
"fluent-json-schema": "^4.2.1",
"graphql": "^16.6.0",
"graphql-request": "^6.1.0",
"graphql-tag": "^2.12.6",
Expand Down
36 changes: 13 additions & 23 deletions src/config/chains.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,15 @@
import { type Static, Type } from '@sinclair/typebox';
import { Enum } from '@sinclair/typebox';
import { StringEnum } from '../utils/typebox';

export const chainIdSchema = Type.Union(
[
Type.Literal('arbitrum'),
Type.Literal('base'),
Type.Literal('optimism'),
Type.Literal('moonbeam'),
Type.Literal('linea'),
Type.Literal('polygon'),
],
{
description: 'Chain ID',
}
);
export type ChainId = Static<typeof chainIdSchema>;
export enum ChainId {
arbitrum = 'arbitrum',
base = 'base',
optimism = 'optimism',
moonbeam = 'moonbeam',
linea = 'linea',
polygon = 'polygon',
}

export const allChainIds: Array<ChainId> = [
'arbitrum',
'base',
'optimism',
'moonbeam',
'linea',
'polygon',
];
export const allChainIds: Array<ChainId> = Object.values(ChainId);
export const chainIdSchema = StringEnum(allChainIds);
export const chainIdAsKeySchema = Enum(ChainId);
46 changes: 24 additions & 22 deletions src/routes/v1/investor.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { type Static, Type } from '@sinclair/typebox';
import type { FastifyInstance, FastifyPluginOptions, FastifySchema } from 'fastify';
import { addressSchemaTypebox } from '../../schema/address';
import { chainIdSchema } from '../../config/chains';
import { addressSchema, transactionHashSchema } from '../../schema/address';
import { bigDecimalSchema } from '../../schema/bigint';
import { getAsyncCache } from '../../utils/async-lock';
import type { Address, Hex } from '../../utils/scalar-types';
import { getClmTimeline } from '../../utils/timeline';
import type { TimelineClmInteraction } from '../../utils/timeline-types';
import { type TimelineClmInteraction, actionsEnumSchema } from '../../utils/timeline-types';

export default async function (
instance: FastifyInstance,
Expand All @@ -16,7 +18,7 @@ export default async function (
// timeline endpoint
{
const urlParamsSchema = Type.Object({
investor_address: addressSchemaTypebox,
investor_address: addressSchema,
});
type UrlParams = Static<typeof urlParamsSchema>;

Expand Down Expand Up @@ -52,39 +54,39 @@ const clmInteractionLegacySchema = Type.Object({
datetime: Type.String(),
product_key: Type.String(),
display_name: Type.String(),
chain: Type.String(),
chain: chainIdSchema,
is_eol: Type.Boolean(),
is_dashboard_eol: Type.Boolean(),
transaction_hash: Type.String(),
transaction_hash: transactionHashSchema,

/** called shares for legacy reasons, this is now the total between manager and reward pool */
share_balance: Type.String(),
share_diff: Type.String(),
share_balance: bigDecimalSchema,
share_diff: bigDecimalSchema,

token0_to_usd: Type.String(),
underlying0_balance: Type.String(),
underlying0_diff: Type.String(),
token0_to_usd: bigDecimalSchema,
underlying0_balance: bigDecimalSchema,
underlying0_diff: bigDecimalSchema,

token1_to_usd: Type.String(),
underlying1_balance: Type.String(),
underlying1_diff: Type.String(),
token1_to_usd: bigDecimalSchema,
underlying1_balance: bigDecimalSchema,
underlying1_diff: bigDecimalSchema,

usd_balance: Type.String(),
usd_diff: Type.String(),
usd_balance: bigDecimalSchema,
usd_diff: bigDecimalSchema,
});

const clmInteractionRewardPoolSchema = Type.Object({
reward_pool_address: Type.String(),
reward_pool_balance: Type.String(),
reward_pool_diff: Type.String(),
reward_pool_address: addressSchema,
reward_pool_balance: bigDecimalSchema,
reward_pool_diff: bigDecimalSchema,
});
type ClmInteractionRewardPool = Static<typeof clmInteractionRewardPoolSchema>;

const clmInteractionManagerSchema = Type.Object({
manager_address: Type.String(),
manager_balance: Type.String(),
manager_diff: Type.String(),
actions: Type.Array(Type.String()),
manager_address: addressSchema,
manager_balance: bigDecimalSchema,
manager_diff: bigDecimalSchema,
actions: Type.Array(actionsEnumSchema),
});

const clmInteractionBaseSchema = Type.Intersect([
Expand Down
9 changes: 5 additions & 4 deletions src/routes/v1/status.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { type Static, Type } from '@sinclair/typebox';
import type { FastifyInstance, FastifyPluginOptions, FastifySchema } from 'fastify';
import { type ChainId, chainIdSchema } from '../../config/chains';
import { type ChainId, chainIdAsKeySchema } from '../../config/chains';
import { timestampNumberSchema } from '../../schema/bigint';
import { getAsyncCache } from '../../utils/async-lock';
import { getAllSdks, sdkContextSchema } from '../../utils/sdk';

Expand All @@ -20,7 +21,7 @@ export default async function (
},
};

instance.get('/', { schema }, async (_, reply) => {
instance.get('', { schema }, async (_, reply) => {
const res = await asyncCache.wrap('status', 60 * 1000, async () => {
return await getStatus();
});
Expand All @@ -35,12 +36,12 @@ const endpointStatusSchema = Type.Object({
subgraph: sdkContextSchema.properties.subgraph,
tag: sdkContextSchema.properties.tag,
blockNumber: Type.Union([Type.Number(), Type.Null()]),
timestamp: Type.Union([Type.Number(), Type.Null()]),
timestamp: Type.Union([timestampNumberSchema, Type.Null()]),
hasErrors: Type.Boolean(),
});
type EndpointStatus = Static<typeof endpointStatusSchema>;

const statusSchema = Type.Partial(Type.Record(chainIdSchema, Type.Array(endpointStatusSchema)));
const statusSchema = Type.Record(chainIdAsKeySchema, Type.Array(endpointStatusSchema));
type Status = Static<typeof statusSchema>;

async function getStatus(): Promise<Status> {
Expand Down
90 changes: 48 additions & 42 deletions src/routes/v1/vault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,19 @@ import { type Static, Type } from '@sinclair/typebox';
import type { FastifyInstance, FastifyPluginOptions, FastifySchema } from 'fastify';
import { type ChainId, chainIdSchema } from '../../config/chains';
import type { HarvestDataFragment, Token } from '../../queries/codegen/sdk';
import { addressSchemaTypebox } from '../../schema/address';
import { bigintSchemaTypebox } from '../../schema/bigint';
import { type Period, getPeriodSeconds, periodSchemaTypebox } from '../../schema/period';
import { addressSchema } from '../../schema/address';
import {
bigDecimalSchema,
bigintSchema,
timestampNumberSchema,
timestampStrSchema,
} from '../../schema/bigint';
import { type Period, getPeriodSeconds, periodSchema } from '../../schema/period';
import { getAsyncCache } from '../../utils/async-lock';
import { interpretAsDecimal } from '../../utils/decimal';
import type { Address, Hex } from '../../utils/scalar-types';
import { getSdksForChain, paginateSdkCalls } from '../../utils/sdk';
import { setOpts } from '../../utils/typebox';

export default async function (
instance: FastifyInstance,
Expand All @@ -21,15 +27,15 @@ export default async function (
{
const urlParamsSchema = Type.Object({
chain: chainIdSchema,
vault_address: addressSchemaTypebox,
vault_address: addressSchema,
});
type UrlParams = Static<typeof urlParamsSchema>;

const schema: FastifySchema = {
tags: ['vault'],
params: urlParamsSchema,
response: {
200: Type.Exclude(Type.Undefined(), vaultPriceSchema),
200: vaultPriceSchema,
},
};

Expand All @@ -56,8 +62,8 @@ export default async function (
// vault harvests
{
const urlParamsSchema = Type.Object({
chain: Type.Awaited(chainIdSchema, { description: 'The chain the vault is on' }),
vault_address: Type.Awaited(addressSchemaTypebox, {
chain: setOpts(chainIdSchema, { description: 'The chain the vault is on' }),
vault_address: setOpts(addressSchema, {
description: 'The vault contract address',
}),
});
Expand Down Expand Up @@ -96,12 +102,12 @@ export default async function (
// historical prices
{
const urlParamsSchema = Type.Object({
chain: Type.Awaited(chainIdSchema, { description: 'The chain the vault is on' }),
vault_address: Type.Awaited(addressSchemaTypebox, {
chain: setOpts(chainIdSchema, { description: 'The chain the vault is on' }),
vault_address: setOpts(addressSchema, {
description: 'The vault contract address',
}),
period: Type.Awaited(periodSchemaTypebox, { description: 'The snapshot period for prices' }),
since: Type.Awaited(bigintSchemaTypebox, { description: 'The unix timestamp to start from' }),
period: setOpts(periodSchema, { description: 'The snapshot period for prices' }),
since: setOpts(timestampStrSchema, { description: 'The unix timestamp to start from' }),
});

type UrlParams = Static<typeof urlParamsSchema>;
Expand Down Expand Up @@ -139,11 +145,11 @@ export default async function (
// historical data availability
{
const urlParamsSchema = Type.Object({
chain: Type.Awaited(chainIdSchema, { description: 'The chain the vault is on' }),
vault_address: Type.Awaited(addressSchemaTypebox, {
chain: setOpts(chainIdSchema, { description: 'The chain the vault is on' }),
vault_address: setOpts(addressSchema, {
description: 'The vault contract address',
}),
period: Type.Awaited(periodSchemaTypebox, { description: 'The snapshot period for prices' }),
period: setOpts(periodSchema, { description: 'The snapshot period for prices' }),
});

type UrlParams = Static<typeof urlParamsSchema>;
Expand Down Expand Up @@ -178,8 +184,8 @@ export default async function (

{
const urlParamsSchema = Type.Object({
chain: Type.Awaited(chainIdSchema, { description: 'The chain the vault is on' }),
vault_address: Type.Awaited(addressSchemaTypebox, {
chain: setOpts(chainIdSchema, { description: 'The chain the vault is on' }),
vault_address: setOpts(addressSchema, {
description: 'The vault contract address',
}),
});
Expand Down Expand Up @@ -214,17 +220,17 @@ export default async function (
done();
}

const vaultPriceSchema = Type.Union([
Type.Object({
min: Type.String(),
current: Type.String(),
max: Type.String(),
}),
Type.Undefined(),
]);
const vaultPriceSchema = Type.Object({
min: bigintSchema,
current: bigintSchema,
max: bigintSchema,
});
type VaultPrice = Static<typeof vaultPriceSchema>;

const getVaultPrice = async (chain: ChainId, vault_address: Address): Promise<VaultPrice> => {
const getVaultPrice = async (
chain: ChainId,
vault_address: Address
): Promise<VaultPrice | undefined> => {
const res = await Promise.all(
getSdksForChain(chain).map(async sdk =>
sdk.VaultPrice({
Expand All @@ -246,12 +252,12 @@ const getVaultPrice = async (chain: ChainId, vault_address: Address): Promise<Va
};

export const vaultHarvestSchema = Type.Object({
timestamp: Type.String({ description: 'The timestamp of the harvest' }),
compoundedAmount0: Type.String({ description: 'The amount of token0 compounded' }),
compoundedAmount1: Type.String({ description: 'The amount of token1 compounded' }),
token0ToUsd: Type.String({ description: 'The price of token0 in USD' }),
token1ToUsd: Type.String({ description: 'The price of token1 in USD' }),
totalSupply: Type.String({ description: 'The total supply of the vault' }),
timestamp: setOpts(timestampStrSchema, { description: 'The timestamp of the harvest' }),
compoundedAmount0: setOpts(bigDecimalSchema, { description: 'The amount of token0 compounded' }),
compoundedAmount1: setOpts(bigDecimalSchema, { description: 'The amount of token1 compounded' }),
token0ToUsd: setOpts(bigDecimalSchema, { description: 'The price of token0 in USD' }),
token1ToUsd: setOpts(bigDecimalSchema, { description: 'The price of token1 in USD' }),
totalSupply: setOpts(bigDecimalSchema, { description: 'The total supply of the vault' }),
});
export type VaultHarvest = Static<typeof vaultHarvestSchema>;
const vaultHarvestsSchema = Type.Array(vaultHarvestSchema);
Expand Down Expand Up @@ -307,10 +313,10 @@ export function prepareVaultHarvests(vault: {

const vaultHistoricPricesSchema = Type.Array(
Type.Object({
t: Type.Number(),
min: Type.String(),
v: Type.String(),
max: Type.String(),
t: timestampNumberSchema,
min: bigDecimalSchema,
v: bigDecimalSchema,
max: bigDecimalSchema,
})
);
type VaultHistoricPrices = Static<typeof vaultHistoricPricesSchema>;
Expand Down Expand Up @@ -385,13 +391,13 @@ const getVaultHistoricPricesRange = async (
};

const vaultInvestorSchema = Type.Object({
investor_address: addressSchemaTypebox,
total_shares_balance: Type.String(),
underlying_balance0: Type.String(),
underlying_balance1: Type.String(),
usd_balance0: Type.String(),
usd_balance1: Type.String(),
usd_balance: Type.String(),
investor_address: addressSchema,
total_shares_balance: bigDecimalSchema,
underlying_balance0: bigDecimalSchema,
underlying_balance1: bigDecimalSchema,
usd_balance0: bigDecimalSchema,
usd_balance1: bigDecimalSchema,
usd_balance: bigDecimalSchema,
});
const vaultInvestorsSchema = Type.Array(vaultInvestorSchema);
type VaultInvestors = Static<typeof vaultInvestorsSchema>;
Expand Down
Loading

0 comments on commit d673557

Please sign in to comment.