Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions components/overlays/add-connection-overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ import {
aiGatewayTeamsLoadingAtom,
} from "@/lib/ai-gateway/state";
import { api } from "@/lib/api-client";
// start keeperhub
import { getCustomIntegrationFormHandler } from "@/lib/extension-registry";
// end keeperhub
import type { IntegrationType } from "@/lib/types/integration";
import {
getIntegration,
Expand Down Expand Up @@ -361,6 +364,18 @@ export function ConfigureConnectionOverlay({

// Render config fields
const renderConfigFields = () => {
// start keeperhub - check for custom form handlers (e.g., web3 wallet)
const customHandler = getCustomIntegrationFormHandler(type);
if (customHandler) {
return customHandler({
integrationType: type,
isEditMode: false,
config,
updateConfig,
});
}
// end keeperhub

if (type === "database") {
return (
<SecretField
Expand Down
15 changes: 15 additions & 0 deletions components/overlays/edit-connection-overlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { useIsMobile } from "@/hooks/use-mobile";
import { api, type Integration } from "@/lib/api-client";
// start keeperhub
import { getCustomIntegrationFormHandler } from "@/lib/extension-registry";
import { getIntegration, getIntegrationLabels } from "@/plugins";
// end keeperhub
import { ConfirmOverlay } from "./confirm-overlay";
import { Overlay } from "./overlay";
import { useOverlay } from "./overlay-provider";
Expand Down Expand Up @@ -267,6 +270,18 @@ export function EditConnectionOverlay({

// Render config fields
const renderConfigFields = () => {
// start keeperhub - check for custom form handlers (e.g., web3 wallet display)
const customHandler = getCustomIntegrationFormHandler(integration.type);
if (customHandler) {
return customHandler({
integrationType: integration.type,
isEditMode: true,
config,
updateConfig,
});
}
// end keeperhub

if (integration.type === "database") {
return (
<SecretField
Expand Down
27 changes: 15 additions & 12 deletions components/workflow/config/action-config.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ import {
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
// start keeperhub
import { integrationRequiresCredentials } from "@/keeperhub/lib/integration-helpers";
// end keeperhub
import { aiGatewayStatusAtom } from "@/lib/ai-gateway/state";
Expand All @@ -39,6 +38,7 @@ import {
findActionById,
getActionsByCategory,
getAllIntegrations,
getIntegration,
} from "@/plugins";
import { ActionConfigRenderer } from "./action-config-renderer";
import { SchemaBuilder, type SchemaField } from "./schema-builder";
Expand Down Expand Up @@ -524,17 +524,20 @@ export function ActionConfig({
</Tooltip>
</TooltipProvider>
</div>
{hasExistingConnections && (
<Button
className="size-6"
disabled={disabled}
onClick={handleAddSecondaryConnection}
size="icon"
variant="ghost"
>
<Plus className="size-4" />
</Button>
)}
{/* start keeperhub - hide + button for singleConnection integrations */}
{hasExistingConnections &&
!getIntegration(integrationType)?.singleConnection && (
<Button
className="size-6"
disabled={disabled}
onClick={handleAddSecondaryConnection}
size="icon"
variant="ghost"
>
<Plus className="size-4" />
</Button>
)}
{/* end keeperhub */}
</div>
<IntegrationSelector
disabled={disabled}
Expand Down
18 changes: 5 additions & 13 deletions keeperhub/plugins/web3/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,11 @@ const web3Plugin: IntegrationPlugin = {

icon: Web3Icon,

// Minimal form field - Web3 uses PARA wallet (user must create manually)
// This field is informational only and not used
formFields: [
{
id: "info",
label: "Para Wallet",
type: "text",
placeholder: "Create a wallet to use Web3 actions",
configKey: "info",
helpText:
"You'll need to create a Para wallet to use Web3 actions in your workflows.",
},
],
// Web3 uses Para wallet - one wallet per user
singleConnection: true,

// No form fields - wallet creation is handled by the custom form handler
formFields: [],

// No test function needed - no credentials to test
// testConfig is optional, so we omit it
Expand Down
5 changes: 5 additions & 0 deletions plugins/registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,11 @@ export type IntegrationPlugin = {
// Defaults to true for backward compatibility
requiresCredentials?: boolean;

// Whether only one connection is allowed per user
// Set to true for integrations with unique constraints (e.g., web3 wallet)
// When true, the "+" button to add more connections will be hidden
singleConnection?: boolean;

// Form fields for the integration dialog
formFields: Array<{
id: string;
Expand Down