@runesx/api-client 0.2.0 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@runesx/api-client",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "A Node.js client for interacting with the RunesX platform API and WebSocket",
5
5
  "main": "src/index.mjs",
6
6
  "type": "module",
package/src/index.mjs CHANGED
@@ -4,6 +4,7 @@ import { createApi } from './api.mjs';
4
4
  import { createConfig } from './config.mjs';
5
5
  import { getPools, getPool } from './store/poolStore.mjs';
6
6
  import { getCoins, getCoinByTicker } from './store/coinStore.mjs';
7
+ import { getChains, getChainByName } from './store/chainStore.mjs';
7
8
  import { getWallets as getWalletsStore, getWalletByTicker } from './store/walletStore.mjs';
8
9
  import { getUserShares, getUserShareByPoolId } from './store/userSharesStore.mjs';
9
10
  import { waitForStores } from './waitForStores.mjs';
@@ -22,9 +23,9 @@ export function createRunesXClient(options = {}) {
22
23
  throw new Error('API_KEY is required');
23
24
  }
24
25
  socket = setupSocket(config).socket;
25
- const { pools, coins, wallets, userShares } = await waitForStores(socket);
26
+ const { pools, coins, chains, wallets, userShares } = await waitForStores(socket);
26
27
  initialized = true;
27
- return { pools, coins, wallets, userShares };
28
+ return { pools, coins, chains, wallets, userShares };
28
29
  }
29
30
 
30
31
  function ensureInitialized() {
@@ -43,6 +44,8 @@ export function createRunesXClient(options = {}) {
43
44
  getPool,
44
45
  getCoins,
45
46
  getCoinByTicker,
47
+ getChains,
48
+ getChainByName,
46
49
  getWallets: getWalletsStore,
47
50
  getWalletByTicker,
48
51
  getUserShares,
package/src/socket.mjs CHANGED
@@ -3,12 +3,14 @@ import { io } from 'socket.io-client';
3
3
 
4
4
  import { setInitialPools, updatePool, resetPools } from './store/poolStore.mjs';
5
5
  import { setInitialCoins, updateCoin, resetCoins } from './store/coinStore.mjs';
6
+ import { setInitialChains, updateChain, resetChains } from './store/chainStore.mjs';
6
7
  import { setInitialWallets, updateWallet, resetWallets } from './store/walletStore.mjs';
7
8
  import { setInitialUserShares, updateUserShare, resetUserShares } from './store/userSharesStore.mjs';
8
9
 
9
10
  export function setupSocket(config) {
10
11
  const socket = io(config.socketUrl, {
11
12
  auth: { authorization: `Bearer ${config.apiKey}` },
13
+ extraHeaders: { authorization: `Bearer ${config.apiKey}` },
12
14
  transports: ['websocket'],
13
15
  reconnection: true,
14
16
  reconnectionAttempts: Infinity,
@@ -30,6 +32,7 @@ export function setupSocket(config) {
30
32
  if (errorCount.count >= 3) {
31
33
  resetPools();
32
34
  resetCoins();
35
+ resetChains();
33
36
  resetWallets();
34
37
  resetUserShares();
35
38
  }
@@ -39,6 +42,7 @@ export function setupSocket(config) {
39
42
  console.log('Disconnected from Socket.IO server:', reason);
40
43
  resetPools();
41
44
  resetCoins();
45
+ resetChains();
42
46
  resetWallets();
43
47
  resetUserShares();
44
48
  });
@@ -52,6 +56,7 @@ export function setupSocket(config) {
52
56
  socket.emit('join_private');
53
57
  resetPools();
54
58
  resetCoins();
59
+ resetChains();
55
60
  resetWallets();
56
61
  resetUserShares();
57
62
  });
@@ -62,6 +67,7 @@ export function setupSocket(config) {
62
67
  if (errorCount.count >= 3) {
63
68
  resetPools();
64
69
  resetCoins();
70
+ resetChains();
65
71
  resetWallets();
66
72
  resetUserShares();
67
73
  }
@@ -89,6 +95,15 @@ export function setupSocket(config) {
89
95
  }
90
96
  });
91
97
 
98
+ socket.on('chains_updated', ({ chains, isInitial }) => {
99
+ // console.log('Received chains_updated:', { chains, isInitial });
100
+ if (isInitial) {
101
+ setInitialChains(chains);
102
+ } else {
103
+ chains.forEach(chain => updateChain(chain));
104
+ }
105
+ });
106
+
92
107
  socket.on('wallets_updated', ({ wallets, isInitial }) => {
93
108
  // console.log('Received wallets_updated:', { wallets, isInitial });
94
109
  if (isInitial) {
@@ -130,8 +145,8 @@ export function setupSocket(config) {
130
145
  // console.log('Status update:', data);
131
146
  });
132
147
 
133
- socket.on('deposit_address_generated', ({ requestId, chainId, address, memo }) => {
134
- // console.log('Deposit address generated:', { requestId, chainId, address, memo });
148
+ socket.on('deposit_address_generated', ({ requestId, chainName, address, memo }) => {
149
+ // console.log('Deposit address generated:', { requestId, chainName, address, memo });
135
150
  });
136
151
 
137
152
  socket.on('deposit_processed', (data) => {
@@ -227,6 +242,7 @@ export function setupSocket(config) {
227
242
  clearInterval(heartbeatInterval);
228
243
  resetPools();
229
244
  resetCoins();
245
+ resetChains();
230
246
  resetWallets();
231
247
  resetUserShares();
232
248
  });
@@ -0,0 +1,92 @@
1
+ const chainStore = {
2
+ chains: new Map(), // Store chain data by name (lowercase)
3
+ isInitialReceived: false,
4
+ pendingUpdates: [],
5
+ };
6
+
7
+ const setInitialChains = (chains) => {
8
+ chainStore.chains.clear();
9
+ chains.forEach(chain => {
10
+ chainStore.chains.set(chain.name.toLowerCase(), {
11
+ id: chain.id,
12
+ name: chain.name,
13
+ blockchainId: chain.blockchainId,
14
+ requiredConfirmations: chain.requiredConfirmations,
15
+ hasMemo: chain.hasMemo,
16
+ status: chain.status,
17
+ chainType: chain.chainType,
18
+ nativeTicker: chain.nativeTicker,
19
+ explorerTxUrl: chain.explorerTxUrl,
20
+ updatedAt: chain.updatedAt,
21
+ });
22
+ });
23
+ chainStore.isInitialReceived = true;
24
+
25
+ if (chainStore.pendingUpdates.length > 0) {
26
+ chainStore.pendingUpdates.forEach(({ chains }) => {
27
+ chains.forEach(chain => updateChain(chain));
28
+ });
29
+ chainStore.pendingUpdates = [];
30
+ }
31
+ };
32
+
33
+ const updateChain = (chain) => {
34
+ if (!chainStore.isInitialReceived) {
35
+ chainStore.pendingUpdates.push({ chains: [chain] });
36
+ return;
37
+ }
38
+
39
+ const key = chain.name.toLowerCase();
40
+ const existingChain = chainStore.chains.get(key);
41
+ const incomingUpdatedAt = new Date(chain.updatedAt).getTime();
42
+
43
+ if (existingChain) {
44
+ const existingUpdatedAt = new Date(existingChain.updatedAt).getTime();
45
+ if (incomingUpdatedAt <= existingUpdatedAt) {
46
+ return;
47
+ }
48
+
49
+ chainStore.chains.set(key, {
50
+ ...existingChain,
51
+ blockchainId: chain.blockchainId,
52
+ requiredConfirmations: chain.requiredConfirmations,
53
+ hasMemo: chain.hasMemo,
54
+ status: chain.status,
55
+ chainType: chain.chainType,
56
+ nativeTicker: chain.nativeTicker,
57
+ explorerTxUrl: chain.explorerTxUrl,
58
+ updatedAt: chain.updatedAt,
59
+ });
60
+ } else if (chain.name && chain.status) {
61
+ chainStore.chains.set(key, {
62
+ id: chain.id,
63
+ name: chain.name,
64
+ blockchainId: chain.blockchainId,
65
+ requiredConfirmations: chain.requiredConfirmations,
66
+ hasMemo: chain.hasMemo,
67
+ status: chain.status,
68
+ chainType: chain.chainType,
69
+ nativeTicker: chain.nativeTicker,
70
+ explorerTxUrl: chain.explorerTxUrl,
71
+ updatedAt: chain.updatedAt,
72
+ });
73
+ } else {
74
+ console.warn(`Ignoring update for unknown chain ${chain.name} with incomplete data`);
75
+ }
76
+ };
77
+
78
+ const getChains = () => {
79
+ return Array.from(chainStore.chains.values());
80
+ };
81
+
82
+ const getChainByName = (name) => {
83
+ return chainStore.chains.get(name.toLowerCase());
84
+ };
85
+
86
+ const resetChains = () => {
87
+ chainStore.chains.clear();
88
+ chainStore.isInitialReceived = false;
89
+ chainStore.pendingUpdates = [];
90
+ };
91
+
92
+ export { chainStore, setInitialChains, updateChain, getChains, getChainByName, resetChains };
@@ -1,5 +1,6 @@
1
1
  import { poolStore, getPools } from './store/poolStore.mjs';
2
2
  import { coinStore, getCoins } from './store/coinStore.mjs';
3
+ import { chainStore, getChains } from './store/chainStore.mjs';
3
4
  import { walletStore, getWallets } from './store/walletStore.mjs';
4
5
  import { userSharesStore, getUserShares } from './store/userSharesStore.mjs';
5
6
 
@@ -74,6 +75,41 @@ export function waitForStores(socket) {
74
75
  });
75
76
  };
76
77
 
78
+ // Function to wait for chainStore to be populated
79
+ const waitForChains = () => {
80
+ return new Promise((resolve, reject) => {
81
+ if (chainStore.isInitialReceived) {
82
+ const chains = getChains();
83
+ resolve(chains);
84
+ return;
85
+ }
86
+
87
+ const timeout = setTimeout(() => {
88
+ reject(new Error('Timeout waiting for initial chain data'));
89
+ }, 30000); // 30-second timeout
90
+
91
+ socket.on('chains_updated', ({ isInitial }) => {
92
+ if (isInitial) {
93
+ const chains = getChains();
94
+ clearTimeout(timeout);
95
+ resolve(chains);
96
+ }
97
+ });
98
+
99
+ socket.on('connect_error', (err) => {
100
+ console.error('Socket connect error:', err.message);
101
+ clearTimeout(timeout);
102
+ reject(new Error('Socket connection failed'));
103
+ });
104
+
105
+ socket.on('disconnect', (reason) => {
106
+ console.error('Socket disconnected:', reason);
107
+ clearTimeout(timeout);
108
+ reject(new Error('Socket disconnected before receiving initial chain data'));
109
+ });
110
+ });
111
+ };
112
+
77
113
  // Function to wait for walletStore to be populated
78
114
  const waitForWallets = () => {
79
115
  return new Promise((resolve, reject) => {
@@ -145,10 +181,11 @@ export function waitForStores(socket) {
145
181
  };
146
182
 
147
183
  // Return a promise that resolves when all stores are populated
148
- return Promise.all([waitForPools(), waitForCoins(), waitForWallets(), waitForUserShares()])
149
- .then(([pools, coins, wallets, userShares]) => ({
184
+ return Promise.all([waitForPools(), waitForCoins(), waitForChains(), waitForWallets(), waitForUserShares()])
185
+ .then(([pools, coins, chains, wallets, userShares]) => ({
150
186
  pools,
151
187
  coins,
188
+ chains,
152
189
  wallets,
153
190
  userShares,
154
191
  }));