Skip to content

Commit aa653a8

Browse files
treeoflife2g1nt0ki
andauthored
Feat: Prefetch Function Support in Adapter (#3027)
* Feat: Prefetch Function Support in Adapter * remove unused vars * type error * Fix: remove timestamp from prefetch * Fix * minor fix --------- Co-authored-by: g1nt0ki <[email protected]>
1 parent bc04e2d commit aa653a8

File tree

4 files changed

+77
-27
lines changed

4 files changed

+77
-27
lines changed

adapters/types.ts

+2
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ export type FetchOptions = {
3939
getStartBlock: () => Promise<number>,
4040
getEndBlock: () => Promise<number>,
4141
dateString: string,
42+
preFetchedResults?: any,
4243
}
4344

4445
export type FetchGetLogsOptions = {
@@ -98,6 +99,7 @@ export type AdapterBase = {
9899
protocolType?: ProtocolType;
99100
version?: number;
100101
deadFrom?: string;
102+
prefetch?: FetchV2;
101103
}
102104

103105
export type SimpleAdapter = AdapterBase & {

adapters/utils/runAdapter.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,9 @@ function getUnixTimeNow() {
1717
export default async function runAdapter(volumeAdapter: BaseAdapter, cleanCurrentDayTimestamp: number, chainBlocks: ChainBlocks, id?: string, version?: string, {
1818
adapterVersion = 1,
1919
isTest = false,
20+
_module = {},
2021
}: any = {}) {
21-
22+
const prefetch = _module?.prefetch
2223
const closeToCurrentTime = Math.trunc(Date.now() / 1000) - cleanCurrentDayTimestamp < 24 * 60 * 60 // 12 hours
2324
const chains = Object.keys(volumeAdapter).filter(c => c !== DISABLED_ADAPTER_KEY)
2425
const validStart = {} as {
@@ -29,6 +30,16 @@ export default async function runAdapter(volumeAdapter: BaseAdapter, cleanCurren
2930
}
3031
await Promise.all(chains.map(setChainValidStart))
3132

33+
// Run prefetch if provided
34+
let preFetchedResults: any = null;
35+
if (typeof prefetch === 'function') {
36+
const firstChain = chains.find(chain => validStart[chain]?.canRun);
37+
if (firstChain) {
38+
const options = await getOptionsObject(cleanCurrentDayTimestamp, firstChain, chainBlocks);
39+
preFetchedResults = await prefetch(options);
40+
}
41+
}
42+
3243
const response = await Promise.all(chains.filter(chain => {
3344
const res = validStart[chain]?.canRun
3445
if (isTest && !res) console.log(`Skipping ${chain} because the configured start time is ${new Date(validStart[chain]?.startTimestamp * 1e3).toUTCString()} \n\n`)
@@ -49,6 +60,10 @@ export default async function runAdapter(volumeAdapter: BaseAdapter, cleanCurren
4960
const fetchFunction = volumeAdapter[chain].customBackfill ?? volumeAdapter[chain].fetch
5061
try {
5162
const options = await getOptionsObject(cleanCurrentDayTimestamp, chain, chainBlocks)
63+
if (preFetchedResults !== null) {
64+
options.preFetchedResults = preFetchedResults;
65+
}
66+
5267
let result: any
5368
if (adapterVersion === 1) {
5469
result = await (fetchFunction as Fetch)(options.toTimestamp, chainBlocks, options);

cli/testAdapter.ts

+2
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const passedFile = path.resolve(process.cwd(), `./${adapterType}/${process.argv[
8383
// Get adapter
8484
const volumes = await runAdapter(adapter, endTimestamp, chainBlocks, undefined, undefined, {
8585
adapterVersion,
86+
_module: module,
8687
})
8788
printVolumes(volumes, adapter)
8889
console.info("\n")
@@ -91,6 +92,7 @@ const passedFile = path.resolve(process.cwd(), `./${adapterType}/${process.argv[
9192
const allVolumes = await Promise.all(Object.entries(breakdownAdapter).map(([version, adapter]) =>
9293
runAdapter(adapter, endTimestamp, chainBlocks, undefined, undefined, {
9394
adapterVersion,
95+
prefetch: adapter?.prefetch,
9496
isTest: true,
9597
}).then(res => ({ version, res }))
9698
))

fees/rainbow-wallet.ts

+57-26
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,62 @@
1-
import { Adapter, FetchOptions, FetchResultFees } from "../adapters/types";
1+
import { Adapter, FetchOptions, } from "../adapters/types";
22
import { CHAIN } from "../helpers/chains";
3-
import { getTokenDiff } from "../helpers/token";
3+
import { queryDuneSql } from "../helpers/dune";
44

55
const rainbowRouter = '0x00000000009726632680fb29d3f7a9734e3010e2'
66

7-
const fetch: any = async (timestamp: number, _: any, options: FetchOptions) => {
8-
const { createBalances, getLogs, } = options
9-
const dailyFees = createBalances()
10-
11-
const ethLogs = await getLogs({ target: rainbowRouter, eventAbi: 'event EthWithdrawn(address indexed target, uint256 amount)' })
12-
const tokenLogs = await getLogs({ target: rainbowRouter, eventAbi: 'event TokenWithdrawn(address indexed token, address indexed target, uint256 amount)' })
13-
let extraTokens = new Set<string>()
7+
const RainBowRouter = {
8+
[CHAIN.ETHEREUM]: rainbowRouter,
9+
[CHAIN.OPTIMISM]: rainbowRouter,
10+
[CHAIN.BSC]: rainbowRouter,
11+
[CHAIN.UNICHAIN]: '0x2a0332E28913A06Fa924d40A3E2160f763010417',
12+
[CHAIN.POLYGON]: rainbowRouter,
13+
[CHAIN.BASE]: rainbowRouter,
14+
[CHAIN.ARBITRUM]: rainbowRouter,
15+
[CHAIN.AVAX]: rainbowRouter,
16+
[CHAIN.INK]: rainbowRouter,
17+
[CHAIN.BERACHAIN]: rainbowRouter,
18+
[CHAIN.BLAST]: rainbowRouter,
19+
[CHAIN.ZORA]: '0xA61550E9ddD2797E16489db09343162BE98d9483',
20+
[CHAIN.APECHAIN]: rainbowRouter,
21+
[CHAIN.GRAVITY]: rainbowRouter,
22+
}
1423

15-
ethLogs.forEach((log: any) => dailyFees.addGasToken(log.amount))
16-
tokenLogs.forEach((log: any) => {
17-
extraTokens.add(log.token)
18-
dailyFees.add(log.token, log.amount)
19-
})
24+
// Prefetch function that will run once before any fetch calls
25+
// don't do console.log(options) as there is circular dependency in ChainApi
26+
const prefetch = async (options: FetchOptions) => {
27+
return queryDuneSql(options, `
28+
SELECT
29+
CASE
30+
WHEN blockchain = 'bnb' THEN 'bsc'
31+
WHEN blockchain = 'avalanche_c' THEN 'avax'
32+
ELSE blockchain
33+
END as chain,
34+
sum(amount_usd) as volume,
35+
sum(amount_usd * 0.0085) as fees
36+
FROM dex.trades
37+
WHERE (
38+
(tx_to = 0x00000000009726632680fb29d3f7a9734e3010e2 AND blockchain NOT IN ('unichain', 'zora'))
39+
OR
40+
(tx_to = 0x2a0332E28913A06Fa924d40A3E2160f763010417 AND blockchain = 'unichain')
41+
OR
42+
(tx_to = 0xA61550E9ddD2797E16489db09343162BE98d9483 AND blockchain = 'zora')
43+
)
44+
AND block_time >= from_unixtime(${options.startTimestamp})
45+
AND block_time <= from_unixtime(${options.endTimestamp})
46+
GROUP BY 1
47+
`);
48+
};
2049

21-
await getTokenDiff({ options, target: rainbowRouter, balances: dailyFees, extraTokens: [...extraTokens], })
22-
dailyFees.removeNegativeBalances()
50+
const fetch: any = async (timestamp: number, _: any, options: FetchOptions) => {
51+
const results = options.preFetchedResults || [];
52+
53+
let dailyFees = 0;
54+
for (const result of results) {
55+
if (result.chain === options.chain) {
56+
dailyFees = result.fees;
57+
break;
58+
}
59+
}
2360

2461
return {
2562
timestamp,
@@ -37,16 +74,10 @@ const methodology = {
3774
const chainAdapter = { fetch, start: '2023-01-01', meta: { methodology } }
3875

3976
const adapter: Adapter = {
40-
adapter: {
41-
[CHAIN.ETHEREUM]: chainAdapter,
42-
[CHAIN.OPTIMISM]: chainAdapter,
43-
[CHAIN.ARBITRUM]: chainAdapter,
44-
[CHAIN.POLYGON]: chainAdapter,
45-
[CHAIN.BASE]: chainAdapter,
46-
[CHAIN.BSC]: chainAdapter,
47-
[CHAIN.AVAX]: chainAdapter,
48-
},
49-
77+
adapter: Object.fromEntries(Object.entries(RainBowRouter).map(
78+
([chain]) => [chain, chainAdapter]
79+
)),
80+
prefetch: prefetch,
5081
}
5182

5283
export default adapter;

0 commit comments

Comments
 (0)