@tangle-network/blueprint-ui 0.1.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{registry-JhwB9BPD.d.ts → BlueprintHostPanel-L1KKLNbr.d.ts} +38 -1
- package/dist/{chunk-A6PJT5YQ.js → chunk-5PCH2RJF.js} +370 -10
- package/dist/chunk-5PCH2RJF.js.map +1 -0
- package/dist/components.d.ts +2 -2
- package/dist/components.js +18 -15
- package/dist/components.js.map +1 -1
- package/dist/index.d.ts +142 -8
- package/dist/index.js +19 -21
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -0
- package/dist/wallet/index.d.ts +188 -0
- package/dist/wallet/index.js +466 -0
- package/dist/wallet/index.js.map +1 -0
- package/package.json +16 -15
- package/src/components/forms/JobExecutionDialog.tsx +10 -2
- package/src/contracts/abi.ts +3 -0
- package/src/hooks/useJobPrice.test.ts +214 -0
- package/src/hooks/useJobPrice.ts +56 -2
- package/src/hooks/useQuotes.ts +44 -1
- package/src/test-setup.ts +1 -0
- package/src/wallet/detectParentOrigin.ts +74 -0
- package/src/wallet/index.ts +67 -0
- package/src/wallet/parentBridgeConnector.ts +156 -0
- package/src/wallet/parentBridgeProtocol.ts +109 -0
- package/src/wallet/parentBridgeProvider.test.ts +209 -0
- package/src/wallet/parentBridgeProvider.ts +411 -0
- package/tsconfig.json +1 -1
- package/dist/BlueprintHostPanel-6iVEh-f1.d.ts +0 -39
- package/dist/chunk-A6PJT5YQ.js.map +0 -1
- package/dist/chunk-GD3AZEJL.js +0 -327
- package/dist/chunk-GD3AZEJL.js.map +0 -1
- package/dist/host.d.ts +0 -96
- package/dist/host.js +0 -39
- package/dist/host.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -6,10 +6,8 @@ import * as nanostores from 'nanostores';
|
|
|
6
6
|
import { WritableAtom } from 'nanostores';
|
|
7
7
|
import * as node_modules_viem__types_actions_siwe_verifySiweMessage from 'node_modules/viem/_types/actions/siwe/verifySiweMessage';
|
|
8
8
|
import * as node_modules_viem__types_utils_ccip from 'node_modules/viem/_types/utils/ccip';
|
|
9
|
-
import { J as JobDefinition } from './
|
|
10
|
-
export { A as AbiContextParam, B as BlueprintDefinition, a as
|
|
11
|
-
export { BlueprintAppEntry, BlueprintAppModuleBinding, BlueprintAppResolvedView, BlueprintAppVisibility, BlueprintExperienceTier, BlueprintExternalAppConfig, BlueprintExternalAppMode, BlueprintExternalAppTrust, BlueprintPermissionDescriptor, BlueprintPermissionScope, BlueprintPublisher, BlueprintPublisherVerification, BlueprintResourceModel, BlueprintResourceRoute, BlueprintSlugPolicy, BlueprintUiManifest, BlueprintUiSurface, buildCanonicalBlueprintSlug, canPublisherClaimSlug, deriveBlueprintRequestedSlug, getBlueprintExperienceTierLabel, getBlueprintPath, getBlueprintPublisherVerificationLabel, getBlueprintServicePath, getBlueprintSlugPolicyLabel, getBlueprintSurfaceLabel, getExternalAppTrustLabel, isTrustedExternalAppHost, isVerifiedBlueprintPublisher, resolveBlueprintAppView, sanitizeBlueprintSlugPart, toBlueprintAppEntry } from './host.js';
|
|
12
|
-
export { B as BlueprintHostHero, a as BlueprintHostHeroProps, b as BlueprintHostPanel, c as BlueprintHostPanelProps } from './BlueprintHostPanel-6iVEh-f1.js';
|
|
9
|
+
import { J as JobDefinition } from './BlueprintHostPanel-L1KKLNbr.js';
|
|
10
|
+
export { A as AbiContextParam, B as BlueprintDefinition, a as BlueprintHostHero, b as BlueprintHostHeroProps, c as BlueprintHostPanel, d as BlueprintHostPanelProps, e as JobCategory, f as JobFieldDef, g as getAllBlueprints, h as getBlueprint, i as getBlueprintJobs, j as getJobById, r as registerBlueprint } from './BlueprintHostPanel-L1KKLNbr.js';
|
|
13
11
|
export { mainnet } from 'viem/chains';
|
|
14
12
|
import 'react/jsx-runtime';
|
|
15
13
|
import 'react';
|
|
@@ -295,6 +293,9 @@ declare const tangleServicesAbi: readonly [{
|
|
|
295
293
|
readonly name: "details";
|
|
296
294
|
readonly type: "tuple";
|
|
297
295
|
readonly components: readonly [{
|
|
296
|
+
readonly name: "requester";
|
|
297
|
+
readonly type: "address";
|
|
298
|
+
}, {
|
|
298
299
|
readonly name: "blueprintId";
|
|
299
300
|
readonly type: "uint64";
|
|
300
301
|
}, {
|
|
@@ -8171,6 +8172,95 @@ declare function getAddresses<T extends CoreAddresses = CoreAddresses>(): T;
|
|
|
8171
8172
|
*/
|
|
8172
8173
|
declare function encodeJobArgs(job: JobDefinition, formValues: Record<string, unknown>, context?: Record<string, unknown>): `0x${string}`;
|
|
8173
8174
|
|
|
8175
|
+
type BlueprintAppVisibility = 'first-party' | 'third-party';
|
|
8176
|
+
type BlueprintPublisherVerification = 'first-party' | 'verified' | 'unverified';
|
|
8177
|
+
type BlueprintExperienceTier = 'generic' | 'declarative' | 'curated-module' | 'external-app';
|
|
8178
|
+
type BlueprintSlugPolicy = 'reserved' | 'publisher-scoped' | 'public-requested';
|
|
8179
|
+
type BlueprintUiSurface = 'generic-overview' | 'service-explorer' | 'service-console' | 'actions-panel' | 'resources' | 'chat' | 'vaults' | 'metrics' | 'permissions';
|
|
8180
|
+
type BlueprintResourceRoute = 'bots' | 'agents' | 'runs' | 'vault' | 'chat' | 'custom';
|
|
8181
|
+
type BlueprintPermissionScope = 'blueprint' | 'service' | 'resource';
|
|
8182
|
+
type BlueprintExternalAppMode = 'link' | 'iframe';
|
|
8183
|
+
type BlueprintExternalAppTrust = 'trusted' | 'restricted';
|
|
8184
|
+
type BlueprintPublisher = {
|
|
8185
|
+
label: string;
|
|
8186
|
+
namespace?: string;
|
|
8187
|
+
visibility: BlueprintAppVisibility;
|
|
8188
|
+
verification: BlueprintPublisherVerification;
|
|
8189
|
+
};
|
|
8190
|
+
type BlueprintResourceModel = {
|
|
8191
|
+
serviceNoun: string;
|
|
8192
|
+
resourceNoun: string;
|
|
8193
|
+
resourceRoute?: BlueprintResourceRoute;
|
|
8194
|
+
};
|
|
8195
|
+
type BlueprintPermissionDescriptor = {
|
|
8196
|
+
key: string;
|
|
8197
|
+
label: string;
|
|
8198
|
+
scope: BlueprintPermissionScope;
|
|
8199
|
+
description?: string;
|
|
8200
|
+
};
|
|
8201
|
+
type BlueprintExternalAppConfig = {
|
|
8202
|
+
url: string;
|
|
8203
|
+
mode: BlueprintExternalAppMode;
|
|
8204
|
+
label?: string;
|
|
8205
|
+
host: string;
|
|
8206
|
+
trust: BlueprintExternalAppTrust;
|
|
8207
|
+
reason?: string;
|
|
8208
|
+
};
|
|
8209
|
+
type BlueprintUiManifest = {
|
|
8210
|
+
displayName: string;
|
|
8211
|
+
tagline: string;
|
|
8212
|
+
description: string;
|
|
8213
|
+
surfaces: BlueprintUiSurface[];
|
|
8214
|
+
resources: BlueprintResourceModel;
|
|
8215
|
+
permissions?: BlueprintPermissionDescriptor[];
|
|
8216
|
+
externalApp?: BlueprintExternalAppConfig;
|
|
8217
|
+
};
|
|
8218
|
+
type BlueprintAppModuleBinding = {
|
|
8219
|
+
moduleId: string;
|
|
8220
|
+
status: 'active' | 'planned';
|
|
8221
|
+
};
|
|
8222
|
+
type BlueprintAppEntry = {
|
|
8223
|
+
slug: string;
|
|
8224
|
+
canonicalSlug?: string;
|
|
8225
|
+
blueprintId?: bigint;
|
|
8226
|
+
publisher: BlueprintPublisher;
|
|
8227
|
+
tier: BlueprintExperienceTier;
|
|
8228
|
+
slugPolicy: BlueprintSlugPolicy;
|
|
8229
|
+
manifest: BlueprintUiManifest;
|
|
8230
|
+
module?: BlueprintAppModuleBinding;
|
|
8231
|
+
};
|
|
8232
|
+
type BlueprintAppResolvedView = {
|
|
8233
|
+
slug: string;
|
|
8234
|
+
canonicalSlug: string;
|
|
8235
|
+
blueprintId?: bigint;
|
|
8236
|
+
publisher: BlueprintPublisher;
|
|
8237
|
+
tier: BlueprintExperienceTier;
|
|
8238
|
+
slugPolicy: BlueprintSlugPolicy;
|
|
8239
|
+
manifest: BlueprintUiManifest;
|
|
8240
|
+
module?: BlueprintAppModuleBinding;
|
|
8241
|
+
fallbackEnabled: boolean;
|
|
8242
|
+
};
|
|
8243
|
+
|
|
8244
|
+
declare function buildCanonicalBlueprintSlug(entry: BlueprintAppEntry): string;
|
|
8245
|
+
declare function resolveBlueprintAppView(entry: BlueprintAppEntry): BlueprintAppResolvedView;
|
|
8246
|
+
declare function toBlueprintAppEntry(view: BlueprintAppResolvedView): BlueprintAppEntry;
|
|
8247
|
+
declare function getBlueprintExperienceTierLabel(tier: BlueprintExperienceTier): string;
|
|
8248
|
+
declare function getBlueprintSlugPolicyLabel(policy: BlueprintSlugPolicy): string;
|
|
8249
|
+
declare function getBlueprintSurfaceLabel(surface: BlueprintUiSurface): string;
|
|
8250
|
+
declare function getBlueprintPublisherVerificationLabel(verification: BlueprintPublisherVerification): string;
|
|
8251
|
+
declare function getExternalAppTrustLabel(trust: BlueprintExternalAppTrust): string;
|
|
8252
|
+
declare function isVerifiedBlueprintPublisher(publisher: BlueprintPublisher): boolean;
|
|
8253
|
+
declare function canPublisherClaimSlug(slug: string, publisher?: Pick<BlueprintPublisher, 'namespace' | 'verification'>, reservedSlugs?: Set<string>): boolean;
|
|
8254
|
+
declare function isTrustedExternalAppHost(host: string, trustedHosts?: readonly string[]): boolean;
|
|
8255
|
+
declare function getBlueprintPath(view: BlueprintAppResolvedView): string;
|
|
8256
|
+
declare function getBlueprintServicePath(view: BlueprintAppResolvedView, serviceId: string): string;
|
|
8257
|
+
declare function sanitizeBlueprintSlugPart(value: string): string;
|
|
8258
|
+
declare function deriveBlueprintRequestedSlug(blueprint: Pick<{
|
|
8259
|
+
name: string;
|
|
8260
|
+
author: string;
|
|
8261
|
+
id: bigint;
|
|
8262
|
+
}, 'name' | 'author' | 'id'>): string;
|
|
8263
|
+
|
|
8174
8264
|
interface DiscoveredOperator {
|
|
8175
8265
|
address: Address;
|
|
8176
8266
|
ecdsaPublicKey: string;
|
|
@@ -8224,6 +8314,12 @@ declare function useJobForm(job: JobDefinition | null): JobFormState;
|
|
|
8224
8314
|
* Together they provide full RFQ coverage for the UI.
|
|
8225
8315
|
*/
|
|
8226
8316
|
interface JobQuote {
|
|
8317
|
+
/**
|
|
8318
|
+
* Address of the account that will submit `submitJobFromQuote`.
|
|
8319
|
+
* Required since tnt-core v0.13.0 — the contract enforces
|
|
8320
|
+
* `requester == msg.sender` and rejects `address(0)` (no wildcard quotes).
|
|
8321
|
+
*/
|
|
8322
|
+
requester: Address;
|
|
8227
8323
|
serviceId: bigint;
|
|
8228
8324
|
jobIndex: number;
|
|
8229
8325
|
price: bigint;
|
|
@@ -8240,7 +8336,20 @@ interface UseJobPriceResult {
|
|
|
8240
8336
|
formattedPrice: string;
|
|
8241
8337
|
refetch: () => void;
|
|
8242
8338
|
}
|
|
8243
|
-
|
|
8339
|
+
/**
|
|
8340
|
+
* Fetches a signed `JobQuote` for `submitJobFromQuote`.
|
|
8341
|
+
*
|
|
8342
|
+
* @param operatorRpcUrl Operator RPC base URL (e.g. from `getOperatorPreferences`).
|
|
8343
|
+
* @param serviceId Target service id.
|
|
8344
|
+
* @param jobIndex Job index within the blueprint.
|
|
8345
|
+
* @param blueprintId Blueprint id (used for the PoW challenge domain).
|
|
8346
|
+
* @param enabled Gate to disable fetching while inputs settle.
|
|
8347
|
+
* @param requester Address that will submit `submitJobFromQuote` —
|
|
8348
|
+
* must equal `msg.sender` at submission time. Required
|
|
8349
|
+
* since tnt-core v0.13.0; the contract rejects
|
|
8350
|
+
* `address(0)` and any mismatch.
|
|
8351
|
+
*/
|
|
8352
|
+
declare function useJobPrice(operatorRpcUrl: string | undefined, serviceId: bigint, jobIndex: number, blueprintId: bigint, enabled: boolean, requester: Address): UseJobPriceResult;
|
|
8244
8353
|
/**
|
|
8245
8354
|
* Batch version — fetches job prices for multiple jobs at once.
|
|
8246
8355
|
* Used by the blueprint job list to show all prices simultaneously.
|
|
@@ -8260,11 +8369,16 @@ interface UseJobPricesResult {
|
|
|
8260
8369
|
error: string | null;
|
|
8261
8370
|
refetch: () => void;
|
|
8262
8371
|
}
|
|
8372
|
+
/**
|
|
8373
|
+
* Batch counterpart to {@link useJobPrice}. Same `requester` contract: the
|
|
8374
|
+
* caller must pass `useAccount().address`; the field is required since
|
|
8375
|
+
* tnt-core v0.13.0.
|
|
8376
|
+
*/
|
|
8263
8377
|
declare function useJobPrices(operatorRpcUrl: string | undefined, serviceId: bigint, blueprintId: bigint, jobIndexes: {
|
|
8264
8378
|
index: number;
|
|
8265
8379
|
name: string;
|
|
8266
8380
|
multiplier: number;
|
|
8267
|
-
}[], enabled: boolean): UseJobPricesResult;
|
|
8381
|
+
}[], enabled: boolean, requester: Address): UseJobPricesResult;
|
|
8268
8382
|
|
|
8269
8383
|
interface ServiceInfo {
|
|
8270
8384
|
active: boolean;
|
|
@@ -8327,6 +8441,12 @@ interface OperatorQuote {
|
|
|
8327
8441
|
totalCost: bigint;
|
|
8328
8442
|
signature: `0x${string}`;
|
|
8329
8443
|
details: {
|
|
8444
|
+
/**
|
|
8445
|
+
* Address of the account that will submit `createServiceFromQuotes`.
|
|
8446
|
+
* Required since tnt-core v0.13.0 — the contract enforces
|
|
8447
|
+
* `requester == msg.sender` and rejects `address(0)` (no wildcard quotes).
|
|
8448
|
+
*/
|
|
8449
|
+
requester: Address;
|
|
8330
8450
|
blueprintId: bigint;
|
|
8331
8451
|
ttlBlocks: bigint;
|
|
8332
8452
|
totalCost: bigint;
|
|
@@ -8354,7 +8474,21 @@ declare function solvePoW(blueprintId: bigint, timestamp: bigint): Promise<{
|
|
|
8354
8474
|
proof: Uint8Array;
|
|
8355
8475
|
}>;
|
|
8356
8476
|
declare function formatCost(totalCost: bigint): string;
|
|
8357
|
-
|
|
8477
|
+
/**
|
|
8478
|
+
* Fetches signed `OperatorQuote` payloads from a set of operators for
|
|
8479
|
+
* `createServiceFromQuotes`.
|
|
8480
|
+
*
|
|
8481
|
+
* @param operators Operators discovered from the on-chain registry.
|
|
8482
|
+
* @param blueprintId Target blueprint id.
|
|
8483
|
+
* @param ttlBlocks Requested service TTL in blocks.
|
|
8484
|
+
* @param enabled Gate to disable fetching (e.g. while inputs settle).
|
|
8485
|
+
* @param requester Address that will submit `createServiceFromQuotes` —
|
|
8486
|
+
* must equal `msg.sender` at submission time. Required
|
|
8487
|
+
* since tnt-core v0.13.0; the contract rejects
|
|
8488
|
+
* `address(0)` and any mismatch.
|
|
8489
|
+
* @param requireTee If true, asks operators for TEE-attested quotes.
|
|
8490
|
+
*/
|
|
8491
|
+
declare function useQuotes(operators: DiscoveredOperator[], blueprintId: bigint, ttlBlocks: bigint, enabled: boolean, requester: Address, requireTee?: boolean): UseQuotesResult;
|
|
8358
8492
|
|
|
8359
8493
|
interface SubmitJobOpts {
|
|
8360
8494
|
serviceId: bigint;
|
|
@@ -8467,4 +8601,4 @@ interface UseWalletEthBalanceResult {
|
|
|
8467
8601
|
}
|
|
8468
8602
|
declare function useWalletEthBalance({ address, refreshKey, readBalance, pollMs, onError, }: UseWalletEthBalanceOptions): UseWalletEthBalanceResult;
|
|
8469
8603
|
|
|
8470
|
-
export { type CoreAddresses, DEFAULT_THEME, type DiscoveredOperator, type InfraConfig, JobDefinition, type JobFormState, type JobPriceEntry, type JobQuote, type JobSubmitStatus, type NetworkConfig, type OperatorInfo, type OperatorQuote, type ProvisionPhase, type ProvisionStatus, type ServiceInfo, type SessionEntry, type SidecarAuth, type SubmitJobOpts, type Theme, type TrackedTx, type UseJobPriceResult, type UseJobPricesResult, type UseQuotesResult, type UseSidecarAuthOptions, addTx, allTangleChains, clearTxs, cn, configureNetworks, createTangleLocalChain, createTangleTransports, defaultConnectKitOptions, deserializeWithBigInt, discoverOperatorsWithClient, encodeJobArgs, formatCost, gcSessions, getAddresses, getInfra, getNetworks, getPhaseLabel, getPublicClient, getSession, getTangleWalletChains, infraStore, isTerminalPhase, kTheme, pendingCount, persistedAtom, publicClient, publicClientStore, removeSession, resolveOperatorRpc, resolveRpcUrl, rpcUrl, sanitizeSelectedChainId, selectedChainIdStore, serializeWithBigInt, sessionMapStore, setSession, solvePoW, tangleJobsAbi, tangleLocal, tangleMainnet, tangleOperatorsAbi, tangleServicesAbi, tangleTestnet, tangleWalletChains, themeIsDark, themeStore, toggleTheme, txListStore, updateInfra, updateTx, useAuthenticatedFetch, useJobForm, useJobPrice, useJobPrices, useOperators, useProvisionProgress, useQuotes, useServiceValidation, useSessionAuth, useSidecarAuth, useSubmitJob, useThemeValue, useWagmiSidecarAuth, useWalletEthBalance };
|
|
8604
|
+
export { type BlueprintAppEntry, type BlueprintAppModuleBinding, type BlueprintAppResolvedView, type BlueprintAppVisibility, type BlueprintExperienceTier, type BlueprintExternalAppConfig, type BlueprintExternalAppMode, type BlueprintExternalAppTrust, type BlueprintPermissionDescriptor, type BlueprintPermissionScope, type BlueprintPublisher, type BlueprintPublisherVerification, type BlueprintResourceModel, type BlueprintResourceRoute, type BlueprintSlugPolicy, type BlueprintUiManifest, type BlueprintUiSurface, type CoreAddresses, DEFAULT_THEME, type DiscoveredOperator, type InfraConfig, JobDefinition, type JobFormState, type JobPriceEntry, type JobQuote, type JobSubmitStatus, type NetworkConfig, type OperatorInfo, type OperatorQuote, type ProvisionPhase, type ProvisionStatus, type ServiceInfo, type SessionEntry, type SidecarAuth, type SubmitJobOpts, type Theme, type TrackedTx, type UseJobPriceResult, type UseJobPricesResult, type UseQuotesResult, type UseSidecarAuthOptions, addTx, allTangleChains, buildCanonicalBlueprintSlug, canPublisherClaimSlug, clearTxs, cn, configureNetworks, createTangleLocalChain, createTangleTransports, defaultConnectKitOptions, deriveBlueprintRequestedSlug, deserializeWithBigInt, discoverOperatorsWithClient, encodeJobArgs, formatCost, gcSessions, getAddresses, getBlueprintExperienceTierLabel, getBlueprintPath, getBlueprintPublisherVerificationLabel, getBlueprintServicePath, getBlueprintSlugPolicyLabel, getBlueprintSurfaceLabel, getExternalAppTrustLabel, getInfra, getNetworks, getPhaseLabel, getPublicClient, getSession, getTangleWalletChains, infraStore, isTerminalPhase, isTrustedExternalAppHost, isVerifiedBlueprintPublisher, kTheme, pendingCount, persistedAtom, publicClient, publicClientStore, removeSession, resolveBlueprintAppView, resolveOperatorRpc, resolveRpcUrl, rpcUrl, sanitizeBlueprintSlugPart, sanitizeSelectedChainId, selectedChainIdStore, serializeWithBigInt, sessionMapStore, setSession, solvePoW, tangleJobsAbi, tangleLocal, tangleMainnet, tangleOperatorsAbi, tangleServicesAbi, tangleTestnet, tangleWalletChains, themeIsDark, themeStore, toBlueprintAppEntry, toggleTheme, txListStore, updateInfra, updateTx, useAuthenticatedFetch, useJobForm, useJobPrice, useJobPrices, useOperators, useProvisionProgress, useQuotes, useServiceValidation, useSessionAuth, useSidecarAuth, useSubmitJob, useThemeValue, useWagmiSidecarAuth, useWalletEthBalance };
|
package/dist/index.js
CHANGED
|
@@ -1,28 +1,45 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BlueprintHostHero,
|
|
3
|
+
BlueprintHostPanel,
|
|
2
4
|
DEFAULT_THEME,
|
|
3
5
|
addTx,
|
|
4
6
|
allTangleChains,
|
|
7
|
+
buildCanonicalBlueprintSlug,
|
|
8
|
+
canPublisherClaimSlug,
|
|
5
9
|
clearTxs,
|
|
10
|
+
cn,
|
|
6
11
|
configureNetworks,
|
|
7
12
|
createTangleLocalChain,
|
|
13
|
+
deriveBlueprintRequestedSlug,
|
|
8
14
|
deserializeWithBigInt,
|
|
9
15
|
encodeJobArgs,
|
|
10
16
|
formatCost,
|
|
11
17
|
getAddresses,
|
|
18
|
+
getBlueprintExperienceTierLabel,
|
|
19
|
+
getBlueprintPath,
|
|
20
|
+
getBlueprintPublisherVerificationLabel,
|
|
21
|
+
getBlueprintServicePath,
|
|
22
|
+
getBlueprintSlugPolicyLabel,
|
|
23
|
+
getBlueprintSurfaceLabel,
|
|
12
24
|
getEnvVar,
|
|
25
|
+
getExternalAppTrustLabel,
|
|
13
26
|
getInfra,
|
|
14
27
|
getNetworks,
|
|
15
28
|
getPublicClient,
|
|
16
29
|
infraStore,
|
|
30
|
+
isTrustedExternalAppHost,
|
|
31
|
+
isVerifiedBlueprintPublisher,
|
|
17
32
|
kTheme,
|
|
18
33
|
mainnet,
|
|
19
34
|
pendingCount,
|
|
20
35
|
persistedAtom,
|
|
21
36
|
publicClient,
|
|
22
37
|
publicClientStore,
|
|
38
|
+
resolveBlueprintAppView,
|
|
23
39
|
resolveOperatorRpc,
|
|
24
40
|
resolveRpcUrl,
|
|
25
41
|
rpcUrl,
|
|
42
|
+
sanitizeBlueprintSlugPart,
|
|
26
43
|
sanitizeSelectedChainId,
|
|
27
44
|
selectedChainIdStore,
|
|
28
45
|
serializeWithBigInt,
|
|
@@ -35,6 +52,7 @@ import {
|
|
|
35
52
|
tangleTestnet,
|
|
36
53
|
themeIsDark,
|
|
37
54
|
themeStore,
|
|
55
|
+
toBlueprintAppEntry,
|
|
38
56
|
toggleTheme,
|
|
39
57
|
txListStore,
|
|
40
58
|
updateInfra,
|
|
@@ -45,27 +63,7 @@ import {
|
|
|
45
63
|
useQuotes,
|
|
46
64
|
useSubmitJob,
|
|
47
65
|
useThemeValue
|
|
48
|
-
} from "./chunk-
|
|
49
|
-
import {
|
|
50
|
-
BlueprintHostHero,
|
|
51
|
-
BlueprintHostPanel,
|
|
52
|
-
buildCanonicalBlueprintSlug,
|
|
53
|
-
canPublisherClaimSlug,
|
|
54
|
-
cn,
|
|
55
|
-
deriveBlueprintRequestedSlug,
|
|
56
|
-
getBlueprintExperienceTierLabel,
|
|
57
|
-
getBlueprintPath,
|
|
58
|
-
getBlueprintPublisherVerificationLabel,
|
|
59
|
-
getBlueprintServicePath,
|
|
60
|
-
getBlueprintSlugPolicyLabel,
|
|
61
|
-
getBlueprintSurfaceLabel,
|
|
62
|
-
getExternalAppTrustLabel,
|
|
63
|
-
isTrustedExternalAppHost,
|
|
64
|
-
isVerifiedBlueprintPublisher,
|
|
65
|
-
resolveBlueprintAppView,
|
|
66
|
-
sanitizeBlueprintSlugPart,
|
|
67
|
-
toBlueprintAppEntry
|
|
68
|
-
} from "./chunk-GD3AZEJL.js";
|
|
66
|
+
} from "./chunk-5PCH2RJF.js";
|
|
69
67
|
import {
|
|
70
68
|
bpThemeTokens
|
|
71
69
|
} from "./chunk-37ADATBT.js";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils/web3.ts","../src/stores/session.ts","../src/blueprints/registry.ts","../src/hooks/useOperators.ts","../src/hooks/useServiceValidation.ts","../src/hooks/useAuthenticatedFetch.ts","../src/hooks/useSessionAuth.ts","../src/hooks/useProvisionProgress.ts","../src/hooks/useSidecarAuth.ts","../src/hooks/useWagmiSidecarAuth.ts","../src/hooks/useWalletEthBalance.ts"],"sourcesContent":["import type { Chain } from 'viem';\nimport { http } from 'wagmi';\nimport { mainnet, rpcUrl, tangleLocal, tangleMainnet, tangleTestnet } from '../contracts/chains';\n\nexport function getTangleWalletChains(localChain: Chain = tangleLocal): readonly [Chain, ...Chain[]] {\n return [localChain, tangleTestnet, tangleMainnet, mainnet];\n}\n\nexport const tangleWalletChains: readonly [Chain, ...Chain[]] = getTangleWalletChains();\n\nexport function createTangleTransports(localChain: Pick<Chain, 'id' | 'rpcUrls'> = tangleLocal) {\n const localRpcUrl = localChain.rpcUrls.default.http[0] ?? rpcUrl;\n\n return {\n [localChain.id]: http(localRpcUrl),\n [tangleTestnet.id]: http('https://testnet-rpc.tangle.tools'),\n [tangleMainnet.id]: http('https://rpc.tangle.tools'),\n [mainnet.id]: http(),\n };\n}\n\nexport const defaultConnectKitOptions = {\n hideBalance: false,\n hideTooltips: false,\n hideQuestionMarkCTA: true,\n overlayBlur: 4,\n} as const;\n","import { persistedAtom } from './persistedAtom';\n\nexport interface SessionEntry {\n token: string;\n address: string;\n expiresAt: number;\n sandboxId: string;\n}\n\n/**\n * Persisted session tokens keyed by sandbox ID.\n * Auto-cleaned on read if expired.\n */\nexport const sessionMapStore = persistedAtom<Record<string, SessionEntry>>({\n key: 'bp_sessions',\n initial: {},\n});\n\n/** Active session for a given sandbox. */\nexport function getSession(sandboxId: string): SessionEntry | null {\n const map = sessionMapStore.get();\n const entry = map[sandboxId];\n if (!entry) return null;\n\n // Check expiry with 60s buffer\n if (Date.now() / 1000 > entry.expiresAt - 60) {\n removeSession(sandboxId);\n return null;\n }\n\n return entry;\n}\n\nexport function setSession(entry: SessionEntry) {\n const map = { ...sessionMapStore.get() };\n map[entry.sandboxId] = entry;\n sessionMapStore.set(map);\n}\n\nexport function removeSession(sandboxId: string) {\n const map = { ...sessionMapStore.get() };\n delete map[sandboxId];\n sessionMapStore.set(map);\n}\n\n/** Clean up all expired sessions. */\nexport function gcSessions() {\n const now = Date.now() / 1000;\n const map = sessionMapStore.get();\n const cleaned: Record<string, SessionEntry> = {};\n let changed = false;\n\n for (const [key, entry] of Object.entries(map) as [string, SessionEntry][]) {\n if (entry.expiresAt > now) {\n cleaned[key] = entry;\n } else {\n changed = true;\n }\n }\n\n if (changed) {\n sessionMapStore.set(cleaned);\n }\n}\n","import type { Address } from 'viem';\n\n/**\n * Blueprint Registry — defines the metadata layer for Tangle blueprints.\n *\n * Each blueprint exposes a set of jobs. The registry maps on-chain job IDs\n * to human-readable metadata: labels, descriptions, categories, form fields,\n * and pricing info. This enables the UI to render appropriate forms for each\n * job without procedurally generating UI from raw ABI data.\n *\n * Third-party blueprints can register here to appear in the wizard.\n */\n\n// ── Types ──\n\nexport type JobCategory = 'lifecycle' | 'execution' | 'batch' | 'workflow' | 'ssh' | 'management';\n\nexport interface JobFieldDef {\n name: string;\n label: string;\n type: 'text' | 'textarea' | 'number' | 'boolean' | 'select' | 'json' | 'combobox';\n placeholder?: string;\n required?: boolean;\n defaultValue?: string | number | boolean;\n options?: { label: string; value: string }[];\n helperText?: string;\n /** Minimum allowed value for number fields */\n min?: number;\n /** Maximum allowed value for number fields */\n max?: number;\n /** Step increment for number fields */\n step?: number;\n /** Solidity ABI type for encoding (e.g. 'string', 'uint64', 'bool', 'uint8') */\n abiType?: string;\n /** ABI param name if different from `name` (e.g. 'agent_identifier' vs 'agentIdentifier') */\n abiParam?: string;\n /** Field is included in ABI encoding but never shown in form (e.g. sidecar_token) */\n internal?: boolean;\n}\n\n/** ABI param injected from runtime context, not user input (e.g. sidecar_url, sandbox_id) */\nexport interface AbiContextParam {\n abiName: string;\n abiType: string;\n}\n\nexport interface JobDefinition {\n id: number;\n name: string;\n label: string;\n description: string;\n category: JobCategory;\n icon: string;\n pricingMultiplier: number;\n /** Fields the user needs to fill for this job */\n fields: JobFieldDef[];\n /** Whether this job requires an existing sandbox to target */\n requiresSandbox: boolean;\n /** Optional warning shown before submission */\n warning?: string;\n /** ABI params prepended from runtime context (e.g. sidecar_url for sandbox jobs) */\n contextParams?: AbiContextParam[];\n /** Override for jobs with complex ABI encoding (e.g. nested structs) */\n customEncoder?: (values: Record<string, unknown>, context?: Record<string, unknown>) => `0x${string}`;\n}\n\nexport interface BlueprintDefinition {\n id: string;\n name: string;\n version: string;\n description: string;\n icon: string;\n color: string;\n /** Contract address per chain ID — resolved at runtime */\n contracts: Record<number, Address>;\n /** Supported job definitions */\n jobs: JobDefinition[];\n /** Category ordering for the UI */\n categories: { key: JobCategory; label: string; icon: string }[];\n}\n\n// ── Registry ──\n\nconst blueprintRegistry = new Map<string, BlueprintDefinition>();\n\nexport function registerBlueprint(bp: BlueprintDefinition) {\n blueprintRegistry.set(bp.id, bp);\n}\n\nexport function getBlueprint(id: string): BlueprintDefinition | undefined {\n return blueprintRegistry.get(id);\n}\n\nexport function getAllBlueprints(): BlueprintDefinition[] {\n return Array.from(blueprintRegistry.values());\n}\n\nexport function getBlueprintJobs(blueprintId: string, category?: JobCategory): JobDefinition[] {\n const bp = blueprintRegistry.get(blueprintId);\n if (!bp) return [];\n return category ? bp.jobs.filter((j) => j.category === category) : bp.jobs;\n}\n\nexport function getJobById(blueprintId: string, jobId: number): JobDefinition | undefined {\n const bp = blueprintRegistry.get(blueprintId);\n return bp?.jobs.find((j) => j.id === jobId);\n}\n","import { useState, useEffect } from 'react';\nimport type { Address } from 'viem';\nimport { tangleOperatorsAbi } from '../contracts/abi';\nimport { publicClient, getAddresses } from '../contracts/publicClient';\n\nexport interface DiscoveredOperator {\n address: Address;\n ecdsaPublicKey: string;\n rpcAddress: string;\n}\n\ninterface OperatorDiscoveryClient {\n readContract(args: Record<string, unknown>): Promise<unknown>;\n getLogs(args: Record<string, unknown>): Promise<Array<Record<string, unknown>>>;\n multicall(args: Record<string, unknown>): Promise<Array<Record<string, unknown>>>;\n}\n\ninterface OperatorDiscoveryResult {\n operators: DiscoveredOperator[];\n operatorCount: bigint;\n}\n\nfunction readPreferenceValue(\n result: unknown,\n field: 'ecdsaPublicKey' | 'rpcAddress',\n): string {\n if (Array.isArray(result)) {\n return String(result[field === 'ecdsaPublicKey' ? 0 : 1] ?? '');\n }\n if (result && typeof result === 'object') {\n return String((result as Record<string, unknown>)[field] ?? '');\n }\n return '';\n}\n\nasync function verifyCandidatesWithMulticall(\n client: OperatorDiscoveryClient,\n servicesAddress: Address,\n blueprintId: bigint,\n candidates: DiscoveredOperator[],\n): Promise<DiscoveredOperator[] | null> {\n const [registrationResults, preferencesResults] = await Promise.all([\n client.multicall({\n contracts: candidates.map((op) => ({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'isOperatorRegistered' as const,\n args: [blueprintId, op.address] as const,\n })),\n }),\n client.multicall({\n contracts: candidates.map((op) => ({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'getOperatorPreferences' as const,\n args: [blueprintId, op.address] as const,\n })),\n }),\n ]);\n\n const hadRegistrationFailure = registrationResults.some((result) => result?.status === 'failure');\n const hadPreferenceFailure = preferencesResults.some((result) => result?.status === 'failure');\n\n const active: DiscoveredOperator[] = [];\n candidates.forEach((op, i) => {\n if (registrationResults[i]?.result !== true) return;\n const prefs = preferencesResults[i];\n if (prefs?.status === 'success' && prefs.result != null) {\n active.push({\n ...op,\n ecdsaPublicKey: readPreferenceValue(prefs.result, 'ecdsaPublicKey') || op.ecdsaPublicKey,\n rpcAddress: readPreferenceValue(prefs.result, 'rpcAddress') || op.rpcAddress,\n });\n return;\n }\n active.push(op);\n });\n\n if (active.length === 0 && (hadRegistrationFailure || hadPreferenceFailure)) {\n return null;\n }\n\n return active;\n}\n\nasync function verifyCandidatesDirectly(\n client: OperatorDiscoveryClient,\n servicesAddress: Address,\n blueprintId: bigint,\n candidates: DiscoveredOperator[],\n): Promise<DiscoveredOperator[]> {\n const results = await Promise.allSettled(\n candidates.map(async (op) => {\n const registration = await client.readContract({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'isOperatorRegistered',\n args: [blueprintId, op.address],\n });\n\n if (registration !== true) {\n return null;\n }\n\n try {\n const preferences = await client.readContract({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'getOperatorPreferences',\n args: [blueprintId, op.address],\n });\n\n return {\n ...op,\n ecdsaPublicKey: readPreferenceValue(preferences, 'ecdsaPublicKey') || op.ecdsaPublicKey,\n rpcAddress: readPreferenceValue(preferences, 'rpcAddress') || op.rpcAddress,\n };\n } catch {\n return op;\n }\n }),\n );\n\n const active = results\n .filter((result): result is PromiseFulfilledResult<DiscoveredOperator | null> => result.status === 'fulfilled')\n .map((result) => result.value)\n .filter((op): op is DiscoveredOperator => op != null);\n\n if (active.length > 0) {\n return active;\n }\n\n const failure = results.find((result): result is PromiseRejectedResult => result.status === 'rejected');\n if (failure) {\n throw failure.reason instanceof Error ? failure.reason : new Error(String(failure.reason));\n }\n\n return [];\n}\n\n/**\n * Shared discovery logic for operator lookup.\n * Tries multicall first for efficiency, then falls back to direct reads when\n * multicall is unavailable in local/dev environments.\n */\nexport async function discoverOperatorsWithClient(\n client: OperatorDiscoveryClient,\n servicesAddress: Address,\n blueprintId: bigint,\n): Promise<OperatorDiscoveryResult> {\n const count = await client.readContract({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'blueprintOperatorCount',\n args: [blueprintId],\n });\n const operatorCount = count as bigint;\n\n if (operatorCount === 0n) {\n return { operators: [], operatorCount };\n }\n\n const registeredLogs = await client.getLogs({\n address: servicesAddress,\n event: {\n type: 'event' as const,\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 args: { blueprintId },\n fromBlock: 0n,\n toBlock: 'latest',\n });\n\n const byAddress = new Map<Address, DiscoveredOperator>();\n for (const log of registeredLogs) {\n const args = (log.args ?? {}) as Record<string, unknown>;\n const addr = args.operator as Address | undefined;\n if (!addr) continue;\n byAddress.set(addr, {\n address: addr,\n ecdsaPublicKey: String(args.ecdsaPublicKey ?? '0x'),\n rpcAddress: String(args.rpcAddress ?? ''),\n });\n }\n\n const candidates = Array.from(byAddress.values());\n if (candidates.length === 0) {\n return { operators: [], operatorCount };\n }\n\n try {\n const active = await verifyCandidatesWithMulticall(client, servicesAddress, blueprintId, candidates);\n if (active != null) {\n return { operators: active, operatorCount };\n }\n } catch {\n // Fall through to direct reads below.\n }\n\n const active = await verifyCandidatesDirectly(client, servicesAddress, blueprintId, candidates);\n return { operators: active, operatorCount };\n}\n\n/**\n * Discover operators registered for a blueprint by scanning OperatorRegistered\n * events, then verifying each is still active. Falls back to direct reads when\n * multicall is unavailable.\n */\nexport function useOperators(blueprintId: bigint) {\n const [operators, setOperators] = useState<DiscoveredOperator[]>([]);\n const [operatorCount, setOperatorCount] = useState<bigint>(0n);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n const addrs = getAddresses();\n\n async function discover() {\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await discoverOperatorsWithClient(publicClient, addrs.services, blueprintId);\n if (cancelled) return;\n setOperatorCount(result.operatorCount);\n setOperators(result.operators);\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n }\n\n discover();\n return () => { cancelled = true; };\n }, [blueprintId]);\n\n return { operators, isLoading, error, operatorCount };\n}\n","import { useState, useCallback } from 'react';\nimport type { Address } from 'viem';\nimport { tangleServicesAbi } from '../contracts/abi';\nimport { publicClient, getAddresses } from '../contracts/publicClient';\n\nexport interface ServiceInfo {\n active: boolean;\n blueprintId: bigint;\n owner: Address;\n operatorCount: number;\n operators: Address[];\n permitted: boolean;\n ttl: bigint;\n createdAt: bigint;\n}\n\n/**\n * Validate a service on-chain: check if active, fetch operators,\n * verify the current user is a permitted caller.\n */\nexport function useServiceValidation() {\n const [isValidating, setIsValidating] = useState(false);\n const [serviceInfo, setServiceInfo] = useState<ServiceInfo | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const validate = useCallback(async (serviceId: bigint, userAddress?: Address) => {\n setIsValidating(true);\n setError(null);\n setServiceInfo(null);\n\n const addrs = getAddresses();\n\n try {\n // Run reads in parallel without multicall to avoid type union issues\n const [isActiveResult, serviceDataResult, operatorsResult, permittedResult] = await Promise.all([\n publicClient.readContract({\n address: addrs.services,\n abi: tangleServicesAbi,\n functionName: 'isServiceActive',\n args: [serviceId],\n }).catch(() => false),\n\n publicClient.readContract({\n address: addrs.services,\n abi: tangleServicesAbi,\n functionName: 'getService',\n args: [serviceId],\n }).catch(() => null),\n\n publicClient.readContract({\n address: addrs.services,\n abi: tangleServicesAbi,\n functionName: 'getServiceOperators',\n args: [serviceId],\n }).catch(() => [] as readonly Address[]),\n\n userAddress\n ? publicClient.readContract({\n address: addrs.services,\n abi: tangleServicesAbi,\n functionName: 'isPermittedCaller',\n args: [serviceId, userAddress],\n }).catch(() => false)\n : Promise.resolve(true),\n ]);\n\n const isActive = isActiveResult as boolean;\n const serviceData = serviceDataResult as Record<string, any> | null;\n const operators = (operatorsResult ?? []) as readonly Address[];\n const permitted = permittedResult as boolean;\n\n if (!serviceData) {\n setError('Service not found');\n setIsValidating(false);\n return null;\n }\n\n const info: ServiceInfo = {\n active: isActive,\n blueprintId: serviceData.blueprintId ?? serviceData[0] ?? 0n,\n owner: serviceData.owner ?? serviceData[1] ?? ('0x0' as Address),\n operatorCount: operators.length,\n operators: [...operators],\n permitted,\n ttl: serviceData.ttl ?? serviceData[3] ?? 0n,\n createdAt: serviceData.createdAt ?? serviceData[2] ?? 0n,\n };\n\n setServiceInfo(info);\n\n if (!isActive) {\n setError('Service is not active');\n } else if (!permitted && userAddress) {\n setError('You are not a permitted caller for this service');\n }\n\n setIsValidating(false);\n return info;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n setError(msg);\n setIsValidating(false);\n return null;\n }\n }, []);\n\n const reset = useCallback(() => {\n setServiceInfo(null);\n setError(null);\n }, []);\n\n return { validate, reset, isValidating, serviceInfo, error };\n}\n","import { useCallback } from 'react';\nimport { getSession } from '../stores/session';\nimport { useSessionAuth } from './useSessionAuth';\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\ninterface UseAuthenticatedFetchOptions {\n sandboxId: string;\n apiUrl?: string;\n}\n\n/**\n * Returns a `fetch` wrapper that injects the Bearer session token.\n * If the token is expired or a 401 is received, triggers re-authentication.\n */\nexport function useAuthenticatedFetch({ sandboxId, apiUrl }: UseAuthenticatedFetchOptions) {\n const { authenticate } = useSessionAuth({ sandboxId, apiUrl });\n\n const authFetch = useCallback(\n async (url: string, init?: RequestInit): Promise<Response> => {\n let session = getSession(sandboxId);\n\n // If no session, authenticate first\n if (!session) {\n session = await authenticate();\n if (!session) {\n throw new Error('Authentication required');\n }\n }\n\n // Make request with token\n const headers = new Headers(init?.headers);\n headers.set('Authorization', `Bearer ${session.token}`);\n\n const res = await fetch(url, { ...init, headers });\n\n // If 401, try re-authenticating once\n if (res.status === 401) {\n session = await authenticate();\n if (!session) {\n throw new Error('Re-authentication failed');\n }\n\n const retryHeaders = new Headers(init?.headers);\n retryHeaders.set('Authorization', `Bearer ${session.token}`);\n return fetch(url, { ...init, headers: retryHeaders });\n }\n\n return res;\n },\n [sandboxId, authenticate],\n );\n\n return { authFetch };\n}\n","import { useCallback, useState } from 'react';\nimport { useSignMessage } from 'wagmi';\nimport { getSession, setSession, removeSession, type SessionEntry } from '../stores/session';\nimport { getEnvVar } from '../utils/env';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface ChallengeResponse {\n nonce: string;\n message: string;\n expires_at: number;\n}\n\ninterface SessionResponse {\n token: string;\n address: string;\n expires_at: number;\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\ninterface UseSessionAuthOptions {\n sandboxId: string;\n apiUrl?: string;\n}\n\nexport function useSessionAuth({ sandboxId, apiUrl }: UseSessionAuthOptions) {\n const baseUrl = apiUrl ?? getEnvVar('VITE_OPERATOR_API_URL') ?? 'http://localhost:9090';\n const { signMessageAsync } = useSignMessage();\n\n const [isAuthenticating, setIsAuthenticating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Get cached session\n const session = getSession(sandboxId);\n\n const authenticate = useCallback(async (): Promise<SessionEntry | null> => {\n setIsAuthenticating(true);\n setError(null);\n\n try {\n // Step 1: Request challenge\n const challengeRes = await fetch(`${baseUrl}/api/auth/challenge`, {\n method: 'POST',\n });\n if (!challengeRes.ok) {\n throw new Error(`Challenge request failed: HTTP ${challengeRes.status}`);\n }\n const challenge: ChallengeResponse = await challengeRes.json();\n\n // Step 2: Sign with wallet\n const signature = await signMessageAsync({ message: challenge.message });\n\n // Step 3: Exchange signature for session token\n const sessionRes = await fetch(`${baseUrl}/api/auth/session`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n nonce: challenge.nonce,\n signature,\n }),\n });\n if (!sessionRes.ok) {\n const body = await sessionRes.json().catch(() => ({}));\n throw new Error(body.error ?? `Session exchange failed: HTTP ${sessionRes.status}`);\n }\n const sessionData: SessionResponse = await sessionRes.json();\n\n // Step 4: Store session\n const entry: SessionEntry = {\n token: sessionData.token,\n address: sessionData.address,\n expiresAt: sessionData.expires_at,\n sandboxId,\n };\n setSession(entry);\n\n return entry;\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Authentication failed';\n setError(msg);\n return null;\n } finally {\n setIsAuthenticating(false);\n }\n }, [baseUrl, sandboxId, signMessageAsync]);\n\n const logout = useCallback(() => {\n removeSession(sandboxId);\n }, [sandboxId]);\n\n return {\n session,\n isAuthenticated: session !== null,\n isAuthenticating,\n error,\n authenticate,\n logout,\n };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { getEnvVar } from '../utils/env';\n\n// ---------------------------------------------------------------------------\n// Types matching sandbox-runtime/src/provision_progress.rs\n// ---------------------------------------------------------------------------\n\nexport type ProvisionPhase =\n | 'queued'\n | 'image_pull'\n | 'container_create'\n | 'container_start'\n | 'health_check'\n | 'ready'\n | 'failed';\n\nexport interface ProvisionStatus {\n call_id: number;\n sandbox_id: string | null;\n phase: ProvisionPhase;\n message: string | null;\n started_at: number;\n updated_at: number;\n progress_pct: number;\n sidecar_url: string | null;\n}\n\nconst PHASE_LABELS: Record<ProvisionPhase, string> = {\n queued: 'Queued',\n image_pull: 'Pulling image',\n container_create: 'Creating container',\n container_start: 'Starting container',\n health_check: 'Health check',\n ready: 'Ready',\n failed: 'Failed',\n};\n\nexport function getPhaseLabel(phase: ProvisionPhase): string {\n return PHASE_LABELS[phase] ?? phase;\n}\n\nexport function isTerminalPhase(phase: ProvisionPhase): boolean {\n return phase === 'ready' || phase === 'failed';\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nconst POLL_INTERVAL = 2000;\n\ninterface UseProvisionProgressOptions {\n callId: number | null;\n apiUrl?: string;\n enabled?: boolean;\n}\n\nexport function useProvisionProgress({\n callId,\n apiUrl,\n enabled = true,\n}: UseProvisionProgressOptions) {\n const [status, setStatus] = useState<ProvisionStatus | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isPolling, setIsPolling] = useState(false);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const baseUrl = apiUrl ?? getEnvVar('VITE_OPERATOR_API_URL') ?? 'http://localhost:9090';\n\n const fetchProgress = useCallback(async () => {\n if (callId == null) return;\n\n try {\n const res = await fetch(`${baseUrl}/api/provisions/${callId}`);\n if (res.status === 404) {\n // Not yet tracked — keep polling\n return;\n }\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n const data: ProvisionStatus = await res.json();\n setStatus(data);\n setError(null);\n\n // Stop polling on terminal phase\n if (isTerminalPhase(data.phase) && intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n setIsPolling(false);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to fetch provision status');\n }\n }, [callId, baseUrl]);\n\n useEffect(() => {\n if (!enabled || callId == null) return;\n\n setIsPolling(true);\n fetchProgress(); // Initial fetch\n\n intervalRef.current = setInterval(fetchProgress, POLL_INTERVAL);\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n setIsPolling(false);\n };\n }, [enabled, callId, fetchProgress]);\n\n return {\n status,\n error,\n isPolling,\n phase: status?.phase ?? null,\n progressPct: status?.progress_pct ?? 0,\n sandboxId: status?.sandbox_id ?? null,\n sidecarUrl: status?.sidecar_url ?? null,\n message: status?.message ?? null,\n isReady: status?.phase === 'ready',\n isFailed: status?.phase === 'failed',\n };\n}\n","import { useState, useCallback, useEffect, useRef } from 'react';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface UseSidecarAuthOptions {\n /** Scoping key for token storage (e.g. botId, sandboxId). */\n resourceId: string;\n /** Base URL of the sidecar or operator API. */\n apiUrl: string;\n /**\n * Sign a plaintext message and return the hex signature.\n * Consuming apps wire this to their wallet library (e.g. wagmi's signMessageAsync).\n */\n signMessage: (message: string) => Promise<string>;\n}\n\nexport interface SidecarAuth {\n token: string | null;\n isAuthenticated: boolean;\n isAuthenticating: boolean;\n authenticate: () => Promise<string | null>;\n clearCachedToken: () => void;\n error: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// localStorage helpers\n// ---------------------------------------------------------------------------\n\nfunction storageKey(resourceId: string, apiUrl: string): string {\n return `sidecar_session_${resourceId}__${apiUrl}`;\n}\n\nfunction loadSession(resourceId: string, apiUrl: string): { token: string; expiresAt: number } | null {\n if (typeof window === 'undefined') return null;\n try {\n const raw = localStorage.getItem(storageKey(resourceId, apiUrl));\n if (!raw) return null;\n const data = JSON.parse(raw) as { token: string; expiresAt: number };\n // Discard if within 60s of expiry\n if (data.expiresAt * 1000 - Date.now() < 60_000) {\n localStorage.removeItem(storageKey(resourceId, apiUrl));\n return null;\n }\n return data;\n } catch {\n return null;\n }\n}\n\nfunction saveSession(resourceId: string, apiUrl: string, token: string, expiresAt: number) {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(storageKey(resourceId, apiUrl), JSON.stringify({ token, expiresAt }));\n } catch {\n // storage full — ignore\n }\n}\n\nfunction clearSession(resourceId: string, apiUrl: string) {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(storageKey(resourceId, apiUrl));\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\n/**\n * Generic sidecar PASETO challenge/response auth.\n *\n * Flow:\n * 1. POST /api/auth/challenge -> { nonce, message, expires_at }\n * 2. signMessage(message) -> signature (provided by consuming app)\n * 3. POST /api/auth/session -> { token, address, expires_at }\n *\n * Tokens are cached in localStorage and auto-refreshed 5 minutes before expiry.\n */\nexport function useSidecarAuth({ resourceId, apiUrl, signMessage }: UseSidecarAuthOptions): SidecarAuth {\n const cached = loadSession(resourceId, apiUrl);\n const [token, setToken] = useState<string | null>(cached?.token ?? null);\n const [expiresAt, setExpiresAt] = useState<number>(cached?.expiresAt ?? 0);\n const [isAuthenticating, setIsAuthenticating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const refreshTimerRef = useRef<ReturnType<typeof setTimeout>>();\n\n const clearCachedToken = useCallback(() => {\n setToken(null);\n setExpiresAt(0);\n clearSession(resourceId, apiUrl);\n }, [resourceId, apiUrl]);\n\n const authenticate = useCallback(async (): Promise<string | null> => {\n if (!apiUrl) return null;\n setIsAuthenticating(true);\n setError(null);\n\n try {\n // Step 1: Get challenge\n const challengeRes = await fetch(`${apiUrl}/api/auth/challenge`, {\n method: 'POST',\n });\n if (!challengeRes.ok) {\n throw new Error(`Challenge failed: ${challengeRes.status}`);\n }\n const { nonce, message } = await challengeRes.json();\n\n // Step 2: Sign with wallet (injected)\n const signature = await signMessage(message);\n\n // Step 3: Exchange for session token\n const sessionRes = await fetch(`${apiUrl}/api/auth/session`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ nonce, signature }),\n });\n if (!sessionRes.ok) {\n const text = await sessionRes.text();\n throw new Error(text || `Session exchange failed: ${sessionRes.status}`);\n }\n\n const { token: newToken, expires_at } = await sessionRes.json();\n setToken(newToken);\n setExpiresAt(expires_at);\n saveSession(resourceId, apiUrl, newToken, expires_at);\n return newToken;\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Authentication failed');\n clearCachedToken();\n return null;\n } finally {\n setIsAuthenticating(false);\n }\n }, [resourceId, apiUrl, signMessage, clearCachedToken]);\n\n // Auto-refresh token 5 minutes before expiry\n useEffect(() => {\n if (refreshTimerRef.current) {\n clearTimeout(refreshTimerRef.current);\n }\n\n if (!token || !expiresAt) return;\n\n const msUntilRefresh = (expiresAt - 300) * 1000 - Date.now();\n if (msUntilRefresh <= 0) {\n clearCachedToken();\n return;\n }\n\n refreshTimerRef.current = setTimeout(() => {\n authenticate().catch(() => {\n clearCachedToken();\n });\n }, msUntilRefresh);\n\n return () => {\n if (refreshTimerRef.current) {\n clearTimeout(refreshTimerRef.current);\n }\n };\n }, [token, expiresAt, authenticate, clearCachedToken]);\n\n return {\n token,\n isAuthenticated: token !== null,\n isAuthenticating,\n authenticate,\n clearCachedToken,\n error,\n };\n}\n","import { useSignMessage } from 'wagmi';\nimport { useSidecarAuth } from './useSidecarAuth';\n\nexport function useWagmiSidecarAuth(resourceId: string, apiUrl: string) {\n const { signMessageAsync } = useSignMessage();\n return useSidecarAuth({\n resourceId,\n apiUrl,\n signMessage: (msg: string) => signMessageAsync({ message: msg }),\n });\n}\n","import { useEffect, useState } from 'react';\n\nconst WEI_PER_ETH = 1_000_000_000_000_000_000n;\nconst DISPLAY_SCALE = 1_000n; // 3 decimal places\n\nfunction formatEthBalance(wei: bigint): string {\n const whole = wei / WEI_PER_ETH;\n const fraction = ((wei % WEI_PER_ETH) * DISPLAY_SCALE) / WEI_PER_ETH;\n return `${whole.toString()}.${fraction.toString().padStart(3, '0')}`;\n}\n\ninterface UseWalletEthBalanceOptions {\n address?: string;\n refreshKey?: number | string;\n readBalance: (address: string) => Promise<bigint>;\n pollMs?: number;\n onError?: (error: unknown) => void;\n}\n\ninterface UseWalletEthBalanceResult {\n balance: string | null;\n hasError: boolean;\n}\n\nexport function useWalletEthBalance({\n address,\n refreshKey,\n readBalance,\n pollMs = 15_000,\n onError,\n}: UseWalletEthBalanceOptions): UseWalletEthBalanceResult {\n const [balance, setBalance] = useState<string | null>(null);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n if (!address) {\n setBalance(null);\n setHasError(false);\n return;\n }\n\n let cancelled = false;\n\n const fetchBalance = () => {\n readBalance(address)\n .then((wei) => {\n if (cancelled) return;\n setBalance(formatEthBalance(wei));\n setHasError(false);\n })\n .catch((error: unknown) => {\n if (cancelled) return;\n setHasError(true);\n onError?.(error);\n });\n };\n\n fetchBalance();\n const interval = setInterval(fetchBalance, pollMs);\n\n return () => {\n cancelled = true;\n clearInterval(interval);\n };\n }, [address, refreshKey, readBalance, pollMs, onError]);\n\n return { balance, hasError };\n}\n"],"mappings":"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","names":["active","useState","useState","useCallback","useCallback","useState","useState","useCallback","useCallback","useCallback","useEffect","useState","useState","useCallback","useEffect","useState","useCallback","useEffect","useRef","useSignMessage","useSignMessage","useEffect","useState"]}
|
|
1
|
+
{"version":3,"sources":["../src/utils/web3.ts","../src/stores/session.ts","../src/blueprints/registry.ts","../src/hooks/useOperators.ts","../src/hooks/useServiceValidation.ts","../src/hooks/useAuthenticatedFetch.ts","../src/hooks/useSessionAuth.ts","../src/hooks/useProvisionProgress.ts","../src/hooks/useSidecarAuth.ts","../src/hooks/useWagmiSidecarAuth.ts","../src/hooks/useWalletEthBalance.ts"],"sourcesContent":["import type { Chain } from 'viem';\nimport { http } from 'wagmi';\nimport { mainnet, rpcUrl, tangleLocal, tangleMainnet, tangleTestnet } from '../contracts/chains';\n\nexport function getTangleWalletChains(localChain: Chain = tangleLocal): readonly [Chain, ...Chain[]] {\n return [localChain, tangleTestnet, tangleMainnet, mainnet];\n}\n\nexport const tangleWalletChains: readonly [Chain, ...Chain[]] = getTangleWalletChains();\n\nexport function createTangleTransports(localChain: Pick<Chain, 'id' | 'rpcUrls'> = tangleLocal) {\n const localRpcUrl = localChain.rpcUrls.default.http[0] ?? rpcUrl;\n\n return {\n [localChain.id]: http(localRpcUrl),\n [tangleTestnet.id]: http('https://testnet-rpc.tangle.tools'),\n [tangleMainnet.id]: http('https://rpc.tangle.tools'),\n [mainnet.id]: http(),\n };\n}\n\nexport const defaultConnectKitOptions = {\n hideBalance: false,\n hideTooltips: false,\n hideQuestionMarkCTA: true,\n overlayBlur: 4,\n} as const;\n","import { persistedAtom } from './persistedAtom';\n\nexport interface SessionEntry {\n token: string;\n address: string;\n expiresAt: number;\n sandboxId: string;\n}\n\n/**\n * Persisted session tokens keyed by sandbox ID.\n * Auto-cleaned on read if expired.\n */\nexport const sessionMapStore = persistedAtom<Record<string, SessionEntry>>({\n key: 'bp_sessions',\n initial: {},\n});\n\n/** Active session for a given sandbox. */\nexport function getSession(sandboxId: string): SessionEntry | null {\n const map = sessionMapStore.get();\n const entry = map[sandboxId];\n if (!entry) return null;\n\n // Check expiry with 60s buffer\n if (Date.now() / 1000 > entry.expiresAt - 60) {\n removeSession(sandboxId);\n return null;\n }\n\n return entry;\n}\n\nexport function setSession(entry: SessionEntry) {\n const map = { ...sessionMapStore.get() };\n map[entry.sandboxId] = entry;\n sessionMapStore.set(map);\n}\n\nexport function removeSession(sandboxId: string) {\n const map = { ...sessionMapStore.get() };\n delete map[sandboxId];\n sessionMapStore.set(map);\n}\n\n/** Clean up all expired sessions. */\nexport function gcSessions() {\n const now = Date.now() / 1000;\n const map = sessionMapStore.get();\n const cleaned: Record<string, SessionEntry> = {};\n let changed = false;\n\n for (const [key, entry] of Object.entries(map) as [string, SessionEntry][]) {\n if (entry.expiresAt > now) {\n cleaned[key] = entry;\n } else {\n changed = true;\n }\n }\n\n if (changed) {\n sessionMapStore.set(cleaned);\n }\n}\n","import type { Address } from 'viem';\n\n/**\n * Blueprint Registry — defines the metadata layer for Tangle blueprints.\n *\n * Each blueprint exposes a set of jobs. The registry maps on-chain job IDs\n * to human-readable metadata: labels, descriptions, categories, form fields,\n * and pricing info. This enables the UI to render appropriate forms for each\n * job without procedurally generating UI from raw ABI data.\n *\n * Third-party blueprints can register here to appear in the wizard.\n */\n\n// ── Types ──\n\nexport type JobCategory = 'lifecycle' | 'execution' | 'batch' | 'workflow' | 'ssh' | 'management';\n\nexport interface JobFieldDef {\n name: string;\n label: string;\n type: 'text' | 'textarea' | 'number' | 'boolean' | 'select' | 'json' | 'combobox';\n placeholder?: string;\n required?: boolean;\n defaultValue?: string | number | boolean;\n options?: { label: string; value: string }[];\n helperText?: string;\n /** Minimum allowed value for number fields */\n min?: number;\n /** Maximum allowed value for number fields */\n max?: number;\n /** Step increment for number fields */\n step?: number;\n /** Solidity ABI type for encoding (e.g. 'string', 'uint64', 'bool', 'uint8') */\n abiType?: string;\n /** ABI param name if different from `name` (e.g. 'agent_identifier' vs 'agentIdentifier') */\n abiParam?: string;\n /** Field is included in ABI encoding but never shown in form (e.g. sidecar_token) */\n internal?: boolean;\n}\n\n/** ABI param injected from runtime context, not user input (e.g. sidecar_url, sandbox_id) */\nexport interface AbiContextParam {\n abiName: string;\n abiType: string;\n}\n\nexport interface JobDefinition {\n id: number;\n name: string;\n label: string;\n description: string;\n category: JobCategory;\n icon: string;\n pricingMultiplier: number;\n /** Fields the user needs to fill for this job */\n fields: JobFieldDef[];\n /** Whether this job requires an existing sandbox to target */\n requiresSandbox: boolean;\n /** Optional warning shown before submission */\n warning?: string;\n /** ABI params prepended from runtime context (e.g. sidecar_url for sandbox jobs) */\n contextParams?: AbiContextParam[];\n /** Override for jobs with complex ABI encoding (e.g. nested structs) */\n customEncoder?: (values: Record<string, unknown>, context?: Record<string, unknown>) => `0x${string}`;\n}\n\nexport interface BlueprintDefinition {\n id: string;\n name: string;\n version: string;\n description: string;\n icon: string;\n color: string;\n /** Contract address per chain ID — resolved at runtime */\n contracts: Record<number, Address>;\n /** Supported job definitions */\n jobs: JobDefinition[];\n /** Category ordering for the UI */\n categories: { key: JobCategory; label: string; icon: string }[];\n}\n\n// ── Registry ──\n\nconst blueprintRegistry = new Map<string, BlueprintDefinition>();\n\nexport function registerBlueprint(bp: BlueprintDefinition) {\n blueprintRegistry.set(bp.id, bp);\n}\n\nexport function getBlueprint(id: string): BlueprintDefinition | undefined {\n return blueprintRegistry.get(id);\n}\n\nexport function getAllBlueprints(): BlueprintDefinition[] {\n return Array.from(blueprintRegistry.values());\n}\n\nexport function getBlueprintJobs(blueprintId: string, category?: JobCategory): JobDefinition[] {\n const bp = blueprintRegistry.get(blueprintId);\n if (!bp) return [];\n return category ? bp.jobs.filter((j) => j.category === category) : bp.jobs;\n}\n\nexport function getJobById(blueprintId: string, jobId: number): JobDefinition | undefined {\n const bp = blueprintRegistry.get(blueprintId);\n return bp?.jobs.find((j) => j.id === jobId);\n}\n","import { useState, useEffect } from 'react';\nimport type { Address } from 'viem';\nimport { tangleOperatorsAbi } from '../contracts/abi';\nimport { publicClient, getAddresses } from '../contracts/publicClient';\n\nexport interface DiscoveredOperator {\n address: Address;\n ecdsaPublicKey: string;\n rpcAddress: string;\n}\n\ninterface OperatorDiscoveryClient {\n readContract(args: Record<string, unknown>): Promise<unknown>;\n getLogs(args: Record<string, unknown>): Promise<Array<Record<string, unknown>>>;\n multicall(args: Record<string, unknown>): Promise<Array<Record<string, unknown>>>;\n}\n\ninterface OperatorDiscoveryResult {\n operators: DiscoveredOperator[];\n operatorCount: bigint;\n}\n\nfunction readPreferenceValue(\n result: unknown,\n field: 'ecdsaPublicKey' | 'rpcAddress',\n): string {\n if (Array.isArray(result)) {\n return String(result[field === 'ecdsaPublicKey' ? 0 : 1] ?? '');\n }\n if (result && typeof result === 'object') {\n return String((result as Record<string, unknown>)[field] ?? '');\n }\n return '';\n}\n\nasync function verifyCandidatesWithMulticall(\n client: OperatorDiscoveryClient,\n servicesAddress: Address,\n blueprintId: bigint,\n candidates: DiscoveredOperator[],\n): Promise<DiscoveredOperator[] | null> {\n const [registrationResults, preferencesResults] = await Promise.all([\n client.multicall({\n contracts: candidates.map((op) => ({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'isOperatorRegistered' as const,\n args: [blueprintId, op.address] as const,\n })),\n }),\n client.multicall({\n contracts: candidates.map((op) => ({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'getOperatorPreferences' as const,\n args: [blueprintId, op.address] as const,\n })),\n }),\n ]);\n\n const hadRegistrationFailure = registrationResults.some((result) => result?.status === 'failure');\n const hadPreferenceFailure = preferencesResults.some((result) => result?.status === 'failure');\n\n const active: DiscoveredOperator[] = [];\n candidates.forEach((op, i) => {\n if (registrationResults[i]?.result !== true) return;\n const prefs = preferencesResults[i];\n if (prefs?.status === 'success' && prefs.result != null) {\n active.push({\n ...op,\n ecdsaPublicKey: readPreferenceValue(prefs.result, 'ecdsaPublicKey') || op.ecdsaPublicKey,\n rpcAddress: readPreferenceValue(prefs.result, 'rpcAddress') || op.rpcAddress,\n });\n return;\n }\n active.push(op);\n });\n\n if (active.length === 0 && (hadRegistrationFailure || hadPreferenceFailure)) {\n return null;\n }\n\n return active;\n}\n\nasync function verifyCandidatesDirectly(\n client: OperatorDiscoveryClient,\n servicesAddress: Address,\n blueprintId: bigint,\n candidates: DiscoveredOperator[],\n): Promise<DiscoveredOperator[]> {\n const results = await Promise.allSettled(\n candidates.map(async (op) => {\n const registration = await client.readContract({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'isOperatorRegistered',\n args: [blueprintId, op.address],\n });\n\n if (registration !== true) {\n return null;\n }\n\n try {\n const preferences = await client.readContract({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'getOperatorPreferences',\n args: [blueprintId, op.address],\n });\n\n return {\n ...op,\n ecdsaPublicKey: readPreferenceValue(preferences, 'ecdsaPublicKey') || op.ecdsaPublicKey,\n rpcAddress: readPreferenceValue(preferences, 'rpcAddress') || op.rpcAddress,\n };\n } catch {\n return op;\n }\n }),\n );\n\n const active = results\n .filter((result): result is PromiseFulfilledResult<DiscoveredOperator | null> => result.status === 'fulfilled')\n .map((result) => result.value)\n .filter((op): op is DiscoveredOperator => op != null);\n\n if (active.length > 0) {\n return active;\n }\n\n const failure = results.find((result): result is PromiseRejectedResult => result.status === 'rejected');\n if (failure) {\n throw failure.reason instanceof Error ? failure.reason : new Error(String(failure.reason));\n }\n\n return [];\n}\n\n/**\n * Shared discovery logic for operator lookup.\n * Tries multicall first for efficiency, then falls back to direct reads when\n * multicall is unavailable in local/dev environments.\n */\nexport async function discoverOperatorsWithClient(\n client: OperatorDiscoveryClient,\n servicesAddress: Address,\n blueprintId: bigint,\n): Promise<OperatorDiscoveryResult> {\n const count = await client.readContract({\n address: servicesAddress,\n abi: tangleOperatorsAbi,\n functionName: 'blueprintOperatorCount',\n args: [blueprintId],\n });\n const operatorCount = count as bigint;\n\n if (operatorCount === 0n) {\n return { operators: [], operatorCount };\n }\n\n const registeredLogs = await client.getLogs({\n address: servicesAddress,\n event: {\n type: 'event' as const,\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 args: { blueprintId },\n fromBlock: 0n,\n toBlock: 'latest',\n });\n\n const byAddress = new Map<Address, DiscoveredOperator>();\n for (const log of registeredLogs) {\n const args = (log.args ?? {}) as Record<string, unknown>;\n const addr = args.operator as Address | undefined;\n if (!addr) continue;\n byAddress.set(addr, {\n address: addr,\n ecdsaPublicKey: String(args.ecdsaPublicKey ?? '0x'),\n rpcAddress: String(args.rpcAddress ?? ''),\n });\n }\n\n const candidates = Array.from(byAddress.values());\n if (candidates.length === 0) {\n return { operators: [], operatorCount };\n }\n\n try {\n const active = await verifyCandidatesWithMulticall(client, servicesAddress, blueprintId, candidates);\n if (active != null) {\n return { operators: active, operatorCount };\n }\n } catch {\n // Fall through to direct reads below.\n }\n\n const active = await verifyCandidatesDirectly(client, servicesAddress, blueprintId, candidates);\n return { operators: active, operatorCount };\n}\n\n/**\n * Discover operators registered for a blueprint by scanning OperatorRegistered\n * events, then verifying each is still active. Falls back to direct reads when\n * multicall is unavailable.\n */\nexport function useOperators(blueprintId: bigint) {\n const [operators, setOperators] = useState<DiscoveredOperator[]>([]);\n const [operatorCount, setOperatorCount] = useState<bigint>(0n);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<Error | null>(null);\n\n useEffect(() => {\n let cancelled = false;\n const addrs = getAddresses();\n\n async function discover() {\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await discoverOperatorsWithClient(publicClient, addrs.services, blueprintId);\n if (cancelled) return;\n setOperatorCount(result.operatorCount);\n setOperators(result.operators);\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err : new Error(String(err)));\n }\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n }\n\n discover();\n return () => { cancelled = true; };\n }, [blueprintId]);\n\n return { operators, isLoading, error, operatorCount };\n}\n","import { useState, useCallback } from 'react';\nimport type { Address } from 'viem';\nimport { tangleServicesAbi } from '../contracts/abi';\nimport { publicClient, getAddresses } from '../contracts/publicClient';\n\nexport interface ServiceInfo {\n active: boolean;\n blueprintId: bigint;\n owner: Address;\n operatorCount: number;\n operators: Address[];\n permitted: boolean;\n ttl: bigint;\n createdAt: bigint;\n}\n\n/**\n * Validate a service on-chain: check if active, fetch operators,\n * verify the current user is a permitted caller.\n */\nexport function useServiceValidation() {\n const [isValidating, setIsValidating] = useState(false);\n const [serviceInfo, setServiceInfo] = useState<ServiceInfo | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n const validate = useCallback(async (serviceId: bigint, userAddress?: Address) => {\n setIsValidating(true);\n setError(null);\n setServiceInfo(null);\n\n const addrs = getAddresses();\n\n try {\n // Run reads in parallel without multicall to avoid type union issues\n const [isActiveResult, serviceDataResult, operatorsResult, permittedResult] = await Promise.all([\n publicClient.readContract({\n address: addrs.services,\n abi: tangleServicesAbi,\n functionName: 'isServiceActive',\n args: [serviceId],\n }).catch(() => false),\n\n publicClient.readContract({\n address: addrs.services,\n abi: tangleServicesAbi,\n functionName: 'getService',\n args: [serviceId],\n }).catch(() => null),\n\n publicClient.readContract({\n address: addrs.services,\n abi: tangleServicesAbi,\n functionName: 'getServiceOperators',\n args: [serviceId],\n }).catch(() => [] as readonly Address[]),\n\n userAddress\n ? publicClient.readContract({\n address: addrs.services,\n abi: tangleServicesAbi,\n functionName: 'isPermittedCaller',\n args: [serviceId, userAddress],\n }).catch(() => false)\n : Promise.resolve(true),\n ]);\n\n const isActive = isActiveResult as boolean;\n const serviceData = serviceDataResult as Record<string, any> | null;\n const operators = (operatorsResult ?? []) as readonly Address[];\n const permitted = permittedResult as boolean;\n\n if (!serviceData) {\n setError('Service not found');\n setIsValidating(false);\n return null;\n }\n\n const info: ServiceInfo = {\n active: isActive,\n blueprintId: serviceData.blueprintId ?? serviceData[0] ?? 0n,\n owner: serviceData.owner ?? serviceData[1] ?? ('0x0' as Address),\n operatorCount: operators.length,\n operators: [...operators],\n permitted,\n ttl: serviceData.ttl ?? serviceData[3] ?? 0n,\n createdAt: serviceData.createdAt ?? serviceData[2] ?? 0n,\n };\n\n setServiceInfo(info);\n\n if (!isActive) {\n setError('Service is not active');\n } else if (!permitted && userAddress) {\n setError('You are not a permitted caller for this service');\n }\n\n setIsValidating(false);\n return info;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n setError(msg);\n setIsValidating(false);\n return null;\n }\n }, []);\n\n const reset = useCallback(() => {\n setServiceInfo(null);\n setError(null);\n }, []);\n\n return { validate, reset, isValidating, serviceInfo, error };\n}\n","import { useCallback } from 'react';\nimport { getSession } from '../stores/session';\nimport { useSessionAuth } from './useSessionAuth';\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\ninterface UseAuthenticatedFetchOptions {\n sandboxId: string;\n apiUrl?: string;\n}\n\n/**\n * Returns a `fetch` wrapper that injects the Bearer session token.\n * If the token is expired or a 401 is received, triggers re-authentication.\n */\nexport function useAuthenticatedFetch({ sandboxId, apiUrl }: UseAuthenticatedFetchOptions) {\n const { authenticate } = useSessionAuth({ sandboxId, apiUrl });\n\n const authFetch = useCallback(\n async (url: string, init?: RequestInit): Promise<Response> => {\n let session = getSession(sandboxId);\n\n // If no session, authenticate first\n if (!session) {\n session = await authenticate();\n if (!session) {\n throw new Error('Authentication required');\n }\n }\n\n // Make request with token\n const headers = new Headers(init?.headers);\n headers.set('Authorization', `Bearer ${session.token}`);\n\n const res = await fetch(url, { ...init, headers });\n\n // If 401, try re-authenticating once\n if (res.status === 401) {\n session = await authenticate();\n if (!session) {\n throw new Error('Re-authentication failed');\n }\n\n const retryHeaders = new Headers(init?.headers);\n retryHeaders.set('Authorization', `Bearer ${session.token}`);\n return fetch(url, { ...init, headers: retryHeaders });\n }\n\n return res;\n },\n [sandboxId, authenticate],\n );\n\n return { authFetch };\n}\n","import { useCallback, useState } from 'react';\nimport { useSignMessage } from 'wagmi';\nimport { getSession, setSession, removeSession, type SessionEntry } from '../stores/session';\nimport { getEnvVar } from '../utils/env';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ninterface ChallengeResponse {\n nonce: string;\n message: string;\n expires_at: number;\n}\n\ninterface SessionResponse {\n token: string;\n address: string;\n expires_at: number;\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\ninterface UseSessionAuthOptions {\n sandboxId: string;\n apiUrl?: string;\n}\n\nexport function useSessionAuth({ sandboxId, apiUrl }: UseSessionAuthOptions) {\n const baseUrl = apiUrl ?? getEnvVar('VITE_OPERATOR_API_URL') ?? 'http://localhost:9090';\n const { signMessageAsync } = useSignMessage();\n\n const [isAuthenticating, setIsAuthenticating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n // Get cached session\n const session = getSession(sandboxId);\n\n const authenticate = useCallback(async (): Promise<SessionEntry | null> => {\n setIsAuthenticating(true);\n setError(null);\n\n try {\n // Step 1: Request challenge\n const challengeRes = await fetch(`${baseUrl}/api/auth/challenge`, {\n method: 'POST',\n });\n if (!challengeRes.ok) {\n throw new Error(`Challenge request failed: HTTP ${challengeRes.status}`);\n }\n const challenge: ChallengeResponse = await challengeRes.json();\n\n // Step 2: Sign with wallet\n const signature = await signMessageAsync({ message: challenge.message });\n\n // Step 3: Exchange signature for session token\n const sessionRes = await fetch(`${baseUrl}/api/auth/session`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n nonce: challenge.nonce,\n signature,\n }),\n });\n if (!sessionRes.ok) {\n const body = await sessionRes.json().catch(() => ({}));\n throw new Error(body.error ?? `Session exchange failed: HTTP ${sessionRes.status}`);\n }\n const sessionData: SessionResponse = await sessionRes.json();\n\n // Step 4: Store session\n const entry: SessionEntry = {\n token: sessionData.token,\n address: sessionData.address,\n expiresAt: sessionData.expires_at,\n sandboxId,\n };\n setSession(entry);\n\n return entry;\n } catch (err) {\n const msg = err instanceof Error ? err.message : 'Authentication failed';\n setError(msg);\n return null;\n } finally {\n setIsAuthenticating(false);\n }\n }, [baseUrl, sandboxId, signMessageAsync]);\n\n const logout = useCallback(() => {\n removeSession(sandboxId);\n }, [sandboxId]);\n\n return {\n session,\n isAuthenticated: session !== null,\n isAuthenticating,\n error,\n authenticate,\n logout,\n };\n}\n","import { useCallback, useEffect, useRef, useState } from 'react';\nimport { getEnvVar } from '../utils/env';\n\n// ---------------------------------------------------------------------------\n// Types matching sandbox-runtime/src/provision_progress.rs\n// ---------------------------------------------------------------------------\n\nexport type ProvisionPhase =\n | 'queued'\n | 'image_pull'\n | 'container_create'\n | 'container_start'\n | 'health_check'\n | 'ready'\n | 'failed';\n\nexport interface ProvisionStatus {\n call_id: number;\n sandbox_id: string | null;\n phase: ProvisionPhase;\n message: string | null;\n started_at: number;\n updated_at: number;\n progress_pct: number;\n sidecar_url: string | null;\n}\n\nconst PHASE_LABELS: Record<ProvisionPhase, string> = {\n queued: 'Queued',\n image_pull: 'Pulling image',\n container_create: 'Creating container',\n container_start: 'Starting container',\n health_check: 'Health check',\n ready: 'Ready',\n failed: 'Failed',\n};\n\nexport function getPhaseLabel(phase: ProvisionPhase): string {\n return PHASE_LABELS[phase] ?? phase;\n}\n\nexport function isTerminalPhase(phase: ProvisionPhase): boolean {\n return phase === 'ready' || phase === 'failed';\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\nconst POLL_INTERVAL = 2000;\n\ninterface UseProvisionProgressOptions {\n callId: number | null;\n apiUrl?: string;\n enabled?: boolean;\n}\n\nexport function useProvisionProgress({\n callId,\n apiUrl,\n enabled = true,\n}: UseProvisionProgressOptions) {\n const [status, setStatus] = useState<ProvisionStatus | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [isPolling, setIsPolling] = useState(false);\n const intervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n\n const baseUrl = apiUrl ?? getEnvVar('VITE_OPERATOR_API_URL') ?? 'http://localhost:9090';\n\n const fetchProgress = useCallback(async () => {\n if (callId == null) return;\n\n try {\n const res = await fetch(`${baseUrl}/api/provisions/${callId}`);\n if (res.status === 404) {\n // Not yet tracked — keep polling\n return;\n }\n if (!res.ok) {\n throw new Error(`HTTP ${res.status}`);\n }\n const data: ProvisionStatus = await res.json();\n setStatus(data);\n setError(null);\n\n // Stop polling on terminal phase\n if (isTerminalPhase(data.phase) && intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n setIsPolling(false);\n }\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to fetch provision status');\n }\n }, [callId, baseUrl]);\n\n useEffect(() => {\n if (!enabled || callId == null) return;\n\n setIsPolling(true);\n fetchProgress(); // Initial fetch\n\n intervalRef.current = setInterval(fetchProgress, POLL_INTERVAL);\n\n return () => {\n if (intervalRef.current) {\n clearInterval(intervalRef.current);\n intervalRef.current = null;\n }\n setIsPolling(false);\n };\n }, [enabled, callId, fetchProgress]);\n\n return {\n status,\n error,\n isPolling,\n phase: status?.phase ?? null,\n progressPct: status?.progress_pct ?? 0,\n sandboxId: status?.sandbox_id ?? null,\n sidecarUrl: status?.sidecar_url ?? null,\n message: status?.message ?? null,\n isReady: status?.phase === 'ready',\n isFailed: status?.phase === 'failed',\n };\n}\n","import { useState, useCallback, useEffect, useRef } from 'react';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface UseSidecarAuthOptions {\n /** Scoping key for token storage (e.g. botId, sandboxId). */\n resourceId: string;\n /** Base URL of the sidecar or operator API. */\n apiUrl: string;\n /**\n * Sign a plaintext message and return the hex signature.\n * Consuming apps wire this to their wallet library (e.g. wagmi's signMessageAsync).\n */\n signMessage: (message: string) => Promise<string>;\n}\n\nexport interface SidecarAuth {\n token: string | null;\n isAuthenticated: boolean;\n isAuthenticating: boolean;\n authenticate: () => Promise<string | null>;\n clearCachedToken: () => void;\n error: string | null;\n}\n\n// ---------------------------------------------------------------------------\n// localStorage helpers\n// ---------------------------------------------------------------------------\n\nfunction storageKey(resourceId: string, apiUrl: string): string {\n return `sidecar_session_${resourceId}__${apiUrl}`;\n}\n\nfunction loadSession(resourceId: string, apiUrl: string): { token: string; expiresAt: number } | null {\n if (typeof window === 'undefined') return null;\n try {\n const raw = localStorage.getItem(storageKey(resourceId, apiUrl));\n if (!raw) return null;\n const data = JSON.parse(raw) as { token: string; expiresAt: number };\n // Discard if within 60s of expiry\n if (data.expiresAt * 1000 - Date.now() < 60_000) {\n localStorage.removeItem(storageKey(resourceId, apiUrl));\n return null;\n }\n return data;\n } catch {\n return null;\n }\n}\n\nfunction saveSession(resourceId: string, apiUrl: string, token: string, expiresAt: number) {\n if (typeof window === 'undefined') return;\n try {\n localStorage.setItem(storageKey(resourceId, apiUrl), JSON.stringify({ token, expiresAt }));\n } catch {\n // storage full — ignore\n }\n}\n\nfunction clearSession(resourceId: string, apiUrl: string) {\n if (typeof window === 'undefined') return;\n localStorage.removeItem(storageKey(resourceId, apiUrl));\n}\n\n// ---------------------------------------------------------------------------\n// Hook\n// ---------------------------------------------------------------------------\n\n/**\n * Generic sidecar PASETO challenge/response auth.\n *\n * Flow:\n * 1. POST /api/auth/challenge -> { nonce, message, expires_at }\n * 2. signMessage(message) -> signature (provided by consuming app)\n * 3. POST /api/auth/session -> { token, address, expires_at }\n *\n * Tokens are cached in localStorage and auto-refreshed 5 minutes before expiry.\n */\nexport function useSidecarAuth({ resourceId, apiUrl, signMessage }: UseSidecarAuthOptions): SidecarAuth {\n const cached = loadSession(resourceId, apiUrl);\n const [token, setToken] = useState<string | null>(cached?.token ?? null);\n const [expiresAt, setExpiresAt] = useState<number>(cached?.expiresAt ?? 0);\n const [isAuthenticating, setIsAuthenticating] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const refreshTimerRef = useRef<ReturnType<typeof setTimeout>>();\n\n const clearCachedToken = useCallback(() => {\n setToken(null);\n setExpiresAt(0);\n clearSession(resourceId, apiUrl);\n }, [resourceId, apiUrl]);\n\n const authenticate = useCallback(async (): Promise<string | null> => {\n if (!apiUrl) return null;\n setIsAuthenticating(true);\n setError(null);\n\n try {\n // Step 1: Get challenge\n const challengeRes = await fetch(`${apiUrl}/api/auth/challenge`, {\n method: 'POST',\n });\n if (!challengeRes.ok) {\n throw new Error(`Challenge failed: ${challengeRes.status}`);\n }\n const { nonce, message } = await challengeRes.json();\n\n // Step 2: Sign with wallet (injected)\n const signature = await signMessage(message);\n\n // Step 3: Exchange for session token\n const sessionRes = await fetch(`${apiUrl}/api/auth/session`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ nonce, signature }),\n });\n if (!sessionRes.ok) {\n const text = await sessionRes.text();\n throw new Error(text || `Session exchange failed: ${sessionRes.status}`);\n }\n\n const { token: newToken, expires_at } = await sessionRes.json();\n setToken(newToken);\n setExpiresAt(expires_at);\n saveSession(resourceId, apiUrl, newToken, expires_at);\n return newToken;\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Authentication failed');\n clearCachedToken();\n return null;\n } finally {\n setIsAuthenticating(false);\n }\n }, [resourceId, apiUrl, signMessage, clearCachedToken]);\n\n // Auto-refresh token 5 minutes before expiry\n useEffect(() => {\n if (refreshTimerRef.current) {\n clearTimeout(refreshTimerRef.current);\n }\n\n if (!token || !expiresAt) return;\n\n const msUntilRefresh = (expiresAt - 300) * 1000 - Date.now();\n if (msUntilRefresh <= 0) {\n clearCachedToken();\n return;\n }\n\n refreshTimerRef.current = setTimeout(() => {\n authenticate().catch(() => {\n clearCachedToken();\n });\n }, msUntilRefresh);\n\n return () => {\n if (refreshTimerRef.current) {\n clearTimeout(refreshTimerRef.current);\n }\n };\n }, [token, expiresAt, authenticate, clearCachedToken]);\n\n return {\n token,\n isAuthenticated: token !== null,\n isAuthenticating,\n authenticate,\n clearCachedToken,\n error,\n };\n}\n","import { useSignMessage } from 'wagmi';\nimport { useSidecarAuth } from './useSidecarAuth';\n\nexport function useWagmiSidecarAuth(resourceId: string, apiUrl: string) {\n const { signMessageAsync } = useSignMessage();\n return useSidecarAuth({\n resourceId,\n apiUrl,\n signMessage: (msg: string) => signMessageAsync({ message: msg }),\n });\n}\n","import { useEffect, useState } from 'react';\n\nconst WEI_PER_ETH = 1_000_000_000_000_000_000n;\nconst DISPLAY_SCALE = 1_000n; // 3 decimal places\n\nfunction formatEthBalance(wei: bigint): string {\n const whole = wei / WEI_PER_ETH;\n const fraction = ((wei % WEI_PER_ETH) * DISPLAY_SCALE) / WEI_PER_ETH;\n return `${whole.toString()}.${fraction.toString().padStart(3, '0')}`;\n}\n\ninterface UseWalletEthBalanceOptions {\n address?: string;\n refreshKey?: number | string;\n readBalance: (address: string) => Promise<bigint>;\n pollMs?: number;\n onError?: (error: unknown) => void;\n}\n\ninterface UseWalletEthBalanceResult {\n balance: string | null;\n hasError: boolean;\n}\n\nexport function useWalletEthBalance({\n address,\n refreshKey,\n readBalance,\n pollMs = 15_000,\n onError,\n}: UseWalletEthBalanceOptions): UseWalletEthBalanceResult {\n const [balance, setBalance] = useState<string | null>(null);\n const [hasError, setHasError] = useState(false);\n\n useEffect(() => {\n if (!address) {\n setBalance(null);\n setHasError(false);\n return;\n }\n\n let cancelled = false;\n\n const fetchBalance = () => {\n readBalance(address)\n .then((wei) => {\n if (cancelled) return;\n setBalance(formatEthBalance(wei));\n setHasError(false);\n })\n .catch((error: unknown) => {\n if (cancelled) return;\n setHasError(true);\n onError?.(error);\n });\n };\n\n fetchBalance();\n const interval = setInterval(fetchBalance, pollMs);\n\n return () => {\n cancelled = true;\n clearInterval(interval);\n };\n }, [address, refreshKey, readBalance, pollMs, onError]);\n\n return { balance, hasError };\n}\n"],"mappings":"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","names":["active","useState","useState","useCallback","useCallback","useState","useState","useCallback","useCallback","useCallback","useEffect","useState","useState","useCallback","useEffect","useState","useCallback","useEffect","useRef","useSignMessage","useSignMessage","useEffect","useState"]}
|
package/dist/styles.css
CHANGED
|
@@ -252,6 +252,7 @@
|
|
|
252
252
|
.mb-3{margin-bottom:calc(var(--spacing) * 3);}
|
|
253
253
|
.ml-2{margin-left:calc(var(--spacing) * 2);}
|
|
254
254
|
.ml-auto{margin-left:auto;}
|
|
255
|
+
.ms{margin-inline-start:calc(var(--spacing) * 4);}
|
|
255
256
|
.mt-0\.5{margin-top:calc(var(--spacing) * 0.5);}
|
|
256
257
|
.mt-1{margin-top:calc(var(--spacing) * 1);}
|
|
257
258
|
.mt-1\.5{margin-top:calc(var(--spacing) * 1.5);}
|