@tangle-network/blueprint-ui 0.5.2 → 0.5.4
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-5PCH2RJF.js → chunk-F2QBCGUW.js} +44 -2
- package/dist/chunk-F2QBCGUW.js.map +1 -0
- package/dist/components.d.ts +20 -4
- package/dist/components.js +39 -1
- package/dist/components.js.map +1 -1
- package/dist/index.d.ts +19 -3
- package/dist/index.js +32 -1
- package/dist/index.js.map +1 -1
- package/dist/styles.css +5 -0
- package/dist/{BlueprintHostPanel-L1KKLNbr.d.ts → useRegistrationCommand-BvqgHBiJ.d.ts} +28 -1
- package/dist/wallet/index.d.ts +41 -1
- package/dist/wallet/index.js +19 -1
- package/dist/wallet/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/OperatorOnboardingGuide.tsx +61 -0
- package/src/components.ts +4 -0
- package/src/hooks/useRegistrationCommand.ts +83 -0
- package/src/hooks/useServiceRequest.ts +52 -0
- package/src/index.ts +8 -0
- package/src/wallet/index.ts +23 -17
- package/src/wallet/tangleConnectors.test.ts +18 -0
- package/src/wallet/tangleConnectors.ts +62 -0
- package/dist/chunk-5PCH2RJF.js.map +0 -1
|
@@ -1461,6 +1461,47 @@ function useThemeValue() {
|
|
|
1461
1461
|
return useStore(themeStore);
|
|
1462
1462
|
}
|
|
1463
1463
|
|
|
1464
|
+
// src/hooks/useRegistrationCommand.ts
|
|
1465
|
+
import { useMemo as useMemo3 } from "react";
|
|
1466
|
+
function useRegistrationCommand(options) {
|
|
1467
|
+
const {
|
|
1468
|
+
blueprintId,
|
|
1469
|
+
rpcAddress,
|
|
1470
|
+
ecdsaPublicKey,
|
|
1471
|
+
rpcUrl: rpcUrl2,
|
|
1472
|
+
registrationInputs = "0x",
|
|
1473
|
+
mode = "cargo-tangle",
|
|
1474
|
+
servicesAddress = "TANGLE_CORE"
|
|
1475
|
+
} = options;
|
|
1476
|
+
const blueprintIdNumber = Number(blueprintId);
|
|
1477
|
+
const command = useMemo3(() => {
|
|
1478
|
+
if (mode === "cast") {
|
|
1479
|
+
return [
|
|
1480
|
+
`cast send ${servicesAddress} \\`,
|
|
1481
|
+
` "registerOperator(uint64,bytes,string,bytes)" \\`,
|
|
1482
|
+
` ${blueprintIdNumber} \\`,
|
|
1483
|
+
` ${ecdsaPublicKey} \\`,
|
|
1484
|
+
` ${rpcAddress} \\`,
|
|
1485
|
+
` ${registrationInputs} \\`,
|
|
1486
|
+
` --rpc-url ${rpcUrl2} \\`,
|
|
1487
|
+
` --private-key <YOUR_OPERATOR_KEY>`
|
|
1488
|
+
].join("\n");
|
|
1489
|
+
}
|
|
1490
|
+
const wsUrl = rpcUrl2.replace(/^http/, "ws");
|
|
1491
|
+
return [
|
|
1492
|
+
`cargo tangle blueprint register \\`,
|
|
1493
|
+
` --blueprint-id ${blueprintIdNumber} \\`,
|
|
1494
|
+
` --http-rpc-url ${rpcUrl2} \\`,
|
|
1495
|
+
` --ws-rpc-url ${wsUrl} \\`,
|
|
1496
|
+
` --keystore-uri <YOUR_KEYSTORE> \\`,
|
|
1497
|
+
` --rpc-address ${rpcAddress} \\`,
|
|
1498
|
+
` --ecdsa-public-key ${ecdsaPublicKey}`
|
|
1499
|
+
].join("\n");
|
|
1500
|
+
}, [blueprintIdNumber, ecdsaPublicKey, mode, registrationInputs, rpcAddress, rpcUrl2, servicesAddress]);
|
|
1501
|
+
const label = mode === "cast" ? "cast send (raw)" : "cargo-tangle (canonical)";
|
|
1502
|
+
return { command, label, blueprintIdNumber };
|
|
1503
|
+
}
|
|
1504
|
+
|
|
1464
1505
|
export {
|
|
1465
1506
|
cn,
|
|
1466
1507
|
resolveOperatorRpc,
|
|
@@ -1535,6 +1576,7 @@ export {
|
|
|
1535
1576
|
useJobPrice,
|
|
1536
1577
|
useJobPrices,
|
|
1537
1578
|
useSubmitJob,
|
|
1538
|
-
useThemeValue
|
|
1579
|
+
useThemeValue,
|
|
1580
|
+
useRegistrationCommand
|
|
1539
1581
|
};
|
|
1540
|
-
//# sourceMappingURL=chunk-
|
|
1582
|
+
//# sourceMappingURL=chunk-F2QBCGUW.js.map
|
|
@@ -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"]}
|
package/dist/components.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as class_variance_authority_types from 'class-variance-authority/types';
|
|
3
3
|
import * as React$1 from 'react';
|
|
4
|
-
import { ReactNode } from 'react';
|
|
4
|
+
import { ReactNode, FC } from 'react';
|
|
5
5
|
import { VariantProps } from 'class-variance-authority';
|
|
6
|
-
import { f as JobFieldDef, J as JobDefinition } from './
|
|
7
|
-
export { a as BlueprintHostHero, c as BlueprintHostPanel,
|
|
6
|
+
import { f as JobFieldDef, J as JobDefinition, R as RegistrationCommandOptions } from './useRegistrationCommand-BvqgHBiJ.js';
|
|
7
|
+
export { a as BlueprintHostHero, c as BlueprintHostPanel, m as Button, n as buttonVariants } from './useRegistrationCommand-BvqgHBiJ.js';
|
|
8
8
|
import * as DialogPrimitive from '@radix-ui/react-dialog';
|
|
9
9
|
import * as SeparatorPrimitive from '@radix-ui/react-separator';
|
|
10
10
|
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
@@ -176,4 +176,20 @@ interface JobExecutionDialogProps {
|
|
|
176
176
|
}
|
|
177
177
|
declare function JobExecutionDialog({ open, onOpenChange, job, serviceId, context, onSuccess, }: JobExecutionDialogProps): react_jsx_runtime.JSX.Element;
|
|
178
178
|
|
|
179
|
-
|
|
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, type OperatorOnboardingGuideProps, Select, type SelectOption, Separator, Skeleton, StaggerContainer, StaggerItem, Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TangleLogo, Textarea, ThemeToggle, Toggle, Web3Shell, badgeVariants };
|
package/dist/components.js
CHANGED
|
@@ -20,9 +20,10 @@ import {
|
|
|
20
20
|
toggleTheme,
|
|
21
21
|
useJobForm,
|
|
22
22
|
useJobPrice,
|
|
23
|
+
useRegistrationCommand,
|
|
23
24
|
useSubmitJob,
|
|
24
25
|
useThemeValue
|
|
25
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-F2QBCGUW.js";
|
|
26
27
|
|
|
27
28
|
// src/components/ui/dialog.tsx
|
|
28
29
|
import * as DialogPrimitive from "@radix-ui/react-dialog";
|
|
@@ -1074,6 +1075,42 @@ function JobExecutionDialog({
|
|
|
1074
1075
|
] })
|
|
1075
1076
|
] }) });
|
|
1076
1077
|
}
|
|
1078
|
+
|
|
1079
|
+
// src/components/OperatorOnboardingGuide.tsx
|
|
1080
|
+
import { useCallback, useState as useState4 } from "react";
|
|
1081
|
+
import { jsx as jsx24, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
1082
|
+
var OperatorOnboardingGuide = ({
|
|
1083
|
+
title = "Register as operator",
|
|
1084
|
+
description = "Run this command on your operator VPS to register for this blueprint on-chain.",
|
|
1085
|
+
...commandOptions
|
|
1086
|
+
}) => {
|
|
1087
|
+
const { command, label, blueprintIdNumber } = useRegistrationCommand(commandOptions);
|
|
1088
|
+
const [copied, setCopied] = useState4(false);
|
|
1089
|
+
const handleCopy = useCallback(() => {
|
|
1090
|
+
navigator.clipboard.writeText(command).then(() => {
|
|
1091
|
+
setCopied(true);
|
|
1092
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
1093
|
+
});
|
|
1094
|
+
}, [command]);
|
|
1095
|
+
return /* @__PURE__ */ jsxs13("div", { className: "space-y-4", children: [
|
|
1096
|
+
/* @__PURE__ */ jsxs13("div", { children: [
|
|
1097
|
+
/* @__PURE__ */ jsx24("h3", { className: "text-lg font-semibold text-foreground", children: title }),
|
|
1098
|
+
/* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground mt-1", children: description })
|
|
1099
|
+
] }),
|
|
1100
|
+
/* @__PURE__ */ jsxs13("div", { className: "rounded-lg border border-border bg-muted/30 p-4", children: [
|
|
1101
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center justify-between mb-2", children: [
|
|
1102
|
+
/* @__PURE__ */ jsxs13("span", { className: "text-xs font-mono text-muted-foreground uppercase tracking-wider", children: [
|
|
1103
|
+
"Blueprint #",
|
|
1104
|
+
blueprintIdNumber,
|
|
1105
|
+
" \xB7 ",
|
|
1106
|
+
label
|
|
1107
|
+
] }),
|
|
1108
|
+
/* @__PURE__ */ jsx24(Button, { size: "sm", variant: "outline", onClick: handleCopy, children: copied ? "Copied!" : "Copy" })
|
|
1109
|
+
] }),
|
|
1110
|
+
/* @__PURE__ */ jsx24("pre", { className: "text-sm font-mono text-foreground overflow-x-auto whitespace-pre-wrap break-all", children: command })
|
|
1111
|
+
] })
|
|
1112
|
+
] });
|
|
1113
|
+
};
|
|
1077
1114
|
export {
|
|
1078
1115
|
AnimatedPage,
|
|
1079
1116
|
AppDocument,
|
|
@@ -1104,6 +1141,7 @@ export {
|
|
|
1104
1141
|
Identicon,
|
|
1105
1142
|
Input,
|
|
1106
1143
|
JobExecutionDialog,
|
|
1144
|
+
OperatorOnboardingGuide,
|
|
1107
1145
|
Select,
|
|
1108
1146
|
Separator,
|
|
1109
1147
|
Skeleton,
|