@runesx/api-client 0.2.0 → 0.4.0
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/README.md +603 -418
- package/package.json +1 -1
- package/src/api.mjs +314 -4
- package/src/index.mjs +104 -11
- package/src/socket.mjs +164 -112
- package/src/store/chainStore.mjs +92 -0
- package/src/waitForStores.mjs +39 -2
package/README.md
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
1
|
# RunesX API Client
|
|
2
2
|
|
|
3
|
-
A Node.js client for interacting with the RunesX platform API and WebSocket, enabling developers to build bots or scripts for real-time trading, liquidity management, and data monitoring.
|
|
3
|
+
A Node.js client for interacting with the RunesX platform API and WebSocket, enabling developers to build bots or scripts for real-time trading, liquidity management, withdrawals, deposits, and data monitoring.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
|
-
|
|
7
|
-
- **
|
|
8
|
-
- **
|
|
9
|
-
- **
|
|
10
|
-
- **
|
|
11
|
-
- **
|
|
6
|
+
|
|
7
|
+
- **WebSocket Integration**: Real-time events for pools, coins, chains, wallets, user shares, operations, deposits, withdrawals, candlesticks, volume, and chat
|
|
8
|
+
- **Full REST API**: Complete HTTP API coverage for all public and private endpoints
|
|
9
|
+
- **Store Management**: Automatic real-time state management for pools, coins, chains, wallets, and user shares with buffering for out-of-order updates
|
|
10
|
+
- **Swap Estimation**: Client-side swap estimation using DFS or BFS pathfinding algorithms
|
|
11
|
+
- **Liquidity Management**: Estimate, deposit, and withdraw liquidity with RUNES compliance checking
|
|
12
|
+
- **Withdrawal Flow**: Full multi-step withdrawal verification (PIN, email, 2FA)
|
|
13
|
+
- **Price Utilities**: Calculate token prices in RUNES and USD
|
|
14
|
+
- **Event System**: Register callbacks for any WebSocket event
|
|
12
15
|
|
|
13
16
|
## Installation
|
|
17
|
+
|
|
14
18
|
```bash
|
|
15
19
|
npm install @runesx/api-client
|
|
16
20
|
```
|
|
17
21
|
|
|
18
|
-
##
|
|
19
|
-
|
|
20
|
-
1. Initialize the Client
|
|
21
|
-
Create and initialize the client with your API key and endpoint URLs. This connects to the WebSocket and fetches initial data for pools, coins, wallets, and user shares.
|
|
22
|
+
## Quick Start
|
|
22
23
|
|
|
23
24
|
```javascript
|
|
24
25
|
import { createRunesXClient } from '@runesx/api-client';
|
|
@@ -30,497 +31,681 @@ const client = createRunesXClient({
|
|
|
30
31
|
});
|
|
31
32
|
|
|
32
33
|
async function main() {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
34
|
+
const { pools, coins, chains, wallets, userShares } = await client.initialize();
|
|
35
|
+
console.log(`Connected: ${pools.length} pools, ${coins.length} coins, ${wallets.length} wallets`);
|
|
36
|
+
|
|
37
|
+
// Listen for real-time events
|
|
38
|
+
client.on('operationUpdate', (operation) => {
|
|
39
|
+
console.log('New operation:', operation);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Get prices
|
|
43
|
+
const prices = await client.getPrices();
|
|
44
|
+
console.log('Prices:', prices);
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
main();
|
|
47
|
+
main().catch(console.error);
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## Configuration
|
|
51
|
+
|
|
52
|
+
```javascript
|
|
53
|
+
const client = createRunesXClient({
|
|
54
|
+
apiKey: 'your-api-key', // Required. Your RunesX API key
|
|
55
|
+
apiUrl: 'https://www.runesx.xyz/api', // Optional. Default: http://localhost:3010
|
|
56
|
+
socketUrl: 'https://www.runesx.xyz/api', // Optional. Default: http://localhost:3010
|
|
57
|
+
});
|
|
47
58
|
```
|
|
48
59
|
|
|
49
|
-
|
|
50
|
-
|
|
60
|
+
You can also set these via environment variables:
|
|
61
|
+
- `API_KEY` - Your API key
|
|
62
|
+
- `API_URL` - API base URL
|
|
63
|
+
- `SOCKET_URL` - WebSocket URL
|
|
64
|
+
|
|
65
|
+
## API Key Scopes
|
|
66
|
+
|
|
67
|
+
When generating an API key, you can assign specific scopes:
|
|
68
|
+
|
|
69
|
+
| Scope | Description |
|
|
70
|
+
|-------|-------------|
|
|
71
|
+
| `read` | Read-only access to user data (wallets, shares, operations, transactions) |
|
|
72
|
+
| `swap` | Execute token swaps |
|
|
73
|
+
| `liquidity_deposit` | Deposit liquidity to pools |
|
|
74
|
+
| `liquidity_withdraw` | Withdraw liquidity from pools |
|
|
75
|
+
| `wallet_withdraw` | Withdraw to external addresses |
|
|
76
|
+
| `chat` | Access yard/chat features |
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Store Data (Real-time via WebSocket)
|
|
81
|
+
|
|
82
|
+
After `initialize()`, the client maintains real-time stores updated via WebSocket. These are always up-to-date.
|
|
83
|
+
|
|
84
|
+
### Pools
|
|
51
85
|
|
|
52
|
-
### Get All Pools
|
|
53
86
|
```javascript
|
|
54
|
-
const pools = client.getPools();
|
|
55
|
-
|
|
56
|
-
id: pool.id,
|
|
57
|
-
pair: `${pool.coinA.ticker}/${pool.coinB.ticker}`,
|
|
58
|
-
reserveA: pool.reserveA,
|
|
59
|
-
reserveB: pool.reserveB,
|
|
60
|
-
})));
|
|
87
|
+
const pools = client.getPools(); // All pools
|
|
88
|
+
const pool = client.getPool(poolId); // Pool by ID
|
|
61
89
|
```
|
|
62
90
|
|
|
63
|
-
|
|
91
|
+
Pool object:
|
|
64
92
|
```javascript
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
93
|
+
{
|
|
94
|
+
id, reserveA, reserveB, totalShares, activeLiquidityProviders,
|
|
95
|
+
runesCompliant, lpFeeRate, treasuryFeeRate,
|
|
96
|
+
coinA: { id, ticker, dp, projectName },
|
|
97
|
+
coinB: { id, ticker, dp, projectName },
|
|
98
|
+
liquidityShares: [...],
|
|
99
|
+
updatedAt
|
|
100
|
+
}
|
|
71
101
|
```
|
|
72
102
|
|
|
73
|
-
###
|
|
103
|
+
### Coins
|
|
104
|
+
|
|
74
105
|
```javascript
|
|
75
|
-
const coins = client.getCoins();
|
|
76
|
-
|
|
77
|
-
ticker: coin.ticker,
|
|
78
|
-
projectName: coin.projectName,
|
|
79
|
-
status: coin.status,
|
|
80
|
-
})));
|
|
106
|
+
const coins = client.getCoins(); // All coins
|
|
107
|
+
const coin = client.getCoinByTicker('RUNES'); // Coin by ticker
|
|
81
108
|
```
|
|
82
109
|
|
|
83
|
-
###
|
|
110
|
+
### Chains
|
|
111
|
+
|
|
84
112
|
```javascript
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
ticker: coin.ticker,
|
|
88
|
-
dp: coin.dp,
|
|
89
|
-
projectName: coin.projectName,
|
|
90
|
-
} : 'Coin not found');
|
|
113
|
+
const chains = client.getChains(); // All chains
|
|
114
|
+
const chain = client.getChainByName('RuneBase'); // Chain by name
|
|
91
115
|
```
|
|
92
116
|
|
|
93
|
-
###
|
|
117
|
+
### Wallets
|
|
118
|
+
|
|
94
119
|
```javascript
|
|
95
|
-
const wallets = client.getWallets();
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
available: wallet.available,
|
|
99
|
-
locked: wallet.locked,
|
|
100
|
-
})));
|
|
120
|
+
const wallets = client.getWallets(); // All wallets
|
|
121
|
+
const wallet = client.getWalletByTicker('RUNES'); // Wallet by ticker
|
|
122
|
+
// wallet.available, wallet.locked
|
|
101
123
|
```
|
|
102
124
|
|
|
103
|
-
###
|
|
125
|
+
### User Shares
|
|
126
|
+
|
|
104
127
|
```javascript
|
|
105
|
-
const
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
available: wallet.available,
|
|
109
|
-
} : 'Wallet not found');
|
|
128
|
+
const shares = client.getUserShares(); // All shares
|
|
129
|
+
const share = client.getUserShareByPoolId(poolId); // Share by pool
|
|
130
|
+
// share.shares, share.poolId
|
|
110
131
|
```
|
|
111
132
|
|
|
112
|
-
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## REST API Methods
|
|
136
|
+
|
|
137
|
+
### Public Endpoints (No Auth Required)
|
|
138
|
+
|
|
139
|
+
#### System Status
|
|
140
|
+
|
|
113
141
|
```javascript
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
poolId: share.poolId,
|
|
117
|
-
shares: share.shares,
|
|
118
|
-
})));
|
|
142
|
+
const status = await client.getStatus();
|
|
143
|
+
// { apiVersion, apiStatus, ratatoskrVersion, ratatoskrStatus }
|
|
119
144
|
```
|
|
120
145
|
|
|
121
|
-
|
|
146
|
+
#### Coins (via API)
|
|
147
|
+
|
|
122
148
|
```javascript
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
poolId: share.poolId,
|
|
126
|
-
shares: share.shares,
|
|
127
|
-
} : 'No shares found');
|
|
149
|
+
const coins = await client.getCoinsApi(); // All coins
|
|
150
|
+
const coin = await client.getCoinApi('RUNES'); // Single coin with chain details
|
|
128
151
|
```
|
|
129
152
|
|
|
130
|
-
|
|
131
|
-
Estimate and execute a swap between two tokens, such as 0.1 xRUNES to XLM, with slippage tolerance.
|
|
153
|
+
#### Pools (via API)
|
|
132
154
|
|
|
133
155
|
```javascript
|
|
134
|
-
|
|
156
|
+
const pools = await client.getPoolsApi(); // All pools
|
|
157
|
+
const pool = await client.getPoolByPair('RUNES', 'USDC'); // Specific pool
|
|
158
|
+
const shares = await client.getPoolLiquidityShares(poolId); // Pool's liquidity shares
|
|
159
|
+
```
|
|
135
160
|
|
|
136
|
-
|
|
137
|
-
try {
|
|
138
|
-
const inputCoin = client.getCoinByTicker('xRUNES');
|
|
139
|
-
const outputCoin = client.getCoinByTicker('XLM');
|
|
140
|
-
if (!inputCoin || !outputCoin) {
|
|
141
|
-
throw new Error('Required coins not found');
|
|
142
|
-
}
|
|
161
|
+
#### Prices
|
|
143
162
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const slippageTolerance = '1'; // 1%
|
|
148
|
-
|
|
149
|
-
// Estimate swap
|
|
150
|
-
const swapEstimate = await client.estimateSwap(inputCoin, outputCoin, amountIn, maxHops, algorithm);
|
|
151
|
-
console.log('Swap estimate:', {
|
|
152
|
-
input: swapEstimate.input,
|
|
153
|
-
output: swapEstimate.output,
|
|
154
|
-
priceImpact: `${(swapEstimate.slippage.priceImpact * 100).toFixed(2)}%`,
|
|
155
|
-
path: swapEstimate.path,
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
// Calculate minimum output with slippage
|
|
159
|
-
const amountOutBN = new BigNumber(swapEstimate.output.amount);
|
|
160
|
-
const minAmountOut = amountOutBN
|
|
161
|
-
.times(new BigNumber(1).minus(new BigNumber(slippageTolerance).div(100)))
|
|
162
|
-
.toFixed(outputCoin.dp, BigNumber.ROUND_DOWN);
|
|
163
|
-
|
|
164
|
-
// Check wallet balance
|
|
165
|
-
const wallet = client.getWalletByTicker(inputCoin.ticker);
|
|
166
|
-
if (!wallet || new BigNumber(wallet.available).lt(amountIn)) {
|
|
167
|
-
throw new Error(`Insufficient balance for ${inputCoin.ticker}: ${wallet?.available || 0}`);
|
|
168
|
-
}
|
|
163
|
+
```javascript
|
|
164
|
+
const prices = await client.getPrices();
|
|
165
|
+
// { prices: [{ ticker, projectName, dp, priceInRunes, priceInUSD }], runesPriceUSD, timestamp }
|
|
169
166
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
path: swapEstimate.path,
|
|
174
|
-
minAmountOut,
|
|
175
|
-
});
|
|
176
|
-
console.log('Swap executed:', swap.data);
|
|
177
|
-
} catch (error) {
|
|
178
|
-
console.error('Swap failed:', error.message);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
167
|
+
const price = await client.getPrice('RUNES');
|
|
168
|
+
// { ticker, projectName, dp, priceInRunes, priceInUSD, runesPriceUSD, timestamp }
|
|
169
|
+
```
|
|
181
170
|
|
|
182
|
-
|
|
171
|
+
#### Candlesticks
|
|
172
|
+
|
|
173
|
+
```javascript
|
|
174
|
+
const candles = await client.getCandlesticks(poolId, '1h', fromTimestamp, toTimestamp);
|
|
175
|
+
// [{ time, open, high, low, close, volume }]
|
|
183
176
|
```
|
|
184
177
|
|
|
185
|
-
|
|
186
|
-
Deposit and withdraw liquidity for a trading pair, such as RUNES/XLM.
|
|
178
|
+
Valid timeframes: `1m`, `5m`, `15m`, `1h`, `4h`, `12h`, `1d`, `1w`, `1M`
|
|
187
179
|
|
|
180
|
+
#### Volume
|
|
188
181
|
|
|
189
182
|
```javascript
|
|
190
|
-
|
|
183
|
+
const total = await client.getVolumeTotal();
|
|
184
|
+
const poolVol = await client.getVolumePool(poolId);
|
|
185
|
+
```
|
|
191
186
|
|
|
192
|
-
|
|
193
|
-
try {
|
|
194
|
-
const coinA = client.getCoinByTicker('RUNES');
|
|
195
|
-
const coinB = client.getCoinByTicker('XLM');
|
|
196
|
-
if (!coinA || !coinB) {
|
|
197
|
-
throw new Error('Required coins not found');
|
|
198
|
-
}
|
|
187
|
+
#### Buckets
|
|
199
188
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
console.error('Cannot deposit liquidity:', warnings);
|
|
204
|
-
return;
|
|
205
|
-
}
|
|
189
|
+
```javascript
|
|
190
|
+
const buckets = await client.getBucketsPools();
|
|
191
|
+
```
|
|
206
192
|
|
|
207
|
-
|
|
208
|
-
const amountA = '1'; // 1 RUNES
|
|
209
|
-
const estimate = await client.estimateLiquidityFrontend({
|
|
210
|
-
coinA,
|
|
211
|
-
coinB,
|
|
212
|
-
amountA,
|
|
213
|
-
amountB: null,
|
|
214
|
-
pools: client.getPools(),
|
|
215
|
-
coins: client.getCoins(),
|
|
216
|
-
});
|
|
217
|
-
console.log('Liquidity estimate:', {
|
|
218
|
-
amountA: estimate.amountA,
|
|
219
|
-
amountB: estimate.amountB,
|
|
220
|
-
pair: `${estimate.coinA.ticker}/${estimate.coinB.ticker}`,
|
|
221
|
-
isPoolEmpty: estimate.isPoolEmpty,
|
|
222
|
-
flipped: estimate.flipped,
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
// Validate wallet balances
|
|
226
|
-
const walletA = client.getWalletByTicker(coinA.ticker);
|
|
227
|
-
const walletB = client.getWalletByTicker(coinB.ticker);
|
|
228
|
-
if (!walletA || new BigNumber(walletA.available).lt(estimate.amountA)) {
|
|
229
|
-
throw new Error(`Insufficient balance for ${coinA.ticker}: ${walletA?.available || 0}`);
|
|
230
|
-
}
|
|
231
|
-
if (!walletB || new BigNumber(walletB.available).lt(estimate.amountB)) {
|
|
232
|
-
throw new Error(`Insufficient balance for ${coinB.ticker}: ${walletB?.available || 0}`);
|
|
233
|
-
}
|
|
193
|
+
#### Operations
|
|
234
194
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
coinB: { ticker: estimate.coinB.ticker },
|
|
239
|
-
amountA: estimate.amountA,
|
|
240
|
-
amountB: estimate.amountB,
|
|
241
|
-
};
|
|
242
|
-
const depositResult = await client.depositLiquidity(depositParams);
|
|
243
|
-
console.log('Liquidity deposited:', {
|
|
244
|
-
pair: `${depositResult.coinA.ticker}/${depositResult.coinB.ticker}`,
|
|
245
|
-
amountA: depositResult.amountA,
|
|
246
|
-
amountB: depositResult.amountB,
|
|
247
|
-
shares: depositResult.shares,
|
|
248
|
-
uid: depositResult.uid,
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
// Wait for user shares update
|
|
252
|
-
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
253
|
-
|
|
254
|
-
// Calculate and withdraw shares
|
|
255
|
-
const updatedUserShares = client.getUserShares();
|
|
256
|
-
const calculatedShares = client.calculateShareAmounts();
|
|
257
|
-
const share = calculatedShares.find(
|
|
258
|
-
s => s.coinA.ticker === depositParams.coinA.ticker && s.coinB.ticker === depositParams.coinB.ticker
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
if (!share) {
|
|
262
|
-
throw new Error('No shares found for the deposited pool');
|
|
263
|
-
}
|
|
195
|
+
```javascript
|
|
196
|
+
// Recent operations (public)
|
|
197
|
+
const recent = await client.getRecentOperations({ operationType: 'swap', limit: 20 });
|
|
264
198
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
});
|
|
271
|
-
console.log('Liquidity withdrawn:', {
|
|
272
|
-
pair: `${withdrawResult.coinA.ticker}/${withdrawResult.coinB.ticker}`,
|
|
273
|
-
amountA: withdrawResult.amountA,
|
|
274
|
-
amountB: withdrawResult.amountB,
|
|
275
|
-
shares: withdrawResult.shares,
|
|
276
|
-
uid: withdrawResult.uid,
|
|
277
|
-
});
|
|
278
|
-
} catch (error) {
|
|
279
|
-
console.error('Liquidity operation failed:', error.message);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
199
|
+
// Pool operations
|
|
200
|
+
const poolOps = await client.getPoolOperations(poolId, { operationType: 'swap' });
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Valid operation types: `swap`, `liquidityDeposit`, `liquidityWithdrawal`
|
|
282
204
|
|
|
283
|
-
|
|
205
|
+
#### Yard Messages
|
|
206
|
+
|
|
207
|
+
```javascript
|
|
208
|
+
const messages = await client.getYardMessages({ limit: 50 });
|
|
209
|
+
const older = await client.getYardMessages({ before: '2024-01-01T00:00:00Z', limit: 50 });
|
|
284
210
|
```
|
|
285
211
|
|
|
286
|
-
|
|
287
|
-
|
|
212
|
+
### Private Endpoints (Auth Required)
|
|
213
|
+
|
|
214
|
+
#### Wallets
|
|
288
215
|
|
|
289
|
-
### Monitor a Specific Pool
|
|
290
216
|
```javascript
|
|
291
|
-
client.
|
|
217
|
+
const wallets = await client.getWalletsApi(); // Scope: read
|
|
292
218
|
```
|
|
293
219
|
|
|
294
|
-
|
|
220
|
+
#### Swap (Scope: swap)
|
|
221
|
+
|
|
295
222
|
```javascript
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
}))
|
|
306
|
-
: 'No wallets available');
|
|
307
|
-
}, interval);
|
|
308
|
-
}
|
|
223
|
+
const result = await client.postSwap({
|
|
224
|
+
amountIn: '1.0',
|
|
225
|
+
path: [{ from: 'RUNES', to: 'USDC' }],
|
|
226
|
+
minAmountOut: '0.009',
|
|
227
|
+
idempotencyKey: 'optional-unique-key', // Auto-generated if not provided
|
|
228
|
+
});
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
#### Liquidity (Scope: liquidity_deposit / liquidity_withdraw)
|
|
309
232
|
|
|
310
|
-
|
|
233
|
+
```javascript
|
|
234
|
+
// Deposit
|
|
235
|
+
const deposit = await client.depositLiquidity({
|
|
236
|
+
tickerA: 'RUNES',
|
|
237
|
+
tickerB: 'USDC',
|
|
238
|
+
amountA: '100',
|
|
239
|
+
amountB: '1.5',
|
|
240
|
+
minShares: '1000', // Optional slippage protection
|
|
241
|
+
idempotencyKey: 'optional-key',
|
|
242
|
+
});
|
|
243
|
+
|
|
244
|
+
// Withdraw
|
|
245
|
+
const withdraw = await client.withdrawLiquidity({
|
|
246
|
+
tickerA: 'RUNES',
|
|
247
|
+
tickerB: 'USDC',
|
|
248
|
+
shares: '5000',
|
|
249
|
+
minAmountA: '90', // Optional slippage protection
|
|
250
|
+
minAmountB: '1.3', // Optional slippage protection
|
|
251
|
+
idempotencyKey: 'optional-key',
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
// Get user's liquidity shares via API
|
|
255
|
+
const shares = await client.getLiquidityShares();
|
|
311
256
|
```
|
|
312
257
|
|
|
313
|
-
|
|
258
|
+
#### Deposits
|
|
259
|
+
|
|
314
260
|
```javascript
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
261
|
+
// Get deposit address for a chain
|
|
262
|
+
const { address, memo } = await client.getDepositAddress('RuneBase');
|
|
263
|
+
|
|
264
|
+
// Get all deposit addresses
|
|
265
|
+
const addresses = await client.getAllDepositAddresses();
|
|
266
|
+
// [{ chainName, address, memo }]
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
#### Withdrawals (Scope: wallet_withdraw)
|
|
270
|
+
|
|
271
|
+
The withdrawal process is multi-step:
|
|
272
|
+
|
|
273
|
+
```javascript
|
|
274
|
+
// 1. Initiate withdrawal
|
|
275
|
+
const initResult = await client.initiateWithdraw({
|
|
276
|
+
ticker: 'RUNES',
|
|
277
|
+
chain: 'RuneBase',
|
|
278
|
+
address: 'RxYz...',
|
|
279
|
+
amount: '100',
|
|
280
|
+
memo: null, // Optional, for chains that require it
|
|
281
|
+
idempotencyKey: 'optional-key',
|
|
282
|
+
});
|
|
283
|
+
const { pendingWithdrawalId } = initResult.data;
|
|
284
|
+
|
|
285
|
+
// 2. Verify PIN (shown as image via socket event 'withdrawal_pin_generated')
|
|
286
|
+
await client.verifyWithdrawPin({ pendingWithdrawalId, pinCode: '123456' });
|
|
287
|
+
|
|
288
|
+
// 3. Send email PIN
|
|
289
|
+
await client.sendWithdrawEmailPin({ pendingWithdrawalId });
|
|
290
|
+
|
|
291
|
+
// 4. Verify email PIN
|
|
292
|
+
await client.verifyWithdrawEmailPin({ pendingWithdrawalId, emailPinCode: '654321' });
|
|
293
|
+
|
|
294
|
+
// 5. Verify 2FA (if enabled)
|
|
295
|
+
await client.verifyWithdraw2FA({ pendingWithdrawalId, twoFactorToken: '123456' });
|
|
296
|
+
|
|
297
|
+
// Check pending withdrawals
|
|
298
|
+
const pending = await client.getPendingWithdrawals();
|
|
299
|
+
|
|
300
|
+
// Cancel a pending withdrawal
|
|
301
|
+
await client.cancelWithdrawal({ pendingWithdrawalId });
|
|
302
|
+
```
|
|
327
303
|
|
|
328
|
-
|
|
304
|
+
#### Transaction History (Scope: read)
|
|
305
|
+
|
|
306
|
+
```javascript
|
|
307
|
+
const history = await client.getTransactionHistory({
|
|
308
|
+
page: 1,
|
|
309
|
+
limit: 20,
|
|
310
|
+
type: 'deposit', // Optional: 'deposit' or 'withdrawal'
|
|
311
|
+
status: 'confirmed', // Optional
|
|
312
|
+
});
|
|
313
|
+
// { success, data: { transactions: [...], total, page, pages } }
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
#### User Operations (Scope: read)
|
|
317
|
+
|
|
318
|
+
```javascript
|
|
319
|
+
const ops = await client.getUserOperations({
|
|
320
|
+
operationType: 'swap', // Optional
|
|
321
|
+
poolId: '1', // Optional
|
|
322
|
+
startTime: '2024-01-01T00:00:00Z', // Optional
|
|
323
|
+
endTime: '2024-12-31T23:59:59Z', // Optional
|
|
324
|
+
page: 1,
|
|
325
|
+
limit: 50,
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
#### Yard Moderation (Scope: chat)
|
|
330
|
+
|
|
331
|
+
```javascript
|
|
332
|
+
// Delete a message (via REST API)
|
|
333
|
+
await client.deleteYardMessage(messageId);
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
---
|
|
337
|
+
|
|
338
|
+
## WebSocket Events
|
|
339
|
+
|
|
340
|
+
### Event Listener System
|
|
341
|
+
|
|
342
|
+
Use `client.on()` and `client.off()` to register callbacks for any WebSocket event:
|
|
343
|
+
|
|
344
|
+
```javascript
|
|
345
|
+
// Register a callback
|
|
346
|
+
const handler = (data) => console.log('Pool update:', data);
|
|
347
|
+
client.on('pools_updated', handler);
|
|
348
|
+
|
|
349
|
+
// Remove a specific callback
|
|
350
|
+
client.off('pools_updated', handler);
|
|
351
|
+
|
|
352
|
+
// Remove all callbacks for an event
|
|
353
|
+
client.off('pools_updated');
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Available Events
|
|
357
|
+
|
|
358
|
+
#### Public Events (received after joining public room)
|
|
359
|
+
|
|
360
|
+
| Event | Data | Description |
|
|
361
|
+
|-------|------|-------------|
|
|
362
|
+
| `pools_updated` | `{ pools, isInitial }` | Pool data updated |
|
|
363
|
+
| `coins_updated` | `{ coins, isInitial }` | Coin data updated |
|
|
364
|
+
| `chains_updated` | `{ chains, isInitial }` | Chain data updated |
|
|
365
|
+
| `buckets_updated` | `{ type, buckets }` | Pool bucket data |
|
|
366
|
+
| `operations_updated` | `[operations]` | Initial recent operations |
|
|
367
|
+
| `recent_yard_messages` | `{ messages, lastReadAt }` | Initial chat messages |
|
|
368
|
+
| `status_updated` | `{ apiVersion, apiStatus, ratatoskrVersion, ratatoskrStatus }` | System status |
|
|
369
|
+
| `volumeUpdate` | `{ type, poolId, timestamp, volume }` | Volume update |
|
|
370
|
+
| `operationUpdate` | `operation` | New operation executed |
|
|
371
|
+
| `yard_message` | `{ id, text, userId, username, role, timestamp }` | New chat message |
|
|
372
|
+
| `message_deleted` | `{ messageId }` | Chat message deleted |
|
|
373
|
+
| `candlestick_updated` | `data` | Candlestick update (requires joining candlestick room) |
|
|
374
|
+
|
|
375
|
+
#### Private Events (received after joining private room)
|
|
376
|
+
|
|
377
|
+
| Event | Data | Description |
|
|
378
|
+
|-------|------|-------------|
|
|
379
|
+
| `wallets_updated` | `{ wallets, isInitial }` | Wallet balances updated |
|
|
380
|
+
| `user_shares_updated` | `{ userShares, isInitial }` | Liquidity shares updated |
|
|
381
|
+
| `deposit_address_generated` | `{ requestId, chainName, address, memo }` | Deposit address ready |
|
|
382
|
+
| `deposit_processed` | `{ amount, coin, chain, confirmations, status, credited }` | Deposit confirmation update |
|
|
383
|
+
| `withdrawal_initiated` | `data` | Withdrawal process started |
|
|
384
|
+
| `withdrawal_pin_generated` | `{ pinImage, ticker, amount, pendingWithdrawalId, expiresAt, dp, fee, memoRequired }` | PIN image ready |
|
|
385
|
+
| `withdrawal_updated` | `{ pendingWithdrawalId, expiresAt, stage }` | Withdrawal stage changed |
|
|
386
|
+
| `withdrawal_queued` | `{ pendingWithdrawalId, ticker }` | Withdrawal queued for processing |
|
|
387
|
+
| `withdrawal_processed` | `{ amount, coin, chain, confirmations, status, credited }` | Withdrawal confirmation update |
|
|
388
|
+
| `withdrawal_canceled` | `{ ticker, amount }` | Withdrawal canceled |
|
|
389
|
+
| `withdrawal_expired` | `{ pendingWithdrawalId, ticker, amount }` | Withdrawal expired |
|
|
390
|
+
| `banned` | `{ reason, bannedUntil }` | User banned from yard chat |
|
|
391
|
+
| `yard_read_marked` | `{ lastReadAt }` | Yard marked as read |
|
|
392
|
+
| `session_expired` | `{ message }` | Session expired, reconnect needed |
|
|
393
|
+
|
|
394
|
+
#### Connection Events
|
|
395
|
+
|
|
396
|
+
| Event | Data | Description |
|
|
397
|
+
|-------|------|-------------|
|
|
398
|
+
| `connect` | `null` | Connected to server |
|
|
399
|
+
| `disconnect` | `reason` | Disconnected from server |
|
|
400
|
+
| `connect_error` | `error` | Connection error |
|
|
401
|
+
| `reconnect_attempt` | `attempt` | Reconnection attempt number |
|
|
402
|
+
| `reconnect` | `null` | Successfully reconnected |
|
|
403
|
+
| `error` | `error` | Socket error |
|
|
404
|
+
|
|
405
|
+
### Socket Convenience Methods
|
|
406
|
+
|
|
407
|
+
#### Candlestick Subscriptions
|
|
408
|
+
|
|
409
|
+
```javascript
|
|
410
|
+
// Subscribe to candlestick updates for a pool
|
|
411
|
+
client.joinCandlesticks(poolId, '1h');
|
|
412
|
+
|
|
413
|
+
client.on('candlestick_updated', (data) => {
|
|
414
|
+
console.log('Candlestick:', data);
|
|
415
|
+
});
|
|
416
|
+
|
|
417
|
+
// Unsubscribe
|
|
418
|
+
client.leaveCandlesticks(poolId, '1h');
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
#### Chat (The Yard)
|
|
422
|
+
|
|
423
|
+
```javascript
|
|
424
|
+
// Send a message (Scope: chat)
|
|
425
|
+
client.sendYardMessage('Hello from my bot!');
|
|
426
|
+
|
|
427
|
+
// Listen for messages
|
|
428
|
+
client.on('yard_message', (msg) => {
|
|
429
|
+
console.log(`[${msg.username}]: ${msg.text}`);
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// Delete a message (moderator/admin only)
|
|
433
|
+
client.deleteMessage(messageId);
|
|
434
|
+
|
|
435
|
+
// Mark yard as read
|
|
436
|
+
client.markYardRead();
|
|
329
437
|
```
|
|
330
438
|
|
|
331
|
-
###
|
|
439
|
+
### Raw Socket Access
|
|
440
|
+
|
|
441
|
+
For advanced use cases, access the underlying Socket.IO instance:
|
|
442
|
+
|
|
332
443
|
```javascript
|
|
333
444
|
const socket = client.getSocket();
|
|
445
|
+
socket.emit('custom_event', data);
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
---
|
|
334
449
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
450
|
+
## Client-Side Utilities
|
|
451
|
+
|
|
452
|
+
### Swap Estimation
|
|
453
|
+
|
|
454
|
+
Estimate swap outcomes locally without making API calls:
|
|
455
|
+
|
|
456
|
+
```javascript
|
|
457
|
+
const inputCoin = client.getCoinByTicker('RUNES');
|
|
458
|
+
const outputCoin = client.getCoinByTicker('USDC');
|
|
459
|
+
|
|
460
|
+
const estimate = await client.estimateSwap(inputCoin, outputCoin, '100', 6, 'dfs');
|
|
461
|
+
console.log({
|
|
462
|
+
outputAmount: estimate.output.amount,
|
|
463
|
+
priceImpact: `${estimate.slippage.priceImpact.toFixed(2)}%`,
|
|
464
|
+
path: estimate.path,
|
|
465
|
+
inputPriceUSD: estimate.input.priceUSD,
|
|
466
|
+
outputPriceUSD: estimate.output.priceUSD,
|
|
346
467
|
});
|
|
468
|
+
```
|
|
347
469
|
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
470
|
+
### Liquidity Estimation
|
|
471
|
+
|
|
472
|
+
```javascript
|
|
473
|
+
const coinA = client.getCoinByTicker('RUNES');
|
|
474
|
+
const coinB = client.getCoinByTicker('USDC');
|
|
475
|
+
|
|
476
|
+
// Estimate how much coinB is needed for a given coinA amount
|
|
477
|
+
const estimate = client.estimateLiquidityFrontend({
|
|
478
|
+
coinA, coinB,
|
|
479
|
+
amountA: '100',
|
|
480
|
+
amountB: null,
|
|
481
|
+
pools: client.getPools(),
|
|
482
|
+
coins: client.getCoins(),
|
|
357
483
|
});
|
|
484
|
+
console.log(`Need ${estimate.amountB} ${estimate.coinB.ticker} for ${estimate.amountA} ${estimate.coinA.ticker}`);
|
|
485
|
+
```
|
|
358
486
|
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
487
|
+
### Deposit Share Estimation
|
|
488
|
+
|
|
489
|
+
```javascript
|
|
490
|
+
const pool = client.getPool(poolId);
|
|
491
|
+
const shareEstimate = client.estimateDepositShares({
|
|
492
|
+
pool,
|
|
493
|
+
amountA: '100',
|
|
494
|
+
amountB: '1.5',
|
|
495
|
+
slippagePercent: 2,
|
|
368
496
|
});
|
|
497
|
+
console.log(`Estimated shares: ${shareEstimate.estimatedShares}, min: ${shareEstimate.minShares}`);
|
|
498
|
+
```
|
|
499
|
+
|
|
500
|
+
### RUNES Compliance Check
|
|
501
|
+
|
|
502
|
+
```javascript
|
|
503
|
+
const { isCompliant, warnings } = client.checkRunesLiquidityFrontend(coinA, coinB);
|
|
504
|
+
if (!isCompliant) {
|
|
505
|
+
console.warn('Pool not RUNES-compliant:', warnings);
|
|
506
|
+
}
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
### Share Amount Calculation
|
|
369
510
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
poolId: share.poolId,
|
|
375
|
-
shares: share.shares,
|
|
376
|
-
})));
|
|
377
|
-
}
|
|
511
|
+
```javascript
|
|
512
|
+
const shareAmounts = client.calculateShareAmounts();
|
|
513
|
+
shareAmounts.forEach(share => {
|
|
514
|
+
console.log(`${share.pair}: ${share.amountA} / ${share.amountB} (${share.shares} shares)`);
|
|
378
515
|
});
|
|
379
516
|
```
|
|
380
517
|
|
|
381
|
-
|
|
382
|
-
Disconnect the WebSocket when done to free resources.
|
|
518
|
+
### Price Utilities
|
|
383
519
|
|
|
384
520
|
```javascript
|
|
385
|
-
client.
|
|
521
|
+
const runesPrice = client.utils.getRunesPriceUSD();
|
|
522
|
+
const tokenPrice = client.utils.getTokenPriceUSD('USDC');
|
|
523
|
+
const priceInRunes = client.utils.getTokenPriceInRunes('USDC');
|
|
524
|
+
const usdValue = client.utils.calculateUSDValue('100', 'RUNES', 2);
|
|
525
|
+
|
|
526
|
+
// Get prices for multiple tokens
|
|
527
|
+
const prices = client.utils.getPrices(['RUNES', 'USDC', 'XLM']);
|
|
386
528
|
```
|
|
387
529
|
|
|
388
|
-
|
|
389
|
-
|
|
530
|
+
---
|
|
531
|
+
|
|
532
|
+
## Complete Example: Trading Bot
|
|
390
533
|
|
|
391
534
|
```javascript
|
|
535
|
+
import { createRunesXClient } from '@runesx/api-client';
|
|
536
|
+
import { BigNumber } from 'bignumber.js';
|
|
537
|
+
|
|
538
|
+
const client = createRunesXClient({
|
|
539
|
+
apiKey: process.env.API_KEY,
|
|
540
|
+
apiUrl: 'https://www.runesx.xyz/api',
|
|
541
|
+
socketUrl: 'https://www.runesx.xyz/api',
|
|
542
|
+
});
|
|
543
|
+
|
|
544
|
+
async function main() {
|
|
545
|
+
await client.initialize();
|
|
546
|
+
console.log('Bot started');
|
|
547
|
+
|
|
548
|
+
// Monitor for new operations
|
|
549
|
+
client.on('operationUpdate', (op) => {
|
|
550
|
+
if (op.operationType === 'swap') {
|
|
551
|
+
console.log(`Swap: ${op.amountIn} ${op.inputCoin?.ticker} -> ${op.amountOut} ${op.outputCoin?.ticker}`);
|
|
552
|
+
}
|
|
553
|
+
});
|
|
554
|
+
|
|
555
|
+
// Monitor wallet changes
|
|
556
|
+
client.on('wallets_updated', ({ isInitial }) => {
|
|
557
|
+
if (!isInitial) {
|
|
558
|
+
const wallets = client.getWallets();
|
|
559
|
+
wallets.forEach(w => {
|
|
560
|
+
console.log(`${w.ticker}: ${w.available} available, ${w.locked} locked`);
|
|
561
|
+
});
|
|
562
|
+
}
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
// Monitor deposit confirmations
|
|
566
|
+
client.on('deposit_processed', (data) => {
|
|
567
|
+
if (data.status === 'confirmed' && data.credited) {
|
|
568
|
+
console.log(`Deposit confirmed: ${data.amount} ${data.coin.ticker}`);
|
|
569
|
+
}
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
// Example: execute a swap when price is favorable
|
|
573
|
+
const checkAndSwap = async () => {
|
|
574
|
+
const inputCoin = client.getCoinByTicker('RUNES');
|
|
575
|
+
const outputCoin = client.getCoinByTicker('USDC');
|
|
576
|
+
if (!inputCoin || !outputCoin) { return; }
|
|
577
|
+
|
|
578
|
+
const estimate = await client.estimateSwap(inputCoin, outputCoin, '10');
|
|
579
|
+
const priceImpact = estimate.slippage.priceImpact;
|
|
580
|
+
|
|
581
|
+
if (priceImpact < 1) { // Less than 1% price impact
|
|
582
|
+
const minOut = new BigNumber(estimate.output.amount)
|
|
583
|
+
.times(0.99)
|
|
584
|
+
.toFixed(outputCoin.dp, BigNumber.ROUND_DOWN);
|
|
585
|
+
|
|
586
|
+
const result = await client.postSwap({
|
|
587
|
+
amountIn: '10',
|
|
588
|
+
path: estimate.path,
|
|
589
|
+
minAmountOut: minOut,
|
|
590
|
+
});
|
|
591
|
+
console.log('Swap result:', result);
|
|
592
|
+
}
|
|
593
|
+
};
|
|
594
|
+
|
|
595
|
+
setInterval(checkAndSwap, 60000);
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
main().catch(console.error);
|
|
599
|
+
|
|
392
600
|
process.on('SIGINT', () => {
|
|
393
|
-
console.log('Shutting down...');
|
|
394
601
|
client.disconnect();
|
|
395
602
|
process.exit(0);
|
|
396
603
|
});
|
|
397
604
|
```
|
|
398
605
|
|
|
606
|
+
---
|
|
399
607
|
|
|
400
608
|
## API Reference
|
|
401
609
|
|
|
402
|
-
###
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
- `params.pools` (array): Array of pools.
|
|
505
|
-
- `params.coins` (array): Array of coins.
|
|
506
|
-
- **Returns**: Liquidity estimate object.
|
|
507
|
-
|
|
508
|
-
### `checkRunesLiquidityFrontend(coinA, coinB)`
|
|
509
|
-
Checks RUNES compliance for a trading pair.
|
|
510
|
-
- **Parameters**:
|
|
511
|
-
- `coinA` (object): First coin.
|
|
512
|
-
- `coinB` (object): Second coin.
|
|
513
|
-
- **Returns**: `{ isCompliant, warnings }`.
|
|
514
|
-
|
|
515
|
-
### `calculateShareAmounts()`
|
|
516
|
-
Calculates amounts for user shares.
|
|
517
|
-
- **Returns**: Array of share objects with calculated amounts.
|
|
518
|
-
|
|
519
|
-
### `monitorPool(poolId, interval)`
|
|
520
|
-
Monitors a pool periodically.
|
|
521
|
-
- **Parameters**:
|
|
522
|
-
- `poolId` (number): Pool ID.
|
|
523
|
-
- `interval` (number, optional): Interval in milliseconds (default: 10000).
|
|
524
|
-
|
|
525
|
-
### `disconnect()`
|
|
526
|
-
Disconnects the WebSocket.
|
|
610
|
+
### Client Creation & Lifecycle
|
|
611
|
+
|
|
612
|
+
| Method | Description |
|
|
613
|
+
|--------|-------------|
|
|
614
|
+
| `createRunesXClient(options)` | Create a client instance |
|
|
615
|
+
| `initialize()` | Connect WebSocket, wait for initial data. Returns `{ pools, coins, chains, wallets, userShares }` |
|
|
616
|
+
| `disconnect()` | Disconnect WebSocket |
|
|
617
|
+
| `getSocket()` | Get raw Socket.IO instance |
|
|
618
|
+
|
|
619
|
+
### Store Accessors (Real-time Data)
|
|
620
|
+
|
|
621
|
+
| Method | Returns |
|
|
622
|
+
|--------|---------|
|
|
623
|
+
| `getPools()` | All pools array |
|
|
624
|
+
| `getPool(poolId)` | Pool by ID |
|
|
625
|
+
| `getCoins()` | All coins array |
|
|
626
|
+
| `getCoinByTicker(ticker)` | Coin by ticker |
|
|
627
|
+
| `getChains()` | All chains array |
|
|
628
|
+
| `getChainByName(name)` | Chain by name |
|
|
629
|
+
| `getWallets()` | All wallets array |
|
|
630
|
+
| `getWalletByTicker(ticker)` | Wallet by ticker |
|
|
631
|
+
| `getUserShares()` | All user shares array |
|
|
632
|
+
| `getUserShareByPoolId(poolId)` | User share by pool ID |
|
|
633
|
+
|
|
634
|
+
### Event System
|
|
635
|
+
|
|
636
|
+
| Method | Description |
|
|
637
|
+
|--------|-------------|
|
|
638
|
+
| `on(event, callback)` | Register event callback |
|
|
639
|
+
| `off(event, callback?)` | Remove callback (or all for event) |
|
|
640
|
+
|
|
641
|
+
### Socket Emit Methods
|
|
642
|
+
|
|
643
|
+
| Method | Description |
|
|
644
|
+
|--------|-------------|
|
|
645
|
+
| `joinCandlesticks(poolId, timeframe)` | Subscribe to candlestick updates |
|
|
646
|
+
| `leaveCandlesticks(poolId, timeframe)` | Unsubscribe from candlestick updates |
|
|
647
|
+
| `sendYardMessage(text)` | Send a chat message (scope: chat) |
|
|
648
|
+
| `deleteMessage(messageId)` | Delete a chat message (mod/admin) |
|
|
649
|
+
| `markYardRead()` | Mark yard as read |
|
|
650
|
+
|
|
651
|
+
### Public REST API
|
|
652
|
+
|
|
653
|
+
| Method | Description |
|
|
654
|
+
|--------|-------------|
|
|
655
|
+
| `getStatus()` | System status |
|
|
656
|
+
| `getCoinsApi()` | All coins via API |
|
|
657
|
+
| `getCoinApi(ticker)` | Single coin via API |
|
|
658
|
+
| `getPoolsApi()` | All pools via API |
|
|
659
|
+
| `getPoolByPair(tickerA, tickerB)` | Pool by ticker pair |
|
|
660
|
+
| `getPoolLiquidityShares(poolId)` | Pool liquidity shares |
|
|
661
|
+
| `getPrices()` | All token prices |
|
|
662
|
+
| `getPrice(ticker)` | Single token price |
|
|
663
|
+
| `getCandlesticks(poolId, timeframe, from, to)` | OHLCV candlestick data |
|
|
664
|
+
| `getVolumeTotal()` | Total platform volume |
|
|
665
|
+
| `getVolumePool(poolId)` | Pool volume |
|
|
666
|
+
| `getBucketsPools()` | Pool bucket data |
|
|
667
|
+
| `getRecentOperations({ operationType?, limit? })` | Recent operations |
|
|
668
|
+
| `getPoolOperations(poolId, { operationType?, limit? })` | Pool operations |
|
|
669
|
+
| `getYardMessages({ before?, limit? })` | Chat messages |
|
|
670
|
+
|
|
671
|
+
### Private REST API
|
|
672
|
+
|
|
673
|
+
| Method | Scope | Description |
|
|
674
|
+
|--------|-------|-------------|
|
|
675
|
+
| `getWalletsApi()` | read | Wallet balances |
|
|
676
|
+
| `getLiquidityShares()` | read | User's liquidity shares |
|
|
677
|
+
| `postSwap({ amountIn, path, minAmountOut, idempotencyKey? })` | swap | Execute swap |
|
|
678
|
+
| `depositLiquidity({ tickerA, tickerB, amountA, amountB, minShares?, idempotencyKey? })` | liquidity_deposit | Deposit liquidity |
|
|
679
|
+
| `withdrawLiquidity({ tickerA, tickerB, shares, minAmountA?, minAmountB?, idempotencyKey? })` | liquidity_withdraw | Withdraw liquidity |
|
|
680
|
+
| `getDepositAddress(chainName)` | read | Get deposit address |
|
|
681
|
+
| `getAllDepositAddresses()` | read | Get all deposit addresses |
|
|
682
|
+
| `initiateWithdraw({ ticker, chain, address, amount, memo?, idempotencyKey? })` | wallet_withdraw | Start withdrawal |
|
|
683
|
+
| `verifyWithdrawPin({ pendingWithdrawalId, pinCode })` | wallet_withdraw | Verify PIN |
|
|
684
|
+
| `sendWithdrawEmailPin({ pendingWithdrawalId })` | wallet_withdraw | Send email PIN |
|
|
685
|
+
| `verifyWithdrawEmailPin({ pendingWithdrawalId, emailPinCode })` | wallet_withdraw | Verify email PIN |
|
|
686
|
+
| `verifyWithdraw2FA({ pendingWithdrawalId, twoFactorToken })` | wallet_withdraw | Verify 2FA |
|
|
687
|
+
| `getPendingWithdrawals()` | wallet_withdraw | Get pending withdrawals |
|
|
688
|
+
| `cancelWithdrawal({ pendingWithdrawalId })` | wallet_withdraw | Cancel withdrawal |
|
|
689
|
+
| `getTransactionHistory({ page?, limit?, type?, status? })` | read | Transaction history |
|
|
690
|
+
| `getUserOperations({ operationType?, poolId?, startTime?, endTime?, page?, limit? })` | read | User operations |
|
|
691
|
+
| `deleteYardMessage(messageId)` | chat | Delete chat message |
|
|
692
|
+
|
|
693
|
+
### Client-Side Utilities
|
|
694
|
+
|
|
695
|
+
| Method | Description |
|
|
696
|
+
|--------|-------------|
|
|
697
|
+
| `estimateSwap(inputCoin, outputCoin, amountIn, maxHops?, algorithm?)` | Estimate swap output locally |
|
|
698
|
+
| `estimateLiquidityFrontend({ coinA, coinB, amountA, amountB, pools, coins })` | Estimate liquidity amounts |
|
|
699
|
+
| `estimateDepositShares({ pool, amountA, amountB, slippagePercent? })` | Estimate deposit shares |
|
|
700
|
+
| `checkRunesLiquidityFrontend(coinA, coinB)` | Check RUNES compliance |
|
|
701
|
+
| `calculateShareAmounts()` | Calculate share token amounts |
|
|
702
|
+
| `monitorPool(poolId, interval?)` | Log pool state periodically |
|
|
703
|
+
| `utils.getRunesPriceUSD()` | RUNES price in USD |
|
|
704
|
+
| `utils.getTokenPriceInRunes(ticker)` | Token price in RUNES |
|
|
705
|
+
| `utils.getTokenPriceUSD(ticker)` | Token price in USD |
|
|
706
|
+
| `utils.getPrices(tickers)` | Multiple token prices |
|
|
707
|
+
| `utils.calculateUSDValue(amount, ticker, decimals?)` | USD value of token amount |
|
|
708
|
+
|
|
709
|
+
## License
|
|
710
|
+
|
|
711
|
+
MIT
|