turn cropper dex to be on chain

This commit is contained in:
g1nt0ki
2022-11-25 15:55:03 +01:00
parent cc02a27b84
commit fe5815cc9a
9 changed files with 68 additions and 109 deletions

View File

@@ -15,7 +15,6 @@
"dependencies": {
"@defillama/sdk": "latest",
"@project-serum/anchor": "^0.25.0",
"@project-serum/borsh": "^0.2.5",
"@solana/spl-token": "^0.3.0",
"@solana/web3.js": "^1.36.0",
"@solendprotocol/solend-sdk": "^0.6.2",

View File

@@ -1,17 +1,11 @@
const retry = require('./helper/retry')
const { GraphQLClient, gql } = require('graphql-request')
async function fetch() {
var endpoint = 'https://cache.bondappetit.io/api'
var graphQLClient = new GraphQLClient(endpoint)
var query = gql`
{
getTVL
}
`;
var results = await retry(async bail => await graphQLClient.request(query))
var query = gql` { getTVL } `;
var results = await graphQLClient.request(query)
return parseFloat(results.getTVL)
}

View File

@@ -1,10 +1,7 @@
const retry = require('./helper/retry')
const axios = require("axios");
const { get } = require('./helper/http')
async function fetch() {
var response = await retry(async bail => await axios.get('https://btn.group/pools/tvl'))
return response.data;
return get('https://btn.group/pools/tvl')
}
module.exports = {

View File

@@ -1,13 +1,8 @@
const axios = require("axios");
const retry = require("./helper/retry");
const http = require("./helper/http");
async function staking() {
const response = (
await retry(async (bail) => await axios.get("https://treasury-app.coti.io/get-total"))
).data;
return {
'coti': Number(response.totalCotiInPool).toFixed(0),
'coti': Number((await http.get("https://treasury-app.coti.io/get-total")).totalCotiInPool).toFixed(0),
};
};

View File

@@ -1,14 +1,7 @@
const retry = require("./helper/retry");
const axios = require("axios");
const { get } = require('./helper/http')
async function fetch() {
const response = (
await retry(
async () => await axios.get("https://api.crema.finance/v1/swap/count")
)
).data;
const tvl = response.data.tvl_in_usd;
return tvl;
return (await get("https://api.crema.finance/v1/swap/count")).data.tvl_in_usd;
}
module.exports = {

View File

@@ -1,19 +1,6 @@
const retry = require("./helper/retry");
const axios = require("axios");
const { toUSDTBalances } = require("./helper/balances");
const { getTokenBalance } = require("./helper/solana");
async function fetch() {
const response = (
await retry(async (bail) => await axios.get("https://api.cropper.finance/cmc/pools"))
).data;
const liqArrPerPool = Object.values(response).map((pool) => pool.tvl);
const dexTvl = liqArrPerPool.reduce((a, b) => a + b, 0)
return toUSDTBalances(dexTvl);
}
const { getTokenBalance, getConnection, exportDexTVL, } = require("./helper/solana");
const { PublicKey } = require('@solana/web3.js')
const DEX_PROGRAM_ID = 'CTMAxxk34HjKWxQ3QLZK1HpaLXmBveao3ESePXbiyfzh'
async function fetchStaking() {
return {
@@ -21,11 +8,31 @@ async function fetchStaking() {
};
}
async function getTokenAccounts() {
// structure taken from https://github.com/CropperFinance/cropper_instructions/blob/main/amm-instructions/amm_stats.rs#L323
const programId = new PublicKey(DEX_PROGRAM_ID);
const connection = getConnection();
const accounts = await connection.getProgramAccounts(programId, {
filters: [{
dataSize: 291
}]
});
const tokenAccounts = []
accounts.forEach(({ account: { data }}) => {
let i = 3 + 32 * 4 // offset
const tokenAccountA = new PublicKey(data.subarray(i, i+32)).toString()
i += 32
const tokenAccountB= new PublicKey(data.subarray(i, i+32)).toString()
tokenAccounts.push(tokenAccountA, tokenAccountB)
})
return tokenAccounts
}
module.exports = {
timetravel: false,
misrepresentedTokens: true,
solana: {
tvl: fetch,
tvl: exportDexTVL(DEX_PROGRAM_ID, getTokenAccounts),
staking: fetchStaking
}
}; // node test.js projects/cropper.js

View File

@@ -1,16 +1,6 @@
const { PublicKey, } = require("@solana/web3.js");
const { getConnection, sumTokens2, } = require("../helper/solana");
const { getConnection, sumTokens2, readBigUInt64LE, } = require("../helper/solana");
function readBigUInt64LE(buffer, offset) {
const first = buffer[offset];
const last = buffer[offset + 7];
if (first === undefined || last === undefined) {
throw new Error();
}
const lo = first + buffer[++offset] * 2 ** 8 + buffer[++offset] * 2 ** 16 + buffer[++offset] * 2 ** 24;
const hi = buffer[++offset] + buffer[++offset] * 2 ** 8 + buffer[++offset] * 2 ** 16 + last * 2 ** 24;
return BigInt(lo) + (BigInt(hi) << BigInt(32));
}
async function tvl() {
const connection = getConnection();

View File

@@ -256,8 +256,28 @@ async function sumOrcaLPs(tokensAndAccounts) {
return totalUsdValue;
}
function exportDexTVL(DEX_PROGRAM_ID) {
function exportDexTVL(DEX_PROGRAM_ID, getTokenAccounts) {
return async () => {
if (!getTokenAccounts) getTokenAccounts = _getTokenAccounts
const tokenAccounts = await getTokenAccounts()
const chunks = sliceIntoChunks(tokenAccounts, 99)
const results = []
for (const chunk of chunks)
results.push(...await getTokenAccountBalances(chunk, { individual: true }))
const data = []
for (let i = 0; i < results.length; i = i + 2) {
const tokenA = results[i]
const tokenB = results[i + 1]
data.push({ token0: tokenA.mint, token0Bal: tokenA.amount, token1: tokenB.mint, token1Bal: tokenB.amount, })
}
return transformDexBalances({ chain: 'solana', data, blacklistedTokens, })
}
async function _getTokenAccounts() {
const connection = getConnection()
const TokenSwapLayout = BufferLayout.struct([
@@ -293,19 +313,7 @@ function exportDexTVL(DEX_PROGRAM_ID) {
tokenAccounts.push(new PublicKey(tokenSwap.tokenAccountB).toString())
});
const chunks = sliceIntoChunks(tokenAccounts, 99)
const results = []
for (const chunk of chunks)
results.push(...await getTokenAccountBalances(chunk, { individual: true }))
const data = []
for (let i = 0; i < results.length; i = i + 2) {
const tokenA = results[i]
const tokenB = results[i + 1]
data.push({ token0: tokenA.mint, token0Bal: tokenA.amount, token1: tokenB.mint, token1Bal: tokenB.amount, })
}
return transformDexBalances({ chain: 'solana', data, blacklistedTokens, })
return tokenAccounts
}
}
@@ -370,6 +378,17 @@ async function transformBalances({ tokenBalances, balances = {}, }) {
return balances
}
function readBigUInt64LE(buffer, offset) {
const first = buffer[offset];
const last = buffer[offset + 7];
if (first === undefined || last === undefined) {
throw new Error();
}
const lo = first + buffer[++offset] * 2 ** 8 + buffer[++offset] * 2 ** 16 + buffer[++offset] * 2 ** 24;
const hi = buffer[++offset] + buffer[++offset] * 2 ** 8 + buffer[++offset] * 2 ** 16 + last * 2 ** 24;
return BigInt(lo) + (BigInt(hi) << BigInt(32));
}
module.exports = {
endpoint,
tokens,
@@ -396,4 +415,5 @@ module.exports = {
getTokenAccountBalances,
getTokenList,
getSolTokenMap,
readBigUInt64LE,
};

View File

@@ -1,48 +1,12 @@
const { PublicKey } = require("@solana/web3.js");
const { getConnection } = require("../helper/solana");
const { publicKey, struct, u64, u8, option, } = require('@project-serum/borsh')
const feeFields = [u64('denominator'), u64('numerator')];
const StakePoolLayout = struct([
u8('accountType'),
publicKey('manager'),
publicKey('staker'),
publicKey('stakeDepositAuthority'),
u8('stakeWithdrawBumpSeed'),
publicKey('validatorList'),
publicKey('reserveStake'),
publicKey('poolMint'),
publicKey('managerFeeAccount'),
publicKey('tokenProgramId'),
u64('totalLamports'),
u64('poolTokenSupply'),
u64('lastUpdateEpoch'),
struct([u64('unixTimestamp'), u64('epoch'), publicKey('custodian')], 'lockup'),
struct(feeFields, 'epochFee'),
option(struct(feeFields), 'nextEpochFee'),
option(publicKey(), 'preferredDepositValidatorVoteAddress'),
option(publicKey(), 'preferredWithdrawValidatorVoteAddress'),
struct(feeFields, 'stakeDepositFee'),
struct(feeFields, 'stakeWithdrawalFee'),
option(struct(feeFields), 'nextStakeWithdrawalFee'),
u8('stakeReferralFee'),
option(publicKey(), 'solDepositAuthority'),
struct(feeFields, 'solDepositFee'),
u8('solReferralFee'),
option(publicKey(), 'solWithdrawAuthority'),
struct(feeFields, 'solWithdrawalFee'),
option(struct(feeFields), 'nextSolWithdrawalFee'),
u64('lastEpochPoolTokenSupply'),
u64('lastEpochTotalLamports'),
])
async function tvl() {
// https://jito.network/staking
const connection = getConnection();
const account = await connection.getAccountInfo(new PublicKey('Jito4APyf642JPZPx3hGc6WWJ8zPKtRbRs4P815Awbb'))
const decodedData = StakePoolLayout.decode(account.data)
return {
solana: decodedData.totalLamports/1e9
solana: Number(account.data.readBigUint64LE(258))/1e9
}
}