squarefi-bff-api-module 1.36.29 → 1.36.31

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.
@@ -891,21 +891,90 @@ export interface paths {
891
891
  };
892
892
  requestBody?: never;
893
893
  responses: {
894
- /** @description Bank data resolved successfully */
894
+ /** @description Bank data resolved. `data` is null ONLY when the bank-data lookup subsystem is
895
+ * disabled on the environment; with lookups enabled a failed resolution is
896
+ * reported as 400, never as a null `data`.
897
+ * */
895
898
  200: {
896
899
  headers: {
897
900
  [name: string]: unknown;
898
901
  };
899
- content?: never;
902
+ content: {
903
+ "application/json": {
904
+ /** @example true */
905
+ success: boolean;
906
+ data: components["schemas"]["BankData"] | null;
907
+ };
908
+ };
900
909
  };
901
- /** @description Missing/unsupported code */
910
+ /** @description Bad request — one of:
911
+ * - `VALIDATION_ERROR` — query parameter `code` is missing/empty, or longer than 64 characters
912
+ * - `UNSUPPORTED_BANK_CODE` — `code` does not match any supported format (IBAN, SWIFT/BIC, US RTN)
913
+ * - `BANK_DATA_LOOKUP_FAILED` — the code is well-formed but could not be resolved
914
+ * (unknown code or a transient lookup failure); always reported as this single
915
+ * 400, never as 404/502
916
+ * - `EXTERNAL_SERVICE_ERROR` — the bank-data lookup is temporarily unavailable
917
+ *
918
+ * The body also carries a top-level `correlationId` (added by the error handler to
919
+ * every 4xx/5xx it formats).
920
+ * */
902
921
  400: {
903
922
  headers: {
904
923
  [name: string]: unknown;
905
924
  };
906
- content?: never;
925
+ content: {
926
+ "application/json": components["schemas"]["ErrorResponse"];
927
+ };
907
928
  };
908
929
  401: components["responses"]["UnauthorizedError"];
930
+ /** @description Per-user bank-data lookup rate limit exceeded (stricter than the general frontend
931
+ * rate limit). The body is sent directly by the rate-limit middleware, bypassing
932
+ * the group error handler, so it carries no `correlationId` and no `details` field.
933
+ *
934
+ * The platform-wide per-user and per-IP limiters can also answer 429 on this
935
+ * endpoint — same envelope, code and headers, but with the generic message
936
+ * "Too many requests. Please try again later.".
937
+ * */
938
+ 429: {
939
+ headers: {
940
+ /** @description Maximum number of lookups allowed in the current window */
941
+ "X-RateLimit-Limit"?: string;
942
+ /** @description Lookups remaining in the current window */
943
+ "X-RateLimit-Remaining"?: string;
944
+ /** @description Unix timestamp (ms) at which the current window resets */
945
+ "X-RateLimit-Reset"?: string;
946
+ [name: string]: unknown;
947
+ };
948
+ content: {
949
+ /** @example {
950
+ * "success": false,
951
+ * "error": {
952
+ * "code": "RATE_LIMIT_EXCEEDED",
953
+ * "message": "Too many bank data lookups. Please slow down."
954
+ * }
955
+ * } */
956
+ "application/json": components["schemas"]["ErrorResponse"];
957
+ };
958
+ };
959
+ /** @description Unexpected internal error, handled by the catch-all error handler; the body
960
+ * carries a `correlationId`.
961
+ * */
962
+ 500: {
963
+ headers: {
964
+ [name: string]: unknown;
965
+ };
966
+ content: {
967
+ /** @example {
968
+ * "success": false,
969
+ * "error": {
970
+ * "code": "INTERNAL_ERROR",
971
+ * "message": "Internal server error"
972
+ * },
973
+ * "correlationId": "3f7f2f9a-8f0e-4a3b-9a3d-2f1c9d6a1b2c"
974
+ * } */
975
+ "application/json": components["schemas"]["ErrorResponse"];
976
+ };
977
+ };
909
978
  };
910
979
  };
911
980
  put?: never;
@@ -4582,6 +4651,269 @@ export interface paths {
4582
4651
  patch?: never;
4583
4652
  trace?: never;
4584
4653
  };
4654
+ "/frontend/kyc_verification/{wallet_id}/init": {
4655
+ parameters: {
4656
+ query?: never;
4657
+ header?: never;
4658
+ path?: never;
4659
+ cookie?: never;
4660
+ };
4661
+ get?: never;
4662
+ put?: never;
4663
+ /**
4664
+ * Initialize KYC verification for a wallet
4665
+ * @description Starts a provider-agnostic KYC data-collection flow for the wallet via
4666
+ * the Auth API. The KYC provider (Persona, Sumsub, …) is resolved
4667
+ * internally per tenant — the caller does not choose it. Returns the
4668
+ * provider verification id plus an optional short-lived SDK token the
4669
+ * client uses to launch the verification. The caller's Bearer token is
4670
+ * forwarded to the Auth API.
4671
+ *
4672
+ * Provider-agnostic replacement for the deprecated
4673
+ * `GET /frontend/kyc_persona/{wallet_id}/init`.
4674
+ *
4675
+ * **Authentication**: Bearer token with x-tenant-id header required
4676
+ *
4677
+ * **Access Control**: Any user with access to the wallet (scoped card-users excluded)
4678
+ *
4679
+ */
4680
+ post: {
4681
+ parameters: {
4682
+ query?: never;
4683
+ header?: never;
4684
+ path: {
4685
+ /** @description Wallet UUID */
4686
+ wallet_id: string;
4687
+ };
4688
+ cookie?: never;
4689
+ };
4690
+ requestBody: {
4691
+ content: {
4692
+ "application/json": {
4693
+ /**
4694
+ * @description KYC entity type
4695
+ * @enum {string}
4696
+ */
4697
+ type: "individual" | "business";
4698
+ };
4699
+ };
4700
+ };
4701
+ responses: {
4702
+ /** @description KYC verification initialized */
4703
+ 200: {
4704
+ headers: {
4705
+ [name: string]: unknown;
4706
+ };
4707
+ content: {
4708
+ "application/json": {
4709
+ /** @example true */
4710
+ success: boolean;
4711
+ data: {
4712
+ /**
4713
+ * Format: uuid
4714
+ * @description Echo of the wallet from the path
4715
+ */
4716
+ wallet_id: string;
4717
+ /**
4718
+ * @description Provider that handled the flow (e.g. persona, sumsub)
4719
+ * @example persona
4720
+ */
4721
+ provider_type: string;
4722
+ /**
4723
+ * @description Provider verification id — Persona: inquiryId, Sumsub: applicantId
4724
+ * @example inq_ABDNxhp9ZzD3yehivCbMVvmjwh5g5r
4725
+ */
4726
+ verification_id: string;
4727
+ /** @description Short-lived SDK/session token when the provider mints one — otherwise null */
4728
+ verification_token?: string | null;
4729
+ };
4730
+ };
4731
+ };
4732
+ };
4733
+ /** @description Validation error (`type` missing or not in [individual, business]) */
4734
+ 400: {
4735
+ headers: {
4736
+ [name: string]: unknown;
4737
+ };
4738
+ content: {
4739
+ "application/json": components["schemas"]["ErrorResponse"];
4740
+ };
4741
+ };
4742
+ /** @description Missing or invalid Bearer token */
4743
+ 401: {
4744
+ headers: {
4745
+ [name: string]: unknown;
4746
+ };
4747
+ content: {
4748
+ "application/json": components["schemas"]["ErrorResponse"];
4749
+ };
4750
+ };
4751
+ /** @description Caller has no access to this wallet */
4752
+ 403: {
4753
+ headers: {
4754
+ [name: string]: unknown;
4755
+ };
4756
+ content: {
4757
+ "application/json": components["schemas"]["ErrorResponse"];
4758
+ };
4759
+ };
4760
+ /** @description Wallet not found upstream */
4761
+ 404: {
4762
+ headers: {
4763
+ [name: string]: unknown;
4764
+ };
4765
+ content: {
4766
+ "application/json": components["schemas"]["ErrorResponse"];
4767
+ };
4768
+ };
4769
+ /** @description Auth API unavailable, timed out, or returned a malformed payload */
4770
+ 502: {
4771
+ headers: {
4772
+ [name: string]: unknown;
4773
+ };
4774
+ content: {
4775
+ "application/json": components["schemas"]["ErrorResponse"];
4776
+ };
4777
+ };
4778
+ };
4779
+ };
4780
+ delete?: never;
4781
+ options?: never;
4782
+ head?: never;
4783
+ patch?: never;
4784
+ trace?: never;
4785
+ };
4786
+ "/frontend/kyc_verification/{wallet_id}/resume": {
4787
+ parameters: {
4788
+ query?: never;
4789
+ header?: never;
4790
+ path?: never;
4791
+ cookie?: never;
4792
+ };
4793
+ get?: never;
4794
+ put?: never;
4795
+ /**
4796
+ * Resume KYC verification for a wallet
4797
+ * @description Resumes an existing provider-agnostic KYC data-collection flow for the
4798
+ * wallet via the Auth API. The provider is resolved internally per tenant.
4799
+ * `verification_ref` is the provider reference returned by init (Persona:
4800
+ * `inquiry_id`, Sumsub: `applicant_id`). The caller's Bearer token is
4801
+ * forwarded to the Auth API.
4802
+ *
4803
+ * Provider-agnostic replacement for the deprecated
4804
+ * `GET /frontend/kyc_persona/{wallet_id}/resume`.
4805
+ *
4806
+ * **Authentication**: Bearer token with x-tenant-id header required
4807
+ *
4808
+ * **Access Control**: Any user with access to the wallet (scoped card-users excluded)
4809
+ *
4810
+ */
4811
+ post: {
4812
+ parameters: {
4813
+ query?: never;
4814
+ header?: never;
4815
+ path: {
4816
+ /** @description Wallet UUID */
4817
+ wallet_id: string;
4818
+ };
4819
+ cookie?: never;
4820
+ };
4821
+ requestBody: {
4822
+ content: {
4823
+ "application/json": {
4824
+ /**
4825
+ * @description Provider verification reference (Persona: inquiry_id, Sumsub: applicant_id)
4826
+ * @example inq_ABDNxhp9ZzD3yehivCbMVvmjwh5g5r
4827
+ */
4828
+ verification_ref: string;
4829
+ };
4830
+ };
4831
+ };
4832
+ responses: {
4833
+ /** @description KYC verification resumed */
4834
+ 200: {
4835
+ headers: {
4836
+ [name: string]: unknown;
4837
+ };
4838
+ content: {
4839
+ "application/json": {
4840
+ /** @example true */
4841
+ success: boolean;
4842
+ data: {
4843
+ /**
4844
+ * Format: uuid
4845
+ * @description Echo of the wallet from the path
4846
+ */
4847
+ wallet_id: string;
4848
+ /**
4849
+ * @description Provider that handled the flow (e.g. persona, sumsub)
4850
+ * @example persona
4851
+ */
4852
+ provider_type: string;
4853
+ /**
4854
+ * @description Provider verification id — Persona: inquiryId, Sumsub: applicantId
4855
+ * @example inq_ABDNxhp9ZzD3yehivCbMVvmjwh5g5r
4856
+ */
4857
+ verification_id: string;
4858
+ /** @description Short-lived SDK/session token when the provider mints one — otherwise null */
4859
+ verification_token?: string | null;
4860
+ };
4861
+ };
4862
+ };
4863
+ };
4864
+ /** @description Validation error (`verification_ref` missing or empty) */
4865
+ 400: {
4866
+ headers: {
4867
+ [name: string]: unknown;
4868
+ };
4869
+ content: {
4870
+ "application/json": components["schemas"]["ErrorResponse"];
4871
+ };
4872
+ };
4873
+ /** @description Missing or invalid Bearer token */
4874
+ 401: {
4875
+ headers: {
4876
+ [name: string]: unknown;
4877
+ };
4878
+ content: {
4879
+ "application/json": components["schemas"]["ErrorResponse"];
4880
+ };
4881
+ };
4882
+ /** @description Caller has no access to this wallet */
4883
+ 403: {
4884
+ headers: {
4885
+ [name: string]: unknown;
4886
+ };
4887
+ content: {
4888
+ "application/json": components["schemas"]["ErrorResponse"];
4889
+ };
4890
+ };
4891
+ /** @description No such verification to resume upstream */
4892
+ 404: {
4893
+ headers: {
4894
+ [name: string]: unknown;
4895
+ };
4896
+ content: {
4897
+ "application/json": components["schemas"]["ErrorResponse"];
4898
+ };
4899
+ };
4900
+ /** @description Auth API unavailable, timed out, or returned a malformed payload */
4901
+ 502: {
4902
+ headers: {
4903
+ [name: string]: unknown;
4904
+ };
4905
+ content: {
4906
+ "application/json": components["schemas"]["ErrorResponse"];
4907
+ };
4908
+ };
4909
+ };
4910
+ };
4911
+ delete?: never;
4912
+ options?: never;
4913
+ head?: never;
4914
+ patch?: never;
4915
+ trace?: never;
4916
+ };
4585
4917
  "/frontend/orders/deposit/ach": {
4586
4918
  parameters: {
4587
4919
  query?: never;
@@ -4830,15 +5162,17 @@ export interface paths {
4830
5162
  put?: never;
4831
5163
  /**
4832
5164
  * Exchange
4833
- * @description Crypto-to-crypto exchange within a wallet.
5165
+ * @description Currency exchange within a wallet — a pure ledger swap for any enabled
5166
+ * currency pair (crypto and fiat alike). Pair availability is governed by
5167
+ * the exchange calculation config: a disabled pair is rejected at create.
4834
5168
  *
4835
5169
  * Two-phase, like the banking withdrawals: the order is created in status
4836
- * `NEW` with the source funds blocked. Call `POST /frontend/orders/{order_id}/approve`
4837
- * (OTP-gated via `request_id`) to execute the swap the order lands in
4838
- * `COMPLETE` synchronouslyor `POST /frontend/orders/{order_id}/cancel`
4839
- * to release the blocked funds.
5170
+ * `NEW` without touching the balance. Call `POST /frontend/orders/{order_id}/approve`
5171
+ * (OTP-gated, keyed on the order id) to check the balance, debit the
5172
+ * source funds and execute the swap the order lands in `COMPLETE`
5173
+ * synchronously or `POST /frontend/orders/{order_id}/cancel` to
5174
+ * discard the order.
4840
5175
  *
4841
- * Fiat legs are not supported — only crypto-to-crypto pairs are accepted.
4842
5176
  * Caller must be `admin` of the wallet.
4843
5177
  *
4844
5178
  */
@@ -4855,7 +5189,7 @@ export interface paths {
4855
5189
  };
4856
5190
  };
4857
5191
  responses: {
4858
- /** @description Exchange order created (status NEW, funds blocked — approve to execute) */
5192
+ /** @description Exchange order created (status NEW — approve to debit and execute) */
4859
5193
  200: {
4860
5194
  headers: {
4861
5195
  [name: string]: unknown;
@@ -4924,10 +5258,11 @@ export interface paths {
4924
5258
  /**
4925
5259
  * Internal
4926
5260
  * @description Transfers funds between two wallets within the platform. Two-phase:
4927
- * the order is created in `NEW` status with the sender's funds blocked;
4928
- * `POST /frontend/orders/{id}/approve` (OTP-gated via the `request_id`)
4929
- * executes the transfer synchronously receiver credited, order
4930
- * `COMPLETE`. A `NEW` order can be canceled to refund the blocked funds.
5261
+ * the order is created in `NEW` status without touching the balance;
5262
+ * `POST /frontend/orders/{id}/approve` (OTP-gated, keyed on the order
5263
+ * id) checks the balance, debits the sender and executes the transfer
5264
+ * synchronously — receiver credited, order `COMPLETE`. A `NEW` order
5265
+ * can simply be canceled (no funds are held).
4931
5266
  * Caller must be `admin` of the source wallet.
4932
5267
  *
4933
5268
  */
@@ -4954,15 +5289,13 @@ export interface paths {
4954
5289
  */
4955
5290
  counterparty_destination_id: string;
4956
5291
  amount: number;
4957
- /** @description Idempotency key (UUID) */
4958
- request_id: string;
4959
5292
  /** @description Optional supporting documents persisted with the order. */
4960
5293
  documents?: components["schemas"]["OrderDocumentInput"][];
4961
5294
  };
4962
5295
  };
4963
5296
  };
4964
5297
  responses: {
4965
- /** @description Transfer created in NEW status (funds blocked, awaiting approve) */
5298
+ /** @description Transfer created in NEW status (awaiting approve; no funds held) */
4966
5299
  200: {
4967
5300
  headers: {
4968
5301
  [name: string]: unknown;
@@ -5031,12 +5364,13 @@ export interface paths {
5031
5364
  /**
5032
5365
  * Crypto
5033
5366
  * @description Sends crypto from an omnibus wallet to an external address. Two-phase:
5034
- * the order is created in `NEW` status with funds blocked;
5035
- * `POST /frontend/orders/{id}/approve` (OTP-gated via the `request_id`)
5036
- * dispatches the on-chain send. If the destination address belongs to a
5037
- * wallet in the same tenant, the order is created as
5038
- * `OMNIBUS_INTERNAL_TRANSFER` (no on-chain transaction) still `NEW` at
5039
- * create, settled synchronously to `COMPLETE` at approve.
5367
+ * the order is created in `NEW` status without touching the balance;
5368
+ * `POST /frontend/orders/{id}/approve` (OTP-gated, keyed on the order
5369
+ * id) checks the balance, debits the funds and dispatches the on-chain
5370
+ * send. If the destination address belongs to a wallet in the same
5371
+ * tenant, the order is created as `OMNIBUS_INTERNAL_TRANSFER` (no
5372
+ * on-chain transaction) still `NEW` at create, debited + settled
5373
+ * synchronously to `COMPLETE` at approve.
5040
5374
  *
5041
5375
  */
5042
5376
  post: {
@@ -5706,10 +6040,13 @@ export interface paths {
5706
6040
  put?: never;
5707
6041
  /**
5708
6042
  * Approve an order
5709
- * @description Moves a NEW order to PROCESSING, triggering its workflow. Exchange orders
5710
- * (EXCHANGE_OMNI) and internal transfers (TRANSFER_INTERNAL /
5711
- * OMNIBUS_INTERNAL_TRANSFER) settle synchronously and land in COMPLETE.
5712
- * Validates the order's request_id via OTP.
6043
+ * @description Moves a NEW order to PROCESSING: checks the balance, debits the funds
6044
+ * (transaction written as `complete`) and triggers its workflow.
6045
+ * Exchange orders (EXCHANGE_OMNI) and internal transfers
6046
+ * (TRANSFER_INTERNAL / OMNIBUS_INTERNAL_TRANSFER) settle synchronously
6047
+ * and land in COMPLETE. An insufficient balance fails the order
6048
+ * (FAILED). OTP verification is mandatory and keyed on the order id
6049
+ * (request the OTP for the order being approved).
5713
6050
  *
5714
6051
  */
5715
6052
  post: {
@@ -5771,7 +6108,7 @@ export interface paths {
5771
6108
  put?: never;
5772
6109
  /**
5773
6110
  * Cancel an order
5774
- * @description Cancels a NEW/FAILED order, cancels its workflow run, and refunds the blocked funds.
6111
+ * @description Cancels a NEW/FAILED order, cancels its workflow run, and refunds the debited funds (if the order was ever approved).
5775
6112
  */
5776
6113
  post: {
5777
6114
  parameters: {
@@ -5792,7 +6129,7 @@ export interface paths {
5792
6129
  };
5793
6130
  };
5794
6131
  responses: {
5795
- /** @description Order canceled and funds refunded */
6132
+ /** @description Order canceled (debited funds refunded when applicable) */
5796
6133
  200: {
5797
6134
  headers: {
5798
6135
  [name: string]: unknown;
@@ -8093,6 +8430,16 @@ export interface paths {
8093
8430
  * @example true
8094
8431
  */
8095
8432
  empty_name?: boolean;
8433
+ /**
8434
+ * Format: uuid
8435
+ * @description Optional KYC entity to link (entity-first KYC model). Must be
8436
+ * an entity of the current user (`GET /kyc/entities`); its type
8437
+ * must be enabled for the tenant. The link is set once at
8438
+ * creation and is immutable. Omitted → wallet is created
8439
+ * without a linked entity (legacy behaviour).
8440
+ *
8441
+ */
8442
+ kyc_entity_id?: string;
8096
8443
  };
8097
8444
  };
8098
8445
  };
@@ -8141,14 +8488,14 @@ export interface paths {
8141
8488
  };
8142
8489
  };
8143
8490
  };
8144
- /** @description Bad request - invalid type */
8491
+ /** @description Bad request invalid name, or `kyc_entity_id` is malformed / not an entity of the current user / belongs to another tenant */
8145
8492
  400: {
8146
8493
  headers: {
8147
8494
  [name: string]: unknown;
8148
8495
  };
8149
8496
  content?: never;
8150
8497
  };
8151
- /** @description Forbidden - no permission to create wallets */
8498
+ /** @description Forbidden no permission to create wallets, or the entity type is not enabled for the tenant */
8152
8499
  403: {
8153
8500
  headers: {
8154
8501
  [name: string]: unknown;
@@ -9872,6 +10219,8 @@ export interface paths {
9872
10219
  * - Cannot invite yourself
9873
10220
  * - Cannot invite a current owner of this wallet
9874
10221
  * - Cannot invite a user who is already a member (active or deactivated)
10222
+ * - When the tenant has KYC enabled, the wallet's entity must be `APPROVED`;
10223
+ * otherwise the invite is rejected with 403 `KYC_REQUIREMENTS_NOT_MET`
9875
10224
  *
9876
10225
  * **Authentication**: Bearer token with x-tenant-id header required
9877
10226
  *
@@ -9925,7 +10274,7 @@ export interface paths {
9925
10274
  };
9926
10275
  content?: never;
9927
10276
  };
9928
- /** @description Access denied (insufficient wallet role) */
10277
+ /** @description Access denied (insufficient wallet role) or KYC not approved for the wallet entity */
9929
10278
  403: {
9930
10279
  headers: {
9931
10280
  [name: string]: unknown;
@@ -10231,6 +10580,12 @@ export interface components {
10231
10580
  memo?: string | null;
10232
10581
  /** Format: uuid */
10233
10582
  currency_id?: string;
10583
+ /**
10584
+ * @description Hosting classification of the address. Defaults to unknown.
10585
+ * @default unknown
10586
+ * @enum {string}
10587
+ */
10588
+ wallet_custody_type: "custodial" | "selfhosted" | "unknown";
10234
10589
  currency: components["schemas"]["CounterpartyCurrencyRef"];
10235
10590
  /** Format: date-time */
10236
10591
  created_at: string;
@@ -10274,6 +10629,60 @@ export interface components {
10274
10629
  */
10275
10630
  target_wallet_id: string | null;
10276
10631
  };
10632
+ /** @description Bank postal address resolved from the bank identifier. Intentionally mirrors the CounterpartyBankingAddress shape so the payload can prefill a counterparty form as-is. */
10633
+ BankDataAddress: {
10634
+ /** @description Resolved `countries.id` of the bank’s country; null when it could not be resolved */
10635
+ country_id: number | null;
10636
+ /** @description Always null today (reserved for future enrichment) */
10637
+ state_id: number | null;
10638
+ city: string | null;
10639
+ postcode: string | null;
10640
+ /** @description Bank street address line */
10641
+ street1: string | null;
10642
+ /** @description Always null today (reserved) */
10643
+ street2: string | null;
10644
+ /** @description Always null today (reserved) */
10645
+ description: string | null;
10646
+ };
10647
+ /**
10648
+ * @description Normalised bank data resolved from a bank identifier. Which identifier fields are populated depends on the looked-up code type: IBAN → `iban` + `swift_bic` (plus `account_number`/`sort_code` for GB IBANs), SWIFT/BIC → `swift_bic`, US RTN → `routing_number`; identifier fields not applicable to the code type are null. `bank_name` and `address` are populated for every code type whenever they are available.
10649
+ * @example {
10650
+ * "account_number": "31926819",
10651
+ * "bank_name": "NATIONAL WESTMINSTER BANK PLC",
10652
+ * "note": null,
10653
+ * "routing_number": null,
10654
+ * "swift_bic": "NWBKGB2LXXX",
10655
+ * "iban": "GB29NWBK60161331926819",
10656
+ * "sort_code": "601613",
10657
+ * "address": {
10658
+ * "country_id": 230,
10659
+ * "state_id": null,
10660
+ * "city": "London",
10661
+ * "postcode": null,
10662
+ * "street1": null,
10663
+ * "street2": null,
10664
+ * "description": null
10665
+ * }
10666
+ * }
10667
+ */
10668
+ BankData: {
10669
+ /** @description Populated only for GB IBANs (22 chars): the embedded 8-digit account number (IBAN positions 14-22); null otherwise */
10670
+ account_number: string | null;
10671
+ /** @description Registered bank name; null when unavailable */
10672
+ bank_name: string | null;
10673
+ /** @description Always null today (reserved) */
10674
+ note: string | null;
10675
+ /** @description Populated only when the looked-up code is a US routing number (echoes the RTN); null otherwise */
10676
+ routing_number: string | null;
10677
+ /** @description SWIFT/BIC (ISO 9362); populated for SWIFT lookups and for IBAN lookups when the IBAN resolves to a BIC */
10678
+ swift_bic: string | null;
10679
+ /** @description Populated only for IBAN lookups (the normalised IBAN itself) */
10680
+ iban: string | null;
10681
+ /** @description Populated only for GB IBANs: the embedded 6-digit sort code (IBAN positions 8-14); null otherwise */
10682
+ sort_code: string | null;
10683
+ /** @description Bank postal address (always present) */
10684
+ address: components["schemas"]["BankDataAddress"];
10685
+ };
10277
10686
  /** @description Bank / rail account coordinates for a sub-account. Rail-dependent — some rails return only a subset of these. */
10278
10687
  BankAccountDetails: {
10279
10688
  swift?: string;
@@ -10734,7 +11143,7 @@ export interface components {
10734
11143
  };
10735
11144
  /** @description Public order metadata fields */
10736
11145
  OrderMeta: {
10737
- /** @description Idempotency key passed at creation time */
11146
+ /** @description Legacy idempotency key null on orders created by the current flow */
10738
11147
  request_id?: string | null;
10739
11148
  note?: string | null;
10740
11149
  reference?: string | null;
@@ -10804,8 +11213,6 @@ export interface components {
10804
11213
  counterparty_destination_id: string;
10805
11214
  /** Format: uuid */
10806
11215
  wallet_account_id?: string;
10807
- /** @description Idempotency key (UUID) */
10808
- request_id: string;
10809
11216
  reference?: string;
10810
11217
  note?: string;
10811
11218
  /** @description Optional supporting documents persisted with the order. */
@@ -10826,8 +11233,6 @@ export interface components {
10826
11233
  virtual_account_id: string;
10827
11234
  /** Format: uuid */
10828
11235
  counterparty_destination_id: string;
10829
- /** @description Idempotency key (UUID) */
10830
- request_id: string;
10831
11236
  reference?: string;
10832
11237
  note?: string;
10833
11238
  /** @description Optional supporting documents persisted with the order. */
@@ -10848,11 +11253,6 @@ export interface components {
10848
11253
  * @description Destination currency UUID
10849
11254
  */
10850
11255
  to_currency_id: string;
10851
- /**
10852
- * Format: uuid
10853
- * @description Idempotency key (UUID); OTP-verified at approve
10854
- */
10855
- request_id: string;
10856
11256
  };
10857
11257
  /** @description Wallet invitation record */
10858
11258
  WalletInvite: {
@@ -29,6 +29,8 @@ export type UseOrderCalcProps = {
29
29
  calcHandler: (props: OrderCalcHandlerProps) => Promise<CalcResult>;
30
30
  disableCalculation?: boolean;
31
31
  to_address?: string;
32
+ minSellAmount?: number | null;
33
+ maxSellAmount?: number | null;
32
34
  };
33
35
  export type UseOrderCalcData = {
34
36
  calcData: CalcData | null;
@@ -1,6 +1,6 @@
1
1
  import debounce from 'lodash.debounce';
2
2
  import { useEffect, useRef, useState } from 'react';
3
- export const useOrderCalc = ({ from_currency_id, to_currency_id, calcHandler, disableCalculation, to_address, }) => {
3
+ export const useOrderCalc = ({ from_currency_id, to_currency_id, calcHandler, disableCalculation, to_address, minSellAmount, maxSellAmount, }) => {
4
4
  const [sellingAmount, setSellingAmount] = useState(0);
5
5
  const [buyingAmount, setBuyingAmount] = useState(0);
6
6
  const [calcData, setCalcData] = useState(null);
@@ -44,6 +44,15 @@ export const useOrderCalc = ({ from_currency_id, to_currency_id, calcHandler, di
44
44
  resetOrderCalc();
45
45
  return;
46
46
  }
47
+ // Skip the backend calc for a sell amount outside the allowed range: returning before the request (and
48
+ // before the pending flag is set) means no error is thrown, so no error toast reaches the user. Forward
49
+ // direction only — a reverse edit derives the sell amount server-side. calcData is left untouched so the
50
+ // caller's stale-guard still blocks submit until a valid amount.
51
+ if (!is_reverse &&
52
+ ((minSellAmount != null && calcParams.amount < minSellAmount) ||
53
+ (maxSellAmount != null && calcParams.amount > maxSellAmount))) {
54
+ return;
55
+ }
47
56
  try {
48
57
  is_reverse ? setIsSellingValuePending(true) : setIsBuyingValuePending(true);
49
58
  const data = await calcHandler(calcParams);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "squarefi-bff-api-module",
3
- "version": "1.36.29",
3
+ "version": "1.36.31",
4
4
  "description": "Squarefi BFF API client module",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",