@venlyfinance/react 0.1.0 → 0.2.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
@@ -10,3 +10,7 @@ Initial release.
10
10
  - `proxyClientOptions()` for the browser-safe production shape; its placeholder credential is the exported `VENLY_PROXY_SECRET_SENTINEL`, which the browser guard recognises as not-a-secret.
11
11
  - The browser guard covers every path a secret can take into the provider: the top-level prop and both per-client options objects.
12
12
  - 30 node:test cases against the SDK's mock transport; zero network.
13
+
14
+ ## 0.1.1
15
+
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.
package/README.md CHANGED
@@ -126,4 +126,6 @@ npm test # node:test, zero network
126
126
  npm run build
127
127
  ```
128
128
 
129
+ See it assembled end to end: [`examples/mock-bank`](../examples/mock-bank/) runs a full account experience on these hooks in mock mode – `npm install && npm run dev`, fake data, zero credentials.
130
+
129
131
  MIT. Part of the [venly-settlement-sdk](https://github.com/Venly/venly-settlement-sdk) monorepo alongside `@venlyfinance/sdk` and `@venlyfinance/settlement-mcp`.
@@ -50,6 +50,12 @@ export class StagedTransferController {
50
50
  this.options = options;
51
51
  }
52
52
  subscribe = (listener) => {
53
+ // A new subscription revives a disposed controller. React StrictMode
54
+ // mounts, unmounts and remounts the same component instance: the
55
+ // cleanup dispose() must not leave the controller permanently dead for
56
+ // the remount, or confirm()'s continuation silently drops its state
57
+ // updates and the flow sticks in "submitting".
58
+ this.#disposed = false;
53
59
  this.#listeners.add(listener);
54
60
  return () => this.#listeners.delete(listener);
55
61
  };
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
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, } from "./queries.js";
5
- export { useCreateAccount, useCreateParty, useCreatePaymentSession, useCreateRampRequest, useCreateVirtualBankAccount, } from "./mutations.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";
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";
8
8
  export { describeRampStatus, useRampLifecycle, type RampLifecycleOptions, type RampStatus, type RampStatusDescriptor, } from "./flows/ramp-lifecycle.js";
package/dist/index.js CHANGED
@@ -4,9 +4,9 @@ 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, } from "./queries.js";
7
+ export { useAccount, useAccounts, useCompanyFees, useFeeQuote, useParties, useParty, useRampRequest, useRampRequests, useReferenceData, useTransfer, useTransfers, useVirtualBankAccounts, useWallets, useCompanyBankAccount, useCompanyBankAccounts, useCompanyWallets, useBankAccountConfig, useDepositWallets, useRampPairs, } from "./queries.js";
8
8
  // Write hooks
9
- export { useCreateAccount, useCreateParty, useCreatePaymentSession, useCreateRampRequest, useCreateVirtualBankAccount, } from "./mutations.js";
9
+ export { useCreateAccount, useCreateParty, useCreatePaymentSession, useCreateRampRequest, useCreateVirtualBankAccount, useCreateCompanyBankAccount, useCreateCompanyWallet, useSetRampAmount, useInitiateRamp, } from "./mutations.js";
10
10
  // Flow machines: the regulated-money lifecycles
11
11
  export { StagedTransferController, useStagedTransfer, validateDraft, } from "./flows/staged-transfer.js";
12
12
  export { approvalCapabilities, interpretApprovalError, useFourEyesApproval, } from "./flows/four-eyes.js";
package/dist/keys.d.ts CHANGED
@@ -15,6 +15,12 @@ export declare const venlyKeys: {
15
15
  readonly rampRequests: (query?: unknown) => readonly ["venly", "ramp-requests", {} | null];
16
16
  readonly rampRequest: (id: string) => readonly ["venly", "ramp-request", string];
17
17
  readonly referenceData: () => readonly ["venly", "reference-data"];
18
+ readonly companyBankAccounts: (query?: unknown) => readonly ["venly", "company-bank-accounts", {} | null];
19
+ readonly companyBankAccount: (id: string) => readonly ["venly", "company-bank-account", string];
20
+ readonly companyWallets: (query?: unknown) => readonly ["venly", "company-wallets", {} | null];
21
+ readonly bankAccountConfig: () => readonly ["venly", "bank-account-config"];
22
+ readonly depositWallets: (query?: unknown) => readonly ["venly", "deposit-wallets", {} | null];
23
+ readonly rampPairs: (direction: "on" | "off") => readonly ["venly", "ramp-pairs", "on" | "off"];
18
24
  readonly companyFees: () => readonly ["venly", "company-fees"];
19
25
  readonly feeQuote: (input: unknown) => readonly ["venly", "fee-quote", unknown];
20
26
  };
package/dist/keys.js CHANGED
@@ -15,6 +15,12 @@ export const venlyKeys = {
15
15
  rampRequests: (query) => ["venly", "ramp-requests", query ?? null],
16
16
  rampRequest: (id) => ["venly", "ramp-request", id],
17
17
  referenceData: () => ["venly", "reference-data"],
18
+ companyBankAccounts: (query) => ["venly", "company-bank-accounts", query ?? null],
19
+ companyBankAccount: (id) => ["venly", "company-bank-account", id],
20
+ companyWallets: (query) => ["venly", "company-wallets", query ?? null],
21
+ bankAccountConfig: () => ["venly", "bank-account-config"],
22
+ depositWallets: (query) => ["venly", "deposit-wallets", query ?? null],
23
+ rampPairs: (direction) => ["venly", "ramp-pairs", direction],
18
24
  companyFees: () => ["venly", "company-fees"],
19
25
  feeQuote: (input) => ["venly", "fee-quote", input],
20
26
  };
@@ -1,4 +1,4 @@
1
- import type { VenlyFinanceClient } from "@venlyfinance/sdk";
1
+ import type { FundflowClient, VenlyFinanceClient } from "@venlyfinance/sdk";
2
2
  type CreateVibaBody = Parameters<VenlyFinanceClient["virtualBankAccounts"]["create"]>[1];
3
3
  type CreatePaymentSessionBody = Parameters<VenlyFinanceClient["paymentSessions"]["create"]>[1];
4
4
  /** Create a party (individual or organisation), then refresh party lists. */
@@ -120,4 +120,89 @@ export declare function useCreateRampRequest(): import("@tanstack/react-query").
120
120
  fiatCurrencyId: string;
121
121
  cryptoCurrencyId: string;
122
122
  }, unknown>;
123
+ type SetRampAmountBody = Parameters<FundflowClient["rampRequests"]["setAmount"]>[1];
124
+ type InitiateRampBody = Parameters<FundflowClient["rampRequests"]["initiate"]>[1];
125
+ /** Whitelist a company bank account (created PENDING, verified out-of-band). */
126
+ export declare function useCreateCompanyBankAccount(): import("@tanstack/react-query").UseMutationResult<import("@venlyfinance/sdk").CompanyBankAccountDetails, Error, import("@venlyfinance/sdk").CreateCompanyBankAccountInput, unknown>;
127
+ /** Whitelist a company wallet (created PENDING; prove ownership out-of-band). */
128
+ export declare function useCreateCompanyWallet(): import("@tanstack/react-query").UseMutationResult<{
129
+ id?: string;
130
+ companyId?: string;
131
+ description?: string;
132
+ address?: string;
133
+ chain?: "ETHEREUM" | "POLYGON" | "BASE" | "ARBITRUM" | "SUI";
134
+ verificationStatus?: "PENDING" | "VERIFIED" | "DENIED";
135
+ verifiedAt?: string;
136
+ createdAt?: string;
137
+ updatedAt?: string;
138
+ version?: number;
139
+ }, Error, {
140
+ description?: string;
141
+ address: string;
142
+ chain: "ETHEREUM" | "POLYGON" | "BASE" | "ARBITRUM" | "SUI";
143
+ }, unknown>;
144
+ /** Edit a ramp amount while AWAITING_APPROVAL; carries the optimistic lock. */
145
+ export declare function useSetRampAmount(): import("@tanstack/react-query").UseMutationResult<{
146
+ id?: string;
147
+ companyId?: string;
148
+ companyName?: string;
149
+ rampType?: "ON_RAMP" | "OFF_RAMP";
150
+ status?: "AWAITING_APPROVAL" | "AWAITING_FUNDS" | "PROCESSING" | "SUCCEEDED" | "FAILED" | "BLOCKED" | "DENIED" | "REJECTED" | "CANCELLED";
151
+ amount?: number;
152
+ netAmount?: number;
153
+ fiatAmount?: number;
154
+ fiatNetAmount?: number;
155
+ cryptoAmount?: number;
156
+ fiatFeeAmount?: number;
157
+ exchangeRate?: number;
158
+ feePercentage?: number;
159
+ paymentReference?: string;
160
+ paymentReceived?: boolean;
161
+ blockchainTransactionHash?: string;
162
+ createdAt?: string;
163
+ companyBankAccount?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["EurSepaCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["GbpChapsCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["GbpFpsCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["OtherCurrencySwiftCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsAchCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsSwiftCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsWireCompanyBankAccountDto"];
164
+ companyWallet?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CompanyWalletDto"];
165
+ depositBankAccount?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["EurSepaDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["GbpChapsDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["GbpFpsDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["OtherCurrencySwiftDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsAchDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsSwiftDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsWireDepositBankAccountDto"];
166
+ depositWallet?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["DepositWalletDto"];
167
+ fiatCurrency?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["FiatCurrencyDto"];
168
+ cryptoCurrency?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CryptoCurrencyDto"];
169
+ events?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["RampRequestEventDto"][];
170
+ version?: number;
171
+ amountReceived?: number;
172
+ }, Error, {
173
+ id: string;
174
+ body: SetRampAmountBody;
175
+ }, unknown>;
176
+ /** Report the off-ramp crypto leg's transaction hash (initiates processing). */
177
+ export declare function useInitiateRamp(): import("@tanstack/react-query").UseMutationResult<{
178
+ id?: string;
179
+ companyId?: string;
180
+ companyName?: string;
181
+ rampType?: "ON_RAMP" | "OFF_RAMP";
182
+ status?: "AWAITING_APPROVAL" | "AWAITING_FUNDS" | "PROCESSING" | "SUCCEEDED" | "FAILED" | "BLOCKED" | "DENIED" | "REJECTED" | "CANCELLED";
183
+ amount?: number;
184
+ netAmount?: number;
185
+ fiatAmount?: number;
186
+ fiatNetAmount?: number;
187
+ cryptoAmount?: number;
188
+ fiatFeeAmount?: number;
189
+ exchangeRate?: number;
190
+ feePercentage?: number;
191
+ paymentReference?: string;
192
+ paymentReceived?: boolean;
193
+ blockchainTransactionHash?: string;
194
+ createdAt?: string;
195
+ companyBankAccount?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["EurSepaCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["GbpChapsCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["GbpFpsCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["OtherCurrencySwiftCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsAchCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsSwiftCompanyBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsWireCompanyBankAccountDto"];
196
+ companyWallet?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CompanyWalletDto"];
197
+ depositBankAccount?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["EurSepaDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["GbpChapsDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["GbpFpsDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["OtherCurrencySwiftDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsAchDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsSwiftDepositBankAccountDto"] | import("@venlyfinance/sdk").FundflowComponents["schemas"]["UsWireDepositBankAccountDto"];
198
+ depositWallet?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["DepositWalletDto"];
199
+ fiatCurrency?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["FiatCurrencyDto"];
200
+ cryptoCurrency?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CryptoCurrencyDto"];
201
+ events?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["RampRequestEventDto"][];
202
+ version?: number;
203
+ amountReceived?: number;
204
+ }, Error, {
205
+ id: string;
206
+ body: InitiateRampBody;
207
+ }, unknown>;
123
208
  export {};
package/dist/mutations.js CHANGED
@@ -56,3 +56,51 @@ export function useCreateRampRequest() {
56
56
  },
57
57
  });
58
58
  }
59
+ /** Whitelist a company bank account (created PENDING, verified out-of-band). */
60
+ export function useCreateCompanyBankAccount() {
61
+ const { fundflow } = useVenly();
62
+ const queryClient = useQueryClient();
63
+ return useMutation({
64
+ mutationFn: (body) => fundflow.bankAccounts.create(body),
65
+ onSuccess: (account) => {
66
+ if (account.id)
67
+ queryClient.setQueryData(venlyKeys.companyBankAccount(account.id), account);
68
+ void queryClient.invalidateQueries({ queryKey: ["venly", "company-bank-accounts"] });
69
+ },
70
+ });
71
+ }
72
+ /** Whitelist a company wallet (created PENDING; prove ownership out-of-band). */
73
+ export function useCreateCompanyWallet() {
74
+ const { fundflow } = useVenly();
75
+ const queryClient = useQueryClient();
76
+ return useMutation({
77
+ mutationFn: (body) => fundflow.companyWallets.create(body),
78
+ onSuccess: () => {
79
+ void queryClient.invalidateQueries({ queryKey: ["venly", "company-wallets"] });
80
+ },
81
+ });
82
+ }
83
+ /** Edit a ramp amount while AWAITING_APPROVAL; carries the optimistic lock. */
84
+ export function useSetRampAmount() {
85
+ const { fundflow } = useVenly();
86
+ const queryClient = useQueryClient();
87
+ return useMutation({
88
+ mutationFn: (input) => fundflow.rampRequests.setAmount(input.id, input.body),
89
+ onSuccess: (ramp, input) => {
90
+ queryClient.setQueryData(venlyKeys.rampRequest(input.id), ramp);
91
+ void queryClient.invalidateQueries({ queryKey: ["venly", "ramp-requests"] });
92
+ },
93
+ });
94
+ }
95
+ /** Report the off-ramp crypto leg's transaction hash (initiates processing). */
96
+ export function useInitiateRamp() {
97
+ const { fundflow } = useVenly();
98
+ const queryClient = useQueryClient();
99
+ return useMutation({
100
+ mutationFn: (input) => fundflow.rampRequests.initiate(input.id, input.body),
101
+ onSuccess: (ramp, input) => {
102
+ queryClient.setQueryData(venlyKeys.rampRequest(input.id), ramp);
103
+ void queryClient.invalidateQueries({ queryKey: ["venly", "ramp-requests"] });
104
+ },
105
+ });
106
+ }
@@ -62,5 +62,5 @@ export declare function useVenly(): VenlyClients;
62
62
  */
63
63
  export declare function useVenlyMock(): {
64
64
  finance: import("@venlyfinance/sdk").VenlyFinanceMock | undefined;
65
- fundflow: import("@venlyfinance/sdk").VenlyMock | undefined;
65
+ fundflow: import("@venlyfinance/sdk").VenlyFundflowMock | undefined;
66
66
  };
package/dist/queries.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { type UseQueryOptions } from "@tanstack/react-query";
2
- import { venlyQueries, type AccountsQuery, type FeeQuoteInput, type PartiesQuery, type RampRequestsQuery, type TransfersQuery, type VirtualBankAccountsQuery, type WalletsQuery } from "./query-options.js";
2
+ 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
3
  type Tune<T> = Omit<UseQueryOptions<T, Error>, "queryKey" | "queryFn">;
4
4
  export declare function useParties(query?: PartiesQuery, options?: Tune<PartiesPage>): import("@tanstack/react-query").UseQueryResult<NoInfer<import("@venlyfinance/sdk").Page<{
5
5
  id?: string;
@@ -197,4 +197,81 @@ export declare function useFeeQuote(input: FeeQuoteInput | undefined, options?:
197
197
  percentage?: number;
198
198
  }>, Error>;
199
199
  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<import("@venlyfinance/sdk").Page<{
201
+ id?: string;
202
+ name?: string;
203
+ bankName?: string;
204
+ bankCountry?: string;
205
+ bankAccountType?: "EUR_SEPA" | "USD_WIRE" | "USD_ACH" | "USD_SWIFT" | "GBP_FPS" | "GBP_CHAPS" | "OTHER_SWIFT";
206
+ supportedRampType?: "ON_RAMP" | "OFF_RAMP" | "ON_AND_OFF_RAMP";
207
+ verificationStatus?: "PENDING" | "VERIFIED" | "DENIED";
208
+ createdAt?: string;
209
+ updatedAt?: string;
210
+ }>>, Error>;
211
+ type BankAccountsPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.companyBankAccounts>["queryFn"]>>;
212
+ export declare function useCompanyBankAccount(id: string | undefined, options?: Tune<BankAccountDetail>): import("@tanstack/react-query").UseQueryResult<NoInfer<{
213
+ id?: string;
214
+ companyId?: string;
215
+ name?: string;
216
+ bankName?: string;
217
+ companyName?: string;
218
+ email?: string;
219
+ phoneNumber?: string;
220
+ bankCountry?: string;
221
+ beneficiaryAddressLine1?: string;
222
+ beneficiaryAddressLine2?: string;
223
+ beneficiaryCity?: string;
224
+ beneficiaryState?: string;
225
+ beneficiaryPostalCode?: string;
226
+ beneficiaryCountry?: string;
227
+ bankAccountType?: "EUR_SEPA" | "USD_WIRE" | "USD_ACH" | "USD_SWIFT" | "GBP_FPS" | "GBP_CHAPS" | "OTHER_SWIFT";
228
+ supportedRampType?: "ON_RAMP" | "OFF_RAMP" | "ON_AND_OFF_RAMP";
229
+ verificationStatus?: "PENDING" | "VERIFIED" | "DENIED";
230
+ verifiedAt?: string;
231
+ createdAt?: string;
232
+ updatedAt?: string;
233
+ version?: number;
234
+ } & {
235
+ iban?: string;
236
+ bic?: string;
237
+ intermediaryBic?: string;
238
+ intermediaryBankName?: string;
239
+ accountNumber?: string;
240
+ sortCode?: string;
241
+ routingNumber?: string;
242
+ bankStreetAddress?: string;
243
+ bankCity?: string;
244
+ bankPostalCode?: string;
245
+ currency?: string;
246
+ }>, Error>;
247
+ 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<import("@venlyfinance/sdk").Page<{
249
+ id?: string;
250
+ description?: string;
251
+ address?: string;
252
+ chain?: "ETHEREUM" | "POLYGON" | "BASE" | "ARBITRUM" | "SUI";
253
+ verificationStatus?: "PENDING" | "VERIFIED" | "DENIED";
254
+ createdAt?: string;
255
+ updatedAt?: string;
256
+ }>>, Error>;
257
+ type WalletsListPage = Awaited<ReturnType<ReturnType<typeof venlyQueries.companyWallets>["queryFn"]>>;
258
+ export declare function useBankAccountConfig(options?: Tune<BankAccountConfigData>): import("@tanstack/react-query").UseQueryResult<NoInfer<{
259
+ enabledAccountTypes?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["BankAccountTypeDto"][];
260
+ supportedCountries?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CountryDto"][];
261
+ supportedCurrencies?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CurrencyItemDto"][];
262
+ }>, Error>;
263
+ type BankAccountConfigData = Awaited<ReturnType<ReturnType<typeof venlyQueries.bankAccountConfig>["queryFn"]>>;
264
+ export declare function useDepositWallets(query?: DepositWalletsQuery, options?: Tune<DepositWalletsData>): import("@tanstack/react-query").UseQueryResult<NoInfer<{
265
+ id?: string;
266
+ address?: string;
267
+ chain?: "ETHEREUM" | "POLYGON" | "BASE" | "ARBITRUM" | "SUI";
268
+ label?: string;
269
+ isDefault?: boolean;
270
+ isActive?: boolean;
271
+ version?: number;
272
+ }[]>, Error>;
273
+ type DepositWalletsData = Awaited<ReturnType<ReturnType<typeof venlyQueries.depositWallets>["queryFn"]>>;
274
+ /** Supported on/off-ramp currency pairs, for destination/asset pickers. */
275
+ export declare function useRampPairs(direction: "on" | "off", options?: Tune<RampPairsData>): import("@tanstack/react-query").UseQueryResult<NoInfer<RampPairsData>, Error>;
276
+ type RampPairsData = Awaited<ReturnType<ReturnType<typeof venlyQueries.rampPairs>["queryFn"]>>;
200
277
  export {};
package/dist/queries.js CHANGED
@@ -89,3 +89,40 @@ export function useFeeQuote(input, options) {
89
89
  ...options,
90
90
  });
91
91
  }
92
+ export function useCompanyBankAccounts(query, options) {
93
+ const clients = useVenly();
94
+ return useQuery({ ...venlyQueries.companyBankAccounts(clients, query), ...options });
95
+ }
96
+ export function useCompanyBankAccount(id, options) {
97
+ const clients = useVenly();
98
+ return useQuery({
99
+ ...venlyQueries.companyBankAccount(clients, id ?? ""),
100
+ enabled: Boolean(id) && (options?.enabled ?? true),
101
+ ...options,
102
+ });
103
+ }
104
+ export function useCompanyWallets(query, options) {
105
+ const clients = useVenly();
106
+ return useQuery({ ...venlyQueries.companyWallets(clients, query), ...options });
107
+ }
108
+ export function useBankAccountConfig(options) {
109
+ const clients = useVenly();
110
+ return useQuery({
111
+ ...venlyQueries.bankAccountConfig(clients),
112
+ staleTime: Infinity, // enabled types/countries change on deploys, not minutes
113
+ ...options,
114
+ });
115
+ }
116
+ export function useDepositWallets(query, options) {
117
+ const clients = useVenly();
118
+ return useQuery({ ...venlyQueries.depositWallets(clients, query), ...options });
119
+ }
120
+ /** Supported on/off-ramp currency pairs, for destination/asset pickers. */
121
+ export function useRampPairs(direction, options) {
122
+ const clients = useVenly();
123
+ return useQuery({
124
+ ...venlyQueries.rampPairs(clients, direction),
125
+ staleTime: Infinity,
126
+ ...options,
127
+ });
128
+ }
@@ -7,6 +7,9 @@ export type VirtualBankAccountsQuery = NonNullable<Parameters<VenlyFinanceClient
7
7
  export type TransfersQuery = NonNullable<Parameters<VenlyFinanceClient["transfers"]["list"]>[1]>;
8
8
  export type RampRequestsQuery = NonNullable<Parameters<FundflowClient["rampRequests"]["list"]>[0]>;
9
9
  export type FeeQuoteInput = Parameters<FundflowClient["fees"]["calculate"]>[0];
10
+ export type CompanyBankAccountsQuery = NonNullable<Parameters<FundflowClient["bankAccounts"]["list"]>[0]>;
11
+ export type CompanyWalletsQuery = NonNullable<Parameters<FundflowClient["companyWallets"]["list"]>[0]>;
12
+ export type DepositWalletsQuery = NonNullable<Parameters<FundflowClient["referenceData"]["depositWallets"]>[0]>;
10
13
  /**
11
14
  * Pure `{ queryKey, queryFn }` factories, one per read. The hooks in
12
15
  * queries.ts are one-line wrappers over these; anything that needs the same
@@ -241,4 +244,64 @@ export declare const venlyQueries: {
241
244
  percentage?: number;
242
245
  }>;
243
246
  };
247
+ readonly companyBankAccounts: (clients: VenlyClients, query?: CompanyBankAccountsQuery) => {
248
+ queryKey: readonly ["venly", "company-bank-accounts", {} | null];
249
+ queryFn: () => Promise<import("@venlyfinance/sdk").Page<{
250
+ id?: string;
251
+ name?: string;
252
+ bankName?: string;
253
+ bankCountry?: string;
254
+ bankAccountType?: "EUR_SEPA" | "USD_WIRE" | "USD_ACH" | "USD_SWIFT" | "GBP_FPS" | "GBP_CHAPS" | "OTHER_SWIFT";
255
+ supportedRampType?: "ON_RAMP" | "OFF_RAMP" | "ON_AND_OFF_RAMP";
256
+ verificationStatus?: "PENDING" | "VERIFIED" | "DENIED";
257
+ createdAt?: string;
258
+ updatedAt?: string;
259
+ }>>;
260
+ };
261
+ readonly companyBankAccount: (clients: VenlyClients, id: string) => {
262
+ queryKey: readonly ["venly", "company-bank-account", string];
263
+ queryFn: () => Promise<import("@venlyfinance/sdk").CompanyBankAccountDetails>;
264
+ };
265
+ readonly companyWallets: (clients: VenlyClients, query?: CompanyWalletsQuery) => {
266
+ queryKey: readonly ["venly", "company-wallets", {} | null];
267
+ queryFn: () => Promise<import("@venlyfinance/sdk").Page<{
268
+ id?: string;
269
+ description?: string;
270
+ address?: string;
271
+ chain?: "ETHEREUM" | "POLYGON" | "BASE" | "ARBITRUM" | "SUI";
272
+ verificationStatus?: "PENDING" | "VERIFIED" | "DENIED";
273
+ createdAt?: string;
274
+ updatedAt?: string;
275
+ }>>;
276
+ };
277
+ readonly bankAccountConfig: (clients: VenlyClients) => {
278
+ queryKey: readonly ["venly", "bank-account-config"];
279
+ queryFn: () => Promise<{
280
+ enabledAccountTypes?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["BankAccountTypeDto"][];
281
+ supportedCountries?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CountryDto"][];
282
+ supportedCurrencies?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CurrencyItemDto"][];
283
+ }>;
284
+ };
285
+ readonly depositWallets: (clients: VenlyClients, query?: DepositWalletsQuery) => {
286
+ queryKey: readonly ["venly", "deposit-wallets", {} | null];
287
+ queryFn: () => Promise<{
288
+ id?: string;
289
+ address?: string;
290
+ chain?: "ETHEREUM" | "POLYGON" | "BASE" | "ARBITRUM" | "SUI";
291
+ label?: string;
292
+ isDefault?: boolean;
293
+ isActive?: boolean;
294
+ version?: number;
295
+ }[]>;
296
+ };
297
+ readonly rampPairs: (clients: VenlyClients, direction: "on" | "off") => {
298
+ queryKey: readonly ["venly", "ramp-pairs", "on" | "off"];
299
+ queryFn: () => Promise<{
300
+ from?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["FiatPairItem"];
301
+ to?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CryptoPairItem"];
302
+ }[]> | Promise<{
303
+ from?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["CryptoPairItem"];
304
+ to?: import("@venlyfinance/sdk").FundflowComponents["schemas"]["FiatPairItem"];
305
+ }[]>;
306
+ };
244
307
  };
@@ -70,4 +70,30 @@ export const venlyQueries = {
70
70
  queryKey: venlyKeys.feeQuote(input),
71
71
  queryFn: () => clients.fundflow.fees.calculate(input),
72
72
  }),
73
+ companyBankAccounts: (clients, query) => ({
74
+ queryKey: venlyKeys.companyBankAccounts(query),
75
+ queryFn: () => clients.fundflow.bankAccounts.list(query),
76
+ }),
77
+ companyBankAccount: (clients, id) => ({
78
+ queryKey: venlyKeys.companyBankAccount(id),
79
+ queryFn: () => clients.fundflow.bankAccounts.get(id),
80
+ }),
81
+ companyWallets: (clients, query) => ({
82
+ queryKey: venlyKeys.companyWallets(query),
83
+ queryFn: () => clients.fundflow.companyWallets.list(query),
84
+ }),
85
+ bankAccountConfig: (clients) => ({
86
+ queryKey: venlyKeys.bankAccountConfig(),
87
+ queryFn: () => clients.fundflow.referenceData.bankAccountConfig(),
88
+ }),
89
+ depositWallets: (clients, query) => ({
90
+ queryKey: venlyKeys.depositWallets(query),
91
+ queryFn: () => clients.fundflow.referenceData.depositWallets(query),
92
+ }),
93
+ rampPairs: (clients, direction) => ({
94
+ queryKey: venlyKeys.rampPairs(direction),
95
+ queryFn: () => direction === "on"
96
+ ? clients.fundflow.rampRequests.onRampPairs()
97
+ : clients.fundflow.rampRequests.offRampPairs(),
98
+ }),
73
99
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venlyfinance/react",
3
- "version": "0.1.0",
3
+ "version": "0.2.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.2.0"
33
+ "@venlyfinance/sdk": "^0.3.0"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "@tanstack/react-query": "^5.0.0",