Skip to content

Commit 7f0858a

Browse files
committed
Merge branch 'feat/images-api'
2 parents dafb543 + a9d63b4 commit 7f0858a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1174
-12
lines changed

dextools-api/Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ COPY package*.json ./
1111
RUN npm ci --only=production
1212

1313
COPY . .
14+
COPY public ./public
1415

1516
USER node
1617

dextools-api/index.js

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
require("dotenv").config();
2+
const path = require("path");
23
const express = require("express");
34
const cors = require("cors");
45
const helmet = require("helmet");
@@ -16,6 +17,7 @@ const getConfig = require("./src/udf/getConfig");
1617
const getSymbols = require("./src/udf/getSymbols");
1718
const getHistory = require("./src/udf/getHistory");
1819
const { getQuote, getFiatCurrencyLimits } = require("./src/api/fiatOnRamp");
20+
const { getTokenIcon } = require("./src/api/getTokenIcon");
1921

2022
const app = express();
2123

@@ -24,6 +26,7 @@ app.use(helmet());
2426
app.use(morgan("dev"));
2527
app.use(compression());
2628
app.use(express.json());
29+
app.use("/public", express.static(path.join(__dirname, "public")));
2730

2831
const asyncHandler = (fn) => async (req, res, next) => {
2932
try {
@@ -49,6 +52,48 @@ app.get("/api/transactions", asyncHandler(getTransactions));
4952
app.post("/api/fiat-on-ramp/quote", asyncHandler(getQuote));
5053
app.get("/api/fiat-on-ramp/currencies", asyncHandler(getFiatCurrencyLimits));
5154

55+
app.get("/api/token-icon", async (req, res, next) => {
56+
try {
57+
const result = await getTokenIcon(req.query);
58+
59+
if (!result.success) {
60+
return res.status(404).json({ error: "Icon not found" });
61+
}
62+
63+
const ext = path.extname(result.iconPath).toLowerCase();
64+
const mimeTypes = {
65+
".png": "image/png",
66+
".jpg": "image/jpeg",
67+
".jpeg": "image/jpeg",
68+
".svg": "image/svg+xml",
69+
".webp": "image/webp",
70+
".gif": "image/gif",
71+
};
72+
73+
const mimeType = mimeTypes[ext] || "image/png";
74+
const fileName = path.basename(result.iconPath);
75+
const tokenName = result.token.includes(".")
76+
? result.token.split(".").pop()
77+
: result.token;
78+
79+
res.setHeader("Content-Type", mimeType);
80+
res.setHeader("Cache-Control", "public, max-age=3600");
81+
res.setHeader(
82+
"Content-Disposition",
83+
`inline; filename="${tokenName}-icon${ext}"`
84+
);
85+
86+
if (result.fallback) {
87+
res.setHeader("X-Fallback", "true");
88+
}
89+
90+
res.sendFile(result.iconPath);
91+
} catch (error) {
92+
console.error("Error serving token icon:", error);
93+
res.status(500).json({ error: error.message });
94+
}
95+
});
96+
5297
app.get("/health", async (req, res) => {
5398
try {
5499
const { query } = require("./clients/pg");
Lines changed: 144 additions & 0 deletions
Loading

dextools-api/public/token-icons/ark.svg

Lines changed: 3 additions & 0 deletions
Loading
16.5 KB
Loading
567 KB
Loading

dextools-api/public/token-icons/babena.svg

Lines changed: 1 addition & 0 deletions
Loading
65.8 KB
Loading
Lines changed: 129 additions & 0 deletions
Loading

0 commit comments

Comments
 (0)