Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
37e007d
feat: implement gas costs
anxolin Apr 8, 2025
7addca9
mock
anxolin Apr 8, 2025
b6baf67
get24hUsdPrice
squadgazzz Apr 8, 2025
858f064
market price and status events mocks (#110)
mrnaveira Apr 8, 2025
17c4be9
Merge branch 'hackathon-mooo' into hackathon/coingecko
squadgazzz Apr 8, 2025
b75b99f
revert
squadgazzz Apr 8, 2025
71e0022
naming
squadgazzz Apr 8, 2025
3d58520
Get order events from DB (#112)
anxolin Apr 8, 2025
3e3c9c9
fetch order and gas amount
mrnaveira Apr 8, 2025
f11c486
Merge branch 'hackathon-mooo' into hackathon/coingecko
squadgazzz Apr 8, 2025
88687e7
coingecko range api
squadgazzz Apr 8, 2025
c957b86
Add gas price data vs=ia prometheus
ahhda Apr 8, 2025
83ba928
rm redundant code
ahhda Apr 8, 2025
0d78aaa
Fix
squadgazzz Apr 8, 2025
74aa1fa
1 day
squadgazzz Apr 8, 2025
d9bd307
todo
squadgazzz Apr 8, 2025
a64d6a7
Merge pull request #114 from cowprotocol/hackathon/coingecko
mrnaveira Apr 8, 2025
923c516
Merge pull request #113 from cowprotocol/gas-prices
ahhda Apr 8, 2025
b982199
Alchemy API
squadgazzz Apr 8, 2025
306b49a
Calculate estimated fill price
anxolin Apr 8, 2025
e41c743
get eth price and sell token prices
mrnaveira Apr 8, 2025
a3d2bea
fix: fix redocly
anxolin Apr 8, 2025
8bcc257
Calculate the prices based on gas costs, gas, price in eth
anxolin Apr 8, 2025
61db043
fix: computation estimated price
anxolin Apr 8, 2025
75b8321
Add more data
anxolin Apr 8, 2025
b75c85e
catch error
anxolin Apr 8, 2025
cb8821f
fix: fix time in gas
anxolin Apr 8, 2025
d9fab64
use all prometheus values
ahhda Apr 8, 2025
166c7b7
get last 24h dates
mrnaveira Apr 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,7 @@
# ETHPLORER_API_KEY=

# MORALIS
# MORALIS_API_KEY=
# MORALIS_API_KEY=

# Alchemy API
# ALCHEMY_API_KEY=
186 changes: 186 additions & 0 deletions apps/api/src/app/routes/__chainId/gas/gasPrice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
import { FastifyPluginAsync } from 'fastify';
import { server } from '../../../../main';
import {
CACHE_CONTROL_HEADER,
getCacheControlHeaderValue,
} from '../../../../utils/cache';
import ms from 'ms';
import { ValuePoint } from '../orders/types';

const CACHE_SECONDS = ms('10m') / 1000;

// Prometheus configuration
const PROMETHEUS_URL = process.env.PROMETHEUS_URL;
const PROMETHEUS_USERNAME = process.env.PROMETHEUS_USERNAME;
const PROMETHEUS_PASSWORD = process.env.PROMETHEUS_PASSWORD;
const GAS_PRICE_QUERY = 'gp_v2_api_gas_price{network="mainnet"}';
const DEFAULT_STEP = '5m'; // Default step interval
const DEFAULT_RANGE = '24h'; // Default time range

interface GasPriceDataPoint {
time: number;
value: string;
}

interface GasPriceResponse {
data: GasPriceDataPoint[];
}

interface PrometheusResponse {
status: string;
data: {
resultType: string;
result: Array<{
metric: Record<string, string>;
values: Array<[number, string]>;
}>;
};
}

/**
* Fetches gas price data from Prometheus using query_range
*/
export async function fetchGasPriceFromPrometheus(
range: string = DEFAULT_RANGE,
step: string = DEFAULT_STEP
): Promise<ValuePoint[] | undefined> {
try {
const query = encodeURIComponent(GAS_PRICE_QUERY);
const url = `${PROMETHEUS_URL}/api/v1/query_range?query=${query}&start=${getStartTime(
range
)}&end=${Math.floor(Date.now() / 1000)}&step=${step}`;

server.log.debug(`Fetching gas price from Prometheus: ${url}`);

// Prepare fetch options with authentication if credentials are provided
const fetchOptions: RequestInit = {};

if (PROMETHEUS_USERNAME && PROMETHEUS_PASSWORD) {
const authHeader =
'Basic ' +
Buffer.from(`${PROMETHEUS_USERNAME}:${PROMETHEUS_PASSWORD}`).toString(
'base64'
);
fetchOptions.headers = {
Authorization: authHeader,
};
}

const response = await fetch(url, fetchOptions);

if (!response.ok) {
server.log.error(
`Failed to fetch gas price from Prometheus: ${response.statusText}`
);
return undefined;
}

const data = (await response.json()) as PrometheusResponse;

if (data.status !== 'success' || !data.data.result.length) {
return undefined;
}

const results = data.data.result;
const values = results.flatMap((result) => result.values);

if (!values || values.length === 0) {
return undefined;
}

// Format data points
const dataPoints = values.map(([timestamp, value]) => ({
time: Math.floor(timestamp) * 1000,
value,
}));

return dataPoints;
} catch (error) {
server.log.error(
`Error fetching gas price from Prometheus: ${
error instanceof Error ? error.message : 'Unknown error'
}`
);
return undefined;
}
}

/**
* Calculate the start time based on the range
*/
function getStartTime(range: string): number {
const now = Math.floor(Date.now() / 1000);
const rangeMs = ms(range);
return now - Math.floor(rangeMs / 1000);
}

const gasPrice: FastifyPluginAsync = async (fastify): Promise<void> => {
fastify.get<{
Reply: GasPriceResponse;
Querystring: {
range?: string;
step?: string;
};
}>(
'/gasPrice',
{
schema: {
description: 'Get the gas price for a given chain',
tags: ['gas'],
querystring: {
type: 'object',
properties: {
range: {
type: 'string',
description: 'Time range to fetch data for (e.g. 1h, 24h, 7d)',
default: DEFAULT_RANGE,
},
step: {
type: 'string',
description: 'Step interval (e.g. 1m, 5m, 1h)',
default: DEFAULT_STEP,
},
},
},
response: {
200: {
type: 'object',
properties: {
data: {
type: 'array',
items: {
type: 'object',
properties: {
time: { type: 'number' },
value: { type: 'string' },
},
},
},
},
},
},
},
},
async function (request, reply) {
reply.header(
CACHE_CONTROL_HEADER,
getCacheControlHeaderValue(CACHE_SECONDS)
);

const { range, step } = request.query;

// Fetch gas price data from Prometheus
const gasPriceData = await fetchGasPriceFromPrometheus(range, step);

if (!gasPriceData) {
return reply.send({ data: [] });
}

return reply.send({
data: gasPriceData,
});
}
);
};

export default gasPrice;
Loading