From d9c37969c652d394502af99e98d1914e9f63094a Mon Sep 17 00:00:00 2001 From: Promise Raji Date: Tue, 4 Aug 2026 14:51:57 +0100 Subject: [PATCH] chore: adding dist directory to gitignore and removing them from version control --- .gitignore | 2 +- cli/dist/index.js | 138 -------- cli/dist/utils/config.js | 31 -- indexer/dist/api.js | 51 --- indexer/dist/index.js | 22 -- indexer/dist/indexer.js | 128 -------- react/dist/index.d.mts | 140 -------- react/dist/index.d.ts | 140 -------- react/dist/index.js | 679 --------------------------------------- react/dist/index.mjs | 630 ------------------------------------ 10 files changed, 1 insertion(+), 1960 deletions(-) delete mode 100755 cli/dist/index.js delete mode 100644 cli/dist/utils/config.js delete mode 100644 indexer/dist/api.js delete mode 100644 indexer/dist/index.js delete mode 100644 indexer/dist/indexer.js delete mode 100644 react/dist/index.d.mts delete mode 100644 react/dist/index.d.ts delete mode 100644 react/dist/index.js delete mode 100644 react/dist/index.mjs diff --git a/.gitignore b/.gitignore index a6b89b0d..a1e67da7 100644 --- a/.gitignore +++ b/.gitignore @@ -9,7 +9,7 @@ # Node / SDK node_modules/ -sdk/dist/ +dist/ sdk/*.tgz # Environment diff --git a/cli/dist/index.js b/cli/dist/index.js deleted file mode 100755 index d8f59b33..00000000 --- a/cli/dist/index.js +++ /dev/null @@ -1,138 +0,0 @@ -#!/usr/bin/env node -import { Command } from 'commander'; -import chalk from 'chalk'; -import { bcForgeClient } from '@bc-forge/sdk'; -import { Keypair } from '@stellar/stellar-sdk'; -import config, { getClientConfig, getSecretKey } from './utils/config.js'; -const program = new Command(); -program - .name('bc-forge') - .description('Administrative CLI for bc-forge token contracts') - .version('1.0.0'); -// ─── Config Commands ──────────────────────────────────────────────────────── -const configCmd = program.command('config').description('Manage CLI configuration'); -configCmd - .command('set ') - .description('Set a configuration value (rpcUrl, networkPassphrase, contractId, secretKey)') - .action((key, value) => { - config.set(key, value); - console.log(chalk.green(`✓ Set ${key} to ${value}`)); -}); -configCmd - .command('list') - .description('List current configuration') - .action(() => { - console.log(chalk.blue('Current Configuration:')); - console.log(config.store); -}); -// ─── Token Commands ───────────────────────────────────────────────────────── -program - .command('balance
') - .description('Check token balance for an address') - .action(async (address) => { - try { - const client = new bcForgeClient(getClientConfig()); - const balance = await client.getBalance(address); - console.log(chalk.cyan(`Balance for ${address}: `) + chalk.white(balance.toString())); - } - catch (err) { - console.error(chalk.red(`Error: ${err.message}`)); - } -}); -program - .command('initialize') - .description('Initialize a new token contract') - .requiredOption('--admin
', 'Admin address') - .requiredOption('--decimals ', 'Decimal places', '7') - .requiredOption('--name ', 'Token name') - .requiredOption('--symbol ', 'Token symbol') - .action(async (options) => { - try { - const secret = getSecretKey(); - if (!secret) - throw new Error('Secret key not configured. Use `bc-forge config set secretKey `'); - const source = Keypair.fromSecret(secret); - const client = new bcForgeClient(getClientConfig()); - console.log(chalk.yellow('Initializing contract...')); - const result = await client.initialize(options.admin, parseInt(options.decimals), options.name, options.symbol, source); - if (result.success) { - console.log(chalk.green(`✓ Contract initialized. TX: ${result.hash}`)); - } - else { - console.log(chalk.red(`✗ Initialization failed. TX: ${result.hash}`)); - } - } - catch (err) { - console.error(chalk.red(`Error: ${err.message}`)); - } -}); -program - .command('mint ') - .description('Mint tokens to an address') - .action(async (to, amount) => { - try { - const secret = getSecretKey(); - if (!secret) - throw new Error('Secret key not configured'); - const source = Keypair.fromSecret(secret); - const client = new bcForgeClient(getClientConfig()); - console.log(chalk.yellow(`Minting ${amount} tokens to ${to}...`)); - const result = await client.mint(to, BigInt(amount), source); - if (result.success) { - console.log(chalk.green(`✓ Minted successfully. TX: ${result.hash}`)); - } - else { - console.log(chalk.red('✗ Minting failed.')); - } - } - catch (err) { - console.error(chalk.red(`Error: ${err.message}`)); - } -}); -program - .command('pause') - .description('Pause token operations') - .action(async () => { - try { - const secret = getSecretKey(); - if (!secret) - throw new Error('Secret key not configured'); - const source = Keypair.fromSecret(secret); - const client = new bcForgeClient(getClientConfig()); - console.log(chalk.yellow('Pausing contract...')); - const result = await client.pause(source); - if (result.success) { - console.log(chalk.green(`✓ Contract paused. TX: ${result.hash}`)); - } - else { - console.log(chalk.red('✗ Pause failed.')); - } - } - catch (err) { - console.error(chalk.red(`Error: ${err.message}`)); - } -}); -program - .command('unpause') - .description('Unpause token operations') - .action(async () => { - try { - const secret = getSecretKey(); - if (!secret) - throw new Error('Secret key not configured'); - const source = Keypair.fromSecret(secret); - const client = new bcForgeClient(getClientConfig()); - console.log(chalk.yellow('Unpausing contract...')); - const result = await client.unpause(source); - if (result.success) { - console.log(chalk.green(`✓ Contract unpaused. TX: ${result.hash}`)); - } - else { - console.log(chalk.red('✗ Unpause failed.')); - } - } - catch (err) { - console.error(chalk.red(`Error: ${err.message}`)); - } -}); -program.parse(); diff --git a/cli/dist/utils/config.js b/cli/dist/utils/config.js deleted file mode 100644 index 9684f963..00000000 --- a/cli/dist/utils/config.js +++ /dev/null @@ -1,31 +0,0 @@ -import Conf from 'conf'; -import dotenv from 'dotenv'; -dotenv.config(); -const schema = { - rpcUrl: { - type: 'string', - default: 'https://soroban-testnet.stellar.org' - }, - networkPassphrase: { - type: 'string', - default: 'Test SDF Network ; September 2015' - }, - contractId: { - type: 'string', - }, - secretKey: { - type: 'string', - } -}; -const config = new Conf({ schema, projectName: 'bc-forge-cli' }); -export function getClientConfig() { - return { - rpcUrl: (process.env.RPC_URL || config.get('rpcUrl')), - networkPassphrase: (process.env.NETWORK_PASSPHRASE || config.get('networkPassphrase')), - contractId: (process.env.CONTRACT_ID || config.get('contractId')), - }; -} -export function getSecretKey() { - return (process.env.SECRET_KEY || config.get('secretKey')); -} -export default config; diff --git a/indexer/dist/api.js b/indexer/dist/api.js deleted file mode 100644 index a4995887..00000000 --- a/indexer/dist/api.js +++ /dev/null @@ -1,51 +0,0 @@ -import express from 'express'; -import { PrismaClient } from '@prisma/client'; -const prisma = new PrismaClient(); -const router = express.Router(); -/** - * GET /mints - * Retrieve mint logs. - */ -router.get('/mints', async (req, res) => { - const mints = await prisma.mint.findMany({ - orderBy: { createdAt: 'desc' }, - }); - res.json(mints); -}); -/** - * GET /transfers - * Retrieve transfer logs. - */ -router.get('/transfers', async (req, res) => { - const transfers = await prisma.transfer.findMany({ - orderBy: { createdAt: 'desc' }, - }); - res.json(transfers); -}); -/** - * GET /burns - * Retrieve burn logs. - */ -router.get('/burns', async (req, res) => { - const burns = await prisma.burn.findMany({ - orderBy: { createdAt: 'desc' }, - }); - res.json(burns); -}); -/** - * GET /stats - * Retrieve basic token operation stats. - */ -router.get('/stats', async (req, res) => { - const [mintCount, transferCount, burnCount] = await Promise.all([ - prisma.mint.count(), - prisma.transfer.count(), - prisma.burn.count(), - ]); - res.json({ - mintCount, - transferCount, - burnCount, - }); -}); -export default router; diff --git a/indexer/dist/index.js b/indexer/dist/index.js deleted file mode 100644 index 3e661285..00000000 --- a/indexer/dist/index.js +++ /dev/null @@ -1,22 +0,0 @@ -import express from 'express'; -import { runIndexer } from './indexer'; -import apiRouter from './api'; -import dotenv from 'dotenv'; -dotenv.config(); -const app = express(); -const PORT = process.env.PORT || 3000; -app.use(express.json()); -// API Layer -app.use('/api/v1', apiRouter); -// Health check -app.get('/health', (req, res) => { - res.json({ status: 'ok' }); -}); -app.listen(PORT, () => { - console.log(`Indexer microservice API listening on port ${PORT}`); - // Start the indexer background process - runIndexer().catch(err => { - console.error('Fatal indexer error:', err); - process.exit(1); - }); -}); diff --git a/indexer/dist/indexer.js b/indexer/dist/indexer.js deleted file mode 100644 index aa3ca9d9..00000000 --- a/indexer/dist/indexer.js +++ /dev/null @@ -1,128 +0,0 @@ -import { rpc as SorobanRpc, scValToNative } from '@stellar/stellar-sdk'; -import { PrismaClient } from '@prisma/client'; -import dotenv from 'dotenv'; -dotenv.config(); -const prisma = new PrismaClient(); -const RPC_URL = process.env.RPC_URL || 'https://soroban-testnet.stellar.org'; -const CONTRACT_ID = process.env.CONTRACT_ID; -if (!CONTRACT_ID) { - throw new Error('CONTRACT_ID environment variable is required'); -} -const server = new SorobanRpc.Server(RPC_URL); -/** - * Main indexer loop to fetch and process Soroban events. - */ -export async function runIndexer() { - console.log(`Starting indexer for contract: ${CONTRACT_ID}`); - // 1. Get the last indexed ledger - let lastLedger = await prisma.lastIndexedLedger.findUnique({ where: { id: 1 } }); - let startLedger = lastLedger ? lastLedger.ledger + 1 : 0; - // 2. Continuous loop - while (true) { - try { - const currentLedger = (await server.getLatestLedger()).sequence; - if (startLedger > currentLedger) { - // Wait for new ledgers - await new Promise(resolve => setTimeout(resolve, 5000)); - continue; - } - const endLedger = Math.min(startLedger + 1000, currentLedger); - console.log(`Indexing ledgers: ${startLedger} to ${endLedger}`); - const response = await server.getEvents({ - startLedger: startLedger, - filters: [ - { - type: 'contract', - contractIds: [CONTRACT_ID], - }, - ], - }); - for (const event of response.events) { - await processEvent(event); - } - // Update last indexed ledger - await prisma.lastIndexedLedger.upsert({ - where: { id: 1 }, - update: { ledger: endLedger }, - create: { id: 1, ledger: endLedger }, - }); - startLedger = endLedger + 1; - // Small delay to avoid hammering the RPC - await new Promise(resolve => setTimeout(resolve, 1000)); - } - catch (error) { - console.error('Indexer error:', error); - await new Promise(resolve => setTimeout(resolve, 5000)); - } - } -} -async function processEvent(event) { - if (!event.topic || event.topic.length === 0) - return; - const topic = scValToNative(event.topic[0]); - const data = event.value; - try { - switch (topic) { - case 'mint': { - const decoded = scValToNative(data); - // (admin, to, amount, new_balance, new_supply) - await prisma.mint.create({ - data: { - to: decoded[1], - amount: decoded[2].toString(), - ledger: event.ledger, - txHash: event.txHash, - }, - }); - break; - } - case 'burn': { - const decoded = scValToNative(data); - // (from, amount, new_balance, new_supply) - await prisma.burn.create({ - data: { - from: decoded[0], - amount: decoded[1].toString(), - ledger: event.ledger, - txHash: event.txHash, - }, - }); - break; - } - case 'xfer': { - const decoded = scValToNative(data); - // (from, to, amount) - await prisma.transfer.create({ - data: { - from: decoded[0], - to: decoded[1], - amount: decoded[2].toString(), - ledger: event.ledger, - txHash: event.txHash, - }, - }); - break; - } - case 'xfer_frm': { - const decoded = scValToNative(data); - // (spender, from, to, amount, remaining_allowance) - await prisma.transfer.create({ - data: { - from: decoded[1], - to: decoded[2], - amount: decoded[3].toString(), - ledger: event.ledger, - txHash: event.txHash, - }, - }); - break; - } - } - } - catch (err) { - // Unique constraint violation might happen if we re-index a ledger - if (err.code !== 'P2002') { - console.error(`Error processing event topic ${topic}:`, err); - } - } -} diff --git a/react/dist/index.d.mts b/react/dist/index.d.mts deleted file mode 100644 index 3c22d5d0..00000000 --- a/react/dist/index.d.mts +++ /dev/null @@ -1,140 +0,0 @@ -import React, { ReactNode } from 'react'; -import * as _bc_forge_sdk from '@bc-forge/sdk'; -import { bcForgeClientConfig, bcForgeClient } from '@bc-forge/sdk'; -import { Keypair } from '@stellar/stellar-sdk'; - -interface BcForgeProviderProps { - config: bcForgeClientConfig; - children: ReactNode; -} -declare const BcForgeProvider: React.FC; -declare const useBcForgeClient: () => bcForgeClient; - -/** - * Hook to fetch basic token information (name, symbol, decimals). - */ -declare function useBcForgeToken(): { - data: { - name: string; - symbol: string; - decimals: number; - } | null; - loading: boolean; - error: Error | null; -}; -/** - * Hook to fetch the balance of a specific address. - */ -declare function useBalance(address: string | undefined): { - data: bigint | null; - loading: boolean; - error: Error | null; - refetch: () => Promise; -}; -/** - * Hook to perform mint operations. - */ -declare function useMint(): { - mint: (to: string, amount: bigint, source: Keypair) => Promise<_bc_forge_sdk.TransactionResult>; - loading: boolean; - error: Error | null; -}; -/** - * Hook to fetch the total supply of the token. - */ -declare function useTotalSupply(): { - data: bigint | null; - loading: boolean; - error: Error | null; - refetch: () => Promise; -}; -/** - * Hook to perform transfer operations. - */ -declare function useTransfer(): { - transfer: (from: string, to: string, amount: bigint, source: Keypair) => Promise<_bc_forge_sdk.TransactionResult>; - loading: boolean; - error: Error | null; -}; -/** - * Hook to perform approve operations. - */ -declare function useApprove(): { - approve: (from: string, spender: string, amount: bigint, source: Keypair) => Promise<_bc_forge_sdk.TransactionResult>; - loading: boolean; - error: Error | null; -}; -/** - * Hook to perform burn operations. - */ -declare function useBurn(): { - burn: (from: string, amount: bigint, source: Keypair) => Promise<_bc_forge_sdk.TransactionResult>; - loading: boolean; - error: Error | null; -}; -/** - * Hook to fetch the allowance between owner and spender. - */ -declare function useAllowance(owner: string | undefined, spender: string | undefined): { - data: bigint | null; - loading: boolean; - error: Error | null; - refetch: () => Promise; -}; - -type AlertVariant = 'info' | 'success' | 'warning' | 'danger'; -interface AlertProps extends Omit, 'title'> { - /** Visual + semantic style of the alert. @default 'info' */ - variant?: AlertVariant; - /** Optional bold title rendered above the content. */ - title?: React.ReactNode; - /** When provided, renders a dismiss button that calls this handler. */ - onDismiss?: () => void; - /** Accessible label for the dismiss button. @default 'Dismiss alert' */ - dismissLabel?: string; -} -/** Alert banner; role is "alert" for danger/warning and "status" otherwise. */ -declare const Alert: React.ForwardRefExoticComponent>; - -type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'; -type BadgeSize = 'sm' | 'md' | 'lg'; -interface BadgeProps extends React.HTMLAttributes { - /** Visual variant of the badge. @default 'default' */ - variant?: BadgeVariant; - /** Size of the badge. @default 'md' */ - size?: BadgeSize; -} -/** Badge label. When `onClick` is provided the element becomes a - * keyboard-focusable interactive control (role="button", tabIndex={0}, - * Enter/Space activation). Pass explicit `role` or `tabIndex` to override. */ -declare const Badge: React.ForwardRefExoticComponent>; - -type DropdownVariant = 'default' | 'primary' | 'danger'; -type DropdownSize = 'sm' | 'md' | 'lg'; -interface DropdownItem { - label: string; - value: string; - disabled?: boolean; -} -interface DropdownProps extends Omit, 'onChange'> { - /** Array of menu items to display. */ - items: DropdownItem[]; - /** Controlled selected value. */ - value?: string; - /** Initial selected value (uncontrolled). */ - defaultValue?: string; - /** Called when an item is selected. */ - onChange?: (item: DropdownItem) => void; - /** Visual style variant. @default 'default' */ - variant?: DropdownVariant; - /** Size. @default 'md' */ - size?: DropdownSize; - /** Placeholder when no item is selected. @default 'Select...' */ - placeholder?: string; - /** Disables the entire dropdown. */ - disabled?: boolean; -} -/** Reusable dropdown menu with full keyboard navigation and ARIA support. */ -declare const Dropdown: React.ForwardRefExoticComponent>; - -export { Alert, type AlertProps, type AlertVariant, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, BcForgeProvider, type BcForgeProviderProps, Dropdown, type DropdownItem, type DropdownProps, type DropdownSize, type DropdownVariant, useAllowance, useApprove, useBalance, useBcForgeClient, useBcForgeToken, useBurn, useMint, useTotalSupply, useTransfer }; diff --git a/react/dist/index.d.ts b/react/dist/index.d.ts deleted file mode 100644 index 3c22d5d0..00000000 --- a/react/dist/index.d.ts +++ /dev/null @@ -1,140 +0,0 @@ -import React, { ReactNode } from 'react'; -import * as _bc_forge_sdk from '@bc-forge/sdk'; -import { bcForgeClientConfig, bcForgeClient } from '@bc-forge/sdk'; -import { Keypair } from '@stellar/stellar-sdk'; - -interface BcForgeProviderProps { - config: bcForgeClientConfig; - children: ReactNode; -} -declare const BcForgeProvider: React.FC; -declare const useBcForgeClient: () => bcForgeClient; - -/** - * Hook to fetch basic token information (name, symbol, decimals). - */ -declare function useBcForgeToken(): { - data: { - name: string; - symbol: string; - decimals: number; - } | null; - loading: boolean; - error: Error | null; -}; -/** - * Hook to fetch the balance of a specific address. - */ -declare function useBalance(address: string | undefined): { - data: bigint | null; - loading: boolean; - error: Error | null; - refetch: () => Promise; -}; -/** - * Hook to perform mint operations. - */ -declare function useMint(): { - mint: (to: string, amount: bigint, source: Keypair) => Promise<_bc_forge_sdk.TransactionResult>; - loading: boolean; - error: Error | null; -}; -/** - * Hook to fetch the total supply of the token. - */ -declare function useTotalSupply(): { - data: bigint | null; - loading: boolean; - error: Error | null; - refetch: () => Promise; -}; -/** - * Hook to perform transfer operations. - */ -declare function useTransfer(): { - transfer: (from: string, to: string, amount: bigint, source: Keypair) => Promise<_bc_forge_sdk.TransactionResult>; - loading: boolean; - error: Error | null; -}; -/** - * Hook to perform approve operations. - */ -declare function useApprove(): { - approve: (from: string, spender: string, amount: bigint, source: Keypair) => Promise<_bc_forge_sdk.TransactionResult>; - loading: boolean; - error: Error | null; -}; -/** - * Hook to perform burn operations. - */ -declare function useBurn(): { - burn: (from: string, amount: bigint, source: Keypair) => Promise<_bc_forge_sdk.TransactionResult>; - loading: boolean; - error: Error | null; -}; -/** - * Hook to fetch the allowance between owner and spender. - */ -declare function useAllowance(owner: string | undefined, spender: string | undefined): { - data: bigint | null; - loading: boolean; - error: Error | null; - refetch: () => Promise; -}; - -type AlertVariant = 'info' | 'success' | 'warning' | 'danger'; -interface AlertProps extends Omit, 'title'> { - /** Visual + semantic style of the alert. @default 'info' */ - variant?: AlertVariant; - /** Optional bold title rendered above the content. */ - title?: React.ReactNode; - /** When provided, renders a dismiss button that calls this handler. */ - onDismiss?: () => void; - /** Accessible label for the dismiss button. @default 'Dismiss alert' */ - dismissLabel?: string; -} -/** Alert banner; role is "alert" for danger/warning and "status" otherwise. */ -declare const Alert: React.ForwardRefExoticComponent>; - -type BadgeVariant = 'default' | 'primary' | 'success' | 'warning' | 'danger' | 'info'; -type BadgeSize = 'sm' | 'md' | 'lg'; -interface BadgeProps extends React.HTMLAttributes { - /** Visual variant of the badge. @default 'default' */ - variant?: BadgeVariant; - /** Size of the badge. @default 'md' */ - size?: BadgeSize; -} -/** Badge label. When `onClick` is provided the element becomes a - * keyboard-focusable interactive control (role="button", tabIndex={0}, - * Enter/Space activation). Pass explicit `role` or `tabIndex` to override. */ -declare const Badge: React.ForwardRefExoticComponent>; - -type DropdownVariant = 'default' | 'primary' | 'danger'; -type DropdownSize = 'sm' | 'md' | 'lg'; -interface DropdownItem { - label: string; - value: string; - disabled?: boolean; -} -interface DropdownProps extends Omit, 'onChange'> { - /** Array of menu items to display. */ - items: DropdownItem[]; - /** Controlled selected value. */ - value?: string; - /** Initial selected value (uncontrolled). */ - defaultValue?: string; - /** Called when an item is selected. */ - onChange?: (item: DropdownItem) => void; - /** Visual style variant. @default 'default' */ - variant?: DropdownVariant; - /** Size. @default 'md' */ - size?: DropdownSize; - /** Placeholder when no item is selected. @default 'Select...' */ - placeholder?: string; - /** Disables the entire dropdown. */ - disabled?: boolean; -} -/** Reusable dropdown menu with full keyboard navigation and ARIA support. */ -declare const Dropdown: React.ForwardRefExoticComponent>; - -export { Alert, type AlertProps, type AlertVariant, Badge, type BadgeProps, type BadgeSize, type BadgeVariant, BcForgeProvider, type BcForgeProviderProps, Dropdown, type DropdownItem, type DropdownProps, type DropdownSize, type DropdownVariant, useAllowance, useApprove, useBalance, useBcForgeClient, useBcForgeToken, useBurn, useMint, useTotalSupply, useTransfer }; diff --git a/react/dist/index.js b/react/dist/index.js deleted file mode 100644 index 8fcab287..00000000 --- a/react/dist/index.js +++ /dev/null @@ -1,679 +0,0 @@ -"use strict"; -var __create = Object.create; -var __defProp = Object.defineProperty; -var __getOwnPropDesc = Object.getOwnPropertyDescriptor; -var __getOwnPropNames = Object.getOwnPropertyNames; -var __getProtoOf = Object.getPrototypeOf; -var __hasOwnProp = Object.prototype.hasOwnProperty; -var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); -}; -var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; -}; -var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod -)); -var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - -// src/index.ts -var index_exports = {}; -__export(index_exports, { - Alert: () => Alert, - Badge: () => Badge, - BcForgeProvider: () => BcForgeProvider, - Dropdown: () => Dropdown, - useAllowance: () => useAllowance, - useApprove: () => useApprove, - useBalance: () => useBalance, - useBcForgeClient: () => useBcForgeClient, - useBcForgeToken: () => useBcForgeToken, - useBurn: () => useBurn, - useMint: () => useMint, - useTotalSupply: () => useTotalSupply, - useTransfer: () => useTransfer -}); -module.exports = __toCommonJS(index_exports); - -// src/context.tsx -var import_react = require("react"); -var import_sdk = require("@bc-forge/sdk"); -var import_jsx_runtime = require("react/jsx-runtime"); -var bcForgeContext = (0, import_react.createContext)({ client: null }); -var BcForgeProvider = ({ config, children }) => { - const client = (0, import_react.useMemo)(() => new import_sdk.bcForgeClient(config), [config.rpcUrl, config.networkPassphrase, config.contractId]); - return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(bcForgeContext.Provider, { value: { client }, children }); -}; -var useBcForgeClient = () => { - const context = (0, import_react.useContext)(bcForgeContext); - if (!context.client) { - throw new Error("useBcForgeClient must be used within a BcForgeProvider"); - } - return context.client; -}; - -// src/hooks.ts -var import_react2 = require("react"); -function useBcForgeToken() { - const client = useBcForgeClient(); - const [data, setData] = (0, import_react2.useState)(null); - const [loading, setLoading] = (0, import_react2.useState)(true); - const [error, setError] = (0, import_react2.useState)(null); - (0, import_react2.useEffect)(() => { - async function fetchData() { - try { - setLoading(true); - const [name, symbol, decimals] = await Promise.all([ - client.getName(), - client.getSymbol(), - client.getDecimals() - ]); - setData({ name, symbol, decimals }); - } catch (err) { - setError(err instanceof Error ? err : new Error(String(err))); - } finally { - setLoading(false); - } - } - fetchData(); - }, [client]); - return { data, loading, error }; -} -function useBalance(address) { - const client = useBcForgeClient(); - const [data, setData] = (0, import_react2.useState)(null); - const [loading, setLoading] = (0, import_react2.useState)(false); - const [error, setError] = (0, import_react2.useState)(null); - const fetchBalance = (0, import_react2.useCallback)(async () => { - if (!address) return; - try { - setLoading(true); - const balance = await client.getBalance(address); - setData(balance); - } catch (err) { - setError(err instanceof Error ? err : new Error(String(err))); - } finally { - setLoading(false); - } - }, [client, address]); - (0, import_react2.useEffect)(() => { - fetchBalance(); - }, [fetchBalance]); - return { data, loading, error, refetch: fetchBalance }; -} -function useMint() { - const client = useBcForgeClient(); - const [loading, setLoading] = (0, import_react2.useState)(false); - const [error, setError] = (0, import_react2.useState)(null); - const mint = (0, import_react2.useCallback)(async (to, amount, source) => { - try { - setLoading(true); - setError(null); - const result = await client.mint(to, amount, source); - return result; - } catch (err) { - const error2 = err instanceof Error ? err : new Error(String(err)); - setError(error2); - throw error2; - } finally { - setLoading(false); - } - }, [client]); - return { mint, loading, error }; -} -function useTotalSupply() { - const client = useBcForgeClient(); - const [data, setData] = (0, import_react2.useState)(null); - const [loading, setLoading] = (0, import_react2.useState)(false); - const [error, setError] = (0, import_react2.useState)(null); - const fetchTotalSupply = (0, import_react2.useCallback)(async () => { - try { - setLoading(true); - const supply = await client.getTotalSupply(); - setData(supply); - } catch (err) { - setError(err instanceof Error ? err : new Error(String(err))); - } finally { - setLoading(false); - } - }, [client]); - (0, import_react2.useEffect)(() => { - fetchTotalSupply(); - }, [fetchTotalSupply]); - return { data, loading, error, refetch: fetchTotalSupply }; -} -function useTransfer() { - const client = useBcForgeClient(); - const [loading, setLoading] = (0, import_react2.useState)(false); - const [error, setError] = (0, import_react2.useState)(null); - const transfer = (0, import_react2.useCallback)(async (from, to, amount, source) => { - try { - setLoading(true); - setError(null); - const result = await client.transfer(from, to, amount, source); - return result; - } catch (err) { - const error2 = err instanceof Error ? err : new Error(String(err)); - setError(error2); - throw error2; - } finally { - setLoading(false); - } - }, [client]); - return { transfer, loading, error }; -} -function useApprove() { - const client = useBcForgeClient(); - const [loading, setLoading] = (0, import_react2.useState)(false); - const [error, setError] = (0, import_react2.useState)(null); - const approve = (0, import_react2.useCallback)(async (from, spender, amount, source) => { - try { - setLoading(true); - setError(null); - const result = await client.approve(from, spender, amount, source); - return result; - } catch (err) { - const error2 = err instanceof Error ? err : new Error(String(err)); - setError(error2); - throw error2; - } finally { - setLoading(false); - } - }, [client]); - return { approve, loading, error }; -} -function useBurn() { - const client = useBcForgeClient(); - const [loading, setLoading] = (0, import_react2.useState)(false); - const [error, setError] = (0, import_react2.useState)(null); - const burn = (0, import_react2.useCallback)(async (from, amount, source) => { - try { - setLoading(true); - setError(null); - const result = await client.burn(from, amount, source); - return result; - } catch (err) { - const error2 = err instanceof Error ? err : new Error(String(err)); - setError(error2); - throw error2; - } finally { - setLoading(false); - } - }, [client]); - return { burn, loading, error }; -} -function useAllowance(owner, spender) { - const client = useBcForgeClient(); - const [data, setData] = (0, import_react2.useState)(null); - const [loading, setLoading] = (0, import_react2.useState)(false); - const [error, setError] = (0, import_react2.useState)(null); - const fetchAllowance = (0, import_react2.useCallback)(async () => { - if (!owner || !spender) return; - try { - setLoading(true); - const allowance = await client.getAllowance(owner, spender); - setData(allowance); - } catch (err) { - setError(err instanceof Error ? err : new Error(String(err))); - } finally { - setLoading(false); - } - }, [client, owner, spender]); - (0, import_react2.useEffect)(() => { - fetchAllowance(); - }, [fetchAllowance]); - return { data, loading, error, refetch: fetchAllowance }; -} - -// src/components/Alert.tsx -var import_react3 = require("react"); -var import_jsx_runtime2 = require("react/jsx-runtime"); -var VARIANT_STYLES = { - info: { backgroundColor: "#eff6ff", borderColor: "#bfdbfe", color: "#1e40af" }, - success: { backgroundColor: "#f0fdf4", borderColor: "#bbf7d0", color: "#166534" }, - warning: { backgroundColor: "#fffbeb", borderColor: "#fde68a", color: "#92400e" }, - danger: { backgroundColor: "#fef2f2", borderColor: "#fecaca", color: "#991b1b" } -}; -var Alert = (0, import_react3.forwardRef)(function Alert2({ variant = "info", title, onDismiss, dismissLabel = "Dismiss alert", style, children, ...rest }, ref) { - const defaultRole = variant === "danger" || variant === "warning" ? "alert" : "status"; - return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)( - "div", - { - ref, - role: defaultRole, - style: { - display: "flex", - alignItems: "flex-start", - gap: 8, - padding: "12px 14px", - border: "1px solid", - borderRadius: 8, - ...VARIANT_STYLES[variant], - ...style - }, - ...rest, - children: [ - /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { flex: 1, minWidth: 0 }, children: [ - title ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontWeight: 700, marginBottom: 2 }, children: title }) : null, - /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { fontSize: 14 }, children }) - ] }), - onDismiss ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)( - "button", - { - type: "button", - onClick: onDismiss, - "aria-label": dismissLabel, - style: { - flexShrink: 0, - border: "none", - background: "transparent", - cursor: "pointer", - color: "inherit", - fontSize: 18, - lineHeight: 1, - padding: 2 - }, - children: "\xD7" - } - ) : null - ] - } - ); -}); - -// src/components/Badge.tsx -var import_react4 = require("react"); -var import_jsx_runtime3 = require("react/jsx-runtime"); -var VARIANT_STYLES2 = { - default: { backgroundColor: "#f3f4f6", color: "#374151" }, - primary: { backgroundColor: "#eff6ff", color: "#1e40af" }, - success: { backgroundColor: "#f0fdf4", color: "#166534" }, - warning: { backgroundColor: "#fffbeb", color: "#92400e" }, - danger: { backgroundColor: "#fef2f2", color: "#991b1b" }, - info: { backgroundColor: "#ecfeff", color: "#155e75" } -}; -var SIZE_STYLES = { - sm: { fontSize: 11, padding: "1px 6px", borderRadius: 8 }, - md: { fontSize: 12, padding: "2px 8px", borderRadius: 10 }, - lg: { fontSize: 14, padding: "3px 10px", borderRadius: 12 } -}; -var BADGE_BASE = { - display: "inline-flex", - alignItems: "center", - fontWeight: 600, - lineHeight: 1.4, - whiteSpace: "nowrap" -}; -var Badge = (0, import_react4.forwardRef)(function Badge2({ variant = "default", size = "md", style, onClick, onKeyDown, children, ...rest }, ref) { - const isInteractive = Boolean(onClick); - const handleKeyDown = (e) => { - if (isInteractive && (e.key === "Enter" || e.key === " ")) { - e.preventDefault(); - onClick(e); - } - onKeyDown?.(e); - }; - return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)( - "span", - { - ref, - role: isInteractive ? "button" : void 0, - tabIndex: isInteractive ? 0 : void 0, - style: { - ...BADGE_BASE, - ...VARIANT_STYLES2[variant], - ...SIZE_STYLES[size], - ...isInteractive ? { cursor: "pointer" } : {}, - ...style - }, - onClick, - onKeyDown: handleKeyDown, - ...rest, - children - } - ); -}); - -// src/components/Dropdown.tsx -var import_react5 = __toESM(require("react")); -var import_jsx_runtime4 = require("react/jsx-runtime"); -var TRIGGER_BASE = { - display: "flex", - alignItems: "center", - justifyContent: "space-between", - gap: 8, - width: "100%", - border: "1px solid", - borderRadius: 6, - cursor: "pointer", - fontFamily: "inherit", - lineHeight: 1.4, - textAlign: "left", - boxSizing: "border-box", - transition: "border-color 0.15s, box-shadow 0.15s" -}; -var TRIGGER_DISABLED = { - opacity: 0.5, - cursor: "not-allowed" -}; -var SIZE_STYLES2 = { - sm: { fontSize: 12, padding: "5px 8px", minHeight: 28 }, - md: { fontSize: 14, padding: "8px 12px", minHeight: 36 }, - lg: { fontSize: 16, padding: "12px 16px", minHeight: 44 } -}; -var ITEM_SIZE_STYLES = { - sm: { fontSize: 12, padding: "5px 8px" }, - md: { fontSize: 14, padding: "8px 12px" }, - lg: { fontSize: 16, padding: "10px 16px" } -}; -var VARIANT_TRIGGER = { - default: { borderColor: "#d1d5db", backgroundColor: "#ffffff", color: "#111827" }, - primary: { borderColor: "#2563eb", backgroundColor: "#2563eb", color: "#ffffff" }, - danger: { borderColor: "#dc2626", backgroundColor: "#dc2626", color: "#ffffff" } -}; -var VARIANT_FOCUS = { - default: { borderColor: "#6366f1", boxShadow: "0 0 0 2px rgba(99,102,241,0.15)" }, - primary: { boxShadow: "0 0 0 2px rgba(37,99,235,0.3)" }, - danger: { boxShadow: "0 0 0 2px rgba(220,38,38,0.3)" } -}; -var ACTIVE_ITEM = { - default: { backgroundColor: "#f3f4f6" }, - primary: { backgroundColor: "#eff6ff", color: "#2563eb" }, - danger: { backgroundColor: "#fef2f2", color: "#dc2626" } -}; -var MENU_BASE = { - position: "absolute", - top: "100%", - left: 0, - right: 0, - zIndex: 50, - marginTop: 4, - border: "1px solid #d1d5db", - borderRadius: 6, - backgroundColor: "#ffffff", - boxShadow: "0 4px 12px rgba(0, 0, 0, 0.1)", - overflow: "hidden", - boxSizing: "border-box" -}; -var ITEM_BASE = { - display: "block", - width: "100%", - border: "none", - backgroundColor: "transparent", - fontFamily: "inherit", - lineHeight: 1.4, - textAlign: "left", - cursor: "pointer", - boxSizing: "border-box", - transition: "background-color 0.1s" -}; -var ITEM_DISABLED = { - opacity: 0.4, - cursor: "not-allowed" -}; -var WRAPPER_BASE = { - position: "relative", - display: "inline-block" -}; -var ELLIPSIS = { - flex: 1, - minWidth: 0, - overflow: "hidden", - textOverflow: "ellipsis", - whiteSpace: "nowrap" -}; -var CHEVRON = { - display: "inline-block", - border: "solid currentColor", - borderWidth: "0 2px 2px 0", - padding: 3, - transition: "transform 0.15s", - flexShrink: 0 -}; -function findFirstEnabled(items, start = 0) { - for (let i = start; i < items.length; i++) { - if (!items[i].disabled) return i; - } - for (let i = 0; i < start; i++) { - if (!items[i].disabled) return i; - } - return -1; -} -function findLastEnabled(items) { - for (let i = items.length - 1; i >= 0; i--) { - if (!items[i].disabled) return i; - } - return -1; -} -function findPrevEnabled(items, current) { - for (let i = current - 1; i >= 0; i--) { - if (!items[i].disabled) return i; - } - return findLastEnabled(items); -} -function findNextEnabled(items, current) { - for (let i = current + 1; i < items.length; i++) { - if (!items[i].disabled) return i; - } - return findFirstEnabled(items); -} -var Dropdown = (0, import_react5.forwardRef)(function Dropdown2({ - items, - value, - defaultValue, - onChange, - variant = "default", - size = "md", - placeholder = "Select...", - disabled = false, - style, - ...rest -}, ref) { - const [isOpen, setIsOpen] = (0, import_react5.useState)(false); - const [activeIndex, setActiveIndex] = (0, import_react5.useState)(-1); - const [internalValue, setInternalValue] = (0, import_react5.useState)(defaultValue ?? ""); - const isControlled = value !== void 0; - const selectedValue = isControlled ? value : internalValue; - const selectedItem = items.find((item) => item.value === selectedValue); - const wrapperRef = (0, import_react5.useRef)(null); - const triggerRef = (0, import_react5.useRef)(null); - const menuId = import_react5.default.useId(); - function mergeRefs(node) { - wrapperRef.current = node; - if (typeof ref === "function") { - ref(node); - } else if (ref && typeof ref === "object") { - ref.current = node; - } - } - const activeDescendant = activeIndex >= 0 ? `${menuId}-item-${activeIndex}` : void 0; - (0, import_react5.useEffect)(() => { - if (!isOpen) return; - function handleClick(e) { - if (wrapperRef.current && !wrapperRef.current.contains(e.target)) { - setIsOpen(false); - setActiveIndex(-1); - } - } - document.addEventListener("mousedown", handleClick); - return () => document.removeEventListener("mousedown", handleClick); - }, [isOpen]); - function selectItem(item) { - if (item.disabled) return; - if (!isControlled) { - setInternalValue(item.value); - } - onChange?.(item); - setIsOpen(false); - setActiveIndex(-1); - triggerRef.current?.focus(); - } - function handleTriggerClick() { - if (disabled) return; - setIsOpen((prev) => { - if (!prev) { - const idx = selectedItem ? items.indexOf(selectedItem) : -1; - setActiveIndex(idx >= 0 ? idx : findFirstEnabled(items)); - } else { - setActiveIndex(-1); - } - return !prev; - }); - } - function handleKeyDown(e) { - if (disabled) return; - if (!isOpen) { - if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") { - e.preventDefault(); - setIsOpen(true); - setActiveIndex(findFirstEnabled(items)); - } - return; - } - switch (e.key) { - case "Escape": - e.preventDefault(); - setIsOpen(false); - setActiveIndex(-1); - triggerRef.current?.focus(); - break; - case "ArrowDown": - e.preventDefault(); - setActiveIndex((prev) => { - const next = findNextEnabled(items, prev >= 0 ? prev : -1); - return next >= 0 ? next : prev; - }); - break; - case "ArrowUp": - e.preventDefault(); - setActiveIndex((prev) => { - if (prev <= 0) { - const last = findLastEnabled(items); - return last >= 0 ? last : prev; - } - const next = findPrevEnabled(items, prev); - return next >= 0 ? next : prev; - }); - break; - case "Home": - e.preventDefault(); - setActiveIndex(findFirstEnabled(items)); - break; - case "End": - e.preventDefault(); - setActiveIndex(findLastEnabled(items)); - break; - case "Enter": - case " ": - e.preventDefault(); - if (activeIndex >= 0 && activeIndex < items.length) { - selectItem(items[activeIndex]); - } - break; - } - } - function handleItemClick(item) { - selectItem(item); - } - const chevronRotation = isOpen ? -135 : 45; - return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)( - "div", - { - ref: mergeRefs, - style: { ...WRAPPER_BASE, ...style }, - ...rest, - children: [ - /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)( - "button", - { - ref: triggerRef, - type: "button", - "aria-haspopup": "menu", - "aria-expanded": isOpen, - "aria-controls": menuId, - disabled, - onClick: handleTriggerClick, - onKeyDown: handleKeyDown, - style: { - ...TRIGGER_BASE, - ...SIZE_STYLES2[size], - ...VARIANT_TRIGGER[variant], - ...disabled ? TRIGGER_DISABLED : {}, - ...isOpen ? VARIANT_FOCUS[variant] : {} - }, - children: [ - /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: ELLIPSIS, children: selectedItem ? selectedItem.label : placeholder }), - /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( - "span", - { - "aria-hidden": "true", - style: { - ...CHEVRON, - transform: `rotate(${chevronRotation}deg)`, - marginTop: isOpen ? -1 : 1 - } - } - ) - ] - } - ), - isOpen && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( - "div", - { - id: menuId, - role: "menu", - "aria-activedescendant": activeDescendant, - style: MENU_BASE, - children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)( - "button", - { - id: `${menuId}-item-${index}`, - role: "menuitem", - type: "button", - disabled: item.disabled, - tabIndex: -1, - onClick: () => handleItemClick(item), - onMouseEnter: () => setActiveIndex(index), - style: { - ...ITEM_BASE, - ...ITEM_SIZE_STYLES[size], - ...index === activeIndex ? ACTIVE_ITEM[variant] : {}, - ...item.disabled ? ITEM_DISABLED : {} - }, - children: item.label - }, - item.value - )) - } - ) - ] - } - ); -}); -// Annotate the CommonJS export names for ESM import in node: -0 && (module.exports = { - Alert, - Badge, - BcForgeProvider, - Dropdown, - useAllowance, - useApprove, - useBalance, - useBcForgeClient, - useBcForgeToken, - useBurn, - useMint, - useTotalSupply, - useTransfer -}); diff --git a/react/dist/index.mjs b/react/dist/index.mjs deleted file mode 100644 index 90fc2ce3..00000000 --- a/react/dist/index.mjs +++ /dev/null @@ -1,630 +0,0 @@ -// src/context.tsx -import { createContext, useContext, useMemo } from "react"; -import { bcForgeClient } from "@bc-forge/sdk"; -import { jsx } from "react/jsx-runtime"; -var bcForgeContext = createContext({ client: null }); -var BcForgeProvider = ({ config, children }) => { - const client = useMemo(() => new bcForgeClient(config), [config.rpcUrl, config.networkPassphrase, config.contractId]); - return /* @__PURE__ */ jsx(bcForgeContext.Provider, { value: { client }, children }); -}; -var useBcForgeClient = () => { - const context = useContext(bcForgeContext); - if (!context.client) { - throw new Error("useBcForgeClient must be used within a BcForgeProvider"); - } - return context.client; -}; - -// src/hooks.ts -import { useState, useEffect, useCallback } from "react"; -function useBcForgeToken() { - const client = useBcForgeClient(); - const [data, setData] = useState(null); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - useEffect(() => { - async function fetchData() { - try { - setLoading(true); - const [name, symbol, decimals] = await Promise.all([ - client.getName(), - client.getSymbol(), - client.getDecimals() - ]); - setData({ name, symbol, decimals }); - } catch (err) { - setError(err instanceof Error ? err : new Error(String(err))); - } finally { - setLoading(false); - } - } - fetchData(); - }, [client]); - return { data, loading, error }; -} -function useBalance(address) { - const client = useBcForgeClient(); - const [data, setData] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const fetchBalance = useCallback(async () => { - if (!address) return; - try { - setLoading(true); - const balance = await client.getBalance(address); - setData(balance); - } catch (err) { - setError(err instanceof Error ? err : new Error(String(err))); - } finally { - setLoading(false); - } - }, [client, address]); - useEffect(() => { - fetchBalance(); - }, [fetchBalance]); - return { data, loading, error, refetch: fetchBalance }; -} -function useMint() { - const client = useBcForgeClient(); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const mint = useCallback(async (to, amount, source) => { - try { - setLoading(true); - setError(null); - const result = await client.mint(to, amount, source); - return result; - } catch (err) { - const error2 = err instanceof Error ? err : new Error(String(err)); - setError(error2); - throw error2; - } finally { - setLoading(false); - } - }, [client]); - return { mint, loading, error }; -} -function useTotalSupply() { - const client = useBcForgeClient(); - const [data, setData] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const fetchTotalSupply = useCallback(async () => { - try { - setLoading(true); - const supply = await client.getTotalSupply(); - setData(supply); - } catch (err) { - setError(err instanceof Error ? err : new Error(String(err))); - } finally { - setLoading(false); - } - }, [client]); - useEffect(() => { - fetchTotalSupply(); - }, [fetchTotalSupply]); - return { data, loading, error, refetch: fetchTotalSupply }; -} -function useTransfer() { - const client = useBcForgeClient(); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const transfer = useCallback(async (from, to, amount, source) => { - try { - setLoading(true); - setError(null); - const result = await client.transfer(from, to, amount, source); - return result; - } catch (err) { - const error2 = err instanceof Error ? err : new Error(String(err)); - setError(error2); - throw error2; - } finally { - setLoading(false); - } - }, [client]); - return { transfer, loading, error }; -} -function useApprove() { - const client = useBcForgeClient(); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const approve = useCallback(async (from, spender, amount, source) => { - try { - setLoading(true); - setError(null); - const result = await client.approve(from, spender, amount, source); - return result; - } catch (err) { - const error2 = err instanceof Error ? err : new Error(String(err)); - setError(error2); - throw error2; - } finally { - setLoading(false); - } - }, [client]); - return { approve, loading, error }; -} -function useBurn() { - const client = useBcForgeClient(); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const burn = useCallback(async (from, amount, source) => { - try { - setLoading(true); - setError(null); - const result = await client.burn(from, amount, source); - return result; - } catch (err) { - const error2 = err instanceof Error ? err : new Error(String(err)); - setError(error2); - throw error2; - } finally { - setLoading(false); - } - }, [client]); - return { burn, loading, error }; -} -function useAllowance(owner, spender) { - const client = useBcForgeClient(); - const [data, setData] = useState(null); - const [loading, setLoading] = useState(false); - const [error, setError] = useState(null); - const fetchAllowance = useCallback(async () => { - if (!owner || !spender) return; - try { - setLoading(true); - const allowance = await client.getAllowance(owner, spender); - setData(allowance); - } catch (err) { - setError(err instanceof Error ? err : new Error(String(err))); - } finally { - setLoading(false); - } - }, [client, owner, spender]); - useEffect(() => { - fetchAllowance(); - }, [fetchAllowance]); - return { data, loading, error, refetch: fetchAllowance }; -} - -// src/components/Alert.tsx -import { forwardRef } from "react"; -import { jsx as jsx2, jsxs } from "react/jsx-runtime"; -var VARIANT_STYLES = { - info: { backgroundColor: "#eff6ff", borderColor: "#bfdbfe", color: "#1e40af" }, - success: { backgroundColor: "#f0fdf4", borderColor: "#bbf7d0", color: "#166534" }, - warning: { backgroundColor: "#fffbeb", borderColor: "#fde68a", color: "#92400e" }, - danger: { backgroundColor: "#fef2f2", borderColor: "#fecaca", color: "#991b1b" } -}; -var Alert = forwardRef(function Alert2({ variant = "info", title, onDismiss, dismissLabel = "Dismiss alert", style, children, ...rest }, ref) { - const defaultRole = variant === "danger" || variant === "warning" ? "alert" : "status"; - return /* @__PURE__ */ jsxs( - "div", - { - ref, - role: defaultRole, - style: { - display: "flex", - alignItems: "flex-start", - gap: 8, - padding: "12px 14px", - border: "1px solid", - borderRadius: 8, - ...VARIANT_STYLES[variant], - ...style - }, - ...rest, - children: [ - /* @__PURE__ */ jsxs("div", { style: { flex: 1, minWidth: 0 }, children: [ - title ? /* @__PURE__ */ jsx2("div", { style: { fontWeight: 700, marginBottom: 2 }, children: title }) : null, - /* @__PURE__ */ jsx2("div", { style: { fontSize: 14 }, children }) - ] }), - onDismiss ? /* @__PURE__ */ jsx2( - "button", - { - type: "button", - onClick: onDismiss, - "aria-label": dismissLabel, - style: { - flexShrink: 0, - border: "none", - background: "transparent", - cursor: "pointer", - color: "inherit", - fontSize: 18, - lineHeight: 1, - padding: 2 - }, - children: "\xD7" - } - ) : null - ] - } - ); -}); - -// src/components/Badge.tsx -import { forwardRef as forwardRef2 } from "react"; -import { jsx as jsx3 } from "react/jsx-runtime"; -var VARIANT_STYLES2 = { - default: { backgroundColor: "#f3f4f6", color: "#374151" }, - primary: { backgroundColor: "#eff6ff", color: "#1e40af" }, - success: { backgroundColor: "#f0fdf4", color: "#166534" }, - warning: { backgroundColor: "#fffbeb", color: "#92400e" }, - danger: { backgroundColor: "#fef2f2", color: "#991b1b" }, - info: { backgroundColor: "#ecfeff", color: "#155e75" } -}; -var SIZE_STYLES = { - sm: { fontSize: 11, padding: "1px 6px", borderRadius: 8 }, - md: { fontSize: 12, padding: "2px 8px", borderRadius: 10 }, - lg: { fontSize: 14, padding: "3px 10px", borderRadius: 12 } -}; -var BADGE_BASE = { - display: "inline-flex", - alignItems: "center", - fontWeight: 600, - lineHeight: 1.4, - whiteSpace: "nowrap" -}; -var Badge = forwardRef2(function Badge2({ variant = "default", size = "md", style, onClick, onKeyDown, children, ...rest }, ref) { - const isInteractive = Boolean(onClick); - const handleKeyDown = (e) => { - if (isInteractive && (e.key === "Enter" || e.key === " ")) { - e.preventDefault(); - onClick(e); - } - onKeyDown?.(e); - }; - return /* @__PURE__ */ jsx3( - "span", - { - ref, - role: isInteractive ? "button" : void 0, - tabIndex: isInteractive ? 0 : void 0, - style: { - ...BADGE_BASE, - ...VARIANT_STYLES2[variant], - ...SIZE_STYLES[size], - ...isInteractive ? { cursor: "pointer" } : {}, - ...style - }, - onClick, - onKeyDown: handleKeyDown, - ...rest, - children - } - ); -}); - -// src/components/Dropdown.tsx -import React4, { forwardRef as forwardRef3, useState as useState2, useRef, useEffect as useEffect2 } from "react"; -import { jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime"; -var TRIGGER_BASE = { - display: "flex", - alignItems: "center", - justifyContent: "space-between", - gap: 8, - width: "100%", - border: "1px solid", - borderRadius: 6, - cursor: "pointer", - fontFamily: "inherit", - lineHeight: 1.4, - textAlign: "left", - boxSizing: "border-box", - transition: "border-color 0.15s, box-shadow 0.15s" -}; -var TRIGGER_DISABLED = { - opacity: 0.5, - cursor: "not-allowed" -}; -var SIZE_STYLES2 = { - sm: { fontSize: 12, padding: "5px 8px", minHeight: 28 }, - md: { fontSize: 14, padding: "8px 12px", minHeight: 36 }, - lg: { fontSize: 16, padding: "12px 16px", minHeight: 44 } -}; -var ITEM_SIZE_STYLES = { - sm: { fontSize: 12, padding: "5px 8px" }, - md: { fontSize: 14, padding: "8px 12px" }, - lg: { fontSize: 16, padding: "10px 16px" } -}; -var VARIANT_TRIGGER = { - default: { borderColor: "#d1d5db", backgroundColor: "#ffffff", color: "#111827" }, - primary: { borderColor: "#2563eb", backgroundColor: "#2563eb", color: "#ffffff" }, - danger: { borderColor: "#dc2626", backgroundColor: "#dc2626", color: "#ffffff" } -}; -var VARIANT_FOCUS = { - default: { borderColor: "#6366f1", boxShadow: "0 0 0 2px rgba(99,102,241,0.15)" }, - primary: { boxShadow: "0 0 0 2px rgba(37,99,235,0.3)" }, - danger: { boxShadow: "0 0 0 2px rgba(220,38,38,0.3)" } -}; -var ACTIVE_ITEM = { - default: { backgroundColor: "#f3f4f6" }, - primary: { backgroundColor: "#eff6ff", color: "#2563eb" }, - danger: { backgroundColor: "#fef2f2", color: "#dc2626" } -}; -var MENU_BASE = { - position: "absolute", - top: "100%", - left: 0, - right: 0, - zIndex: 50, - marginTop: 4, - border: "1px solid #d1d5db", - borderRadius: 6, - backgroundColor: "#ffffff", - boxShadow: "0 4px 12px rgba(0, 0, 0, 0.1)", - overflow: "hidden", - boxSizing: "border-box" -}; -var ITEM_BASE = { - display: "block", - width: "100%", - border: "none", - backgroundColor: "transparent", - fontFamily: "inherit", - lineHeight: 1.4, - textAlign: "left", - cursor: "pointer", - boxSizing: "border-box", - transition: "background-color 0.1s" -}; -var ITEM_DISABLED = { - opacity: 0.4, - cursor: "not-allowed" -}; -var WRAPPER_BASE = { - position: "relative", - display: "inline-block" -}; -var ELLIPSIS = { - flex: 1, - minWidth: 0, - overflow: "hidden", - textOverflow: "ellipsis", - whiteSpace: "nowrap" -}; -var CHEVRON = { - display: "inline-block", - border: "solid currentColor", - borderWidth: "0 2px 2px 0", - padding: 3, - transition: "transform 0.15s", - flexShrink: 0 -}; -function findFirstEnabled(items, start = 0) { - for (let i = start; i < items.length; i++) { - if (!items[i].disabled) return i; - } - for (let i = 0; i < start; i++) { - if (!items[i].disabled) return i; - } - return -1; -} -function findLastEnabled(items) { - for (let i = items.length - 1; i >= 0; i--) { - if (!items[i].disabled) return i; - } - return -1; -} -function findPrevEnabled(items, current) { - for (let i = current - 1; i >= 0; i--) { - if (!items[i].disabled) return i; - } - return findLastEnabled(items); -} -function findNextEnabled(items, current) { - for (let i = current + 1; i < items.length; i++) { - if (!items[i].disabled) return i; - } - return findFirstEnabled(items); -} -var Dropdown = forwardRef3(function Dropdown2({ - items, - value, - defaultValue, - onChange, - variant = "default", - size = "md", - placeholder = "Select...", - disabled = false, - style, - ...rest -}, ref) { - const [isOpen, setIsOpen] = useState2(false); - const [activeIndex, setActiveIndex] = useState2(-1); - const [internalValue, setInternalValue] = useState2(defaultValue ?? ""); - const isControlled = value !== void 0; - const selectedValue = isControlled ? value : internalValue; - const selectedItem = items.find((item) => item.value === selectedValue); - const wrapperRef = useRef(null); - const triggerRef = useRef(null); - const menuId = React4.useId(); - function mergeRefs(node) { - wrapperRef.current = node; - if (typeof ref === "function") { - ref(node); - } else if (ref && typeof ref === "object") { - ref.current = node; - } - } - const activeDescendant = activeIndex >= 0 ? `${menuId}-item-${activeIndex}` : void 0; - useEffect2(() => { - if (!isOpen) return; - function handleClick(e) { - if (wrapperRef.current && !wrapperRef.current.contains(e.target)) { - setIsOpen(false); - setActiveIndex(-1); - } - } - document.addEventListener("mousedown", handleClick); - return () => document.removeEventListener("mousedown", handleClick); - }, [isOpen]); - function selectItem(item) { - if (item.disabled) return; - if (!isControlled) { - setInternalValue(item.value); - } - onChange?.(item); - setIsOpen(false); - setActiveIndex(-1); - triggerRef.current?.focus(); - } - function handleTriggerClick() { - if (disabled) return; - setIsOpen((prev) => { - if (!prev) { - const idx = selectedItem ? items.indexOf(selectedItem) : -1; - setActiveIndex(idx >= 0 ? idx : findFirstEnabled(items)); - } else { - setActiveIndex(-1); - } - return !prev; - }); - } - function handleKeyDown(e) { - if (disabled) return; - if (!isOpen) { - if (e.key === "Enter" || e.key === " " || e.key === "ArrowDown") { - e.preventDefault(); - setIsOpen(true); - setActiveIndex(findFirstEnabled(items)); - } - return; - } - switch (e.key) { - case "Escape": - e.preventDefault(); - setIsOpen(false); - setActiveIndex(-1); - triggerRef.current?.focus(); - break; - case "ArrowDown": - e.preventDefault(); - setActiveIndex((prev) => { - const next = findNextEnabled(items, prev >= 0 ? prev : -1); - return next >= 0 ? next : prev; - }); - break; - case "ArrowUp": - e.preventDefault(); - setActiveIndex((prev) => { - if (prev <= 0) { - const last = findLastEnabled(items); - return last >= 0 ? last : prev; - } - const next = findPrevEnabled(items, prev); - return next >= 0 ? next : prev; - }); - break; - case "Home": - e.preventDefault(); - setActiveIndex(findFirstEnabled(items)); - break; - case "End": - e.preventDefault(); - setActiveIndex(findLastEnabled(items)); - break; - case "Enter": - case " ": - e.preventDefault(); - if (activeIndex >= 0 && activeIndex < items.length) { - selectItem(items[activeIndex]); - } - break; - } - } - function handleItemClick(item) { - selectItem(item); - } - const chevronRotation = isOpen ? -135 : 45; - return /* @__PURE__ */ jsxs2( - "div", - { - ref: mergeRefs, - style: { ...WRAPPER_BASE, ...style }, - ...rest, - children: [ - /* @__PURE__ */ jsxs2( - "button", - { - ref: triggerRef, - type: "button", - "aria-haspopup": "menu", - "aria-expanded": isOpen, - "aria-controls": menuId, - disabled, - onClick: handleTriggerClick, - onKeyDown: handleKeyDown, - style: { - ...TRIGGER_BASE, - ...SIZE_STYLES2[size], - ...VARIANT_TRIGGER[variant], - ...disabled ? TRIGGER_DISABLED : {}, - ...isOpen ? VARIANT_FOCUS[variant] : {} - }, - children: [ - /* @__PURE__ */ jsx4("span", { style: ELLIPSIS, children: selectedItem ? selectedItem.label : placeholder }), - /* @__PURE__ */ jsx4( - "span", - { - "aria-hidden": "true", - style: { - ...CHEVRON, - transform: `rotate(${chevronRotation}deg)`, - marginTop: isOpen ? -1 : 1 - } - } - ) - ] - } - ), - isOpen && /* @__PURE__ */ jsx4( - "div", - { - id: menuId, - role: "menu", - "aria-activedescendant": activeDescendant, - style: MENU_BASE, - children: items.map((item, index) => /* @__PURE__ */ jsx4( - "button", - { - id: `${menuId}-item-${index}`, - role: "menuitem", - type: "button", - disabled: item.disabled, - tabIndex: -1, - onClick: () => handleItemClick(item), - onMouseEnter: () => setActiveIndex(index), - style: { - ...ITEM_BASE, - ...ITEM_SIZE_STYLES[size], - ...index === activeIndex ? ACTIVE_ITEM[variant] : {}, - ...item.disabled ? ITEM_DISABLED : {} - }, - children: item.label - }, - item.value - )) - } - ) - ] - } - ); -}); -export { - Alert, - Badge, - BcForgeProvider, - Dropdown, - useAllowance, - useApprove, - useBalance, - useBcForgeClient, - useBcForgeToken, - useBurn, - useMint, - useTotalSupply, - useTransfer -};