-
- {metadata?.name ?? "Agent"} #{agentId.toString()}
-
+
+
+ {metadata?.name ?? "Agent"} #{agentId.toString()}
+
+ {source && (
+
+ {source === "ows" ? "OWS Writer" : "Direct"}
+
+ )}
+
{role === "owner" ? "You own this agent" : "Your wallet is bound to this agent"}
@@ -460,7 +474,64 @@ export function AgentManage({ agentId, role }: AgentManageProps) {
)}
+ ) : source === "ows" ? (
+ /* OWS agents: paste-based flow (signature generated on local OWS app) */
+
+
+
+ setNewWalletAddr(e.target.value)} placeholder="0x..."
+ className="border-border bg-surface text-foreground placeholder:text-muted w-full rounded border px-3 py-2 text-sm font-mono focus:border-accent focus:outline-none" />
+
+
+ Go to your OWS app → Settings → enter Agent ID {agentId.toString()} → click "Generate Wallet Bind Code". Paste the signature and deadline below.
+
+
+
+ setOwsPastedSig(e.target.value)} placeholder="0x..."
+ className="border-border bg-surface text-foreground placeholder:text-muted w-full rounded border px-3 py-2 text-sm font-mono focus:border-accent focus:outline-none" />
+
+
+
+ setOwsPastedDeadline(e.target.value)} placeholder="e.g. 1712345678"
+ className="border-border bg-surface text-foreground placeholder:text-muted w-full rounded border px-3 py-2 text-sm font-mono focus:border-accent focus:outline-none" />
+
+
+
+
+
+
) : (
+ /* Direct agents: browser-based sign flow (existing) */
{walletStep === "enter" && (
<>
@@ -574,3 +645,119 @@ export function AgentManage({ agentId, role }: AgentManageProps) {
);
}
+
+const ZERO_ADDR = "0x0000000000000000000000000000000000000000";
+
+/** Wrapper that enumerates all agents owned by the connected wallet */
+export function AgentManageAll() {
+ const { address } = useAccount();
+
+ const { data: balance, isLoading: balanceLoading } = useReadContract({
+ address: ERC8004_REGISTRY,
+ abi: erc8004Abi,
+ functionName: "balanceOf",
+ args: address ? [address] : undefined,
+ query: { enabled: !!address },
+ });
+
+ const agentCount = balance !== undefined ? Number(balance) : 0;
+
+ const tokenIndexCalls = useMemo(() => {
+ if (!address || agentCount === 0) return [];
+ return Array.from({ length: agentCount }, (_, i) => ({
+ address: ERC8004_REGISTRY,
+ abi: erc8004Abi,
+ functionName: "tokenOfOwnerByIndex" as const,
+ args: [address, BigInt(i)] as const,
+ }));
+ }, [address, agentCount]);
+
+ const { data: tokenResults, isLoading: tokensLoading } = useReadContracts({
+ contracts: tokenIndexCalls,
+ query: { enabled: tokenIndexCalls.length > 0 },
+ });
+
+ const agentIds = useMemo(() => {
+ if (!tokenResults) return [];
+ return tokenResults
+ .filter((r) => r.status === "success" && r.result !== undefined)
+ .map((r) => r.result as bigint);
+ }, [tokenResults]);
+
+ // Fetch agentURI + getAgentWallet for each agent to determine source
+ const metaCalls = useMemo(() => {
+ if (agentIds.length === 0) return [];
+ return agentIds.flatMap((id) => [
+ { address: ERC8004_REGISTRY, abi: erc8004Abi, functionName: "agentURI" as const, args: [id] as const },
+ { address: ERC8004_REGISTRY, abi: erc8004Abi, functionName: "getAgentWallet" as const, args: [id] as const },
+ ]);
+ }, [agentIds]);
+
+ const { data: metaResults, isLoading: metaLoading } = useReadContracts({
+ contracts: metaCalls,
+ query: { enabled: metaCalls.length > 0 },
+ });
+
+ const agents = useMemo(() => {
+ if (agentIds.length === 0 || !metaResults) return [];
+ return agentIds.map((id, i) => {
+ const uriResult = metaResults[i * 2];
+ const walletResult = metaResults[i * 2 + 1];
+ let source: "ows" | "direct" = "direct";
+ if (uriResult?.status === "success" && uriResult.result) {
+ try {
+ const meta = JSON.parse(uriResult.result as string);
+ if (meta.type === "ows-writer" || meta.owsWallet) source = "ows";
+ } catch { /* not JSON */ }
+ }
+ const walletAddr = walletResult?.status === "success" ? (walletResult.result as string) : undefined;
+ if (walletAddr && walletAddr !== ZERO_ADDR) source = "ows";
+ return { agentId: id, source };
+ });
+ }, [agentIds, metaResults]);
+
+ // Also check if connected wallet is an agent wallet
+ const { data: selfAgentId } = useReadContract({
+ address: ERC8004_REGISTRY,
+ abi: erc8004Abi,
+ functionName: "agentIdByWallet",
+ args: address ? [address] : undefined,
+ query: { enabled: !!address },
+ });
+ const isSelfAgent = selfAgentId !== undefined && selfAgentId > BigInt(0);
+ const selfInList = agents.some((a) => a.agentId === selfAgentId);
+
+ const isLoading = balanceLoading || tokensLoading || metaLoading;
+
+ if (isLoading) {
+ return (
+
+ );
+ }
+
+ const hasAgents = agents.length > 0 || (isSelfAgent && !selfInList);
+
+ if (!hasAgents) {
+ return (
+
+
You have no AI agents registered.
+
+ Switch to the Register tab to register an agent.
+
+
+ );
+ }
+
+ return (
+
+ {agents.map((agent) => (
+
+ ))}
+ {isSelfAgent && !selfInList && (
+
+ )}
+
+ );
+}