@venlyfinance/react 0.3.0 → 0.4.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.
package/CHANGELOG.md CHANGED
@@ -14,3 +14,37 @@ Initial release.
14
14
  ## 0.1.1
15
15
 
16
16
  - Fix: `useStagedTransfer` stuck in "submitting" under React StrictMode – the hook cleanup's `dispose()` left the controller permanently dead for the remount, so `confirm()`'s continuation dropped its state updates. A new subscription now revives the controller. Found by driving the flow in a real browser; regression test added.
17
+
18
+ ## 0.2.0 – 2026-08-07
19
+
20
+ *(Entry backfilled 2026-08-15 – this release shipped without a changelog note.)*
21
+
22
+ - Read hooks for the fundflow company surface: `useCompanyBankAccounts`,
23
+ `useCompanyBankAccount`, `useCompanyWallets`, `useBankAccountConfig`,
24
+ `useDepositWallets`, `useRampPairs`, `useCompanyFees`.
25
+ - Write hooks with cache invalidation: `useCreateCompanyBankAccount`,
26
+ `useCreateCompanyWallet`, `useSetRampAmount`, `useInitiateRamp`.
27
+ - Matching `venlyKeys` / `venlyQueries` factories for every new read.
28
+
29
+ ## 0.3.0 – 2026-08-14
30
+
31
+ *(Entry backfilled 2026-08-15 – this release shipped without a changelog note.)*
32
+
33
+ - **BREAKING (inherited from `@venlyfinance/sdk` 0.4.0 / contract 1.3.0):**
34
+ the `Wallet` type no longer exists – `wallets.list` returns per-asset
35
+ `WalletBalance` rows and this package re-exports `WalletBalance` instead.
36
+ Monetary amounts are JSON numbers.
37
+ - Re-exports the payout types (`Payout`, `PayoutRoute`, `PayoutBankAccount`)
38
+ shipped by sdk 0.4.0.
39
+ - Requires `@venlyfinance/sdk` ^0.4.0.
40
+
41
+ ## 0.4.0 – 2026-08-15
42
+
43
+ - New read hooks: `useSupportedAssets()` (tenant-wide assets, each with its
44
+ on-chain `decimals` – the render contract for amounts; cached hard) and
45
+ `useAccountSupportedAssets(accountId)` (adds per-asset `permitStatus`,
46
+ not frozen because status moves while an asset activates).
47
+ - `venlyKeys.supportedAssets()` / `venlyKeys.accountSupportedAssets(id)` and
48
+ matching `venlyQueries` factories; the account-scoped key shares the
49
+ `["venly", "account", id]` prefix so account invalidations reach it.
50
+ - Requires `@venlyfinance/sdk` ^0.5.0 (the `supportedAssets` resource).
package/README.md CHANGED
@@ -6,6 +6,8 @@ Headless React layer for the [Venly Finance and Fundflow APIs](https://github.co
6
6
 
7
7
  No components, no CSS. This package owns data and state; your UI (or the one your coding agent assembles) owns the pixels. The full behaviour is covered by a node:test suite that runs with zero network.
8
8
 
9
+ Building with a coding agent? Start from [AGENTS.md](AGENTS.md).
10
+
9
11
  ## Try it in 0 minutes (mock mode)
10
12
 
11
13
  ```bash
@@ -36,7 +38,7 @@ Mock mode needs zero credentials and makes zero network calls: every hook answer
36
38
  | Export | What it does |
37
39
  |---|---|
38
40
  | `<VenlyProvider>` | Constructs the Finance + Fundflow clients for `mock`, `staging`, or `production`; brings its own QueryClient if the app has none |
39
- | `useParties` `useAccounts` `useWallets` `useVirtualBankAccounts` `useTransfers` `useRampRequests` `useReferenceData` `useFeeQuote` … | Read hooks, one per API resource, cache keys managed for you |
41
+ | `useParties` `useAccounts` `useWallets` `useSupportedAssets` `useAccountSupportedAssets` `useVirtualBankAccounts` `useTransfers` `useRampRequests` `useReferenceData` `useFeeQuote` … | Read hooks, one per API resource, cache keys managed for you |
40
42
  | `useCreateParty` `useCreateAccount` `useCreateVirtualBankAccount` `useCreatePaymentSession` `useCreateRampRequest` | Write hooks with cache invalidation wired |
41
43
  | `useStagedTransfer` | Stage-then-confirm machine: validate → freeze the exact request with a pinned idempotency key → execute once → poll to terminal |
42
44
  | `useFourEyesApproval` | Approve/reject/cancel with the optimistic-locking `version` carried through; 409 surfaces as `"stale-version"` (refetch and re-decide, never auto-retry) |
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  export { VenlyProvider, useVenly, useVenlyMock, type VenlyClients, type VenlyProviderProps, type VenlyReactEnvironment, } from "./provider.js";
2
2
  export { venlyKeys } from "./keys.js";
3
3
  export { venlyQueries, type AccountsQuery, type FeeQuoteInput, type PartiesQuery, type RampRequestsQuery, type TransfersQuery, type VirtualBankAccountsQuery, type WalletsQuery, } from "./query-options.js";
4
- export { useAccount, useAccounts, useCompanyFees, useFeeQuote, useParties, useParty, useRampRequest, useRampRequests, useReferenceData, useTransfer, useTransfers, useVirtualBankAccounts, useWallets, useCompanyBankAccount, useCompanyBankAccounts, useCompanyWallets, useBankAccountConfig, useDepositWallets, useRampPairs, } from "./queries.js";
4
+ export { useAccount, useAccounts, useCompanyFees, useFeeQuote, useParties, useParty, useRampRequest, useRampRequests, useReferenceData, useTransfer, useTransfers, useVirtualBankAccounts, useWallets, useCompanyBankAccount, useCompanyBankAccounts, useCompanyWallets, useBankAccountConfig, useDepositWallets, useRampPairs, useSupportedAssets, useAccountSupportedAssets, } from "./queries.js";
5
5
  export { useCreateAccount, useCreateParty, useCreatePaymentSession, useCreateRampRequest, useCreateVirtualBankAccount, useCreateCompanyBankAccount, useCreateCompanyWallet, useSetRampAmount, useInitiateRamp, } from "./mutations.js";
6
6
  export { StagedTransferController, useStagedTransfer, validateDraft, type StagedRequest, type StagedTransferOptions, type StagedTransferState, type TransferDraft, } from "./flows/staged-transfer.js";
7
7
  export { approvalCapabilities, interpretApprovalError, useFourEyesApproval, type ApprovalCapability, type ApprovalFailureKind, type FourEyesState, } from "./flows/four-eyes.js";
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ export { VenlyProvider, useVenly, useVenlyMock, } from "./provider.js";
4
4
  export { venlyKeys } from "./keys.js";
5
5
  export { venlyQueries, } from "./query-options.js";
6
6
  // Read hooks
7
- export { useAccount, useAccounts, useCompanyFees, useFeeQuote, useParties, useParty, useRampRequest, useRampRequests, useReferenceData, useTransfer, useTransfers, useVirtualBankAccounts, useWallets, useCompanyBankAccount, useCompanyBankAccounts, useCompanyWallets, useBankAccountConfig, useDepositWallets, useRampPairs, } from "./queries.js";
7
+ export { useAccount, useAccounts, useCompanyFees, useFeeQuote, useParties, useParty, useRampRequest, useRampRequests, useReferenceData, useTransfer, useTransfers, useVirtualBankAccounts, useWallets, useCompanyBankAccount, useCompanyBankAccounts, useCompanyWallets, useBankAccountConfig, useDepositWallets, useRampPairs, useSupportedAssets, useAccountSupportedAssets, } from "./queries.js";
8
8
  // Write hooks
9
9
  export { useCreateAccount, useCreateParty, useCreatePaymentSession, useCreateRampRequest, useCreateVirtualBankAccount, useCreateCompanyBankAccount, useCreateCompanyWallet, useSetRampAmount, useInitiateRamp, } from "./mutations.js";
10
10
  // Flow machines: the regulated-money lifecycles
package/dist/keys.d.ts CHANGED
@@ -9,6 +9,8 @@ export declare const venlyKeys: {
9
9
  readonly accounts: (query?: unknown) => readonly ["venly", "accounts", {} | null];
10
10
  readonly account: (accountId: string) => readonly ["venly", "account", string];
11
11
  readonly wallets: (accountId: string, query?: unknown) => readonly ["venly", "account", string, "wallets", {} | null];
12
+ readonly supportedAssets: () => readonly ["venly", "supported-assets"];
13
+ readonly accountSupportedAssets: (accountId: string) => readonly ["venly", "account", string, "supported-assets"];
12
14
  readonly virtualBankAccounts: (accountId: string, query?: unknown) => readonly ["venly", "account", string, "virtual-bank-accounts", {} | null];
13
15
  readonly transfers: (accountId: string, query?: unknown) => readonly ["venly", "account", string, "transfers", {} | null];
14
16
  readonly transfer: (accountId: string, transferId: string) => readonly ["venly", "account", string, "transfer", string];
package/dist/keys.js CHANGED
@@ -9,6 +9,8 @@ export const venlyKeys = {
9
9
  accounts: (query) => ["venly", "accounts", query ?? null],
10
10
  account: (accountId) => ["venly", "account", accountId],
11
11
  wallets: (accountId, query) => ["venly", "account", accountId, "wallets", query ?? null],
12
+ supportedAssets: () => ["venly", "supported-assets"],
13
+ accountSupportedAssets: (accountId) => ["venly", "account", accountId, "supported-assets"],
12
14
  virtualBankAccounts: (accountId, query) => ["venly", "account", accountId, "virtual-bank-accounts", query ?? null],
13
15
  transfers: (accountId, query) => ["venly", "account", accountId, "transfers", query ?? null],
14
16
  transfer: (accountId, transferId) => ["venly", "account", accountId, "transfer", transferId],
package/dist/queries.d.ts CHANGED
@@ -61,6 +61,29 @@ export declare function useWallets(accountId: string | undefined, query?: Wallet
61
61
  amount?: import("@venlyfinance/sdk").FinanceComponents["schemas"]["CryptoBalanceSummaryDto"];
62
62
  }>>, Error>;
63
63
  type WalletsPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.wallets>["queryFn"]>>;
64
+ /**
65
+ * Tenant-wide supported assets. `decimals` per asset is the render contract
66
+ * for amounts; cached hard (the asset set changes on deploys, not minutes).
67
+ */
68
+ export declare function useSupportedAssets(options?: Tune<SupportedAssetsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<import("@venlyfinance/sdk").Page<{
69
+ chain?: "AVALANCHE" | "BASE" | "ETHEREUM" | "POLYGON" | "SOLANA";
70
+ cryptoCurrency?: string;
71
+ decimals?: number;
72
+ contractAddress?: string;
73
+ }>>, Error>;
74
+ type SupportedAssetsPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.supportedAssets>["queryFn"]>>;
75
+ /**
76
+ * Account-scoped supported assets (adds `permitStatus`). Not frozen:
77
+ * permit status moves while an asset activates.
78
+ */
79
+ export declare function useAccountSupportedAssets(accountId: string | undefined, options?: Tune<AccountSupportedAssetsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<import("@venlyfinance/sdk").Page<{
80
+ chain?: "AVALANCHE" | "BASE" | "ETHEREUM" | "POLYGON" | "SOLANA";
81
+ cryptoCurrency?: string;
82
+ decimals?: number;
83
+ contractAddress?: string;
84
+ permitStatus?: "READY" | "ACTIVATING" | "ACTION_REQUIRED" | "PENDING" | "FAILED" | "NO_WALLET";
85
+ }>>, Error>;
86
+ type AccountSupportedAssetsPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.accountSupportedAssets>["queryFn"]>>;
64
87
  export declare function useVirtualBankAccounts(accountId: string | undefined, query?: VirtualBankAccountsQuery, options?: Tune<VibaPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<import("@venlyfinance/sdk").Page<{
65
88
  id?: string;
66
89
  accountId?: string;
package/dist/queries.js CHANGED
@@ -33,6 +33,30 @@ export function useWallets(accountId, query, options) {
33
33
  ...options,
34
34
  });
35
35
  }
36
+ /**
37
+ * Tenant-wide supported assets. `decimals` per asset is the render contract
38
+ * for amounts; cached hard (the asset set changes on deploys, not minutes).
39
+ */
40
+ export function useSupportedAssets(options) {
41
+ const clients = useVenly();
42
+ return useQuery({
43
+ ...venlyQueries.supportedAssets(clients),
44
+ staleTime: Infinity,
45
+ ...options,
46
+ });
47
+ }
48
+ /**
49
+ * Account-scoped supported assets (adds `permitStatus`). Not frozen:
50
+ * permit status moves while an asset activates.
51
+ */
52
+ export function useAccountSupportedAssets(accountId, options) {
53
+ const clients = useVenly();
54
+ return useQuery({
55
+ ...venlyQueries.accountSupportedAssets(clients, accountId ?? ""),
56
+ enabled: Boolean(accountId) && (options?.enabled ?? true),
57
+ ...options,
58
+ });
59
+ }
36
60
  export function useVirtualBankAccounts(accountId, query, options) {
37
61
  const clients = useVenly();
38
62
  return useQuery({
@@ -86,6 +86,27 @@ export declare const venlyQueries: {
86
86
  amount?: import("@venlyfinance/sdk").FinanceComponents["schemas"]["CryptoBalanceSummaryDto"];
87
87
  }>>;
88
88
  };
89
+ /** Tenant-wide supported assets, each with its on-chain `decimals`. */
90
+ readonly supportedAssets: (clients: VenlyClients) => {
91
+ queryKey: readonly ["venly", "supported-assets"];
92
+ queryFn: () => Promise<import("@venlyfinance/sdk").Page<{
93
+ chain?: "AVALANCHE" | "BASE" | "ETHEREUM" | "POLYGON" | "SOLANA";
94
+ cryptoCurrency?: string;
95
+ decimals?: number;
96
+ contractAddress?: string;
97
+ }>>;
98
+ };
99
+ /** Account-scoped rows: the same assets plus per-asset `permitStatus`. */
100
+ readonly accountSupportedAssets: (clients: VenlyClients, accountId: string) => {
101
+ queryKey: readonly ["venly", "account", string, "supported-assets"];
102
+ queryFn: () => Promise<import("@venlyfinance/sdk").Page<{
103
+ chain?: "AVALANCHE" | "BASE" | "ETHEREUM" | "POLYGON" | "SOLANA";
104
+ cryptoCurrency?: string;
105
+ decimals?: number;
106
+ contractAddress?: string;
107
+ permitStatus?: "READY" | "ACTIVATING" | "ACTION_REQUIRED" | "PENDING" | "FAILED" | "NO_WALLET";
108
+ }>>;
109
+ };
89
110
  readonly virtualBankAccounts: (clients: VenlyClients, accountId: string, query?: VirtualBankAccountsQuery) => {
90
111
  queryKey: readonly ["venly", "account", string, "virtual-bank-accounts", {} | null];
91
112
  queryFn: () => Promise<import("@venlyfinance/sdk").Page<{
@@ -25,6 +25,16 @@ export const venlyQueries = {
25
25
  queryKey: venlyKeys.wallets(accountId, query),
26
26
  queryFn: () => clients.finance.wallets.list(accountId, query),
27
27
  }),
28
+ /** Tenant-wide supported assets, each with its on-chain `decimals`. */
29
+ supportedAssets: (clients) => ({
30
+ queryKey: venlyKeys.supportedAssets(),
31
+ queryFn: () => clients.finance.supportedAssets.list(),
32
+ }),
33
+ /** Account-scoped rows: the same assets plus per-asset `permitStatus`. */
34
+ accountSupportedAssets: (clients, accountId) => ({
35
+ queryKey: venlyKeys.accountSupportedAssets(accountId),
36
+ queryFn: () => clients.finance.supportedAssets.listForAccount(accountId),
37
+ }),
28
38
  virtualBankAccounts: (clients, accountId, query) => ({
29
39
  queryKey: venlyKeys.virtualBankAccounts(accountId, query),
30
40
  queryFn: () => clients.finance.virtualBankAccounts.list(accountId, query),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venlyfinance/react",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Headless React layer for the Venly Finance and Fundflow APIs: provider, TanStack Query hooks, and flow state machines for regulated money movement. Runs with zero credentials in mock mode.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -30,7 +30,7 @@
30
30
  "node": ">=20"
31
31
  },
32
32
  "dependencies": {
33
- "@venlyfinance/sdk": "^0.4.0"
33
+ "@venlyfinance/sdk": "^0.5.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@tanstack/react-query": "^5.0.0",
@@ -62,4 +62,4 @@
62
62
  "directory": "react"
63
63
  },
64
64
  "homepage": "https://github.com/Venly/venly-settlement-sdk/tree/main/react#readme"
65
- }
65
+ }