Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ monitoring/my-kube-prometheus/manifests
monitoring/my-kube-prometheus/alertmanager-config.yaml

# misc
.DS_Store
.DS_Store
docker-compose.override.yml
1 change: 1 addition & 0 deletions node/proxy/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"@shapeshiftoss/common-api": "^10.0.0",
"bottleneck": "^2.19.5",
"elliptic-sdk": "^0.7.2",
"lru-cache": "^10.2.0",
"viem": "^2.33.2"
}
}
78 changes: 0 additions & 78 deletions node/proxy/api/src/affiliateRevenue/bebop.ts

This file was deleted.

89 changes: 89 additions & 0 deletions node/proxy/api/src/affiliateRevenue/bebop/bebop.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import axios from 'axios'
import { Fees } from '..'
import {
getCacheableThreshold,
getDateEndTimestamp,
getDateStartTimestamp,
groupFeesByDate,
saveCachedFees,
splitDateRange,
tryGetCachedFees,
} from '../cache'
import { SLIP44 } from '../constants'
import { BEBOP_API_KEY, BEBOP_API_URL, FEE_BPS_DENOMINATOR, NANOSECONDS_PER_SECOND, SHAPESHIFT_REFERRER } from './constants'
import type { TradesResponse } from './types'

const fetchFeesFromAPI = async (startTimestamp: number, endTimestamp: number): Promise<Fees[]> => {
const fees: Fees[] = []

const start = startTimestamp * NANOSECONDS_PER_SECOND
const end = endTimestamp * NANOSECONDS_PER_SECOND

const { data } = await axios.get<TradesResponse>(BEBOP_API_URL, {
params: { source: SHAPESHIFT_REFERRER, start, end },
headers: { 'source-auth': BEBOP_API_KEY },
})

for (const trade of data.results) {
if (!trade.partnerFeeBps || !trade.partnerFeeNative) continue

const chainId = `eip155:${trade.chain_id}`
const assetId = `${chainId}/slip44:${SLIP44.ETHEREUM}`

fees.push({
chainId,
assetId,
service: 'bebop',
txHash: trade.txHash,
timestamp: Math.floor(new Date(trade.timestamp).getTime() / 1000),
amount: trade.partnerFeeNative,
amountUsd:
trade.volumeUsd !== undefined ? String(trade.volumeUsd * (Number(trade.partnerFeeBps) / FEE_BPS_DENOMINATOR)) : undefined,
})
}

return fees
}

export const getFees = async (startTimestamp: number, endTimestamp: number): Promise<Fees[]> => {
const threshold = getCacheableThreshold()
const { cacheableDates, recentStart } = splitDateRange(startTimestamp, endTimestamp, threshold)

const cachedFees: Fees[] = []
const datesToFetch: string[] = []
let cacheHits = 0
let cacheMisses = 0

for (const date of cacheableDates) {
const cached = tryGetCachedFees('bebop', 'all', date)
if (cached) {
cachedFees.push(...cached)
cacheHits++
} else {
datesToFetch.push(date)
cacheMisses++
}
}

const newFees: Fees[] = []
if (datesToFetch.length > 0) {
const fetchStart = getDateStartTimestamp(datesToFetch[0])
const fetchEnd = getDateEndTimestamp(datesToFetch[datesToFetch.length - 1])
const fetched = await fetchFeesFromAPI(fetchStart, fetchEnd)

const feesByDate = groupFeesByDate(fetched)
for (const date of datesToFetch) {
saveCachedFees('bebop', 'all', date, feesByDate[date] || [])
}
newFees.push(...fetched)
}

const recentFees: Fees[] = []
if (recentStart !== null) {
recentFees.push(...(await fetchFeesFromAPI(recentStart, endTimestamp)))
}

console.log(`[bebop] Cache stats: ${cacheHits} hits, ${cacheMisses} misses`)

return [...cachedFees, ...newFees, ...recentFees]
}
8 changes: 8 additions & 0 deletions node/proxy/api/src/affiliateRevenue/bebop/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export const BEBOP_API_KEY = process.env.BEBOP_API_KEY

if (!BEBOP_API_KEY) throw new Error('BEBOP_API_KEY env var not set')

export const BEBOP_API_URL = 'https://api.bebop.xyz/history/v2/trades'
export const SHAPESHIFT_REFERRER = 'shapeshift'
export const NANOSECONDS_PER_SECOND = 1_000_000_000
export const FEE_BPS_DENOMINATOR = 10000
1 change: 1 addition & 0 deletions node/proxy/api/src/affiliateRevenue/bebop/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { getFees } from './bebop'
37 changes: 37 additions & 0 deletions node/proxy/api/src/affiliateRevenue/bebop/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
export type TradesResponse = {
results: Array<{
chain_id: number
txHash: string
status: string
type: string
taker: string
receiver: string
sellTokens: Record<string, { amount?: string; amountUsd?: number }>
buyTokens: Record<string, { amount?: string; amountUsd?: number }>
volumeUsd?: number
gasFeeUsd?: number
timestamp: string
route: 'JAM' | 'PMM'
gasless: boolean
partnerFeeNative?: string
partnerFeeBps?: string
}>
nextAvailableTimestamp?: string
metadata: {
timestamp: string
results?: number
tokens: Record<
string,
Record<
string,
{
name: string
symbol: string
decimals: number
displayDecimals?: number
icon?: string
}
>
>
}
}
161 changes: 0 additions & 161 deletions node/proxy/api/src/affiliateRevenue/butterswap.ts

This file was deleted.

Loading