Skip to content

Commit

Permalink
add more APIs
Browse files Browse the repository at this point in the history
  • Loading branch information
berteotti committed Aug 5, 2024
1 parent 48237a5 commit 51bd40c
Show file tree
Hide file tree
Showing 8 changed files with 204 additions and 13 deletions.
36 changes: 36 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
5 changes: 4 additions & 1 deletion .env
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
STACKLY_API_KEY=
MORALIS_API_KEY=
MORALIS_API_KEY=
PORTALS_API_KEY=
COINGECKO_API_KEY=
MOBULA_API_KEY=
18 changes: 18 additions & 0 deletions .github/workflows/fly-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# See https://fly.io/docs/app-guides/continuous-deployment-with-github-actions/

name: Fly Deploy
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy app
runs-on: ubuntu-latest
concurrency: deploy-group # optional: ensure only one action runs at a time
steps:
- uses: actions/checkout@v4
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
46 changes: 46 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# syntax = docker/dockerfile:1

# Adjust BUN_VERSION as desired
ARG BUN_VERSION=1.0.22
FROM oven/bun:${BUN_VERSION}-slim as base

LABEL fly_launch_runtime="Next.js"

# Next.js app lives here
WORKDIR /app

# Set production environment
ENV NODE_ENV="production"


# Throw-away build stage to reduce size of final image
FROM base as build

# Install packages needed to build node modules
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential pkg-config python-is-python3

# Install node modules
COPY --link bun.lockb package.json ./
RUN bun install

# Copy application code
COPY --link . .

# Build application
RUN bun --bun run build

# Remove development dependencies
RUN rm -rf node_modules && \
bun install --ci


# Final stage for app image
FROM base

# Copy built application
COPY --from=build /app /app

# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
CMD [ "bun", "run", "start" ]
85 changes: 75 additions & 10 deletions app/api/get-user/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,12 @@ async function findAsyncSequential<T>(
return undefined;
}

export async function POST(request: Request) {
type DCAOrder = {
amount: string;
sellToken: { address: string; decimals: number };
};

export async function GET(request: Request) {
const payload = await request.json();
const headers = request.headers;
const url = new URL(request.url);
Expand All @@ -46,23 +51,83 @@ export async function POST(request: Request) {
id: walletAddress.toLowerCase(),
startTime_gte: +startTime,
})) as {
dcaorders: {
amount: string;
sellToken: { address: string; decimals: number };
}[];
dcaorders: DCAOrder[];
};

const getUSDPriceMoralis = async (order: DCAOrder): Promise<number> => {
const response = await Moralis.EvmApi.token.getTokenPrice({
chain: "0xa4b1",
address: order.sellToken.address,
});

return response.raw.usdPrice;
};

const getUSDPriceMobula = async (order: DCAOrder): Promise<number> => {
const response = await fetch(
`https://api.mobula.io/api/1/market/data?asset=${order.sellToken.address}&blockchain=42161`,
{
method: "GET",
headers: {
Authorization: process.env.MOBULA_API_KEY || "",
},
}
);

const data = await response.json();

return data.data.price;
};

const getUSDPriceCoinGecko = async (order: DCAOrder): Promise<number> => {
const url = `https://api.coingecko.com/api/v3/simple/token_price/arbitrum-one?contract_addresses=${order.sellToken.address}&vs_currencies=usd`;

const response = await fetch(url, {
method: "GET",
headers: {
accept: "application/json",
"x-cg-api-key": process.env.COINGECKO_API_KEY || "",
},
});

const data = await response.json();

return data[order.sellToken.address.toLowerCase()].usd;
};

const getUSDPricePortals = async (order: DCAOrder): Promise<number> => {
const url = `https://api.portals.fi/v2/tokens?ids=arbitrum:${order.sellToken.address}`;

const response = await fetch(url, {
method: "GET",
headers: {
Authorization: process.env.PORTALS_API_KEY || "",
},
});

const data = await response.json();

return data.tokens[0].price;
};

const getPrice = (order: DCAOrder) => {
const optionNumber = Math.floor(Math.random() * 100);

// use mobula and portals more frequently since they have better plans
if (optionNumber > 50) return getUSDPriceMobula(order);
else if (optionNumber > 25) return getUSDPricePortals(order);
else if (optionNumber > 10) return getUSDPriceCoinGecko(order);
else return getUSDPriceCoinGecko(order);
};

const result = await findAsyncSequential(
userOrders.dcaorders,
async (order) => {
try {
const tokenAmount = formatEther(BigInt(order.amount));
const response = await Moralis.EvmApi.token.getTokenPrice({
chain: "0xa4b1",
address: order.sellToken.address,
});
const usdPrice = await getPrice(order);

const stackValue = response.raw.usdPrice * +tokenAmount;
const stackValue = usdPrice * +tokenAmount;
if (stackValue >= +minmumValue) return true;

return false;
Expand Down
Binary file modified bun.lockb
Binary file not shown.
22 changes: 22 additions & 0 deletions fly.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# fly.toml app configuration file generated for zealy-api on 2024-08-05T11:12:59+01:00
#
# See https://fly.io/docs/reference/configuration/ for information about how to use this file.
#

app = 'zealy-api'
primary_region = 'mad'

[build]

[http_service]
internal_port = 3000
force_https = true
auto_stop_machines = 'stop'
auto_start_machines = true
min_machines_running = 0
processes = ['app']

[[vm]]
memory = '1gb'
cpu_kind = 'shared'
cpus = 1
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@
"viem": "^2.16.5"
},
"devDependencies": {
"typescript": "^5",
"@flydotio/dockerfile": "latest",
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.4"
"eslint-config-next": "14.2.4",
"typescript": "^5"
}
}

0 comments on commit 51bd40c

Please sign in to comment.