@tangle-network/blueprint-ui 0.5.5 → 0.5.7
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/dist/chunk-37ADATBT.js +55 -0
- package/dist/chunk-37ADATBT.js.map +1 -0
- package/dist/chunk-F2QBCGUW.js +1582 -0
- package/dist/chunk-F2QBCGUW.js.map +1 -0
- package/dist/chunk-TM5ROMDV.js +57 -0
- package/dist/chunk-TM5ROMDV.js.map +1 -0
- package/dist/components.d.ts +195 -0
- package/dist/components.js +1168 -0
- package/dist/components.js.map +1 -0
- package/dist/detectParentOrigin-BYruoIdc.d.ts +26 -0
- package/dist/iframe/index.d.ts +146 -0
- package/dist/iframe/index.js +607 -0
- package/dist/iframe/index.js.map +1 -0
- package/dist/iframe/testing-index.d.ts +82 -0
- package/dist/iframe/testing-index.js +560 -0
- package/dist/iframe/testing-index.js.map +1 -0
- package/dist/index.d.ts +8620 -0
- package/dist/index.js +870 -0
- package/dist/index.js.map +1 -0
- package/dist/parentBridgeProtocol-BSgLXg9g.d.ts +204 -0
- package/dist/preset.d.ts +60 -0
- package/dist/preset.js +7 -0
- package/dist/preset.js.map +1 -0
- package/dist/styles.css +568 -0
- package/dist/tangleIframeClient-C7NFG_Dw.d.ts +133 -0
- package/dist/useRegistrationCommand-Df1mvvwE.d.ts +151 -0
- package/dist/wallet/index.d.ts +134 -0
- package/dist/wallet/index.js +472 -0
- package/dist/wallet/index.js.map +1 -0
- package/package.json +1 -1
- package/src/components.ts +0 -3
- package/src/index.ts +0 -6
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/utils/resolveOperatorRpc.ts","../src/contracts/chains.ts","../src/utils/env.ts","../src/stores/persistedAtom.ts","../src/stores/txHistory.ts","../src/stores/infra.ts","../src/stores/theme.ts","../src/contracts/abi.ts","../src/contracts/publicClient.ts","../src/contracts/generic-encoder.ts","../src/host/resolver.ts","../src/components/ui/card.tsx","../src/components/ui/badge.tsx","../src/components/ui/button.tsx","../src/host/components/BlueprintHostHero.tsx","../src/host/components/BlueprintHostPanel.tsx","../src/hooks/useJobForm.ts","../src/hooks/useQuotes.ts","../src/hooks/useJobPrice.ts","../src/hooks/useSubmitJob.ts","../src/hooks/useThemeValue.ts","../src/hooks/useRegistrationCommand.ts"],"sourcesContent":["import { clsx, type ClassValue } from 'clsx';\nimport { twMerge } from 'tailwind-merge';\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n","/** Rewrite operator RPC hostname for browser reachability. */\nexport function resolveOperatorRpc(raw: string): string {\n if (typeof window === 'undefined') return raw;\n const withProto = raw.includes('://') ? raw : `http://${raw}`;\n try {\n const url = new URL(withProto);\n const pageHost = window.location.hostname;\n const isNonRoutable =\n url.hostname.endsWith('.local') ||\n !url.hostname.includes('.') ||\n url.hostname === '127.0.0.1' ||\n url.hostname === 'localhost';\n if (isNonRoutable && pageHost !== url.hostname) {\n url.hostname = pageHost;\n }\n return url.toString().replace(/\\/$/, '');\n } catch {\n return withProto;\n }\n}\n","import { defineChain } from 'viem';\nimport { mainnet } from 'viem/chains';\nimport type { Address, Chain } from 'viem';\nimport { getEnvVar, isDevEnv } from '../utils/env';\n\n/**\n * Resolve RPC URL for the current environment.\n * Handles local dev (hostname swap), Vite dev proxy, and remote access.\n */\nexport function resolveRpcUrl(envUrl?: string): string {\n const configured = envUrl ?? getEnvVar('VITE_RPC_URL') ?? 'http://localhost:8545';\n if (typeof window === 'undefined') return configured;\n try {\n const rpc = new URL(configured);\n const isLocalRpc = rpc.hostname === '127.0.0.1' || rpc.hostname === 'localhost';\n const pageHost = window.location.hostname;\n const isLocalPage = pageHost === '127.0.0.1' || pageHost === 'localhost';\n // Dev-mode proxy for LAN access to local RPC\n if (isLocalRpc && !isLocalPage && isDevEnv()) {\n return `${window.location.origin}/rpc-proxy`;\n }\n // Non-dev LAN access: swap hostname\n if (isLocalRpc && !isLocalPage) {\n rpc.hostname = pageHost;\n return rpc.toString().replace(/\\/$/, '');\n }\n } catch {\n // malformed\n }\n return configured;\n}\n\nexport const rpcUrl = resolveRpcUrl();\n\nexport interface LocalChainOptions {\n chainId?: number;\n rpcUrl?: string;\n}\n\nexport function createTangleLocalChain(options: LocalChainOptions = {}) {\n const chainId = options.chainId ?? Number(getEnvVar('VITE_CHAIN_ID') ?? 31337);\n const localRpcUrl = resolveRpcUrl(options.rpcUrl);\n\n return defineChain({\n id: chainId,\n name: 'Tangle Local',\n nativeCurrency: { name: 'Ether', symbol: 'ETH', decimals: 18 },\n rpcUrls: { default: { http: [localRpcUrl] } },\n blockExplorers: { default: { name: 'Explorer', url: '' } },\n contracts: { multicall3: { address: '0xcA11bde05977b3631167028862bE2a173976CA11' } },\n });\n}\n\nexport const tangleLocal = createTangleLocalChain();\n\nexport const tangleTestnet = defineChain({\n id: 3799,\n name: 'Tangle Testnet',\n nativeCurrency: { name: 'Tangle', symbol: 'tTNT', decimals: 18 },\n rpcUrls: {\n default: {\n http: ['https://testnet-rpc.tangle.tools'],\n webSocket: ['wss://testnet-rpc.tangle.tools'],\n },\n },\n blockExplorers: { default: { name: 'Tangle Explorer', url: 'https://testnet-explorer.tangle.tools' } },\n contracts: { multicall3: { address: '0xcA11bde05977b3631167028862bE2a173976CA11' } },\n});\n\nexport const tangleMainnet = defineChain({\n id: 5845,\n name: 'Tangle',\n nativeCurrency: { name: 'Tangle', symbol: 'TNT', decimals: 18 },\n rpcUrls: {\n default: {\n http: ['https://rpc.tangle.tools'],\n webSocket: ['wss://rpc.tangle.tools'],\n },\n },\n blockExplorers: { default: { name: 'Tangle Explorer', url: 'https://explorer.tangle.tools' } },\n contracts: { multicall3: { address: '0xcA11bde05977b3631167028862bE2a173976CA11' } },\n});\n\n/** Minimum required contract addresses for Tangle core hooks. */\nexport interface CoreAddresses {\n jobs: Address;\n services: Address;\n [key: string]: Address;\n}\n\nexport interface NetworkConfig<T extends CoreAddresses = CoreAddresses> {\n chain: Chain;\n rpcUrl: string;\n label: string;\n shortLabel: string;\n addresses: T;\n}\n\nlet _networks: Record<number, NetworkConfig<any>> = {};\n\n/** Register networks with app-specific address shapes at startup. */\nexport function configureNetworks<T extends CoreAddresses>(\n nets: Record<number, NetworkConfig<T>>,\n) {\n _networks = nets;\n}\n\nexport function getNetworks<T extends CoreAddresses = CoreAddresses>(): Record<number, NetworkConfig<T>> {\n return _networks as Record<number, NetworkConfig<T>>;\n}\n\nexport { mainnet };\nexport const allTangleChains = [tangleLocal, tangleTestnet, tangleMainnet] as const;\n","type ImportMetaEnvLike = {\n DEV?: boolean;\n VITE_RPC_URL?: string;\n VITE_CHAIN_ID?: string;\n VITE_BLUEPRINT_ID?: string;\n VITE_SERVICE_ID?: string;\n VITE_SERVICE_IDS?: string;\n VITE_OPERATOR_API_URL?: string;\n};\n\nfunction readImportMetaEnv(): ImportMetaEnvLike {\n return ((import.meta as ImportMeta & { env?: ImportMetaEnvLike }).env ?? {});\n}\n\nexport function getEnvVar(key: keyof ImportMetaEnvLike): string | undefined {\n const value = readImportMetaEnv()[key];\n return typeof value === 'string' ? value : undefined;\n}\n\nexport function isDevEnv(): boolean {\n return Boolean(readImportMetaEnv().DEV);\n}\n","import { atom, type WritableAtom } from 'nanostores';\n\n/**\n * JSON serializer that handles bigint values (converts to `{__bigint: \"123\"}`).\n * Needed because TrackedTx.blockNumber and gasUsed are bigints.\n */\nexport function serializeWithBigInt(value: unknown): string {\n return JSON.stringify(value, (_key, v) =>\n typeof v === 'bigint' ? { __bigint: v.toString() } : v,\n );\n}\n\n/** Deserialize JSON produced by `serializeWithBigInt`. */\nexport function deserializeWithBigInt<T>(raw: string): T {\n return JSON.parse(raw, (_key, v) => {\n if (v && typeof v === 'object' && '__bigint' in v && typeof v.__bigint === 'string') {\n return BigInt(v.__bigint);\n }\n return v;\n }) as T;\n}\n\ninterface PersistedAtomOpts<T> {\n /** localStorage key */\n key: string;\n /** Default value when nothing is stored */\n initial: T;\n /** Custom serializer (defaults to JSON.stringify) */\n serialize?: (value: T) => string;\n /** Custom deserializer (defaults to JSON.parse) */\n deserialize?: (raw: string) => T;\n}\n\n/**\n * A nanostores atom backed by localStorage.\n * Restores on init, persists on every `.set()`.\n * SSR-safe: falls back to `initial` when `window` is unavailable.\n */\nexport function persistedAtom<T>(opts: PersistedAtomOpts<T>): WritableAtom<T> {\n const { key, initial, serialize = JSON.stringify, deserialize = JSON.parse } = opts;\n\n let restored = initial;\n if (typeof window !== 'undefined') {\n try {\n const raw = localStorage.getItem(key);\n if (raw !== null) {\n restored = deserialize(raw);\n }\n } catch {\n // corrupt data — use initial\n }\n }\n\n const store = atom<T>(restored);\n\n if (typeof window !== 'undefined') {\n store.subscribe((value: T) => {\n try {\n localStorage.setItem(key, serialize(value));\n } catch {\n // storage full or unavailable — silently ignore\n }\n });\n }\n\n return store;\n}\n","import { computed } from 'nanostores';\nimport { persistedAtom, serializeWithBigInt, deserializeWithBigInt } from './persistedAtom';\n\nexport interface TrackedTx {\n hash: `0x${string}`;\n label: string;\n status: 'pending' | 'confirmed' | 'failed';\n timestamp: number;\n chainId: number;\n blockNumber?: bigint;\n gasUsed?: bigint;\n}\n\nconst MAX_TXS = 50;\n\nexport const txListStore = persistedAtom<TrackedTx[]>({\n key: 'bp_tx_history',\n initial: [],\n serialize: serializeWithBigInt,\n deserialize: deserializeWithBigInt,\n});\n\nexport const pendingCount = computed(txListStore, (txs: TrackedTx[]) =>\n txs.filter((tx: TrackedTx) => tx.status === 'pending').length,\n);\n\nexport function addTx(hash: `0x${string}`, label: string, chainId: number) {\n const existing = txListStore.get();\n if (existing.some((tx) => tx.hash === hash)) return;\n const newTx: TrackedTx = { hash, label, status: 'pending', timestamp: Date.now(), chainId };\n txListStore.set([newTx, ...existing].slice(0, MAX_TXS));\n}\n\nexport function updateTx(\n hash: `0x${string}`,\n update: Partial<Pick<TrackedTx, 'status' | 'blockNumber' | 'gasUsed'>>,\n) {\n txListStore.set(\n txListStore.get().map((tx: TrackedTx) =>\n tx.hash === hash ? { ...tx, ...update } : tx,\n ),\n );\n}\n\nexport function clearTxs() {\n txListStore.set([]);\n}\n","import { persistedAtom } from './persistedAtom';\nimport { getEnvVar } from '../utils/env';\n\nconst defaultBlueprintId = getEnvVar('VITE_BLUEPRINT_ID') ?? '0';\nconst defaultServiceId = getEnvVar('VITE_SERVICE_ID') ?? getEnvVar('VITE_SERVICE_IDS')?.split(',')[0] ?? '0';\n\nexport interface OperatorInfo {\n address: string;\n rpcAddress: string;\n}\n\nexport interface InfraConfig {\n blueprintId: string;\n serviceId: string;\n /** Whether the user has validated the service on-chain */\n serviceValidated: boolean;\n /** Cached service info from last validation */\n serviceInfo?: {\n active: boolean;\n operatorCount: number;\n owner: string;\n blueprintId: string;\n permitted: boolean;\n /** Operators with RPC endpoints (cached for RFQ) */\n operators?: OperatorInfo[];\n };\n}\n\nexport const infraStore = persistedAtom<InfraConfig>({\n key: 'bp_infra',\n initial: {\n blueprintId: defaultBlueprintId,\n serviceId: defaultServiceId,\n serviceValidated: false,\n },\n});\n\nexport function updateInfra(update: Partial<InfraConfig>) {\n infraStore.set({ ...infraStore.get(), ...update });\n}\n\nexport function getInfra(): InfraConfig {\n return infraStore.get();\n}\n","import { atom } from 'nanostores';\n\nexport type Theme = 'dark' | 'light';\n\nexport const kTheme = 'bp_theme';\nexport const DEFAULT_THEME = 'dark';\n\nexport const themeStore = atom<Theme>(initStore());\n\nexport function themeIsDark() {\n return themeStore.get() === 'dark';\n}\n\nfunction initStore() {\n if (typeof window !== 'undefined') {\n const persisted = localStorage.getItem(kTheme) as Theme | undefined;\n const attr = document.querySelector('html')?.getAttribute('data-theme');\n return persisted ?? (attr as Theme) ?? DEFAULT_THEME;\n }\n return DEFAULT_THEME;\n}\n\nexport function toggleTheme() {\n const next = themeStore.get() === 'dark' ? 'light' : 'dark';\n themeStore.set(next);\n localStorage.setItem(kTheme, next);\n document.querySelector('html')?.setAttribute('data-theme', next);\n}\n","/**\n * Tangle core precompile ABIs — shared across all blueprints.\n * Blueprint-specific ABIs (agentSandboxBlueprintAbi, tradingBlueprintAbi, etc.)\n * stay in each consuming app.\n */\n\nexport const tangleJobsAbi = [\n {\n type: 'function',\n name: 'submitJob',\n inputs: [\n { name: 'serviceId', type: 'uint64' },\n { name: 'job', type: 'uint8' },\n { name: 'args', type: 'bytes' },\n ],\n outputs: [{ name: 'callId', type: 'uint64' }],\n stateMutability: 'payable',\n },\n {\n type: 'event',\n name: 'JobCalled',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'job', type: 'uint8', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n { name: 'caller', type: 'address', indexed: false },\n { name: 'args', type: 'bytes', indexed: false },\n ],\n },\n {\n type: 'event',\n name: 'JobResultReceived',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'job', type: 'uint8', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n { name: 'operator', type: 'address', indexed: false },\n { name: 'outputs', type: 'bytes', indexed: false },\n ],\n },\n {\n type: 'event',\n name: 'JobSubmitted',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n { name: 'jobIndex', type: 'uint8', indexed: false },\n { name: 'caller', type: 'address', indexed: false },\n { name: 'inputs', type: 'bytes', indexed: false },\n ],\n },\n {\n type: 'event',\n name: 'JobCompleted',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n ],\n },\n {\n type: 'event',\n name: 'JobResultSubmitted',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'callId', type: 'uint64', indexed: true },\n { name: 'operator', type: 'address', indexed: true },\n { name: 'output', type: 'bytes', indexed: false },\n ],\n },\n] as const;\n\nexport const tangleServicesAbi = [\n {\n type: 'function',\n name: 'requestService',\n inputs: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'operators', type: 'address[]' },\n { name: 'config', type: 'bytes' },\n { name: 'permittedCallers', type: 'address[]' },\n { name: 'ttl', type: 'uint64' },\n { name: 'paymentToken', type: 'address' },\n { name: 'paymentAmount', type: 'uint256' },\n ],\n outputs: [{ name: 'requestId', type: 'uint64' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n name: 'createServiceFromQuotes',\n inputs: [\n { name: 'blueprintId', type: 'uint64' },\n {\n name: 'quotes',\n type: 'tuple[]',\n components: [\n {\n name: 'details',\n type: 'tuple',\n components: [\n // tnt-core v0.13.0: `requester` is the first field of QuoteDetails.\n // The contract enforces `requester == msg.sender` and rejects address(0).\n { name: 'requester', type: 'address' },\n { name: 'blueprintId', type: 'uint64' },\n { name: 'ttlBlocks', type: 'uint64' },\n { name: 'totalCost', type: 'uint256' },\n { name: 'timestamp', type: 'uint64' },\n { name: 'expiry', type: 'uint64' },\n { name: 'confidentiality', type: 'uint8' },\n {\n name: 'securityCommitments',\n type: 'tuple[]',\n components: [\n {\n name: 'asset',\n type: 'tuple',\n components: [\n { name: 'kind', type: 'uint8' },\n { name: 'token', type: 'address' },\n ],\n },\n { name: 'exposureBps', type: 'uint16' },\n ],\n },\n {\n name: 'resourceCommitments',\n type: 'tuple[]',\n components: [\n { name: 'kind', type: 'uint8' },\n { name: 'count', type: 'uint64' },\n ],\n },\n ],\n },\n { name: 'signature', type: 'bytes' },\n { name: 'operator', type: 'address' },\n ],\n },\n { name: 'config', type: 'bytes' },\n { name: 'permittedCallers', type: 'address[]' },\n { name: 'ttl', type: 'uint64' },\n ],\n outputs: [{ name: 'serviceId', type: 'uint64' }],\n stateMutability: 'payable',\n },\n {\n type: 'function',\n name: 'getService',\n inputs: [{ name: 'serviceId', type: 'uint64' }],\n outputs: [\n {\n name: '',\n type: 'tuple',\n components: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'owner', type: 'address' },\n { name: 'createdAt', type: 'uint64' },\n { name: 'ttl', type: 'uint64' },\n { name: 'terminatedAt', type: 'uint64' },\n { name: 'lastPaymentAt', type: 'uint64' },\n { name: 'operatorCount', type: 'uint32' },\n { name: 'minOperators', type: 'uint32' },\n { name: 'maxOperators', type: 'uint32' },\n { name: 'membership', type: 'uint8' },\n { name: 'pricing', type: 'uint8' },\n { name: 'status', type: 'uint8' },\n ],\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isServiceActive',\n inputs: [{ name: 'serviceId', type: 'uint64' }],\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getServiceOperators',\n inputs: [{ name: 'serviceId', type: 'uint64' }],\n outputs: [{ name: '', type: 'address[]' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isPermittedCaller',\n inputs: [\n { name: 'serviceId', type: 'uint64' },\n { name: 'caller', type: 'address' },\n ],\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'event',\n name: 'ServiceRequested',\n inputs: [\n { name: 'requestId', type: 'uint64', indexed: true },\n { name: 'blueprintId', type: 'uint64', indexed: true },\n { name: 'requester', type: 'address', indexed: true },\n ],\n },\n {\n type: 'event',\n name: 'ServiceActivated',\n inputs: [\n { name: 'serviceId', type: 'uint64', indexed: true },\n { name: 'requestId', type: 'uint64', indexed: true },\n { name: 'blueprintId', type: 'uint64', indexed: true },\n ],\n },\n] as const;\n\nexport const tangleOperatorsAbi = [\n {\n type: 'function',\n name: 'blueprintOperatorCount',\n inputs: [{ name: 'blueprintId', type: 'uint64' }],\n outputs: [{ name: '', type: 'uint256' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'isOperatorRegistered',\n inputs: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'operator', type: 'address' },\n ],\n outputs: [{ name: '', type: 'bool' }],\n stateMutability: 'view',\n },\n {\n type: 'function',\n name: 'getOperatorPreferences',\n inputs: [\n { name: 'blueprintId', type: 'uint64' },\n { name: 'operator', type: 'address' },\n ],\n outputs: [\n {\n name: 'preferences',\n type: 'tuple',\n components: [\n { name: 'ecdsaPublicKey', type: 'bytes' },\n { name: 'rpcAddress', type: 'string' },\n ],\n },\n ],\n stateMutability: 'view',\n },\n {\n type: 'event',\n name: 'OperatorRegistered',\n inputs: [\n { name: 'blueprintId', type: 'uint64', indexed: true },\n { name: 'operator', type: 'address', indexed: true },\n { name: 'ecdsaPublicKey', type: 'bytes', indexed: false },\n { name: 'rpcAddress', type: 'string', indexed: false },\n ],\n },\n {\n type: 'event',\n name: 'OperatorUnregistered',\n inputs: [\n { name: 'blueprintId', type: 'uint64', indexed: true },\n { name: 'operator', type: 'address', indexed: true },\n ],\n },\n] as const;\n","import { createPublicClient, http } from 'viem';\nimport type { PublicClient } from 'viem';\nimport { atom } from 'nanostores';\nimport { getNetworks, tangleLocal, type CoreAddresses } from './chains';\nimport { persistedAtom } from '../stores/persistedAtom';\nimport { getEnvVar } from '../utils/env';\n\nconst defaultChainId = Number(getEnvVar('VITE_CHAIN_ID') ?? tangleLocal.id);\n\nexport const selectedChainIdStore = persistedAtom<number>({\n key: 'bp_selected_chain',\n initial: defaultChainId,\n});\n\nconst clientCache = new Map<number, PublicClient>();\n\nfunction configuredDefaultChainId(): number {\n const networks = getNetworks();\n if (networks[defaultChainId]) return defaultChainId;\n\n for (const [chainId, net] of Object.entries(networks)) {\n if (\n net?.shortLabel === 'Local' ||\n net?.label === 'Tangle Local' ||\n net?.chain?.name === 'Tangle Local'\n ) {\n return Number(chainId);\n }\n }\n\n const [firstConfigured] = Object.keys(networks);\n return firstConfigured ? Number(firstConfigured) : defaultChainId;\n}\n\nfunction normalizeSelectedChainId(chainId: number): number {\n const networks = getNetworks();\n if (!Object.keys(networks).length) return chainId;\n return networks[chainId] ? chainId : configuredDefaultChainId();\n}\n\nexport function sanitizeSelectedChainId(): number {\n const normalized = normalizeSelectedChainId(selectedChainIdStore.get());\n if (normalized !== selectedChainIdStore.get()) {\n selectedChainIdStore.set(normalized);\n }\n return normalized;\n}\n\nfunction getOrCreateClient(chainId: number): PublicClient {\n const normalizedChainId = normalizeSelectedChainId(chainId);\n\n const cached = clientCache.get(normalizedChainId);\n if (cached) return cached;\n const networks = getNetworks();\n const net = networks[normalizedChainId];\n if (!net) {\n const fallback = networks[configuredDefaultChainId()];\n if (!fallback) {\n return createPublicClient({ chain: tangleLocal, transport: http() });\n }\n return createPublicClient({ chain: fallback.chain, transport: http(fallback.rpcUrl) });\n }\n const client = createPublicClient({ chain: net.chain, transport: http(net.rpcUrl) });\n clientCache.set(normalizedChainId, client);\n return client;\n}\n\nexport const publicClientStore = atom<PublicClient>(getOrCreateClient(sanitizeSelectedChainId()));\n\nselectedChainIdStore.subscribe((chainId: number) => {\n const normalized = normalizeSelectedChainId(chainId);\n if (normalized !== chainId) {\n selectedChainIdStore.set(normalized);\n return;\n }\n publicClientStore.set(getOrCreateClient(normalized));\n});\n\nexport function getPublicClient(): PublicClient {\n sanitizeSelectedChainId();\n return publicClientStore.get();\n}\n\nexport const publicClient = new Proxy({} as PublicClient, {\n get(_target, prop) {\n const client = getOrCreateClient(sanitizeSelectedChainId());\n const value = (client as any)[prop];\n return typeof value === 'function' ? value.bind(client) : value;\n },\n});\n\nexport function getAddresses<T extends CoreAddresses = CoreAddresses>(): T {\n const networks = getNetworks<T>();\n const selectedChainId = sanitizeSelectedChainId();\n const net = networks[selectedChainId];\n return net?.addresses ?? networks[configuredDefaultChainId()]?.addresses ?? {} as T;\n}\n","import { encodeAbiParameters } from 'viem';\nimport type { JobDefinition } from '../blueprints/registry';\n\n/**\n * Generic ABI encoder for any blueprint job.\n *\n * Builds the ordered parameter array from:\n * 1. contextParams (e.g. sidecar_url, sandbox_id) — prepended first\n * 2. fields with abiType set — appended in definition order\n *\n * Delegates to job.customEncoder when present (for nested-struct jobs like batch_create).\n */\nexport function encodeJobArgs(\n job: JobDefinition,\n formValues: Record<string, unknown>,\n context?: Record<string, unknown>,\n): `0x${string}` {\n if (job.customEncoder) {\n return job.customEncoder(formValues, context);\n }\n\n const abiDefs: { name: string; type: string }[] = [];\n const values: unknown[] = [];\n\n // Context params first (sidecar_url, sandbox_id, etc.)\n if (job.contextParams) {\n for (const cp of job.contextParams) {\n abiDefs.push({ name: cp.abiName, type: cp.abiType });\n values.push(coerceValue(context?.[cp.abiName], cp.abiType));\n }\n }\n\n // Form fields with ABI metadata\n for (const field of job.fields) {\n if (!field.abiType) continue;\n abiDefs.push({ name: field.abiParam ?? field.name, type: field.abiType });\n values.push(coerceValue(formValues[field.name], field.abiType));\n }\n\n return encodeAbiParameters(abiDefs, values);\n}\n\nfunction coerceValue(value: unknown, abiType: string): unknown {\n switch (abiType) {\n case 'bool':\n return Boolean(value);\n case 'uint8':\n case 'uint16':\n case 'uint32':\n return Number(value) || 0;\n case 'uint64':\n case 'uint128':\n case 'uint256':\n return BigInt(Number(value) || 0);\n case 'string':\n return String(value ?? '');\n case 'string[]':\n if (Array.isArray(value)) return value.map(String);\n return String(value ?? '').split('\\n').filter(Boolean);\n case 'address[]':\n if (Array.isArray(value)) return value;\n return String(value ?? '')\n .split('\\n')\n .map((s) => s.trim())\n .filter((s) => /^0x[a-fA-F0-9]{40}$/.test(s));\n default:\n return value;\n }\n}\n","import type {\n BlueprintAppEntry,\n BlueprintAppResolvedView,\n BlueprintExperienceTier,\n BlueprintExternalAppTrust,\n BlueprintPublisher,\n BlueprintPublisherVerification,\n BlueprintSlugPolicy,\n BlueprintUiSurface,\n} from './types';\n\nconst EXPERIENCE_TIER_LABELS: Record<BlueprintExperienceTier, string> = {\n generic: 'Protocol fallback',\n declarative: 'Declarative blueprint UI',\n 'curated-module': 'Curated app module',\n 'external-app': 'External app handoff',\n};\n\nconst SLUG_POLICY_LABELS: Record<BlueprintSlugPolicy, string> = {\n reserved: 'Reserved slug',\n 'publisher-scoped': 'Publisher-scoped slug',\n 'public-requested': 'Public requested slug',\n};\n\nconst SURFACE_LABELS: Record<BlueprintUiSurface, string> = {\n 'generic-overview': 'Generic overview',\n 'service-explorer': 'Service explorer',\n 'service-console': 'Service console',\n 'actions-panel': 'Actions panel',\n resources: 'Resources',\n chat: 'Chat',\n vaults: 'Vaults',\n metrics: 'Metrics',\n permissions: 'Permissions',\n};\n\nconst PUBLISHER_VERIFICATION_LABELS: Record<\n BlueprintPublisherVerification,\n string\n> = {\n 'first-party': 'First-party publisher',\n verified: 'Verified publisher',\n unverified: 'Unverified publisher',\n};\n\nconst EXTERNAL_APP_TRUST_LABELS: Record<BlueprintExternalAppTrust, string> = {\n trusted: 'Trusted external app',\n restricted: 'Restricted external app',\n};\n\nexport function buildCanonicalBlueprintSlug(entry: BlueprintAppEntry): string {\n if (entry.canonicalSlug) {\n return entry.canonicalSlug;\n }\n\n if (entry.slugPolicy === 'reserved' || !entry.publisher.namespace) {\n return entry.slug;\n }\n\n return `@${entry.publisher.namespace}/${entry.slug}`;\n}\n\nexport function resolveBlueprintAppView(\n entry: BlueprintAppEntry,\n): BlueprintAppResolvedView {\n return {\n slug: entry.slug,\n canonicalSlug: buildCanonicalBlueprintSlug(entry),\n blueprintId: entry.blueprintId,\n publisher: entry.publisher,\n tier: entry.tier,\n slugPolicy: entry.slugPolicy,\n manifest: entry.manifest,\n module: entry.module,\n fallbackEnabled: true,\n };\n}\n\nexport function toBlueprintAppEntry(\n view: BlueprintAppResolvedView,\n): BlueprintAppEntry {\n return {\n slug: view.slug,\n canonicalSlug: view.canonicalSlug,\n blueprintId: view.blueprintId,\n publisher: view.publisher,\n tier: view.tier,\n slugPolicy: view.slugPolicy,\n manifest: view.manifest,\n module: view.module,\n };\n}\n\nexport function getBlueprintExperienceTierLabel(\n tier: BlueprintExperienceTier,\n): string {\n return EXPERIENCE_TIER_LABELS[tier];\n}\n\nexport function getBlueprintSlugPolicyLabel(policy: BlueprintSlugPolicy): string {\n return SLUG_POLICY_LABELS[policy];\n}\n\nexport function getBlueprintSurfaceLabel(surface: BlueprintUiSurface): string {\n return SURFACE_LABELS[surface];\n}\n\nexport function getBlueprintPublisherVerificationLabel(\n verification: BlueprintPublisherVerification,\n): string {\n return PUBLISHER_VERIFICATION_LABELS[verification];\n}\n\nexport function getExternalAppTrustLabel(\n trust: BlueprintExternalAppTrust,\n): string {\n return EXTERNAL_APP_TRUST_LABELS[trust];\n}\n\nexport function isVerifiedBlueprintPublisher(\n publisher: BlueprintPublisher,\n): boolean {\n return (\n publisher.verification === 'first-party' ||\n publisher.verification === 'verified'\n );\n}\n\nexport function canPublisherClaimSlug(\n slug: string,\n publisher?: Pick<BlueprintPublisher, 'namespace' | 'verification'>,\n reservedSlugs: Set<string> = new Set(),\n): boolean {\n if (reservedSlugs.has(slug)) {\n return false;\n }\n\n return (\n publisher?.namespace !== undefined &&\n publisher.namespace.trim().length > 0 &&\n (publisher.verification === 'verified' ||\n publisher.verification === 'first-party')\n );\n}\n\nexport function isTrustedExternalAppHost(\n host: string,\n trustedHosts: readonly string[] = [],\n): boolean {\n const normalizedHost = host.trim().toLowerCase();\n\n return trustedHosts.some(\n (trustedHost) =>\n normalizedHost === trustedHost || normalizedHost.endsWith(`.${trustedHost}`),\n );\n}\n\nexport function getBlueprintPath(view: BlueprintAppResolvedView): string {\n if (view.tier === 'curated-module' || view.tier === 'external-app') {\n return `/blueprints/${view.canonicalSlug}`;\n }\n\n if (view.blueprintId !== undefined) {\n return `/blueprints/${view.blueprintId.toString()}`;\n }\n\n return `/blueprints/${view.slug}`;\n}\n\nexport function getBlueprintServicePath(\n view: BlueprintAppResolvedView,\n serviceId: string,\n): string {\n if (view.tier === 'curated-module' || view.tier === 'external-app') {\n return `${getBlueprintPath(view)}/${serviceId}`;\n }\n\n return `${getBlueprintPath(view)}/services/${serviceId}`;\n}\n\nexport function sanitizeBlueprintSlugPart(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '')\n .replace(/-{2,}/g, '-');\n}\n\nexport function deriveBlueprintRequestedSlug(\n blueprint: Pick<{ name: string; author: string; id: bigint }, 'name' | 'author' | 'id'>,\n): string {\n const fromName = sanitizeBlueprintSlugPart(blueprint.name);\n if (fromName.length > 0) {\n return fromName;\n }\n\n const fromAuthor = sanitizeBlueprintSlugPart(blueprint.author);\n if (fromAuthor.length > 0) {\n return `${fromAuthor}-${blueprint.id.toString()}`;\n }\n\n return `blueprint-${blueprint.id.toString()}`;\n}\n","import * as React from 'react';\nimport { cn } from '../../utils';\n\nfunction Card({ className, ...props }: React.ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"card\"\n className={cn('glass-card rounded-xl text-bp-elements-textPrimary', className)}\n {...props}\n />\n );\n}\n\nfunction CardHeader({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-header\" className={cn('flex flex-col gap-1.5 p-6', className)} {...props} />;\n}\n\nfunction CardTitle({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-title\" className={cn('leading-none font-semibold font-display', className)} {...props} />;\n}\n\nfunction CardDescription({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-description\" className={cn('text-bp-elements-textSecondary text-sm', className)} {...props} />;\n}\n\nfunction CardContent({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-content\" className={cn('px-6 pb-6', className)} {...props} />;\n}\n\nfunction CardFooter({ className, ...props }: React.ComponentProps<'div'>) {\n return <div data-slot=\"card-footer\" className={cn('flex items-center px-6 pb-6', className)} {...props} />;\n}\n\nexport { Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter };\n","import * as React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils';\n\nconst badgeVariants = cva(\n 'inline-flex items-center justify-center rounded-md border px-2.5 py-0.5 text-xs font-semibold font-data uppercase tracking-wider w-fit whitespace-nowrap shrink-0 gap-1 transition-colors',\n {\n variants: {\n variant: {\n default: 'border-bp-elements-borderColor bg-bp-elements-background-depth-3 text-bp-elements-textPrimary',\n secondary: 'border-bp-elements-dividerColor bg-bp-elements-background-depth-2 text-bp-elements-textSecondary',\n destructive: 'border-crimson-500/20 bg-crimson-500/10 text-bp-elements-icon-error',\n success: 'border-teal-500/20 bg-teal-500/10 text-bp-elements-icon-success',\n outline: 'text-bp-elements-textPrimary border-bp-elements-borderColor bg-transparent',\n accent: 'border-violet-500/20 bg-violet-500/10 text-violet-700 dark:text-violet-400',\n amber: 'border-amber-500/20 bg-amber-500/10 text-amber-700 dark:text-amber-400',\n running: 'border-teal-500/20 bg-teal-500/10 text-teal-600 dark:text-teal-400',\n stopped: 'border-amber-500/20 bg-amber-500/10 text-amber-600 dark:text-amber-400',\n cold: 'border-blue-500/20 bg-blue-500/10 text-blue-600 dark:text-blue-400',\n },\n },\n defaultVariants: { variant: 'default' },\n },\n);\n\nfunction Badge({\n className,\n variant,\n asChild = false,\n ...props\n}: React.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & { asChild?: boolean }) {\n const Comp = asChild ? Slot : 'span';\n return <Comp data-slot=\"badge\" className={cn(badgeVariants({ variant }), className)} {...props} />;\n}\n\nexport { Badge, badgeVariants };\n","import * as React from 'react';\nimport { Slot } from '@radix-ui/react-slot';\nimport { cva, type VariantProps } from 'class-variance-authority';\nimport { cn } from '../../utils';\n\nconst buttonVariants = cva(\n 'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-lg text-sm font-medium font-display transition-all duration-200 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg:not([class*=\"size-\"])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:ring-2 focus-visible:ring-violet-400/50 focus-visible:ring-offset-2 focus-visible:ring-offset-bp-elements-background-depth-1',\n {\n variants: {\n variant: {\n default:\n 'bg-violet-600 text-white font-semibold hover:bg-violet-500 shadow-[0_0_20px_rgba(142,89,255,0.25)] hover:shadow-[0_0_30px_rgba(142,89,255,0.35)]',\n destructive:\n 'bg-crimson-500/15 text-crimson-400 border border-crimson-500/20 hover:bg-crimson-500/25 hover:border-crimson-500/30',\n outline:\n 'glass glass-hover text-bp-elements-textPrimary',\n secondary:\n 'bg-bp-elements-background-depth-3 text-bp-elements-textSecondary border border-bp-elements-borderColor hover:bg-bp-elements-background-depth-4 hover:text-bp-elements-textPrimary',\n ghost:\n 'text-bp-elements-textSecondary hover:text-bp-elements-textPrimary hover:bg-bp-elements-item-backgroundHover',\n link:\n 'text-violet-700 dark:text-violet-400 underline-offset-4 hover:underline',\n success:\n 'bg-teal-600/15 text-teal-400 border border-teal-500/20 hover:bg-teal-600/25',\n },\n size: {\n default: 'h-9 px-4 py-2 has-[>svg]:px-3',\n sm: 'h-8 rounded-md gap-1.5 px-3 text-xs has-[>svg]:px-2.5',\n lg: 'h-11 rounded-xl px-7 text-base has-[>svg]:px-5',\n icon: 'size-9',\n 'icon-sm': 'size-8',\n },\n },\n defaultVariants: {\n variant: 'default',\n size: 'default',\n },\n },\n);\n\nfunction Button({\n className,\n variant = 'default',\n size = 'default',\n asChild = false,\n ...props\n}: React.ComponentProps<'button'> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean;\n }) {\n const Comp = asChild ? Slot : 'button';\n return (\n <Comp\n data-slot=\"button\"\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n );\n}\n\nexport { Button, buttonVariants };\n","import * as React from 'react';\nimport { Card, CardContent, CardHeader, CardTitle, CardDescription } from '../../components/ui/card';\nimport { Badge } from '../../components/ui/badge';\nimport { Button } from '../../components/ui/button';\nimport { cn } from '../../utils';\n\ntype Action = {\n label: string;\n href?: string;\n onClick?: () => void;\n variant?: React.ComponentProps<typeof Button>['variant'];\n disabled?: boolean;\n};\n\nexport type BlueprintHostHeroProps = {\n title: string;\n tagline?: string;\n description?: string;\n badges?: string[];\n actions?: Action[];\n children?: React.ReactNode;\n className?: string;\n};\n\nexport function BlueprintHostHero({\n title,\n tagline,\n description,\n badges = [],\n actions = [],\n children,\n className,\n}: BlueprintHostHeroProps) {\n return (\n <Card className={cn('rounded-3xl border-bp-elements-borderColor/70 bg-bp-elements-background-depth-2', className)}>\n <CardHeader className=\"space-y-4\">\n {badges.length > 0 ? (\n <div className=\"flex flex-wrap gap-2\">\n {badges.map((badge) => (\n <Badge key={badge} variant=\"secondary\">\n {badge}\n </Badge>\n ))}\n </div>\n ) : null}\n <div className=\"space-y-2\">\n <CardTitle className=\"text-3xl\">{title}</CardTitle>\n {tagline ? (\n <CardDescription className=\"text-base text-bp-elements-textPrimary/80\">\n {tagline}\n </CardDescription>\n ) : null}\n </div>\n {description ? (\n <p className=\"max-w-3xl text-sm leading-6 text-bp-elements-textSecondary\">\n {description}\n </p>\n ) : null}\n </CardHeader>\n {(actions.length > 0 || children) && (\n <CardContent className=\"space-y-4\">\n {actions.length > 0 ? (\n <div className=\"flex flex-wrap gap-3\">\n {actions.map((action) => {\n const button = (\n <Button\n key={action.label}\n variant={action.variant ?? 'default'}\n onClick={action.onClick}\n disabled={action.disabled}\n >\n {action.label}\n </Button>\n );\n\n return action.href ? (\n <a key={action.label} href={action.href}>\n {button}\n </a>\n ) : (\n button\n );\n })}\n </div>\n ) : null}\n {children}\n </CardContent>\n )}\n </Card>\n );\n}\n","import * as React from 'react';\nimport { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card';\nimport { cn } from '../../utils';\n\nexport type BlueprintHostPanelProps = {\n title: string;\n children: React.ReactNode;\n className?: string;\n};\n\nexport function BlueprintHostPanel({\n title,\n children,\n className,\n}: BlueprintHostPanelProps) {\n return (\n <Card className={cn('rounded-3xl border-bp-elements-borderColor/70 bg-bp-elements-background-depth-2', className)}>\n <CardHeader>\n <CardTitle className=\"text-xl\">{title}</CardTitle>\n </CardHeader>\n <CardContent>{children}</CardContent>\n </Card>\n );\n}\n","import { useState, useCallback, useEffect, useMemo } from 'react';\nimport type { JobDefinition } from '../blueprints/registry';\n\nexport interface JobFormState {\n values: Record<string, unknown>;\n errors: Record<string, string>;\n onChange: (name: string, value: unknown) => void;\n validate: () => boolean;\n reset: () => void;\n}\n\nfunction buildDefaults(job: JobDefinition): Record<string, unknown> {\n const init: Record<string, unknown> = {};\n for (const f of job.fields) {\n if (f.internal) continue;\n if (f.defaultValue !== undefined) {\n init[f.name] = f.defaultValue;\n } else if (f.type === 'boolean') {\n init[f.name] = false;\n } else if (f.type === 'number') {\n init[f.name] = f.min ?? 0;\n } else {\n init[f.name] = '';\n }\n }\n return init;\n}\n\nexport function useJobForm(job: JobDefinition | null): JobFormState {\n const defaults = useMemo(() => (job ? buildDefaults(job) : {}), [job]);\n const [values, setValues] = useState<Record<string, unknown>>(defaults);\n const [errors, setErrors] = useState<Record<string, string>>({});\n\n // Sync form values when job changes (e.g. blueprint selection or async load)\n useEffect(() => {\n setValues(defaults);\n setErrors({});\n }, [defaults]);\n\n const onChange = useCallback((name: string, value: unknown) => {\n setValues((prev) => ({ ...prev, [name]: value }));\n setErrors((prev) => {\n if (!prev[name]) return prev;\n const next = { ...prev };\n delete next[name];\n return next;\n });\n }, []);\n\n const validate = useCallback((): boolean => {\n if (!job) return false;\n const errs: Record<string, string> = {};\n for (const f of job.fields) {\n if (f.internal) continue;\n const v = values[f.name];\n if (f.required && (v === undefined || v === null || v === '')) {\n errs[f.name] = `${f.label} is required`;\n continue;\n }\n if (f.type === 'number' && typeof v === 'number') {\n if (f.min != null && v < f.min) {\n errs[f.name] = `${f.label} must be at least ${f.min}`;\n } else if (f.max != null && v > f.max) {\n errs[f.name] = `${f.label} must be at most ${f.max}`;\n }\n }\n }\n setErrors(errs);\n return Object.keys(errs).length === 0;\n }, [job, values]);\n\n const reset = useCallback(() => {\n setValues(defaults);\n setErrors({});\n }, [defaults]);\n\n return { values, errors, onChange, validate, reset };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport type { Address } from 'viem';\nimport { sha256 as viemSha256, toHex } from 'viem';\nimport type { DiscoveredOperator } from './useOperators';\nimport { resolveOperatorRpc } from '../utils/resolveOperatorRpc';\n\n/**\n * RFQ (Request for Quote) hook — fetches pricing quotes from operators.\n *\n * Implements the Tangle pricing protocol:\n * 1. Solve PoW challenge (SHA256 with 20-bit difficulty)\n * 2. Send gRPC GetPrice request to each operator's registered RPC\n * 3. Collect signed QuoteDetails for createServiceFromQuotes()\n *\n * When operators don't have a pricing engine (no rpcAddress), falls back to\n * multiplier-based estimation from the on-chain getDefaultJobRates().\n */\n\n// ── Types ──\n\ntype SecurityCommitment = {\n asset: { kind: number; token: Address };\n exposureBps: number;\n};\n\ntype ResourceCommitment = {\n kind: number;\n count: bigint;\n};\n\nexport interface OperatorQuote {\n operator: Address;\n totalCost: bigint;\n signature: `0x${string}`;\n details: {\n /**\n * Address of the account that will submit `createServiceFromQuotes`.\n * Required since tnt-core v0.13.0 — the contract enforces\n * `requester == msg.sender` and rejects `address(0)` (no wildcard quotes).\n */\n requester: Address;\n blueprintId: bigint;\n ttlBlocks: bigint;\n totalCost: bigint;\n timestamp: bigint;\n expiry: bigint;\n confidentiality: number;\n securityCommitments: readonly SecurityCommitment[];\n resourceCommitments: readonly ResourceCommitment[];\n };\n costRate: number;\n teeAttested?: boolean;\n teeProvider?: string;\n}\n\nexport interface UseQuotesResult {\n quotes: OperatorQuote[];\n isLoading: boolean;\n isSolvingPow: boolean;\n errors: Map<Address, string>;\n totalCost: bigint;\n refetch: () => void;\n}\n\n// ── PoW solver (mirrors Tangle pricing-engine/src/pow.rs) ──\n\nconst POW_DIFFICULTY = 20;\nconst WEI_PER_TNT = 1_000_000_000_000_000_000; // 10^18\nconst RESOURCE_KIND_TO_ID = {\n CPU: 0,\n MemoryMB: 1,\n StorageMB: 2,\n NetworkEgressMB: 3,\n NetworkIngressMB: 4,\n GPU: 5,\n} as const;\nconst ZERO_ADDRESS = '0x0000000000000000000000000000000000000000' as Address;\nconst DEFAULT_RESOURCE_REQUIREMENTS = [\n { kind: 'CPU', count: 1 },\n { kind: 'MemoryMB', count: 1024 },\n { kind: 'StorageMB', count: 10240 },\n] as const;\n\nfunction sha256(data: Uint8Array): Uint8Array {\n return viemSha256(data, 'bytes');\n}\n\nfunction generateChallenge(blueprintId: bigint, timestamp: bigint): Uint8Array {\n const input = new Uint8Array(16);\n const view = new DataView(input.buffer);\n view.setBigUint64(0, blueprintId, false);\n view.setBigUint64(8, timestamp, false);\n return sha256(input);\n}\n\nfunction checkDifficulty(hash: Uint8Array, difficulty: number): boolean {\n const zeroBytes = Math.floor(difficulty / 8);\n const zeroBits = difficulty % 8;\n for (let i = 0; i < zeroBytes; i++) {\n if (hash[i] !== 0) return false;\n }\n if (zeroBits > 0) {\n const mask = 0xff << (8 - zeroBits);\n if ((hash[zeroBytes] & mask) !== 0) return false;\n }\n return true;\n}\n\nexport async function solvePoW(\n blueprintId: bigint,\n timestamp: bigint,\n): Promise<{ hash: Uint8Array; nonce: number; proof: Uint8Array }> {\n const challenge = generateChallenge(blueprintId, timestamp);\n const buf = new Uint8Array(challenge.length + 8);\n buf.set(challenge, 0);\n const view = new DataView(buf.buffer);\n\n for (let nonce = 0; nonce < 0x1_0000_0000; nonce++) {\n view.setBigUint64(challenge.length, BigInt(nonce), false);\n const hash = sha256(buf);\n if (checkDifficulty(hash, POW_DIFFICULTY)) {\n // Bincode-serialize Proof { hash: Vec<u8>, nonce: u64 }\n const proof = new Uint8Array(8 + 32 + 8);\n const pv = new DataView(proof.buffer);\n pv.setBigUint64(0, 32n, true);\n proof.set(hash, 8);\n pv.setBigUint64(40, BigInt(nonce), true);\n return { hash, nonce, proof };\n }\n // Yield to browser every 5000 iterations\n if (nonce % 5000 === 0 && nonce > 0) {\n await new Promise((r) => setTimeout(r, 0));\n }\n }\n throw new Error('PoW: exhausted nonce space');\n}\n\nexport function formatCost(totalCost: bigint): string {\n // totalCost is in wei (1e18 wei = 1 TNT)\n const tnt = Number(totalCost) / WEI_PER_TNT;\n if (tnt === 0) return '0 TNT';\n if (tnt < 0.001) return `${(tnt * 1_000_000).toFixed(2)} \\u03bcTNT`;\n if (tnt < 0.01) return `${(tnt * 1000).toFixed(2)} mTNT`;\n if (tnt < 1000) return `${tnt.toFixed(4)} TNT`;\n return `${tnt.toLocaleString(undefined, { maximumFractionDigits: 2 })} TNT`;\n}\n\nfunction quoteConfidentiality(requireTee: boolean): number {\n return requireTee ? 1 : 0;\n}\n\nfunction resourceKindToId(kind: string): number {\n const mapped = RESOURCE_KIND_TO_ID[kind as keyof typeof RESOURCE_KIND_TO_ID];\n if (mapped === undefined) {\n throw new Error(`Unsupported resource kind in quote: ${kind}`);\n }\n return mapped;\n}\n\nfunction mapJsonSecurityCommitment(sc: any): SecurityCommitment {\n return {\n asset: {\n kind: sc.asset?.kind ?? 0,\n token: (sc.asset?.token ?? ZERO_ADDRESS) as Address,\n },\n exposureBps: sc.exposure_bps ?? 0,\n };\n}\n\nfunction mapJsonResourceCommitment(resource: any): ResourceCommitment {\n return {\n kind: resourceKindToId(String(resource.kind ?? 'CPU')),\n count: BigInt(resource.count ?? 0),\n };\n}\n\n// ── Hook ──\n\nconst ZERO_ADDRESS_LOWER = ZERO_ADDRESS.toLowerCase();\n\n/**\n * Fetches signed `OperatorQuote` payloads from a set of operators for\n * `createServiceFromQuotes`.\n *\n * @param operators Operators discovered from the on-chain registry.\n * @param blueprintId Target blueprint id.\n * @param ttlBlocks Requested service TTL in blocks.\n * @param enabled Gate to disable fetching (e.g. while inputs settle).\n * @param requester Address that will submit `createServiceFromQuotes` —\n * must equal `msg.sender` at submission time. Required\n * since tnt-core v0.13.0; the contract rejects\n * `address(0)` and any mismatch.\n * @param requireTee If true, asks operators for TEE-attested quotes.\n */\nexport function useQuotes(\n operators: DiscoveredOperator[],\n blueprintId: bigint,\n ttlBlocks: bigint,\n enabled: boolean,\n requester: Address,\n requireTee = false,\n): UseQuotesResult {\n // Defensive guard: only assert when the caller has actually opted in via\n // `enabled`. This lets components compute `requester` from\n // `useAccount().address` and pass `enabled=false` until the wallet connects.\n if (enabled && (!requester || requester.toLowerCase() === ZERO_ADDRESS_LOWER)) {\n throw new Error(\n 'useQuotes: `requester` is required and must be a non-zero address when `enabled=true`. ' +\n 'Pass `useAccount().address` from wagmi. tnt-core v0.13.0 contracts ' +\n 'reject quotes whose requester is address(0) or != msg.sender.',\n );\n }\n const [quotes, setQuotes] = useState<OperatorQuote[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [isSolvingPow, setIsSolvingPow] = useState(false);\n const [errors, setErrors] = useState<Map<Address, string>>(new Map());\n const [fetchKey, setFetchKey] = useState(0);\n\n const refetch = useCallback(() => setFetchKey((k) => k + 1), []);\n\n useEffect(() => {\n if (!enabled || operators.length === 0) {\n // Only set state if it's actually non-empty to avoid triggering re-renders\n setQuotes((prev) => (prev.length === 0 ? prev : []));\n setErrors((prev) => (prev.size === 0 ? prev : new Map()));\n return;\n }\n\n let cancelled = false;\n setIsLoading(true);\n setIsSolvingPow(true);\n setQuotes([]);\n setErrors(new Map());\n\n async function fetchQuotes() {\n const results: OperatorQuote[] = [];\n const errs = new Map<Address, string>();\n\n const promises = operators.map(async (op) => {\n try {\n if (!op.rpcAddress) throw new Error('No RPC address registered');\n\n const rpcUrl = resolveOperatorRpc(op.rpcAddress);\n const timestamp = BigInt(Math.floor(Date.now() / 1000));\n\n // Solve PoW challenge\n if (!cancelled) setIsSolvingPow(true);\n const { proof } = await solvePoW(blueprintId, timestamp);\n if (!cancelled) setIsSolvingPow(false);\n\n // Try gRPC GetPrice endpoint\n // Since we may not have the generated protobuf types, try a JSON/REST\n // fallback first, then gRPC if available\n const response = await fetchPriceFromOperator(rpcUrl, {\n blueprintId,\n ttlBlocks,\n proofOfWork: proof,\n challengeTimestamp: timestamp,\n requireTee,\n requester,\n });\n\n if (!response) throw new Error('No quote returned from operator');\n\n if (!cancelled) results.push(response);\n } catch (err) {\n if (!cancelled) {\n errs.set(op.address, err instanceof Error ? err.message : String(err));\n }\n }\n });\n\n await Promise.allSettled(promises);\n\n if (!cancelled) {\n setQuotes(results);\n setErrors(errs);\n setIsLoading(false);\n setIsSolvingPow(false);\n }\n }\n\n fetchQuotes();\n return () => {\n cancelled = true;\n };\n }, [operators, blueprintId, ttlBlocks, enabled, fetchKey, requireTee, requester]);\n\n const totalCost = quotes.reduce((sum, q) => sum + q.totalCost, 0n);\n\n return { quotes, isLoading, isSolvingPow, errors, totalCost, refetch };\n}\n\n/**\n * Attempt to fetch a price from an operator's RPC endpoint.\n * Tries a JSON endpoint first (/pricing/quote), which operators may optionally expose.\n * Returns null if the operator doesn't support pricing.\n */\nasync function fetchPriceFromOperator(\n rpcUrl: string,\n params: {\n blueprintId: bigint;\n ttlBlocks: bigint;\n proofOfWork: Uint8Array;\n challengeTimestamp: bigint;\n requireTee: boolean;\n requester: Address;\n },\n): Promise<OperatorQuote | null> {\n // Try JSON endpoint (simpler, no protobuf dependency required)\n try {\n const response = await fetch(`${rpcUrl}/pricing/quote`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n blueprint_id: String(params.blueprintId),\n ttl_blocks: String(params.ttlBlocks),\n proof_of_work: toHex(params.proofOfWork),\n challenge_timestamp: String(params.challengeTimestamp),\n require_tee: params.requireTee,\n // tnt-core v0.13.0: bind the quote to the future caller. Operators\n // sign this address into QuoteDetails; the contract enforces\n // `requester == msg.sender`.\n requester: params.requester,\n resource_requirements: DEFAULT_RESOURCE_REQUIREMENTS,\n }),\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n const data = await response.json();\n\n return {\n operator: data.operator as Address,\n totalCost: BigInt(data.total_cost ?? '0'),\n signature: (data.signature ?? '0x') as `0x${string}`,\n costRate: Number(data.cost_rate ?? 0),\n teeAttested: Boolean(data.tee_attested),\n teeProvider: data.tee_provider || undefined,\n details: {\n // Prefer the operator-signed value; fall back to the hook's input.\n // If the operator returns a mismatched requester the contract will\n // revert at submission, so callers should still verify equality.\n requester: ((data.details?.requester as Address | undefined) ?? params.requester),\n blueprintId: BigInt(data.details?.blueprint_id ?? params.blueprintId),\n ttlBlocks: BigInt(data.details?.ttl_blocks ?? params.ttlBlocks),\n totalCost: BigInt(data.details?.total_cost ?? '0'),\n timestamp: BigInt(data.details?.timestamp ?? params.challengeTimestamp),\n expiry: BigInt(data.details?.expiry ?? '0'),\n confidentiality: Number(data.details?.confidentiality ?? quoteConfidentiality(params.requireTee)),\n securityCommitments: (data.details?.security_commitments ?? []).map(mapJsonSecurityCommitment),\n resourceCommitments: (data.details?.resources ?? []).map(mapJsonResourceCommitment),\n },\n };\n } catch {\n // JSON endpoint not available — operator doesn't have pricing engine\n return null;\n }\n}\n","import { useState, useEffect, useCallback, useRef } from 'react';\nimport type { Address } from 'viem';\nimport { toHex } from 'viem';\nimport { solvePoW, formatCost } from './useQuotes';\n\n/**\n * Per-job RFQ hook — fetches price quotes for a specific job before submission.\n *\n * Implements the GetJobPrice protocol:\n * 1. Solve PoW challenge (same as service-level RFQ)\n * 2. POST to operator's /pricing/job-quote endpoint\n * 3. Return signed JobQuoteDetails for submitJobFromQuote()\n *\n * This is the per-job counterpart to useQuotes (which handles service creation).\n * Together they provide full RFQ coverage for the UI.\n */\n\n// ── Types ──\n\nexport interface JobQuote {\n /**\n * Address of the account that will submit `submitJobFromQuote`.\n * Required since tnt-core v0.13.0 — the contract enforces\n * `requester == msg.sender` and rejects `address(0)` (no wildcard quotes).\n */\n requester: Address;\n serviceId: bigint;\n jobIndex: number;\n price: bigint;\n timestamp: bigint;\n expiry: bigint;\n signature: `0x${string}`;\n operatorAddress: Address;\n}\n\nexport interface UseJobPriceResult {\n quote: JobQuote | null;\n isLoading: boolean;\n isSolvingPow: boolean;\n error: string | null;\n formattedPrice: string;\n refetch: () => void;\n}\n\n/** Rewrite operator RPC hostname for browser reachability */\nfunction resolveOperatorRpc(raw: string): string {\n if (typeof window === 'undefined') return raw;\n const withProto = raw.includes('://') ? raw : `http://${raw}`;\n try {\n const url = new URL(withProto);\n const pageHost = window.location.hostname;\n const isNonRoutable =\n url.hostname.endsWith('.local') ||\n !url.hostname.includes('.') ||\n url.hostname === '127.0.0.1' ||\n url.hostname === 'localhost';\n if (isNonRoutable && pageHost !== url.hostname) {\n url.hostname = pageHost;\n }\n return url.toString().replace(/\\/$/, '');\n } catch {\n return withProto;\n }\n}\n\n// ── Hook ──\n\nconst ZERO_ADDRESS_LOWER = '0x0000000000000000000000000000000000000000';\n\n/**\n * Defensive guard: throws when a consumer enables fetching but has not\n * supplied a non-zero `requester`. Skipped when `enabled` is false so\n * components can pass a derived value (e.g. `address ?? ZERO`) before the\n * wallet has connected.\n */\nexport function assertRequester(requester: Address, hookName: string, enabled: boolean): void {\n if (!enabled) return;\n if (!requester || requester.toLowerCase() === ZERO_ADDRESS_LOWER) {\n throw new Error(\n `${hookName}: \\`requester\\` is required and must be a non-zero address when \\`enabled=true\\`. ` +\n 'Pass `useAccount().address` from wagmi. tnt-core v0.13.0 contracts ' +\n 'reject quotes whose requester is address(0) or != msg.sender.',\n );\n }\n}\n\n/**\n * Fetches a signed `JobQuote` for `submitJobFromQuote`.\n *\n * @param operatorRpcUrl Operator RPC base URL (e.g. from `getOperatorPreferences`).\n * @param serviceId Target service id.\n * @param jobIndex Job index within the blueprint.\n * @param blueprintId Blueprint id (used for the PoW challenge domain).\n * @param enabled Gate to disable fetching while inputs settle.\n * @param requester Address that will submit `submitJobFromQuote` —\n * must equal `msg.sender` at submission time. Required\n * since tnt-core v0.13.0; the contract rejects\n * `address(0)` and any mismatch.\n */\nexport function useJobPrice(\n operatorRpcUrl: string | undefined,\n serviceId: bigint,\n jobIndex: number,\n blueprintId: bigint,\n enabled: boolean,\n requester: Address,\n): UseJobPriceResult {\n assertRequester(requester, 'useJobPrice', enabled);\n const [quote, setQuote] = useState<JobQuote | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [isSolvingPow, setIsSolvingPow] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [fetchKey, setFetchKey] = useState(0);\n const cancelledRef = useRef(false);\n\n const refetch = useCallback(() => setFetchKey((k) => k + 1), []);\n\n useEffect(() => {\n if (!enabled || !operatorRpcUrl || serviceId === 0n) {\n setQuote(null);\n setError(null);\n return;\n }\n\n cancelledRef.current = false;\n setIsLoading(true);\n setError(null);\n setQuote(null);\n\n async function fetchJobQuote() {\n try {\n const rpcUrl = resolveOperatorRpc(operatorRpcUrl!);\n const timestamp = BigInt(Math.floor(Date.now() / 1000));\n\n // Solve PoW\n setIsSolvingPow(true);\n const { proof } = await solvePoW(blueprintId, timestamp);\n if (cancelledRef.current) return;\n setIsSolvingPow(false);\n\n // Fetch job price from operator\n const response = await fetch(`${rpcUrl}/pricing/job-quote`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n service_id: String(serviceId),\n job_index: jobIndex,\n proof_of_work: toHex(proof),\n challenge_timestamp: String(timestamp),\n // tnt-core v0.13.0: operators sign `requester` into JobQuoteDetails;\n // the contract enforces `requester == msg.sender` on submission.\n requester,\n }),\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${await response.text().catch(() => 'Unknown error')}`);\n }\n\n const data = await response.json();\n if (cancelledRef.current) return;\n\n setQuote({\n requester: ((data.requester as Address | undefined) ?? requester),\n serviceId: BigInt(data.service_id ?? serviceId),\n jobIndex: data.job_index ?? jobIndex,\n price: BigInt(data.price ?? '0'),\n timestamp: BigInt(data.timestamp ?? timestamp),\n expiry: BigInt(data.expiry ?? '0'),\n signature: (data.signature ?? '0x') as `0x${string}`,\n operatorAddress: data.operator as Address,\n });\n } catch (err) {\n if (!cancelledRef.current) {\n setError(err instanceof Error ? err.message : String(err));\n }\n } finally {\n if (!cancelledRef.current) {\n setIsLoading(false);\n setIsSolvingPow(false);\n }\n }\n }\n\n fetchJobQuote();\n return () => {\n cancelledRef.current = true;\n };\n }, [operatorRpcUrl, serviceId, jobIndex, blueprintId, enabled, fetchKey, requester]);\n\n const formattedPrice = quote ? formatCost(quote.price) : '--';\n\n return { quote, isLoading, isSolvingPow, error, formattedPrice, refetch };\n}\n\n/**\n * Batch version — fetches job prices for multiple jobs at once.\n * Used by the blueprint job list to show all prices simultaneously.\n */\nexport interface JobPriceEntry {\n jobIndex: number;\n jobName: string;\n price: bigint;\n formattedPrice: string;\n mode: 'flat' | 'dynamic' | 'free';\n quote: JobQuote | null;\n error: string | null;\n}\n\nexport interface UseJobPricesResult {\n prices: JobPriceEntry[];\n isLoading: boolean;\n error: string | null;\n refetch: () => void;\n}\n\n/**\n * Batch counterpart to {@link useJobPrice}. Same `requester` contract: the\n * caller must pass `useAccount().address`; the field is required since\n * tnt-core v0.13.0.\n */\nexport function useJobPrices(\n operatorRpcUrl: string | undefined,\n serviceId: bigint,\n blueprintId: bigint,\n jobIndexes: { index: number; name: string; multiplier: number }[],\n enabled: boolean,\n requester: Address,\n): UseJobPricesResult {\n assertRequester(requester, 'useJobPrices', enabled);\n const [prices, setPrices] = useState<JobPriceEntry[]>([]);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [fetchKey, setFetchKey] = useState(0);\n\n const refetch = useCallback(() => setFetchKey((k) => k + 1), []);\n\n useEffect(() => {\n if (!enabled || !operatorRpcUrl || serviceId === 0n || jobIndexes.length === 0) {\n setPrices([]);\n setError(null);\n return;\n }\n\n let cancelled = false;\n setIsLoading(true);\n setError(null);\n\n async function fetchAllPrices() {\n try {\n const rpcUrl = resolveOperatorRpc(operatorRpcUrl!);\n const timestamp = BigInt(Math.floor(Date.now() / 1000));\n const { proof } = await solvePoW(blueprintId, timestamp);\n if (cancelled) return;\n\n // Fetch all job prices in parallel\n const results = await Promise.allSettled(\n jobIndexes.map(async (job) => {\n const response = await fetch(`${rpcUrl}/pricing/job-quote`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n service_id: String(serviceId),\n job_index: job.index,\n proof_of_work: toHex(proof),\n challenge_timestamp: String(timestamp),\n // tnt-core v0.13.0: see useJobPrice notes.\n requester,\n }),\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) return null;\n return response.json();\n }),\n );\n\n if (cancelled) return;\n\n const entries: JobPriceEntry[] = jobIndexes.map((job, i) => {\n const result = results[i];\n if (result.status === 'fulfilled' && result.value) {\n const data = result.value;\n const price = BigInt(data.price ?? '0');\n return {\n jobIndex: job.index,\n jobName: job.name,\n price,\n formattedPrice: formatCost(price),\n mode: (data.mode ?? 'flat') as 'flat' | 'dynamic' | 'free',\n quote: {\n requester: ((data.requester as Address | undefined) ?? requester),\n serviceId: BigInt(data.service_id ?? serviceId),\n jobIndex: job.index,\n price,\n timestamp: BigInt(data.timestamp ?? timestamp),\n expiry: BigInt(data.expiry ?? '0'),\n signature: (data.signature ?? '0x') as `0x${string}`,\n operatorAddress: data.operator as Address,\n },\n error: null,\n };\n }\n // Fallback: estimate from multiplier (base rate = 0.001 TNT = 1e15 wei)\n const estimatedPrice = BigInt(job.multiplier) * 1_000_000_000_000_000n;\n return {\n jobIndex: job.index,\n jobName: job.name,\n price: estimatedPrice,\n formattedPrice: `~${formatCost(estimatedPrice)}`,\n mode: 'flat' as const,\n quote: null,\n error: 'No RFQ response — showing estimate',\n };\n });\n\n setPrices(entries);\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err.message : String(err));\n }\n } finally {\n if (!cancelled) {\n setIsLoading(false);\n }\n }\n }\n\n fetchAllPrices();\n return () => {\n cancelled = true;\n };\n }, [operatorRpcUrl, serviceId, blueprintId, jobIndexes, enabled, fetchKey, requester]);\n\n return { prices, isLoading, error, refetch };\n}\n","import { useCallback, useState, useMemo } from 'react';\nimport { useAccount, useWriteContract, useWaitForTransactionReceipt } from 'wagmi';\nimport { decodeEventLog } from 'viem';\nimport { tangleJobsAbi } from '../contracts/abi';\nimport { getAddresses } from '../contracts/publicClient';\nimport { addTx, updateTx } from '../stores/txHistory';\nimport { selectedChainIdStore } from '../contracts/publicClient';\nimport { useEffect } from 'react';\n\nexport interface SubmitJobOpts {\n serviceId: bigint;\n jobId: number;\n args: `0x${string}`;\n label?: string;\n value?: bigint;\n}\n\nexport type JobSubmitStatus = 'idle' | 'signing' | 'pending' | 'confirmed' | 'failed';\n\nexport function useSubmitJob() {\n const { address } = useAccount();\n const { writeContractAsync, data: hash, isPending: isSigning } = useWriteContract();\n const [status, setStatus] = useState<JobSubmitStatus>('idle');\n const [error, setError] = useState<string | null>(null);\n const [txHash, setTxHash] = useState<`0x${string}` | undefined>();\n\n const { data: receipt, isSuccess, isError } = useWaitForTransactionReceipt({\n hash: txHash,\n });\n\n // Extract callId from the JobCalled event in the receipt logs\n const callId = useMemo<number | null>(() => {\n if (!receipt?.logs) return null;\n for (const log of receipt.logs) {\n try {\n const decoded = decodeEventLog({\n abi: tangleJobsAbi,\n data: log.data,\n topics: log.topics,\n });\n if (decoded.eventName === 'JobCalled' && 'callId' in decoded.args) {\n return Number(decoded.args.callId);\n }\n } catch {\n // Not a matching event, skip\n }\n }\n return null;\n }, [receipt]);\n\n useEffect(() => {\n if (isSuccess && txHash) {\n setStatus('confirmed');\n updateTx(txHash, { status: 'confirmed' });\n }\n if (isError && txHash) {\n setStatus('failed');\n updateTx(txHash, { status: 'failed' });\n }\n }, [isSuccess, isError, txHash]);\n\n const submitJob = useCallback(\n async (opts: SubmitJobOpts) => {\n if (!address) {\n setError('Wallet not connected');\n return undefined;\n }\n\n const addrs = getAddresses();\n const label = opts.label ?? `Job #${opts.jobId}`;\n\n try {\n setStatus('signing');\n setError(null);\n\n const result = await writeContractAsync({\n address: addrs.jobs,\n abi: tangleJobsAbi,\n functionName: 'submitJob',\n args: [opts.serviceId, opts.jobId, opts.args],\n value: opts.value,\n });\n\n setTxHash(result);\n setStatus('pending');\n addTx(result, label, selectedChainIdStore.get());\n\n return result;\n } catch (err: any) {\n setStatus('failed');\n const msg = err?.shortMessage ?? err?.message ?? 'Transaction failed';\n setError(msg);\n return undefined;\n }\n },\n [address, writeContractAsync],\n );\n\n const reset = useCallback(() => {\n setStatus('idle');\n setError(null);\n setTxHash(undefined);\n }, []);\n\n return {\n submitJob,\n reset,\n status,\n error,\n txHash,\n callId,\n isSigning,\n isConnected: !!address,\n };\n}\n","import { useStore } from '@nanostores/react';\nimport { themeStore, type Theme } from '../stores/theme';\n\nexport function useThemeValue(): Theme {\n return useStore(themeStore);\n}\n","/**\n * Builds the operator registration command for a Tangle blueprint.\n *\n * Each blueprint app (trading arena, agent-sandbox, bazaar) used to reimplement\n * this — encoding the `registerOperator` call, building the CLI command, and\n * polling readiness. Lifted here so they install one hook instead of forking.\n */\nimport { useMemo } from 'react';\n\nexport type RegistrationMode = 'cargo-tangle' | 'cast';\n\nexport interface RegistrationCommandOptions {\n blueprintId: bigint;\n rpcAddress: string;\n ecdsaPublicKey: string;\n rpcUrl: string;\n registrationInputs?: string;\n mode?: RegistrationMode;\n /** Contract address for cast mode (defaults to TANGLE_CORE placeholder). */\n servicesAddress?: string;\n}\n\nexport interface RegistrationCommandResult {\n /** The copy-paste command for the operator to run on their VPS. */\n command: string;\n /** A human-readable label for the command type. */\n label: string;\n /** The blueprint id as a plain number (for display). */\n blueprintIdNumber: number;\n}\n\n/**\n * Builds the operator registration command string for the given blueprint.\n * Two modes:\n * - `cargo-tangle` (default) — the canonical `cargo tangle blueprint register` flow.\n * - `cast` — raw `cast send` for operators who manage their own keys.\n */\nexport function useRegistrationCommand(\n options: RegistrationCommandOptions,\n): RegistrationCommandResult {\n const {\n blueprintId,\n rpcAddress,\n ecdsaPublicKey,\n rpcUrl,\n registrationInputs = '0x',\n mode = 'cargo-tangle',\n servicesAddress = 'TANGLE_CORE',\n } = options;\n\n const blueprintIdNumber = Number(blueprintId);\n\n const command = useMemo(() => {\n if (mode === 'cast') {\n return [\n `cast send ${servicesAddress} \\\\`,\n ` \"registerOperator(uint64,bytes,string,bytes)\" \\\\`,\n ` ${blueprintIdNumber} \\\\`,\n ` ${ecdsaPublicKey} \\\\`,\n ` ${rpcAddress} \\\\`,\n ` ${registrationInputs} \\\\`,\n ` --rpc-url ${rpcUrl} \\\\`,\n ` --private-key <YOUR_OPERATOR_KEY>`,\n ].join('\\n');\n }\n\n const wsUrl = rpcUrl.replace(/^http/, 'ws');\n\n return [\n `cargo tangle blueprint register \\\\`,\n ` --blueprint-id ${blueprintIdNumber} \\\\`,\n ` --http-rpc-url ${rpcUrl} \\\\`,\n ` --ws-rpc-url ${wsUrl} \\\\`,\n ` --keystore-uri <YOUR_KEYSTORE> \\\\`,\n ` --rpc-address ${rpcAddress} \\\\`,\n ` --ecdsa-public-key ${ecdsaPublicKey}`,\n ].join('\\n');\n }, [blueprintIdNumber, ecdsaPublicKey, mode, registrationInputs, rpcAddress, rpcUrl, servicesAddress]);\n\n const label = mode === 'cast' ? 'cast send (raw)' : 'cargo-tangle (canonical)';\n\n return { command, label, blueprintIdNumber };\n}\n"],"mappings":"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","names":["atom","atom","atom","jsx","Slot","cva","jsx","cva","Slot","jsx","jsx","jsxs","useState","useEffect","useCallback","useState","useCallback","useEffect","rpcUrl","useState","useEffect","useCallback","toHex","resolveOperatorRpc","ZERO_ADDRESS_LOWER","useState","useCallback","useEffect","rpcUrl","toHex","useCallback","useState","useMemo","useEffect","useState","useMemo","useCallback","useMemo","rpcUrl"]}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// src/wallet/detectParentOrigin.ts
|
|
2
|
+
var TANGLE_CLOUD_ORIGINS_DEFAULT = Object.freeze([
|
|
3
|
+
"https://cloud.tangle.tools",
|
|
4
|
+
"https://develop.cloud.tangle.tools",
|
|
5
|
+
// Local dev (Vite default port for tangle-cloud + Netlify dev preview).
|
|
6
|
+
"http://localhost:4300",
|
|
7
|
+
"http://localhost:8888"
|
|
8
|
+
]);
|
|
9
|
+
function originFromReferrer() {
|
|
10
|
+
if (typeof document === "undefined") return null;
|
|
11
|
+
const ref = document.referrer;
|
|
12
|
+
if (!ref) return null;
|
|
13
|
+
try {
|
|
14
|
+
return new URL(ref).origin;
|
|
15
|
+
} catch {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
function detectTangleCloudParentOrigin(options = {}) {
|
|
20
|
+
if (typeof window === "undefined" || window.parent === window) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
const allowlist = /* @__PURE__ */ new Set([
|
|
24
|
+
...TANGLE_CLOUD_ORIGINS_DEFAULT,
|
|
25
|
+
...options.extraOrigins ?? []
|
|
26
|
+
]);
|
|
27
|
+
const referrerOrigin = originFromReferrer();
|
|
28
|
+
if (referrerOrigin && allowlist.has(referrerOrigin)) {
|
|
29
|
+
return referrerOrigin;
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
const url = new URL(window.location.href);
|
|
33
|
+
const explicit = url.searchParams.get("parent");
|
|
34
|
+
if (explicit && allowlist.has(explicit)) return explicit;
|
|
35
|
+
} catch {
|
|
36
|
+
}
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// src/wallet/parentBridgeProtocol.ts
|
|
41
|
+
var TANGLE_IFRAME_PROTOCOL_VERSION = "1";
|
|
42
|
+
var TANGLE_IFRAME_PROTOCOL_PREFIX = "tangle.app.";
|
|
43
|
+
var NO_WALLET_ADDRESS = "0x0000000000000000000000000000000000000000";
|
|
44
|
+
function makeCorrelationId(prefix) {
|
|
45
|
+
const random = typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : Math.random().toString(36).slice(2) + Date.now().toString(36);
|
|
46
|
+
return `${prefix}.${random}`;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export {
|
|
50
|
+
TANGLE_CLOUD_ORIGINS_DEFAULT,
|
|
51
|
+
detectTangleCloudParentOrigin,
|
|
52
|
+
TANGLE_IFRAME_PROTOCOL_VERSION,
|
|
53
|
+
TANGLE_IFRAME_PROTOCOL_PREFIX,
|
|
54
|
+
NO_WALLET_ADDRESS,
|
|
55
|
+
makeCorrelationId
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=chunk-TM5ROMDV.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/wallet/detectParentOrigin.ts","../src/wallet/parentBridgeProtocol.ts"],"sourcesContent":["// Determine which origin to trust as the parent dapp.\n//\n// `document.referrer` is the *initial* embedder — it's set when the iframe is\n// first loaded and survives reloads (though it can be cleared by `referrerpolicy`\n// or by the embedder). The Tangle Cloud iframe wrapper deliberately omits\n// `referrerpolicy=\"no-referrer\"` so we get the embedder's origin here.\n//\n// We compare it against an allowlist of known Tangle Cloud origins. If it\n// matches, that's the parent. Otherwise the iframe is being loaded directly\n// (standalone domain visit, dev server, untrusted embedder) and the bridge\n// stays disabled — the app falls back to its normal injected/WC wallet path.\n\n/**\n * Default Tangle Cloud origins. Consumers (agent-sandbox UI,\n * trading-arena, future iframe blueprints) pass app-specific additions\n * via `extraOrigins` rather than mutating this list.\n */\nexport const TANGLE_CLOUD_ORIGINS_DEFAULT = Object.freeze([\n 'https://cloud.tangle.tools',\n 'https://develop.cloud.tangle.tools',\n // Local dev (Vite default port for tangle-cloud + Netlify dev preview).\n 'http://localhost:4300',\n 'http://localhost:8888',\n] as const);\n\nfunction originFromReferrer(): string | null {\n if (typeof document === 'undefined') return null;\n const ref = document.referrer;\n if (!ref) return null;\n try {\n return new URL(ref).origin;\n } catch {\n return null;\n }\n}\n\n/**\n * Returns the parent origin to bridge to, or null when no trusted parent is\n * detected. Caller should skip installing the bridge connector when this\n * returns null.\n *\n * `extraOrigins` is the application's escape hatch for staging or dev\n * deploys not covered by the default list. The library deliberately does\n * not read environment variables itself (consumers may bundle for non-Vite\n * runtimes); the consuming app threads `import.meta.env.VITE_*` or\n * `process.env.*` in itself.\n *\n * Falls back to a `?parent=<origin>` query parameter when no referrer is\n * present (some browsers strip referrer from cross-origin loads). Useful\n * for dev embedding flows.\n */\nexport function detectTangleCloudParentOrigin(\n options: { extraOrigins?: readonly string[] } = {},\n): string | null {\n if (typeof window === 'undefined' || window.parent === window) {\n return null;\n }\n const allowlist = new Set<string>([\n ...TANGLE_CLOUD_ORIGINS_DEFAULT,\n ...(options.extraOrigins ?? []),\n ]);\n const referrerOrigin = originFromReferrer();\n if (referrerOrigin && allowlist.has(referrerOrigin)) {\n return referrerOrigin;\n }\n try {\n const url = new URL(window.location.href);\n const explicit = url.searchParams.get('parent');\n if (explicit && allowlist.has(explicit)) return explicit;\n } catch {\n // ignore\n }\n return null;\n}\n","// Tangle Cloud iframe ↔ parent dapp protocol — must mirror the parent's\n// spec at `apps/tangle-cloud/src/blueprintApps/iframe/protocol.ts`. Bump the\n// version constant in lockstep when either side adds a request kind.\n\nimport type { Address, Hex } from 'viem';\n\nexport const TANGLE_IFRAME_PROTOCOL_VERSION = '1' as const;\nexport const TANGLE_IFRAME_PROTOCOL_PREFIX = 'tangle.app.';\n\n// ─── Iframe → Parent requests ────────────────────────────────────────────────\n\nexport type HandshakeRequest = {\n kind: 'tangle.app.handshake';\n appId: string;\n version: typeof TANGLE_IFRAME_PROTOCOL_VERSION;\n};\n\nexport type ReadAccountRequest = {\n kind: 'tangle.app.readAccount';\n correlationId: string;\n};\n\n// Ask the parent to ensure a wallet is connected — opening its connect modal\n// if none is. A sandboxed iframe can't reach a wallet extension itself, so\n// this is the *only* way an iframe can initiate a connection: it delegates to\n// the parent, which owns the wallet. Resolves once the parent has an account.\nexport type RequestConnectRequest = {\n kind: 'tangle.app.requestConnect';\n correlationId: string;\n};\n\nexport type SwitchChainRequest = {\n kind: 'tangle.app.switchChain';\n correlationId: string;\n chainId: number;\n};\n\nexport type SignMessageRequest = {\n kind: 'tangle.app.signMessage';\n correlationId: string;\n chainId: number;\n message: string;\n};\n\nexport type SignTransactionRequest = {\n kind: 'tangle.app.signTransaction';\n correlationId: string;\n chainId: number;\n to: Address;\n data: Hex;\n value?: string;\n};\n\n// EIP-712 typed-data signing for publishers that need to sign custom message\n// shapes — operator envelopes, off-chain attestations, claim proofs, etc.\n// The parent renders the typed-data fields in its approval modal so the user\n// can audit what they're signing. Iframes never see the wallet's signing key\n// or private state.\n//\n// Shape mirrors viem's `signTypedData` argument: `domain` + `types` (without\n// the EIP712Domain entry — viem injects it) + `primaryType` + `message`.\n// Validation on the parent side rejects payloads that are obviously\n// malformed (missing primaryType, types map empty, etc.) but does NOT\n// re-shape the message — the user is the one who decides whether to sign.\nexport type SignTypedDataRequest = {\n kind: 'tangle.app.signTypedData';\n correlationId: string;\n chainId: number;\n domain: Readonly<{\n name?: string;\n version?: string;\n chainId?: number;\n verifyingContract?: Address;\n salt?: Hex;\n }>;\n /** EIP-712 types map; do NOT include the EIP712Domain entry (the parent\n * injects it derived from `domain`). */\n types: Readonly<Record<string, ReadonlyArray<{ name: string; type: string }>>>;\n /** Top-level type name in `types` whose values appear in `message`. */\n primaryType: string;\n /** The actual typed-data values. Shape matches `types[primaryType]`. */\n message: Readonly<Record<string, unknown>>;\n};\n\n// ─── Parent → Iframe messages ────────────────────────────────────────────────\n\nexport type HandshakeAck = {\n kind: 'tangle.app.handshakeAck';\n appId: string;\n protocolVersion: typeof TANGLE_IFRAME_PROTOCOL_VERSION;\n};\n\nexport type ResultEnvelope<T> = { correlationId: string } & (\n | { ok: true; data: T }\n | { ok: false; error: string }\n);\n\nexport type ReadAccountResult = {\n kind: 'tangle.app.readAccountResult';\n} & ResultEnvelope<{ account: Address; chainId: number }>;\n\nexport type ConnectResult = {\n kind: 'tangle.app.connectResult';\n} & ResultEnvelope<{ account: Address; chainId: number }>;\n\nexport type SwitchChainResult = {\n kind: 'tangle.app.switchChainResult';\n} & ResultEnvelope<{ chainId: number }>;\n\nexport type SignMessageResult = {\n kind: 'tangle.app.signMessageResult';\n} & ResultEnvelope<{ signature: Hex }>;\n\nexport type SignTransactionResult = {\n kind: 'tangle.app.signTransactionResult';\n} & ResultEnvelope<{ txHash: Hex }>;\n\nexport type SignTypedDataResult = {\n kind: 'tangle.app.signTypedDataResult';\n} & ResultEnvelope<{ signature: Hex }>;\n\nexport type AccountChanged = {\n kind: 'tangle.app.accountChanged';\n account: Address | null;\n};\n\nexport type ChainChanged = {\n kind: 'tangle.app.chainChanged';\n chainId: number;\n};\n\n// ─── Service context (parent → iframe) ──────────────────────────────────────\n//\n// Iframe blueprints embedded by Tangle Cloud need to know which service +\n// blueprint they're rendering for, plus which operators are quoted. The\n// parent broadcasts this on mount and on every change (mode picker swap,\n// new service activation, operator delta). The iframe just reads — it\n// doesn't query the chain itself.\n//\n// The thin-iframe SDK exposes this as `useTangleService()`. Iframes that\n// use the full wagmi connector path can still listen to `serviceContext`\n// for routing convenience.\n\nexport type ServiceContextOperator = {\n readonly address: Address;\n readonly rpcAddress: string | undefined;\n readonly status: 'active' | 'inactive' | 'unknown';\n};\n\nexport type ServiceContextJob = {\n readonly index: number;\n readonly name: string;\n readonly inputSchema?: unknown;\n};\n\n/**\n * Chain configuration the parent broadcasts to the iframe along with\n * service context. Iframes use this to build a `viem` public client for\n * READ-ONLY queries (`useTanglePublicClient` is the convenience hook).\n *\n * Iframes can ignore this and roll their own RPC config — particularly\n * when they need to read from chains OTHER than the active one (e.g. a\n * trading dapp pulling oracle data from mainnet while the active service\n * lives on Base Sepolia). The injected client is a hint, not a constraint.\n *\n * `rpcUrl` is the public RPC the parent uses, NOT a wallet RPC. Iframes\n * cannot sign or submit with this URL; signing always routes upstream via\n * the bridge.\n */\nexport type ChainContext = {\n readonly id: number;\n readonly name: string;\n readonly rpcUrl: string;\n /** Block-explorer base URL — useful for rendering tx links. */\n readonly blockExplorerUrl?: string;\n /** Native currency metadata for cost displays. */\n readonly nativeCurrency?: { readonly name: string; readonly symbol: string; readonly decimals: number };\n};\n\nexport type ServiceContextBroadcast = {\n kind: 'tangle.app.serviceContext';\n readonly blueprintId: string;\n readonly serviceId: string | null;\n readonly operators: readonly ServiceContextOperator[];\n readonly jobs: readonly ServiceContextJob[];\n readonly mode: string | null;\n /** Active chain the parent is connected to; iframes can build a viem\n * publicClient against this for convenience. Optional for backwards\n * compatibility with parents that haven't been upgraded yet. */\n readonly chain?: ChainContext;\n};\n\n// ─── Job invocation (iframe ↔ parent) ────────────────────────────────────────\n//\n// Instead of the iframe wiring up its own EIP-712 quote / sign / submit\n// flow, it sends a single CallJob request upstream. The parent does the\n// whole dance (fetch RFQ quote, build typed data, request user signature,\n// submit on-chain) and streams results back. The iframe never touches\n// chain logic.\n\nexport type JobInputs = Readonly<Record<string, unknown>>;\n\nexport type CallJobRequest = {\n kind: 'tangle.app.callJob';\n correlationId: string;\n /** Job index within the blueprint, e.g. 0 for the primary entry-point. */\n jobIndex: number;\n /** Free-form inputs validated by the parent against the on-chain ABI. */\n inputs: JobInputs;\n /**\n * Whether the publisher wants intermediate progress (streaming chunks)\n * or just the terminal result. Streaming jobs (LLM generation, video\n * encode) opt in; one-shots (embeddings, classifications) don't.\n */\n stream?: boolean;\n};\n\nexport type JobResultStatus = 'pending' | 'streaming' | 'success' | 'error';\n\nexport type JobResultEvent = {\n kind: 'tangle.app.jobResult';\n correlationId: string;\n status: JobResultStatus;\n /** Present on `streaming` and `success`. Shape is publisher-defined. */\n data?: unknown;\n /** Present on `streaming` only — incremental chunk for live UI. */\n chunk?: unknown;\n /** Present on `error`. Human-readable. */\n error?: string;\n /** Optional progress metadata (e.g. `{ percent: 0.42, eta_ms: 8000 }`). */\n progress?: { readonly percent?: number; readonly eta_ms?: number };\n};\n\nexport type ParentMessage =\n | HandshakeAck\n | ReadAccountResult\n | ConnectResult\n | SwitchChainResult\n | SignMessageResult\n | SignTransactionResult\n | SignTypedDataResult\n | AccountChanged\n | ChainChanged\n | ServiceContextBroadcast\n | JobResultEvent;\n\nexport type IframeRequest =\n | HandshakeRequest\n | ReadAccountRequest\n | RequestConnectRequest\n | SwitchChainRequest\n | SignMessageRequest\n | SignTransactionRequest\n | SignTypedDataRequest\n | CallJobRequest;\n\n// The zero address used by the parent when no wallet is connected. The parent\n// always responds to readAccount with an address; this sentinel means \"no\n// wallet\" without making the response type a union of result shapes.\nexport const NO_WALLET_ADDRESS = '0x0000000000000000000000000000000000000000';\n\n/**\n * Cryptographically-random ASCII correlation id matching the parent's\n * validator regex (`/^[\\w.\\-:]+$/`, max length 128). The connector keeps a\n * Map<correlationId, Resolver> so each request resolves independently.\n */\nexport function makeCorrelationId(prefix: string): string {\n const random =\n typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function'\n ? crypto.randomUUID()\n : Math.random().toString(36).slice(2) + Date.now().toString(36);\n return `${prefix}.${random}`;\n}\n"],"mappings":";AAiBO,IAAM,+BAA+B,OAAO,OAAO;AAAA,EACxD;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AACF,CAAU;AAEV,SAAS,qBAAoC;AAC3C,MAAI,OAAO,aAAa,YAAa,QAAO;AAC5C,QAAM,MAAM,SAAS;AACrB,MAAI,CAAC,IAAK,QAAO;AACjB,MAAI;AACF,WAAO,IAAI,IAAI,GAAG,EAAE;AAAA,EACtB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAiBO,SAAS,8BACd,UAAgD,CAAC,GAClC;AACf,MAAI,OAAO,WAAW,eAAe,OAAO,WAAW,QAAQ;AAC7D,WAAO;AAAA,EACT;AACA,QAAM,YAAY,oBAAI,IAAY;AAAA,IAChC,GAAG;AAAA,IACH,GAAI,QAAQ,gBAAgB,CAAC;AAAA,EAC/B,CAAC;AACD,QAAM,iBAAiB,mBAAmB;AAC1C,MAAI,kBAAkB,UAAU,IAAI,cAAc,GAAG;AACnD,WAAO;AAAA,EACT;AACA,MAAI;AACF,UAAM,MAAM,IAAI,IAAI,OAAO,SAAS,IAAI;AACxC,UAAM,WAAW,IAAI,aAAa,IAAI,QAAQ;AAC9C,QAAI,YAAY,UAAU,IAAI,QAAQ,EAAG,QAAO;AAAA,EAClD,QAAQ;AAAA,EAER;AACA,SAAO;AACT;;;ACnEO,IAAM,iCAAiC;AACvC,IAAM,gCAAgC;AA4PtC,IAAM,oBAAoB;AAO1B,SAAS,kBAAkB,QAAwB;AACxD,QAAM,SACJ,OAAO,WAAW,eAAe,OAAO,OAAO,eAAe,aAC1D,OAAO,WAAW,IAClB,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,IAAI,KAAK,IAAI,EAAE,SAAS,EAAE;AAClE,SAAO,GAAG,MAAM,IAAI,MAAM;AAC5B;","names":[]}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
3
|
+
import * as React$1 from 'react';
|
|
4
|
+
import { ReactNode, FC } from 'react';
|
|
5
|
+
import { VariantProps } from 'class-variance-authority';
|
|
6
|
+
import { f as JobFieldDef, J as JobDefinition, R as RegistrationCommandOptions } from './useRegistrationCommand-Df1mvvwE.js';
|
|
7
|
+
export { a as BlueprintHostHero, c as BlueprintHostPanel, k as Button, l as buttonVariants } from './useRegistrationCommand-Df1mvvwE.js';
|
|
8
|
+
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
9
|
+
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
10
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
11
|
+
import { Address } from 'viem';
|
|
12
|
+
import { Config } from 'wagmi';
|
|
13
|
+
|
|
14
|
+
declare const badgeVariants: (props?: ({
|
|
15
|
+
variant?: "default" | "success" | "secondary" | "destructive" | "outline" | "accent" | "amber" | "running" | "stopped" | "cold" | null | undefined;
|
|
16
|
+
} & class_variance_authority_types.ClassProp) | undefined) => string;
|
|
17
|
+
declare function Badge({ className, variant, asChild, ...props }: React$1.ComponentProps<'span'> & VariantProps<typeof badgeVariants> & {
|
|
18
|
+
asChild?: boolean;
|
|
19
|
+
}): react_jsx_runtime.JSX.Element;
|
|
20
|
+
|
|
21
|
+
declare function Card({ className, ...props }: React$1.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
22
|
+
declare function CardHeader({ className, ...props }: React$1.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
23
|
+
declare function CardTitle({ className, ...props }: React$1.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
24
|
+
declare function CardDescription({ className, ...props }: React$1.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
25
|
+
declare function CardContent({ className, ...props }: React$1.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
26
|
+
declare function CardFooter({ className, ...props }: React$1.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
27
|
+
|
|
28
|
+
declare function Dialog({ ...props }: React$1.ComponentProps<typeof DialogPrimitive.Root>): react_jsx_runtime.JSX.Element;
|
|
29
|
+
declare function DialogTrigger({ ...props }: React$1.ComponentProps<typeof DialogPrimitive.Trigger>): react_jsx_runtime.JSX.Element;
|
|
30
|
+
declare function DialogContent({ className, children, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Content>): react_jsx_runtime.JSX.Element;
|
|
31
|
+
declare function DialogHeader({ className, ...props }: React$1.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
32
|
+
declare function DialogFooter({ className, ...props }: React$1.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
33
|
+
declare function DialogTitle({ className, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Title>): react_jsx_runtime.JSX.Element;
|
|
34
|
+
declare function DialogDescription({ className, ...props }: React$1.ComponentProps<typeof DialogPrimitive.Description>): react_jsx_runtime.JSX.Element;
|
|
35
|
+
|
|
36
|
+
declare function Input({ className, type, ...props }: React$1.ComponentProps<'input'>): react_jsx_runtime.JSX.Element;
|
|
37
|
+
|
|
38
|
+
interface SelectOption {
|
|
39
|
+
label: string;
|
|
40
|
+
value: string;
|
|
41
|
+
}
|
|
42
|
+
interface SelectProps {
|
|
43
|
+
value?: string;
|
|
44
|
+
onValueChange?: (value: string) => void;
|
|
45
|
+
options: SelectOption[];
|
|
46
|
+
placeholder?: string;
|
|
47
|
+
className?: string;
|
|
48
|
+
disabled?: boolean;
|
|
49
|
+
}
|
|
50
|
+
declare function Select({ value, onValueChange, options, placeholder, className, disabled }: SelectProps): react_jsx_runtime.JSX.Element;
|
|
51
|
+
|
|
52
|
+
declare function Separator({ className, orientation, decorative, ...props }: React$1.ComponentProps<typeof SeparatorPrimitive.Root>): react_jsx_runtime.JSX.Element;
|
|
53
|
+
|
|
54
|
+
declare function Skeleton({ className, ...props }: React.ComponentProps<'div'>): react_jsx_runtime.JSX.Element;
|
|
55
|
+
|
|
56
|
+
declare function Table({ className, ...props }: React$1.ComponentProps<'table'>): react_jsx_runtime.JSX.Element;
|
|
57
|
+
declare function TableHeader({ className, ...props }: React$1.ComponentProps<'thead'>): react_jsx_runtime.JSX.Element;
|
|
58
|
+
declare function TableBody({ className, ...props }: React$1.ComponentProps<'tbody'>): react_jsx_runtime.JSX.Element;
|
|
59
|
+
declare function TableRow({ className, ...props }: React$1.ComponentProps<'tr'>): react_jsx_runtime.JSX.Element;
|
|
60
|
+
declare function TableHead({ className, ...props }: React$1.ComponentProps<'th'>): react_jsx_runtime.JSX.Element;
|
|
61
|
+
declare function TableCell({ className, ...props }: React$1.ComponentProps<'td'>): react_jsx_runtime.JSX.Element;
|
|
62
|
+
|
|
63
|
+
declare function Tabs({ className, ...props }: React$1.ComponentProps<typeof TabsPrimitive.Root>): react_jsx_runtime.JSX.Element;
|
|
64
|
+
declare function TabsList({ className, ...props }: React$1.ComponentProps<typeof TabsPrimitive.List>): react_jsx_runtime.JSX.Element;
|
|
65
|
+
declare function TabsTrigger({ className, ...props }: React$1.ComponentProps<typeof TabsPrimitive.Trigger>): react_jsx_runtime.JSX.Element;
|
|
66
|
+
declare function TabsContent({ className, ...props }: React$1.ComponentProps<typeof TabsPrimitive.Content>): react_jsx_runtime.JSX.Element;
|
|
67
|
+
|
|
68
|
+
declare function Textarea({ className, ...props }: React$1.ComponentProps<'textarea'>): react_jsx_runtime.JSX.Element;
|
|
69
|
+
|
|
70
|
+
interface ToggleProps {
|
|
71
|
+
checked: boolean;
|
|
72
|
+
onChange: (checked: boolean) => void;
|
|
73
|
+
disabled?: boolean;
|
|
74
|
+
className?: string;
|
|
75
|
+
}
|
|
76
|
+
declare function Toggle({ checked, onChange, disabled, className }: ToggleProps): react_jsx_runtime.JSX.Element;
|
|
77
|
+
|
|
78
|
+
declare function AnimatedPage({ children, className }: {
|
|
79
|
+
children: React.ReactNode;
|
|
80
|
+
className?: string;
|
|
81
|
+
}): react_jsx_runtime.JSX.Element;
|
|
82
|
+
declare function StaggerContainer({ children, className }: {
|
|
83
|
+
children: React.ReactNode;
|
|
84
|
+
className?: string;
|
|
85
|
+
}): react_jsx_runtime.JSX.Element;
|
|
86
|
+
declare function StaggerItem({ children, className }: {
|
|
87
|
+
children: React.ReactNode;
|
|
88
|
+
className?: string;
|
|
89
|
+
}): react_jsx_runtime.JSX.Element;
|
|
90
|
+
|
|
91
|
+
interface IdenticonProps {
|
|
92
|
+
address: Address;
|
|
93
|
+
size?: number;
|
|
94
|
+
className?: string;
|
|
95
|
+
}
|
|
96
|
+
declare function Identicon({ address, size, className }: IdenticonProps): react_jsx_runtime.JSX.Element;
|
|
97
|
+
|
|
98
|
+
interface TangleLogoProps {
|
|
99
|
+
label?: string;
|
|
100
|
+
}
|
|
101
|
+
declare function TangleLogo({ label }: TangleLogoProps): react_jsx_runtime.JSX.Element;
|
|
102
|
+
|
|
103
|
+
interface AppDocumentProps {
|
|
104
|
+
children: ReactNode;
|
|
105
|
+
description: string;
|
|
106
|
+
themeStorageKeys: [string, string];
|
|
107
|
+
}
|
|
108
|
+
declare function AppDocument({ children, description, themeStorageKeys }: AppDocumentProps): react_jsx_runtime.JSX.Element;
|
|
109
|
+
|
|
110
|
+
interface AppFooterProps {
|
|
111
|
+
brandText: string;
|
|
112
|
+
tone: 'cloud' | 'arena';
|
|
113
|
+
githubUrl?: string;
|
|
114
|
+
docsUrl?: string;
|
|
115
|
+
}
|
|
116
|
+
declare function AppFooter({ brandText, tone, githubUrl, docsUrl, }: AppFooterProps): react_jsx_runtime.JSX.Element;
|
|
117
|
+
|
|
118
|
+
interface AppToasterProps {
|
|
119
|
+
tone: 'cloud' | 'arena';
|
|
120
|
+
}
|
|
121
|
+
declare function AppToaster({ tone }: AppToasterProps): react_jsx_runtime.JSX.Element;
|
|
122
|
+
|
|
123
|
+
interface Web3ShellProps {
|
|
124
|
+
config: Config;
|
|
125
|
+
reconnectOnMount?: boolean;
|
|
126
|
+
children: ReactNode;
|
|
127
|
+
}
|
|
128
|
+
declare function Web3Shell({ config, reconnectOnMount, children, }: Web3ShellProps): react_jsx_runtime.JSX.Element;
|
|
129
|
+
|
|
130
|
+
declare function ChainSwitcher(): react_jsx_runtime.JSX.Element;
|
|
131
|
+
|
|
132
|
+
declare function ThemeToggle(): react_jsx_runtime.JSX.Element;
|
|
133
|
+
|
|
134
|
+
interface ConnectWalletCtaProps {
|
|
135
|
+
onClick?: () => void;
|
|
136
|
+
isReconnecting?: boolean;
|
|
137
|
+
}
|
|
138
|
+
declare function ConnectWalletCta({ onClick, isReconnecting }: ConnectWalletCtaProps): react_jsx_runtime.JSX.Element;
|
|
139
|
+
|
|
140
|
+
interface FormFieldProps {
|
|
141
|
+
field: JobFieldDef;
|
|
142
|
+
value: unknown;
|
|
143
|
+
onChange: (name: string, value: unknown) => void;
|
|
144
|
+
error?: string;
|
|
145
|
+
}
|
|
146
|
+
declare function FormField({ field, value, onChange, error }: FormFieldProps): react_jsx_runtime.JSX.Element | null;
|
|
147
|
+
|
|
148
|
+
interface FormSection {
|
|
149
|
+
label: string;
|
|
150
|
+
fields: string[];
|
|
151
|
+
collapsed?: boolean;
|
|
152
|
+
}
|
|
153
|
+
interface BlueprintJobFormProps {
|
|
154
|
+
job: JobDefinition;
|
|
155
|
+
values: Record<string, unknown>;
|
|
156
|
+
onChange: (name: string, value: unknown) => void;
|
|
157
|
+
errors?: Record<string, string>;
|
|
158
|
+
sections?: FormSection[];
|
|
159
|
+
}
|
|
160
|
+
declare function BlueprintJobForm({ job, values, onChange, errors, sections }: BlueprintJobFormProps): react_jsx_runtime.JSX.Element;
|
|
161
|
+
|
|
162
|
+
interface FormSummaryProps {
|
|
163
|
+
job: JobDefinition;
|
|
164
|
+
values: Record<string, unknown>;
|
|
165
|
+
context?: Record<string, unknown>;
|
|
166
|
+
}
|
|
167
|
+
declare function FormSummary({ job, values, context }: FormSummaryProps): react_jsx_runtime.JSX.Element;
|
|
168
|
+
|
|
169
|
+
interface JobExecutionDialogProps {
|
|
170
|
+
open: boolean;
|
|
171
|
+
onOpenChange: (open: boolean) => void;
|
|
172
|
+
job: JobDefinition;
|
|
173
|
+
serviceId: bigint;
|
|
174
|
+
context?: Record<string, unknown>;
|
|
175
|
+
onSuccess?: () => void;
|
|
176
|
+
}
|
|
177
|
+
declare function JobExecutionDialog({ open, onOpenChange, job, serviceId, context, onSuccess, }: JobExecutionDialogProps): react_jsx_runtime.JSX.Element;
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* OperatorOnboardingGuide — shared component for operator registration.
|
|
181
|
+
*
|
|
182
|
+
* Renders the registration command (cargo-tangle or cast) with a copy button.
|
|
183
|
+
* Each blueprint app (trading, sandbox, bazaar) used to reimplement this;
|
|
184
|
+
* now they install <OperatorOnboardingGuide> and pass their blueprint config.
|
|
185
|
+
*/
|
|
186
|
+
|
|
187
|
+
interface OperatorOnboardingGuideProps extends RegistrationCommandOptions {
|
|
188
|
+
/** Optional title override. Defaults to "Register as operator". */
|
|
189
|
+
title?: string;
|
|
190
|
+
/** Optional description shown above the command. */
|
|
191
|
+
description?: string;
|
|
192
|
+
}
|
|
193
|
+
declare const OperatorOnboardingGuide: FC<OperatorOnboardingGuideProps>;
|
|
194
|
+
|
|
195
|
+
export { AnimatedPage, AppDocument, AppFooter, AppToaster, Badge, BlueprintJobForm, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, ChainSwitcher, ConnectWalletCta, Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, FormField, type FormSection, FormSummary, Identicon, Input, JobExecutionDialog, OperatorOnboardingGuide, Select, type SelectOption, Separator, Skeleton, StaggerContainer, StaggerItem, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TangleLogo, Textarea, ThemeToggle, Toggle, Web3Shell, badgeVariants };
|