### Start Metro Server for React Native Project Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/README.md This command initiates the Metro bundler, essential for serving JavaScript code to the React Native application during development. It's a prerequisite for running the app on emulators or devices. Requires Node.js and npm/Yarn installed. ```bash # using npm npm start # OR using Yarn yarn start ``` -------------------------------- ### Run React Native Application on Android Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/README.md This command builds and launches the React Native application on an Android emulator or connected device. Ensure Metro bundler is running in a separate terminal and the Android environment is correctly set up. Requires Android SDK and emulator/device. ```bash # using npm npm run android # OR using Yarn yarn android ``` -------------------------------- ### Run React Native Application on iOS Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/README.md This command builds and launches the React Native application on an iOS simulator or connected device. Ensure Metro bundler is running in a separate terminal and the iOS development environment (Xcode) is correctly set up. Requires macOS and Xcode. ```bash # using npm npm run ios # OR using Yarn yarn ios ``` -------------------------------- ### Expand ESLint: Enable Type-Checked Lint Rules Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/go.rabby.io/README.md This configuration enables type-aware lint rules for TypeScript files. It replaces the default recommended rules with more robust, type-checked configurations. Ensure you have 'typescript' and 'eslint-plugin-tseslint' installed. ```javascript export default tseslint.config([ globalIgnores(['dist']), { files: ['**/*.{ts,tsx}'], extends: [ // Other configs... // Remove tseslint.configs.recommended and replace with this ...tseslint.configs.recommendedTypeChecked, // Alternatively, use this for stricter rules ...tseslint.configs.strictTypeChecked, // Optionally, add this for stylistic rules ...tseslint.configs.stylisticTypeChecked, // Other configs... ], languageOptions: { parserOptions: { project: ['./tsconfig.node.json', './tsconfig.app.json'], tsconfigRootDir: import.meta.dirname, }, // other options... }, }, ]) ``` -------------------------------- ### Expand ESLint: Enable React-Specific Lint Rules Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/go.rabby.io/README.md This configuration adds React-specific lint rules using eslint-plugin-react-x and eslint-plugin-react-dom. It complements the type-aware linting by providing checks tailored for React and React DOM development. Ensure these plugins are installed. ```javascript // eslint.config.js import reactX from 'eslint-plugin-react-x' import reactDom from 'eslint-plugin-react-dom' export default tseslint.config([ globalIgnores(['dist']), { files: ['**/*.{ts,tsx}'], extends: [ // Other configs... // Enable lint rules for React reactX.configs['recommended-typescript'], // Enable lint rules for React DOM reactDom.configs.recommended, ], languageOptions: { parserOptions: { project: ['./tsconfig.node.json', './tsconfig.app.json'], tsconfigRootDir: import.meta.dirname, }, // other options... }, }, ]) ``` -------------------------------- ### Setup WindowPostMessageStream in Window B (JavaScript) Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/packages/post-message-stream/README.md Configures a WindowPostMessageStream in an iframe (Window B) to communicate back to the parent window (Window A). It reverses the `name` and `target` properties compared to Window A and specifies the `targetOrigin` for secure communication. Incoming messages are handled via the `on('data', ...)` event listener. ```javascript const streamB = new WindowPostMessageStream({ // Notice that these values are reversed relative to window A. name: 'streamB', target: 'streamA', // The origin of window A. If we don't specify this, it would default to // `location.origin`, which won't work if the local origin is different. We // could pass `*`, but that's potentially unsafe. targetOrigin: 'https://foo.com', // We omit `targetWindow` here because it defaults to `window`. }); streamB.on('data', (data) => console.log(data + ', world')); // > 'hello, world' ``` -------------------------------- ### Setup WindowPostMessageStream in Window A (JavaScript) Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/packages/post-message-stream/README.md Configures a WindowPostMessageStream in the parent window (Window A) to communicate with a target iframe (Window B). It specifies the stream names, the target origin, and the target window for secure message exchange. Messages are sent using the `write` method. ```javascript import { WindowPostMessageStream } from '@rabby-wallet/post-message-stream'; const streamA = new WindowPostMessageStream({ name: 'streamA', // We give this stream a name that the other side can target. target: 'streamB', // This must match the `name` of the other side. // Adding `targetWindow` below already ensures that we will only _send_ // messages to `iframeB`, but we need to specify its origin as well to ensure // that we only _receive_ messages from `iframeB`. targetOrigin: new URL(iframeB.src).origin, // We have to specify the content window of `iframeB` as the target, or it // won't receive our messages. targetWindow: iframeB.contentWindow, }); streamA.write('hello'); ``` -------------------------------- ### TradingView Chart Initialization and Configuration (JavaScript) Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html This snippet details the process of loading the TradingView lightweight charts library and creating a chart instance. It configures global variables for chart elements, styling, and interactive components, and sets up the chart's layout, localization, grid, and time scale properties. It dynamically loads the library from a CDN and includes error handling for the loading process. ```javascript // Global variables window.chart = null; window.candlestickSeries = null; window.volumeSeries = null; window.isInitialDataLoad = true; window.lastDataKey = null; window.tooltip = null; window.clearMarkers = null; window.currentExtremes = null; window.priceLineContainers = { tp: null, sl: null, liquidation: null, entry: null }; // Step 1: Load TradingView library dynamically function loadTradingView() { const script = document.createElement('script'); script.src = 'https://unpkg.com/lightweight-charts/dist/lightweight-charts.standalone.production.js'; script.onload = function () { setTimeout(createChart, 500); }; script.onerror = function () { console.error('TradingView: Failed to load library'); }; document.head.appendChild(script); } // Step 2: Create chart function createChart() { if (!window.LightweightCharts) { console.error('TradingView: Library not available'); return; } try { window.chart = LightweightCharts.createChart( document.getElementById('container'), { width: window.innerWidth, height: window.innerHeight, layout: { background: { color: window.colors.background }, textColor: window.colors.text, attributionLogo: true }, localization: { priceFormatter: window?.utils?.formatPrice, dateFormat: window?.utils?.formatTime }, grid: { vertLines: { color: window.colors.border }, horzLines: { color: window.colors.border } }, timeScale: { timeVisible: true, secondsVisible: false, borderColor: 'transparent', tickMarkFormatter: window?.utils?.formatYTime, minBarSpacing: 2, maxBarSpacing: 30, fixLeftEdge: true, fixRightEdge: true }, trackingMode: { exitMode: 0 }, rightPriceScale: { borderColor: 'transparent', borderVisible: false, minimumWidth: 50, sca } ); } catch (error) { console.error('TradingView: Error creating chart', error); } } ``` -------------------------------- ### Initialize Rabby Provider with Duplex Stream Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/packages/providers/README.md This snippet demonstrates how to initialize the Rabby provider by creating a duplex stream to a remote provider and then calling the initializeProvider function. It assumes the existence of LocalMessageDuplexStream and sets the initialized provider as window.ethereum. This is useful for integrating Rabby's provider into a web application's environment. ```javascript import { initializeProvider } from '@rabby-wallet/providers'; // Create a stream to a remote provider: const metamaskStream = new LocalMessageDuplexStream({ name: 'inpage', target: 'contentscript', }); // this will initialize the provider and set it as window.ethereum initializeProvider({ connectionStream: metamaskStream, }); const {ethereum} = window; ``` -------------------------------- ### JavaScript: Create and Use Object Multiplexer Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/packages/object-multiplex/README.md Demonstrates the creation and basic usage of an ObjMultiplex instance in JavaScript. This includes setting up substreams, piping data through a transport layer, and writing object-based data to the substreams. It requires the ObjMultiplex class to be available. ```javascript const mux = new ObjMultiplex(); const streamA = mux.createStream("hello"); const streamB = mux.createStream("world"); mux.pipe(transport).pipe(mux); streamA.write({ thisIsAn: "object" }); streamA.write(123); streamB.pipe(evilAiBrain).pipe(streamB); ``` -------------------------------- ### Create Volume Series with Lightweight Charts in JavaScript Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html This JavaScript function, `createVolumeSeries`, sets up a histogram series for displaying volume data using the Lightweight Charts library. It ensures that a chart instance and the necessary HistogramSeries type are available. It removes any pre-existing volume series before adding a new one with specific formatting for volume data. It returns the created series or null if prerequisites are not met. ```javascript window.createVolumeSeries = function () { if (!window.chart || !window.LightweightCharts?.HistogramSeries) return null; if (window.volumeSeries) { window.chart.removeSeries(window.volumeSeries); } window.volumeSeries = window.chart.addSeries( window.LightweightCharts.HistogramSeries, { priceFormat: { type: 'volume', }, priceScaleId: '', lastValueVisible: false, priceLineVisible: false, }, ); return window.volumeSeries; }; ``` -------------------------------- ### Delayed TradingView Initialization Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html Initiates the loading of the TradingView chart functionality after a short delay (0 milliseconds). This is often used to ensure that the DOM is ready or to avoid blocking the main thread during initial page load. ```javascript setTimeout(loadTradingView, 0); ``` -------------------------------- ### Handle Window Resize for Chart Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html Listens for window resize events and updates the chart's dimensions accordingly. This ensures the chart remains responsive to the viewport size. It relies on a global `window.chart` object and `window.innerWidth`/`window.innerHeight`. ```javascript window.addEventListener('resize', function () { if (window.chart) { window.chart.applyOptions({ width: window.innerWidth, height: window.innerHeight, }); } }); ``` -------------------------------- ### JavaScript Utility Functions for Chart Data Formatting Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html This snippet defines a collection of utility functions for formatting numerical data, prices, and timestamps, making them suitable for display on financial charts. It includes functions for handling large numbers, specific price ranges, and date/time conversions. Dependencies include the BigNumber library. ```javascript const Sub_Numbers = '₀₁₂₃₄₅₆₇₈₉'; window.utils = { formatLittleNumber: (num, minLen = 6) => { const bn = new BigNumber(num); if (bn.toFixed().length >= minLen) { const s = bn.precision(4).toFormat(); const ss = s.replace(/^0.(0*)?(?:.*)/u, (_, z) => { const zeroLength = z.length; const sub = String(zeroLength) .split('') .map(x => Sub_Numbers[x]) .join(''); const end = s.slice(zeroLength + 2); return '0.0' + sub + end; }); return ss; } return num; }, formatPrice: v => { if (Math.abs(v) >= 0.1) { return v.toFixed(2); } if (Math.abs(v) < 0.0001) { const isNegative = v < 0; const absNum = Math.abs(v); return ( (isNegative ? '-' : '') + window.utils.formatLittleNumber(absNum) ); } return v.toFixed(2); }, formatNumber: v => { if (v >= 1000000) { return (v / 1000000).toFixed(2) + 'M'; } else if (v >= 1000) { return (v / 1000).toFixed(2) + 'K'; } return v.toFixed(2); }, formatYTime: t => { if (typeof t === 'number') { const d = new Date(t * 1000); return ( '' + (d.getMonth() + 1) + '/' + d.getDate() + ' ' + d.getHours().toString().padStart(2, '0') + ':' + d.getMinutes().toString().padStart(2, '0') ); } const bd = t; return '' + bd.month + '/' + bd.day; }, formatTime: t => { if (typeof t === 'number') { const d = new Date(t * 1000); return ( '' + String(d.getMonth() + 1).padStart(2, '0') + '/' + String(d.getDate()).padStart(2, '0') + ' ' + String(d.getHours()).padStart(2, '0') + ':' + String(d.getMinutes()).padStart(2, '0') ); } const bd = t; return ( '' + bd.year + '-' + String(bd.month).padStart(2, '0') + '-' + String(bd.day).padStart(2, '0') ); }, // 计算当前可见范围的最高最低价格 calculateVisibleExtremes: (data, from, to) => { if (!data || data.length === 0) return { highest: null, lowest: null, highestTime: null, lowestTime: null }; const rangeData = data.filter( bar => bar.time >= from && bar.time <= to ); if (rangeData.length === 0) return { highest: null, lowest: null, highestTime: null, lowestTime: null }; let highest = rangeData[0].high; let lowest = rangeData[0].low; let highestTime = rangeData[0].time; let lowestTime = rangeData[0].time; rangeData.forEach(bar => { if (bar.high > highest) { highest = bar.high; highestTime = bar.time; } if (bar.low < lowest) { lowest = bar.low; lowestTime = bar.time; } }); return { highest, lowest, highestTime, lowestTime }; } }; window.colors = { background: '#1B1E23', text: '#D1D4DC', border: '#343B47', greenLineColor: '#0ECB81', redLineColor: '#F6465D', highPriceLineColor: '#DDD', lowPriceLineColor: '#DDD', tooltip: { bg: 'rgba(255, 255, 255, 1)', bg2: 'rgba(62, 73, 94, 1)', title: 'rgba(255, 255, 255, 1)', value: 'rgba(25, 41, 69, 1)' } }; window.description = { tp: 'TP', entry: 'Entry', sl: 'SL', liq: 'LIQ', high: 'High', low: 'Low', time: 'Time', open: 'Open', high: 'High', low: 'Low', close: 'Close', chg: '%Chg', volume: 'Volume' }; ``` -------------------------------- ### Create Candlestick Series with Lightweight Charts in JavaScript Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html This JavaScript function, `createCandlestickSeries`, initializes a candlestick series for a TradingView chart using the Lightweight Charts library. It handles the creation of a new series, including customizable colors and formatting, and removes any existing series before creating the new one. It returns the created series object or null if the chart or series type is unavailable. ```javascript window.createCandlestickSeries = function () { if (!window.chart || !window.LightweightCharts?.CandlestickSeries) return null; if (window.candlestickSeries) { window.chart.removeSeries(window.candlestickSeries); } window.candlestickSeries = window.chart.addSeries( window.LightweightCharts.CandlestickSeries, { upColor: window.colors.greenLineColor, downColor: window.colors.redLineColor, borderDownColor: window.colors.redLineColor, borderUpColor: window.colors.greenLineColor, wickDownColor: window.colors.redLineColor, wickUpColor: window.colors.greenLineColor, lastValueVisible: true, priceLineVisible: true, priceLineSource: 0, priceLineWidth: 1, priceLineStyle: 2, priceFormat: { type: 'price', minMove: 0.0000001, }, }, ); return window.candlestickSeries; }; ``` -------------------------------- ### Create and Style Tooltip DOM Element Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html Creates a `div` element to serve as a tooltip for chart interactions. It styles the tooltip for absolute positioning, hidden state by default, and specific visual properties like background, color, padding, and border-radius. It appends the tooltip to a container element with the ID 'container'. ```javascript const tooltip = document.createElement('div'); tooltip.style.position = 'absolute'; tooltip.style.display = 'none'; tooltip.style.pointerEvents = 'none'; tooltip.style.background = window.colors.tooltip.bg; tooltip.style.color = '#D1D4DC'; tooltip.style.padding = '8px 9px'; tooltip.style.borderRadius = '8px'; tooltip.style.fontSize = '12px'; tooltip.style.lineHeight = '1.4'; tooltip.style.zIndex = '1000'; window.tooltip = tooltip; const containerEl = document.getElementById('container'); if (containerEl) containerEl.appendChild(tooltip); ``` -------------------------------- ### Node.js Child Process Communication Stream Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/packages/post-message-stream/README.md Enables duplex stream communication between a parent Node.js process and a child process forked using `child_process.fork()`. The parent uses `ProcessParentMessageStream` and the child uses `ProcessMessageStream`. Ensure the child process module is correctly specified. ```javascript import { fork } from 'child_process'; import { ProcessParentMessageStream } from '@rabby-wallet/post-message-stream'; // `modulePath` is the path to the JavaScript module that will instantiate the // child stream. const process = fork(modulePath); const parentStream = new ProcessParentMessageStream({ process }); parentStream.write('hello'); ``` ```javascript import { ProcessMessageStream } from '@rabby-wallet/post-message-stream'; // The child stream automatically "connects" to the dedicated IPC channel via // properties on `globalThis.process`. const childStream = new ProcessMessageStream(); childStream.on('data', (data) => console.log(data + ', world')); // > 'hello, world' ``` -------------------------------- ### Forwarding Document Messages to Window Events Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html This snippet ensures that messages posted to the document object are also dispatched as 'message' events on the window object. This allows the existing window message listener to capture and process these events, maintaining consistent communication. ```javascript document.addEventListener('message', function (event) { window.dispatchEvent(new MessageEvent('message', event)); }); ``` -------------------------------- ### Update Chart Extremes and Create Markers Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html Updates the chart's highest and lowest price points and creates visual markers on the candlestick series. It checks for existing markers and replaces them, ensuring only the current extremes are marked. Dependencies include global `window` properties for chart series, colors, and marker creation functions. ```javascript window.currentExtremes = newExtremes; const { highest, lowest, highestTime, lowestTime } = newExtremes; if (!highest || !lowest) return; if (window.clearMarkers) { window.clearMarkers.setMarkers([]); } window.clearMarkers = createSeriesMarkers(window.candlestickSeries, [ { time: highestTime, position: 'aboveBar', color: window.colors.greenLineColor, shape: 'arrowDown', text: window.description.high, size: 0.1 }, { time: lowestTime, position: 'belowBar', color: window.colors.redLineColor, shape: 'arrowUp', text: window.description.low, size: 0.1 } ]); ``` -------------------------------- ### TradingView Tooltip HTML Generation Source: https://github.com/rabbyhub/rabby-mobile/blob/develop/apps/mobile/src/components2024/TradingViewCandleChart/demo.html Generates the HTML content for a tooltip displayed on the TradingView chart. It dynamically formats percentage changes and volume, applying specific styles based on whether the change is positive or negative. The tooltip's position is also adjusted based on the cursor's proximity to the left or right side of the container. ```javascript tooltipHTML += '' + window.description.chgPercent + ':'; tooltipHTML += ''; (isPositive ? '+' : '') + changePercent.toFixed(2) + '%'; tooltipHTML += ''; if (typeof volume === 'number') { tooltipHTML += '