@venlyfinance/react 0.3.0 → 0.5.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/AGENTS.md +2 -1
- package/CHANGELOG.md +34 -0
- package/README.md +3 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/keys.d.ts +6 -0
- package/dist/keys.js +3 -0
- package/dist/queries.d.ts +53 -8
- package/dist/queries.js +54 -0
- package/dist/query-options.d.ts +21 -0
- package/dist/query-options.js +10 -0
- package/package.json +3 -3
package/AGENTS.md
CHANGED
|
@@ -9,6 +9,7 @@ You are building a financial product UI on `@venlyfinance/react`. These rules ex
|
|
|
9
9
|
3. **Never place `clientSecret` in browser code.** The provider throws if you try. For browser apps use `proxyClientOptions()` against your own backend route.
|
|
10
10
|
4. **Money movement is stage-then-confirm.** Render a review step showing `state.staged` (the exact request) before calling `confirm()`. Never wire a form submit directly to execution.
|
|
11
11
|
5. **Approval UIs render the rule, not the error.** Use `capability` from `useFourEyesApproval`: when `reason` is `"actor-is-creator"`, say that a second person must approve – do not show buttons that will be refused. On failure `"stale-version"`, refetch and let the operator re-decide; never auto-retry an approval.
|
|
12
|
+
6. **Gate both the screen and its runtime contract, and wire both into CI.** Run `npx @venlyfinance/settlement-mcp review "src/**/*.tsx"` for the design contract and `npx @venlyfinance/settlement-mcp verify "src/**/*.{ts,tsx}"` for package/provider/hook/proxy composition. Each fails (exit 1) on any error-severity finding. A deliberate, justified exception carries `venly-allow:<rule-id>` on the offending line or the line above.
|
|
12
13
|
|
|
13
14
|
## Rendering money states
|
|
14
15
|
|
|
@@ -31,4 +32,4 @@ The UI kit's auth and team blocks therefore render against two adapter interface
|
|
|
31
32
|
## Demo choreography (mock mode)
|
|
32
33
|
|
|
33
34
|
`useVenlyMock()` exposes the store controls. A credible end-to-end demo:
|
|
34
|
-
create party → `advanceVerification(id)` → create account → virtual bank account (note its `referenceCode`) → stage + confirm a transfer → `advanceTransfer(id)` → show the ledger. Inject failures with `failNext("CONFLICT")` to show the stale-version approval path – error states are part of the product.
|
|
35
|
+
create party → `advanceVerification(id)` → create account → virtual bank account (note its `referenceCode`) → **fund it: `simulations.inbound.credit(vbaId, 500)`** (a new account holds nothing, as in production; an unfunded transfer is refused with `402 insufficient-funds`) → stage + confirm a transfer → `advanceTransfer(id)` → show the ledger, and `simulations.ledger.verify()` to prove it balances. Inject failures with `failNext("CONFLICT")` to show the stale-version approval path – error states are part of the product.
|
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, useTransfersForPeriod, collectTransfersForPeriod, type TransferPeriod, type TransfersForPeriodPage, 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, useTransfersForPeriod, collectTransfersForPeriod, 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,8 +9,14 @@ 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];
|
|
16
|
+
readonly transfersForPeriod: (accountId: string, period: {
|
|
17
|
+
start: string;
|
|
18
|
+
end: string;
|
|
19
|
+
}) => readonly ["venly", "account", string, "transfers-for-period", string, string];
|
|
14
20
|
readonly transfer: (accountId: string, transferId: string) => readonly ["venly", "account", string, "transfer", string];
|
|
15
21
|
readonly rampRequests: (query?: unknown) => readonly ["venly", "ramp-requests", {} | null];
|
|
16
22
|
readonly rampRequest: (id: string) => readonly ["venly", "ramp-request", string];
|
package/dist/keys.js
CHANGED
|
@@ -9,8 +9,11 @@ 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],
|
|
16
|
+
transfersForPeriod: (accountId, period) => ["venly", "account", accountId, "transfers-for-period", period.start, period.end],
|
|
14
17
|
transfer: (accountId, transferId) => ["venly", "account", accountId, "transfer", transferId],
|
|
15
18
|
rampRequests: (query) => ["venly", "ramp-requests", query ?? null],
|
|
16
19
|
rampRequest: (id) => ["venly", "ramp-request", id],
|
package/dist/queries.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { type UseQueryOptions } from "@tanstack/react-query";
|
|
2
|
+
import { type Page, type Transfer as TransferRow } from "@venlyfinance/sdk";
|
|
2
3
|
import { venlyQueries, type AccountsQuery, type FeeQuoteInput, type PartiesQuery, type RampRequestsQuery, type TransfersQuery, type VirtualBankAccountsQuery, type WalletsQuery, type CompanyBankAccountsQuery, type CompanyWalletsQuery, type DepositWalletsQuery } from "./query-options.js";
|
|
3
4
|
type Tune<T> = Omit<UseQueryOptions<T, Error>, "queryKey" | "queryFn">;
|
|
4
|
-
export declare function useParties(query?: PartiesQuery, options?: Tune<PartiesPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<
|
|
5
|
+
export declare function useParties(query?: PartiesQuery, options?: Tune<PartiesPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
5
6
|
id?: string;
|
|
6
7
|
externalId?: string;
|
|
7
8
|
partyType?: "INDIVIDUAL" | "ORGANISATION";
|
|
@@ -35,7 +36,7 @@ export declare function useParty(partyId: string | undefined, options?: Tune<Par
|
|
|
35
36
|
version?: number;
|
|
36
37
|
}>, Error>;
|
|
37
38
|
type Party = Awaited<ReturnType<ReturnType<typeof venlyQueries.party>["queryFn"]>>;
|
|
38
|
-
export declare function useAccounts(query?: AccountsQuery, options?: Tune<AccountsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<
|
|
39
|
+
export declare function useAccounts(query?: AccountsQuery, options?: Tune<AccountsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
39
40
|
id?: string;
|
|
40
41
|
externalId?: string;
|
|
41
42
|
name?: string;
|
|
@@ -55,13 +56,36 @@ export declare function useAccount(accountId: string | undefined, options?: Tune
|
|
|
55
56
|
version?: number;
|
|
56
57
|
}>, Error>;
|
|
57
58
|
type Account = Awaited<ReturnType<ReturnType<typeof venlyQueries.account>["queryFn"]>>;
|
|
58
|
-
export declare function useWallets(accountId: string | undefined, query?: WalletsQuery, options?: Tune<WalletsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<
|
|
59
|
+
export declare function useWallets(accountId: string | undefined, query?: WalletsQuery, options?: Tune<WalletsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
59
60
|
asset?: string;
|
|
60
61
|
contractAddress?: string;
|
|
61
62
|
amount?: import("@venlyfinance/sdk").FinanceComponents["schemas"]["CryptoBalanceSummaryDto"];
|
|
62
63
|
}>>, Error>;
|
|
63
64
|
type WalletsPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.wallets>["queryFn"]>>;
|
|
64
|
-
|
|
65
|
+
/**
|
|
66
|
+
* Tenant-wide supported assets. `decimals` per asset is the render contract
|
|
67
|
+
* for amounts; cached hard (the asset set changes on deploys, not minutes).
|
|
68
|
+
*/
|
|
69
|
+
export declare function useSupportedAssets(options?: Tune<SupportedAssetsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
70
|
+
chain?: "AVALANCHE" | "BASE" | "ETHEREUM" | "POLYGON" | "SOLANA";
|
|
71
|
+
cryptoCurrency?: string;
|
|
72
|
+
decimals?: number;
|
|
73
|
+
contractAddress?: string;
|
|
74
|
+
}>>, Error>;
|
|
75
|
+
type SupportedAssetsPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.supportedAssets>["queryFn"]>>;
|
|
76
|
+
/**
|
|
77
|
+
* Account-scoped supported assets (adds `permitStatus`). Not frozen:
|
|
78
|
+
* permit status moves while an asset activates.
|
|
79
|
+
*/
|
|
80
|
+
export declare function useAccountSupportedAssets(accountId: string | undefined, options?: Tune<AccountSupportedAssetsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
81
|
+
chain?: "AVALANCHE" | "BASE" | "ETHEREUM" | "POLYGON" | "SOLANA";
|
|
82
|
+
cryptoCurrency?: string;
|
|
83
|
+
decimals?: number;
|
|
84
|
+
contractAddress?: string;
|
|
85
|
+
permitStatus?: "READY" | "ACTIVATING" | "ACTION_REQUIRED" | "PENDING" | "FAILED" | "NO_WALLET";
|
|
86
|
+
}>>, Error>;
|
|
87
|
+
type AccountSupportedAssetsPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.accountSupportedAssets>["queryFn"]>>;
|
|
88
|
+
export declare function useVirtualBankAccounts(accountId: string | undefined, query?: VirtualBankAccountsQuery, options?: Tune<VibaPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
65
89
|
id?: string;
|
|
66
90
|
accountId?: string;
|
|
67
91
|
bankAccountType?: "EUR_SEPA" | "USD_ACH";
|
|
@@ -81,7 +105,7 @@ export declare function useVirtualBankAccounts(accountId: string | undefined, qu
|
|
|
81
105
|
updatedAt?: string;
|
|
82
106
|
}>>, Error>;
|
|
83
107
|
type VibaPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.virtualBankAccounts>["queryFn"]>>;
|
|
84
|
-
export declare function useTransfers(accountId: string | undefined, query?: TransfersQuery, options?: Tune<TransfersPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<
|
|
108
|
+
export declare function useTransfers(accountId: string | undefined, query?: TransfersQuery, options?: Tune<TransfersPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
85
109
|
id?: string;
|
|
86
110
|
senderAccountId?: string;
|
|
87
111
|
receiverAccountId?: string;
|
|
@@ -99,6 +123,27 @@ export declare function useTransfers(accountId: string | undefined, query?: Tran
|
|
|
99
123
|
updatedAt?: string;
|
|
100
124
|
}>>, Error>;
|
|
101
125
|
type TransfersPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.transfers>["queryFn"]>>;
|
|
126
|
+
export type TransferPeriod = {
|
|
127
|
+
start: string;
|
|
128
|
+
end: string;
|
|
129
|
+
};
|
|
130
|
+
export type TransfersForPeriodPage = {
|
|
131
|
+
/** Rows whose `createdAt` falls in `[start, end]`. */
|
|
132
|
+
items: TransferRow[];
|
|
133
|
+
/**
|
|
134
|
+
* Every transfer on the account after paging to completion. Opening and
|
|
135
|
+
* closing walk from the current wallet total through this full ledger;
|
|
136
|
+
* a window-only set would silently drop later movements.
|
|
137
|
+
*/
|
|
138
|
+
ledger: TransferRow[];
|
|
139
|
+
resultPresent: boolean;
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* Page every transfer on the account (the list contract has no date filter),
|
|
143
|
+
* then keep the window. `iteratePages` walks `hasNextPage`.
|
|
144
|
+
*/
|
|
145
|
+
export declare function collectTransfersForPeriod(list: (query?: TransfersQuery) => Promise<Page<Transfer>>, period: TransferPeriod, pageSize?: number): Promise<TransfersForPeriodPage>;
|
|
146
|
+
export declare function useTransfersForPeriod(accountId: string | undefined, period: TransferPeriod | undefined, options?: Tune<TransfersForPeriodPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<TransfersForPeriodPage>, Error>;
|
|
102
147
|
export declare function useTransfer(accountId: string | undefined, transferId: string | undefined, options?: Tune<Transfer>): import("@tanstack/react-query").UseQueryResult<NoInfer<{
|
|
103
148
|
id?: string;
|
|
104
149
|
senderAccountId?: string;
|
|
@@ -117,7 +162,7 @@ export declare function useTransfer(accountId: string | undefined, transferId: s
|
|
|
117
162
|
updatedAt?: string;
|
|
118
163
|
}>, Error>;
|
|
119
164
|
type Transfer = Awaited<ReturnType<ReturnType<typeof venlyQueries.transfer>["queryFn"]>>;
|
|
120
|
-
export declare function useRampRequests(query?: RampRequestsQuery, options?: Tune<RampPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<
|
|
165
|
+
export declare function useRampRequests(query?: RampRequestsQuery, options?: Tune<RampPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
121
166
|
id?: string;
|
|
122
167
|
paymentReference?: string;
|
|
123
168
|
rampType?: "ON_RAMP" | "OFF_RAMP";
|
|
@@ -197,7 +242,7 @@ export declare function useFeeQuote(input: FeeQuoteInput | undefined, options?:
|
|
|
197
242
|
percentage?: number;
|
|
198
243
|
}>, Error>;
|
|
199
244
|
type FeeQuote = Awaited<ReturnType<ReturnType<typeof venlyQueries.feeQuote>["queryFn"]>>;
|
|
200
|
-
export declare function useCompanyBankAccounts(query?: CompanyBankAccountsQuery, options?: Tune<BankAccountsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<
|
|
245
|
+
export declare function useCompanyBankAccounts(query?: CompanyBankAccountsQuery, options?: Tune<BankAccountsPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
201
246
|
id?: string;
|
|
202
247
|
name?: string;
|
|
203
248
|
bankName?: string;
|
|
@@ -245,7 +290,7 @@ export declare function useCompanyBankAccount(id: string | undefined, options?:
|
|
|
245
290
|
currency?: string;
|
|
246
291
|
}>, Error>;
|
|
247
292
|
type BankAccountDetail = Awaited<ReturnType<ReturnType<typeof venlyQueries.companyBankAccount>["queryFn"]>>;
|
|
248
|
-
export declare function useCompanyWallets(query?: CompanyWalletsQuery, options?: Tune<WalletsListPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<
|
|
293
|
+
export declare function useCompanyWallets(query?: CompanyWalletsQuery, options?: Tune<WalletsListPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<Page<{
|
|
249
294
|
id?: string;
|
|
250
295
|
description?: string;
|
|
251
296
|
address?: string;
|
package/dist/queries.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { useQuery } from "@tanstack/react-query";
|
|
2
|
+
import { iteratePages } from "@venlyfinance/sdk";
|
|
2
3
|
import { useVenly } from "./provider.js";
|
|
3
4
|
import { venlyQueries, } from "./query-options.js";
|
|
5
|
+
import { venlyKeys } from "./keys.js";
|
|
4
6
|
export function useParties(query, options) {
|
|
5
7
|
const clients = useVenly();
|
|
6
8
|
return useQuery({ ...venlyQueries.parties(clients, query), ...options });
|
|
@@ -33,6 +35,30 @@ export function useWallets(accountId, query, options) {
|
|
|
33
35
|
...options,
|
|
34
36
|
});
|
|
35
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Tenant-wide supported assets. `decimals` per asset is the render contract
|
|
40
|
+
* for amounts; cached hard (the asset set changes on deploys, not minutes).
|
|
41
|
+
*/
|
|
42
|
+
export function useSupportedAssets(options) {
|
|
43
|
+
const clients = useVenly();
|
|
44
|
+
return useQuery({
|
|
45
|
+
...venlyQueries.supportedAssets(clients),
|
|
46
|
+
staleTime: Infinity,
|
|
47
|
+
...options,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Account-scoped supported assets (adds `permitStatus`). Not frozen:
|
|
52
|
+
* permit status moves while an asset activates.
|
|
53
|
+
*/
|
|
54
|
+
export function useAccountSupportedAssets(accountId, options) {
|
|
55
|
+
const clients = useVenly();
|
|
56
|
+
return useQuery({
|
|
57
|
+
...venlyQueries.accountSupportedAssets(clients, accountId ?? ""),
|
|
58
|
+
enabled: Boolean(accountId) && (options?.enabled ?? true),
|
|
59
|
+
...options,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
36
62
|
export function useVirtualBankAccounts(accountId, query, options) {
|
|
37
63
|
const clients = useVenly();
|
|
38
64
|
return useQuery({
|
|
@@ -49,6 +75,34 @@ export function useTransfers(accountId, query, options) {
|
|
|
49
75
|
...options,
|
|
50
76
|
});
|
|
51
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Page every transfer on the account (the list contract has no date filter),
|
|
80
|
+
* then keep the window. `iteratePages` walks `hasNextPage`.
|
|
81
|
+
*/
|
|
82
|
+
export async function collectTransfersForPeriod(list, period, pageSize = 20) {
|
|
83
|
+
const ledger = [];
|
|
84
|
+
for await (const item of iteratePages((params) => list({ page: params.page, size: params.size }), {
|
|
85
|
+
size: pageSize,
|
|
86
|
+
})) {
|
|
87
|
+
ledger.push(item);
|
|
88
|
+
}
|
|
89
|
+
const items = ledger.filter((transfer) => {
|
|
90
|
+
const at = transfer.createdAt;
|
|
91
|
+
return Boolean(at && at >= period.start && at <= period.end);
|
|
92
|
+
});
|
|
93
|
+
return { items, ledger, resultPresent: true };
|
|
94
|
+
}
|
|
95
|
+
export function useTransfersForPeriod(accountId, period, options) {
|
|
96
|
+
const clients = useVenly();
|
|
97
|
+
const start = period?.start ?? "";
|
|
98
|
+
const end = period?.end ?? "";
|
|
99
|
+
return useQuery({
|
|
100
|
+
queryKey: venlyKeys.transfersForPeriod(accountId ?? "", { start, end }),
|
|
101
|
+
queryFn: () => collectTransfersForPeriod((query) => clients.finance.transfers.list(accountId ?? "", query), { start, end }),
|
|
102
|
+
enabled: Boolean(accountId && start && end) && (options?.enabled ?? true),
|
|
103
|
+
...options,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
52
106
|
export function useTransfer(accountId, transferId, options) {
|
|
53
107
|
const clients = useVenly();
|
|
54
108
|
return useQuery({
|
package/dist/query-options.d.ts
CHANGED
|
@@ -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<{
|
package/dist/query-options.js
CHANGED
|
@@ -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
|
+
"version": "0.5.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.
|
|
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
|
+
}
|