@voidaisdk/bridge-sdk 0.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/README.md +435 -0
- package/dist/api/client.d.ts +118 -0
- package/dist/api/client.js +449 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.js +41 -0
- package/dist/core/bridge.d.ts +70 -0
- package/dist/core/bridge.js +213 -0
- package/dist/index.d.ts +55 -0
- package/dist/index.js +72 -0
- package/dist/types/index.d.ts +280 -0
- package/dist/types/index.js +2 -0
- package/dist/utils/validation.d.ts +2 -0
- package/dist/utils/validation.js +12 -0
- package/dist/wallet/bittensor.d.ts +59 -0
- package/dist/wallet/bittensor.js +143 -0
- package/dist/wallet/ethereum.d.ts +42 -0
- package/dist/wallet/ethereum.js +107 -0
- package/dist/wallet/solana.d.ts +36 -0
- package/dist/wallet/solana.js +100 -0
- package/dist-browser/voidai-sdk.js +2 -0
- package/dist-browser/voidai-sdk.js.LICENSE.txt +5 -0
- package/package.json +56 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.VoidAIBridgeClient = void 0;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
class VoidAIBridgeClient {
|
|
9
|
+
constructor(config) {
|
|
10
|
+
this.validatedApiKeyData = null;
|
|
11
|
+
this.accessToken = null;
|
|
12
|
+
this.config = config;
|
|
13
|
+
this.client = axios_1.default.create({
|
|
14
|
+
timeout: 10000,
|
|
15
|
+
headers: {
|
|
16
|
+
'Content-Type': 'application/json',
|
|
17
|
+
},
|
|
18
|
+
});
|
|
19
|
+
// Start auth immediately. Requests will await this promise.
|
|
20
|
+
// New flow: POST /auth/login to get JWT. Fallback to validate-api-key for backward compatibility.
|
|
21
|
+
this.ready = this.authenticate().then(() => undefined);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Authenticate and set Authorization header for subsequent requests.
|
|
25
|
+
* New flow: POST /api/v1/auth/login
|
|
26
|
+
* Fallback: GET /api/v1/auth/validate-api-key (legacy)
|
|
27
|
+
*/
|
|
28
|
+
async authenticate() {
|
|
29
|
+
try {
|
|
30
|
+
const token = await this.login();
|
|
31
|
+
this.setAccessToken(token);
|
|
32
|
+
// Populate validatedApiKeyData from JWT payload (best-effort) so existing getters keep working.
|
|
33
|
+
this.validatedApiKeyData = this.tryDecodeTokenToValidationData(token);
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
// If login isn't available or fails unexpectedly, fallback to legacy validation
|
|
37
|
+
// (do not break current working functionality).
|
|
38
|
+
try {
|
|
39
|
+
await this.validateApiKey();
|
|
40
|
+
}
|
|
41
|
+
catch (fallbackError) {
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
setAccessToken(token) {
|
|
47
|
+
this.accessToken = token;
|
|
48
|
+
this.client.defaults.headers.common['Authorization'] = `Bearer ${token}`;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get access token (available after successful auth)
|
|
52
|
+
*/
|
|
53
|
+
getAccessToken() {
|
|
54
|
+
return this.accessToken;
|
|
55
|
+
}
|
|
56
|
+
getLoginUrl() {
|
|
57
|
+
const baseUrl = this.config.getBaseUrl();
|
|
58
|
+
const cleanBase = baseUrl.replace(/\/$/, '');
|
|
59
|
+
return `${cleanBase}/api/v1/auth/login`;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get EVM bridge contract address for burn operations.
|
|
63
|
+
*/
|
|
64
|
+
getBridgeContractAddress() {
|
|
65
|
+
return this.config.bridgeContractAddress;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Login to obtain JWT access token.
|
|
69
|
+
* Frontend usage: { apiKey }
|
|
70
|
+
* Backend usage: { apiKey, secretKey }
|
|
71
|
+
*/
|
|
72
|
+
async login() {
|
|
73
|
+
const loginUrl = this.getLoginUrl();
|
|
74
|
+
const body = {
|
|
75
|
+
apiKey: this.config.apiKey,
|
|
76
|
+
...(this.config.secretKey ? { secretKey: this.config.secretKey } : {}),
|
|
77
|
+
};
|
|
78
|
+
try {
|
|
79
|
+
const response = await axios_1.default.post(loginUrl, body, {
|
|
80
|
+
headers: { 'Content-Type': 'application/json' },
|
|
81
|
+
timeout: 10000,
|
|
82
|
+
});
|
|
83
|
+
if (response.data && response.data.success && response.data.accessToken) {
|
|
84
|
+
return response.data.accessToken;
|
|
85
|
+
}
|
|
86
|
+
const errorData = response.data;
|
|
87
|
+
throw new Error(errorData?.error?.message || errorData?.message || 'Failed to login');
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
91
|
+
// If backend returns 401/403 or structured error, surface message.
|
|
92
|
+
const data = error.response?.data;
|
|
93
|
+
const msg = data?.error?.message || data?.message || error.message || 'Failed to login';
|
|
94
|
+
throw new Error(msg);
|
|
95
|
+
}
|
|
96
|
+
throw error;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
tryDecodeTokenToValidationData(token) {
|
|
100
|
+
try {
|
|
101
|
+
const parts = token.split('.');
|
|
102
|
+
if (parts.length < 2)
|
|
103
|
+
return null;
|
|
104
|
+
const payload = parts[1];
|
|
105
|
+
const json = this.base64UrlDecode(payload);
|
|
106
|
+
const parsed = JSON.parse(json);
|
|
107
|
+
// backend token contains: keyId, name, sub/id, apiKey, etc.
|
|
108
|
+
if (!parsed?.keyId || !parsed?.name)
|
|
109
|
+
return null;
|
|
110
|
+
return {
|
|
111
|
+
keyId: String(parsed.keyId),
|
|
112
|
+
tenantId: String(parsed.sub || parsed.id || ''),
|
|
113
|
+
name: String(parsed.name),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
return null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
base64UrlDecode(input) {
|
|
121
|
+
const base64 = input.replace(/-/g, '+').replace(/_/g, '/');
|
|
122
|
+
const pad = base64.length % 4;
|
|
123
|
+
const padded = pad ? base64 + '='.repeat(4 - pad) : base64;
|
|
124
|
+
// Node (backend) vs Browser
|
|
125
|
+
if (typeof Buffer !== 'undefined') {
|
|
126
|
+
return Buffer.from(padded, 'base64').toString('utf8');
|
|
127
|
+
}
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
return atob(padded);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Validate API key with the backend
|
|
133
|
+
* @throws Error if API key is invalid
|
|
134
|
+
*/
|
|
135
|
+
async validateApiKey() {
|
|
136
|
+
try {
|
|
137
|
+
// Use a temporary axios instance for validation since baseUrl might be different
|
|
138
|
+
const validationUrl = this.getValidationUrl();
|
|
139
|
+
const response = await axios_1.default.get(validationUrl, {
|
|
140
|
+
headers: {
|
|
141
|
+
'api-key': this.config.apiKey,
|
|
142
|
+
},
|
|
143
|
+
timeout: 10000,
|
|
144
|
+
});
|
|
145
|
+
if (response.data.success) {
|
|
146
|
+
this.validatedApiKeyData = response.data.data;
|
|
147
|
+
return response.data.data;
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
const error = new Error(response.data.error.message);
|
|
151
|
+
error.code = response.data.error.code;
|
|
152
|
+
throw error;
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
// If validation fails, ensure we don't keep stale validated data around.
|
|
157
|
+
this.validatedApiKeyData = null;
|
|
158
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
159
|
+
if (error.response?.status === 401) {
|
|
160
|
+
const errorData = error.response.data;
|
|
161
|
+
const apiError = new Error(errorData.error?.message || 'API key is invalid or inactive');
|
|
162
|
+
apiError.code = errorData.error?.code || 'INVALID_API_KEY';
|
|
163
|
+
throw apiError;
|
|
164
|
+
}
|
|
165
|
+
throw new Error(`Failed to validate API key: ${error.message}`);
|
|
166
|
+
}
|
|
167
|
+
throw error;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get validation URL - uses baseUrl from config
|
|
172
|
+
*/
|
|
173
|
+
getValidationUrl() {
|
|
174
|
+
const baseUrl = this.config.getBaseUrl();
|
|
175
|
+
const cleanBase = baseUrl.replace(/\/$/, '');
|
|
176
|
+
return `${cleanBase}/api/v1/auth/validate-api-key`;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get validated API key data
|
|
180
|
+
*/
|
|
181
|
+
getValidatedApiKeyData() {
|
|
182
|
+
return this.validatedApiKeyData;
|
|
183
|
+
}
|
|
184
|
+
getUrl(path) {
|
|
185
|
+
const baseUrl = this.config.getBaseUrl();
|
|
186
|
+
// Remove trailing slash from base and leading slash from path to avoid doubles
|
|
187
|
+
const cleanBase = baseUrl.replace(/\/$/, '');
|
|
188
|
+
const cleanPath = path.replace(/^\//, '');
|
|
189
|
+
return `${cleanBase}/${cleanPath}`;
|
|
190
|
+
}
|
|
191
|
+
async get(path, params, retryAttempted = false) {
|
|
192
|
+
await this.ready;
|
|
193
|
+
const url = this.getUrl(path);
|
|
194
|
+
try {
|
|
195
|
+
const response = await this.client.get(url, { params });
|
|
196
|
+
return response.data;
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
// If token is expired or unauthorized, transparently re-authenticate once and retry.
|
|
200
|
+
const status = error?.response?.status ?? error?.statusCode;
|
|
201
|
+
if (status === 401 && !retryAttempted) {
|
|
202
|
+
try {
|
|
203
|
+
await this.authenticate();
|
|
204
|
+
// Retry the original request once with fresh credentials.
|
|
205
|
+
return await this.get(path, params, true);
|
|
206
|
+
}
|
|
207
|
+
catch (retryError) {
|
|
208
|
+
this.handleError(retryError);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
this.handleError(error);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
async post(path, data, retryAttempted = false) {
|
|
215
|
+
await this.ready;
|
|
216
|
+
const url = this.getUrl(path);
|
|
217
|
+
try {
|
|
218
|
+
const response = await this.client.post(url, data);
|
|
219
|
+
return response.data;
|
|
220
|
+
}
|
|
221
|
+
catch (error) {
|
|
222
|
+
// If token is expired or unauthorized, transparently re-authenticate once and retry.
|
|
223
|
+
const status = error?.response?.status ?? error?.statusCode;
|
|
224
|
+
if (status === 401 && !retryAttempted) {
|
|
225
|
+
try {
|
|
226
|
+
await this.authenticate();
|
|
227
|
+
// Retry the original request once with fresh credentials.
|
|
228
|
+
return await this.post(path, data, true);
|
|
229
|
+
}
|
|
230
|
+
catch (retryError) {
|
|
231
|
+
this.handleError(retryError);
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
this.handleError(error);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
async delete(path, params, retryAttempted = false) {
|
|
238
|
+
await this.ready;
|
|
239
|
+
const url = this.getUrl(path);
|
|
240
|
+
try {
|
|
241
|
+
const response = await this.client.delete(url, { params });
|
|
242
|
+
return response.data;
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
const status = error?.response?.status ?? error?.statusCode;
|
|
246
|
+
if (status === 401 && !retryAttempted) {
|
|
247
|
+
try {
|
|
248
|
+
await this.authenticate();
|
|
249
|
+
return await this.delete(path, params, true);
|
|
250
|
+
}
|
|
251
|
+
catch (retryError) {
|
|
252
|
+
this.handleError(retryError);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
this.handleError(error);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async patch(path, data, retryAttempted = false) {
|
|
259
|
+
await this.ready;
|
|
260
|
+
const url = this.getUrl(path);
|
|
261
|
+
try {
|
|
262
|
+
const response = await this.client.patch(url, data);
|
|
263
|
+
return response.data;
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
const status = error?.response?.status ?? error?.statusCode;
|
|
267
|
+
if (status === 401 && !retryAttempted) {
|
|
268
|
+
try {
|
|
269
|
+
await this.authenticate();
|
|
270
|
+
return await this.patch(path, data, true);
|
|
271
|
+
}
|
|
272
|
+
catch (retryError) {
|
|
273
|
+
this.handleError(retryError);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
this.handleError(error);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Bridge swap operation
|
|
281
|
+
*/
|
|
282
|
+
async bridgeSwap(payload) {
|
|
283
|
+
return this.post('api/v1/bridge/swap', payload);
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Route transaction operation (SWAP / BRIDGE / CCIP)
|
|
287
|
+
*/
|
|
288
|
+
async routeTransaction(payload) {
|
|
289
|
+
// Backend expects amount as a string, but our types use number.
|
|
290
|
+
// Normalize here so callers can continue passing numbers.
|
|
291
|
+
const normalizedPayload = {
|
|
292
|
+
...payload,
|
|
293
|
+
amount: String(payload.amount),
|
|
294
|
+
};
|
|
295
|
+
return this.post('api/v1/bridge/route-transaction', normalizedPayload);
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Cancel a CCIP route transaction
|
|
299
|
+
*/
|
|
300
|
+
async cancelCcip(params) {
|
|
301
|
+
const queryParams = {
|
|
302
|
+
operationType: params.operationType,
|
|
303
|
+
fromToken: params.fromToken,
|
|
304
|
+
toToken: params.toToken,
|
|
305
|
+
uuid: params.uuid,
|
|
306
|
+
};
|
|
307
|
+
return this.delete('api/v1/bridge/cancel-ccip', queryParams);
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Cancel a router swap transaction
|
|
311
|
+
*/
|
|
312
|
+
async cancelRouterSwap(params) {
|
|
313
|
+
const queryParams = {
|
|
314
|
+
uuid: params.uuid,
|
|
315
|
+
};
|
|
316
|
+
return this.delete('api/v1/bridge/cancel-router-swap', queryParams);
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Cancel a bridge swap transaction
|
|
320
|
+
*/
|
|
321
|
+
async cancelBridgeSwap(params) {
|
|
322
|
+
return this.patch('api/v1/bridge/swap/cancel', params);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Get recent API transactions (tenant-level)
|
|
326
|
+
*
|
|
327
|
+
* Maps to:
|
|
328
|
+
* POST /api/v1/bridge/api-transactions?page={page}&limit={limit}
|
|
329
|
+
*/
|
|
330
|
+
async getApiTransactions(page = 1, limit = 20) {
|
|
331
|
+
const path = `api/v1/bridge/api-transactions?page=${encodeURIComponent(String(page))}&limit=${encodeURIComponent(String(limit))}`;
|
|
332
|
+
return this.post(path, undefined);
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* Manually validate a bridge burn transaction (EVM burn completion)
|
|
336
|
+
*/
|
|
337
|
+
async validateBurn(params) {
|
|
338
|
+
return this.post('api/v1/bridge/validate-burn', params);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Manually confirm a CCIP transaction
|
|
342
|
+
*/
|
|
343
|
+
async confirmCcipTransaction(params) {
|
|
344
|
+
const path = `api/v1/bridge/transactions/${encodeURIComponent(params.transactionId)}/tx`;
|
|
345
|
+
const body = {
|
|
346
|
+
txnHash: params.txnHash,
|
|
347
|
+
operationType: params.operationType,
|
|
348
|
+
txnStatus: params.txnStatus,
|
|
349
|
+
};
|
|
350
|
+
return this.patch(path, body);
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Get list of supported chains
|
|
354
|
+
* @param options - Optional query parameters
|
|
355
|
+
* @param options.isActive - Filter by active status
|
|
356
|
+
* @param options.isCcipSupported - Filter by CCIP support
|
|
357
|
+
* @param options.chainId - Filter by specific chain ID
|
|
358
|
+
*/
|
|
359
|
+
async getSupportedChains(options) {
|
|
360
|
+
const params = {};
|
|
361
|
+
if (options?.isActive !== undefined) {
|
|
362
|
+
params.is_active = String(options.isActive);
|
|
363
|
+
}
|
|
364
|
+
if (options?.isCcipSupported !== undefined) {
|
|
365
|
+
params.is_ccip_supported = String(options.isCcipSupported);
|
|
366
|
+
}
|
|
367
|
+
if (options?.chainId !== undefined) {
|
|
368
|
+
params.chain_id = options.chainId;
|
|
369
|
+
}
|
|
370
|
+
const response = await this.get('api/v1/chain/chains', params);
|
|
371
|
+
if (!response.success || !response.data) {
|
|
372
|
+
throw new Error(response.message || 'Failed to fetch chains');
|
|
373
|
+
}
|
|
374
|
+
return response.data.chains;
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Get list of supported assets
|
|
378
|
+
*/
|
|
379
|
+
async getAssetList(chainId) {
|
|
380
|
+
const response = await this.get('api/v1/asset/assets');
|
|
381
|
+
if (!response.success || !response.data) {
|
|
382
|
+
throw new Error(response.message || 'Failed to fetch assets');
|
|
383
|
+
}
|
|
384
|
+
let assets = response.data.assets;
|
|
385
|
+
// Filter by chainId if provided
|
|
386
|
+
if (chainId !== undefined) {
|
|
387
|
+
assets = assets.filter(asset => asset.chainId === chainId);
|
|
388
|
+
}
|
|
389
|
+
return assets;
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Get bridge fee estimate
|
|
393
|
+
* @param params - Fee estimation parameters
|
|
394
|
+
*/
|
|
395
|
+
async getBridgeFeeEstimate(params) {
|
|
396
|
+
const queryParams = {
|
|
397
|
+
fromToken: params.fromToken,
|
|
398
|
+
toToken: params.toToken,
|
|
399
|
+
amount: String(params.amount),
|
|
400
|
+
};
|
|
401
|
+
return this.get('api/v1/bridge/call-fee', queryParams);
|
|
402
|
+
}
|
|
403
|
+
/**
|
|
404
|
+
* Get router swap fee estimate
|
|
405
|
+
* @param params - Fee estimation parameters
|
|
406
|
+
*/
|
|
407
|
+
async getRouterSwapFeeEstimate(params) {
|
|
408
|
+
const queryParams = {
|
|
409
|
+
originAssetId: String(params.originAssetId),
|
|
410
|
+
destinationAssetId: String(params.destinationAssetId),
|
|
411
|
+
amount: String(params.amount),
|
|
412
|
+
operationType: params.operationType,
|
|
413
|
+
toAddress: params.toAddress,
|
|
414
|
+
};
|
|
415
|
+
return this.get('api/v1/router-swap/call-fee', queryParams);
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Normalize and rethrow errors with backend message (if available) so
|
|
419
|
+
* integrators can surface meaningful reasons to their users.
|
|
420
|
+
*/
|
|
421
|
+
handleError(error) {
|
|
422
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
423
|
+
const status = error.response?.status;
|
|
424
|
+
const data = error.response?.data;
|
|
425
|
+
// Try to extract a human friendly message from common backend shapes
|
|
426
|
+
let backendMessage = data?.error?.message ||
|
|
427
|
+
data?.message ||
|
|
428
|
+
(typeof data?.error === 'string' ? data.error : undefined) ||
|
|
429
|
+
(data?.success === false && data?.message ? data.message : undefined);
|
|
430
|
+
// For auth failures, avoid leaking raw backend JSON and give a clearer hint.
|
|
431
|
+
if (status === 401 &&
|
|
432
|
+
(backendMessage === 'Unauthorized' ||
|
|
433
|
+
data?.statusCode === 401 ||
|
|
434
|
+
data?.message === 'Unauthorized')) {
|
|
435
|
+
backendMessage =
|
|
436
|
+
'Session expired or unauthorized. Please verify your API key/secret and try again.';
|
|
437
|
+
}
|
|
438
|
+
const message = backendMessage ||
|
|
439
|
+
error.message ||
|
|
440
|
+
(status ? `Request failed with status ${status}` : 'Request failed');
|
|
441
|
+
throw new Error(message);
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
const message = error?.message || 'Unexpected error';
|
|
445
|
+
throw new Error(message);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
exports.VoidAIBridgeClient = VoidAIBridgeClient;
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BridgeSDKOptions, BridgeSDKServerOptions, Environment } from './types';
|
|
2
|
+
/** Internal: options accepted by BridgeConfig (frontend or server) */
|
|
3
|
+
type BridgeConfigOptions = BridgeSDKOptions | BridgeSDKServerOptions;
|
|
4
|
+
export declare class BridgeConfig {
|
|
5
|
+
readonly apiKey: string;
|
|
6
|
+
readonly secretKey?: string;
|
|
7
|
+
readonly environment: Environment;
|
|
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;
|
|
15
|
+
private static readonly DEFAULTS;
|
|
16
|
+
constructor(options: BridgeConfigOptions);
|
|
17
|
+
getBaseUrl(): string;
|
|
18
|
+
}
|
|
19
|
+
export {};
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BridgeConfig = void 0;
|
|
4
|
+
class BridgeConfig {
|
|
5
|
+
constructor(options) {
|
|
6
|
+
if (!options.apiKey) {
|
|
7
|
+
throw new Error('BridgeSDK: apiKey is required');
|
|
8
|
+
}
|
|
9
|
+
this.apiKey = options.apiKey;
|
|
10
|
+
this.secretKey = 'secretKey' in options ? options.secretKey : undefined;
|
|
11
|
+
this.environment = options.environment || 'mainnet';
|
|
12
|
+
// Ensure environment is valid, default to mainnet if invalid
|
|
13
|
+
const validEnvironments = ['devnet', 'testnet', 'mainnet'];
|
|
14
|
+
if (!validEnvironments.includes(this.environment)) {
|
|
15
|
+
this.environment = 'mainnet';
|
|
16
|
+
}
|
|
17
|
+
const defaults = BridgeConfig.DEFAULTS[this.environment];
|
|
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;
|
|
22
|
+
}
|
|
23
|
+
getBaseUrl() {
|
|
24
|
+
return this.baseUrl;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
exports.BridgeConfig = BridgeConfig;
|
|
28
|
+
BridgeConfig.DEFAULTS = {
|
|
29
|
+
devnet: {
|
|
30
|
+
baseUrl: 'https://api-sdk-dev.voidai.envistudios.com/',
|
|
31
|
+
bridgeContractAddress: '0x6266ce15aC4f32F096Ff91881dd887a0F4bBa569',
|
|
32
|
+
},
|
|
33
|
+
testnet: {
|
|
34
|
+
baseUrl: 'https://api-sdk-stage.voidai.envistudios.com/',
|
|
35
|
+
bridgeContractAddress: '0x4aA4396BfD6F268b427077079800F420dF947b63',
|
|
36
|
+
},
|
|
37
|
+
mainnet: {
|
|
38
|
+
baseUrl: 'https://api-sdk.voidai.envistudios.com/',
|
|
39
|
+
bridgeContractAddress: '0x604e8Ef901C0E69E79463D997ba7D0724A909b84',
|
|
40
|
+
},
|
|
41
|
+
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { VoidAIBridgeClient } from '../api/client';
|
|
2
|
+
import { BridgeSwapRequest, BridgeSwapResponse, RouteSwapRequest, RouteBridgeRequest, RouteCcipRequest, RouteTransactionResponse, BridgeFeeEstimateRequest, BridgeFeeEstimateResponse, RouterSwapFeeEstimateRequest, RouterSwapFeeEstimateResponse, CancelCcipRequest, CancelRouterSwapRequest, CancelBridgeSwapRequest, CancelOperationResponse, ApiTransactionsResponse, ValidateBurnRequest, ValidateBurnResponse, CcipTxConfirmationRequest, CcipTxConfirmationResponse } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Bridge API Methods
|
|
5
|
+
* Provides read-only API methods for bridge operations
|
|
6
|
+
*/
|
|
7
|
+
export declare class Bridge {
|
|
8
|
+
private apiClient;
|
|
9
|
+
constructor(apiClient: VoidAIBridgeClient);
|
|
10
|
+
/**
|
|
11
|
+
* Get transaction status
|
|
12
|
+
*/
|
|
13
|
+
getTransactionStatus(txId: string): Promise<string>;
|
|
14
|
+
/**
|
|
15
|
+
* Get transaction history for an address
|
|
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>;
|
|
46
|
+
/**
|
|
47
|
+
* Cancel a CCIP route transaction
|
|
48
|
+
*/
|
|
49
|
+
cancelCcipRoute(params: CancelCcipRequest): Promise<CancelOperationResponse>;
|
|
50
|
+
/**
|
|
51
|
+
* Cancel a router swap transaction
|
|
52
|
+
*/
|
|
53
|
+
cancelRouterSwap(params: CancelRouterSwapRequest): Promise<CancelOperationResponse>;
|
|
54
|
+
/**
|
|
55
|
+
* Cancel a bridge swap transaction
|
|
56
|
+
*/
|
|
57
|
+
cancelBridgeSwap(params: CancelBridgeSwapRequest): Promise<CancelOperationResponse>;
|
|
58
|
+
/**
|
|
59
|
+
* Get recent API transactions for the current tenant
|
|
60
|
+
*/
|
|
61
|
+
getRecentTransactions(page?: number, limit?: number): Promise<ApiTransactionsResponse>;
|
|
62
|
+
/**
|
|
63
|
+
* Manually validate a bridge burn transaction
|
|
64
|
+
*/
|
|
65
|
+
validateBurnTransaction(params: ValidateBurnRequest): Promise<ValidateBurnResponse>;
|
|
66
|
+
/**
|
|
67
|
+
* Manually confirm a CCIP transaction
|
|
68
|
+
*/
|
|
69
|
+
confirmCcipTransaction(params: CcipTxConfirmationRequest): Promise<CcipTxConfirmationResponse>;
|
|
70
|
+
}
|