voidai-sdk 0.1.1 → 0.1.2

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.
@@ -7,14 +7,180 @@ exports.VoidAIBridgeClient = void 0;
7
7
  const axios_1 = __importDefault(require("axios"));
8
8
  class VoidAIBridgeClient {
9
9
  constructor(config) {
10
+ this.validatedApiKeyData = null;
11
+ this.accessToken = null;
10
12
  this.config = config;
11
13
  this.client = axios_1.default.create({
12
14
  timeout: 10000,
13
15
  headers: {
14
16
  'Content-Type': 'application/json',
15
- 'x-api-key': this.config.apiKey,
17
+ 'api-key': this.config.apiKey,
16
18
  },
17
19
  });
20
+ // Start auth immediately. Requests will await this promise.
21
+ // New flow: POST /auth/login to get JWT. Fallback to validate-api-key for backward compatibility.
22
+ this.ready = this.authenticate().then(() => undefined);
23
+ }
24
+ /**
25
+ * Authenticate and set Authorization header for subsequent requests.
26
+ * New flow: POST /api/v1/auth/login
27
+ * Fallback: GET /api/v1/auth/validate-api-key (legacy)
28
+ */
29
+ async authenticate() {
30
+ try {
31
+ const token = await this.login();
32
+ this.setAccessToken(token);
33
+ // Populate validatedApiKeyData from JWT payload (best-effort) so existing getters keep working.
34
+ this.validatedApiKeyData = this.tryDecodeTokenToValidationData(token);
35
+ }
36
+ catch (error) {
37
+ // If login isn't available or fails unexpectedly, fallback to legacy validation
38
+ // (do not break current working functionality).
39
+ try {
40
+ await this.validateApiKey();
41
+ }
42
+ catch (fallbackError) {
43
+ throw error;
44
+ }
45
+ }
46
+ }
47
+ setAccessToken(token) {
48
+ this.accessToken = token;
49
+ this.client.defaults.headers.common['Authorization'] = `Bearer ${token}`;
50
+ }
51
+ /**
52
+ * Get access token (available after successful auth)
53
+ */
54
+ getAccessToken() {
55
+ return this.accessToken;
56
+ }
57
+ getLoginUrl() {
58
+ const baseUrl = this.config.getBaseUrl();
59
+ const cleanBase = baseUrl.replace(/\/$/, '');
60
+ return `${cleanBase}/api/v1/auth/login`;
61
+ }
62
+ /**
63
+ * Get EVM bridge contract address for burn operations.
64
+ */
65
+ getBridgeContractAddress() {
66
+ return this.config.bridgeContractAddress;
67
+ }
68
+ /**
69
+ * Login to obtain JWT access token.
70
+ * Frontend usage: { apiKey }
71
+ * Backend usage: { apiKey, secretKey }
72
+ */
73
+ async login() {
74
+ const loginUrl = this.getLoginUrl();
75
+ const body = {
76
+ apiKey: this.config.apiKey,
77
+ ...(this.config.secretKey ? { secretKey: this.config.secretKey } : {}),
78
+ };
79
+ try {
80
+ const response = await axios_1.default.post(loginUrl, body, {
81
+ headers: { 'Content-Type': 'application/json' },
82
+ timeout: 10000,
83
+ });
84
+ if (response.data && response.data.success && response.data.accessToken) {
85
+ return response.data.accessToken;
86
+ }
87
+ const errorData = response.data;
88
+ throw new Error(errorData?.error?.message || errorData?.message || 'Failed to login');
89
+ }
90
+ catch (error) {
91
+ if (axios_1.default.isAxiosError(error)) {
92
+ // If backend returns 401/403 or structured error, surface message.
93
+ const data = error.response?.data;
94
+ const msg = data?.error?.message || data?.message || error.message || 'Failed to login';
95
+ throw new Error(msg);
96
+ }
97
+ throw error;
98
+ }
99
+ }
100
+ tryDecodeTokenToValidationData(token) {
101
+ try {
102
+ const parts = token.split('.');
103
+ if (parts.length < 2)
104
+ return null;
105
+ const payload = parts[1];
106
+ const json = this.base64UrlDecode(payload);
107
+ const parsed = JSON.parse(json);
108
+ // backend token contains: keyId, name, sub/id, apiKey, etc.
109
+ if (!parsed?.keyId || !parsed?.name)
110
+ return null;
111
+ return {
112
+ keyId: String(parsed.keyId),
113
+ tenantId: String(parsed.sub || parsed.id || ''),
114
+ name: String(parsed.name),
115
+ };
116
+ }
117
+ catch {
118
+ return null;
119
+ }
120
+ }
121
+ base64UrlDecode(input) {
122
+ const base64 = input.replace(/-/g, '+').replace(/_/g, '/');
123
+ const pad = base64.length % 4;
124
+ const padded = pad ? base64 + '='.repeat(4 - pad) : base64;
125
+ // Node (backend) vs Browser
126
+ if (typeof Buffer !== 'undefined') {
127
+ return Buffer.from(padded, 'base64').toString('utf8');
128
+ }
129
+ // @ts-ignore
130
+ return atob(padded);
131
+ }
132
+ /**
133
+ * Validate API key with the backend
134
+ * @throws Error if API key is invalid
135
+ */
136
+ async validateApiKey() {
137
+ try {
138
+ // Use a temporary axios instance for validation since baseUrl might be different
139
+ const validationUrl = this.getValidationUrl();
140
+ const response = await axios_1.default.get(validationUrl, {
141
+ headers: {
142
+ 'api-key': this.config.apiKey,
143
+ },
144
+ timeout: 10000,
145
+ });
146
+ if (response.data.success) {
147
+ this.validatedApiKeyData = response.data.data;
148
+ return response.data.data;
149
+ }
150
+ else {
151
+ const error = new Error(response.data.error.message);
152
+ error.code = response.data.error.code;
153
+ throw error;
154
+ }
155
+ }
156
+ catch (error) {
157
+ // If validation fails, ensure we don't keep stale validated data around.
158
+ this.validatedApiKeyData = null;
159
+ if (axios_1.default.isAxiosError(error)) {
160
+ if (error.response?.status === 401) {
161
+ const errorData = error.response.data;
162
+ const apiError = new Error(errorData.error?.message || 'API key is invalid or inactive');
163
+ apiError.code = errorData.error?.code || 'INVALID_API_KEY';
164
+ throw apiError;
165
+ }
166
+ throw new Error(`Failed to validate API key: ${error.message}`);
167
+ }
168
+ throw error;
169
+ }
170
+ }
171
+ /**
172
+ * Get validation URL - uses baseUrl from config
173
+ */
174
+ getValidationUrl() {
175
+ const baseUrl = this.config.getBaseUrl();
176
+ const cleanBase = baseUrl.replace(/\/$/, '');
177
+ return `${cleanBase}/api/v1/auth/validate-api-key`;
178
+ }
179
+ /**
180
+ * Get validated API key data
181
+ */
182
+ getValidatedApiKeyData() {
183
+ return this.validatedApiKeyData;
18
184
  }
19
185
  getUrl(path) {
20
186
  const baseUrl = this.config.getBaseUrl();
@@ -23,28 +189,64 @@ class VoidAIBridgeClient {
23
189
  const cleanPath = path.replace(/^\//, '');
24
190
  return `${cleanBase}/${cleanPath}`;
25
191
  }
26
- async get(path, params) {
192
+ async get(path, params, retryAttempted = false) {
193
+ await this.ready;
27
194
  const url = this.getUrl(path);
28
195
  try {
29
196
  const response = await this.client.get(url, { params });
30
197
  return response.data;
31
198
  }
32
199
  catch (error) {
200
+ // If token is expired or unauthorized, transparently re-authenticate once and retry.
201
+ const status = error?.response?.status ?? error?.statusCode;
202
+ if (status === 401 && !retryAttempted) {
203
+ try {
204
+ await this.authenticate();
205
+ // Retry the original request once with fresh credentials.
206
+ return await this.get(path, params, true);
207
+ }
208
+ catch (retryError) {
209
+ this.handleError(retryError);
210
+ }
211
+ }
33
212
  this.handleError(error);
34
- throw error;
35
213
  }
36
214
  }
37
- async post(path, data) {
215
+ async post(path, data, retryAttempted = false) {
216
+ await this.ready;
38
217
  const url = this.getUrl(path);
39
218
  try {
40
219
  const response = await this.client.post(url, data);
41
220
  return response.data;
42
221
  }
43
222
  catch (error) {
223
+ // If token is expired or unauthorized, transparently re-authenticate once and retry.
224
+ const status = error?.response?.status ?? error?.statusCode;
225
+ if (status === 401 && !retryAttempted) {
226
+ try {
227
+ await this.authenticate();
228
+ // Retry the original request once with fresh credentials.
229
+ return await this.post(path, data, true);
230
+ }
231
+ catch (retryError) {
232
+ this.handleError(retryError);
233
+ }
234
+ }
44
235
  this.handleError(error);
45
- throw error;
46
236
  }
47
237
  }
238
+ /**
239
+ * Bridge swap operation
240
+ */
241
+ async bridgeSwap(payload) {
242
+ return this.post('api/v1/bridge/swap', payload);
243
+ }
244
+ /**
245
+ * Route transaction operation (SWAP / BRIDGE / CCIP)
246
+ */
247
+ async routeTransaction(payload) {
248
+ return this.post('api/v1/bridge/route-transaction', payload);
249
+ }
48
250
  /**
49
251
  * Get list of supported chains
50
252
  * @param options - Optional query parameters
@@ -63,26 +265,82 @@ class VoidAIBridgeClient {
63
265
  if (options?.chainId !== undefined) {
64
266
  params.chain_id = options.chainId;
65
267
  }
66
- const response = await this.get('api/chains', params);
67
- return response.chains;
268
+ const response = await this.get('api/v1/chain/chains', params);
269
+ if (!response.success || !response.data) {
270
+ throw new Error(response.message || 'Failed to fetch chains');
271
+ }
272
+ return response.data.chains;
68
273
  }
69
274
  /**
70
275
  * Get list of supported assets
71
276
  */
72
277
  async getAssetList(chainId) {
73
- const response = await this.get('api/asset');
278
+ const response = await this.get('api/v1/asset/assets');
279
+ if (!response.success || !response.data) {
280
+ throw new Error(response.message || 'Failed to fetch assets');
281
+ }
282
+ let assets = response.data.assets;
74
283
  // Filter by chainId if provided
75
284
  if (chainId !== undefined) {
76
- return response.assets.filter(asset => asset.chainId === chainId);
285
+ assets = assets.filter(asset => asset.chainId === chainId);
77
286
  }
78
- return response.assets;
287
+ return assets;
79
288
  }
289
+ /**
290
+ * Get bridge fee estimate
291
+ * @param params - Fee estimation parameters
292
+ */
293
+ async getBridgeFeeEstimate(params) {
294
+ const queryParams = {
295
+ fromToken: params.fromToken,
296
+ toToken: params.toToken,
297
+ amount: String(params.amount),
298
+ };
299
+ return this.get('api/v1/bridge/call-fee', queryParams);
300
+ }
301
+ /**
302
+ * Get router swap fee estimate
303
+ * @param params - Fee estimation parameters
304
+ */
305
+ async getRouterSwapFeeEstimate(params) {
306
+ const queryParams = {
307
+ originAssetId: String(params.originAssetId),
308
+ destinationAssetId: String(params.destinationAssetId),
309
+ amount: String(params.amount),
310
+ operationType: params.operationType,
311
+ toAddress: params.toAddress,
312
+ };
313
+ return this.get('api/v1/router-swap/call-fee', queryParams);
314
+ }
315
+ /**
316
+ * Normalize and rethrow errors with backend message (if available) so
317
+ * integrators can surface meaningful reasons to their users.
318
+ */
80
319
  handleError(error) {
81
320
  if (axios_1.default.isAxiosError(error)) {
82
- console.error('Bridge API Error:', error.response?.data || error.message);
321
+ const status = error.response?.status;
322
+ const data = error.response?.data;
323
+ // Try to extract a human friendly message from common backend shapes
324
+ let backendMessage = data?.error?.message ||
325
+ data?.message ||
326
+ (typeof data?.error === 'string' ? data.error : undefined) ||
327
+ (data?.success === false && data?.message ? data.message : undefined);
328
+ // For auth failures, avoid leaking raw backend JSON and give a clearer hint.
329
+ if (status === 401 &&
330
+ (backendMessage === 'Unauthorized' ||
331
+ data?.statusCode === 401 ||
332
+ data?.message === 'Unauthorized')) {
333
+ backendMessage =
334
+ 'Session expired or unauthorized. Please verify your API key/secret and try again.';
335
+ }
336
+ const message = backendMessage ||
337
+ error.message ||
338
+ (status ? `Request failed with status ${status}` : 'Request failed');
339
+ throw new Error(message);
83
340
  }
84
341
  else {
85
- console.error('Unexpected Error:', error);
342
+ const message = error?.message || 'Unexpected error';
343
+ throw new Error(message);
86
344
  }
87
345
  }
88
346
  }
package/dist/config.d.ts CHANGED
@@ -1,9 +1,19 @@
1
- import { BridgeSDKOptions, Environment } from './types';
1
+ import { BridgeSDKOptions, BridgeSDKServerOptions, Environment } from './types';
2
+ /** Internal: options accepted by BridgeConfig (frontend or server) */
3
+ type BridgeConfigOptions = BridgeSDKOptions | BridgeSDKServerOptions;
2
4
  export declare class BridgeConfig {
3
5
  readonly apiKey: string;
6
+ readonly secretKey?: string;
4
7
  readonly environment: Environment;
5
8
  readonly baseUrl: string;
9
+ /**
10
+ * EVM bridge contract address used for burn operations
11
+ * (wTAO/wALPHA -> TAO/ALPHA). Network-specific values can be
12
+ * configured here per environment.
13
+ */
14
+ readonly bridgeContractAddress: string;
6
15
  private static readonly DEFAULTS;
7
- constructor(options: BridgeSDKOptions);
16
+ constructor(options: BridgeConfigOptions);
8
17
  getBaseUrl(): string;
9
18
  }
19
+ export {};
package/dist/config.js CHANGED
@@ -7,6 +7,7 @@ class BridgeConfig {
7
7
  throw new Error('BridgeSDK: apiKey is required');
8
8
  }
9
9
  this.apiKey = options.apiKey;
10
+ this.secretKey = 'secretKey' in options ? options.secretKey : undefined;
10
11
  this.environment = options.environment || 'production';
11
12
  // Ensure environment is valid, default to production if invalid
12
13
  const validEnvironments = ['development', 'staging', 'production'];
@@ -14,8 +15,10 @@ class BridgeConfig {
14
15
  this.environment = 'production';
15
16
  }
16
17
  const defaults = BridgeConfig.DEFAULTS[this.environment];
17
- // Allow custom base URL override
18
- this.baseUrl = options.baseUrl || defaults.baseUrl;
18
+ // Base URL & bridge contract address are derived from environment;
19
+ // consumers should not override these at runtime.
20
+ this.baseUrl = defaults.baseUrl;
21
+ this.bridgeContractAddress = defaults.bridgeContractAddress;
19
22
  }
20
23
  getBaseUrl() {
21
24
  return this.baseUrl;
@@ -24,12 +27,16 @@ class BridgeConfig {
24
27
  exports.BridgeConfig = BridgeConfig;
25
28
  BridgeConfig.DEFAULTS = {
26
29
  development: {
27
- baseUrl: 'https://api-dev.voidai.envistudios.com',
30
+ // Local/dev backend
31
+ baseUrl: 'https://api-sdk-dev.voidai.envistudios.com/',
32
+ bridgeContractAddress: '0x6266ce15aC4f32F096Ff91881dd887a0F4bBa569',
28
33
  },
29
34
  staging: {
30
- baseUrl: 'https://api-staging.voidai.envistudios.com',
35
+ baseUrl: 'https://api-sdk-stage.voidai.envistudios.com/',
36
+ bridgeContractAddress: '0x6266ce15aC4f32F096Ff91881dd887a0F4bBa569',
31
37
  },
32
38
  production: {
33
- baseUrl: 'https://api.voidai.envistudios.com',
39
+ baseUrl: 'https://api-sdk.voidai.envistudios.com/',
40
+ bridgeContractAddress: '0x6266ce15aC4f32F096Ff91881dd887a0F4bBa569',
34
41
  },
35
42
  };
@@ -1,4 +1,5 @@
1
1
  import { VoidAIBridgeClient } from '../api/client';
2
+ import { BridgeSwapRequest, BridgeSwapResponse, RouteSwapRequest, RouteBridgeRequest, RouteCcipRequest, RouteTransactionResponse, BridgeFeeEstimateRequest, BridgeFeeEstimateResponse, RouterSwapFeeEstimateRequest, RouterSwapFeeEstimateResponse } from '../types';
2
3
  /**
3
4
  * Bridge API Methods
4
5
  * Provides read-only API methods for bridge operations
@@ -14,4 +15,32 @@ export declare class Bridge {
14
15
  * Get transaction history for an address
15
16
  */
16
17
  getHistory(address: string): Promise<any[]>;
18
+ /**
19
+ * Initiate a bridge operation (formerly swap).
20
+ */
21
+ bridge(payload: BridgeSwapRequest): Promise<BridgeSwapResponse>;
22
+ /**
23
+ * Alias for backward compatibility.
24
+ */
25
+ swap(payload: BridgeSwapRequest): Promise<BridgeSwapResponse>;
26
+ /**
27
+ * Route a SWAP operation through the unified route-transaction API.
28
+ */
29
+ routeSwap(payload: RouteSwapRequest): Promise<RouteTransactionResponse>;
30
+ /**
31
+ * Route a BRIDGE operation through the unified route-transaction API.
32
+ */
33
+ routeBridge(payload: RouteBridgeRequest): Promise<RouteTransactionResponse>;
34
+ /**
35
+ * Route a CCIP operation through the unified route-transaction API.
36
+ */
37
+ routeCcip(payload: RouteCcipRequest): Promise<RouteTransactionResponse>;
38
+ /**
39
+ * Get bridge fee estimate
40
+ */
41
+ getBridgeFeeEstimate(params: BridgeFeeEstimateRequest): Promise<BridgeFeeEstimateResponse>;
42
+ /**
43
+ * Get router swap fee estimate
44
+ */
45
+ getRouterSwapFeeEstimate(params: RouterSwapFeeEstimateRequest): Promise<RouterSwapFeeEstimateResponse>;
17
46
  }
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Bridge = void 0;
4
+ const viem_1 = require("viem");
4
5
  /**
5
6
  * Bridge API Methods
6
7
  * Provides read-only API methods for bridge operations
@@ -22,5 +23,119 @@ class Bridge {
22
23
  async getHistory(address) {
23
24
  return this.apiClient.get(`/transactions/history/${address}`);
24
25
  }
26
+ /**
27
+ * Initiate a bridge operation (formerly swap).
28
+ */
29
+ async bridge(payload) {
30
+ try {
31
+ const response = await this.apiClient.bridgeSwap(payload);
32
+ // For EVM flows that return encodedData + signature, prepare
33
+ // a ready-to-send Ethereum transaction for the bridge contract.
34
+ const maybeWithEncoded = response;
35
+ if (maybeWithEncoded.encodedData && maybeWithEncoded.signature) {
36
+ // IMPORTANT:
37
+ // - The bridge contract address is configured per environment
38
+ // in BridgeConfig (config.ts). The encodedData & signature are
39
+ // already validated/constructed by the backend.
40
+ // - We simply ABI-encode the function call so frontend integrators
41
+ // can pass it directly to MetaMask / wallet providers.
42
+ const bridgeContractAddress = this.apiClient.getBridgeContractAddress();
43
+ const calldata = (0, viem_1.encodeFunctionData)({
44
+ abi: [
45
+ {
46
+ type: 'function',
47
+ name: 'burn',
48
+ stateMutability: 'nonpayable',
49
+ inputs: [
50
+ { name: 'encodedData', type: 'bytes' },
51
+ { name: 'signature', type: 'bytes' },
52
+ ],
53
+ outputs: [],
54
+ },
55
+ ],
56
+ functionName: 'burn',
57
+ args: [maybeWithEncoded.encodedData, maybeWithEncoded.signature],
58
+ });
59
+ // Attach the prepared transaction payload in a non-breaking way.
60
+ maybeWithEncoded.evmTransaction = {
61
+ to: bridgeContractAddress,
62
+ data: calldata,
63
+ value: '0x0',
64
+ };
65
+ }
66
+ return response;
67
+ }
68
+ catch (error) {
69
+ // Surface a clean error message while preserving the original error for debugging.
70
+ const message = error?.message || 'Failed to execute bridge swap';
71
+ throw new Error(message);
72
+ }
73
+ }
74
+ /**
75
+ * Alias for backward compatibility.
76
+ */
77
+ async swap(payload) {
78
+ return this.bridge(payload);
79
+ }
80
+ /**
81
+ * Route a SWAP operation through the unified route-transaction API.
82
+ */
83
+ async routeSwap(payload) {
84
+ try {
85
+ return await this.apiClient.routeTransaction(payload);
86
+ }
87
+ catch (error) {
88
+ const message = error?.message || 'Failed to route SWAP transaction';
89
+ throw new Error(message);
90
+ }
91
+ }
92
+ /**
93
+ * Route a BRIDGE operation through the unified route-transaction API.
94
+ */
95
+ async routeBridge(payload) {
96
+ try {
97
+ return await this.apiClient.routeTransaction(payload);
98
+ }
99
+ catch (error) {
100
+ const message = error?.message || 'Failed to route BRIDGE transaction';
101
+ throw new Error(message);
102
+ }
103
+ }
104
+ /**
105
+ * Route a CCIP operation through the unified route-transaction API.
106
+ */
107
+ async routeCcip(payload) {
108
+ try {
109
+ return await this.apiClient.routeTransaction(payload);
110
+ }
111
+ catch (error) {
112
+ const message = error?.message || 'Failed to route CCIP transaction';
113
+ throw new Error(message);
114
+ }
115
+ }
116
+ /**
117
+ * Get bridge fee estimate
118
+ */
119
+ async getBridgeFeeEstimate(params) {
120
+ try {
121
+ return await this.apiClient.getBridgeFeeEstimate(params);
122
+ }
123
+ catch (error) {
124
+ const message = error?.message || 'Failed to get bridge fee estimate';
125
+ throw new Error(message);
126
+ }
127
+ }
128
+ /**
129
+ * Get router swap fee estimate
130
+ */
131
+ async getRouterSwapFeeEstimate(params) {
132
+ try {
133
+ return await this.apiClient.getRouterSwapFeeEstimate(params);
134
+ }
135
+ catch (error) {
136
+ const message = error?.message || 'Failed to get router swap fee estimate';
137
+ throw new Error(message);
138
+ }
139
+ }
25
140
  }
26
141
  exports.Bridge = Bridge;
package/dist/index.d.ts CHANGED
@@ -4,12 +4,16 @@ import { BittensorWallet } from './wallet/bittensor';
4
4
  import { EthereumWallet } from './wallet/ethereum';
5
5
  import { SolanaWallet } from './wallet/solana';
6
6
  import { Bridge } from './core/bridge';
7
- import { BridgeSDKOptions } from './types';
7
+ import { BridgeSDKOptions, BridgeSDKServerOptions, ApiKeyValidationData } from './types';
8
8
  export * from './types';
9
9
  export * from './config';
10
10
  export * from './wallet/bittensor';
11
11
  export * from './wallet/ethereum';
12
12
  export * from './wallet/solana';
13
+ /**
14
+ * BridgeSDK – for frontend/browser usage.
15
+ * Use apiKey only; do not pass secretKey in frontend.
16
+ */
13
17
  export declare class BridgeSDK {
14
18
  readonly config: BridgeConfig;
15
19
  readonly api: VoidAIBridgeClient;
@@ -19,9 +23,33 @@ export declare class BridgeSDK {
19
23
  solana: SolanaWallet;
20
24
  };
21
25
  readonly bridge: Bridge;
26
+ /**
27
+ * Resolves once the SDK has validated the API key (or rejects if invalid).
28
+ * Consumers can await this if they want to gate UI on readiness.
29
+ */
30
+ readonly ready: Promise<void>;
22
31
  constructor(options: BridgeSDKOptions);
23
32
  /**
24
- * Initialize the SDK
33
+ * Get validated API key data (available after successful validation)
34
+ */
35
+ getValidatedApiKeyData(): ApiKeyValidationData | null;
36
+ }
37
+ /**
38
+ * BridgeSDKServer – for backend/server usage.
39
+ * Requires apiKey + secretKey for JWT authentication.
40
+ * No wallet integrations (use BridgeSDK in frontend for that).
41
+ */
42
+ export declare class BridgeSDKServer {
43
+ readonly config: BridgeConfig;
44
+ readonly api: VoidAIBridgeClient;
45
+ readonly bridge: Bridge;
46
+ /**
47
+ * Resolves once the SDK has validated the API key (or rejects if invalid).
48
+ */
49
+ readonly ready: Promise<void>;
50
+ constructor(options: BridgeSDKServerOptions);
51
+ /**
52
+ * Get validated API key data (available after successful validation)
25
53
  */
26
- init(): Promise<void>;
54
+ getValidatedApiKeyData(): ApiKeyValidationData | null;
27
55
  }
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.BridgeSDK = void 0;
17
+ exports.BridgeSDKServer = exports.BridgeSDK = void 0;
18
18
  const config_1 = require("./config");
19
19
  const client_1 = require("./api/client");
20
20
  const bittensor_1 = require("./wallet/bittensor");
@@ -26,10 +26,15 @@ __exportStar(require("./config"), exports);
26
26
  __exportStar(require("./wallet/bittensor"), exports);
27
27
  __exportStar(require("./wallet/ethereum"), exports);
28
28
  __exportStar(require("./wallet/solana"), exports);
29
+ /**
30
+ * BridgeSDK – for frontend/browser usage.
31
+ * Use apiKey only; do not pass secretKey in frontend.
32
+ */
29
33
  class BridgeSDK {
30
34
  constructor(options) {
31
35
  this.config = new config_1.BridgeConfig(options);
32
36
  this.api = new client_1.VoidAIBridgeClient(this.config);
37
+ this.ready = this.api.ready;
33
38
  this.wallets = {
34
39
  bittensor: new bittensor_1.BittensorWallet(),
35
40
  ethereum: new ethereum_1.EthereumWallet(),
@@ -38,10 +43,30 @@ class BridgeSDK {
38
43
  this.bridge = new bridge_1.Bridge(this.api);
39
44
  }
40
45
  /**
41
- * Initialize the SDK
46
+ * Get validated API key data (available after successful validation)
42
47
  */
43
- async init() {
44
- console.log('BridgeSDK initialized');
48
+ getValidatedApiKeyData() {
49
+ return this.api.getValidatedApiKeyData();
45
50
  }
46
51
  }
47
52
  exports.BridgeSDK = BridgeSDK;
53
+ /**
54
+ * BridgeSDKServer – for backend/server usage.
55
+ * Requires apiKey + secretKey for JWT authentication.
56
+ * No wallet integrations (use BridgeSDK in frontend for that).
57
+ */
58
+ class BridgeSDKServer {
59
+ constructor(options) {
60
+ this.config = new config_1.BridgeConfig(options);
61
+ this.api = new client_1.VoidAIBridgeClient(this.config);
62
+ this.ready = this.api.ready;
63
+ this.bridge = new bridge_1.Bridge(this.api);
64
+ }
65
+ /**
66
+ * Get validated API key data (available after successful validation)
67
+ */
68
+ getValidatedApiKeyData() {
69
+ return this.api.getValidatedApiKeyData();
70
+ }
71
+ }
72
+ exports.BridgeSDKServer = BridgeSDKServer;