@mimicry/kaleidoscope
Version:
Kaleidoscope is an NPM package that conveniently aggregates responses from multiple NFT data providers.
137 lines (125 loc) • 4.21 kB
text/typescript
import { Chain, Timeframe } from '../../../../../enums';
import {
ContractPointer,
NFTCollectionMetadata,
NFTCollectionSales,
Value,
} from '../../../../../types';
import { RestfulProvider } from '../../RestfulProvider';
import { NftCollectionDataProvider } from '../NftCollectionDataProvider';
import { numberToValue } from '../../../../../utils/numberToValue';
import { chainToBlockchainExplorerHost } from '../../../../../utils/crossChainSupport';
// Docs: https://www.coingecko.com/en/api/documentation
export class CoinGeckoNonFungible extends RestfulProvider
implements NftCollectionDataProvider {
constructor(_config: any) {
const apiHost = 'https://api.coingecko.com/api/v3/';
super(_config, apiHost);
}
// https://api.coingecko.com/api/v3/nfts/{chain}/contract/{contract_address}
async getFloor(_contract: ContractPointer): Promise<Value> {
const host = this.getApiHost();
const chain = this.getBlockchain(_contract.chain);
const uri = `${host}nfts/${chain}/contract/${_contract.address}`;
const json: any = await this.gotJson(uri);
const currencyInfo = this.getCurrencyInfoFromChain(_contract.chain);
return numberToValue(
Number(json.floor_price.native_currency),
currencyInfo
);
}
async getFloorChart(
_contract: ContractPointer,
_timeframe?: Timeframe
): Promise<any> {
throw new Error('Method not implemented.');
}
async getHistoricSales(
_contract: ContractPointer
): Promise<NFTCollectionSales> {
throw new Error('Method not implemented.');
}
async getMarketCap(_contract: ContractPointer): Promise<Value> {
throw new Error('Method not implemented.');
}
// /nfts/{asset_platform_id}/contract/{contract_address}
async getMetadata(_contract: ContractPointer): Promise<any> {
const host = this.getApiHost();
const chain = this.getBlockchain(_contract.chain);
const uri = `${host}nfts/${chain}/contract/${_contract.address}`;
const json: any = await this.gotJson(uri);
const currencyInfo = this.getCurrencyInfoFromChain(_contract.chain);
const metadata: NFTCollectionMetadata = {
contract: _contract,
symbol: json.symbol,
name: json.name,
description: json.description,
collectionSize: Number(json.total_supply),
ownerCount: Number(json.number_of_unique_addresses),
images: {
thumbnail: json.image.small,
},
urls: {
explorer: `${chainToBlockchainExplorerHost(_contract.chain)}/address/${
_contract.address
}`,
website: json.links.homepage,
discord: json.links.discord,
twitter: json.links.twitter,
},
stats: {
currencyInfo: currencyInfo,
floor: {
h24: numberToValue(
Number(json.floor_price.native_currency),
currencyInfo
).amount,
h24Change: numberToValue(
Number(json.floor_price_24h_percentage_change.native_currency),
currencyInfo
).amount.decimal,
},
volume: {
h24: numberToValue(
Number(json.volume_24h.native_currency),
currencyInfo
).amount,
h24Change: numberToValue(
Number(json.volume_24h_percentage_change.native_currency),
currencyInfo
).amount.decimal,
},
},
};
return metadata;
}
getBlockchain(_chain?: Chain): string {
switch (_chain) {
case undefined:
case Chain.ETHEREUM:
return 'ethereum';
case Chain.BSC:
return 'binance-smart-chain';
case Chain.POLYGON:
return 'polygon-pos';
case Chain.ARBITRUM:
return 'arbitrum-one';
case Chain.SOLANA:
throw new Error(
'Solana is supported by CoinGecko, but not yet implemented.'
);
// return 'solana';
case Chain.OPTIMISM:
return 'optimistic-ethereum';
case Chain.AVALANCHE:
return 'avalanche';
case Chain.KLAYTN:
return 'klay-token';
default:
throw new Error(`${_chain} is not supported by ${this.getName()}.`);
}
}
getName(): string {
return 'CoinGecko';
}
}