satuchain-api 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +215 -0
- package/dist/cjs/client.cjs +113 -0
- package/dist/cjs/client.js.map +1 -0
- package/dist/cjs/errors.cjs +36 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.cjs +11 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/types.cjs +4 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/esm/client.d.ts +33 -0
- package/dist/esm/client.d.ts.map +1 -0
- package/dist/esm/client.js +109 -0
- package/dist/esm/client.js.map +1 -0
- package/dist/esm/errors.d.ts +17 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +29 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/types.d.ts +65 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +3 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/types/client.d.ts +33 -0
- package/dist/types/client.d.ts.map +1 -0
- package/dist/types/errors.d.ts +17 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/types.d.ts +65 -0
- package/dist/types/types.d.ts.map +1 -0
- package/package.json +45 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SATU TEAM
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
# satuchain-api
|
|
2
|
+
|
|
3
|
+
Official JavaScript/TypeScript SDK for the **SATUCHAIN Developer API** — live forex rates, crypto prices, and commodity data.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/satuchain-api)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
## Requirements
|
|
9
|
+
|
|
10
|
+
- **≥ 10,000 STU** tokens on BNB Chain to generate an API key
|
|
11
|
+
- Get your key at [dev.satuchain.com](https://dev.satuchain.com)
|
|
12
|
+
|
|
13
|
+
## Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install satuchain-api
|
|
17
|
+
# or
|
|
18
|
+
yarn add satuchain-api
|
|
19
|
+
# or
|
|
20
|
+
pnpm add satuchain-api
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
```typescript
|
|
26
|
+
import { SatuChainAPI } from "satuchain-api";
|
|
27
|
+
|
|
28
|
+
const api = new SatuChainAPI("sk_live_YOUR_KEY");
|
|
29
|
+
|
|
30
|
+
const data = await api.getCommodities();
|
|
31
|
+
|
|
32
|
+
// Forex — units per 1 USD
|
|
33
|
+
console.log(data.forex.IDR.value); // e.g. 16250
|
|
34
|
+
console.log(data.forex.MYR.value); // e.g. 4.71
|
|
35
|
+
console.log(data.forex.EUR.value); // e.g. 0.9251
|
|
36
|
+
|
|
37
|
+
// Crypto — price in USD
|
|
38
|
+
console.log(data.crypto.BTC.value); // e.g. 67420.50
|
|
39
|
+
console.log(data.crypto.BNB.value); // e.g. 580.10
|
|
40
|
+
console.log(data.crypto.STU.value); // e.g. 0.00182
|
|
41
|
+
|
|
42
|
+
// Commodities
|
|
43
|
+
console.log(data.commodities.XAU.value); // Gold e.g. 2680.50 (USD/troy oz)
|
|
44
|
+
console.log(data.commodities.XAU.changePercent); // e.g. -0.42 (% from prev close)
|
|
45
|
+
console.log(data.commodities.XAG.value); // Silver e.g. 31.40 (USD/troy oz)
|
|
46
|
+
console.log(data.commodities.COPPER.value); // Copper e.g. 4.20 (USD/lb)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Constructor
|
|
50
|
+
|
|
51
|
+
```typescript
|
|
52
|
+
// Simple — just pass the key
|
|
53
|
+
const api = new SatuChainAPI("sk_live_...");
|
|
54
|
+
|
|
55
|
+
// Full options
|
|
56
|
+
const api = new SatuChainAPI({
|
|
57
|
+
apiKey: "sk_live_...",
|
|
58
|
+
baseUrl: "https://dev.satuchain.com", // optional, default
|
|
59
|
+
timeout: 10000, // optional, ms
|
|
60
|
+
});
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Methods
|
|
64
|
+
|
|
65
|
+
### `getCommodities(opts?)`
|
|
66
|
+
|
|
67
|
+
Fetches all available data in a single request.
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const data = await api.getCommodities();
|
|
71
|
+
// data.crypto — BTC, BNB, STU
|
|
72
|
+
// data.forex — CNY, EUR, IDR, JPY, MYR, NGN, SGD, VND
|
|
73
|
+
// data.commodities — XAU, XAG, COPPER
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### `getForex(opts?)`
|
|
77
|
+
|
|
78
|
+
Returns only forex rates.
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const forex = await api.getForex();
|
|
82
|
+
console.log(forex.IDR.value); // IDR per 1 USD
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### `getCrypto(opts?)`
|
|
86
|
+
|
|
87
|
+
Returns only crypto prices.
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
const crypto = await api.getCrypto();
|
|
91
|
+
console.log(crypto.BTC.value); // USD
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### `getMetals(opts?)`
|
|
95
|
+
|
|
96
|
+
Returns only commodity prices.
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
const metals = await api.getMetals();
|
|
100
|
+
console.log(metals.XAU.value); // USD/troy oz
|
|
101
|
+
console.log(metals.XAU.changePercent); // % change from prev close
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Rate Limits
|
|
105
|
+
|
|
106
|
+
Each API key is limited to **60 requests per minute**. Rate limit info is available after any request:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
const data = await api.getCommodities();
|
|
110
|
+
|
|
111
|
+
console.log(api.rateLimit);
|
|
112
|
+
// { limit: 60, remaining: 59, resetAt: 1712345678 }
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
On rate limit exceeded, a `SatuChainRateLimitError` is thrown with a `retryAfter` field (seconds):
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { SatuChainRateLimitError } from "satuchain-api";
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
const data = await api.getCommodities();
|
|
122
|
+
} catch (err) {
|
|
123
|
+
if (err instanceof SatuChainRateLimitError) {
|
|
124
|
+
console.log(`Retry after ${err.retryAfter}s`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Error Handling
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import {
|
|
133
|
+
SatuChainAuthError,
|
|
134
|
+
SatuChainRateLimitError,
|
|
135
|
+
SatuChainUpstreamError,
|
|
136
|
+
SatuChainError,
|
|
137
|
+
} from "satuchain-api";
|
|
138
|
+
|
|
139
|
+
try {
|
|
140
|
+
const data = await api.getCommodities();
|
|
141
|
+
} catch (err) {
|
|
142
|
+
if (err instanceof SatuChainAuthError) {
|
|
143
|
+
// 401 — invalid or revoked API key
|
|
144
|
+
} else if (err instanceof SatuChainRateLimitError) {
|
|
145
|
+
// 429 — slow down, check err.retryAfter
|
|
146
|
+
} else if (err instanceof SatuChainUpstreamError) {
|
|
147
|
+
// 502 — upstream data source unavailable
|
|
148
|
+
} else if (err instanceof SatuChainError) {
|
|
149
|
+
// network timeout or other SDK error
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## Request Cancellation
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
const controller = new AbortController();
|
|
158
|
+
|
|
159
|
+
setTimeout(() => controller.abort(), 3000);
|
|
160
|
+
|
|
161
|
+
const data = await api.getCommodities({ signal: controller.signal });
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## CommonJS
|
|
165
|
+
|
|
166
|
+
```javascript
|
|
167
|
+
const { SatuChainAPI } = require("satuchain-api");
|
|
168
|
+
|
|
169
|
+
const api = new SatuChainAPI("sk_live_YOUR_KEY");
|
|
170
|
+
api.getCommodities().then((data) => {
|
|
171
|
+
console.log(data.forex.IDR.value);
|
|
172
|
+
});
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Response Shape
|
|
176
|
+
|
|
177
|
+
```typescript
|
|
178
|
+
{
|
|
179
|
+
ok: true,
|
|
180
|
+
base: "USD",
|
|
181
|
+
updatedAtUnix: 1712345600, // forex update time
|
|
182
|
+
nextUpdateUnix: 1712349200,
|
|
183
|
+
crypto: {
|
|
184
|
+
BTC: { name: "Bitcoin", value: 67420.50 },
|
|
185
|
+
BNB: { name: "BNB", value: 580.10 },
|
|
186
|
+
STU: { name: "SATU Token", value: 0.00182 }
|
|
187
|
+
},
|
|
188
|
+
forex: {
|
|
189
|
+
CNY: { name: "Chinese Yuan", value: 7.2412 },
|
|
190
|
+
EUR: { name: "Euro", value: 0.9251 },
|
|
191
|
+
IDR: { name: "Indonesian Rupiah", value: 16250 },
|
|
192
|
+
JPY: { name: "Japanese Yen", value: 151.82 },
|
|
193
|
+
MYR: { name: "Malaysian Ringgit", value: 4.7120 },
|
|
194
|
+
NGN: { name: "Nigerian Naira", value: 1580 },
|
|
195
|
+
SGD: { name: "Singapore Dollar", value: 1.3510 },
|
|
196
|
+
VND: { name: "Vietnamese Dong", value: 25100 }
|
|
197
|
+
},
|
|
198
|
+
commodities: {
|
|
199
|
+
XAU: { name: "Gold", value: 2680.50, changePercent: -0.42, unit: "USD/troy oz" },
|
|
200
|
+
XAG: { name: "Silver", value: 31.40, changePercent: 0.81, unit: "USD/troy oz" },
|
|
201
|
+
COPPER: { name: "Copper", value: 4.20, changePercent: -0.15, unit: "USD/lb" }
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Links
|
|
207
|
+
|
|
208
|
+
- **API Portal**: [dev.satuchain.com](https://dev.satuchain.com)
|
|
209
|
+
- **SATUCHAIN**: [satuchain.com](https://satuchain.com)
|
|
210
|
+
- **X (Twitter)**: [@SatuChain](https://x.com/SatuChain)
|
|
211
|
+
- **Telegram**: [t.me/satuchain](https://t.me/satuchain)
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
MIT — see [LICENSE](LICENSE)
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SatuChainAPI = void 0;
|
|
4
|
+
const errors_js_1 = require("./errors.js");
|
|
5
|
+
const DEFAULT_BASE_URL = "https://dev.satuchain.com";
|
|
6
|
+
const DEFAULT_TIMEOUT = 10000;
|
|
7
|
+
class SatuChainAPI {
|
|
8
|
+
constructor(options) {
|
|
9
|
+
/** Last rate-limit info from the most recent response */
|
|
10
|
+
this.rateLimit = null;
|
|
11
|
+
if (typeof options === "string") {
|
|
12
|
+
this.apiKey = options;
|
|
13
|
+
this.baseUrl = DEFAULT_BASE_URL;
|
|
14
|
+
this.timeout = DEFAULT_TIMEOUT;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
this.apiKey = options.apiKey;
|
|
18
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
19
|
+
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
20
|
+
}
|
|
21
|
+
if (!this.apiKey.startsWith("sk_live_")) {
|
|
22
|
+
throw new errors_js_1.SatuChainError("API key must start with sk_live_");
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
async request(path, opts) {
|
|
26
|
+
const controller = new AbortController();
|
|
27
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
28
|
+
const signal = opts?.signal
|
|
29
|
+
? AbortSignal.any
|
|
30
|
+
? AbortSignal.any([opts.signal, controller.signal])
|
|
31
|
+
: controller.signal
|
|
32
|
+
: controller.signal;
|
|
33
|
+
let res;
|
|
34
|
+
try {
|
|
35
|
+
res = await fetch(`${this.baseUrl}${path}`, {
|
|
36
|
+
method: "GET",
|
|
37
|
+
headers: {
|
|
38
|
+
"X-API-Key": this.apiKey,
|
|
39
|
+
"Accept": "application/json",
|
|
40
|
+
"User-Agent": "satuchain-sdk/1.0.1",
|
|
41
|
+
},
|
|
42
|
+
signal,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
catch (err) {
|
|
46
|
+
clearTimeout(timer);
|
|
47
|
+
if (err?.name === "AbortError") {
|
|
48
|
+
throw new errors_js_1.SatuChainError(`Request timed out after ${this.timeout}ms`);
|
|
49
|
+
}
|
|
50
|
+
throw new errors_js_1.SatuChainError(`Network error: ${err?.message ?? err}`);
|
|
51
|
+
}
|
|
52
|
+
clearTimeout(timer);
|
|
53
|
+
// Parse rate-limit headers
|
|
54
|
+
const rlLimit = parseInt(res.headers.get("x-ratelimit-limit") ?? "");
|
|
55
|
+
const rlRemaining = parseInt(res.headers.get("x-ratelimit-remaining") ?? "");
|
|
56
|
+
const rlReset = parseInt(res.headers.get("x-ratelimit-reset") ?? "");
|
|
57
|
+
if (!isNaN(rlLimit)) {
|
|
58
|
+
this.rateLimit = { limit: rlLimit, remaining: rlRemaining, resetAt: rlReset };
|
|
59
|
+
}
|
|
60
|
+
if (res.status === 401) {
|
|
61
|
+
const body = await res.json().catch(() => ({}));
|
|
62
|
+
throw new errors_js_1.SatuChainAuthError(body?.error);
|
|
63
|
+
}
|
|
64
|
+
if (res.status === 429) {
|
|
65
|
+
const retryAfter = parseInt(res.headers.get("retry-after") ?? "60");
|
|
66
|
+
const body = await res.json().catch(() => ({}));
|
|
67
|
+
throw new errors_js_1.SatuChainRateLimitError(retryAfter, body?.error);
|
|
68
|
+
}
|
|
69
|
+
if (!res.ok) {
|
|
70
|
+
throw new errors_js_1.SatuChainUpstreamError(res.status);
|
|
71
|
+
}
|
|
72
|
+
const json = await res.json();
|
|
73
|
+
if (!json.ok) {
|
|
74
|
+
throw new errors_js_1.SatuChainError(json.error ?? "API error");
|
|
75
|
+
}
|
|
76
|
+
return json;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Fetch live commodity, forex, and crypto price data.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* const data = await api.getCommodities();
|
|
83
|
+
* console.log(data.forex.IDR.value); // IDR per 1 USD
|
|
84
|
+
* console.log(data.crypto.BTC.value); // BTC price in USD
|
|
85
|
+
* console.log(data.commodities.XAU.value); // Gold price in USD/troy oz
|
|
86
|
+
*/
|
|
87
|
+
async getCommodities(opts) {
|
|
88
|
+
return this.request("/api/commodities", opts);
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Get just the forex rates (subset of getCommodities).
|
|
92
|
+
*/
|
|
93
|
+
async getForex(opts) {
|
|
94
|
+
const data = await this.getCommodities(opts);
|
|
95
|
+
return data.forex;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Get just the crypto prices (subset of getCommodities).
|
|
99
|
+
*/
|
|
100
|
+
async getCrypto(opts) {
|
|
101
|
+
const data = await this.getCommodities(opts);
|
|
102
|
+
return data.crypto;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Get just the commodity prices (subset of getCommodities).
|
|
106
|
+
*/
|
|
107
|
+
async getMetals(opts) {
|
|
108
|
+
const data = await this.getCommodities(opts);
|
|
109
|
+
return data.commodities;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
exports.SatuChainAPI = SatuChainAPI;
|
|
113
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SatuChainUpstreamError = exports.SatuChainRateLimitError = exports.SatuChainAuthError = exports.SatuChainError = void 0;
|
|
4
|
+
class SatuChainError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.name = "SatuChainError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.SatuChainError = SatuChainError;
|
|
11
|
+
class SatuChainAuthError extends SatuChainError {
|
|
12
|
+
constructor(message = "Invalid or missing API key") {
|
|
13
|
+
super(message);
|
|
14
|
+
this.status = 401;
|
|
15
|
+
this.name = "SatuChainAuthError";
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
exports.SatuChainAuthError = SatuChainAuthError;
|
|
19
|
+
class SatuChainRateLimitError extends SatuChainError {
|
|
20
|
+
constructor(retryAfter, message) {
|
|
21
|
+
super(message ?? `Rate limit exceeded. Retry after ${retryAfter}s`);
|
|
22
|
+
this.status = 429;
|
|
23
|
+
this.name = "SatuChainRateLimitError";
|
|
24
|
+
this.retryAfter = retryAfter;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.SatuChainRateLimitError = SatuChainRateLimitError;
|
|
28
|
+
class SatuChainUpstreamError extends SatuChainError {
|
|
29
|
+
constructor(status, message) {
|
|
30
|
+
super(message ?? `Upstream error: ${status}`);
|
|
31
|
+
this.name = "SatuChainUpstreamError";
|
|
32
|
+
this.status = status;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.SatuChainUpstreamError = SatuChainUpstreamError;
|
|
36
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":";;;AAAA,MAAa,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AALD,wCAKC;AAED,MAAa,kBAAmB,SAAQ,cAAc;IAEpD,YAAY,OAAO,GAAG,4BAA4B;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC;QAFR,WAAM,GAAG,GAAG,CAAC;QAGpB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAND,gDAMC;AAED,MAAa,uBAAwB,SAAQ,cAAc;IAGzD,YAAY,UAAkB,EAAE,OAAgB;QAC9C,KAAK,CAAC,OAAO,IAAI,oCAAoC,UAAU,GAAG,CAAC,CAAC;QAH7D,WAAM,GAAG,GAAG,CAAC;QAIpB,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AARD,0DAQC;AAED,MAAa,sBAAuB,SAAQ,cAAc;IAExD,YAAY,MAAc,EAAE,OAAgB;QAC1C,KAAK,CAAC,OAAO,IAAI,mBAAmB,MAAM,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF;AAPD,wDAOC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SatuChainUpstreamError = exports.SatuChainRateLimitError = exports.SatuChainAuthError = exports.SatuChainError = exports.SatuChainAPI = void 0;
|
|
4
|
+
var client_js_1 = require("./client.js");
|
|
5
|
+
Object.defineProperty(exports, "SatuChainAPI", { enumerable: true, get: function () { return client_js_1.SatuChainAPI; } });
|
|
6
|
+
var errors_js_1 = require("./errors.js");
|
|
7
|
+
Object.defineProperty(exports, "SatuChainError", { enumerable: true, get: function () { return errors_js_1.SatuChainError; } });
|
|
8
|
+
Object.defineProperty(exports, "SatuChainAuthError", { enumerable: true, get: function () { return errors_js_1.SatuChainAuthError; } });
|
|
9
|
+
Object.defineProperty(exports, "SatuChainRateLimitError", { enumerable: true, get: function () { return errors_js_1.SatuChainRateLimitError; } });
|
|
10
|
+
Object.defineProperty(exports, "SatuChainUpstreamError", { enumerable: true, get: function () { return errors_js_1.SatuChainUpstreamError; } });
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;AAAA,yCAA2C;AAAlC,yGAAA,YAAY,OAAA;AACrB,yCAKqB;AAJnB,2GAAA,cAAc,OAAA;AACd,+GAAA,kBAAkB,OAAA;AAClB,oHAAA,uBAAuB,OAAA;AACvB,mHAAA,sBAAsB,OAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":";AAAA,gFAAgF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SatuChainAPIOptions, RequestOptions, CommoditiesResponse, RateLimitInfo } from "./types.js";
|
|
2
|
+
export declare class SatuChainAPI {
|
|
3
|
+
private readonly apiKey;
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
private readonly timeout;
|
|
6
|
+
/** Last rate-limit info from the most recent response */
|
|
7
|
+
rateLimit: RateLimitInfo | null;
|
|
8
|
+
constructor(options: SatuChainAPIOptions | string);
|
|
9
|
+
private request;
|
|
10
|
+
/**
|
|
11
|
+
* Fetch live commodity, forex, and crypto price data.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const data = await api.getCommodities();
|
|
15
|
+
* console.log(data.forex.IDR.value); // IDR per 1 USD
|
|
16
|
+
* console.log(data.crypto.BTC.value); // BTC price in USD
|
|
17
|
+
* console.log(data.commodities.XAU.value); // Gold price in USD/troy oz
|
|
18
|
+
*/
|
|
19
|
+
getCommodities(opts?: RequestOptions): Promise<CommoditiesResponse>;
|
|
20
|
+
/**
|
|
21
|
+
* Get just the forex rates (subset of getCommodities).
|
|
22
|
+
*/
|
|
23
|
+
getForex(opts?: RequestOptions): Promise<CommoditiesResponse["forex"]>;
|
|
24
|
+
/**
|
|
25
|
+
* Get just the crypto prices (subset of getCommodities).
|
|
26
|
+
*/
|
|
27
|
+
getCrypto(opts?: RequestOptions): Promise<CommoditiesResponse["crypto"]>;
|
|
28
|
+
/**
|
|
29
|
+
* Get just the commodity prices (subset of getCommodities).
|
|
30
|
+
*/
|
|
31
|
+
getMetals(opts?: RequestOptions): Promise<CommoditiesResponse["commodities"]>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AAWpB,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,yDAAyD;IAClD,SAAS,EAAE,aAAa,GAAG,IAAI,CAAQ;gBAElC,OAAO,EAAE,mBAAmB,GAAG,MAAM;YAgBnC,OAAO;IAiErB;;;;;;;;OAQG;IACG,cAAc,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIzE;;OAEG;IACG,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAK5E;;OAEG;IACG,SAAS,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAK9E;;OAEG;IACG,SAAS,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;CAIpF"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { SatuChainAuthError, SatuChainRateLimitError, SatuChainUpstreamError, SatuChainError, } from "./errors.js";
|
|
2
|
+
const DEFAULT_BASE_URL = "https://dev.satuchain.com";
|
|
3
|
+
const DEFAULT_TIMEOUT = 10000;
|
|
4
|
+
export class SatuChainAPI {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
/** Last rate-limit info from the most recent response */
|
|
7
|
+
this.rateLimit = null;
|
|
8
|
+
if (typeof options === "string") {
|
|
9
|
+
this.apiKey = options;
|
|
10
|
+
this.baseUrl = DEFAULT_BASE_URL;
|
|
11
|
+
this.timeout = DEFAULT_TIMEOUT;
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
this.apiKey = options.apiKey;
|
|
15
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
|
|
16
|
+
this.timeout = options.timeout ?? DEFAULT_TIMEOUT;
|
|
17
|
+
}
|
|
18
|
+
if (!this.apiKey.startsWith("sk_live_")) {
|
|
19
|
+
throw new SatuChainError("API key must start with sk_live_");
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
async request(path, opts) {
|
|
23
|
+
const controller = new AbortController();
|
|
24
|
+
const timer = setTimeout(() => controller.abort(), this.timeout);
|
|
25
|
+
const signal = opts?.signal
|
|
26
|
+
? AbortSignal.any
|
|
27
|
+
? AbortSignal.any([opts.signal, controller.signal])
|
|
28
|
+
: controller.signal
|
|
29
|
+
: controller.signal;
|
|
30
|
+
let res;
|
|
31
|
+
try {
|
|
32
|
+
res = await fetch(`${this.baseUrl}${path}`, {
|
|
33
|
+
method: "GET",
|
|
34
|
+
headers: {
|
|
35
|
+
"X-API-Key": this.apiKey,
|
|
36
|
+
"Accept": "application/json",
|
|
37
|
+
"User-Agent": "satuchain-sdk/1.0.1",
|
|
38
|
+
},
|
|
39
|
+
signal,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
clearTimeout(timer);
|
|
44
|
+
if (err?.name === "AbortError") {
|
|
45
|
+
throw new SatuChainError(`Request timed out after ${this.timeout}ms`);
|
|
46
|
+
}
|
|
47
|
+
throw new SatuChainError(`Network error: ${err?.message ?? err}`);
|
|
48
|
+
}
|
|
49
|
+
clearTimeout(timer);
|
|
50
|
+
// Parse rate-limit headers
|
|
51
|
+
const rlLimit = parseInt(res.headers.get("x-ratelimit-limit") ?? "");
|
|
52
|
+
const rlRemaining = parseInt(res.headers.get("x-ratelimit-remaining") ?? "");
|
|
53
|
+
const rlReset = parseInt(res.headers.get("x-ratelimit-reset") ?? "");
|
|
54
|
+
if (!isNaN(rlLimit)) {
|
|
55
|
+
this.rateLimit = { limit: rlLimit, remaining: rlRemaining, resetAt: rlReset };
|
|
56
|
+
}
|
|
57
|
+
if (res.status === 401) {
|
|
58
|
+
const body = await res.json().catch(() => ({}));
|
|
59
|
+
throw new SatuChainAuthError(body?.error);
|
|
60
|
+
}
|
|
61
|
+
if (res.status === 429) {
|
|
62
|
+
const retryAfter = parseInt(res.headers.get("retry-after") ?? "60");
|
|
63
|
+
const body = await res.json().catch(() => ({}));
|
|
64
|
+
throw new SatuChainRateLimitError(retryAfter, body?.error);
|
|
65
|
+
}
|
|
66
|
+
if (!res.ok) {
|
|
67
|
+
throw new SatuChainUpstreamError(res.status);
|
|
68
|
+
}
|
|
69
|
+
const json = await res.json();
|
|
70
|
+
if (!json.ok) {
|
|
71
|
+
throw new SatuChainError(json.error ?? "API error");
|
|
72
|
+
}
|
|
73
|
+
return json;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Fetch live commodity, forex, and crypto price data.
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
* const data = await api.getCommodities();
|
|
80
|
+
* console.log(data.forex.IDR.value); // IDR per 1 USD
|
|
81
|
+
* console.log(data.crypto.BTC.value); // BTC price in USD
|
|
82
|
+
* console.log(data.commodities.XAU.value); // Gold price in USD/troy oz
|
|
83
|
+
*/
|
|
84
|
+
async getCommodities(opts) {
|
|
85
|
+
return this.request("/api/commodities", opts);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Get just the forex rates (subset of getCommodities).
|
|
89
|
+
*/
|
|
90
|
+
async getForex(opts) {
|
|
91
|
+
const data = await this.getCommodities(opts);
|
|
92
|
+
return data.forex;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Get just the crypto prices (subset of getCommodities).
|
|
96
|
+
*/
|
|
97
|
+
async getCrypto(opts) {
|
|
98
|
+
const data = await this.getCommodities(opts);
|
|
99
|
+
return data.crypto;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Get just the commodity prices (subset of getCommodities).
|
|
103
|
+
*/
|
|
104
|
+
async getMetals(opts) {
|
|
105
|
+
const data = await this.getCommodities(opts);
|
|
106
|
+
return data.commodities;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class SatuChainError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class SatuChainAuthError extends SatuChainError {
|
|
5
|
+
readonly status = 401;
|
|
6
|
+
constructor(message?: string);
|
|
7
|
+
}
|
|
8
|
+
export declare class SatuChainRateLimitError extends SatuChainError {
|
|
9
|
+
readonly status = 429;
|
|
10
|
+
readonly retryAfter: number;
|
|
11
|
+
constructor(retryAfter: number, message?: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class SatuChainUpstreamError extends SatuChainError {
|
|
14
|
+
readonly status: number;
|
|
15
|
+
constructor(status: number, message?: string);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,SAA+B;CAInD;AAED,qBAAa,uBAAwB,SAAQ,cAAc;IACzD,QAAQ,CAAC,MAAM,OAAO;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAChB,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAKjD;AAED,qBAAa,sBAAuB,SAAQ,cAAc;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAK7C"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export class SatuChainError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = "SatuChainError";
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
export class SatuChainAuthError extends SatuChainError {
|
|
8
|
+
constructor(message = "Invalid or missing API key") {
|
|
9
|
+
super(message);
|
|
10
|
+
this.status = 401;
|
|
11
|
+
this.name = "SatuChainAuthError";
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export class SatuChainRateLimitError extends SatuChainError {
|
|
15
|
+
constructor(retryAfter, message) {
|
|
16
|
+
super(message ?? `Rate limit exceeded. Retry after ${retryAfter}s`);
|
|
17
|
+
this.status = 429;
|
|
18
|
+
this.name = "SatuChainRateLimitError";
|
|
19
|
+
this.retryAfter = retryAfter;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class SatuChainUpstreamError extends SatuChainError {
|
|
23
|
+
constructor(status, message) {
|
|
24
|
+
super(message ?? `Upstream error: ${status}`);
|
|
25
|
+
this.name = "SatuChainUpstreamError";
|
|
26
|
+
this.status = status;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,cAAe,SAAQ,KAAK;IACvC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,cAAc;IAEpD,YAAY,OAAO,GAAG,4BAA4B;QAChD,KAAK,CAAC,OAAO,CAAC,CAAC;QAFR,WAAM,GAAG,GAAG,CAAC;QAGpB,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,uBAAwB,SAAQ,cAAc;IAGzD,YAAY,UAAkB,EAAE,OAAgB;QAC9C,KAAK,CAAC,OAAO,IAAI,oCAAoC,UAAU,GAAG,CAAC,CAAC;QAH7D,WAAM,GAAG,GAAG,CAAC;QAIpB,IAAI,CAAC,IAAI,GAAG,yBAAyB,CAAC;QACtC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,sBAAuB,SAAQ,cAAc;IAExD,YAAY,MAAc,EAAE,OAAgB;QAC1C,KAAK,CAAC,OAAO,IAAI,mBAAmB,MAAM,EAAE,CAAC,CAAC;QAC9C,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC;QACrC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { SatuChainAPI } from "./client.js";
|
|
2
|
+
export { SatuChainError, SatuChainAuthError, SatuChainRateLimitError, SatuChainUpstreamError, } from "./errors.js";
|
|
3
|
+
export type { SatuChainAPIOptions, RequestOptions, CommoditiesResponse, ForexEntry, CryptoEntry, CommodityEntry, RateLimitInfo, } from "./types.js";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export interface ForexEntry {
|
|
2
|
+
name: string;
|
|
3
|
+
/** Units of this currency per 1 USD */
|
|
4
|
+
value: number | null;
|
|
5
|
+
}
|
|
6
|
+
export interface CryptoEntry {
|
|
7
|
+
name: string;
|
|
8
|
+
/** Price in USD */
|
|
9
|
+
value: number | null;
|
|
10
|
+
}
|
|
11
|
+
export interface CommodityEntry {
|
|
12
|
+
name: string;
|
|
13
|
+
/** Price in USD per unit (troy oz for XAU/XAG, lb for COPPER) */
|
|
14
|
+
value: number | null;
|
|
15
|
+
/** Percentage change from previous close (positive = up, negative = down) */
|
|
16
|
+
changePercent?: number | null;
|
|
17
|
+
/** Unit description e.g. "USD/troy oz" */
|
|
18
|
+
unit?: string;
|
|
19
|
+
note?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface RateLimitInfo {
|
|
22
|
+
limit: number;
|
|
23
|
+
remaining: number;
|
|
24
|
+
resetAt: number;
|
|
25
|
+
}
|
|
26
|
+
export interface CommoditiesResponse {
|
|
27
|
+
ok: true;
|
|
28
|
+
base: "USD";
|
|
29
|
+
updatedAtUnix: number | null;
|
|
30
|
+
nextUpdateUnix: number | null;
|
|
31
|
+
crypto: {
|
|
32
|
+
BTC: CryptoEntry;
|
|
33
|
+
BNB: CryptoEntry;
|
|
34
|
+
STU: CryptoEntry;
|
|
35
|
+
};
|
|
36
|
+
forex: {
|
|
37
|
+
CNY: ForexEntry;
|
|
38
|
+
EUR: ForexEntry;
|
|
39
|
+
IDR: ForexEntry;
|
|
40
|
+
JPY: ForexEntry;
|
|
41
|
+
MYR: ForexEntry;
|
|
42
|
+
NGN: ForexEntry;
|
|
43
|
+
SGD: ForexEntry;
|
|
44
|
+
VND: ForexEntry;
|
|
45
|
+
[key: string]: ForexEntry;
|
|
46
|
+
};
|
|
47
|
+
commodities: {
|
|
48
|
+
XAU: CommodityEntry;
|
|
49
|
+
XAG: CommodityEntry;
|
|
50
|
+
COPPER: CommodityEntry;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export interface SatuChainAPIOptions {
|
|
54
|
+
/** Your API key — starts with sk_live_ */
|
|
55
|
+
apiKey: string;
|
|
56
|
+
/** Base URL (default: https://dev.satuchain.com) */
|
|
57
|
+
baseUrl?: string;
|
|
58
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
59
|
+
timeout?: number;
|
|
60
|
+
}
|
|
61
|
+
export interface RequestOptions {
|
|
62
|
+
/** AbortSignal for cancellation */
|
|
63
|
+
signal?: AbortSignal;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,KAAK,CAAC;IACZ,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE;QACN,GAAG,EAAE,WAAW,CAAC;QACjB,GAAG,EAAE,WAAW,CAAC;QACjB,GAAG,EAAE,WAAW,CAAC;KAClB,CAAC;IACF,KAAK,EAAE;QACL,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;KAC3B,CAAC;IACF,WAAW,EAAE;QACX,GAAG,EAAE,cAAc,CAAC;QACpB,GAAG,EAAE,cAAc,CAAC;QACpB,MAAM,EAAE,cAAc,CAAC;KACxB,CAAC;CACH;AAID,MAAM,WAAW,mBAAmB;IAClC,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,gFAAgF"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { SatuChainAPIOptions, RequestOptions, CommoditiesResponse, RateLimitInfo } from "./types.js";
|
|
2
|
+
export declare class SatuChainAPI {
|
|
3
|
+
private readonly apiKey;
|
|
4
|
+
private readonly baseUrl;
|
|
5
|
+
private readonly timeout;
|
|
6
|
+
/** Last rate-limit info from the most recent response */
|
|
7
|
+
rateLimit: RateLimitInfo | null;
|
|
8
|
+
constructor(options: SatuChainAPIOptions | string);
|
|
9
|
+
private request;
|
|
10
|
+
/**
|
|
11
|
+
* Fetch live commodity, forex, and crypto price data.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* const data = await api.getCommodities();
|
|
15
|
+
* console.log(data.forex.IDR.value); // IDR per 1 USD
|
|
16
|
+
* console.log(data.crypto.BTC.value); // BTC price in USD
|
|
17
|
+
* console.log(data.commodities.XAU.value); // Gold price in USD/troy oz
|
|
18
|
+
*/
|
|
19
|
+
getCommodities(opts?: RequestOptions): Promise<CommoditiesResponse>;
|
|
20
|
+
/**
|
|
21
|
+
* Get just the forex rates (subset of getCommodities).
|
|
22
|
+
*/
|
|
23
|
+
getForex(opts?: RequestOptions): Promise<CommoditiesResponse["forex"]>;
|
|
24
|
+
/**
|
|
25
|
+
* Get just the crypto prices (subset of getCommodities).
|
|
26
|
+
*/
|
|
27
|
+
getCrypto(opts?: RequestOptions): Promise<CommoditiesResponse["crypto"]>;
|
|
28
|
+
/**
|
|
29
|
+
* Get just the commodity prices (subset of getCommodities).
|
|
30
|
+
*/
|
|
31
|
+
getMetals(opts?: RequestOptions): Promise<CommoditiesResponse["commodities"]>;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,aAAa,EACd,MAAM,YAAY,CAAC;AAWpB,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IAEjC,yDAAyD;IAClD,SAAS,EAAE,aAAa,GAAG,IAAI,CAAQ;gBAElC,OAAO,EAAE,mBAAmB,GAAG,MAAM;YAgBnC,OAAO;IAiErB;;;;;;;;OAQG;IACG,cAAc,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC;IAIzE;;OAEG;IACG,QAAQ,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAK5E;;OAEG;IACG,SAAS,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAK9E;;OAEG;IACG,SAAS,CAAC,IAAI,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;CAIpF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare class SatuChainError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
export declare class SatuChainAuthError extends SatuChainError {
|
|
5
|
+
readonly status = 401;
|
|
6
|
+
constructor(message?: string);
|
|
7
|
+
}
|
|
8
|
+
export declare class SatuChainRateLimitError extends SatuChainError {
|
|
9
|
+
readonly status = 429;
|
|
10
|
+
readonly retryAfter: number;
|
|
11
|
+
constructor(retryAfter: number, message?: string);
|
|
12
|
+
}
|
|
13
|
+
export declare class SatuChainUpstreamError extends SatuChainError {
|
|
14
|
+
readonly status: number;
|
|
15
|
+
constructor(status: number, message?: string);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,cAAe,SAAQ,KAAK;gBAC3B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,kBAAmB,SAAQ,cAAc;IACpD,QAAQ,CAAC,MAAM,OAAO;gBACV,OAAO,SAA+B;CAInD;AAED,qBAAa,uBAAwB,SAAQ,cAAc;IACzD,QAAQ,CAAC,MAAM,OAAO;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAChB,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAKjD;AAED,qBAAa,sBAAuB,SAAQ,cAAc;IACxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;gBACZ,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;CAK7C"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { SatuChainAPI } from "./client.js";
|
|
2
|
+
export { SatuChainError, SatuChainAuthError, SatuChainRateLimitError, SatuChainUpstreamError, } from "./errors.js";
|
|
3
|
+
export type { SatuChainAPIOptions, RequestOptions, CommoditiesResponse, ForexEntry, CryptoEntry, CommodityEntry, RateLimitInfo, } from "./types.js";
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,GACvB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,mBAAmB,EACnB,cAAc,EACd,mBAAmB,EACnB,UAAU,EACV,WAAW,EACX,cAAc,EACd,aAAa,GACd,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export interface ForexEntry {
|
|
2
|
+
name: string;
|
|
3
|
+
/** Units of this currency per 1 USD */
|
|
4
|
+
value: number | null;
|
|
5
|
+
}
|
|
6
|
+
export interface CryptoEntry {
|
|
7
|
+
name: string;
|
|
8
|
+
/** Price in USD */
|
|
9
|
+
value: number | null;
|
|
10
|
+
}
|
|
11
|
+
export interface CommodityEntry {
|
|
12
|
+
name: string;
|
|
13
|
+
/** Price in USD per unit (troy oz for XAU/XAG, lb for COPPER) */
|
|
14
|
+
value: number | null;
|
|
15
|
+
/** Percentage change from previous close (positive = up, negative = down) */
|
|
16
|
+
changePercent?: number | null;
|
|
17
|
+
/** Unit description e.g. "USD/troy oz" */
|
|
18
|
+
unit?: string;
|
|
19
|
+
note?: string;
|
|
20
|
+
}
|
|
21
|
+
export interface RateLimitInfo {
|
|
22
|
+
limit: number;
|
|
23
|
+
remaining: number;
|
|
24
|
+
resetAt: number;
|
|
25
|
+
}
|
|
26
|
+
export interface CommoditiesResponse {
|
|
27
|
+
ok: true;
|
|
28
|
+
base: "USD";
|
|
29
|
+
updatedAtUnix: number | null;
|
|
30
|
+
nextUpdateUnix: number | null;
|
|
31
|
+
crypto: {
|
|
32
|
+
BTC: CryptoEntry;
|
|
33
|
+
BNB: CryptoEntry;
|
|
34
|
+
STU: CryptoEntry;
|
|
35
|
+
};
|
|
36
|
+
forex: {
|
|
37
|
+
CNY: ForexEntry;
|
|
38
|
+
EUR: ForexEntry;
|
|
39
|
+
IDR: ForexEntry;
|
|
40
|
+
JPY: ForexEntry;
|
|
41
|
+
MYR: ForexEntry;
|
|
42
|
+
NGN: ForexEntry;
|
|
43
|
+
SGD: ForexEntry;
|
|
44
|
+
VND: ForexEntry;
|
|
45
|
+
[key: string]: ForexEntry;
|
|
46
|
+
};
|
|
47
|
+
commodities: {
|
|
48
|
+
XAU: CommodityEntry;
|
|
49
|
+
XAG: CommodityEntry;
|
|
50
|
+
COPPER: CommodityEntry;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
export interface SatuChainAPIOptions {
|
|
54
|
+
/** Your API key — starts with sk_live_ */
|
|
55
|
+
apiKey: string;
|
|
56
|
+
/** Base URL (default: https://dev.satuchain.com) */
|
|
57
|
+
baseUrl?: string;
|
|
58
|
+
/** Request timeout in milliseconds (default: 10000) */
|
|
59
|
+
timeout?: number;
|
|
60
|
+
}
|
|
61
|
+
export interface RequestOptions {
|
|
62
|
+
/** AbortSignal for cancellation */
|
|
63
|
+
signal?: AbortSignal;
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,uCAAuC;IACvC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,6EAA6E;IAC7E,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,IAAI,CAAC;IACT,IAAI,EAAE,KAAK,CAAC;IACZ,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,MAAM,EAAE;QACN,GAAG,EAAE,WAAW,CAAC;QACjB,GAAG,EAAE,WAAW,CAAC;QACjB,GAAG,EAAE,WAAW,CAAC;KAClB,CAAC;IACF,KAAK,EAAE;QACL,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,GAAG,EAAE,UAAU,CAAC;QAChB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CAAC;KAC3B,CAAC;IACF,WAAW,EAAE;QACX,GAAG,EAAE,cAAc,CAAC;QACpB,GAAG,EAAE,cAAc,CAAC;QACpB,MAAM,EAAE,cAAc,CAAC;KACxB,CAAC;CACH;AAID,MAAM,WAAW,mBAAmB;IAClC,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,mCAAmC;IACnC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "satuchain-api",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Official JavaScript/TypeScript SDK for the SATUCHAIN Developer API",
|
|
5
|
+
"keywords": ["satuchain", "crypto", "forex", "commodities", "gold", "api", "sdk"],
|
|
6
|
+
"author": "SATU TEAM <dev@satuchain.com>",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"homepage": "https://dev.satuchain.com",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/satuchain/dev-api.git"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/satuchain/dev-api/issues"
|
|
15
|
+
},
|
|
16
|
+
"type": "module",
|
|
17
|
+
"main": "./dist/cjs/index.cjs",
|
|
18
|
+
"module": "./dist/esm/index.js",
|
|
19
|
+
"types": "./dist/types/index.d.ts",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": "./dist/esm/index.js",
|
|
23
|
+
"require": "./dist/cjs/index.cjs",
|
|
24
|
+
"types": "./dist/types/index.d.ts"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"README.md",
|
|
30
|
+
"LICENSE"
|
|
31
|
+
],
|
|
32
|
+
"scripts": {
|
|
33
|
+
"build": "npm run build:esm && npm run build:cjs && npm run build:types",
|
|
34
|
+
"build:esm": "tsc -p tsconfig.esm.json",
|
|
35
|
+
"build:cjs": "tsc -p tsconfig.cjs.json && node scripts/rename-cjs.mjs",
|
|
36
|
+
"build:types": "tsc -p tsconfig.types.json",
|
|
37
|
+
"clean": "rm -rf dist"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"typescript": "^5.4.0"
|
|
41
|
+
},
|
|
42
|
+
"engines": {
|
|
43
|
+
"node": ">=18.0.0"
|
|
44
|
+
}
|
|
45
|
+
}
|