@wealthfolio/addon-sdk 3.3.0 → 3.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -82,6 +82,7 @@ export type DataSource = (typeof DataSource)[keyof typeof DataSource];
82
82
  export declare const AccountType: {
83
83
  readonly SECURITIES: "SECURITIES";
84
84
  readonly CASH: "CASH";
85
+ readonly CREDIT_CARD: "CREDIT_CARD";
85
86
  readonly CRYPTOCURRENCY: "CRYPTOCURRENCY";
86
87
  };
87
88
  export type AccountType = (typeof AccountType)[keyof typeof AccountType];
@@ -129,6 +130,7 @@ export interface Activity {
129
130
  unitPrice?: string | null;
130
131
  amount?: string | null;
131
132
  fee?: string | null;
133
+ tax?: string | null;
132
134
  currency: string;
133
135
  fxRate?: string | null;
134
136
  notes?: string;
@@ -161,6 +163,7 @@ export interface ActivityDetails {
161
163
  unitPrice: string | null;
162
164
  amount: string | null;
163
165
  fee: string | null;
166
+ tax?: string | null;
164
167
  currency: string;
165
168
  needsReview: boolean;
166
169
  comment?: string;
@@ -198,6 +201,8 @@ export interface AssetResolutionInput {
198
201
  quoteMode?: QuoteMode;
199
202
  quoteCcy?: string;
200
203
  instrumentType?: string;
204
+ providerId?: string;
205
+ providerSymbol?: string;
201
206
  }
202
207
  /** @deprecated Use AssetResolutionInput. */
203
208
  export type SymbolInput = AssetResolutionInput;
@@ -216,6 +221,7 @@ export interface ActivityCreate {
216
221
  amount?: string | number | null;
217
222
  currency?: string;
218
223
  fee?: string | number | null;
224
+ tax?: string | number | null;
219
225
  comment?: string | null;
220
226
  fxRate?: string | number | null;
221
227
  metadata?: string | Record<string, unknown>;
@@ -235,6 +241,7 @@ export interface ActivityUpdate {
235
241
  amount?: string | number | null;
236
242
  currency?: string;
237
243
  fee?: string | number | null;
244
+ tax?: string | number | null;
238
245
  comment?: string | null;
239
246
  fxRate?: string | number | null;
240
247
  metadata?: string | Record<string, unknown>;
@@ -273,6 +280,7 @@ export interface ActivityImport {
273
280
  quantity?: number | string | null;
274
281
  unitPrice?: number | string | null;
275
282
  fee?: number | string | null;
283
+ tax?: number | string | null;
276
284
  fxRate?: number | string | null;
277
285
  accountName?: string;
278
286
  symbolName?: string;
@@ -284,6 +292,10 @@ export interface ActivityImport {
284
292
  instrumentType?: string;
285
293
  /** Resolved quote mode hint (e.g., MANUAL, MARKET) */
286
294
  quoteMode?: string;
295
+ /** Market data provider that resolved this import row, if selected. */
296
+ providerId?: string;
297
+ /** Provider-native symbol/code selected by search/import. */
298
+ providerSymbol?: string;
287
299
  errors?: Record<string, string[]>;
288
300
  warnings?: Record<string, string[]>;
289
301
  duplicateOfId?: string;
@@ -318,6 +330,14 @@ export interface SymbolSearchResult {
318
330
  exchange: string;
319
331
  /** Canonical exchange MIC code (e.g., "XNAS", "XTSE") */
320
332
  exchangeMic?: string;
333
+ /** Canonical asset symbol used for persistence (e.g., "SHOP" for "SHOP.TO") */
334
+ canonicalSymbol?: string;
335
+ /** Canonical exchange MIC used for persistence */
336
+ canonicalExchangeMic?: string;
337
+ /** Market data provider that returned or resolved this symbol */
338
+ providerId?: string;
339
+ /** Provider-native symbol/code (e.g., Yahoo "BRK-B") */
340
+ providerSymbol?: string;
321
341
  /** Friendly exchange name (e.g., "NASDAQ" instead of "NMS" or "XNAS") */
322
342
  exchangeName?: string;
323
343
  /** Currency derived from exchange (e.g., "USD", "CAD") */
@@ -453,6 +473,10 @@ export interface Holding {
453
473
  realizedGainPct?: number | null;
454
474
  totalGain?: MonetaryValue | null;
455
475
  totalGainPct?: number | null;
476
+ income?: MonetaryValue | null;
477
+ totalReturn?: MonetaryValue | null;
478
+ totalReturnPct?: number | null;
479
+ returnBasis?: MonetaryValue | null;
456
480
  dayChange?: MonetaryValue | null;
457
481
  dayChangePct?: number | null;
458
482
  prevCloseValue?: MonetaryValue | null;
@@ -511,6 +535,7 @@ export interface Settings {
511
535
  theme: string;
512
536
  font: string;
513
537
  baseCurrency: string;
538
+ defaultReturnMetric: 'twr' | 'irr' | 'valueReturn';
514
539
  timezone?: string;
515
540
  instanceId: string;
516
541
  onboardingCompleted: boolean;
@@ -583,6 +608,8 @@ export interface DateRange {
583
608
  to: Date | undefined;
584
609
  }
585
610
  export type TimePeriod = '1D' | '1W' | '1M' | '3M' | '6M' | 'YTD' | '1Y' | '5Y' | 'ALL';
611
+ export type ValuationStatus = 'complete' | 'partialUnpriced' | 'unavailable';
612
+ export type BasisStatus = 'complete' | 'partialUnknown' | 'unknown' | 'notApplicable';
586
613
  export interface AccountValuation {
587
614
  id: string;
588
615
  accountId: string;
@@ -595,6 +622,17 @@ export interface AccountValuation {
595
622
  totalValue: number;
596
623
  costBasis: number;
597
624
  netContribution: number;
625
+ cashBalanceBase: number;
626
+ investmentMarketValueBase: number;
627
+ totalValueBase: number;
628
+ costBasisBase: number;
629
+ netContributionBase: number;
630
+ externalInflowBase: number;
631
+ externalOutflowBase: number;
632
+ externalFlowSource: 'NO_FLOW' | 'UNKNOWN' | 'CASH_AMOUNT' | 'QUOTE_DERIVED_MARKET_VALUE' | 'COST_BASIS_FALLBACK' | 'REMOVED_LOT_BASIS_FALLBACK' | 'LEGACY_ACTIVITY_AMOUNT_FALLBACK' | 'UNKNOWN_BOUNDARY_TRANSFER' | 'ACTIVITY_DERIVED' | 'STORED_GROSS' | 'NET_CONTRIBUTION_FALLBACK' | 'MIXED';
633
+ performanceEligibleValueBase: number;
634
+ valueStatus: ValuationStatus;
635
+ basisStatus: BasisStatus;
598
636
  calculatedAt: string;
599
637
  }
600
638
  export interface AccountSummaryView {
@@ -606,9 +644,9 @@ export interface AccountSummaryView {
606
644
  totalValueAccountCurrency: number;
607
645
  totalValueBaseCurrency: number;
608
646
  baseCurrency: string;
609
- performance: SimplePerformanceMetrics;
647
+ performance: SimplePerformanceResult;
610
648
  }
611
- export interface SimplePerformanceMetrics {
649
+ export interface SimplePerformanceResult {
612
650
  accountId: string;
613
651
  totalValue?: number | null;
614
652
  accountCurrency?: string | null;
@@ -616,16 +654,16 @@ export interface SimplePerformanceMetrics {
616
654
  fxRateToBase?: number | null;
617
655
  totalGainLossAmount?: number | null;
618
656
  cumulativeReturnPercent?: number | null;
619
- dayGainLossAmount?: number | null;
620
- dayReturnPercentModDietz?: number | null;
621
657
  portfolioWeight?: number | null;
622
658
  }
659
+ /** @deprecated Use SimplePerformanceResult. */
660
+ export type SimplePerformanceMetrics = SimplePerformanceResult;
623
661
  export interface AccountGroup {
624
662
  groupName: string;
625
663
  accounts: AccountSummaryView[];
626
664
  totalValueBaseCurrency: number;
627
665
  baseCurrency: string;
628
- performance: SimplePerformanceMetrics;
666
+ performance: SimplePerformanceResult;
629
667
  accountCount: number;
630
668
  }
631
669
  export interface ExchangeRate {
@@ -666,32 +704,77 @@ export interface ReturnData {
666
704
  date: string;
667
705
  value: number;
668
706
  }
669
- export interface PerformanceMetrics {
707
+ export interface PerformanceResult {
708
+ scope: PerformanceScopeDescriptor;
709
+ period: PerformancePeriod;
710
+ mode: ReturnMethod;
711
+ returns: PerformanceReturns;
712
+ attribution: PerformanceAttribution;
713
+ risk: PerformanceRisk;
714
+ dataQuality: PerformanceDataQuality;
715
+ basisStatus?: BasisStatus;
716
+ summary?: PerformanceSummary;
717
+ series: ReturnData[];
718
+ isHoldingsMode?: boolean;
719
+ isMixedTrackingMode?: boolean;
720
+ }
721
+ /** @deprecated Use PerformanceResult. */
722
+ export type PerformanceMetrics = PerformanceResult;
723
+ export interface PerformanceScopeDescriptor {
670
724
  id: string;
671
- returns: ReturnData[];
672
- periodStartDate?: string | null;
673
- periodEndDate?: string | null;
674
725
  currency: string;
675
- /** Period gain in dollars (SOTA: change in unrealized P&L for HOLDINGS mode) */
676
- periodGain: number;
677
- /** Period return percentage (SOTA formula for HOLDINGS mode). Null when start value ≤ 0. */
678
- periodReturn: number | null;
679
- /** Time-weighted return (null for HOLDINGS mode - requires cash flow tracking) */
680
- cumulativeTwr?: number | null;
681
- /** Legacy field for backward compatibility */
682
- gainLossAmount?: number | null;
683
- /** Annualized TWR (null for HOLDINGS mode) */
726
+ }
727
+ export interface PerformancePeriod {
728
+ startDate?: string | null;
729
+ endDate?: string | null;
730
+ }
731
+ export type ReturnMethod = 'timeWeighted' | 'valueReturn' | 'symbolPriceBased' | 'notApplicable';
732
+ export type PerformanceSummaryBasis = 'marketValue' | 'bookBasis' | 'mixed' | 'notApplicable';
733
+ export type PerformanceSummaryStatus = 'complete' | 'unavailable';
734
+ export interface PerformanceSummary {
735
+ amount?: number | null;
736
+ percent?: number | null;
737
+ method: ReturnMethod;
738
+ basis: PerformanceSummaryBasis;
739
+ quality: PerformanceDataQuality['status'];
740
+ amountStatus: PerformanceSummaryStatus;
741
+ percentStatus: PerformanceSummaryStatus;
742
+ basisStatus: BasisStatus;
743
+ reasons: string[];
744
+ }
745
+ export interface PerformanceReturns {
746
+ twr?: number | null;
684
747
  annualizedTwr?: number | null;
685
- simpleReturn: number;
686
- annualizedSimpleReturn: number;
687
- /** Money-weighted return (null for HOLDINGS mode - requires cash flow tracking) */
688
- cumulativeMwr?: number | null;
689
- /** Annualized MWR (null for HOLDINGS mode) */
690
- annualizedMwr?: number | null;
691
- volatility: number;
692
- maxDrawdown: number;
693
- /** Indicates if this is a HOLDINGS mode account (no cash flow tracking) */
694
- isHoldingsMode?: boolean;
748
+ /** Selected-period money-weighted return derived from annualized XIRR. */
749
+ irr?: number | null;
750
+ /** Annualized XIRR using dated cash flows. */
751
+ annualizedIrr?: number | null;
752
+ valueReturn?: number | null;
753
+ annualizedValueReturn?: number | null;
754
+ }
755
+ export interface PerformanceAttribution {
756
+ contributions: number;
757
+ distributions: number;
758
+ income: number;
759
+ realizedPnl: number;
760
+ unrealizedPnlChange: number;
761
+ fxEffect: number;
762
+ fees: number;
763
+ taxes: number;
764
+ residual: number;
765
+ }
766
+ export interface PerformanceRisk {
767
+ volatility?: number | null;
768
+ maxDrawdown?: number | null;
769
+ peakDate?: string | null;
770
+ troughDate?: string | null;
771
+ recoveryDate?: string | null;
772
+ drawdownDurationDays?: number | null;
773
+ }
774
+ export interface PerformanceDataQuality {
775
+ status: 'ok' | 'partial' | 'noData' | 'notApplicable';
776
+ warnings?: string[];
777
+ notApplicableReasons?: string[];
695
778
  }
696
779
  export interface UpdateAssetProfile {
697
780
  id: string;
@@ -766,6 +849,10 @@ export interface SnapshotHoldingInput {
766
849
  currency: string;
767
850
  averageCost?: string;
768
851
  exchangeMic?: string;
852
+ quoteCcy?: string;
853
+ instrumentType?: string;
854
+ providerId?: string;
855
+ providerSymbol?: string;
769
856
  name?: string;
770
857
  dataSource?: string;
771
858
  assetKind?: string;
@@ -776,6 +863,10 @@ export interface SnapshotPositionInput {
776
863
  avgCost?: string;
777
864
  currency: string;
778
865
  exchangeMic?: string;
866
+ quoteCcy?: string;
867
+ instrumentType?: string;
868
+ providerId?: string;
869
+ providerSymbol?: string;
779
870
  }
780
871
  export interface SnapshotInput {
781
872
  date: string;
@@ -3,7 +3,7 @@
3
3
  * Provides comprehensive access to Wealthfolio functionality organized by domain
4
4
  */
5
5
  import type { EventCallback, UnlistenFn } from './types';
6
- import type { Account, Activity, ActivityBulkMutationRequest, ActivityBulkMutationResult, ActivityCreate, ActivityDetails, ActivityImport, ActivitySearchResponse, ActivityUpdate, AccountValuation, CheckSnapshotImportResult, ImportActivitiesResult, Asset, ContributionLimit, DepositsCalculation, ExchangeRate, Goal, GoalAllocation, Holding, ImportMappingData, IncomeSummary, MarketDataProviderInfo, NewContributionLimit, PerformanceMetrics, Quote, Settings, SimplePerformanceMetrics, SnapshotHoldingInput, SnapshotImportResult, SnapshotInfo, SnapshotInput, SymbolSearchResult, UpdateAssetProfile } from './data-types';
6
+ import type { Account, Activity, ActivityBulkMutationRequest, ActivityBulkMutationResult, ActivityCreate, ActivityDetails, ActivityImport, ActivitySearchResponse, ActivityUpdate, AccountValuation, CheckSnapshotImportResult, ImportActivitiesResult, Asset, ContributionLimit, DepositsCalculation, ExchangeRate, Goal, GoalAllocation, Holding, ImportMappingData, IncomeSummary, MarketDataProviderInfo, NewContributionLimit, PerformanceResult, Quote, Settings, SimplePerformanceResult, SnapshotHoldingInput, SnapshotImportResult, SnapshotInfo, SnapshotInput, SymbolSearchResult, UpdateAssetProfile } from './data-types';
7
7
  export interface ActivitySearchFilters {
8
8
  accountIds?: string | string[];
9
9
  activityTypes?: string | string[];
@@ -141,12 +141,20 @@ export interface ActivitiesAPI {
141
141
  saveImportMapping(mapping: ImportMappingData): Promise<ImportMappingData>;
142
142
  }
143
143
  /**
144
- * A single dividend event returned by Yahoo Finance.
144
+ * A cash dividend event returned by a market data provider.
145
145
  */
146
- export interface YahooDividend {
146
+ export interface DividendEvent {
147
147
  amount: number;
148
148
  date: number;
149
149
  }
150
+ export interface FetchDividendsOptions {
151
+ exchangeMic?: string;
152
+ instrumentType?: string;
153
+ quoteCcy?: string;
154
+ providerId?: string;
155
+ startDate?: string;
156
+ endDate?: string;
157
+ }
150
158
  /**
151
159
  * Market data and asset APIs
152
160
  */
@@ -176,11 +184,11 @@ export interface MarketDataAPI {
176
184
  */
177
185
  getProviders(): Promise<MarketDataProviderInfo[]>;
178
186
  /**
179
- * Fetch dividend history for a symbol from Yahoo Finance.
187
+ * Fetch dividend history for a symbol.
180
188
  * @param symbol Ticker symbol
181
189
  * @returns Promise resolving to array of dividend events
182
190
  */
183
- fetchDividends(symbol: string): Promise<YahooDividend[]>;
191
+ fetchDividends(symbol: string, options?: FetchDividendsOptions): Promise<DividendEvent[]>;
184
192
  }
185
193
  /**
186
194
  * Asset management APIs
@@ -236,7 +244,7 @@ export interface PerformanceAPI {
236
244
  * @param endDate End date for calculation
237
245
  * @returns Promise resolving to performance metrics
238
246
  */
239
- calculateHistory(itemType: 'account' | 'symbol', itemId: string, startDate: string, endDate: string): Promise<PerformanceMetrics>;
247
+ calculateHistory(itemType: 'account' | 'symbol', itemId: string, startDate?: string, endDate?: string): Promise<PerformanceResult>;
240
248
  /**
241
249
  * Calculate performance summary
242
250
  * @param args Performance calculation arguments
@@ -247,13 +255,13 @@ export interface PerformanceAPI {
247
255
  itemId: string;
248
256
  startDate?: string | null;
249
257
  endDate?: string | null;
250
- }): Promise<PerformanceMetrics>;
258
+ }): Promise<PerformanceResult>;
251
259
  /**
252
260
  * Calculate simple performance for multiple accounts
253
261
  * @param accountIds Array of account identifiers
254
262
  * @returns Promise resolving to array of simple performance metrics
255
263
  */
256
- calculateAccountsSimple(accountIds: string[]): Promise<SimplePerformanceMetrics[]>;
264
+ calculateAccountsSimple(accountIds: string[]): Promise<SimplePerformanceResult[]>;
257
265
  }
258
266
  /**
259
267
  * Exchange rates APIs
@@ -375,7 +383,6 @@ export interface SettingsAPI {
375
383
  */
376
384
  backupDatabase(): Promise<{
377
385
  filename: string;
378
- data: Uint8Array;
379
386
  }>;
380
387
  }
381
388
  /**
@@ -578,6 +585,28 @@ export interface QueryAPI {
578
585
  */
579
586
  refetchQueries(queryKey: string | string[]): void;
580
587
  }
588
+ export interface NetworkRequest {
589
+ url: string;
590
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD';
591
+ headers?: Record<string, string>;
592
+ body?: string;
593
+ auth?: NetworkAuth;
594
+ }
595
+ export interface NetworkResponse {
596
+ status: number;
597
+ headers: Record<string, string>;
598
+ body: string;
599
+ }
600
+ export interface NetworkAuth {
601
+ type: 'bearer';
602
+ secretKey: string;
603
+ }
604
+ export interface NetworkAPI {
605
+ /**
606
+ * Send a brokered HTTPS request to a host declared in the addon manifest.
607
+ */
608
+ request(request: NetworkRequest): Promise<NetworkResponse>;
609
+ }
581
610
  /**
582
611
  * Snapshot management APIs
583
612
  * For accounts using HOLDINGS tracking mode
@@ -631,6 +660,8 @@ export interface HostAPI {
631
660
  navigation: NavigationAPI;
632
661
  /** React Query operations */
633
662
  query: QueryAPI;
663
+ /** Brokered external network operations */
664
+ network: NetworkAPI;
634
665
  /** Toast notification operations */
635
666
  toast: ToastAPI;
636
667
  }
@@ -0,0 +1,10 @@
1
+ export declare const HOST_DEPENDENCIES: {
2
+ readonly '@tanstack/react-query': "^5.90.0";
3
+ readonly '@wealthfolio/addon-sdk': "^3.6.0";
4
+ readonly '@wealthfolio/ui': "^3.6.0";
5
+ readonly 'date-fns': "^4.1.0";
6
+ readonly 'lucide-react': "^0.561.0";
7
+ readonly react: "^19.2.0";
8
+ readonly 'react-dom': "^19.2.0";
9
+ readonly recharts: "^3.7.0";
10
+ };
@@ -8,22 +8,32 @@
8
8
  * @author Wealthfolio Team
9
9
  * @license MIT
10
10
  */
11
- export type { AddonContext, AddonEnableFunction, EventCallback, RouteConfig, RouterManager, SidebarItemConfig, SidebarItemHandle, SidebarManager, UnlistenFn, } from './types';
12
- export type { ActivitySearchFilters, ActivitySort, HostAPI, SnapshotsAPI, ToastAPI, YahooDividend, } from './host-api';
11
+ export type { AddonContext, AddonEnableFunction, AddonRouteLocation, AddonRouteRenderContext, AddonRouteRenderer, EventCallback, RouteConfig, RouterManager, SidebarItemConfig, SidebarItemHandle, SidebarManager, UnlistenFn, } from './types';
12
+ export type { ActivitySearchFilters, ActivitySort, HostAPI, NetworkAuth, NetworkAPI, NetworkRequest, NetworkResponse, SnapshotsAPI, ToastAPI, DividendEvent, FetchDividendsOptions, } from './host-api';
13
13
  export type { QueryClient } from '@tanstack/react-query';
14
14
  export { QueryKeys } from './query-keys';
15
15
  export type * from './data-types';
16
- export type { AddonFile, AddonInstallResult, AddonManifest, AddonStoreListing, AddonUpdateCheckResult, AddonUpdateInfo, AddonValidationResult, DevelopmentManifest, ExtractedAddon, InstalledAddon, InstalledManifest, } from './manifest';
16
+ export type { AddonFile, AddonHostDependencies, AddonInstallResult, AddonManifest, AddonStoreListing, AddonUpdateCheckResult, AddonUpdateInfo, AddonValidationResult, DevelopmentManifest, ExtractedAddon, InstalledAddon, InstalledManifest, } from './manifest';
17
17
  export { isInstalledManifest } from './manifest';
18
18
  export type { FunctionPermission, Permission, PermissionCategory, RiskLevel, } from './permissions';
19
19
  export { getFunctionRiskLevel, getPermissionCategoriesByRisk, getPermissionCategory, isPermissionRequired, PERMISSION_CATEGORIES, } from './permissions';
20
20
  export { formatAddonSize, generateAddonId, isAddonManifest, isCompatibleVersion, validateManifest, } from './utils';
21
21
  export { calculateGoalProgress } from './goal-progress';
22
22
  /**
23
- * React version guaranteed by the host application. Addons may assert against
24
- * this at runtime if they rely on a particular React feature set.
23
+ * React version provided by the Wealthfolio add-on sandbox for host-externalized
24
+ * add-ons.
25
+ */
26
+ export declare const ReactVersion = "19.2.4";
27
+ export { HOST_DEPENDENCIES } from './host-dependencies';
28
+ /**
29
+ * Addons receive their context as a parameter to the enable() function.
30
+ * Each addon gets its own isolated iframe context with scoped host APIs.
31
+ *
32
+ * Example:
33
+ * export default function enable(ctx: AddonContext) {
34
+ * // Use ctx.api.secrets.set/get/delete for secure storage
35
+ * // Use ctx.sidebar.addItem() to add navigation
36
+ * // Use ctx.router.add() with a render callback to register routes
37
+ * }
25
38
  */
26
- export declare const ReactVersion = "19.1.1";
27
- export declare const React: typeof import("react");
28
- export declare const ReactDOM: typeof import("react-dom");
29
39
  export { SDK_VERSION } from './version';
@@ -2,6 +2,11 @@
2
2
  * Addon manifest and metadata types
3
3
  */
4
4
  import type { Permission } from './permissions';
5
+ export interface AddonNetworkAccess {
6
+ allowedHosts: string[];
7
+ approvedHosts?: string[];
8
+ }
9
+ export type AddonHostDependencies = Record<string, string>;
5
10
  /**
6
11
  * Unified addon manifest structure that handles both development and runtime scenarios
7
12
  * This represents both what developers write in their manifest.json and installed addon metadata
@@ -37,6 +42,10 @@ export interface AddonManifest {
37
42
  keywords?: string[];
38
43
  /** Addon icon (base64 or relative path) */
39
44
  icon?: string;
45
+ /** Network hosts this addon may reach through the host broker */
46
+ network?: AddonNetworkAccess;
47
+ /** Host-provided packages this addon imports instead of bundling */
48
+ hostDependencies?: AddonHostDependencies;
40
49
  /** Installation timestamp in ISO format */
41
50
  installedAt?: string;
42
51
  /** Last update timestamp */
@@ -125,6 +134,8 @@ export interface AddonUpdateInfo {
125
134
  updateAvailable: boolean;
126
135
  /** Download URL for the update */
127
136
  downloadUrl?: string;
137
+ /** Optional SHA-256 digest for the update package bytes */
138
+ sha256?: string;
128
139
  /** Release notes for the latest version */
129
140
  releaseNotes?: string;
130
141
  /** Release date of the latest version */
@@ -157,6 +168,8 @@ export interface AddonStoreListing {
157
168
  metadata: AddonManifest;
158
169
  /** Download URL */
159
170
  downloadUrl: string;
171
+ /** Optional SHA-256 digest for the package bytes */
172
+ sha256?: string;
160
173
  /** Number of downloads */
161
174
  downloads?: number;
162
175
  /** Average rating */
@@ -1,4 +1,3 @@
1
- import React from 'react';
2
1
  import type { HostAPI } from './host-api';
3
2
  /**
4
3
  * Core types for addon development
@@ -18,23 +17,45 @@ export interface SidebarItemConfig {
18
17
  id: string;
19
18
  /** Display text for the sidebar item */
20
19
  label: string;
21
- /** Optional icon name or React component */
22
- icon?: string | React.ReactNode;
20
+ /** Optional host-supported icon name */
21
+ icon?: string;
23
22
  /** Optional route to navigate to when clicked */
24
23
  route?: string;
25
24
  /** Optional ordering priority (lower numbers appear first) */
26
25
  order?: number;
27
- /** Optional click handler (if no route provided) */
28
- onClick?: () => void;
29
26
  }
27
+ /**
28
+ * Route location supplied by the host when an addon route is rendered.
29
+ */
30
+ export interface AddonRouteLocation {
31
+ pathname: string;
32
+ search: string;
33
+ hash: string;
34
+ params: Record<string, string | undefined>;
35
+ }
36
+ /**
37
+ * Context supplied to addon route render functions.
38
+ */
39
+ export interface AddonRouteRenderContext {
40
+ root: HTMLElement;
41
+ location: AddonRouteLocation;
42
+ }
43
+ /**
44
+ * Render callback for iframe-hosted addon routes.
45
+ */
46
+ export type AddonRouteRenderer = (context: AddonRouteRenderContext) => void | Promise<void>;
30
47
  /**
31
48
  * Configuration for adding a route
32
49
  */
33
50
  export interface RouteConfig {
51
+ /** Optional stable route identifier */
52
+ id?: string;
34
53
  /** Route path pattern */
35
54
  path: string;
36
- /** Lazy-loaded React component */
37
- component: React.LazyExoticComponent<React.ComponentType<unknown>>;
55
+ /** Optional label for diagnostics */
56
+ title?: string;
57
+ /** Render inside the addon's sandboxed iframe */
58
+ render: AddonRouteRenderer;
38
59
  }
39
60
  /**
40
61
  * Sidebar management interface
@@ -71,6 +92,11 @@ export type UnlistenFn = () => void;
71
92
  * Main addon context interface providing access to Wealthfolio APIs
72
93
  */
73
94
  export interface AddonContext {
95
+ /** UI primitives owned by the addon's sandboxed iframe */
96
+ ui: {
97
+ /** Root element for addon-rendered content */
98
+ root: HTMLElement;
99
+ };
74
100
  /** Sidebar management */
75
101
  sidebar: SidebarManager;
76
102
  /** Router management */