Skip to content

Commit 5157eba

Browse files
committed
feat: add source
1 parent 81807e5 commit 5157eba

18 files changed

Lines changed: 775 additions & 0 deletions
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
name: Publish npm Beta
2+
3+
on:
4+
workflow_dispatch:
5+
push:
6+
tags:
7+
- "js-sdk-v*"
8+
9+
permissions:
10+
contents: read
11+
12+
jobs:
13+
publish:
14+
runs-on: ubuntu-latest
15+
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v4
19+
20+
- name: Setup Node.js
21+
uses: actions/setup-node@v4
22+
with:
23+
node-version: "20"
24+
registry-url: "https://registry.npmjs.org"
25+
26+
- name: Install dependencies
27+
run: npm ci
28+
29+
- name: Validate beta version and tag alignment
30+
shell: bash
31+
run: |
32+
VERSION=$(node -p "require('./package.json').version")
33+
echo "Package version: ${VERSION}"
34+
35+
if [[ "${VERSION}" != *"-beta"* ]]; then
36+
echo "package.json version must include -beta for beta channel publish."
37+
exit 1
38+
fi
39+
40+
if [[ "${GITHUB_REF_TYPE}" == "tag" ]]; then
41+
TAG_VERSION="${GITHUB_REF_NAME#js-sdk-v}"
42+
if [[ "${TAG_VERSION}" != "${VERSION}" ]]; then
43+
echo "Tag/version mismatch. Tag=${TAG_VERSION}, package.json=${VERSION}"
44+
exit 1
45+
fi
46+
fi
47+
48+
- name: Build package
49+
run: npm run build
50+
51+
- name: Publish to npm beta channel
52+
env:
53+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
54+
run: npm publish --tag beta --access public

.gitignore

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.*
7+
.yarn/*
8+
!.yarn/patches
9+
!.yarn/plugins
10+
!.yarn/releases
11+
!.yarn/versions
12+
13+
# testing
14+
/coverage
15+
16+
# next.js
17+
/.next/
18+
/out/
19+
20+
# production
21+
/build
22+
23+
# misc
24+
.DS_Store
25+
*.pem
26+
27+
# debug
28+
npm-debug.log*
29+
yarn-debug.log*
30+
yarn-error.log*
31+
.pnpm-debug.log*
32+
33+
# env files (can opt-in for committing if needed)
34+
.env*
35+
# …but keep example templates committed
36+
!.env*.example
37+
38+
# vercel
39+
.vercel
40+
41+
# typescript
42+
*.tsbuildinfo
43+
next-env.d.ts

README.md

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
# RealMarketAPI JavaScript SDK (Beta)
2+
3+
Official beta JavaScript/TypeScript SDK for RealMarketAPI REST and WebSocket market data endpoints.
4+
5+
Website: https://realmarketapi.com/
6+
7+
## Install
8+
9+
```bash
10+
npm install realmarketapi-js-sdk-beta
11+
```
12+
13+
## Requirements
14+
15+
- Node.js 18+ (recommended).
16+
- RealMarketAPI key.
17+
18+
## Quick Start
19+
20+
### REST
21+
22+
```ts
23+
import { RealMarketApiClient } from "realmarketapi-js-sdk-beta";
24+
25+
const client = new RealMarketApiClient({
26+
apiKey: process.env.REALMARKET_API_KEY!
27+
});
28+
29+
const price = await client.getPrice("EURUSD", "M1");
30+
console.log(price.closePrice);
31+
```
32+
33+
### WebSocket
34+
35+
```ts
36+
import { RealMarketApiWebSocket } from "realmarketapi-js-sdk-beta";
37+
38+
const ws = new RealMarketApiWebSocket({
39+
apiKey: process.env.REALMARKET_API_KEY!
40+
});
41+
42+
const stop = ws.streamPrice("BTCUSDT", "M1", {
43+
onOpen: () => console.log("connected"),
44+
onMessage: msg => console.log(msg),
45+
onError: err => console.error(err),
46+
onClose: () => console.log("closed")
47+
});
48+
49+
setTimeout(() => stop(), 30_000);
50+
```
51+
52+
## Client Configuration
53+
54+
### `RealMarketApiClient`
55+
56+
```ts
57+
const client = new RealMarketApiClient({
58+
apiKey: "YOUR_API_KEY",
59+
baseUrl: "https://api.realmarketapi.com", // optional
60+
fetchImpl: fetch // optional custom fetch
61+
});
62+
```
63+
64+
Options:
65+
- `apiKey` (required): your RealMarketAPI key.
66+
- `baseUrl` (optional): defaults to `https://api.realmarketapi.com`.
67+
- `fetchImpl` (optional): inject a custom fetch implementation.
68+
69+
### `RealMarketApiWebSocket`
70+
71+
```ts
72+
const ws = new RealMarketApiWebSocket({
73+
apiKey: "YOUR_API_KEY",
74+
baseUrl: "https://api.realmarketapi.com", // optional
75+
reconnectDelayMs: 2000 // optional
76+
});
77+
```
78+
79+
Options:
80+
- `apiKey` (required): your RealMarketAPI key.
81+
- `baseUrl` (optional): defaults to `https://api.realmarketapi.com`.
82+
- `reconnectDelayMs` (optional): reconnect delay after disconnect, default `2000` ms.
83+
84+
## REST API Reference
85+
86+
### `getPrice(symbolCode, timeFrame)`
87+
- Returns latest ticker payload for one symbol/timeframe.
88+
89+
### `getCandles(symbolCode, timeFrame)`
90+
- Returns latest candle array for one symbol/timeframe.
91+
92+
### `getHistory(symbolCode, startTime, endTime, pageNumber?, pageSize?)`
93+
- Returns paginated historical ticker data in the provided ISO 8601 time range.
94+
95+
### `getSymbols()`
96+
- Returns list of available symbols.
97+
98+
### `getSma(symbolCode, timeFrame, period?)`
99+
- Returns SMA points for one symbol/timeframe.
100+
101+
## WebSocket API Reference
102+
103+
### `streamPrice(symbolCode, timeFrame, handlers)`
104+
- Streams live price updates.
105+
- Returns a stop function `() => void`.
106+
107+
### `streamCandles(symbolCode, timeFrame, handlers)`
108+
- Streams live candle updates.
109+
- Returns a stop function `() => void`.
110+
111+
Handlers:
112+
- `onMessage(message)` required.
113+
- `onError(error)` optional.
114+
- `onOpen()` optional.
115+
- `onClose()` optional.
116+
117+
## Type Shapes
118+
119+
```ts
120+
type ListResult<T> = { data: T[] };
121+
122+
type PagedResult<T> = {
123+
data: T[];
124+
pageNumber: number;
125+
pageSize: number;
126+
totalPages: number;
127+
totalRecords: number;
128+
};
129+
130+
type PriceTickerResult = {
131+
symbolCode: string;
132+
timeFrame: string;
133+
openTime: string;
134+
closePrice: number;
135+
askPrice?: number;
136+
bidPrice?: number;
137+
};
138+
139+
type PriceCandleResult = {
140+
symbolCode: string;
141+
timeFrame: string;
142+
openTime: string;
143+
openPrice: number;
144+
highPrice: number;
145+
lowPrice: number;
146+
closePrice: number;
147+
volume: number;
148+
};
149+
150+
type SymbolResult = {
151+
symbolCode: string;
152+
name?: string;
153+
category?: string;
154+
};
155+
156+
type IndicatorPoint = {
157+
openTime: string;
158+
value: number;
159+
};
160+
```
161+
162+
## Error Handling
163+
164+
REST methods throw `Error` when the API response is not successful.
165+
166+
```ts
167+
try {
168+
const data = await client.getSymbols();
169+
console.log(data.data.length);
170+
} catch (error) {
171+
console.error("Request failed:", error);
172+
}
173+
```
174+
175+
## Beta Notes
176+
177+
- Current REST scope: price, candles, history, symbols, SMA.
178+
- Current WebSocket scope: price and candles with automatic reconnect.
179+
- API surface may expand before stable `1.0`.
180+
181+
## Links
182+
183+
- Main site: https://realmarketapi.com/
184+
- API base URL default: https://api.realmarketapi.com

dist/client.d.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import type { IndicatorPoint, ListResult, PagedResult, PriceCandleResult, PriceTickerResult, SymbolResult } from "./types.js";
2+
export interface RealMarketApiClientOptions {
3+
apiKey: string;
4+
baseUrl?: string;
5+
fetchImpl?: typeof fetch;
6+
}
7+
export declare class RealMarketApiClient {
8+
private readonly apiKey;
9+
private readonly baseUrl;
10+
private readonly fetchImpl;
11+
constructor(options: RealMarketApiClientOptions);
12+
getPrice(symbolCode: string, timeFrame: string): Promise<PriceTickerResult>;
13+
getCandles(symbolCode: string, timeFrame: string): Promise<ListResult<PriceCandleResult>>;
14+
getHistory(symbolCode: string, startTime: string, endTime: string, pageNumber?: number, pageSize?: number): Promise<PagedResult<PriceTickerResult>>;
15+
getSymbols(): Promise<ListResult<SymbolResult>>;
16+
getSma(symbolCode: string, timeFrame: string, period?: number): Promise<ListResult<IndicatorPoint>>;
17+
private get;
18+
}

dist/client.js

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
export class RealMarketApiClient {
2+
apiKey;
3+
baseUrl;
4+
fetchImpl;
5+
constructor(options) {
6+
this.apiKey = options.apiKey;
7+
this.baseUrl = (options.baseUrl ?? "https://api.realmarketapi.com").replace(/\/$/, "");
8+
this.fetchImpl = options.fetchImpl ?? fetch;
9+
}
10+
async getPrice(symbolCode, timeFrame) {
11+
return this.get("/api/v1/price", { symbolCode, timeFrame });
12+
}
13+
async getCandles(symbolCode, timeFrame) {
14+
return this.get("/api/v1/candle", { symbolCode, timeFrame });
15+
}
16+
async getHistory(symbolCode, startTime, endTime, pageNumber = 1, pageSize = 20) {
17+
return this.get("/api/v1/history", {
18+
symbolCode,
19+
startTime,
20+
endTime,
21+
pageNumber: String(pageNumber),
22+
pageSize: String(pageSize)
23+
});
24+
}
25+
async getSymbols() {
26+
return this.get("/api/v1/symbol");
27+
}
28+
async getSma(symbolCode, timeFrame, period = 20) {
29+
return this.get("/api/v1/indicator/sma", {
30+
symbolCode,
31+
timeFrame,
32+
period: String(period)
33+
});
34+
}
35+
async get(path, query = {}) {
36+
const params = new URLSearchParams({ apiKey: this.apiKey, ...query });
37+
const response = await this.fetchImpl(`${this.baseUrl}${path}?${params.toString()}`);
38+
if (!response.ok) {
39+
const body = await response.text();
40+
throw new Error(`RealMarketApi error ${response.status}: ${body}`);
41+
}
42+
return (await response.json());
43+
}
44+
}

dist/index.d.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./client.js";
2+
export * from "./websocket.js";
3+
export * from "./types.js";

dist/index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export * from "./client.js";
2+
export * from "./websocket.js";
3+
export * from "./types.js";

dist/types.d.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
export interface ListResult<T> {
2+
data: T[];
3+
}
4+
export interface PagedResult<T> {
5+
data: T[];
6+
pageNumber: number;
7+
pageSize: number;
8+
totalPages: number;
9+
totalRecords: number;
10+
}
11+
export interface PriceTickerResult {
12+
symbolCode: string;
13+
timeFrame: string;
14+
openTime: string;
15+
closePrice: number;
16+
askPrice?: number;
17+
bidPrice?: number;
18+
}
19+
export interface PriceCandleResult {
20+
symbolCode: string;
21+
timeFrame: string;
22+
openTime: string;
23+
openPrice: number;
24+
highPrice: number;
25+
lowPrice: number;
26+
closePrice: number;
27+
volume: number;
28+
}
29+
export interface SymbolResult {
30+
symbolCode: string;
31+
name?: string;
32+
category?: string;
33+
}
34+
export interface IndicatorPoint {
35+
openTime: string;
36+
value: number;
37+
}

dist/types.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export {};

0 commit comments

Comments
 (0)