Skip to content

Commit d4e8667

Browse files
committed
feat(erc-20): separate and cache initial load
1 parent 65fdfb0 commit d4e8667

File tree

4 files changed

+259
-191
lines changed

4 files changed

+259
-191
lines changed

examples/api/src/app/api/erc-20/lib/utils.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ export async function getFollowingHolderInfo({
6565
fid: string;
6666
tokenAddress: string;
6767
blockchain: string;
68-
}): Promise<{ user: FarcasterUser; amount: number }[]> {
68+
}): Promise<{
69+
holders: { user: FarcasterUser; amount: number }[];
70+
holdersCount: number;
71+
}> {
6972
const acc: any[] = [];
7073

7174
let hasNextPage = true;
@@ -118,7 +121,7 @@ export async function getFollowingHolderInfo({
118121
})
119122
.sort((a, b) => Number(b.amount) - Number(a.amount));
120123

121-
return result;
124+
return { holders: result, holdersCount: result.length };
122125
}
123126

124127
export async function getPriceData({
@@ -170,7 +173,7 @@ export async function getPriceData({
170173
change24hNumber.toFixed(2)
171174
).toLocaleString();
172175
const change24hFormatted =
173-
change24hNumber > 0 ? `+${change24hPartial}%` : `-${change24hPartial}%`;
176+
change24hNumber > 0 ? `+${change24hPartial}%` : `-${-change24hPartial}%`;
174177

175178
return {
176179
unitPriceUsd: unitPriceUsdFormatted,
@@ -181,6 +184,7 @@ export async function getPriceData({
181184
}
182185

183186
// Use on-chain data as fallback
187+
// TODO: Query uniswap contracts directly
184188
const chain = chainByName[blockchain.toLowerCase()];
185189
const url = `https://api.1inch.dev/price/v1.1/${chain.id}/${tokenAddress}?currency=USD`;
186190
const res = await fetch(url, {
@@ -195,7 +199,7 @@ export async function getPriceData({
195199
};
196200
}
197201

198-
export async function tokenInfo({
202+
export async function getTokenInfo({
199203
tokenAddress,
200204
blockchain,
201205
}: {
Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,66 +1,75 @@
1-
import { NextRequest, NextResponse } from "next/server";
1+
import { NextRequest } from "next/server";
22
import {
33
getFollowingHolderInfo,
44
getPriceData,
55
parseTokenParam,
6-
tokenInfo,
6+
getTokenInfo,
77
} from "./lib/utils";
88

99
export async function GET(request: NextRequest) {
10-
const fid = request.nextUrl.searchParams.get("fid")?.toLowerCase();
10+
const fid = request.nextUrl.searchParams.get("fid");
1111
const token = request.nextUrl.searchParams.get("token")?.toLowerCase();
1212
let tokenAddress = request.nextUrl.searchParams
1313
.get("tokenAddress")
1414
?.toLowerCase();
1515
let blockchain = request.nextUrl.searchParams
1616
.get("blockchain")
1717
?.toLowerCase();
18+
const methodName = request.nextUrl.searchParams
19+
.get("function")
20+
?.toLowerCase();
1821

1922
if (token) {
2023
const parsedToken = parseTokenParam(token);
2124
tokenAddress = parsedToken.tokenAddress;
2225
blockchain = parsedToken.blockchain;
2326
}
2427

25-
if (!tokenAddress) {
26-
return NextResponse.json({
27-
error: "Missing tokenAddress",
28-
});
29-
}
28+
const { fn, options } = {
29+
holders: {
30+
fn: getFollowingHolderInfo,
31+
options: {
32+
headers: new Headers({
33+
"Cache-Control": "public, max-age=3600, immutable",
34+
}),
35+
},
36+
},
37+
price: {
38+
fn: getPriceData,
39+
options: {
40+
headers: new Headers({
41+
"Cache-Control": "public, max-age=3600, immutable",
42+
}),
43+
},
44+
},
45+
token: {
46+
fn: getTokenInfo,
47+
options: {
48+
headers: new Headers({
49+
"Cache-Control": "public, max-age=3600, immutable",
50+
}),
51+
},
52+
},
53+
}[methodName];
3054

31-
if (!blockchain) {
32-
return NextResponse.json({
33-
error: "Missing or invalid blockchain",
55+
if (!fn) {
56+
return Response.json({
57+
error: "Invalid function",
3458
});
3559
}
3660

37-
const [holderData, priceData, tokenData] = await Promise.all([
38-
getFollowingHolderInfo({
39-
blockchain: blockchain,
40-
tokenAddress: tokenAddress,
41-
fid: fid,
42-
}),
43-
getPriceData({
44-
blockchain: blockchain,
45-
tokenAddress: tokenAddress,
46-
}),
47-
tokenInfo({
48-
tokenAddress,
49-
blockchain,
50-
}),
51-
]);
61+
const result = await fn({
62+
fid,
63+
tokenAddress,
64+
blockchain,
65+
});
5266

53-
return NextResponse.json({
54-
holderData: {
55-
holders: [...(holderData || [])],
56-
holdersCount: holderData?.length || 0,
57-
},
58-
priceData,
59-
tokenData,
67+
return Response.json(result, {
68+
...options,
6069
});
6170
}
6271

6372
// needed for preflight requests to succeed
6473
export const OPTIONS = async (request: NextRequest) => {
65-
return NextResponse.json({});
74+
return Response.json({});
6675
};

mods/erc-20/src/buying.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ const buy: ModElement[] = [
1313
{
1414
type: "text",
1515
label:
16-
"Buying ~${{refs.buyAmountUsd}} of {{refs.tokenReq.response.data.tokenData.name}}...",
16+
"Buying ~${{refs.buyAmountUsd}} of {{refs.tokenReq.response.data.name}}...",
17+
variant: "secondary",
1718
},
1819
],
1920
},
@@ -37,7 +38,7 @@ const buy: ModElement[] = [
3738
],
3839
},
3940
{
40-
type: "horizontal-layout",
41+
type: "vertical-layout",
4142
onload: {
4243
type: "POST",
4344
url: "{{api}}/erc-20/buy?walletAddress={{user.wallet.address}}&token={{embed.url}}&buyAmountUsd={{refs.buyAmountUsd}}",

0 commit comments

Comments
 (0)