rfunds-online/lib/types.ts

209 lines
5.8 KiB
TypeScript

import type { Node, Edge } from '@xyflow/react'
// ─── Integration Source Metadata ─────────────────────────────
export interface IntegrationSource {
type: 'rvote' | 'safe' | 'manual'
// Safe fields
safeAddress?: string
safeChainId?: number
tokenAddress?: string | null // null = native token
tokenSymbol?: string
tokenDecimals?: number
// rVote fields
rvoteSpaceSlug?: string
rvoteProposalId?: string
rvoteProposalStatus?: string
rvoteProposalScore?: number
lastFetchedAt?: number
}
// ─── Superfluid Stream (planning only) ───────────────────────
export interface StreamAllocation {
targetId: string
flowRate: number // tokens per month
tokenSymbol: string // e.g., 'DAIx', 'USDCx'
tokenAddress?: string
status: 'planned' | 'active' | 'paused'
color: string
}
// ─── 0xSplits Configuration (planning only) ──────────────────
export interface SplitRecipient {
address: string
label?: string
percentage: number // 0-100, must sum to 100
}
export interface SplitsConfig {
recipients: SplitRecipient[]
distributorFee: number // 0-10%
chainId: number
}
// ─── Integration Config (persisted per space) ────────────────
export interface IntegrationConfig {
rvote?: {
spaceSlug: string
spaceName?: string
lastSyncedAt?: number
}
safe?: {
address: string
chainIds: number[] // e.g., [100, 10] for Gnosis + Optimism
lastSyncedAt?: number
}
}
// ─── Funding Sources ────────────────────────────────────────
export type FundingSourceType = 'card' | 'crypto_wallet' | 'safe_treasury' | 'bank_transfer' | 'ridentity';
export interface FundingSource {
id: string;
type: FundingSourceType;
label: string;
enabled: boolean;
// Card/bank-specific
transakConfig?: {
fiatCurrency: string;
defaultAmount?: number;
};
// Crypto wallet-specific
walletAddress?: string;
chainId?: number;
tokenAddress?: string;
// Safe treasury-specific
safeAddress?: string;
safeChainId?: number;
// rIdentity-specific
encryptIdUserId?: string;
// Common
lastUsedAt?: number;
}
// ─── Source Node Types ──────────────────────────────────────
export interface SourceAllocation {
targetId: string
percentage: number
color: string
}
export interface SourceNodeData {
label: string
sourceType: 'card' | 'safe_wallet' | 'ridentity' | 'unconfigured'
flowRate: number
targetAllocations: SourceAllocation[]
// Card-specific
transakConfig?: { fiatCurrency: string; defaultAmount?: number }
// Safe/Wallet-specific
walletAddress?: string
chainId?: number
safeAddress?: string
// rIdentity-specific
encryptIdUserId?: string
[key: string]: unknown
}
// ─── Outcome Phase Types ────────────────────────────────────
export interface PhaseTask {
label: string
completed: boolean
}
export interface OutcomePhase {
label: string // e.g., "Phase 1: Research"
fundingThreshold: number // funding level to unlock this phase
tasks: PhaseTask[]
}
// ─── Core Flow Types ─────────────────────────────────────────
// Overflow allocation - funds flowing to OTHER FUNNELS when above max threshold
export interface OverflowAllocation {
targetId: string
percentage: number // 0-100
color: string
}
// Spending allocation - funds flowing DOWN to OUTCOMES/OUTPUTS
export interface SpendingAllocation {
targetId: string
percentage: number // 0-100
color: string
}
export interface FunnelNodeData {
label: string
currentValue: number
minThreshold: number
maxThreshold: number
maxCapacity: number
inflowRate: number
// Overflow goes SIDEWAYS to other funnels
overflowAllocations: OverflowAllocation[]
// Spending goes DOWN to outcomes/outputs
spendingAllocations: SpendingAllocation[]
// Integration metadata
source?: IntegrationSource
streamAllocations?: StreamAllocation[]
splitsConfig?: SplitsConfig
fundingSources?: FundingSource[]
[key: string]: unknown
}
export interface OutcomeNodeData {
label: string
description?: string
fundingReceived: number
fundingTarget: number
status: 'not-started' | 'in-progress' | 'completed' | 'blocked'
phases?: OutcomePhase[] // ordered by fundingThreshold ascending
// Integration metadata
source?: IntegrationSource
// Optional detail fields
completedAt?: number
milestones?: Array<{ label: string; completedAt?: number }>
[key: string]: unknown
}
export type FlowNode = Node<FunnelNodeData | OutcomeNodeData | SourceNodeData>
export interface AllocationEdgeData {
allocation: number // percentage 0-100
color: string
edgeType: 'overflow' | 'spending' | 'source' // overflow = sideways, spending = downward, source = top-down from source
sourceId: string
targetId: string
siblingCount: number // how many allocations in this group
onAdjust?: (sourceId: string, targetId: string, edgeType: 'overflow' | 'spending' | 'source', delta: number) => void
[key: string]: unknown
}
export interface StreamEdgeData {
flowRate: number
tokenSymbol: string
status: 'planned' | 'active' | 'paused'
sourceId: string
targetId: string
[key: string]: unknown
}
export type FlowEdgeData = AllocationEdgeData | StreamEdgeData
export type FlowEdge = Edge<FlowEdgeData>
// Serializable space config (no xyflow internals)
export interface SpaceConfig {
name: string
nodes: FlowNode[]
integrations?: IntegrationConfig
createdAt: number
updatedAt: number
}