Components
Pre-built UI components for common Tenzro Platform interactions. All components are unstyled and can be customized with your own CSS or design system.
AI Components
ModelSelector
Dropdown for selecting AI models.
import { ModelSelector } from '@tenzro/platform-ui';
function MyComponent() {
const [modelId, setModelId] = useState<string>();
return (
<ModelSelector
value={modelId}
onChange={setModelId}
filter={{ provider: 'tenzro' }} // Optional filter
placeholder="Select a model"
className="model-select"
/>
);
}
// Props
interface ModelSelectorProps {
value?: string;
onChange: (modelId: string) => void;
filter?: {
provider?: string;
capabilities?: string[];
};
placeholder?: string;
className?: string;
disabled?: boolean;
}InferenceRunner
Complete inference UI with model selection, input, and results.
import { InferenceRunner } from '@tenzro/platform-ui';
function AIPage() {
return (
<InferenceRunner
onResult={(result) => {
console.log('Inference complete:', result);
console.log('TEE attestation:', result.teeAttestation);
}}
onError={(error) => console.error(error)}
defaultModel="llama-3.1-70b"
maxTokens={2048}
showAttestation={true}
/>
);
}
// Props
interface InferenceRunnerProps {
onResult: (result: InferenceResult) => void;
onError?: (error: Error) => void;
defaultModel?: string;
maxTokens?: number;
temperature?: number;
showAttestation?: boolean;
className?: string;
}MultiPartySessionManager
Full UI for managing multi-party inference sessions.
import { MultiPartySessionManager } from '@tenzro/platform-ui';
function MultiPartyPage() {
return (
<MultiPartySessionManager
onSessionCreated={(session) => console.log('Created:', session)}
onSessionCompleted={(session, result) => console.log('Completed:', result)}
allowCreate={true}
showParticipants={true}
/>
);
}
// Props
interface MultiPartySessionManagerProps {
onSessionCreated?: (session: MultiPartySession) => void;
onSessionCompleted?: (session: MultiPartySession, result: any) => void;
allowCreate?: boolean;
showParticipants?: boolean;
className?: string;
}TEEAttestationViewer
Display TEE attestation details.
import { TEEAttestationViewer } from '@tenzro/platform-ui';
function AttestationPage({ attestation }) {
return (
<TEEAttestationViewer
attestation={attestation}
showRaw={false}
onVerify={(result) => console.log('Verification:', result)}
/>
);
}
// Props
interface TEEAttestationViewerProps {
attestation: EnhancedTEEAttestation;
showRaw?: boolean;
onVerify?: (result: VerificationResult) => void;
className?: string;
}TEEAttestationBadge
Compact badge showing TEE attestation status.
import { TEEAttestationBadge } from '@tenzro/platform-ui';
function InferenceCard({ result }) {
return (
<div>
<p>{result.content}</p>
<TEEAttestationBadge
attestation={result.teeAttestation}
size="sm"
showType={true}
/>
</div>
);
}
// Props
interface TEEAttestationBadgeProps {
attestation?: EnhancedTEEAttestation;
size?: 'sm' | 'md' | 'lg';
showType?: boolean;
className?: string;
}RAGQueryRunner
Interface for RAG (Retrieval-Augmented Generation) queries.
import { RAGQueryRunner } from '@tenzro/platform-ui';
function RAGPage() {
return (
<RAGQueryRunner
dataSourceIds={['ds-1', 'ds-2']}
onResult={(result) => console.log('Answer:', result.answer)}
showSources={true}
maxResults={5}
/>
);
}
// Props
interface RAGQueryRunnerProps {
dataSourceIds: string[];
onResult?: (result: RAGQueryResult) => void;
showSources?: boolean;
maxResults?: number;
className?: string;
}Verifiable AI Components
import {
InferenceHistory,
VerifyInference,
RecordInferenceButton,
VerifiableAIDashboard
} from '@tenzro/platform-ui';
// Display inference history with ledger proofs
<InferenceHistory
limit={20}
onVerify={(proof) => console.log('Verified:', proof)}
/>
// Verify a specific inference
<VerifyInference
proofId="proof-123"
onResult={(result) => console.log('Valid:', result.valid)}
/>
// Button to record inference to ledger
<RecordInferenceButton
inferenceResult={result}
onRecorded={(proof) => console.log('Proof ID:', proof.id)}
/>
// Complete dashboard for verifiable AI
<VerifiableAIDashboard
showStats={true}
showHistory={true}
onInferenceSelected={(inference) => console.log(inference)}
/>Bridge Components
BridgeQuote
Complete bridge quote and transfer UI.
import { BridgeQuote } from '@tenzro/platform-ui';
function BridgePage() {
return (
<BridgeQuote
onQuote={(quote) => console.log('Quote:', quote)}
onTransfer={(operation) => console.log('Transfer initiated:', operation)}
defaultFromChain="ethereum"
defaultToChain="canton"
assets={['USDC', 'USDT', 'ETH']}
/>
);
}
// Props
interface BridgeQuoteProps {
onQuote?: (quote: BridgeQuoteResult) => void;
onTransfer?: (operation: BridgeOperation) => void;
defaultFromChain?: string;
defaultToChain?: string;
assets?: string[];
className?: string;
}Ledger Components
PartySelector
Dropdown for selecting Canton Network parties.
import { PartySelector } from '@tenzro/platform-ui';
function MyComponent() {
const [partyId, setPartyId] = useState<string>();
return (
<PartySelector
value={partyId}
onChange={setPartyId}
namespace="myapp" // Optional filter by namespace
placeholder="Select a party"
/>
);
}
// Props
interface PartySelectorProps {
value?: string;
onChange: (partyIdentifier: string) => void;
namespace?: string;
placeholder?: string;
className?: string;
disabled?: boolean;
}TransferForm
Form for ledger transfers between parties.
import { TransferForm } from '@tenzro/platform-ui';
function TransferPage() {
return (
<TransferForm
onTransfer={(result) => console.log('Transfer complete:', result)}
onError={(error) => console.error(error)}
defaultAsset="CC"
showBalances={true}
/>
);
}
// Props
interface TransferFormProps {
onTransfer?: (result: TransferResult) => void;
onError?: (error: Error) => void;
defaultFromParty?: string;
defaultToParty?: string;
defaultAsset?: string;
showBalances?: boolean;
className?: string;
}Custody Components
KeySelector
Dropdown for selecting custody keys.
import { KeySelector } from '@tenzro/platform-ui';
function SigningPage() {
const [keyId, setKeyId] = useState<string>();
return (
<KeySelector
value={keyId}
onChange={setKeyId}
algorithm="ECDSA_SECP256K1" // Optional filter
purpose="signing"
/>
);
}
// Props
interface KeySelectorProps {
value?: string;
onChange: (keyId: string) => void;
algorithm?: string;
purpose?: 'signing' | 'encryption';
placeholder?: string;
className?: string;
disabled?: boolean;
}SignForm
Form for signing messages with custody keys.
import { SignForm } from '@tenzro/platform-ui';
function SignPage() {
return (
<SignForm
onSign={(signature) => console.log('Signature:', signature)}
onError={(error) => console.error(error)}
defaultEncoding="hex"
/>
);
}
// Props
interface SignFormProps {
onSign?: (signature: SignatureResult) => void;
onError?: (error: Error) => void;
defaultKeyId?: string;
defaultEncoding?: 'hex' | 'base64' | 'utf8';
className?: string;
}Anchor Components
AnchorSubmit
Form for submitting state roots for anchoring.
import { AnchorSubmit } from '@tenzro/platform-ui';
function AnchorPage() {
return (
<AnchorSubmit
onSubmit={(anchor) => console.log('Anchored:', anchor)}
namespace="myapp"
showProof={true}
/>
);
}
// Props
interface AnchorSubmitProps {
onSubmit?: (anchor: AnchorResult) => void;
onError?: (error: Error) => void;
namespace?: string;
showProof?: boolean;
className?: string;
}ProofVerifier
UI for verifying Merkle proofs.
import { ProofVerifier } from '@tenzro/platform-ui';
function VerifyPage() {
return (
<ProofVerifier
onVerify={(result) => console.log('Valid:', result.valid)}
showDetails={true}
/>
);
}
// Props
interface ProofVerifierProps {
onVerify?: (result: VerificationResult) => void;
defaultStateRoot?: string;
showDetails?: boolean;
className?: string;
}Token Components
CollectionCreator
Form for creating token collections.
import { CollectionCreator } from '@tenzro/platform-ui';
function CollectionPage() {
return (
<CollectionCreator
onCreate={(collection) => console.log('Created:', collection)}
defaultType="ERC721"
chains={['ethereum', 'polygon', 'base']}
/>
);
}
// Props
interface CollectionCreatorProps {
onCreate?: (collection: Collection) => void;
onError?: (error: Error) => void;
defaultType?: 'ERC721' | 'ERC1155';
chains?: string[];
className?: string;
}API Keys Components
ApiKeyCreator
Form for creating API keys.
import { ApiKeyCreator } from '@tenzro/platform-ui';
function ApiKeysPage() {
return (
<ApiKeyCreator
onCreate={(key) => {
// Important: key.key is only available once!
console.log('Created key:', key.key);
}}
availableScopes={[
'read:wallet',
'write:wallet',
'read:token',
'write:token',
'ai:infer',
'ledger:read',
'ledger:write',
]}
defaultExpiry={30} // days
/>
);
}
// Props
interface ApiKeyCreatorProps {
onCreate?: (key: ApiKey) => void;
onError?: (error: Error) => void;
availableScopes?: string[];
defaultExpiry?: number;
className?: string;
}Styling Components
All components accept a className prop for custom styling. They render semantic HTML elements that can be styled with CSS:
/* Example: Styling ModelSelector */
.model-selector {
/* Wrapper */
}
.model-selector select {
/* The select element */
padding: 0.5rem 1rem;
border: 1px solid #e5e7eb;
border-radius: 0.375rem;
}
.model-selector option {
/* Option elements */
}
/* Example: Styling InferenceRunner */
.inference-runner {
display: flex;
flex-direction: column;
gap: 1rem;
}
.inference-runner textarea {
min-height: 100px;
}
.inference-runner button {
background: #3b82f6;
color: white;
padding: 0.5rem 1rem;
border-radius: 0.375rem;
}
.inference-runner .result {
background: #f3f4f6;
padding: 1rem;
border-radius: 0.375rem;
}Composing Components
Components can be composed to build complex UIs:
import {
ModelSelector,
TEEAttestationBadge,
useInfer
} from '@tenzro/platform-ui';
function CustomInference() {
const [modelId, setModelId] = useState<string>();
const [prompt, setPrompt] = useState('');
const { infer, loading, result } = useInfer();
return (
<div className="custom-inference">
<ModelSelector value={modelId} onChange={setModelId} />
<textarea
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
placeholder="Enter your prompt..."
/>
<button
onClick={() => infer({ modelId: modelId!, prompt })}
disabled={!modelId || !prompt || loading}
>
{loading ? 'Running...' : 'Run Inference'}
</button>
{result && (
<div className="result">
<p>{result.content}</p>
<TEEAttestationBadge attestation={result.teeAttestation} />
</div>
)}
</div>
);
}