From b190fb8a7a8b4c2e2c211d8d31b7d2d79798819f Mon Sep 17 00:00:00 2001 From: Matthew Callens Date: Fri, 30 Jun 2023 13:21:59 -0400 Subject: [PATCH] fix market data node bug and system program transfer filter for helius (#4255) --- .../src/routes/graphql/clients/coingecko.ts | 12 +++---- .../src/routes/graphql/clients/helius.ts | 24 ++++++++++---- .../src/routes/graphql/providers/bitcoin.ts | 18 ++++------- .../src/routes/graphql/providers/ethereum.ts | 31 +++++-------------- .../src/routes/graphql/providers/util.ts | 6 ++-- backend/workers/price-indexer/src/types.ts | 12 +++---- 6 files changed, 46 insertions(+), 57 deletions(-) diff --git a/backend/native/backpack-api/src/routes/graphql/clients/coingecko.ts b/backend/native/backpack-api/src/routes/graphql/clients/coingecko.ts index 976cdf1b2..2741063e1 100644 --- a/backend/native/backpack-api/src/routes/graphql/clients/coingecko.ts +++ b/backend/native/backpack-api/src/routes/graphql/clients/coingecko.ts @@ -82,12 +82,12 @@ export type CoinGeckoPriceData = { market_cap_rank: number; fully_filuted_valuation: number; total_volume: number; - high_24h: number; - low_24h: number; - price_change_24h: number; - price_change_percentage_24h: number; - market_cap_change_24h: number; - market_cap_change_percentage_24h: number; + high_24h: number | null; + low_24h: number | null; + price_change_24h: number | null; + price_change_percentage_24h: number | null; + market_cap_change_24h: number | null; + market_cap_change_percentage_24h: number | null; circulating_supply: number; total_supply: number; max_supply: number | null; diff --git a/backend/native/backpack-api/src/routes/graphql/clients/helius.ts b/backend/native/backpack-api/src/routes/graphql/clients/helius.ts index cb55f3cb5..3f0fa6595 100644 --- a/backend/native/backpack-api/src/routes/graphql/clients/helius.ts +++ b/backend/native/backpack-api/src/routes/graphql/clients/helius.ts @@ -1,8 +1,8 @@ import { RESTDataSource } from "@apollo/datasource-rest"; import { getATAAddressSync } from "@saberhq/token-utils"; import type { AccountInfo } from "@solana/web3.js"; -import { PublicKey } from "@solana/web3.js"; -import type { EnrichedTransaction } from "helius-sdk"; +import { PublicKey, SystemProgram } from "@solana/web3.js"; +import { type EnrichedTransaction, Source, TransactionType } from "helius-sdk"; import { LRUCache } from "lru-cache"; export const IN_MEM_SOL_COLLECTION_DATA_CACHE = new LRUCache< @@ -104,12 +104,18 @@ export class Helius extends RESTDataSource { until?: string, mint?: string ): Promise { + let isNativeTransferFilter = false; let target = address; + if (mint) { - target = getATAAddressSync({ - mint: new PublicKey(mint), - owner: new PublicKey(address), - }).toBase58(); + if (mint !== SystemProgram.programId.toBase58()) { + target = getATAAddressSync({ + mint: new PublicKey(mint), + owner: new PublicKey(address), + }).toBase58(); + } else { + isNativeTransferFilter = true; + } } return this.get(`/v0/addresses/${target}/transactions`, { @@ -118,6 +124,12 @@ export class Helius extends RESTDataSource { commitment: "confirmed", before, until, + ...(isNativeTransferFilter + ? { + source: Source.SYSTEM_PROGRAM, + type: TransactionType.TRANSFER, + } + : undefined), }, }); } diff --git a/backend/native/backpack-api/src/routes/graphql/providers/bitcoin.ts b/backend/native/backpack-api/src/routes/graphql/providers/bitcoin.ts index 93a6745bd..ed35ced91 100644 --- a/backend/native/backpack-api/src/routes/graphql/providers/bitcoin.ts +++ b/backend/native/backpack-api/src/routes/graphql/providers/bitcoin.ts @@ -25,6 +25,7 @@ import { ProviderId } from "../types"; import { calculateBalanceAggregate, createConnection } from "../utils"; import type { BlockchainDataProvider } from "."; +import { createMarketDataNode } from "./util"; export type BitcoinProviderSettings = { context?: ApiContext; @@ -123,18 +124,11 @@ export class Bitcoin implements BlockchainDataProvider { amount: balance.final_balance.toString(), decimals: this.decimals(), displayAmount, - marketData: prices?.bitcoin - ? NodeBuilder.marketData("bitcoin", { - lastUpdatedAt: prices.bitcoin.last_updated, - percentChange: prices.bitcoin.price_change_percentage_24h, - price: prices.bitcoin.current_price, - sparkline: prices.bitcoin.sparkline_in_7d.price, - usdChange: prices.bitcoin.price_change_24h, - value: parseFloat(displayAmount) * prices.bitcoin.current_price, - valueChange: - parseFloat(displayAmount) * prices.bitcoin.price_change_24h, - }) - : undefined, + marketData: createMarketDataNode( + displayAmount, + "bitcoin", + prices.bitcoin + ), token: this.defaultAddress(), tokenListEntry: NodeBuilder.tokenListEntry({ address: BitcoinToken.address, diff --git a/backend/native/backpack-api/src/routes/graphql/providers/ethereum.ts b/backend/native/backpack-api/src/routes/graphql/providers/ethereum.ts index 6ea8b26cb..814bba3cc 100644 --- a/backend/native/backpack-api/src/routes/graphql/providers/ethereum.ts +++ b/backend/native/backpack-api/src/routes/graphql/providers/ethereum.ts @@ -29,6 +29,7 @@ import { ProviderId } from "../types"; import { calculateBalanceAggregate, createConnection } from "../utils"; import type { BlockchainDataProvider } from "."; +import { createMarketDataNode } from "./util"; export type EthereumProviderSettings = { context?: ApiContext; @@ -163,17 +164,11 @@ export class Ethereum implements BlockchainDataProvider { amount: native.toString(), decimals: this.decimals(), displayAmount: nativeDisplayAmount, - marketData: NodeBuilder.marketData("ethereum", { - lastUpdatedAt: prices.ethereum.last_updated, - percentChange: prices.ethereum.price_change_percentage_24h, - price: prices.ethereum.current_price, - sparkline: prices.ethereum.sparkline_in_7d.price, - usdChange: prices.ethereum.price_change_24h, - value: - parseFloat(nativeDisplayAmount) * prices.ethereum.current_price, - valueChange: - parseFloat(nativeDisplayAmount) * prices.ethereum.price_change_24h, - }), + marketData: createMarketDataNode( + nativeDisplayAmount, + "ethereum", + prices.ethereum + ), token: this.defaultAddress(), tokenListEntry: NodeBuilder.tokenListEntry(this.tokenList["native"]), }, @@ -187,19 +182,7 @@ export class Ethereum implements BlockchainDataProvider { const amount = curr.rawBalance ?? "0"; const displayAmount = curr.balance ?? "0"; - - const marketData = - p && id - ? NodeBuilder.marketData(id, { - lastUpdatedAt: p.last_updated, - percentChange: p.price_change_percentage_24h, - price: p.current_price, - sparkline: p.sparkline_in_7d.price, - usdChange: p.price_change_24h, - value: parseFloat(displayAmount) * p.current_price, - valueChange: parseFloat(displayAmount) * p.price_change_24h, - }) - : undefined; + const marketData = createMarketDataNode(displayAmount, id, p); const tokenListEntry = this.tokenList[curr.contractAddress] ? NodeBuilder.tokenListEntry(this.tokenList[curr.contractAddress]) diff --git a/backend/native/backpack-api/src/routes/graphql/providers/util.ts b/backend/native/backpack-api/src/routes/graphql/providers/util.ts index 6fbee02de..62efa1e68 100644 --- a/backend/native/backpack-api/src/routes/graphql/providers/util.ts +++ b/backend/native/backpack-api/src/routes/graphql/providers/util.ts @@ -20,12 +20,12 @@ export function createMarketDataNode( } return NodeBuilder.marketData(id, { lastUpdatedAt: price.last_updated, - percentChange: price.price_change_percentage_24h, + percentChange: price.price_change_percentage_24h ?? 0, price: price.current_price, sparkline: price.sparkline_in_7d.price, - usdChange: price.price_change_24h, + usdChange: price.price_change_24h ?? 0, value: parseFloat(displayAmount) * price.current_price, - valueChange: parseFloat(displayAmount) * price.price_change_24h, + valueChange: parseFloat(displayAmount) * (price.price_change_24h ?? 0), }); } diff --git a/backend/workers/price-indexer/src/types.ts b/backend/workers/price-indexer/src/types.ts index a0014ee6b..f2adca792 100644 --- a/backend/workers/price-indexer/src/types.ts +++ b/backend/workers/price-indexer/src/types.ts @@ -15,12 +15,12 @@ export type CoinGeckoPriceData = { market_cap_rank: number; fully_filuted_valuation: number; total_volume: number; - high_24h: number; - low_24h: number; - price_change_24h: number; - price_change_percentage_24h: number; - market_cap_change_24h: number; - market_cap_change_percentage_24h: number; + high_24h: number | null; + low_24h: number | null; + price_change_24h: number | null; + price_change_percentage_24h: number | null; + market_cap_change_24h: number | null; + market_cap_change_percentage_24h: number | null; circulating_supply: number; total_supply: number; max_supply: number | null;