diff --git a/app/vibenet/demos/b20/components/AnnouncementModule.tsx b/app/vibenet/demos/b20/components/AnnouncementModule.tsx index 4aa54c1..37e636e 100644 --- a/app/vibenet/demos/b20/components/AnnouncementModule.tsx +++ b/app/vibenet/demos/b20/components/AnnouncementModule.tsx @@ -15,24 +15,31 @@ import type { TokenAccess, TokenInfo } from '../lib/types'; import { CopyPromptButton } from './CopyPromptButton'; import { ErrorNote, Field, Input, Notice } from './primitives'; +type AnnouncementModuleProps = { + open: boolean; + onClose: () => void; + token: TokenInfo | null; + tokenAccess: TokenAccess; + wallet: Address | null; + onSend: (label: string, to: Address, data: Hex, action: string) => Promise; +}; + // Disclosure-only announcement flow, presented through the shared TransactionModal. // Publishing requires OPERATOR_ROLE and an Asset token (Stablecoins do not support // announcements). -export function AnnouncementModule({ +export function AnnouncementModule(props: AnnouncementModuleProps) { + if (!props.open) return null; + return ; +} + +function AnnouncementModuleInner({ open, onClose, token, tokenAccess, wallet, onSend, -}: { - open: boolean; - onClose: () => void; - token: TokenInfo | null; - tokenAccess: TokenAccess; - wallet: Address | null; - onSend: (label: string, to: Address, data: Hex, action: string) => Promise; -}) { +}: AnnouncementModuleProps) { const [id, setId] = useState(''); const [description, setDescription] = useState(''); const [uri, setUri] = useState(''); @@ -41,19 +48,8 @@ export function AnnouncementModule({ const [error, setError] = useState(null); const [txHash, setTxHash] = useState(null); - const reset = () => { - setStep('build'); - setFinalizing(false); - setError(null); - setTxHash(null); - setId(''); - setDescription(''); - setUri(''); - }; - const handleClose = () => { if (finalizing) return; - reset(); onClose(); }; diff --git a/app/vibenet/demos/b20/components/AssignPolicyModal.tsx b/app/vibenet/demos/b20/components/AssignPolicyModal.tsx index 685496f..431755e 100644 --- a/app/vibenet/demos/b20/components/AssignPolicyModal.tsx +++ b/app/vibenet/demos/b20/components/AssignPolicyModal.tsx @@ -13,41 +13,40 @@ import type { TokenInfo } from '../lib/types'; export type PendingAssignment = { scope: string; scopeLabel: string; policyId: bigint; policyLabel: string }; +type AssignPolicyModalProps = { + open: boolean; + onClose: () => void; + token: TokenInfo | null; + assignment: PendingAssignment | null; + onSend: (label: string, to: Address, data: Hex, action: string) => Promise; +}; + // Assign (or clear) a policy on a token feature, through the shared // TransactionModal so the change is reviewed and confirmed like every other send. -export function AssignPolicyModal({ +export function AssignPolicyModal(props: AssignPolicyModalProps) { + if (!props.open || !props.assignment) return null; + return ; +} + +function AssignPolicyInner({ open, onClose, token, assignment, onSend, -}: { - open: boolean; - onClose: () => void; - token: TokenInfo | null; - assignment: PendingAssignment | null; - onSend: (label: string, to: Address, data: Hex, action: string) => Promise; -}) { +}: Omit & { assignment: PendingAssignment }) { const [step, setStep] = useState('build'); const [finalizing, setFinalizing] = useState(false); const [error, setError] = useState(null); const [txHash, setTxHash] = useState(null); - const reset = () => { - setStep('build'); - setFinalizing(false); - setError(null); - setTxHash(null); - }; - const handleClose = () => { if (finalizing) return; - reset(); onClose(); }; const submit = async () => { - if (!token || !assignment) return; + if (!token) return; setError(null); setStep('submitted'); setFinalizing(true); @@ -76,7 +75,7 @@ export function AssignPolicyModal({ error={error ?? undefined} result={txHash ? { txHash } : null} titles={{ build: 'Assign Policy', submitted: 'Assign Policy' }} - canProceed={Boolean(assignment)} + canProceed proceedLabel="Assign" onProceed={() => void submit()} onSubmittedBack={() => { @@ -90,20 +89,18 @@ export function AssignPolicyModal({
Policy updated - Updated “{assignment?.scopeLabel}” to {assignment?.policyLabel}. + Updated “{assignment.scopeLabel}” to {assignment.policyLabel}.
)} buildBody={ - assignment ? ( -
    - - {assignment.scopeLabel} - - {assignment.policyLabel} - -
- ) : null +
    + + {assignment.scopeLabel} + + {assignment.policyLabel} + +
} /> ); diff --git a/app/vibenet/demos/b20/components/DeployModule.tsx b/app/vibenet/demos/b20/components/DeployModule.tsx index e8e1ed1..34f6b09 100644 --- a/app/vibenet/demos/b20/components/DeployModule.tsx +++ b/app/vibenet/demos/b20/components/DeployModule.tsx @@ -31,28 +31,35 @@ import { import type { CreatedToken } from '../lib/types'; import { ErrorNote, Field, Input } from './primitives'; +type DeployModuleProps = { + open: boolean; + onClose: () => void; + wallet: Address | null; + onSendCalls: (label: string, calls: Array<{ to: Address; data: Hex }>, action: string) => Promise; + onCreated: (token: CreatedToken) => Promise; + /** Guided flow: after a stablecoin is created, jump to a first payment in it. */ + onFirstPayment?: () => void; +}; + // Create-token flow, presented through the shared TransactionModal: the form is // the build step and a successful deploy shows a compact custom success view. // The whole deployment runs as ONE atomic EIP-8130 transaction whose calls // create the bare token, then grant roles, apply options, and mint — all in a // single transaction (the 8130 account executes the calls in order, so the // freshly deployed token is callable by the calls that follow it). -export function DeployModule({ +export function DeployModule(props: DeployModuleProps) { + if (!props.open) return null; + return ; +} + +function DeployModuleInner({ open, onClose, wallet, onSendCalls, onCreated, onFirstPayment, -}: { - open: boolean; - onClose: () => void; - wallet: Address | null; - onSendCalls: (label: string, calls: Array<{ to: Address; data: Hex }>, action: string) => Promise; - onCreated: (token: CreatedToken) => Promise; - /** Guided flow: after a stablecoin is created, jump to a first payment in it. */ - onFirstPayment?: () => void; -}) { +}: DeployModuleProps) { const [variant, setVariant] = useState<'asset' | 'stablecoin'>('asset'); // Advanced mode reveals the salt, supply cap, and token-info link — hidden by // default so the common path stays short (mirrors the account create modal's @@ -71,17 +78,8 @@ export function DeployModule({ const [error, setError] = useState(null); const [createdToken, setCreatedToken] = useState(null); - const reset = () => { - setStep('build'); - setFinalizing(false); - setError(null); - setCreatedToken(null); - setSalt(''); - }; - const handleClose = () => { if (finalizing) return; - reset(); onClose(); }; @@ -215,10 +213,7 @@ export function DeployModule({ diff --git a/app/vibenet/demos/b20/components/GasModule.tsx b/app/vibenet/demos/b20/components/GasModule.tsx index 0509322..65e846e 100644 --- a/app/vibenet/demos/b20/components/GasModule.tsx +++ b/app/vibenet/demos/b20/components/GasModule.tsx @@ -12,12 +12,31 @@ import { TransactionModal, type TxStep } from '../../_shared/TransactionModal'; import type { TokenInfo } from '../lib/types'; import { Notice } from './primitives'; +type GasModuleProps = { + open: boolean; + onClose: () => void; + token: TokenInfo | null; + /** ETH being sent by the demo transaction, e.g. "0.001". */ + ethAmount: string; + /** Recipient of the demo ETH transfer. */ + recipient: string; + /** Flat per-transaction fee in token terms, e.g. "0.10". */ + fee: string; + /** Sends the demo transaction with its gas paid in the token; resolves to the tx hash. */ + onPay: () => Promise; +}; + // "Gas Payments" flow: send a real transaction whose network fee is paid in the // currently selected stablecoin, not ETH. The account spends the token; the // demo's own ERC-8168 gas payer spends the ETH that actually buys the gas, so // the account never needs to hold ETH. This is a demonstration send, not a // persistent setting — every payment pays its own fee in the token. -export function GasModule({ +export function GasModule(props: GasModuleProps) { + if (!props.open) return null; + return ; +} + +function GasModuleInner({ open, onClose, token, @@ -25,19 +44,7 @@ export function GasModule({ recipient, fee, onPay, -}: { - open: boolean; - onClose: () => void; - token: TokenInfo | null; - /** ETH being sent by the demo transaction, e.g. "0.001". */ - ethAmount: string; - /** Recipient of the demo ETH transfer. */ - recipient: string; - /** Flat per-transaction fee in token terms, e.g. "0.10". */ - fee: string; - /** Sends the demo transaction with its gas paid in the token; resolves to the tx hash. */ - onPay: () => Promise; -}) { +}: GasModuleProps) { const [step, setStep] = useState('build'); const [finalizing, setFinalizing] = useState(false); const [error, setError] = useState(null); @@ -45,16 +52,8 @@ export function GasModule({ const isStablecoin = token?.variant === 'stablecoin'; - const reset = () => { - setStep('build'); - setFinalizing(false); - setError(null); - setTxHash(null); - }; - const handleClose = () => { if (finalizing) return; - reset(); onClose(); }; diff --git a/app/vibenet/demos/b20/components/MemoModule.tsx b/app/vibenet/demos/b20/components/MemoModule.tsx index e8c9773..6f6616d 100644 --- a/app/vibenet/demos/b20/components/MemoModule.tsx +++ b/app/vibenet/demos/b20/components/MemoModule.tsx @@ -15,21 +15,28 @@ import type { TokenInfo } from '../lib/types'; import { CopyPromptButton } from './CopyPromptButton'; import { ErrorNote, Field, Input } from './primitives'; +type MemoModuleProps = { + open: boolean; + onClose: () => void; + token: TokenInfo | null; + addressBook: AddressBookEntry[]; + onSend: (label: string, to: Address, data: Hex, action: string) => Promise; +}; + // Send-with-memo flow, presented through the shared TransactionModal. It attaches // a bytes32 reference to a B20 transfer so the transaction can be reconciled later. -export function MemoModule({ +export function MemoModule(props: MemoModuleProps) { + if (!props.open) return null; + return ; +} + +function MemoModuleInner({ open, onClose, token, addressBook, onSend, -}: { - open: boolean; - onClose: () => void; - token: TokenInfo | null; - addressBook: AddressBookEntry[]; - onSend: (label: string, to: Address, data: Hex, action: string) => Promise; -}) { +}: MemoModuleProps) { const [to, setTo] = useState(''); const [value, setValue] = useState(''); const [memo, setMemo] = useState(''); @@ -38,19 +45,8 @@ export function MemoModule({ const [error, setError] = useState(null); const [txHash, setTxHash] = useState(null); - const reset = () => { - setStep('build'); - setFinalizing(false); - setError(null); - setTxHash(null); - setTo(''); - setValue(''); - setMemo(''); - }; - const handleClose = () => { if (finalizing) return; - reset(); onClose(); }; diff --git a/app/vibenet/demos/b20/components/TransferModule.tsx b/app/vibenet/demos/b20/components/TransferModule.tsx index 7ea97bd..266b605 100644 --- a/app/vibenet/demos/b20/components/TransferModule.tsx +++ b/app/vibenet/demos/b20/components/TransferModule.tsx @@ -12,21 +12,28 @@ import { amount, b20Abi, memoToBytes32 } from '../lib/protocol'; import type { TokenInfo } from '../lib/types'; import { ErrorNote, Field, Input } from './primitives'; +type TransferModuleProps = { + open: boolean; + onClose: () => void; + token: TokenInfo | null; + addressBook: AddressBookEntry[]; + onSend: (label: string, to: Address, data: Hex, action: string) => Promise; +}; + // Plain token transfer — a recipient and an amount, presented through the shared // TransactionModal. -export function TransferModule({ +export function TransferModule(props: TransferModuleProps) { + if (!props.open) return null; + return ; +} + +function TransferModuleInner({ open, onClose, token, addressBook, onSend, -}: { - open: boolean; - onClose: () => void; - token: TokenInfo | null; - addressBook: AddressBookEntry[]; - onSend: (label: string, to: Address, data: Hex, action: string) => Promise; -}) { +}: TransferModuleProps) { const [to, setTo] = useState(''); const [value, setValue] = useState(''); const [step, setStep] = useState('build'); @@ -34,18 +41,8 @@ export function TransferModule({ const [error, setError] = useState(null); const [txHash, setTxHash] = useState(null); - const reset = () => { - setStep('build'); - setFinalizing(false); - setError(null); - setTxHash(null); - setTo(''); - setValue(''); - }; - const handleClose = () => { if (finalizing) return; - reset(); onClose(); };