From 8a2aaf85542c10b594eeafbd510254050606c6f3 Mon Sep 17 00:00:00 2001 From: Rakibul Yeasin Date: Fri, 24 Feb 2023 12:47:53 +0600 Subject: [PATCH 1/7] Added future & spot testnet and ported all to TS --- README.md | 20 ++++++++++- package.json | 2 +- src/index.tsx | 12 ++++--- src/utils/{adaptor.js => adaptor.ts} | 21 +++--------- ...eStickService.js => candleStickService.ts} | 3 +- src/utils/{constants.js => constants.ts} | 0 .../{fetchService.js => fetchService.ts} | 8 +++-- src/utils/types.ts | 14 +++++++- src/utils/urls.ts | 34 +++++++++++++++++++ 9 files changed, 86 insertions(+), 28 deletions(-) rename src/utils/{adaptor.js => adaptor.ts} (61%) rename src/utils/{candleStickService.js => candleStickService.ts} (61%) rename src/utils/{constants.js => constants.ts} (100%) rename src/utils/{fetchService.js => fetchService.ts} (53%) create mode 100644 src/utils/urls.ts diff --git a/README.md b/README.md index 6a11737..097b64e 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ import TradeViewChart from 'react-crypto-chart'; No Object
Candlestick Config type -
 
+    
     {
         upColor: "#00c176",
         downColor: "#cf304a",
@@ -153,6 +153,22 @@ import TradeViewChart from 'react-crypto-chart';
     }
   
+ + useFuturesTestnet + No + Boolean + +
false
+ + + + useSpotTestnet + No + Boolean + +
false
+ + @@ -160,6 +176,8 @@ import TradeViewChart from 'react-crypto-chart'; - **Justin K Xavier** - _Initial work_ - [LinkedIn](https://www.linkedin.com/in/justin-k-xavier-59b82710a/) +- **Rakibul Yeasin** - _Spot and Future Testnet_ - [Github](https://github.com/dreygur) + See also the list of [contributors](https://github.com/justinkx/RNChallenge_1/graphs/contributors) who participated in this project. ## License diff --git a/package.json b/package.json index 9d8eda2..9d2113f 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "react-crypto-chart", + "name": "@dreygur/react-crypto-chart", "version": "0.0.6", "description": "crypto chart widget for react using binance api", "main": "./lib/cjs/index.js", diff --git a/src/index.tsx b/src/index.tsx index 5c5d52c..4202b71 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -2,30 +2,32 @@ import React, { memo, useEffect, useCallback, useState } from 'react'; import { fetchCandleStickData } from './utils/fetchService'; import TradeView from './TradeView'; -import { WS_URL } from './utils/constants'; +import { getWebsocketUrl } from './utils/urls'; import { candleSocketAdaptor } from './utils/adaptor'; import { condleStickDefaultConfig, histogramDefaultConfig, defaultChartLayout, } from './utils/constants'; -import { Props, CandleStickSocketData } from './utils/types'; +import { Props, CandleStickSocketData, CandleStickAdaptorResult } from './utils/types'; const TradeViewChart: React.FC = ({ pair = 'BTCBUSD', interval = '1m', + useFuturesTestnet = false, + useSpotTestnet = false, candleStickConfig = condleStickDefaultConfig, histogramConfig = histogramDefaultConfig, chartLayout = defaultChartLayout, containerStyle, }) => { - const [candleStickData, setCandleData] = useState<[] | null>(null); + const [candleStickData, setCandleData] = useState(null); const [updatedata, setUpdateData] = useState( null ); const fetchCandleData = useCallback(async () => { - const candleData = await fetchCandleStickData(pair); + const candleData = await fetchCandleStickData(pair, interval); setCandleData(candleData); }, [pair]); @@ -35,7 +37,7 @@ const TradeViewChart: React.FC = ({ useEffect(() => { const ws = new WebSocket( - `${WS_URL}/${pair.toLocaleLowerCase()}@kline_${interval}` + `${getWebsocketUrl(useFuturesTestnet, useSpotTestnet)}/${pair.toLocaleLowerCase()}@kline_${interval}` ); // ws.onopen = () => console.log("open"); ws.onmessage = (e) => { diff --git a/src/utils/adaptor.js b/src/utils/adaptor.ts similarity index 61% rename from src/utils/adaptor.js rename to src/utils/adaptor.ts index c8d9502..f7c41cc 100644 --- a/src/utils/adaptor.js +++ b/src/utils/adaptor.ts @@ -1,17 +1,13 @@ -export const candleStickAdaptor = (data) => { +import { CandleStickAdaptorResult } from "./types"; + +export const candleStickAdaptor = (data: any): CandleStickAdaptorResult => { const [ openTime, open, high, low, close, - volume, - closeTime, - quoteAssetVolume, - numberOfTrades, - takerBuyBaseAssetVolume, - takerBuyQuotessetVolume, - ignore, + volume ] = data; return { time: openTime / 1000, @@ -21,17 +17,10 @@ export const candleStickAdaptor = (data) => { close: parseFloat(close), value: parseFloat(volume), color: open < close ? "#005a40" : "#82112b", - - // closeTime, - // quoteAssetVolume, - // numberOfTrades, - // takerBuyBaseAssetVolume, - // takerBuyQuotessetVolume, - // ignore, }; }; -export const candleSocketAdaptor = (data) => { +export const candleSocketAdaptor = (data: any) => { const { k: { T, o, c, h, l, v, V }, } = data; diff --git a/src/utils/candleStickService.js b/src/utils/candleStickService.ts similarity index 61% rename from src/utils/candleStickService.js rename to src/utils/candleStickService.ts index ae6a976..08e8bfe 100644 --- a/src/utils/candleStickService.js +++ b/src/utils/candleStickService.ts @@ -1,7 +1,8 @@ import { candleStickAdaptor } from "./adaptor"; +import { CandleStickAdaptorResult } from "./types"; export const parseCandleStickData = (candleArray = []) => { - const transformedData = candleArray.reduce((accu, curr) => { + const transformedData = candleArray.reduce((accu: CandleStickAdaptorResult[], curr) => { const candle = candleStickAdaptor(curr); accu.push(candle); return accu; diff --git a/src/utils/constants.js b/src/utils/constants.ts similarity index 100% rename from src/utils/constants.js rename to src/utils/constants.ts diff --git a/src/utils/fetchService.js b/src/utils/fetchService.ts similarity index 53% rename from src/utils/fetchService.js rename to src/utils/fetchService.ts index 2ae791a..43a68c0 100644 --- a/src/utils/fetchService.js +++ b/src/utils/fetchService.ts @@ -1,11 +1,13 @@ -import { BASE_URL } from "./constants"; +import { getBaseUrl } from "./urls"; import { parseCandleStickData } from "./candleStickService"; export const fetchCandleStickData = async ( symbol = "BTCBUSD", - interval = "1m" + interval = "1m", + useFuturesTestnet = false, + useSpotTestnet = false, ) => { - const url = `${BASE_URL}symbol=${symbol}&interval=${interval}`; + const url = `${getBaseUrl(useFuturesTestnet, useSpotTestnet)}symbol=${symbol}&interval=${interval}`; const result = await fetch(url); const data = await result.json(); return parseCandleStickData(data); diff --git a/src/utils/types.ts b/src/utils/types.ts index 18a6860..cfbed2d 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -1,5 +1,15 @@ import { CrosshairMode, LineStyle } from 'lightweight-charts'; +export interface CandleStickAdaptorResult { + time: number; + open: number; + high: number; + low: number; + close: number; + value: number; + color: string; +} + export interface CandleStickSocketData { open: number; high: number; @@ -10,7 +20,7 @@ export interface CandleStickSocketData { color: string; } export interface TradeViewProps { - initialChartData: []; + initialChartData: CandleStickAdaptorResult[]; updatedata: CandleStickSocketData | null; candleStickConfig: CandleStickConfig; histogramConfig: HistogramConfig; @@ -56,6 +66,8 @@ export interface Props { candleStickConfig: CandleStickConfig; histogramConfig: HistogramConfig; chartLayout: DeffaultChartLayout; + useFuturesTestnet?: boolean; + useSpotTestnet?: boolean; containerStyle?: { [x: string]: any; }; diff --git a/src/utils/urls.ts b/src/utils/urls.ts new file mode 100644 index 0000000..240ef09 --- /dev/null +++ b/src/utils/urls.ts @@ -0,0 +1,34 @@ +const url: { [key: string]: { [key: string]: string } } = { + main: { + base: "https://api.binance.com/api/v3/klines?", + ws: "wss://stream.binance.com:9443/ws" + }, + future: { + base: "https://testnet.binancefuture.com/fapi/v1/klines?", + ws: "wss://stream.binancefuture.com/ws" + }, + spot: { + base: "https://testnet.binance.vision/api/v3/klines?", + ws: "wss://testnet.binance.vision/ws" + } +}; + +export function getBaseUrl(useFuturesTestnet: boolean, useSpotTestnet: boolean): string { + if (useFuturesTestnet && !useSpotTestnet) { + return url.future.base; + } + if (!useFuturesTestnet && useSpotTestnet) { + return url.spot.base; + } + return url.main.base; +} + +export function getWebsocketUrl(useFuturesTestnet: boolean, useSpotTestnet: boolean): string { + if (useFuturesTestnet && !useSpotTestnet) { + return url.future.ws; + } + if (!useFuturesTestnet && useSpotTestnet) { + return url.spot.ws; + } + return url.main.ws; +} \ No newline at end of file From 5ecf4e29393ea1b3efaa293efe2547de573d8550 Mon Sep 17 00:00:00 2001 From: Rakibul Yeasin Date: Fri, 24 Feb 2023 12:51:03 +0600 Subject: [PATCH 2/7] Added future & spot testnet and ported all to TS --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 9d2113f..371f358 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "module": "./lib/esm/index.js", "types": "./lib/esm/index.d.ts", "author": "Justin K Xavier", + "private": false, "repository": { "url": "https://github.com/justinkx/react-crypto-chart.git" }, From 0d341980d50ff9180b4cd529a3ced03d3c08f3f6 Mon Sep 17 00:00:00 2001 From: Rakibul Yeasin Date: Fri, 24 Feb 2023 15:44:42 +0600 Subject: [PATCH 3/7] Cleaned some junks and added test api --- package.json | 25 +++++++--------- src/TradeView.tsx | 4 +-- src/index.tsx | 24 ++++++--------- src/utils/fetchService.ts | 2 +- src/utils/types.ts | 8 ++--- src/utils/urls.ts | 4 +-- tsconfig.json | 62 +++++++++++++++++++-------------------- 7 files changed, 60 insertions(+), 69 deletions(-) diff --git a/package.json b/package.json index 371f358..044584b 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,11 @@ { "name": "@dreygur/react-crypto-chart", - "version": "0.0.6", + "version": "0.0.7", "description": "crypto chart widget for react using binance api", - "main": "./lib/cjs/index.js", - "module": "./lib/esm/index.js", - "types": "./lib/esm/index.d.ts", + "main": "lib/cjs/index.js", + "module": "lib/esm/index.js", + "types": "lib/esm/index.d.ts", "author": "Justin K Xavier", - "private": false, "repository": { "url": "https://github.com/justinkx/react-crypto-chart.git" }, @@ -17,20 +16,18 @@ "build:cjs": "tsc --module commonjs --outDir lib/cjs" }, "files": [ - "/lib" + "lib" ], "devDependencies": { - "@types/react": "^17.0.11", - "@types/react-dom": "^17.0.7", - "react": "^17.0.2", - "react-dom": "^17.0.2", + "@types/react": "^18.0.28", + "@types/react-dom": "^18.0.11", "typescript": "^4.3.2" }, - "peerDependencies": { - "react": "^16.8.0", - "react-dom": "^16.8.0" - }, "dependencies": { "lightweight-charts": "^3.8.0" + }, + "peerDependencies": { + "react": "^18.2.0", + "react-dom": "^18.2.0" } } diff --git a/src/TradeView.tsx b/src/TradeView.tsx index 8eb2de0..fbe7bd2 100644 --- a/src/TradeView.tsx +++ b/src/TradeView.tsx @@ -23,8 +23,7 @@ const TradeView: React.FC = ({ const volumeSeries = useRef(); const setInitialData = useCallback(() => { - candleSeries.current = - chart?.current?.addCandlestickSeries(candleStickConfig); + candleSeries.current = chart?.current?.addCandlestickSeries(candleStickConfig); candleSeries?.current.setData(initialChartData); volumeSeries.current = chart.current.addHistogramSeries(histogramConfig); volumeSeries?.current?.setData(initialChartData); @@ -72,6 +71,7 @@ const TradeView: React.FC = ({ return () => resizeObserver.current.disconnect(); }, []); + return (
= ({ containerStyle, }) => { const [candleStickData, setCandleData] = useState(null); - const [updatedata, setUpdateData] = useState( - null - ); - - const fetchCandleData = useCallback(async () => { - const candleData = await fetchCandleStickData(pair, interval); - setCandleData(candleData); - }, [pair]); + const [updatedata, setUpdateData] = useState(null); useEffect(() => { - fetchCandleData(); - }, [fetchCandleData]); + fetchCandleStickData(pair, interval, useFuturesTestnet, useSpotTestnet) + .then(res => setCandleData(res)) + .catch(err => console.log(err)); - useEffect(() => { const ws = new WebSocket( - `${getWebsocketUrl(useFuturesTestnet, useSpotTestnet)}/${pair.toLocaleLowerCase()}@kline_${interval}` + `${getWebsocketUrl({ useFuturesTestnet, useSpotTestnet })}/${pair.toLocaleLowerCase()}@kline_${interval}` ); - // ws.onopen = () => console.log("open"); + ws.onmessage = (e) => { const message = JSON.parse(e.data); const parsedMessage = candleSocketAdaptor(message); @@ -48,11 +41,12 @@ const TradeViewChart: React.FC = ({ return () => { ws.close(); }; - }, [pair, interval]); + }, [pair, interval, useFuturesTestnet, useSpotTestnet]); if (!candleStickData) { return
; } + return ( { - const url = `${getBaseUrl(useFuturesTestnet, useSpotTestnet)}symbol=${symbol}&interval=${interval}`; + const url = `${getBaseUrl({ useFuturesTestnet, useSpotTestnet })}symbol=${symbol}&interval=${interval}`; const result = await fetch(url); const data = await result.json(); return parseCandleStickData(data); diff --git a/src/utils/types.ts b/src/utils/types.ts index cfbed2d..7a58ace 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -62,10 +62,10 @@ export interface TradeViewChart { } export interface Props { pair: string; - interval: string; - candleStickConfig: CandleStickConfig; - histogramConfig: HistogramConfig; - chartLayout: DeffaultChartLayout; + interval?: string; + candleStickConfig?: CandleStickConfig; + histogramConfig?: HistogramConfig; + chartLayout?: DeffaultChartLayout; useFuturesTestnet?: boolean; useSpotTestnet?: boolean; containerStyle?: { diff --git a/src/utils/urls.ts b/src/utils/urls.ts index 240ef09..e13b135 100644 --- a/src/utils/urls.ts +++ b/src/utils/urls.ts @@ -13,7 +13,7 @@ const url: { [key: string]: { [key: string]: string } } = { } }; -export function getBaseUrl(useFuturesTestnet: boolean, useSpotTestnet: boolean): string { +export function getBaseUrl({ useFuturesTestnet, useSpotTestnet }: { useFuturesTestnet?: boolean, useSpotTestnet?:boolean }): string { if (useFuturesTestnet && !useSpotTestnet) { return url.future.base; } @@ -23,7 +23,7 @@ export function getBaseUrl(useFuturesTestnet: boolean, useSpotTestnet: boolean): return url.main.base; } -export function getWebsocketUrl(useFuturesTestnet: boolean, useSpotTestnet: boolean): string { +export function getWebsocketUrl({ useFuturesTestnet, useSpotTestnet }: { useFuturesTestnet?: boolean, useSpotTestnet?: boolean }): string { if (useFuturesTestnet && !useSpotTestnet) { return url.future.ws; } diff --git a/tsconfig.json b/tsconfig.json index 7d2ffa6..c04e3cb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,33 +1,33 @@ { - "compilerOptions": { - "outDir": "lib/esm", - "module": "esnext", - "target": "es5", - "lib": [ - "es6", - "dom", - "es2016", - "es2017" - ], - "jsx": "react", - "declaration": true, - "moduleResolution": "node", - "noUnusedLocals": true, - "noUnusedParameters": true, - "esModuleInterop": true, - "noImplicitReturns": true, - "noImplicitThis": true, - "noImplicitAny": true, - "strictNullChecks": true, - "suppressImplicitAnyIndexErrors": true, - "allowSyntheticDefaultImports": true, - "allowJs": true - }, - "include": [ - "src" + "compilerOptions": { + "outDir": "lib/esm", + "module": "esnext", + "target": "es5", + "lib": [ + "dom", + "dom.iterable", + "esnext" ], - "exclude": [ - "node_modules", - "lib" - ] -} \ No newline at end of file + "jsx": "react-jsx", + "declaration": true, + "moduleResolution": "node", + "noUnusedLocals": true, + "noUnusedParameters": true, + "esModuleInterop": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noImplicitAny": true, + "strictNullChecks": true, + "suppressImplicitAnyIndexErrors": true, + "allowSyntheticDefaultImports": true, + "allowJs": true, + "strict": true + }, + "include": [ + "src" + ], + "exclude": [ + "node_modules", + "lib" + ] +} From 55fa033f8a101d4ff75b7ffa831f0101461d5c64 Mon Sep 17 00:00:00 2001 From: Rakibul Yeasin Date: Fri, 24 Feb 2023 15:51:28 +0600 Subject: [PATCH 4/7] Cleaned some junks and added test api --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 097b64e..4f275af 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ npm install npm start ``` -- [Stackblitz example](https://stackblitz.com/edit/react-crypto-chart) +- [Stackblitz example](https://stackblitz.com/edit/react-crypto-chart-jcogao) ## How To Install From b0cc8a848487bcfcacce23fd55ba0a4b042da1f6 Mon Sep 17 00:00:00 2001 From: Rakibul Yeasin Date: Fri, 24 Feb 2023 16:01:33 +0600 Subject: [PATCH 5/7] Revert back to original json --- package.json | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 044584b..cd7cb41 100644 --- a/package.json +++ b/package.json @@ -1,10 +1,10 @@ { - "name": "@dreygur/react-crypto-chart", - "version": "0.0.7", + "name": "react-crypto-chart", + "version": "0.0.6", "description": "crypto chart widget for react using binance api", - "main": "lib/cjs/index.js", - "module": "lib/esm/index.js", - "types": "lib/esm/index.d.ts", + "main": "./lib/cjs/index.js", + "module": "./lib/esm/index.js", + "types": "./lib/esm/index.d.ts", "author": "Justin K Xavier", "repository": { "url": "https://github.com/justinkx/react-crypto-chart.git" @@ -16,7 +16,7 @@ "build:cjs": "tsc --module commonjs --outDir lib/cjs" }, "files": [ - "lib" + "/lib" ], "devDependencies": { "@types/react": "^18.0.28", @@ -31,3 +31,4 @@ "react-dom": "^18.2.0" } } +} From 64b2008e9b6cee11276ce6c385199d638dff9fa1 Mon Sep 17 00:00:00 2001 From: Rakibul Yeasin Date: Fri, 24 Feb 2023 16:01:55 +0600 Subject: [PATCH 6/7] Revert back to original json --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index cd7cb41..1407480 100644 --- a/package.json +++ b/package.json @@ -31,4 +31,3 @@ "react-dom": "^18.2.0" } } -} From 6238a774e3f4228ed592b589ce079ee34520ac66 Mon Sep 17 00:00:00 2001 From: Rakibul Yeasin Date: Fri, 24 Feb 2023 16:09:28 +0600 Subject: [PATCH 7/7] Reverted readme and package to original --- README.md | 4 +--- package.json | 7 +++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 4f275af..3128758 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ npm install npm start ``` -- [Stackblitz example](https://stackblitz.com/edit/react-crypto-chart-jcogao) +- [Stackblitz example](https://stackblitz.com/edit/react-crypto-chart) ## How To Install @@ -176,8 +176,6 @@ import TradeViewChart from 'react-crypto-chart'; - **Justin K Xavier** - _Initial work_ - [LinkedIn](https://www.linkedin.com/in/justin-k-xavier-59b82710a/) -- **Rakibul Yeasin** - _Spot and Future Testnet_ - [Github](https://github.com/dreygur) - See also the list of [contributors](https://github.com/justinkx/RNChallenge_1/graphs/contributors) who participated in this project. ## License diff --git a/package.json b/package.json index 1407480..2020a5f 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,13 @@ "module": "./lib/esm/index.js", "types": "./lib/esm/index.d.ts", "author": "Justin K Xavier", + "contributors": [ + { + "name": "Rakibul Yeasin", + "email": "ryeasin03@gmail.com", + "url": "https://dreygur.js.org/" + } + ], "repository": { "url": "https://github.com/justinkx/react-crypto-chart.git" },