voidai-sdk 0.1.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 ADDED
@@ -0,0 +1,119 @@
1
+ # VoidAI Bridge SDK
2
+
3
+ TypeScript SDK for VoidAI Bridge - A bridge application that bridges TAO tokens between Bittensor and Ethereum blockchains.
4
+
5
+ ## 📦 Installation
6
+
7
+ ```bash
8
+ npm install voidai-sdk
9
+ ```
10
+
11
+ ## 🚀 Quick Start
12
+
13
+ ```typescript
14
+ import { BridgeSDK } from 'voidai-sdk';
15
+
16
+ // Initialize the SDK
17
+ const sdk = new BridgeSDK({
18
+ apiKey: 'your-api-key',
19
+ environment: 'development' // or 'production', 'staging'
20
+ });
21
+
22
+ await sdk.init();
23
+
24
+ // Connect wallets
25
+ await sdk.wallets.bittensor.connect();
26
+ await sdk.wallets.ethereum.connect();
27
+ await sdk.wallets.solana.connect();
28
+
29
+ // Use API methods
30
+ const chains = await sdk.api.getSupportedChains();
31
+ const assets = await sdk.api.getAssetList();
32
+ ```
33
+
34
+ ## 📁 Project Structure
35
+
36
+ ```
37
+ bridge-sdk/
38
+ ├── src/ # SDK source code
39
+ │ ├── api/ # API client
40
+ │ ├── config.ts # Configuration
41
+ │ ├── core/ # Core bridge logic
42
+ │ ├── types/ # TypeScript types
43
+ │ ├── utils/ # Utilities
44
+ │ ├── wallet/ # Wallet integrations
45
+ │ └── index.ts # Main entry point
46
+ ├── dist/ # Compiled SDK (Node.js)
47
+ ├── dist-browser/ # Browser bundle
48
+ ├── test/ # Test suite
49
+ ├── examples/ # Example applications
50
+ │ └── frontend/ # Frontend demo
51
+ └── package.json
52
+ ```
53
+
54
+ ## 🔧 Development
55
+
56
+ ### Build
57
+
58
+ ```bash
59
+ # Build for Node.js
60
+ npm run build
61
+
62
+ # Build for browser
63
+ npm run build:browser
64
+
65
+ # Build both
66
+ npm run build:all
67
+ ```
68
+
69
+ ### Test
70
+
71
+ ```bash
72
+ npm test
73
+ ```
74
+
75
+ See [TEST_COVERAGE.md](./TEST_COVERAGE.md) for detailed test coverage information.
76
+
77
+ ## 📚 Documentation
78
+
79
+ - [Test Coverage](./TEST_COVERAGE.md) - Comprehensive test coverage documentation
80
+ - [Examples](./examples/README.md) - Example applications and demos
81
+
82
+ ## 🌐 Browser Usage
83
+
84
+ For browser usage, include the bundled SDK:
85
+
86
+ ```html
87
+ <script src="node_modules/voidai-sdk/dist-browser/voidai-sdk.js"></script>
88
+ <script>
89
+ const sdk = new VoidAISDK.BridgeSDK({
90
+ apiKey: 'your-api-key',
91
+ environment: 'development'
92
+ });
93
+ </script>
94
+ ```
95
+
96
+ ## 🔑 Features
97
+
98
+ - **Multi-Wallet Support**
99
+ - Bittensor (Talisman, Polkadot.js, Subwallet)
100
+ - Ethereum (MetaMask)
101
+ - Solana (Phantom)
102
+
103
+ - **API Methods**
104
+ - Get supported chains
105
+ - Get asset list
106
+ - Chain filtering (by chainId, isActive, isCcipSupported)
107
+
108
+ - **TypeScript Support**
109
+ - Full type definitions included
110
+ - IntelliSense support
111
+
112
+ ## 📝 License
113
+
114
+ MIT
115
+
116
+ ## 🤝 Contributing
117
+
118
+ Contributions are welcome! Please ensure all tests pass before submitting a pull request.
119
+
@@ -0,0 +1,27 @@
1
+ import { BridgeConfig } from '../config';
2
+ import { Chain, Asset } from '../types';
3
+ export declare class VoidAIBridgeClient {
4
+ private config;
5
+ private client;
6
+ constructor(config: BridgeConfig);
7
+ private getUrl;
8
+ get<T>(path: string, params?: any): Promise<T>;
9
+ post<T>(path: string, data?: any): Promise<T>;
10
+ /**
11
+ * Get list of supported chains
12
+ * @param options - Optional query parameters
13
+ * @param options.isActive - Filter by active status
14
+ * @param options.isCcipSupported - Filter by CCIP support
15
+ * @param options.chainId - Filter by specific chain ID
16
+ */
17
+ getSupportedChains(options?: {
18
+ isActive?: boolean;
19
+ isCcipSupported?: boolean;
20
+ chainId?: string;
21
+ }): Promise<Chain[]>;
22
+ /**
23
+ * Get list of supported assets
24
+ */
25
+ getAssetList(chainId?: string): Promise<Asset[]>;
26
+ private handleError;
27
+ }
@@ -0,0 +1,89 @@
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.config = config;
11
+ this.client = axios_1.default.create({
12
+ timeout: 10000,
13
+ headers: {
14
+ 'Content-Type': 'application/json',
15
+ 'x-api-key': this.config.apiKey,
16
+ },
17
+ });
18
+ }
19
+ getUrl(path) {
20
+ const baseUrl = this.config.getBaseUrl();
21
+ // Remove trailing slash from base and leading slash from path to avoid doubles
22
+ const cleanBase = baseUrl.replace(/\/$/, '');
23
+ const cleanPath = path.replace(/^\//, '');
24
+ return `${cleanBase}/${cleanPath}`;
25
+ }
26
+ async get(path, params) {
27
+ const url = this.getUrl(path);
28
+ try {
29
+ const response = await this.client.get(url, { params });
30
+ return response.data;
31
+ }
32
+ catch (error) {
33
+ this.handleError(error);
34
+ throw error;
35
+ }
36
+ }
37
+ async post(path, data) {
38
+ const url = this.getUrl(path);
39
+ try {
40
+ const response = await this.client.post(url, data);
41
+ return response.data;
42
+ }
43
+ catch (error) {
44
+ this.handleError(error);
45
+ throw error;
46
+ }
47
+ }
48
+ /**
49
+ * Get list of supported chains
50
+ * @param options - Optional query parameters
51
+ * @param options.isActive - Filter by active status
52
+ * @param options.isCcipSupported - Filter by CCIP support
53
+ * @param options.chainId - Filter by specific chain ID
54
+ */
55
+ async getSupportedChains(options) {
56
+ const params = {};
57
+ if (options?.isActive !== undefined) {
58
+ params.is_active = String(options.isActive);
59
+ }
60
+ if (options?.isCcipSupported !== undefined) {
61
+ params.is_ccip_supported = String(options.isCcipSupported);
62
+ }
63
+ if (options?.chainId !== undefined) {
64
+ params.chain_id = options.chainId;
65
+ }
66
+ const response = await this.get('api/chains', params);
67
+ return response.chains;
68
+ }
69
+ /**
70
+ * Get list of supported assets
71
+ */
72
+ async getAssetList(chainId) {
73
+ const response = await this.get('api/asset');
74
+ // Filter by chainId if provided
75
+ if (chainId !== undefined) {
76
+ return response.assets.filter(asset => asset.chainId === chainId);
77
+ }
78
+ return response.assets;
79
+ }
80
+ handleError(error) {
81
+ if (axios_1.default.isAxiosError(error)) {
82
+ console.error('Bridge API Error:', error.response?.data || error.message);
83
+ }
84
+ else {
85
+ console.error('Unexpected Error:', error);
86
+ }
87
+ }
88
+ }
89
+ exports.VoidAIBridgeClient = VoidAIBridgeClient;
@@ -0,0 +1,50 @@
1
+ import { VoidAIBridgeClient } from '../api/client';
2
+ import { SignInResponse, RefreshTokenResponse } from '../types';
3
+ export declare class AuthSession {
4
+ private apiClient;
5
+ private accessToken;
6
+ private refreshToken;
7
+ private accessTokenWs;
8
+ private adminStatus;
9
+ constructor(apiClient: VoidAIBridgeClient);
10
+ /**
11
+ * Get nonce (signature) for wallet authentication
12
+ * @param wallet - Public key wallet address
13
+ */
14
+ getNonce(wallet: string): Promise<string>;
15
+ /**
16
+ * Sign in with wallet
17
+ * @param publicKey - Wallet public key
18
+ * @param signature - Signed nonce
19
+ * @param chainId - Blockchain chain ID
20
+ */
21
+ signIn(publicKey: string, signature: string, chainId: string): Promise<SignInResponse>;
22
+ /**
23
+ * Refresh access token using refresh token
24
+ */
25
+ refreshAccessToken(): Promise<RefreshTokenResponse>;
26
+ /**
27
+ * Get current access token
28
+ */
29
+ getAccessToken(): string | null;
30
+ /**
31
+ * Get current refresh token
32
+ */
33
+ getRefreshToken(): string | null;
34
+ /**
35
+ * Get WebSocket access token
36
+ */
37
+ getAccessTokenWs(): string | null;
38
+ /**
39
+ * Check if user is admin
40
+ */
41
+ isAdmin(): boolean;
42
+ /**
43
+ * Check if user is authenticated
44
+ */
45
+ isAuthenticated(): boolean;
46
+ /**
47
+ * Logout and clear session
48
+ */
49
+ logout(): Promise<void>;
50
+ }
@@ -0,0 +1,110 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AuthSession = void 0;
4
+ class AuthSession {
5
+ constructor(apiClient) {
6
+ this.accessToken = null;
7
+ this.refreshToken = null;
8
+ this.accessTokenWs = null;
9
+ this.adminStatus = false;
10
+ this.apiClient = apiClient;
11
+ }
12
+ /**
13
+ * Get nonce (signature) for wallet authentication
14
+ * @param wallet - Public key wallet address
15
+ */
16
+ async getNonce(wallet) {
17
+ const response = await this.apiClient.post('/api/wallet/get-nonce', {
18
+ wallet,
19
+ });
20
+ return response.nonce;
21
+ }
22
+ /**
23
+ * Sign in with wallet
24
+ * @param publicKey - Wallet public key
25
+ * @param signature - Signed nonce
26
+ * @param chainId - Blockchain chain ID
27
+ */
28
+ async signIn(publicKey, signature, chainId) {
29
+ const requestBody = {
30
+ publicKey,
31
+ signature,
32
+ chainId,
33
+ };
34
+ const response = await this.apiClient.post('/api/wallet/signin/wallet', requestBody);
35
+ // Store session data
36
+ this.accessToken = response.accessToken;
37
+ this.refreshToken = response.refreshToken;
38
+ this.accessTokenWs = response.accessTokenWs;
39
+ this.adminStatus = response.isAdmin;
40
+ // Update client with access token for future requests
41
+ this.apiClient.setAccessToken(response.accessToken);
42
+ return response;
43
+ }
44
+ /**
45
+ * Refresh access token using refresh token
46
+ */
47
+ async refreshAccessToken() {
48
+ if (!this.refreshToken) {
49
+ throw new Error('VoidAI SDK: No refresh token available');
50
+ }
51
+ // Temporarily set refresh token as authorization
52
+ const previousToken = this.apiClient.getAccessToken();
53
+ this.apiClient.setAccessToken(this.refreshToken);
54
+ try {
55
+ const response = await this.apiClient.post('/api/wallet/refresh-token');
56
+ // Update stored tokens
57
+ this.accessToken = response.accessToken;
58
+ this.refreshToken = response.refreshToken;
59
+ // Update client with new access token
60
+ this.apiClient.setAccessToken(response.accessToken);
61
+ return response;
62
+ }
63
+ catch (error) {
64
+ // Restore previous token on error
65
+ this.apiClient.setAccessToken(previousToken);
66
+ throw error;
67
+ }
68
+ }
69
+ /**
70
+ * Get current access token
71
+ */
72
+ getAccessToken() {
73
+ return this.accessToken;
74
+ }
75
+ /**
76
+ * Get current refresh token
77
+ */
78
+ getRefreshToken() {
79
+ return this.refreshToken;
80
+ }
81
+ /**
82
+ * Get WebSocket access token
83
+ */
84
+ getAccessTokenWs() {
85
+ return this.accessTokenWs;
86
+ }
87
+ /**
88
+ * Check if user is admin
89
+ */
90
+ isAdmin() {
91
+ return this.adminStatus;
92
+ }
93
+ /**
94
+ * Check if user is authenticated
95
+ */
96
+ isAuthenticated() {
97
+ return !!this.accessToken;
98
+ }
99
+ /**
100
+ * Logout and clear session
101
+ */
102
+ async logout() {
103
+ this.accessToken = null;
104
+ this.refreshToken = null;
105
+ this.accessTokenWs = null;
106
+ this.adminStatus = false;
107
+ this.apiClient.setAccessToken(null);
108
+ }
109
+ }
110
+ exports.AuthSession = AuthSession;
@@ -0,0 +1,9 @@
1
+ import { BridgeSDKOptions, Environment } from './types';
2
+ export declare class BridgeConfig {
3
+ readonly apiKey: string;
4
+ readonly environment: Environment;
5
+ readonly baseUrl: string;
6
+ private static readonly DEFAULTS;
7
+ constructor(options: BridgeSDKOptions);
8
+ getBaseUrl(): string;
9
+ }
package/dist/config.js ADDED
@@ -0,0 +1,35 @@
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.environment = options.environment || 'production';
11
+ // Ensure environment is valid, default to production if invalid
12
+ const validEnvironments = ['development', 'staging', 'production'];
13
+ if (!validEnvironments.includes(this.environment)) {
14
+ this.environment = 'production';
15
+ }
16
+ const defaults = BridgeConfig.DEFAULTS[this.environment];
17
+ // Allow custom base URL override
18
+ this.baseUrl = options.baseUrl || defaults.baseUrl;
19
+ }
20
+ getBaseUrl() {
21
+ return this.baseUrl;
22
+ }
23
+ }
24
+ exports.BridgeConfig = BridgeConfig;
25
+ BridgeConfig.DEFAULTS = {
26
+ development: {
27
+ baseUrl: 'https://api-dev.voidai.envistudios.com',
28
+ },
29
+ staging: {
30
+ baseUrl: 'https://api-staging.voidai.envistudios.com',
31
+ },
32
+ production: {
33
+ baseUrl: 'https://api.voidai.envistudios.com',
34
+ },
35
+ };
@@ -0,0 +1,17 @@
1
+ import { VoidAIBridgeClient } from '../api/client';
2
+ /**
3
+ * Bridge API Methods
4
+ * Provides read-only API methods for bridge operations
5
+ */
6
+ export declare class Bridge {
7
+ private apiClient;
8
+ constructor(apiClient: VoidAIBridgeClient);
9
+ /**
10
+ * Get transaction status
11
+ */
12
+ getTransactionStatus(txId: string): Promise<string>;
13
+ /**
14
+ * Get transaction history for an address
15
+ */
16
+ getHistory(address: string): Promise<any[]>;
17
+ }
@@ -0,0 +1,26 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Bridge = void 0;
4
+ /**
5
+ * Bridge API Methods
6
+ * Provides read-only API methods for bridge operations
7
+ */
8
+ class Bridge {
9
+ constructor(apiClient) {
10
+ this.apiClient = apiClient;
11
+ }
12
+ /**
13
+ * Get transaction status
14
+ */
15
+ async getTransactionStatus(txId) {
16
+ const { status } = await this.apiClient.get(`/transactions/${txId}/status`);
17
+ return status;
18
+ }
19
+ /**
20
+ * Get transaction history for an address
21
+ */
22
+ async getHistory(address) {
23
+ return this.apiClient.get(`/transactions/history/${address}`);
24
+ }
25
+ }
26
+ exports.Bridge = Bridge;
@@ -0,0 +1,27 @@
1
+ import { BridgeConfig } from './config';
2
+ import { VoidAIBridgeClient } from './api/client';
3
+ import { BittensorWallet } from './wallet/bittensor';
4
+ import { EthereumWallet } from './wallet/ethereum';
5
+ import { SolanaWallet } from './wallet/solana';
6
+ import { Bridge } from './core/bridge';
7
+ import { BridgeSDKOptions } from './types';
8
+ export * from './types';
9
+ export * from './config';
10
+ export * from './wallet/bittensor';
11
+ export * from './wallet/ethereum';
12
+ export * from './wallet/solana';
13
+ export declare class BridgeSDK {
14
+ readonly config: BridgeConfig;
15
+ readonly api: VoidAIBridgeClient;
16
+ readonly wallets: {
17
+ bittensor: BittensorWallet;
18
+ ethereum: EthereumWallet;
19
+ solana: SolanaWallet;
20
+ };
21
+ readonly bridge: Bridge;
22
+ constructor(options: BridgeSDKOptions);
23
+ /**
24
+ * Initialize the SDK
25
+ */
26
+ init(): Promise<void>;
27
+ }
package/dist/index.js ADDED
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.BridgeSDK = void 0;
18
+ const config_1 = require("./config");
19
+ const client_1 = require("./api/client");
20
+ const bittensor_1 = require("./wallet/bittensor");
21
+ const ethereum_1 = require("./wallet/ethereum");
22
+ const solana_1 = require("./wallet/solana");
23
+ const bridge_1 = require("./core/bridge");
24
+ __exportStar(require("./types"), exports);
25
+ __exportStar(require("./config"), exports);
26
+ __exportStar(require("./wallet/bittensor"), exports);
27
+ __exportStar(require("./wallet/ethereum"), exports);
28
+ __exportStar(require("./wallet/solana"), exports);
29
+ class BridgeSDK {
30
+ constructor(options) {
31
+ this.config = new config_1.BridgeConfig(options);
32
+ this.api = new client_1.VoidAIBridgeClient(this.config);
33
+ this.wallets = {
34
+ bittensor: new bittensor_1.BittensorWallet(),
35
+ ethereum: new ethereum_1.EthereumWallet(),
36
+ solana: new solana_1.SolanaWallet()
37
+ };
38
+ this.bridge = new bridge_1.Bridge(this.api);
39
+ }
40
+ /**
41
+ * Initialize the SDK
42
+ */
43
+ async init() {
44
+ console.log('BridgeSDK initialized');
45
+ }
46
+ }
47
+ exports.BridgeSDK = BridgeSDK;
@@ -0,0 +1,54 @@
1
+ export type Environment = 'development' | 'production' | 'staging';
2
+ export interface BridgeSDKOptions {
3
+ apiKey: string;
4
+ environment?: Environment;
5
+ baseUrl?: string;
6
+ }
7
+ export interface Chain {
8
+ id: number;
9
+ name: string;
10
+ chainId: string;
11
+ network: string;
12
+ isActive: boolean;
13
+ logoUri: string;
14
+ isCcipSupported: boolean;
15
+ ccipBridgeConfigurationStatus: string;
16
+ ccipChainSelector: string | null;
17
+ ccipRouterAddress: string | null;
18
+ ccipAdminRegistryContract: string | null;
19
+ ccipSupportedInBounds: string[];
20
+ ccipSupportedOutBounds: string[];
21
+ voidAiRouterAddress: string | null;
22
+ ccipRmnProxy?: string | null;
23
+ ccipRegistryModuleOwnerCustom?: string | null;
24
+ createdAt: string;
25
+ updatedAt: string;
26
+ }
27
+ export interface AssetBalance {
28
+ tokenAddress: string;
29
+ balance: string;
30
+ decimals: number;
31
+ formatted: string;
32
+ }
33
+ export interface Asset {
34
+ id: number;
35
+ chainId: string;
36
+ tokenName: string;
37
+ symbol: string;
38
+ decimal: number;
39
+ type: string;
40
+ tokenPoolAddress: string;
41
+ tokenPoolType: string;
42
+ tokenAddress: string;
43
+ isActive: boolean;
44
+ metadata: Record<string, any>;
45
+ subnetId: number;
46
+ createdAt: string;
47
+ updatedAt: string;
48
+ }
49
+ export interface ChainsApiResponse {
50
+ chains: Chain[];
51
+ }
52
+ export interface AssetsApiResponse {
53
+ assets: Asset[];
54
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export declare const isValidAddress: (address: string) => boolean;
2
+ export declare const isValidHash: (hash: string) => boolean;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidHash = exports.isValidAddress = void 0;
4
+ const isValidAddress = (address) => {
5
+ // Basic hex validation for generic blockchain address
6
+ return /^0x[a-fA-F0-9]{40,}$/.test(address);
7
+ };
8
+ exports.isValidAddress = isValidAddress;
9
+ const isValidHash = (hash) => {
10
+ return /^0x[a-fA-F0-9]{64}$/.test(hash);
11
+ };
12
+ exports.isValidHash = isValidHash;
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Bittensor Wallet Connection
3
+ * Handles connection to Bittensor-compatible wallets (Talisman, Subwallet, Polkadot.js)
4
+ */
5
+ export interface BittensorAccount {
6
+ address: string;
7
+ name?: string;
8
+ source: string;
9
+ }
10
+ export interface BittensorWalletExtension {
11
+ accounts: {
12
+ get: () => Promise<BittensorAccount[]>;
13
+ };
14
+ signer?: {
15
+ signRaw?: (options: {
16
+ address: string;
17
+ data: string;
18
+ }) => Promise<{
19
+ signature: string;
20
+ }>;
21
+ };
22
+ }
23
+ export declare class BittensorWallet {
24
+ private extension;
25
+ private account;
26
+ private extensionName;
27
+ /**
28
+ * Connect to a Bittensor-compatible wallet
29
+ * @param extensionName - Optional: specific extension name ('talisman', 'subwallet-js', 'polkadot-js')
30
+ * @returns Connected account information
31
+ */
32
+ connect(extensionName?: string): Promise<BittensorAccount>;
33
+ /**
34
+ * Get currently connected account
35
+ */
36
+ getAccount(): BittensorAccount | null;
37
+ /**
38
+ * Get extension name
39
+ */
40
+ getExtensionName(): string | null;
41
+ /**
42
+ * Check if wallet is connected
43
+ */
44
+ isConnected(): boolean;
45
+ /**
46
+ * Disconnect wallet
47
+ * Note: This only disconnects from the SDK. To fully disconnect from the extension,
48
+ * users need to disconnect accounts in their wallet extension settings.
49
+ */
50
+ disconnect(): void;
51
+ /**
52
+ * Check if wallet extension is available
53
+ */
54
+ static isExtensionAvailable(extensionName?: string): boolean;
55
+ /**
56
+ * Get the wallet extension instance (for advanced usage)
57
+ */
58
+ getExtension(): BittensorWalletExtension | null;
59
+ }
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ /**
3
+ * Bittensor Wallet Connection
4
+ * Handles connection to Bittensor-compatible wallets (Talisman, Subwallet, Polkadot.js)
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.BittensorWallet = void 0;
8
+ class BittensorWallet {
9
+ constructor() {
10
+ this.extension = null;
11
+ this.account = null;
12
+ this.extensionName = null;
13
+ }
14
+ /**
15
+ * Connect to a Bittensor-compatible wallet
16
+ * @param extensionName - Optional: specific extension name ('talisman', 'subwallet-js', 'polkadot-js')
17
+ * @returns Connected account information
18
+ */
19
+ async connect(extensionName) {
20
+ // Check if running in browser environment
21
+ if (typeof window === 'undefined') {
22
+ throw new Error('BittensorWallet: Browser environment required for wallet connection');
23
+ }
24
+ // Check if any compatible extension is available
25
+ if (typeof window.injectedWeb3 === 'undefined') {
26
+ throw new Error('No compatible wallet extension found. Please install Talisman, Subwallet, or Polkadot.js extension.');
27
+ }
28
+ const injectedWeb3 = window.injectedWeb3;
29
+ const supportedExtensions = ['talisman', 'subwallet-js', 'polkadot-js'];
30
+ let targetExtension = null;
31
+ let selectedExtensionName = '';
32
+ // If specific extension requested, use it
33
+ if (extensionName && injectedWeb3[extensionName]) {
34
+ targetExtension = injectedWeb3[extensionName];
35
+ selectedExtensionName = extensionName;
36
+ }
37
+ else {
38
+ // Find the first available supported extension
39
+ for (const name of supportedExtensions) {
40
+ if (injectedWeb3[name]) {
41
+ targetExtension = injectedWeb3[name];
42
+ selectedExtensionName = name;
43
+ break;
44
+ }
45
+ }
46
+ // Fallback: try to pick the first one available
47
+ if (!targetExtension) {
48
+ const available = Object.keys(injectedWeb3);
49
+ if (available.length > 0) {
50
+ selectedExtensionName = available[0];
51
+ targetExtension = injectedWeb3[selectedExtensionName];
52
+ }
53
+ else {
54
+ throw new Error('No compatible wallet extension found.');
55
+ }
56
+ }
57
+ }
58
+ // Request access to extension - this will trigger a popup for account authorization
59
+ let extension;
60
+ try {
61
+ extension = await targetExtension.enable('VoidAI Bridge SDK');
62
+ }
63
+ catch (error) {
64
+ // Handle case where user rejects authorization or no accounts are authorized
65
+ if (error.message && error.message.includes('authorised')) {
66
+ throw new Error('No accounts are authorized. Please authorize accounts in your wallet extension and try again.');
67
+ }
68
+ throw new Error(`Failed to enable wallet extension: ${error.message || error}`);
69
+ }
70
+ if (!extension) {
71
+ throw new Error('Failed to enable wallet extension. Please try again.');
72
+ }
73
+ // Get all authorized accounts
74
+ let allAccounts;
75
+ try {
76
+ allAccounts = await extension.accounts.get();
77
+ }
78
+ catch (error) {
79
+ throw new Error(`Failed to get accounts: ${error.message || error}`);
80
+ }
81
+ if (allAccounts.length === 0) {
82
+ throw new Error('No accounts found. Please authorize at least one account in your wallet extension and try again.');
83
+ }
84
+ // Store extension and use first account
85
+ this.extension = extension;
86
+ const account = allAccounts[0];
87
+ this.account = account;
88
+ this.extensionName = selectedExtensionName;
89
+ return account;
90
+ }
91
+ /**
92
+ * Get currently connected account
93
+ */
94
+ getAccount() {
95
+ return this.account;
96
+ }
97
+ /**
98
+ * Get extension name
99
+ */
100
+ getExtensionName() {
101
+ return this.extensionName;
102
+ }
103
+ /**
104
+ * Check if wallet is connected
105
+ */
106
+ isConnected() {
107
+ return this.account !== null && this.extension !== null;
108
+ }
109
+ /**
110
+ * Disconnect wallet
111
+ * Note: This only disconnects from the SDK. To fully disconnect from the extension,
112
+ * users need to disconnect accounts in their wallet extension settings.
113
+ */
114
+ disconnect() {
115
+ this.extension = null;
116
+ this.account = null;
117
+ this.extensionName = null;
118
+ }
119
+ /**
120
+ * Check if wallet extension is available
121
+ */
122
+ static isExtensionAvailable(extensionName) {
123
+ if (typeof window === 'undefined') {
124
+ return false;
125
+ }
126
+ const injectedWeb3 = window.injectedWeb3;
127
+ if (!injectedWeb3) {
128
+ return false;
129
+ }
130
+ if (extensionName) {
131
+ return !!injectedWeb3[extensionName];
132
+ }
133
+ const supportedExtensions = ['talisman', 'subwallet-js', 'polkadot-js'];
134
+ return supportedExtensions.some(name => !!injectedWeb3[name]) || Object.keys(injectedWeb3).length > 0;
135
+ }
136
+ /**
137
+ * Get the wallet extension instance (for advanced usage)
138
+ */
139
+ getExtension() {
140
+ return this.extension;
141
+ }
142
+ }
143
+ exports.BittensorWallet = BittensorWallet;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Ethereum Wallet Connection (MetaMask)
3
+ */
4
+ export interface EthereumAccount {
5
+ address: string;
6
+ chainId?: string;
7
+ }
8
+ export declare class EthereumWallet {
9
+ private account;
10
+ private chainId;
11
+ /**
12
+ * Check if MetaMask is installed
13
+ */
14
+ static isMetaMaskInstalled(): boolean;
15
+ /**
16
+ * Connect to MetaMask wallet
17
+ * @returns Connected account information
18
+ */
19
+ connect(): Promise<EthereumAccount>;
20
+ /**
21
+ * Get currently connected account
22
+ */
23
+ getAccount(): EthereumAccount | null;
24
+ /**
25
+ * Get current chain ID
26
+ */
27
+ getChainId(): string | null;
28
+ /**
29
+ * Check if wallet is connected
30
+ */
31
+ isConnected(): boolean;
32
+ /**
33
+ * Disconnect wallet
34
+ */
35
+ disconnect(): void;
36
+ /**
37
+ * Get the ethereum provider (for advanced usage)
38
+ */
39
+ getProvider(): any;
40
+ private handleAccountsChanged;
41
+ private handleChainChanged;
42
+ }
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ /**
3
+ * Ethereum Wallet Connection (MetaMask)
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EthereumWallet = void 0;
7
+ class EthereumWallet {
8
+ constructor() {
9
+ this.account = null;
10
+ this.chainId = null;
11
+ }
12
+ /**
13
+ * Check if MetaMask is installed
14
+ */
15
+ static isMetaMaskInstalled() {
16
+ if (typeof window === 'undefined') {
17
+ return false;
18
+ }
19
+ return typeof window.ethereum !== 'undefined' && window.ethereum.isMetaMask;
20
+ }
21
+ /**
22
+ * Connect to MetaMask wallet
23
+ * @returns Connected account information
24
+ */
25
+ async connect() {
26
+ if (typeof window === 'undefined') {
27
+ throw new Error('EthereumWallet: Browser environment required');
28
+ }
29
+ if (!EthereumWallet.isMetaMaskInstalled()) {
30
+ throw new Error('MetaMask is not installed. Please install MetaMask extension from https://metamask.io/');
31
+ }
32
+ const ethereum = window.ethereum;
33
+ try {
34
+ // Request account access - this will trigger MetaMask popup
35
+ const accounts = await ethereum.request({ method: 'eth_requestAccounts' });
36
+ if (!accounts || accounts.length === 0) {
37
+ throw new Error('No accounts found. Please unlock MetaMask and try again.');
38
+ }
39
+ // Get chain ID
40
+ const chainId = await ethereum.request({ method: 'eth_chainId' });
41
+ this.account = {
42
+ address: accounts[0],
43
+ chainId: chainId
44
+ };
45
+ this.chainId = chainId;
46
+ // Listen for account changes
47
+ ethereum.on('accountsChanged', this.handleAccountsChanged.bind(this));
48
+ ethereum.on('chainChanged', this.handleChainChanged.bind(this));
49
+ return this.account;
50
+ }
51
+ catch (error) {
52
+ if (error.code === 4001) {
53
+ throw new Error('User rejected the connection request');
54
+ }
55
+ throw new Error(`Failed to connect to MetaMask: ${error.message || error}`);
56
+ }
57
+ }
58
+ /**
59
+ * Get currently connected account
60
+ */
61
+ getAccount() {
62
+ return this.account;
63
+ }
64
+ /**
65
+ * Get current chain ID
66
+ */
67
+ getChainId() {
68
+ return this.chainId;
69
+ }
70
+ /**
71
+ * Check if wallet is connected
72
+ */
73
+ isConnected() {
74
+ return this.account !== null;
75
+ }
76
+ /**
77
+ * Disconnect wallet
78
+ */
79
+ disconnect() {
80
+ this.account = null;
81
+ this.chainId = null;
82
+ }
83
+ /**
84
+ * Get the ethereum provider (for advanced usage)
85
+ */
86
+ getProvider() {
87
+ if (typeof window === 'undefined') {
88
+ return null;
89
+ }
90
+ return window.ethereum;
91
+ }
92
+ handleAccountsChanged(accounts) {
93
+ if (accounts.length === 0) {
94
+ this.disconnect();
95
+ }
96
+ else if (this.account && accounts[0] !== this.account.address) {
97
+ this.account.address = accounts[0];
98
+ }
99
+ }
100
+ handleChainChanged(chainId) {
101
+ this.chainId = chainId;
102
+ if (this.account) {
103
+ this.account.chainId = chainId;
104
+ }
105
+ }
106
+ }
107
+ exports.EthereumWallet = EthereumWallet;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Solana Wallet Connection (Phantom)
3
+ */
4
+ export interface SolanaAccount {
5
+ address: string;
6
+ publicKey: string;
7
+ }
8
+ export declare class SolanaWallet {
9
+ private account;
10
+ /**
11
+ * Check if Phantom is installed
12
+ */
13
+ static isPhantomInstalled(): boolean;
14
+ /**
15
+ * Connect to Phantom wallet
16
+ * @returns Connected account information
17
+ */
18
+ connect(): Promise<SolanaAccount>;
19
+ /**
20
+ * Get currently connected account
21
+ */
22
+ getAccount(): SolanaAccount | null;
23
+ /**
24
+ * Check if wallet is connected
25
+ */
26
+ isConnected(): boolean;
27
+ /**
28
+ * Disconnect wallet
29
+ */
30
+ disconnect(): void;
31
+ /**
32
+ * Get the Solana provider (for advanced usage)
33
+ */
34
+ getProvider(): any;
35
+ private handleDisconnect;
36
+ }
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ /**
3
+ * Solana Wallet Connection (Phantom)
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.SolanaWallet = void 0;
7
+ class SolanaWallet {
8
+ constructor() {
9
+ this.account = null;
10
+ }
11
+ /**
12
+ * Check if Phantom is installed
13
+ */
14
+ static isPhantomInstalled() {
15
+ if (typeof window === 'undefined') {
16
+ return false;
17
+ }
18
+ return typeof window.solana !== 'undefined' && window.solana.isPhantom;
19
+ }
20
+ /**
21
+ * Connect to Phantom wallet
22
+ * @returns Connected account information
23
+ */
24
+ async connect() {
25
+ if (typeof window === 'undefined') {
26
+ throw new Error('SolanaWallet: Browser environment required');
27
+ }
28
+ if (!SolanaWallet.isPhantomInstalled()) {
29
+ throw new Error('Phantom is not installed. Please install Phantom extension from https://phantom.app/');
30
+ }
31
+ const solana = window.solana;
32
+ try {
33
+ // Request connection - this will trigger Phantom popup
34
+ const response = await solana.connect();
35
+ if (!response || !response.publicKey) {
36
+ throw new Error('Failed to connect to Phantom wallet');
37
+ }
38
+ this.account = {
39
+ address: response.publicKey.toString(),
40
+ publicKey: response.publicKey.toString()
41
+ };
42
+ // Listen for disconnect
43
+ solana.on('disconnect', this.handleDisconnect.bind(this));
44
+ return this.account;
45
+ }
46
+ catch (error) {
47
+ if (error.code === 4001) {
48
+ throw new Error('User rejected the connection request');
49
+ }
50
+ throw new Error(`Failed to connect to Phantom: ${error.message || error}`);
51
+ }
52
+ }
53
+ /**
54
+ * Get currently connected account
55
+ */
56
+ getAccount() {
57
+ return this.account;
58
+ }
59
+ /**
60
+ * Check if wallet is connected
61
+ */
62
+ isConnected() {
63
+ return this.account !== null;
64
+ }
65
+ /**
66
+ * Disconnect wallet
67
+ */
68
+ disconnect() {
69
+ if (this.account && typeof window !== 'undefined') {
70
+ const solana = window.solana;
71
+ if (solana && solana.disconnect && typeof solana.disconnect === 'function') {
72
+ try {
73
+ const disconnectResult = solana.disconnect();
74
+ if (disconnectResult && typeof disconnectResult.catch === 'function') {
75
+ disconnectResult.catch(() => {
76
+ // Ignore disconnect errors
77
+ });
78
+ }
79
+ }
80
+ catch (error) {
81
+ // Ignore disconnect errors
82
+ }
83
+ }
84
+ }
85
+ this.account = null;
86
+ }
87
+ /**
88
+ * Get the Solana provider (for advanced usage)
89
+ */
90
+ getProvider() {
91
+ if (typeof window === 'undefined') {
92
+ return null;
93
+ }
94
+ return window.solana;
95
+ }
96
+ handleDisconnect() {
97
+ this.disconnect();
98
+ }
99
+ }
100
+ exports.SolanaWallet = SolanaWallet;
@@ -0,0 +1,2 @@
1
+ /*! For license information please see voidai-sdk.js.LICENSE.txt */
2
+ !function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.VoidAISDK=t():e.VoidAISDK=t()}(this,()=>(()=>{"use strict";var e={28:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BridgeConfig=void 0;class n{constructor(e){if(!e.apiKey)throw new Error("BridgeSDK: apiKey is required");this.apiKey=e.apiKey,this.environment=e.environment||"production",["development","staging","production"].includes(this.environment)||(this.environment="production");const t=n.DEFAULTS[this.environment];this.baseUrl=e.baseUrl||t.baseUrl}getBaseUrl(){return this.baseUrl}}t.BridgeConfig=n,n.DEFAULTS={development:{baseUrl:"https://api-dev.voidai.envistudios.com"},staging:{baseUrl:"https://api-staging.voidai.envistudios.com"},production:{baseUrl:"https://api.voidai.envistudios.com"}}},156:function(e,t,n){var r=this&&this.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var o=Object.getOwnPropertyDescriptor(t,n);o&&!("get"in o?!t.__esModule:o.writable||o.configurable)||(o={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,o)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),o=this&&this.__exportStar||function(e,t){for(var n in e)"default"===n||Object.prototype.hasOwnProperty.call(t,n)||r(t,e,n)};Object.defineProperty(t,"__esModule",{value:!0}),t.BridgeSDK=void 0;const i=n(28),s=n(436),a=n(570),c=n(967),l=n(318),u=n(925);o(n(574),t),o(n(28),t),o(n(570),t),o(n(967),t),o(n(318),t),t.BridgeSDK=class{constructor(e){this.config=new i.BridgeConfig(e),this.api=new s.VoidAIBridgeClient(this.config),this.wallets={bittensor:new a.BittensorWallet,ethereum:new c.EthereumWallet,solana:new l.SolanaWallet},this.bridge=new u.Bridge(this.api)}async init(){console.log("BridgeSDK initialized")}}},318:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.SolanaWallet=void 0;class n{constructor(){this.account=null}static isPhantomInstalled(){return"undefined"!=typeof window&&void 0!==window.solana&&window.solana.isPhantom}async connect(){if("undefined"==typeof window)throw new Error("SolanaWallet: Browser environment required");if(!n.isPhantomInstalled())throw new Error("Phantom is not installed. Please install Phantom extension from https://phantom.app/");const e=window.solana;try{const t=await e.connect();if(!t||!t.publicKey)throw new Error("Failed to connect to Phantom wallet");return this.account={address:t.publicKey.toString(),publicKey:t.publicKey.toString()},e.on("disconnect",this.handleDisconnect.bind(this)),this.account}catch(e){if(4001===e.code)throw new Error("User rejected the connection request");throw new Error(`Failed to connect to Phantom: ${e.message||e}`)}}getAccount(){return this.account}isConnected(){return null!==this.account}disconnect(){if(this.account&&"undefined"!=typeof window){const e=window.solana;if(e&&e.disconnect&&"function"==typeof e.disconnect)try{const t=e.disconnect();t&&"function"==typeof t.catch&&t.catch(()=>{})}catch(e){}}this.account=null}getProvider(){return"undefined"==typeof window?null:window.solana}handleDisconnect(){this.disconnect()}}t.SolanaWallet=n},425:(e,t,n)=>{function r(e,t){return function(){return e.apply(t,arguments)}}const{toString:o}=Object.prototype,{getPrototypeOf:i}=Object,{iterator:s,toStringTag:a}=Symbol,c=(l=Object.create(null),e=>{const t=o.call(e);return l[t]||(l[t]=t.slice(8,-1).toLowerCase())});var l;const u=e=>(e=e.toLowerCase(),t=>c(t)===e),d=e=>t=>typeof t===e,{isArray:f}=Array,h=d("undefined");function p(e){return null!==e&&!h(e)&&null!==e.constructor&&!h(e.constructor)&&g(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}const m=u("ArrayBuffer"),w=d("string"),g=d("function"),y=d("number"),b=e=>null!==e&&"object"==typeof e,E=e=>{if("object"!==c(e))return!1;const t=i(e);return!(null!==t&&t!==Object.prototype&&null!==Object.getPrototypeOf(t)||a in e||s in e)},O=u("Date"),v=u("File"),S=u("Blob"),R=u("FileList"),A=u("URLSearchParams"),[T,x,j,C]=["ReadableStream","Request","Response","Headers"].map(u);function P(e,t,{allOwnKeys:n=!1}={}){if(null==e)return;let r,o;if("object"!=typeof e&&(e=[e]),f(e))for(r=0,o=e.length;r<o;r++)t.call(null,e[r],r,e);else{if(p(e))return;const o=n?Object.getOwnPropertyNames(e):Object.keys(e),i=o.length;let s;for(r=0;r<i;r++)s=o[r],t.call(null,e[s],s,e)}}function _(e,t){if(p(e))return null;t=t.toLowerCase();const n=Object.keys(e);let r,o=n.length;for(;o-- >0;)if(r=n[o],t===r.toLowerCase())return r;return null}const U="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:"undefined"!=typeof window?window:n.g,N=e=>!h(e)&&e!==U,B=(k="undefined"!=typeof Uint8Array&&i(Uint8Array),e=>k&&e instanceof k);var k;const F=u("HTMLFormElement"),L=(({hasOwnProperty:e})=>(t,n)=>e.call(t,n))(Object.prototype),D=u("RegExp"),I=(e,t)=>{const n=Object.getOwnPropertyDescriptors(e),r={};P(n,(n,o)=>{let i;!1!==(i=t(n,o,e))&&(r[o]=i||n)}),Object.defineProperties(e,r)},M=u("AsyncFunction"),q=(W="function"==typeof setImmediate,z=g(U.postMessage),W?setImmediate:z?(K=`axios@${Math.random()}`,$=[],U.addEventListener("message",({source:e,data:t})=>{e===U&&t===K&&$.length&&$.shift()()},!1),e=>{$.push(e),U.postMessage(K,"*")}):e=>setTimeout(e));var W,z,K,$;const H="undefined"!=typeof queueMicrotask?queueMicrotask.bind(U):"undefined"!=typeof process&&process.nextTick||q;var V={isArray:f,isArrayBuffer:m,isBuffer:p,isFormData:e=>{let t;return e&&("function"==typeof FormData&&e instanceof FormData||g(e.append)&&("formdata"===(t=c(e))||"object"===t&&g(e.toString)&&"[object FormData]"===e.toString()))},isArrayBufferView:function(e){let t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&m(e.buffer),t},isString:w,isNumber:y,isBoolean:e=>!0===e||!1===e,isObject:b,isPlainObject:E,isEmptyObject:e=>{if(!b(e)||p(e))return!1;try{return 0===Object.keys(e).length&&Object.getPrototypeOf(e)===Object.prototype}catch(e){return!1}},isReadableStream:T,isRequest:x,isResponse:j,isHeaders:C,isUndefined:h,isDate:O,isFile:v,isBlob:S,isRegExp:D,isFunction:g,isStream:e=>b(e)&&g(e.pipe),isURLSearchParams:A,isTypedArray:B,isFileList:R,forEach:P,merge:function e(){const{caseless:t,skipUndefined:n}=N(this)&&this||{},r={},o=(o,i)=>{const s=t&&_(r,i)||i;E(r[s])&&E(o)?r[s]=e(r[s],o):E(o)?r[s]=e({},o):f(o)?r[s]=o.slice():n&&h(o)||(r[s]=o)};for(let e=0,t=arguments.length;e<t;e++)arguments[e]&&P(arguments[e],o);return r},extend:(e,t,n,{allOwnKeys:o}={})=>(P(t,(t,o)=>{n&&g(t)?e[o]=r(t,n):e[o]=t},{allOwnKeys:o}),e),trim:e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,""),stripBOM:e=>(65279===e.charCodeAt(0)&&(e=e.slice(1)),e),inherits:(e,t,n,r)=>{e.prototype=Object.create(t.prototype,r),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),n&&Object.assign(e.prototype,n)},toFlatObject:(e,t,n,r)=>{let o,s,a;const c={};if(t=t||{},null==e)return t;do{for(o=Object.getOwnPropertyNames(e),s=o.length;s-- >0;)a=o[s],r&&!r(a,e,t)||c[a]||(t[a]=e[a],c[a]=!0);e=!1!==n&&i(e)}while(e&&(!n||n(e,t))&&e!==Object.prototype);return t},kindOf:c,kindOfTest:u,endsWith:(e,t,n)=>{e=String(e),(void 0===n||n>e.length)&&(n=e.length),n-=t.length;const r=e.indexOf(t,n);return-1!==r&&r===n},toArray:e=>{if(!e)return null;if(f(e))return e;let t=e.length;if(!y(t))return null;const n=new Array(t);for(;t-- >0;)n[t]=e[t];return n},forEachEntry:(e,t)=>{const n=(e&&e[s]).call(e);let r;for(;(r=n.next())&&!r.done;){const n=r.value;t.call(e,n[0],n[1])}},matchAll:(e,t)=>{let n;const r=[];for(;null!==(n=e.exec(t));)r.push(n);return r},isHTMLForm:F,hasOwnProperty:L,hasOwnProp:L,reduceDescriptors:I,freezeMethods:e=>{I(e,(t,n)=>{if(g(e)&&-1!==["arguments","caller","callee"].indexOf(n))return!1;const r=e[n];g(r)&&(t.enumerable=!1,"writable"in t?t.writable=!1:t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+n+"'")}))})},toObjectSet:(e,t)=>{const n={},r=e=>{e.forEach(e=>{n[e]=!0})};return f(e)?r(e):r(String(e).split(t)),n},toCamelCase:e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(e,t,n){return t.toUpperCase()+n}),noop:()=>{},toFiniteNumber:(e,t)=>null!=e&&Number.isFinite(e=+e)?e:t,findKey:_,global:U,isContextDefined:N,isSpecCompliantForm:function(e){return!!(e&&g(e.append)&&"FormData"===e[a]&&e[s])},toJSONObject:e=>{const t=new Array(10),n=(e,r)=>{if(b(e)){if(t.indexOf(e)>=0)return;if(p(e))return e;if(!("toJSON"in e)){t[r]=e;const o=f(e)?[]:{};return P(e,(e,t)=>{const i=n(e,r+1);!h(i)&&(o[t]=i)}),t[r]=void 0,o}}return e};return n(e,0)},isAsyncFn:M,isThenable:e=>e&&(b(e)||g(e))&&g(e.then)&&g(e.catch),setImmediate:q,asap:H,isIterable:e=>null!=e&&g(e[s])};function J(e,t,n,r,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=(new Error).stack,this.message=e,this.name="AxiosError",t&&(this.code=t),n&&(this.config=n),r&&(this.request=r),o&&(this.response=o,this.status=o.status?o.status:null)}V.inherits(J,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:V.toJSONObject(this.config),code:this.code,status:this.status}}});const X=J.prototype,G={};function Q(e){return V.isPlainObject(e)||V.isArray(e)}function Z(e){return V.endsWith(e,"[]")?e.slice(0,-2):e}function Y(e,t,n){return e?e.concat(t).map(function(e,t){return e=Z(e),!n&&t?"["+e+"]":e}).join(n?".":""):t}["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{G[e]={value:e}}),Object.defineProperties(J,G),Object.defineProperty(X,"isAxiosError",{value:!0}),J.from=(e,t,n,r,o,i)=>{const s=Object.create(X);V.toFlatObject(e,s,function(e){return e!==Error.prototype},e=>"isAxiosError"!==e);const a=e&&e.message?e.message:"Error",c=null==t&&e?e.code:t;return J.call(s,a,c,n,r,o),e&&null==s.cause&&Object.defineProperty(s,"cause",{value:e,configurable:!0}),s.name=e&&e.name||"Error",i&&Object.assign(s,i),s};const ee=V.toFlatObject(V,{},null,function(e){return/^is[A-Z]/.test(e)});function te(e,t,n){if(!V.isObject(e))throw new TypeError("target must be an object");t=t||new FormData;const r=(n=V.toFlatObject(n,{metaTokens:!0,dots:!1,indexes:!1},!1,function(e,t){return!V.isUndefined(t[e])})).metaTokens,o=n.visitor||l,i=n.dots,s=n.indexes,a=(n.Blob||"undefined"!=typeof Blob&&Blob)&&V.isSpecCompliantForm(t);if(!V.isFunction(o))throw new TypeError("visitor must be a function");function c(e){if(null===e)return"";if(V.isDate(e))return e.toISOString();if(V.isBoolean(e))return e.toString();if(!a&&V.isBlob(e))throw new J("Blob is not supported. Use a Buffer instead.");return V.isArrayBuffer(e)||V.isTypedArray(e)?a&&"function"==typeof Blob?new Blob([e]):Buffer.from(e):e}function l(e,n,o){let a=e;if(e&&!o&&"object"==typeof e)if(V.endsWith(n,"{}"))n=r?n:n.slice(0,-2),e=JSON.stringify(e);else if(V.isArray(e)&&function(e){return V.isArray(e)&&!e.some(Q)}(e)||(V.isFileList(e)||V.endsWith(n,"[]"))&&(a=V.toArray(e)))return n=Z(n),a.forEach(function(e,r){!V.isUndefined(e)&&null!==e&&t.append(!0===s?Y([n],r,i):null===s?n:n+"[]",c(e))}),!1;return!!Q(e)||(t.append(Y(o,n,i),c(e)),!1)}const u=[],d=Object.assign(ee,{defaultVisitor:l,convertValue:c,isVisitable:Q});if(!V.isObject(e))throw new TypeError("data must be an object");return function e(n,r){if(!V.isUndefined(n)){if(-1!==u.indexOf(n))throw Error("Circular reference detected in "+r.join("."));u.push(n),V.forEach(n,function(n,i){!0===(!(V.isUndefined(n)||null===n)&&o.call(t,n,V.isString(i)?i.trim():i,r,d))&&e(n,r?r.concat(i):[i])}),u.pop()}}(e),t}function ne(e){const t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(e){return t[e]})}function re(e,t){this._pairs=[],e&&te(e,this,t)}const oe=re.prototype;function ie(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+")}function se(e,t,n){if(!t)return e;const r=n&&n.encode||ie;V.isFunction(n)&&(n={serialize:n});const o=n&&n.serialize;let i;if(i=o?o(t,n):V.isURLSearchParams(t)?t.toString():new re(t,n).toString(r),i){const t=e.indexOf("#");-1!==t&&(e=e.slice(0,t)),e+=(-1===e.indexOf("?")?"?":"&")+i}return e}oe.append=function(e,t){this._pairs.push([e,t])},oe.toString=function(e){const t=e?function(t){return e.call(this,t,ne)}:ne;return this._pairs.map(function(e){return t(e[0])+"="+t(e[1])},"").join("&")};var ae=class{constructor(){this.handlers=[]}use(e,t,n){return this.handlers.push({fulfilled:e,rejected:t,synchronous:!!n&&n.synchronous,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(e){this.handlers[e]&&(this.handlers[e]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(e){V.forEach(this.handlers,function(t){null!==t&&e(t)})}},ce={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1},le={isBrowser:!0,classes:{URLSearchParams:"undefined"!=typeof URLSearchParams?URLSearchParams:re,FormData:"undefined"!=typeof FormData?FormData:null,Blob:"undefined"!=typeof Blob?Blob:null},protocols:["http","https","file","blob","url","data"]};const ue="undefined"!=typeof window&&"undefined"!=typeof document,de="object"==typeof navigator&&navigator||void 0,fe=ue&&(!de||["ReactNative","NativeScript","NS"].indexOf(de.product)<0),he="undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope&&"function"==typeof self.importScripts,pe=ue&&window.location.href||"http://localhost";var me={...Object.freeze({__proto__:null,hasBrowserEnv:ue,hasStandardBrowserWebWorkerEnv:he,hasStandardBrowserEnv:fe,navigator:de,origin:pe}),...le};function we(e){function t(e,n,r,o){let i=e[o++];if("__proto__"===i)return!0;const s=Number.isFinite(+i),a=o>=e.length;return i=!i&&V.isArray(r)?r.length:i,a?(V.hasOwnProp(r,i)?r[i]=[r[i],n]:r[i]=n,!s):(r[i]&&V.isObject(r[i])||(r[i]=[]),t(e,n,r[i],o)&&V.isArray(r[i])&&(r[i]=function(e){const t={},n=Object.keys(e);let r;const o=n.length;let i;for(r=0;r<o;r++)i=n[r],t[i]=e[i];return t}(r[i])),!s)}if(V.isFormData(e)&&V.isFunction(e.entries)){const n={};return V.forEachEntry(e,(e,r)=>{t(function(e){return V.matchAll(/\w+|\[(\w*)]/g,e).map(e=>"[]"===e[0]?"":e[1]||e[0])}(e),r,n,0)}),n}return null}const ge={transitional:ce,adapter:["xhr","http","fetch"],transformRequest:[function(e,t){const n=t.getContentType()||"",r=n.indexOf("application/json")>-1,o=V.isObject(e);if(o&&V.isHTMLForm(e)&&(e=new FormData(e)),V.isFormData(e))return r?JSON.stringify(we(e)):e;if(V.isArrayBuffer(e)||V.isBuffer(e)||V.isStream(e)||V.isFile(e)||V.isBlob(e)||V.isReadableStream(e))return e;if(V.isArrayBufferView(e))return e.buffer;if(V.isURLSearchParams(e))return t.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),e.toString();let i;if(o){if(n.indexOf("application/x-www-form-urlencoded")>-1)return function(e,t){return te(e,new me.classes.URLSearchParams,{visitor:function(e,t,n,r){return me.isNode&&V.isBuffer(e)?(this.append(t,e.toString("base64")),!1):r.defaultVisitor.apply(this,arguments)},...t})}(e,this.formSerializer).toString();if((i=V.isFileList(e))||n.indexOf("multipart/form-data")>-1){const t=this.env&&this.env.FormData;return te(i?{"files[]":e}:e,t&&new t,this.formSerializer)}}return o||r?(t.setContentType("application/json",!1),function(e){if(V.isString(e))try{return(0,JSON.parse)(e),V.trim(e)}catch(e){if("SyntaxError"!==e.name)throw e}return(0,JSON.stringify)(e)}(e)):e}],transformResponse:[function(e){const t=this.transitional||ge.transitional,n=t&&t.forcedJSONParsing,r="json"===this.responseType;if(V.isResponse(e)||V.isReadableStream(e))return e;if(e&&V.isString(e)&&(n&&!this.responseType||r)){const n=!(t&&t.silentJSONParsing)&&r;try{return JSON.parse(e,this.parseReviver)}catch(e){if(n){if("SyntaxError"===e.name)throw J.from(e,J.ERR_BAD_RESPONSE,this,null,this.response);throw e}}}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:me.classes.FormData,Blob:me.classes.Blob},validateStatus:function(e){return e>=200&&e<300},headers:{common:{Accept:"application/json, text/plain, */*","Content-Type":void 0}}};V.forEach(["delete","get","head","post","put","patch"],e=>{ge.headers[e]={}});var ye=ge;const be=V.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),Ee=Symbol("internals");function Oe(e){return e&&String(e).trim().toLowerCase()}function ve(e){return!1===e||null==e?e:V.isArray(e)?e.map(ve):String(e)}function Se(e,t,n,r,o){return V.isFunction(r)?r.call(this,t,n):(o&&(t=n),V.isString(t)?V.isString(r)?-1!==t.indexOf(r):V.isRegExp(r)?r.test(t):void 0:void 0)}class Re{constructor(e){e&&this.set(e)}set(e,t,n){const r=this;function o(e,t,n){const o=Oe(t);if(!o)throw new Error("header name must be a non-empty string");const i=V.findKey(r,o);(!i||void 0===r[i]||!0===n||void 0===n&&!1!==r[i])&&(r[i||t]=ve(e))}const i=(e,t)=>V.forEach(e,(e,n)=>o(e,n,t));if(V.isPlainObject(e)||e instanceof this.constructor)i(e,t);else if(V.isString(e)&&(e=e.trim())&&!/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim()))i((e=>{const t={};let n,r,o;return e&&e.split("\n").forEach(function(e){o=e.indexOf(":"),n=e.substring(0,o).trim().toLowerCase(),r=e.substring(o+1).trim(),!n||t[n]&&be[n]||("set-cookie"===n?t[n]?t[n].push(r):t[n]=[r]:t[n]=t[n]?t[n]+", "+r:r)}),t})(e),t);else if(V.isObject(e)&&V.isIterable(e)){let n,r,o={};for(const t of e){if(!V.isArray(t))throw TypeError("Object iterator must return a key-value pair");o[r=t[0]]=(n=o[r])?V.isArray(n)?[...n,t[1]]:[n,t[1]]:t[1]}i(o,t)}else null!=e&&o(t,e,n);return this}get(e,t){if(e=Oe(e)){const n=V.findKey(this,e);if(n){const e=this[n];if(!t)return e;if(!0===t)return function(e){const t=Object.create(null),n=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g;let r;for(;r=n.exec(e);)t[r[1]]=r[2];return t}(e);if(V.isFunction(t))return t.call(this,e,n);if(V.isRegExp(t))return t.exec(e);throw new TypeError("parser must be boolean|regexp|function")}}}has(e,t){if(e=Oe(e)){const n=V.findKey(this,e);return!(!n||void 0===this[n]||t&&!Se(0,this[n],n,t))}return!1}delete(e,t){const n=this;let r=!1;function o(e){if(e=Oe(e)){const o=V.findKey(n,e);!o||t&&!Se(0,n[o],o,t)||(delete n[o],r=!0)}}return V.isArray(e)?e.forEach(o):o(e),r}clear(e){const t=Object.keys(this);let n=t.length,r=!1;for(;n--;){const o=t[n];e&&!Se(0,this[o],o,e,!0)||(delete this[o],r=!0)}return r}normalize(e){const t=this,n={};return V.forEach(this,(r,o)=>{const i=V.findKey(n,o);if(i)return t[i]=ve(r),void delete t[o];const s=e?function(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(e,t,n)=>t.toUpperCase()+n)}(o):String(o).trim();s!==o&&delete t[o],t[s]=ve(r),n[s]=!0}),this}concat(...e){return this.constructor.concat(this,...e)}toJSON(e){const t=Object.create(null);return V.forEach(this,(n,r)=>{null!=n&&!1!==n&&(t[r]=e&&V.isArray(n)?n.join(", "):n)}),t}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([e,t])=>e+": "+t).join("\n")}getSetCookie(){return this.get("set-cookie")||[]}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(e){return e instanceof this?e:new this(e)}static concat(e,...t){const n=new this(e);return t.forEach(e=>n.set(e)),n}static accessor(e){const t=(this[Ee]=this[Ee]={accessors:{}}).accessors,n=this.prototype;function r(e){const r=Oe(e);t[r]||(function(e,t){const n=V.toCamelCase(" "+t);["get","set","has"].forEach(r=>{Object.defineProperty(e,r+n,{value:function(e,n,o){return this[r].call(this,t,e,n,o)},configurable:!0})})}(n,e),t[r]=!0)}return V.isArray(e)?e.forEach(r):r(e),this}}Re.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]),V.reduceDescriptors(Re.prototype,({value:e},t)=>{let n=t[0].toUpperCase()+t.slice(1);return{get:()=>e,set(e){this[n]=e}}}),V.freezeMethods(Re);var Ae=Re;function Te(e,t){const n=this||ye,r=t||n,o=Ae.from(r.headers);let i=r.data;return V.forEach(e,function(e){i=e.call(n,i,o.normalize(),t?t.status:void 0)}),o.normalize(),i}function xe(e){return!(!e||!e.__CANCEL__)}function je(e,t,n){J.call(this,null==e?"canceled":e,J.ERR_CANCELED,t,n),this.name="CanceledError"}function Ce(e,t,n){const r=n.config.validateStatus;n.status&&r&&!r(n.status)?t(new J("Request failed with status code "+n.status,[J.ERR_BAD_REQUEST,J.ERR_BAD_RESPONSE][Math.floor(n.status/100)-4],n.config,n.request,n)):e(n)}V.inherits(je,J,{__CANCEL__:!0});const Pe=(e,t,n=3)=>{let r=0;const o=function(e,t){e=e||10;const n=new Array(e),r=new Array(e);let o,i=0,s=0;return t=void 0!==t?t:1e3,function(a){const c=Date.now(),l=r[s];o||(o=c),n[i]=a,r[i]=c;let u=s,d=0;for(;u!==i;)d+=n[u++],u%=e;if(i=(i+1)%e,i===s&&(s=(s+1)%e),c-o<t)return;const f=l&&c-l;return f?Math.round(1e3*d/f):void 0}}(50,250);return function(n,i){let s,a,c=0,l=1e3/i;const u=(n,i=Date.now())=>{c=i,s=null,a&&(clearTimeout(a),a=null),(n=>{const i=n.loaded,s=n.lengthComputable?n.total:void 0,a=i-r,c=o(a);r=i,e({loaded:i,total:s,progress:s?i/s:void 0,bytes:a,rate:c||void 0,estimated:c&&s&&i<=s?(s-i)/c:void 0,event:n,lengthComputable:null!=s,[t?"download":"upload"]:!0})})(...n)};return[(...e)=>{const t=Date.now(),n=t-c;n>=l?u(e,t):(s=e,a||(a=setTimeout(()=>{a=null,u(s)},l-n)))},()=>s&&u(s)]}(0,n)},_e=(e,t)=>{const n=null!=e;return[r=>t[0]({lengthComputable:n,total:e,loaded:r}),t[1]]},Ue=e=>(...t)=>V.asap(()=>e(...t));var Ne=me.hasStandardBrowserEnv?((e,t)=>n=>(n=new URL(n,me.origin),e.protocol===n.protocol&&e.host===n.host&&(t||e.port===n.port)))(new URL(me.origin),me.navigator&&/(msie|trident)/i.test(me.navigator.userAgent)):()=>!0,Be=me.hasStandardBrowserEnv?{write(e,t,n,r,o,i,s){if("undefined"==typeof document)return;const a=[`${e}=${encodeURIComponent(t)}`];V.isNumber(n)&&a.push(`expires=${new Date(n).toUTCString()}`),V.isString(r)&&a.push(`path=${r}`),V.isString(o)&&a.push(`domain=${o}`),!0===i&&a.push("secure"),V.isString(s)&&a.push(`SameSite=${s}`),document.cookie=a.join("; ")},read(e){if("undefined"==typeof document)return null;const t=document.cookie.match(new RegExp("(?:^|; )"+e+"=([^;]*)"));return t?decodeURIComponent(t[1]):null},remove(e){this.write(e,"",Date.now()-864e5,"/")}}:{write(){},read:()=>null,remove(){}};function ke(e,t,n){let r=!/^([a-z][a-z\d+\-.]*:)?\/\//i.test(t);return e&&(r||0==n)?function(e,t){return t?e.replace(/\/?\/$/,"")+"/"+t.replace(/^\/+/,""):e}(e,t):t}const Fe=e=>e instanceof Ae?{...e}:e;function Le(e,t){t=t||{};const n={};function r(e,t,n,r){return V.isPlainObject(e)&&V.isPlainObject(t)?V.merge.call({caseless:r},e,t):V.isPlainObject(t)?V.merge({},t):V.isArray(t)?t.slice():t}function o(e,t,n,o){return V.isUndefined(t)?V.isUndefined(e)?void 0:r(void 0,e,0,o):r(e,t,0,o)}function i(e,t){if(!V.isUndefined(t))return r(void 0,t)}function s(e,t){return V.isUndefined(t)?V.isUndefined(e)?void 0:r(void 0,e):r(void 0,t)}function a(n,o,i){return i in t?r(n,o):i in e?r(void 0,n):void 0}const c={url:i,method:i,data:i,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,withXSRFToken:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:a,headers:(e,t,n)=>o(Fe(e),Fe(t),0,!0)};return V.forEach(Object.keys({...e,...t}),function(r){const i=c[r]||o,s=i(e[r],t[r],r);V.isUndefined(s)&&i!==a||(n[r]=s)}),n}var De=e=>{const t=Le({},e);let{data:n,withXSRFToken:r,xsrfHeaderName:o,xsrfCookieName:i,headers:s,auth:a}=t;if(t.headers=s=Ae.from(s),t.url=se(ke(t.baseURL,t.url,t.allowAbsoluteUrls),e.params,e.paramsSerializer),a&&s.set("Authorization","Basic "+btoa((a.username||"")+":"+(a.password?unescape(encodeURIComponent(a.password)):""))),V.isFormData(n))if(me.hasStandardBrowserEnv||me.hasStandardBrowserWebWorkerEnv)s.setContentType(void 0);else if(V.isFunction(n.getHeaders)){const e=n.getHeaders(),t=["content-type","content-length"];Object.entries(e).forEach(([e,n])=>{t.includes(e.toLowerCase())&&s.set(e,n)})}if(me.hasStandardBrowserEnv&&(r&&V.isFunction(r)&&(r=r(t)),r||!1!==r&&Ne(t.url))){const e=o&&i&&Be.read(i);e&&s.set(o,e)}return t},Ie="undefined"!=typeof XMLHttpRequest&&function(e){return new Promise(function(t,n){const r=De(e);let o=r.data;const i=Ae.from(r.headers).normalize();let s,a,c,l,u,{responseType:d,onUploadProgress:f,onDownloadProgress:h}=r;function p(){l&&l(),u&&u(),r.cancelToken&&r.cancelToken.unsubscribe(s),r.signal&&r.signal.removeEventListener("abort",s)}let m=new XMLHttpRequest;function w(){if(!m)return;const r=Ae.from("getAllResponseHeaders"in m&&m.getAllResponseHeaders());Ce(function(e){t(e),p()},function(e){n(e),p()},{data:d&&"text"!==d&&"json"!==d?m.response:m.responseText,status:m.status,statusText:m.statusText,headers:r,config:e,request:m}),m=null}m.open(r.method.toUpperCase(),r.url,!0),m.timeout=r.timeout,"onloadend"in m?m.onloadend=w:m.onreadystatechange=function(){m&&4===m.readyState&&(0!==m.status||m.responseURL&&0===m.responseURL.indexOf("file:"))&&setTimeout(w)},m.onabort=function(){m&&(n(new J("Request aborted",J.ECONNABORTED,e,m)),m=null)},m.onerror=function(t){const r=new J(t&&t.message?t.message:"Network Error",J.ERR_NETWORK,e,m);r.event=t||null,n(r),m=null},m.ontimeout=function(){let t=r.timeout?"timeout of "+r.timeout+"ms exceeded":"timeout exceeded";const o=r.transitional||ce;r.timeoutErrorMessage&&(t=r.timeoutErrorMessage),n(new J(t,o.clarifyTimeoutError?J.ETIMEDOUT:J.ECONNABORTED,e,m)),m=null},void 0===o&&i.setContentType(null),"setRequestHeader"in m&&V.forEach(i.toJSON(),function(e,t){m.setRequestHeader(t,e)}),V.isUndefined(r.withCredentials)||(m.withCredentials=!!r.withCredentials),d&&"json"!==d&&(m.responseType=r.responseType),h&&([c,u]=Pe(h,!0),m.addEventListener("progress",c)),f&&m.upload&&([a,l]=Pe(f),m.upload.addEventListener("progress",a),m.upload.addEventListener("loadend",l)),(r.cancelToken||r.signal)&&(s=t=>{m&&(n(!t||t.type?new je(null,e,m):t),m.abort(),m=null)},r.cancelToken&&r.cancelToken.subscribe(s),r.signal&&(r.signal.aborted?s():r.signal.addEventListener("abort",s)));const g=function(e){const t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}(r.url);g&&-1===me.protocols.indexOf(g)?n(new J("Unsupported protocol "+g+":",J.ERR_BAD_REQUEST,e)):m.send(o||null)})},Me=(e,t)=>{const{length:n}=e=e?e.filter(Boolean):[];if(t||n){let n,r=new AbortController;const o=function(e){if(!n){n=!0,s();const t=e instanceof Error?e:this.reason;r.abort(t instanceof J?t:new je(t instanceof Error?t.message:t))}};let i=t&&setTimeout(()=>{i=null,o(new J(`timeout ${t} of ms exceeded`,J.ETIMEDOUT))},t);const s=()=>{e&&(i&&clearTimeout(i),i=null,e.forEach(e=>{e.unsubscribe?e.unsubscribe(o):e.removeEventListener("abort",o)}),e=null)};e.forEach(e=>e.addEventListener("abort",o));const{signal:a}=r;return a.unsubscribe=()=>V.asap(s),a}};const qe=function*(e,t){let n=e.byteLength;if(!t||n<t)return void(yield e);let r,o=0;for(;o<n;)r=o+t,yield e.slice(o,r),o=r},We=(e,t,n,r)=>{const o=async function*(e,t){for await(const n of async function*(e){if(e[Symbol.asyncIterator])return void(yield*e);const t=e.getReader();try{for(;;){const{done:e,value:n}=await t.read();if(e)break;yield n}}finally{await t.cancel()}}(e))yield*qe(n,t)}(e,t);let i,s=0,a=e=>{i||(i=!0,r&&r(e))};return new ReadableStream({async pull(e){try{const{done:t,value:r}=await o.next();if(t)return a(),void e.close();let i=r.byteLength;if(n){let e=s+=i;n(e)}e.enqueue(new Uint8Array(r))}catch(e){throw a(e),e}},cancel:e=>(a(e),o.return())},{highWaterMark:2})},{isFunction:ze}=V,Ke=(({Request:e,Response:t})=>({Request:e,Response:t}))(V.global),{ReadableStream:$e,TextEncoder:He}=V.global,Ve=(e,...t)=>{try{return!!e(...t)}catch(e){return!1}},Je=e=>{e=V.merge.call({skipUndefined:!0},Ke,e);const{fetch:t,Request:n,Response:r}=e,o=t?ze(t):"function"==typeof fetch,i=ze(n),s=ze(r);if(!o)return!1;const a=o&&ze($e),c=o&&("function"==typeof He?(l=new He,e=>l.encode(e)):async e=>new Uint8Array(await new n(e).arrayBuffer()));var l;const u=i&&a&&Ve(()=>{let e=!1;const t=new n(me.origin,{body:new $e,method:"POST",get duplex(){return e=!0,"half"}}).headers.has("Content-Type");return e&&!t}),d=s&&a&&Ve(()=>V.isReadableStream(new r("").body)),f={stream:d&&(e=>e.body)};o&&["text","arrayBuffer","blob","formData","stream"].forEach(e=>{!f[e]&&(f[e]=(t,n)=>{let r=t&&t[e];if(r)return r.call(t);throw new J(`Response type '${e}' is not supported`,J.ERR_NOT_SUPPORT,n)})});return async e=>{let{url:o,method:s,data:a,signal:l,cancelToken:h,timeout:p,onDownloadProgress:m,onUploadProgress:w,responseType:g,headers:y,withCredentials:b="same-origin",fetchOptions:E}=De(e),O=t||fetch;g=g?(g+"").toLowerCase():"text";let v=Me([l,h&&h.toAbortSignal()],p),S=null;const R=v&&v.unsubscribe&&(()=>{v.unsubscribe()});let A;try{if(w&&u&&"get"!==s&&"head"!==s&&0!==(A=await(async(e,t)=>{const r=V.toFiniteNumber(e.getContentLength());return null==r?(async e=>{if(null==e)return 0;if(V.isBlob(e))return e.size;if(V.isSpecCompliantForm(e)){const t=new n(me.origin,{method:"POST",body:e});return(await t.arrayBuffer()).byteLength}return V.isArrayBufferView(e)||V.isArrayBuffer(e)?e.byteLength:(V.isURLSearchParams(e)&&(e+=""),V.isString(e)?(await c(e)).byteLength:void 0)})(t):r})(y,a))){let e,t=new n(o,{method:"POST",body:a,duplex:"half"});if(V.isFormData(a)&&(e=t.headers.get("content-type"))&&y.setContentType(e),t.body){const[e,n]=_e(A,Pe(Ue(w)));a=We(t.body,65536,e,n)}}V.isString(b)||(b=b?"include":"omit");const t=i&&"credentials"in n.prototype,l={...E,signal:v,method:s.toUpperCase(),headers:y.normalize().toJSON(),body:a,duplex:"half",credentials:t?b:void 0};S=i&&new n(o,l);let h=await(i?O(S,E):O(o,l));const p=d&&("stream"===g||"response"===g);if(d&&(m||p&&R)){const e={};["status","statusText","headers"].forEach(t=>{e[t]=h[t]});const t=V.toFiniteNumber(h.headers.get("content-length")),[n,o]=m&&_e(t,Pe(Ue(m),!0))||[];h=new r(We(h.body,65536,n,()=>{o&&o(),R&&R()}),e)}g=g||"text";let T=await f[V.findKey(f,g)||"text"](h,e);return!p&&R&&R(),await new Promise((t,n)=>{Ce(t,n,{data:T,headers:Ae.from(h.headers),status:h.status,statusText:h.statusText,config:e,request:S})})}catch(t){if(R&&R(),t&&"TypeError"===t.name&&/Load failed|fetch/i.test(t.message))throw Object.assign(new J("Network Error",J.ERR_NETWORK,e,S),{cause:t.cause||t});throw J.from(t,t&&t.code,e,S)}}},Xe=new Map,Ge=e=>{let t=e&&e.env||{};const{fetch:n,Request:r,Response:o}=t,i=[r,o,n];let s,a,c=i.length,l=Xe;for(;c--;)s=i[c],a=l.get(s),void 0===a&&l.set(s,a=c?new Map:Je(t)),l=a;return a};Ge();const Qe={http:null,xhr:Ie,fetch:{get:Ge}};V.forEach(Qe,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch(e){}Object.defineProperty(e,"adapterName",{value:t})}});const Ze=e=>`- ${e}`,Ye=e=>V.isFunction(e)||null===e||!1===e;var et=function(e,t){e=V.isArray(e)?e:[e];const{length:n}=e;let r,o;const i={};for(let s=0;s<n;s++){let n;if(r=e[s],o=r,!Ye(r)&&(o=Qe[(n=String(r)).toLowerCase()],void 0===o))throw new J(`Unknown adapter '${n}'`);if(o&&(V.isFunction(o)||(o=o.get(t))))break;i[n||"#"+s]=o}if(!o){const e=Object.entries(i).map(([e,t])=>`adapter ${e} `+(!1===t?"is not supported by the environment":"is not available in the build"));throw new J("There is no suitable adapter to dispatch the request "+(n?e.length>1?"since :\n"+e.map(Ze).join("\n"):" "+Ze(e[0]):"as no adapter specified"),"ERR_NOT_SUPPORT")}return o};function tt(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new je(null,e)}function nt(e){return tt(e),e.headers=Ae.from(e.headers),e.data=Te.call(e,e.transformRequest),-1!==["post","put","patch"].indexOf(e.method)&&e.headers.setContentType("application/x-www-form-urlencoded",!1),et(e.adapter||ye.adapter,e)(e).then(function(t){return tt(e),t.data=Te.call(e,e.transformResponse,t),t.headers=Ae.from(t.headers),t},function(t){return xe(t)||(tt(e),t&&t.response&&(t.response.data=Te.call(e,e.transformResponse,t.response),t.response.headers=Ae.from(t.response.headers))),Promise.reject(t)})}const rt="1.13.2",ot={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{ot[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}});const it={};ot.transitional=function(e,t,n){function r(e,t){return"[Axios v"+rt+"] Transitional option '"+e+"'"+t+(n?". "+n:"")}return(n,o,i)=>{if(!1===e)throw new J(r(o," has been removed"+(t?" in "+t:"")),J.ERR_DEPRECATED);return t&&!it[o]&&(it[o]=!0,console.warn(r(o," has been deprecated since v"+t+" and will be removed in the near future"))),!e||e(n,o,i)}},ot.spelling=function(e){return(t,n)=>(console.warn(`${n} is likely a misspelling of ${e}`),!0)};var st={assertOptions:function(e,t,n){if("object"!=typeof e)throw new J("options must be an object",J.ERR_BAD_OPTION_VALUE);const r=Object.keys(e);let o=r.length;for(;o-- >0;){const i=r[o],s=t[i];if(s){const t=e[i],n=void 0===t||s(t,i,e);if(!0!==n)throw new J("option "+i+" must be "+n,J.ERR_BAD_OPTION_VALUE);continue}if(!0!==n)throw new J("Unknown option "+i,J.ERR_BAD_OPTION)}},validators:ot};const at=st.validators;class ct{constructor(e){this.defaults=e||{},this.interceptors={request:new ae,response:new ae}}async request(e,t){try{return await this._request(e,t)}catch(e){if(e instanceof Error){let t={};Error.captureStackTrace?Error.captureStackTrace(t):t=new Error;const n=t.stack?t.stack.replace(/^.+\n/,""):"";try{e.stack?n&&!String(e.stack).endsWith(n.replace(/^.+\n.+\n/,""))&&(e.stack+="\n"+n):e.stack=n}catch(e){}}throw e}}_request(e,t){"string"==typeof e?(t=t||{}).url=e:t=e||{},t=Le(this.defaults,t);const{transitional:n,paramsSerializer:r,headers:o}=t;void 0!==n&&st.assertOptions(n,{silentJSONParsing:at.transitional(at.boolean),forcedJSONParsing:at.transitional(at.boolean),clarifyTimeoutError:at.transitional(at.boolean)},!1),null!=r&&(V.isFunction(r)?t.paramsSerializer={serialize:r}:st.assertOptions(r,{encode:at.function,serialize:at.function},!0)),void 0!==t.allowAbsoluteUrls||(void 0!==this.defaults.allowAbsoluteUrls?t.allowAbsoluteUrls=this.defaults.allowAbsoluteUrls:t.allowAbsoluteUrls=!0),st.assertOptions(t,{baseUrl:at.spelling("baseURL"),withXsrfToken:at.spelling("withXSRFToken")},!0),t.method=(t.method||this.defaults.method||"get").toLowerCase();let i=o&&V.merge(o.common,o[t.method]);o&&V.forEach(["delete","get","head","post","put","patch","common"],e=>{delete o[e]}),t.headers=Ae.concat(i,o);const s=[];let a=!0;this.interceptors.request.forEach(function(e){"function"==typeof e.runWhen&&!1===e.runWhen(t)||(a=a&&e.synchronous,s.unshift(e.fulfilled,e.rejected))});const c=[];let l;this.interceptors.response.forEach(function(e){c.push(e.fulfilled,e.rejected)});let u,d=0;if(!a){const e=[nt.bind(this),void 0];for(e.unshift(...s),e.push(...c),u=e.length,l=Promise.resolve(t);d<u;)l=l.then(e[d++],e[d++]);return l}u=s.length;let f=t;for(;d<u;){const e=s[d++],t=s[d++];try{f=e(f)}catch(e){t.call(this,e);break}}try{l=nt.call(this,f)}catch(e){return Promise.reject(e)}for(d=0,u=c.length;d<u;)l=l.then(c[d++],c[d++]);return l}getUri(e){return se(ke((e=Le(this.defaults,e)).baseURL,e.url,e.allowAbsoluteUrls),e.params,e.paramsSerializer)}}V.forEach(["delete","get","head","options"],function(e){ct.prototype[e]=function(t,n){return this.request(Le(n||{},{method:e,url:t,data:(n||{}).data}))}}),V.forEach(["post","put","patch"],function(e){function t(t){return function(n,r,o){return this.request(Le(o||{},{method:e,headers:t?{"Content-Type":"multipart/form-data"}:{},url:n,data:r}))}}ct.prototype[e]=t(),ct.prototype[e+"Form"]=t(!0)});var lt=ct;class ut{constructor(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");let t;this.promise=new Promise(function(e){t=e});const n=this;this.promise.then(e=>{if(!n._listeners)return;let t=n._listeners.length;for(;t-- >0;)n._listeners[t](e);n._listeners=null}),this.promise.then=e=>{let t;const r=new Promise(e=>{n.subscribe(e),t=e}).then(e);return r.cancel=function(){n.unsubscribe(t)},r},e(function(e,r,o){n.reason||(n.reason=new je(e,r,o),t(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(e){this.reason?e(this.reason):this._listeners?this._listeners.push(e):this._listeners=[e]}unsubscribe(e){if(!this._listeners)return;const t=this._listeners.indexOf(e);-1!==t&&this._listeners.splice(t,1)}toAbortSignal(){const e=new AbortController,t=t=>{e.abort(t)};return this.subscribe(t),e.signal.unsubscribe=()=>this.unsubscribe(t),e.signal}static source(){let e;return{token:new ut(function(t){e=t}),cancel:e}}}var dt=ut;const ft={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511,WebServerIsDown:521,ConnectionTimedOut:522,OriginIsUnreachable:523,TimeoutOccurred:524,SslHandshakeFailed:525,InvalidSslCertificate:526};Object.entries(ft).forEach(([e,t])=>{ft[t]=e});var ht=ft;const pt=function e(t){const n=new lt(t),o=r(lt.prototype.request,n);return V.extend(o,lt.prototype,n,{allOwnKeys:!0}),V.extend(o,n,null,{allOwnKeys:!0}),o.create=function(n){return e(Le(t,n))},o}(ye);pt.Axios=lt,pt.CanceledError=je,pt.CancelToken=dt,pt.isCancel=xe,pt.VERSION=rt,pt.toFormData=te,pt.AxiosError=J,pt.Cancel=pt.CanceledError,pt.all=function(e){return Promise.all(e)},pt.spread=function(e){return function(t){return e.apply(null,t)}},pt.isAxiosError=function(e){return V.isObject(e)&&!0===e.isAxiosError},pt.mergeConfig=Le,pt.AxiosHeaders=Ae,pt.formToJSON=e=>we(V.isHTMLForm(e)?new FormData(e):e),pt.getAdapter=et,pt.HttpStatusCode=ht,pt.default=pt,e.exports=pt},436:function(e,t,n){var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.VoidAIBridgeClient=void 0;const o=r(n(425));t.VoidAIBridgeClient=class{constructor(e){this.config=e,this.client=o.default.create({timeout:1e4,headers:{"Content-Type":"application/json","x-api-key":this.config.apiKey}})}getUrl(e){return`${this.config.getBaseUrl().replace(/\/$/,"")}/${e.replace(/^\//,"")}`}async get(e,t){const n=this.getUrl(e);try{return(await this.client.get(n,{params:t})).data}catch(e){throw this.handleError(e),e}}async post(e,t){const n=this.getUrl(e);try{return(await this.client.post(n,t)).data}catch(e){throw this.handleError(e),e}}async getSupportedChains(e){const t={};return void 0!==e?.isActive&&(t.is_active=String(e.isActive)),void 0!==e?.isCcipSupported&&(t.is_ccip_supported=String(e.isCcipSupported)),void 0!==e?.chainId&&(t.chain_id=e.chainId),(await this.get("api/chains",t)).chains}async getAssetList(e){const t=await this.get("api/asset");return void 0!==e?t.assets.filter(t=>t.chainId===e):t.assets}handleError(e){o.default.isAxiosError(e)?console.error("Bridge API Error:",e.response?.data||e.message):console.error("Unexpected Error:",e)}}},570:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.BittensorWallet=void 0,t.BittensorWallet=class{constructor(){this.extension=null,this.account=null,this.extensionName=null}async connect(e){if("undefined"==typeof window)throw new Error("BittensorWallet: Browser environment required for wallet connection");if(void 0===window.injectedWeb3)throw new Error("No compatible wallet extension found. Please install Talisman, Subwallet, or Polkadot.js extension.");const t=window.injectedWeb3,n=["talisman","subwallet-js","polkadot-js"];let r,o,i=null,s="";if(e&&t[e])i=t[e],s=e;else{for(const e of n)if(t[e]){i=t[e],s=e;break}if(!i){const e=Object.keys(t);if(!(e.length>0))throw new Error("No compatible wallet extension found.");s=e[0],i=t[s]}}try{r=await i.enable("VoidAI Bridge SDK")}catch(e){if(e.message&&e.message.includes("authorised"))throw new Error("No accounts are authorized. Please authorize accounts in your wallet extension and try again.");throw new Error(`Failed to enable wallet extension: ${e.message||e}`)}if(!r)throw new Error("Failed to enable wallet extension. Please try again.");try{o=await r.accounts.get()}catch(e){throw new Error(`Failed to get accounts: ${e.message||e}`)}if(0===o.length)throw new Error("No accounts found. Please authorize at least one account in your wallet extension and try again.");this.extension=r;const a=o[0];return this.account=a,this.extensionName=s,a}getAccount(){return this.account}getExtensionName(){return this.extensionName}isConnected(){return null!==this.account&&null!==this.extension}disconnect(){this.extension=null,this.account=null,this.extensionName=null}static isExtensionAvailable(e){if("undefined"==typeof window)return!1;const t=window.injectedWeb3;return!!t&&(e?!!t[e]:["talisman","subwallet-js","polkadot-js"].some(e=>!!t[e])||Object.keys(t).length>0)}getExtension(){return this.extension}}},574:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0})},925:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.Bridge=void 0,t.Bridge=class{constructor(e){this.apiClient=e}async getTransactionStatus(e){const{status:t}=await this.apiClient.get(`/transactions/${e}/status`);return t}async getHistory(e){return this.apiClient.get(`/transactions/history/${e}`)}}},967:(e,t)=>{Object.defineProperty(t,"__esModule",{value:!0}),t.EthereumWallet=void 0;class n{constructor(){this.account=null,this.chainId=null}static isMetaMaskInstalled(){return"undefined"!=typeof window&&void 0!==window.ethereum&&window.ethereum.isMetaMask}async connect(){if("undefined"==typeof window)throw new Error("EthereumWallet: Browser environment required");if(!n.isMetaMaskInstalled())throw new Error("MetaMask is not installed. Please install MetaMask extension from https://metamask.io/");const e=window.ethereum;try{const t=await e.request({method:"eth_requestAccounts"});if(!t||0===t.length)throw new Error("No accounts found. Please unlock MetaMask and try again.");const n=await e.request({method:"eth_chainId"});return this.account={address:t[0],chainId:n},this.chainId=n,e.on("accountsChanged",this.handleAccountsChanged.bind(this)),e.on("chainChanged",this.handleChainChanged.bind(this)),this.account}catch(e){if(4001===e.code)throw new Error("User rejected the connection request");throw new Error(`Failed to connect to MetaMask: ${e.message||e}`)}}getAccount(){return this.account}getChainId(){return this.chainId}isConnected(){return null!==this.account}disconnect(){this.account=null,this.chainId=null}getProvider(){return"undefined"==typeof window?null:window.ethereum}handleAccountsChanged(e){0===e.length?this.disconnect():this.account&&e[0]!==this.account.address&&(this.account.address=e[0])}handleChainChanged(e){this.chainId=e,this.account&&(this.account.chainId=e)}}t.EthereumWallet=n}},t={};function n(r){var o=t[r];if(void 0!==o)return o.exports;var i=t[r]={exports:{}};return e[r].call(i.exports,i,i.exports,n),i.exports}return n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n(156)})());
@@ -0,0 +1 @@
1
+ /*! Axios v1.13.2 Copyright (c) 2025 Matt Zabriskie and contributors */
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "voidai-sdk",
3
+ "version": "0.1.0",
4
+ "description": "TypeScript SDK for VoidAI Bridge - Blockchain wallet authentication and API integration",
5
+ "main": "dist/index.js",
6
+ "browser": "dist-browser/voidai-sdk.js",
7
+ "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "dist-browser",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "tsc",
15
+ "build:browser": "webpack",
16
+ "build:all": "npm run build && npm run build:browser",
17
+ "test": "jest",
18
+ "lint": "eslint src/**/*.ts",
19
+ "prepare": "npm run build:all",
20
+ "prepublishOnly": "npm test"
21
+ },
22
+ "keywords": [
23
+ "blockchain",
24
+ "bridge",
25
+ "sdk",
26
+ "typescript",
27
+ "voidai",
28
+ "polkadot",
29
+ "ethereum",
30
+ "wallet",
31
+ "authentication"
32
+ ],
33
+ "author": "VoidAI",
34
+ "license": "MIT",
35
+ "repository": {
36
+ "type": "git",
37
+ "url": "https://github.com/your-org/bridge-sdk"
38
+ },
39
+ "devDependencies": {
40
+ "@types/jest": "^29.5.12",
41
+ "@types/node": "^20.11.24",
42
+ "eslint": "^8.57.0",
43
+ "jest": "^29.7.0",
44
+ "ts-jest": "^29.1.2",
45
+ "ts-loader": "^9.5.4",
46
+ "typescript": "^5.3.3",
47
+ "webpack": "^5.103.0",
48
+ "webpack-cli": "^6.0.1"
49
+ },
50
+ "dependencies": {
51
+ "axios": "^1.6.7",
52
+ "cors": "^2.8.5",
53
+ "zod": "^3.22.4"
54
+ }
55
+ }