# Wonky Ord API Sample Implementations

This document provides sample implementations for interacting with the Wonky Ord API in various programming languages.

## JavaScript (Node.js) Implementation

```javascript
// api-client.js
const axios = require('axios');

class WonkyOrdClient {
    constructor(baseURL = 'https://junkinals.junk-coin.com') {
        this.baseURL = baseURL;
        this.client = axios.create({ baseURL });
    }

    // Block Operations
    async getBlockCount() {
        const response = await this.client.get('/block-count');
        return response.data;
    }

    async getBlock(query) {
        const response = await this.client.get(`/block/${query}`);
        return response.data;
    }

    async getBlocksRange(start, end, options = {}) {
        const params = new URLSearchParams(options);
        const response = await this.client.get(`/blocks/${start}/${end}?${params}`);
        return response.data;
    }

    // Transaction Operations
    async getTransaction(txid, json = false) {
        const response = await this.client.get(`/tx/${txid}`, {
            params: { json }
        });
        return response.data;
    }

    // Balance Operations
    async getUtxoBalance(address, options = {}) {
        const response = await this.client.get(`/utxos/balance/${address}`, {
            params: options
        });
        return response.data;
    }

    // JKC20 Operations
    async getJkc20Balance(address, options = {}) {
        const response = await this.client.get(`/jkc20/balance/${address}`, {
            params: options
        });
        return response.data;
    }

    // Dune Operations
    async getDuneBalance(address, options = {}) {
        const response = await this.client.get(`/dunes/balance/${address}`, {
            params: options
        });
        return response.data;
    }

    // Inscription Operations
    async getInscription(inscriptionId, json = false) {
        const response = await this.client.get(`/inscription/${inscriptionId}`, {
            params: { json }
        });
        return response.data;
    }
}

// Usage Example
async function main() {
    const client = new WonkyOrdClient();

    try {
        // Get block count
        const blockCount = await client.getBlockCount();
        console.log('Current block count:', blockCount);

        // Get UTXO balance for address
        const balance = await client.getUtxoBalance('YOUR_ADDRESS', {
            show_all: true,
            limit: 10
        });
        console.log('Balance:', balance);

        // Get JKC20 balance
        const jkc20Balance = await client.getJkc20Balance('YOUR_ADDRESS', {
            tick: 'EXAMPLE',
            show_utxos: true
        });
        console.log('JKC20 Balance:', jkc20Balance);

    } catch (error) {
        console.error('Error:', error.message);
    }
}

main();
```

## Python Implementation

```python
# wonky_ord_client.py
import requests
from typing import Dict, Optional, Any
from urllib.parse import urljoin

class WonkyOrdClient:
    def __init__(self, base_url: str = 'https://junkinals.junk-coin.com'):
        self.base_url = base_url

    def _make_request(self, endpoint: str, params: Optional[Dict] = None) -> Any:
        url = urljoin(self.base_url, endpoint)
        response = requests.get(url, params=params)
        response.raise_for_status()
        return response.json() if 'application/json' in response.headers.get('content-type', '') else response.text

    def get_block_count(self) -> str:
        return self._make_request('/block-count')

    def get_block(self, query: str) -> str:
        return self._make_request(f'/block/{query}')

    def get_blocks_range(self, start: int, end: int, **options) -> list:
        return self._make_request(f'/blocks/{start}/{end}', params=options)

    def get_transaction(self, txid: str, json: bool = False) -> Any:
        return self._make_request(f'/tx/{txid}', params={'json': json})

    def get_utxo_balance(self, address: str, **options) -> Dict:
        return self._make_request(f'/utxos/balance/{address}', params=options)

    def get_jkc20_balance(self, address: str, **options) -> Dict:
        return self._make_request(f'/jkc20/balance/{address}', params=options)

    def get_dune_balance(self, address: str, **options) -> Dict:
        return self._make_request(f'/dunes/balance/{address}', params=options)

    def get_inscription(self, inscription_id: str, json: bool = False) -> Any:
        return self._make_request(f'/inscription/{inscription_id}', params={'json': json})

# Usage Example
def main():
    client = WonkyOrdClient()

    try:
        # Get block count
        block_count = client.get_block_count()
        print(f"Current block count: {block_count}")

        # Get UTXO balance
        balance = client.get_utxo_balance(
            "YOUR_ADDRESS",
            show_all=True,
            limit=10
        )
        print(f"Balance: {balance}")

        # Get JKC20 balance
        jkc20_balance = client.get_jkc20_balance(
            "YOUR_ADDRESS",
            tick="EXAMPLE",
            show_utxos=True
        )
        print(f"JKC20 Balance: {jkc20_balance}")

    except requests.exceptions.RequestException as e:
        print(f"Error: {e}")

if __name__ == "__main__":
    main()
```

## Curl Examples

```bash
# Get block count
curl -X GET "https://junkinals.junk-coin.com/block-count"

# Get block by height or hash
curl -X GET "https://junkinals.junk-coin.com/block/123456"

# Get UTXO balance for address
curl -X GET "https://junkinals.junk-coin.com/utxos/balance/YOUR_ADDRESS?show_all=true&limit=10"

# Get JKC20 balance
curl -X GET "https://junkinals.junk-coin.com/jkc20/balance/YOUR_ADDRESS?tick=EXAMPLE&show_utxos=true"

# Get inscription details
curl -X GET "https://junkinals.junk-coin.com/inscription/YOUR_INSCRIPTION_ID?json=true"

# Get dune balance
curl -X GET "https://junkinals.junk-coin.com/dunes/balance/YOUR_ADDRESS?show_all=true"
```

## Error Handling Examples

### JavaScript
```javascript
async function safeApiCall() {
    try {
        const client = new WonkyOrdClient();
        const result = await client.getBlockCount();
        return result;
    } catch (error) {
        if (error.response) {
            // The request was made and the server responded with a status code
            // that falls out of the range of 2xx
            console.error('Error response:', error.response.data);
            console.error('Status code:', error.response.status);
        } else if (error.request) {
            // The request was made but no response was received
            console.error('No response received:', error.request);
        } else {
            // Something happened in setting up the request
            console.error('Error:', error.message);
        }
        throw error;
    }
}
```

### Python
```python
def safe_api_call():
    try:
        client = WonkyOrdClient()
        result = client.get_block_count()
        return result
    except requests.exceptions.HTTPError as e:
        # Handle HTTP errors (4xx, 5xx)
        print(f"HTTP Error: {e.response.status_code} - {e.response.text}")
        raise
    except requests.exceptions.ConnectionError:
        # Handle connection errors
        print("Connection Error: Could not connect to the API")
        raise
    except requests.exceptions.Timeout:
        # Handle timeout errors
        print("Timeout Error: The request timed out")
        raise
    except requests.exceptions.RequestException as e:
        # Handle any other requests-related errors
        print(f"Error: {e}")
        raise
```

## Rate Limiting Implementation

### JavaScript
```javascript
class RateLimitedClient extends WonkyOrdClient {
    constructor(baseURL, requestsPerSecond = 2) {
        super(baseURL);
        this.queue = [];
        this.processing = false;
        this.interval = 1000 / requestsPerSecond;
    }

    async processQueue() {
        if (this.processing || this.queue.length === 0) return;
        
        this.processing = true;
        while (this.queue.length > 0) {
            const { method, args, resolve, reject } = this.queue.shift();
            try {
                const result = await super[method](...args);
                resolve(result);
            } catch (error) {
                reject(error);
            }
            await new Promise(resolve => setTimeout(resolve, this.interval));
        }
        this.processing = false;
    }

    async makeRequest(method, ...args) {
        return new Promise((resolve, reject) => {
            this.queue.push({ method, args, resolve, reject });
            this.processQueue();
        });
    }

    getBlockCount() {
        return this.makeRequest('getBlockCount');
    }

    getBlock(query) {
        return this.makeRequest('getBlock', query);
    }

    // Add other methods as needed
}
```

### Python
```python
import time
from threading import Lock

class RateLimitedClient(WonkyOrdClient):
    def __init__(self, base_url: str = 'https://junkinals.junk-coin.com', requests_per_second: int = 2):
        super().__init__(base_url)
        self.interval = 1.0 / requests_per_second
        self.last_request_time = 0
        self.lock = Lock()

    def _make_request(self, endpoint: str, params: Optional[Dict] = None) -> Any:
        with self.lock:
            # Calculate time to wait
            now = time.time()
            time_since_last_request = now - self.last_request_time
            if time_since_last_request < self.interval:
                time.sleep(self.interval - time_since_last_request)

            # Make the request
            response = super()._make_request(endpoint, params)
            self.last_request_time = time.time()
            return response
```

These implementations provide a foundation for interacting with the Wonky Ord API. They include:

1. Basic API client implementations in JavaScript and Python
2. Curl examples for quick testing
3. Proper error handling examples
4. Rate limiting implementation to prevent API abuse
5. Type hints (in Python) and JSDoc comments for better code documentation

To use these implementations:

1. For JavaScript:
   ```bash
   npm install axios
   ```

2. For Python:
   ```bash
   pip install requests
   ```

3. Replace `'YOUR_ADDRESS'` and other placeholder values with actual values when making API calls.

Remember to handle errors appropriately and implement proper rate limiting in production environments.
