-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
## Title: | ||
<!--please follow this pattern for PR title "protocol_name : protocol_category : other comments". Example - "uniswap: dex : tvl by user"--> | ||
- [ ] Pattern for PR title "protocol_name : protocol_category : other comments". Example - "uniswap: dex : tvl by user" | ||
|
||
## Checklist before requesting a review | ||
1. **index.ts file** | ||
|
||
- [ ] **Contains function** | ||
|
||
```export const getUserTVLByBlock = async (blocks: BlockData) => { | ||
const { blockNumber, blockTimestamp } = blocks | ||
// Retrieve data using block number and timestamp | ||
// YOUR LOGIC HERE | ||
return csvRows | ||
|
||
}; | ||
``` | ||
- [ ] **getUserTVLByBlock function takes input with this schema** | ||
|
||
``` | ||
interface BlockData { | ||
blockNumber: number; | ||
blockTimestamp: number; | ||
} | ||
``` | ||
- [ ] **getUserTVLByBlock function returns output in this schema** | ||
|
||
``` | ||
const csvRows: OutputDataSchemaRow[] = []; | ||
|
||
type OutputDataSchemaRow = { | ||
block_number: number; //block_number which was given as input | ||
timestamp: number; // block timestamp which was given an input, epoch format | ||
user_address: string; // wallet address, all lowercase | ||
token_address: string; // token address all lowercase | ||
token_balance: bigint; // token balance, raw amount. Please dont divide by decimals | ||
token_symbol: string; //token symbol should be empty string if it is not available | ||
usd_price: number; //assign 0 if not available | ||
}; | ||
``` | ||
- [ ] **contains function** | ||
|
||
``` | ||
const readBlocksFromCSV = async (filePath: string): Promise<BlockData[]> => { | ||
const blocks: BlockData[] = []; | ||
|
||
await new Promise<void>((resolve, reject) => { | ||
fs.createReadStream(filePath) | ||
.pipe(csv()) // Specify the separator as '\t' for TSV files | ||
.on('data', (row) => { | ||
const blockNumber = parseInt(row.number, 10); | ||
const blockTimestamp = parseInt(row.timestamp, 10); | ||
if (!isNaN(blockNumber) && blockTimestamp) { | ||
blocks.push({ blockNumber: blockNumber, blockTimestamp }); | ||
} | ||
}) | ||
.on('end', () => { | ||
resolve(); | ||
}) | ||
.on('error', (err) => { | ||
reject(err); | ||
}); | ||
}); | ||
|
||
return blocks; | ||
}; | ||
|
||
``` | ||
- [ ] **has this code** | ||
|
||
``` | ||
readBlocksFromCSV('hourly_blocks.csv').then(async (blocks: any[]) => { | ||
console.log(blocks); | ||
const allCsvRows: any[] = []; | ||
|
||
for (const block of blocks) { | ||
try { | ||
const result = await getUserTVLByBlock(block); | ||
allCsvRows.push(...result); | ||
} catch (error) { | ||
console.error(`An error occurred for block ${block}:`, error); | ||
} | ||
} | ||
await new Promise((resolve, reject) => { | ||
const ws = fs.createWriteStream(`outputData.csv`, { flags: 'w' }); | ||
write(allCsvRows, { headers: true }) | ||
.pipe(ws) | ||
.on("finish", () => { | ||
console.log(`CSV file has been written.`); | ||
resolve; | ||
}); | ||
}); | ||
|
||
}).catch((err) => { | ||
console.error('Error reading CSV file:', err); | ||
}); | ||
``` | ||
2. **Output data** | ||
- [ ] Data is returned for underlying tokens only. Not for special tokens (lp/veTokens etc) | ||
- [ ] Follows the exact sequence mentioned in OutputDataSchemaRow . This is needed as we want same column ordering in output csv | ||
- Value of each field is : | ||
- [ ] block_number *is same as input block number. This signifies TVL is as of this block_number.* | ||
- [ ] timestamp is same as input timestamp. This signifies TVL is as of this timestamp. It is in epoch format. | ||
- [ ] user_address is in lowercase | ||
- [ ] token_address is in lowercase | ||
- [ ] token_balance is in raw amount. Please dont divide by decimals. | ||
- [ ] token_symbol value if present, empty string if value is not available. | ||
- [ ] usd_price if value is available, 0 if value is not available. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
name: Trigger deployment to production | ||
|
||
on: | ||
push: | ||
branches: | ||
- main | ||
paths: | ||
- adapters/** | ||
|
||
jobs: | ||
deploy-docker-image: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- name: Trigger workflow | ||
uses: peter-evans/repository-dispatch@v2 | ||
with: | ||
token: ${{ secrets.GH_PAT }} | ||
repository: delta-hq/openblocklabs-airflow-mwaa | ||
event-type: trigger-workflow | ||
client-payload: '{"ref": "main", "ENV": "prod"}' |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "clip-finance", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"start": "node dist/index.js", | ||
"compile": "tsc", | ||
"watch": "tsc -w", | ||
"clear": "rm -rf dist" | ||
}, | ||
"keywords": [], | ||
"author": "", | ||
"license": "ISC", | ||
"dependencies": { | ||
"@types/big.js": "^6.2.2", | ||
"big.js": "^6.2.1", | ||
"bignumber.js": "^9.1.2", | ||
"csv-parser": "^3.0.0", | ||
"decimal.js-light": "^2.5.1", | ||
"fast-csv": "^5.0.1", | ||
"jsbi": "^4.3.0", | ||
"tiny-invariant": "^1.3.1", | ||
"toformat": "^2.0.0", | ||
"viem": "^2.8.13" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^20.11.17", | ||
"typescript": "^5.3.3" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import { getTimestampAtBlock, getUserBalanceSnapshotAtBlock } from "./sdk/subgraphDetails"; | ||
import fs from 'fs'; | ||
import csv from 'csv-parser'; | ||
import { write } from 'fast-csv'; | ||
|
||
interface CSVRow { | ||
block_number: number; | ||
timestamp: number; | ||
user_address: string; | ||
token_address: string; | ||
token_balance: bigint; | ||
token_symbol: string; | ||
usd_price: number | ||
} | ||
|
||
interface BlockData { | ||
blockNumber: number; | ||
blockTimestamp: number; | ||
} | ||
|
||
export const getUserTVLByBlock = async (blocks: BlockData) => { | ||
const { blockNumber, blockTimestamp } = blocks; | ||
const snapshotBlocks: number[] = [blockNumber]; | ||
|
||
const csvRows: CSVRow[] = []; | ||
|
||
for (const block of snapshotBlocks) { | ||
let snapshots = await getUserBalanceSnapshotAtBlock(block, ""); | ||
|
||
// const timestamp = await getTimestampAtBlock(block); | ||
|
||
for (const snapshot of snapshots) { | ||
const csvRow: CSVRow = { | ||
block_number: block, | ||
timestamp: blockTimestamp, | ||
user_address: snapshot.id, | ||
token_address: snapshot.token, | ||
token_balance: BigInt(snapshot.balance.toString()), | ||
token_symbol: snapshot.tokenSymbol, | ||
usd_price: 0 | ||
}; | ||
csvRows.push(csvRow); | ||
} | ||
} | ||
|
||
console.log("Total rows:", csvRows.length); | ||
|
||
return csvRows; | ||
}; | ||
|
||
const readBlocksFromCSV = async (filePath: string): Promise<BlockData[]> => { | ||
const blocks: BlockData[] = []; | ||
|
||
await new Promise<void>((resolve, reject) => { | ||
fs.createReadStream(filePath) | ||
.pipe(csv()) // Specify the separator as '\t' for TSV files | ||
.on('data', (row) => { | ||
|
||
const blockNumber = parseInt(row.number, 10); | ||
const blockTimestamp = parseInt(row.timestamp, 10); | ||
if (!isNaN(blockNumber) && blockTimestamp) { | ||
blocks.push({ blockNumber: blockNumber, blockTimestamp }); | ||
} | ||
}) | ||
.on('end', () => { | ||
resolve(); | ||
}) | ||
.on('error', (err) => { | ||
reject(err); | ||
}); | ||
}); | ||
|
||
return blocks; | ||
}; | ||
|
||
readBlocksFromCSV('hourly_blocks.csv').then(async (blocks: any[]) => { | ||
console.log(blocks); | ||
const allCsvRows: any[] = []; | ||
|
||
for (const block of blocks) { | ||
try { | ||
const result = await getUserTVLByBlock(block); | ||
allCsvRows.push(...result); | ||
} catch (error) { | ||
console.error(`An error occurred for block ${block}:`, error); | ||
} | ||
} | ||
await new Promise((resolve, reject) => { | ||
const ws = fs.createWriteStream(`outputData.csv`, { flags: 'w' }); | ||
write(allCsvRows, { headers: true }) | ||
.pipe(ws) | ||
.on("finish", () => { | ||
console.log(`CSV file has been written.`); | ||
resolve; | ||
}); | ||
}); | ||
|
||
}).catch((err) => { | ||
console.error('Error reading CSV file:', err); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export const enum CHAINS { | ||
LINEA = 59144, | ||
} | ||
|
||
export const SUBGRAPH_URLS = { | ||
[CHAINS.LINEA]: | ||
"https://api.goldsky.com/api/public/project_cltzfe75l0y4u01s98n3c7fmu/subgraphs/clip-finance-shares-token/v2.4/gn", | ||
}; | ||
|
||
export const RESERVE_SUBGRAPH_URLS = { | ||
[CHAINS.LINEA]: | ||
"https://api.goldsky.com/api/public/project_cltzfe75l0y4u01s98n3c7fmu/subgraphs/clip-finance-shares-token/v2.5/gn", | ||
|
||
} | ||
|
||
export const RPC_URLS = { | ||
[CHAINS.LINEA]: | ||
"https://rpc.linea.build", | ||
}; |