@pollar/react 0.11.4-rc.1 → 0.11.4-rc.4

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/dist/index.mjs CHANGED
@@ -1036,7 +1036,7 @@ var PollarModalFooter = ({ shield = false }) => {
1036
1036
  /* @__PURE__ */ jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
1037
1037
  /* @__PURE__ */ jsxs("span", { className: "pollar-footer-version", children: [
1038
1038
  "v",
1039
- "0.11.4-rc.1"
1039
+ "0.11.4-rc.4"
1040
1040
  ] })
1041
1041
  ] })
1042
1042
  ] });
@@ -2077,7 +2077,8 @@ function KycModalTemplate({
2077
2077
  kycStatus !== "approved" && kycStatus !== "rejected" && kycStatus !== "expired" && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onDoneVerifying, children: "Check again" }),
2078
2078
  /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: onClose, children: "Close" })
2079
2079
  ] })
2080
- ] })
2080
+ ] }),
2081
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
2081
2082
  ]
2082
2083
  }
2083
2084
  );
@@ -2087,7 +2088,15 @@ function newIdempotencyKey() {
2087
2088
  if (c && typeof c.randomUUID === "function") return c.randomUUID();
2088
2089
  return `kyc-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
2089
2090
  }
2090
- function KycModal({ onClose, country = "MX", level = "basic", onApproved, corridorId, providerId }) {
2091
+ function KycModal({
2092
+ onClose,
2093
+ country = "MX",
2094
+ level = "basic",
2095
+ onApproved,
2096
+ corridorId,
2097
+ cardProviderId,
2098
+ providerId
2099
+ }) {
2091
2100
  const { getClient, styles } = usePollar();
2092
2101
  const [step, setStep] = useState("select_provider");
2093
2102
  const [providers, setProviders] = useState([]);
@@ -2115,7 +2124,7 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved, corrid
2115
2124
  else finish(read.decisionStatus === "expired" ? "expired" : read.status);
2116
2125
  }
2117
2126
  function readStatus(providerId2) {
2118
- return corridorId ? client.getKycStatus(void 0, corridorId) : client.getKycStatus(providerId2);
2127
+ return corridorId || cardProviderId ? client.getKycStatus(void 0, corridorId, cardProviderId) : client.getKycStatus(providerId2);
2119
2128
  }
2120
2129
  const starting = useRef(false);
2121
2130
  async function handleSelectProvider(provider, listed = true) {
@@ -2132,7 +2141,8 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved, corrid
2132
2141
  provider.levels?.[0] ?? level,
2133
2142
  listed ? country : void 0,
2134
2143
  corridorId,
2135
- key
2144
+ key,
2145
+ cardProviderId
2136
2146
  );
2137
2147
  if (result.alreadyApproved) {
2138
2148
  finish("approved");
@@ -2161,7 +2171,7 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved, corrid
2161
2171
  const loadProviders = useCallback(() => {
2162
2172
  setIsLoading(true);
2163
2173
  setError(null);
2164
- return getClient().getKycProviders(country, corridorId).then((result) => {
2174
+ return getClient().getKycProviders(country, corridorId, cardProviderId).then((result) => {
2165
2175
  setProviders(result.providers);
2166
2176
  return result.providers;
2167
2177
  }).catch((e) => {
@@ -2169,7 +2179,7 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved, corrid
2169
2179
  setError(kycErrorMessage(e, "load"));
2170
2180
  return [];
2171
2181
  }).finally(() => setIsLoading(false));
2172
- }, [getClient, country, corridorId]);
2182
+ }, [getClient, country, corridorId, cardProviderId]);
2173
2183
  useEffect(() => {
2174
2184
  void loadProviders().then((list) => {
2175
2185
  if (!providerId || autoOpened.current) return;
@@ -2191,7 +2201,8 @@ function KycModal({ onClose, country = "MX", level = "basic", onApproved, corrid
2191
2201
  const read = await client.pollKycDecision(selectedProvider.id, {
2192
2202
  intervalMs: 3e3,
2193
2203
  timeoutMs: 12e4,
2194
- ...corridorId ? { corridorId } : {}
2204
+ ...corridorId ? { corridorId } : {},
2205
+ ...cardProviderId ? { cardProviderId } : {}
2195
2206
  });
2196
2207
  finishWith(read);
2197
2208
  } catch {
@@ -2513,7 +2524,8 @@ function RequirementFormModal({ formId, progress, onClose, onSubmitted }) {
2513
2524
  ] })
2514
2525
  ]
2515
2526
  }
2516
- )
2527
+ ),
2528
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
2517
2529
  ]
2518
2530
  }
2519
2531
  ) });
@@ -3890,7 +3902,8 @@ function RampWidgetTemplate({
3890
3902
  /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Close" }),
3891
3903
  /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: onRetry, children: "Try again" })
3892
3904
  ] })
3893
- ] })
3905
+ ] }),
3906
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
3894
3907
  ] });
3895
3908
  }
3896
3909
 
@@ -3913,6 +3926,7 @@ var REGISTRY_COPY = {
3913
3926
  notApplicable: "This check is only for Bolivian ID cards (CI). Your verified document is not one, so this route is not available.",
3914
3927
  identityRequired: "Verify your identity first.",
3915
3928
  nameMismatch: "Both surnames together must read as on your document: {full}.",
3929
+ rejected: "The registry did not confirm: {fields}. Check how they are written and try again.",
3916
3930
  loadError: "Could not load your details. Please try again.",
3917
3931
  submitError: "Could not check your details. Please try again.",
3918
3932
  step: "Step {n} of {total}"
@@ -3934,6 +3948,7 @@ var REGISTRY_COPY = {
3934
3948
  notApplicable: "Esta validaci\xF3n es solo para c\xE9dulas bolivianas (CI). Tu documento verificado no lo es, as\xED que esta ruta no est\xE1 disponible.",
3935
3949
  identityRequired: "Primero verifica tu identidad.",
3936
3950
  nameMismatch: "Los dos apellidos juntos deben leerse como en tu documento: {full}.",
3951
+ rejected: "El registro no confirm\xF3: {fields}. Revisa c\xF3mo est\xE1n escritos e intenta de nuevo.",
3937
3952
  loadError: "No se pudieron cargar tus datos. Intenta de nuevo.",
3938
3953
  submitError: "No se pudieron validar tus datos. Intenta de nuevo.",
3939
3954
  step: "Paso {n} de {total}"
@@ -3949,9 +3964,15 @@ var REGISTRATION_COPY = {
3949
3964
  close: "Close",
3950
3965
  notReady: "Complete the previous steps first.",
3951
3966
  missing: "Some details are missing: {fields}.",
3967
+ invalid: "Some details need to be corrected: {fields}.",
3968
+ fix: "Review my details",
3969
+ incomplete: "Your registration with the provider did not finish. Register again to complete it.",
3970
+ providerDown: "The provider is not responding right now. Please try again in a few minutes.",
3971
+ ipNotSupported: "The provider cannot accept your current connection (IPv6). Please try again from another network, for example Wi-Fi.",
3952
3972
  loadError: "Could not load the registration. Please try again.",
3953
3973
  submitError: "Could not register you. Please try again.",
3954
- step: "Step {n} of {total}"
3974
+ step: "Step {n} of {total}",
3975
+ terms: "Read the provider's terms of service"
3955
3976
  },
3956
3977
  es: {
3957
3978
  title: "Registro con el proveedor de pagos",
@@ -3962,9 +3983,15 @@ var REGISTRATION_COPY = {
3962
3983
  close: "Cerrar",
3963
3984
  notReady: "Primero completa los pasos anteriores.",
3964
3985
  missing: "Faltan algunos datos: {fields}.",
3986
+ invalid: "Hay datos que corregir: {fields}.",
3987
+ fix: "Revisar mis datos",
3988
+ incomplete: "Tu registro con el proveedor no se complet\xF3. Reg\xEDstrate de nuevo para terminarlo.",
3989
+ providerDown: "El proveedor no responde en este momento. Intenta de nuevo en unos minutos.",
3990
+ ipNotSupported: "El proveedor no acepta tu conexi\xF3n actual (IPv6). Intenta desde otra red, por ejemplo Wi-Fi.",
3965
3991
  loadError: "No se pudo cargar el registro. Intenta de nuevo.",
3966
3992
  submitError: "No se pudo completar el registro. Intenta de nuevo.",
3967
- step: "Paso {n} de {total}"
3993
+ step: "Paso {n} de {total}",
3994
+ terms: "Leer los t\xE9rminos de servicio del proveedor"
3968
3995
  }
3969
3996
  };
3970
3997
  var SHARED_FIELD_LABELS = {
@@ -3979,7 +4006,24 @@ var SHARED_FIELD_LABELS = {
3979
4006
  source_of_funds: "Source of funds",
3980
4007
  destination_of_funds: "Use of funds",
3981
4008
  income_level: "Income level",
3982
- doc_provider_id: "SEGIP validation"
4009
+ doc_provider_id: "SEGIP validation",
4010
+ first_name: "First name",
4011
+ last_name: "Last name",
4012
+ email: "Email",
4013
+ birth_date: "Date of birth",
4014
+ document_country: "Document country",
4015
+ phone_country_code: "Phone country code",
4016
+ phone_number: "Phone number",
4017
+ occupation: "Occupation",
4018
+ annual_salary: "Annual income",
4019
+ account_purpose: "Purpose of the card",
4020
+ expected_monthly_volume: "Expected monthly spend",
4021
+ address_line1: "Street address",
4022
+ address_line2: "Address line 2",
4023
+ city: "City",
4024
+ region: "State or province",
4025
+ postal_code: "Postal code",
4026
+ country_code: "Country of residence"
3983
4027
  },
3984
4028
  es: {
3985
4029
  name: "Nombres",
@@ -3992,7 +4036,24 @@ var SHARED_FIELD_LABELS = {
3992
4036
  source_of_funds: "Origen de los fondos",
3993
4037
  destination_of_funds: "Destino de los fondos",
3994
4038
  income_level: "Nivel de ingresos",
3995
- doc_provider_id: "Validaci\xF3n SEGIP"
4039
+ doc_provider_id: "Validaci\xF3n SEGIP",
4040
+ first_name: "Nombres",
4041
+ last_name: "Apellidos",
4042
+ email: "Correo electr\xF3nico",
4043
+ birth_date: "Fecha de nacimiento",
4044
+ document_country: "Pa\xEDs del documento",
4045
+ phone_country_code: "C\xF3digo de pa\xEDs del tel\xE9fono",
4046
+ phone_number: "Tel\xE9fono",
4047
+ occupation: "Ocupaci\xF3n",
4048
+ annual_salary: "Ingreso anual",
4049
+ account_purpose: "Uso de la tarjeta",
4050
+ expected_monthly_volume: "Gasto mensual esperado",
4051
+ address_line1: "Direcci\xF3n",
4052
+ address_line2: "Direcci\xF3n (l\xEDnea 2)",
4053
+ city: "Ciudad",
4054
+ region: "Estado o provincia",
4055
+ postal_code: "C\xF3digo postal",
4056
+ country_code: "Pa\xEDs de residencia"
3996
4057
  }
3997
4058
  };
3998
4059
  var errorCode = (error) => error && typeof error === "object" && typeof error.code === "string" ? error.code : null;
@@ -4000,6 +4061,15 @@ function missingFieldsOf(error) {
4000
4061
  const body = error && typeof error === "object" ? error.body : void 0;
4001
4062
  return Array.isArray(body?.missing) ? body.missing.filter((item) => typeof item === "string") : [];
4002
4063
  }
4064
+ function registrationFixOf(error) {
4065
+ const body = error && typeof error === "object" ? error.body : void 0;
4066
+ const strings = (value) => Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
4067
+ const forms = Array.isArray(body?.forms) ? body.forms.flatMap((item) => {
4068
+ const form = item && typeof item === "object" ? item : {};
4069
+ return typeof form.formId === "string" ? [{ formId: form.formId, keys: strings(form.keys) }] : [];
4070
+ }) : [];
4071
+ return { invalid: strings(body?.invalid), forms };
4072
+ }
4003
4073
  function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4004
4074
  const { getClient, styles } = usePollar();
4005
4075
  const client = getClient();
@@ -4012,6 +4082,7 @@ function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4012
4082
  const [surname2, setSurname2] = useState("");
4013
4083
  const [complement, setComplement] = useState("");
4014
4084
  const [error, setError] = useState(null);
4085
+ const [rejected, setRejected] = useState([]);
4015
4086
  const [review, setReview] = useState(false);
4016
4087
  const [submitting, setSubmitting] = useState(false);
4017
4088
  const mounted = useRef(true);
@@ -4027,6 +4098,7 @@ function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4027
4098
  if (loaded.status === "approved") return onApproved();
4028
4099
  setCheck(loaded);
4029
4100
  if (loaded.status === "pending") setReview(true);
4101
+ if (loaded.status === "rejected") showRejected(loaded.rejectedFields);
4030
4102
  if (loaded.prefill.applies) {
4031
4103
  setSurname1(loaded.prefill.surname1);
4032
4104
  setSurname2(loaded.prefill.surname2 ?? "");
@@ -4038,10 +4110,21 @@ function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4038
4110
  });
4039
4111
  }, [optionId]);
4040
4112
  const prefill = check?.prefill.applies ? check.prefill : null;
4113
+ function showRejected(fields) {
4114
+ const labels = {
4115
+ surname1: copy.surname1,
4116
+ surname2: copy.surname2,
4117
+ complementNumber: copy.complement
4118
+ };
4119
+ const named = fields?.length ? fields : ["surname2"];
4120
+ setRejected(named);
4121
+ setError(copy.rejected.replace("{fields}", named.map((field) => labels[field] ?? field).join(", ")));
4122
+ }
4041
4123
  async function submit() {
4042
4124
  if (!prefill) return;
4043
4125
  setSubmitting(true);
4044
4126
  setError(null);
4127
+ setRejected([]);
4045
4128
  try {
4046
4129
  const result = await client.submitRegistryCheck(optionId, {
4047
4130
  surname1: surname1.trim(),
@@ -4050,6 +4133,7 @@ function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4050
4133
  });
4051
4134
  if (!mounted.current) return;
4052
4135
  if (result.status === "approved") onApproved();
4136
+ else if (result.status === "rejected") showRejected(result.rejectedFields);
4053
4137
  else setReview(true);
4054
4138
  } catch (e) {
4055
4139
  if (!mounted.current) return;
@@ -4114,6 +4198,7 @@ function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4114
4198
  value: surname1,
4115
4199
  required: true,
4116
4200
  disabled: submitting,
4201
+ "aria-invalid": rejected.includes("surname1") || void 0,
4117
4202
  onChange: (e) => setSurname1(e.target.value)
4118
4203
  }
4119
4204
  )
@@ -4127,6 +4212,7 @@ function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4127
4212
  className: "pollar-input",
4128
4213
  value: surname2,
4129
4214
  disabled: submitting,
4215
+ "aria-invalid": rejected.includes("surname2") || void 0,
4130
4216
  onChange: (e) => setSurname2(e.target.value)
4131
4217
  }
4132
4218
  )
@@ -4143,6 +4229,7 @@ function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4143
4229
  value: complement,
4144
4230
  maxLength: 3,
4145
4231
  disabled: submitting,
4232
+ "aria-invalid": rejected.includes("complementNumber") || void 0,
4146
4233
  onChange: (e) => setComplement(e.target.value.toUpperCase().replace(/[^0-9A-Z]/g, ""))
4147
4234
  }
4148
4235
  )
@@ -4153,12 +4240,19 @@ function RegistryCheckModal({ optionId, progress, onClose, onApproved }) {
4153
4240
  ] })
4154
4241
  ]
4155
4242
  }
4156
- )
4243
+ ),
4244
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
4157
4245
  ]
4158
4246
  }
4159
4247
  ) });
4160
4248
  }
4161
- function ProviderRegistrationModal({ corridorId, progress, onClose, onRegistered }) {
4249
+ function ProviderRegistrationModal({
4250
+ corridorId,
4251
+ cardProviderId,
4252
+ progress,
4253
+ onClose,
4254
+ onRegistered
4255
+ }) {
4162
4256
  const { getClient, styles } = usePollar();
4163
4257
  const client = getClient();
4164
4258
  const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
@@ -4167,9 +4261,12 @@ function ProviderRegistrationModal({ corridorId, progress, onClose, onRegistered
4167
4261
  const copy = REGISTRATION_COPY[language];
4168
4262
  const labels = SHARED_FIELD_LABELS[language];
4169
4263
  const [registration, setRegistration] = useState(null);
4264
+ const [termsUrl, setTermsUrl] = useState(null);
4170
4265
  const [consent, setConsent] = useState(false);
4171
4266
  const [error, setError] = useState(null);
4172
4267
  const [submitting, setSubmitting] = useState(false);
4268
+ const [fixForm, setFixForm] = useState(null);
4269
+ const [fixing, setFixing] = useState(null);
4173
4270
  const mounted = useRef(true);
4174
4271
  useEffect(() => {
4175
4272
  mounted.current = true;
@@ -4178,34 +4275,59 @@ function ProviderRegistrationModal({ corridorId, progress, onClose, onRegistered
4178
4275
  };
4179
4276
  }, []);
4180
4277
  useEffect(() => {
4181
- client.getProviderRegistration(corridorId).then((loaded) => {
4278
+ const load = cardProviderId ? client.getCardProviderRegistration(cardProviderId).then((loaded) => {
4279
+ setTermsUrl(loaded.termsUrl);
4280
+ return loaded;
4281
+ }) : client.getProviderRegistration(corridorId ?? "");
4282
+ load.then((loaded) => {
4182
4283
  if (!mounted.current) return;
4183
4284
  if (loaded.status === "registered") onRegistered();
4184
4285
  else setRegistration(loaded);
4185
4286
  }).catch(() => mounted.current && setError(copy.loadError));
4186
- }, [corridorId]);
4287
+ }, [corridorId, cardProviderId]);
4187
4288
  async function submit() {
4188
4289
  setSubmitting(true);
4189
4290
  setError(null);
4291
+ setFixForm(null);
4190
4292
  try {
4191
- await client.submitProviderRegistration(corridorId);
4293
+ if (cardProviderId) await client.submitCardProviderRegistration(cardProviderId);
4294
+ else await client.submitProviderRegistration(corridorId ?? "");
4192
4295
  if (mounted.current) onRegistered();
4193
4296
  } catch (e) {
4194
4297
  if (!mounted.current) return;
4195
4298
  const code = errorCode(e);
4196
4299
  if (code === "KYC_REGISTRATION_MISSING_DATA") {
4300
+ const fix = registrationFixOf(e);
4301
+ const named = (keys) => keys.map((key) => labels[key] ?? key).join(", ");
4302
+ const missing = missingFieldsOf(e).filter((key) => !fix.invalid.includes(key));
4197
4303
  setError(
4198
- copy.missing.replace(
4199
- "{fields}",
4200
- missingFieldsOf(e).map((key) => labels[key] ?? key).join(", ")
4201
- )
4304
+ [
4305
+ fix.invalid.length ? copy.invalid.replace("{fields}", named(fix.invalid)) : null,
4306
+ missing.length ? copy.missing.replace("{fields}", named(missing)) : null
4307
+ ].filter(Boolean).join(" ")
4202
4308
  );
4309
+ setFixForm(fix.forms[0]?.formId ?? null);
4203
4310
  } else if (code === "KYC_REGISTRATION_STEPS_PENDING") setError(copy.notReady);
4311
+ else if (code === "SDK_CARDS_PROVIDER_ERROR") setError(copy.providerDown);
4312
+ else if (code === "SDK_CARDS_IP_NOT_SUPPORTED") setError(copy.ipNotSupported);
4204
4313
  else setError(copy.submitError);
4205
4314
  } finally {
4206
4315
  if (mounted.current) setSubmitting(false);
4207
4316
  }
4208
4317
  }
4318
+ if (fixing) {
4319
+ return /* @__PURE__ */ jsx(
4320
+ RequirementFormModal,
4321
+ {
4322
+ formId: fixing,
4323
+ onClose: () => setFixing(null),
4324
+ onSubmitted: () => {
4325
+ setFixing(null);
4326
+ void submit();
4327
+ }
4328
+ }
4329
+ );
4330
+ }
4209
4331
  return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxs(
4210
4332
  "div",
4211
4333
  {
@@ -4224,6 +4346,7 @@ function ProviderRegistrationModal({ corridorId, progress, onClose, onRegistered
4224
4346
  /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": copy.close, children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
4225
4347
  ] }),
4226
4348
  error && /* @__PURE__ */ jsx("p", { className: "pollar-form-error", role: "alert", children: error }),
4349
+ fixForm && !submitting && /* @__PURE__ */ jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: () => setFixing(fixForm), children: copy.fix }) }),
4227
4350
  !registration && !error && /* @__PURE__ */ jsx("div", { className: "pollar-loading-block", children: /* @__PURE__ */ jsx("div", { className: "pollar-spinner" }) }),
4228
4351
  registration && /* @__PURE__ */ jsxs(
4229
4352
  "form",
@@ -4235,8 +4358,10 @@ function ProviderRegistrationModal({ corridorId, progress, onClose, onRegistered
4235
4358
  },
4236
4359
  children: [
4237
4360
  registration.ready ? /* @__PURE__ */ jsxs(Fragment, { children: [
4361
+ registration.status === "incomplete" && /* @__PURE__ */ jsx("p", { className: "pollar-form-error", role: "status", children: copy.incomplete }),
4238
4362
  /* @__PURE__ */ jsx("p", { className: "pollar-form-description", children: copy.intro }),
4239
4363
  /* @__PURE__ */ jsx("ul", { className: "pollar-form-description", children: registration.fields.map((key) => /* @__PURE__ */ jsx("li", { children: labels[key] ?? key }, key)) }),
4364
+ termsUrl && /* @__PURE__ */ jsx("p", { className: "pollar-form-description", children: /* @__PURE__ */ jsx("a", { href: termsUrl, target: "_blank", rel: "noreferrer", children: copy.terms }) }),
4240
4365
  /* @__PURE__ */ jsxs("label", { className: "pollar-form-choice", children: [
4241
4366
  /* @__PURE__ */ jsx(
4242
4367
  "input",
@@ -4256,7 +4381,8 @@ function ProviderRegistrationModal({ corridorId, progress, onClose, onRegistered
4256
4381
  ] })
4257
4382
  ]
4258
4383
  }
4259
- )
4384
+ ),
4385
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
4260
4386
  ]
4261
4387
  }
4262
4388
  ) });
@@ -6767,6 +6893,781 @@ function EarnModal({ onClose }) {
6767
6893
  }
6768
6894
  ) });
6769
6895
  }
6896
+
6897
+ // src/components/card-modal/card-kyc.ts
6898
+ var nonEmpty2 = (value) => typeof value === "string" && !!value.trim();
6899
+ function requiredCardStep(error) {
6900
+ if (!error || typeof error !== "object") return null;
6901
+ const { code, body } = error;
6902
+ if (code !== "SDK_CARDS_REQUIREMENT_REQUIRED" || !body || typeof body !== "object") return null;
6903
+ const { cardProviderId, requirementType, optionId } = body;
6904
+ if (!nonEmpty2(cardProviderId) || !nonEmpty2(optionId)) return null;
6905
+ if (requirementType === "KYC" || requirementType === "FORM" || requirementType === "REGISTRY_CHECK" || requirementType === "PROVIDER_REGISTRATION") {
6906
+ return { cardProviderId, type: requirementType, optionId };
6907
+ }
6908
+ return null;
6909
+ }
6910
+ function pendingFromRequirement(cardProviderId, next) {
6911
+ return {
6912
+ cardProviderId,
6913
+ type: next.type,
6914
+ optionId: next.optionId,
6915
+ progress: { position: next.completed + 1, total: next.total }
6916
+ };
6917
+ }
6918
+ function blockedStepMessage(next) {
6919
+ if (next.type === "REGISTRY_CHECK" && next.status === "pending") return "Your details are under review.";
6920
+ if (next.type !== "KYC") return null;
6921
+ if (next.status === "pending" && next.reviewReason) return "Your verification is under review.";
6922
+ if (next.status === "rejected") return "Your verification was not approved.";
6923
+ return null;
6924
+ }
6925
+ function cardStage(holder, requirements) {
6926
+ if (holder === void 0 || requirements === void 0) return null;
6927
+ if (holder === null || holder.kycStatus === "NOT_STARTED" && requirements?.next) return "steps";
6928
+ if (holder.kycStatus !== "NOT_STARTED") return null;
6929
+ return requirements?.steps.some((step) => step.type === "PROVIDER_REGISTRATION") ? "steps" : "provider-form";
6930
+ }
6931
+ var KYC_POLL_MS = 5e3;
6932
+ var REVEAL_MS = 3e4;
6933
+ var TX_LIMIT = 10;
6934
+ var FUNDING_POLL_MS = 5e3;
6935
+ var FUNDING_INFLIGHT = /* @__PURE__ */ new Set(["CREATED", "BURNED", "ATTESTED", "MINTED"]);
6936
+ var FUNDING_COPY = {
6937
+ CREATED: {
6938
+ title: "Confirming your payment",
6939
+ step: 1,
6940
+ hint: "Your USDC payment is being confirmed on Stellar. This takes a few seconds."
6941
+ },
6942
+ BURNED: {
6943
+ title: "Sending it to the card network",
6944
+ step: 2,
6945
+ hint: "Your USDC left Stellar. Circle is confirming the transfer, usually in about a minute."
6946
+ },
6947
+ ATTESTED: {
6948
+ title: "Crossing to the card network",
6949
+ step: 3,
6950
+ hint: "Transfer confirmed. Delivering the USDC to the card network."
6951
+ },
6952
+ MINTED: {
6953
+ title: "Arrived, crediting your card",
6954
+ step: 4,
6955
+ hint: "The USDC reached the card provider, which is adding it to your card. This can take a few minutes."
6956
+ },
6957
+ CREDITED: { title: "Credited to your card" },
6958
+ FAILED: { title: "Failed" }
6959
+ };
6960
+ var FUNDING_STEPS = 4;
6961
+ var INCOME_RANGES = [
6962
+ { value: "0-1000", label: "Up to 1,000 USD" },
6963
+ { value: "1000-5000", label: "1,000 to 5,000 USD" },
6964
+ { value: "5000-10000", label: "5,000 to 10,000 USD" },
6965
+ { value: "10000+", label: "More than 10,000 USD" }
6966
+ ];
6967
+ var TX_LABELS = {
6968
+ deposit: "Deposit",
6969
+ transactionTransfer: "Bank deposit",
6970
+ spend: "Purchase",
6971
+ spend_adjustment: "Adjustment",
6972
+ fee: "Fee",
6973
+ fee_refund: "Fee refund",
6974
+ withdrawal: "Withdrawal",
6975
+ card_insurance: "Card issuance"
6976
+ };
6977
+ var KYC_PENDING_COPY = {
6978
+ PENDING: "Your information is being reviewed.",
6979
+ NEEDS_ACTION: "Finish verifying your identity with the card provider: you will be asked for a photo of your document and a selfie.",
6980
+ IN_REVIEW: "Your verification is under manual review. This can take a while."
6981
+ };
6982
+ var KYC_FINAL_COPY = {
6983
+ DENIED: "Your verification was denied.",
6984
+ LOCKED: "Your account is locked.",
6985
+ CANCELED: "Your verification was canceled."
6986
+ };
6987
+ var emptyKyc = {
6988
+ firstName: "",
6989
+ lastName: "",
6990
+ birthDate: "",
6991
+ nationalId: "",
6992
+ countryOfIssue: "",
6993
+ phoneCountryCode: "",
6994
+ phoneNumber: "",
6995
+ occupation: "",
6996
+ annualSalary: "1000-5000",
6997
+ accountPurpose: "Personal expenses",
6998
+ expectedMonthlyVolume: "1000-5000",
6999
+ address: { line1: "", line2: "", city: "", region: "", postalCode: "", countryCode: "" }
7000
+ };
7001
+ function usd(cents) {
7002
+ if (cents === null || cents === void 0) return "-";
7003
+ return (cents / 100).toLocaleString("en-US", { style: "currency", currency: "USD" });
7004
+ }
7005
+ function money(amount, currency) {
7006
+ const n = Number(amount);
7007
+ try {
7008
+ return n.toLocaleString("en-US", { style: "currency", currency });
7009
+ } catch {
7010
+ return `${n.toFixed(2)} ${currency}`;
7011
+ }
7012
+ }
7013
+ function groupPan(pan) {
7014
+ return pan.replace(/\s+/g, "").replace(/(.{4})/g, "$1 ").trim();
7015
+ }
7016
+ var CARD_ERROR_COPY = {
7017
+ SDK_CARDS_PROVIDER_ERROR: "The card provider is not responding right now. Please try again in a few minutes.",
7018
+ SDK_CARDS_IP_NOT_SUPPORTED: "The card provider cannot accept your current connection (IPv6). Please try again from another network, for example Wi-Fi."
7019
+ };
7020
+ function errorText(e, fallback) {
7021
+ if (isPollarApiError(e)) {
7022
+ const known = CARD_ERROR_COPY[e.code];
7023
+ if (known) return known;
7024
+ const providerMessage = e.body.providerMessage;
7025
+ if (typeof providerMessage === "string" && providerMessage) return providerMessage;
7026
+ const message = e.body.message;
7027
+ if (typeof message === "string" && message) return message;
7028
+ return e.code;
7029
+ }
7030
+ return e instanceof Error && e.message ? e.message : fallback;
7031
+ }
7032
+ function CardModal({ onClose }) {
7033
+ const { getClient, styles, wallet } = usePollar();
7034
+ const { theme, accentColor, styleOverrides, overlayStyle } = modalChrome(styles);
7035
+ const cssVars = buildModalCssVars(theme, accentColor, styleOverrides);
7036
+ const [providers, setProviders] = useState(null);
7037
+ const [holder, setHolder] = useState(void 0);
7038
+ const [requirements, setRequirements] = useState(void 0);
7039
+ const [pendingStep, setPendingStep] = useState(null);
7040
+ const stepAttempt = useRef(null);
7041
+ const [cards, setCards] = useState(null);
7042
+ const [balance, setBalance] = useState(null);
7043
+ const [transactions, setTransactions] = useState(null);
7044
+ const [deposit, setDeposit] = useState(null);
7045
+ const [fundings, setFundings] = useState(null);
7046
+ const [fundAmount, setFundAmount] = useState("");
7047
+ const [showManual, setShowManual] = useState(false);
7048
+ const [occupations, setOccupations] = useState([]);
7049
+ const [kyc, setKyc] = useState(emptyKyc);
7050
+ const [terms, setTerms] = useState(false);
7051
+ const [nickname, setNickname] = useState("");
7052
+ const [secrets, setSecrets] = useState(null);
7053
+ const [panel, setPanel] = useState("card");
7054
+ const [busy, setBusy] = useState(null);
7055
+ const [error, setError] = useState("");
7056
+ const revealTimer = useRef(null);
7057
+ const provider = providers?.[0] ?? null;
7058
+ const card = cards?.[0] ?? null;
7059
+ const loadHolder = useCallback(async () => {
7060
+ const h = await getClient().getCardHolder();
7061
+ setHolder(h);
7062
+ return h;
7063
+ }, [getClient]);
7064
+ const loadRequirements = useCallback(
7065
+ async (cardProviderId) => {
7066
+ try {
7067
+ const r = await getClient().getCardRequirements({ cardProviderId });
7068
+ setRequirements(r);
7069
+ return r;
7070
+ } catch {
7071
+ setRequirements(null);
7072
+ return null;
7073
+ }
7074
+ },
7075
+ [getClient]
7076
+ );
7077
+ const loadCardData = useCallback(async () => {
7078
+ const client = getClient();
7079
+ const list = await client.getCards();
7080
+ if (list.length === 0) {
7081
+ setCards(list);
7082
+ return;
7083
+ }
7084
+ const [b, tx] = await Promise.all([client.getCardBalance(), client.getCardTransactions({ limit: TX_LIMIT })]);
7085
+ setBalance(b);
7086
+ setTransactions(tx.transactions);
7087
+ setCards(list);
7088
+ }, [getClient]);
7089
+ useEffect(() => {
7090
+ let cancelled = false;
7091
+ (async () => {
7092
+ try {
7093
+ const ps = await getClient().getCardProviders();
7094
+ if (cancelled) return;
7095
+ setProviders(ps);
7096
+ if (ps.length === 0) return;
7097
+ const [h] = await Promise.all([loadHolder(), loadRequirements(ps[0].id)]);
7098
+ if (cancelled) return;
7099
+ if (h?.kycStatus === "APPROVED") await loadCardData();
7100
+ } catch (e) {
7101
+ if (!cancelled) {
7102
+ setProviders((cur) => cur ?? []);
7103
+ setError(errorText(e, "Could not load your card"));
7104
+ }
7105
+ }
7106
+ })();
7107
+ return () => {
7108
+ cancelled = true;
7109
+ };
7110
+ }, [getClient, loadHolder, loadRequirements, loadCardData]);
7111
+ const stage = cardStage(holder, requirements);
7112
+ useEffect(() => {
7113
+ if (stage !== "provider-form") return;
7114
+ const profile = getClient().getUserProfile();
7115
+ setKyc((k) => ({
7116
+ ...k,
7117
+ firstName: k.firstName || profile?.first_name || "",
7118
+ lastName: k.lastName || profile?.last_name || ""
7119
+ }));
7120
+ getClient().getCardOccupations().then(setOccupations).catch(() => setOccupations([]));
7121
+ }, [stage, getClient]);
7122
+ const kycPending = holder ? holder.kycStatus in KYC_PENDING_COPY : false;
7123
+ useEffect(() => {
7124
+ if (!kycPending) return;
7125
+ const id = setInterval(() => {
7126
+ loadHolder().then((h) => {
7127
+ if (h?.kycStatus === "APPROVED") void loadCardData();
7128
+ }).catch(() => {
7129
+ });
7130
+ }, KYC_POLL_MS);
7131
+ return () => clearInterval(id);
7132
+ }, [kycPending, loadHolder, loadCardData]);
7133
+ useEffect(
7134
+ () => () => {
7135
+ if (revealTimer.current) clearTimeout(revealTimer.current);
7136
+ },
7137
+ []
7138
+ );
7139
+ function openStep(step) {
7140
+ stepAttempt.current = step;
7141
+ setPendingStep(step);
7142
+ }
7143
+ async function run(key, work, fallback) {
7144
+ if (busy) return;
7145
+ setBusy(key);
7146
+ setError("");
7147
+ try {
7148
+ await work();
7149
+ } catch (e) {
7150
+ const step = requiredCardStep(e);
7151
+ if (step) openStep(step);
7152
+ else setError(errorText(e, fallback));
7153
+ } finally {
7154
+ setBusy(null);
7155
+ }
7156
+ }
7157
+ async function afterStep() {
7158
+ if (!provider) return;
7159
+ const [h, r] = await Promise.all([loadHolder(), loadRequirements(provider.id)]);
7160
+ if (h?.kycStatus === "APPROVED") await loadCardData();
7161
+ if (r?.next && !blockedStepMessage(r.next)) openStep(pendingFromRequirement(provider.id, r.next));
7162
+ }
7163
+ const start = () => run(
7164
+ "start",
7165
+ async () => {
7166
+ if (!provider) return;
7167
+ if (requirements?.next) {
7168
+ openStep(pendingFromRequirement(provider.id, requirements.next));
7169
+ return;
7170
+ }
7171
+ if (holder) return afterStep();
7172
+ setHolder(await getClient().createCardHolder());
7173
+ },
7174
+ "Could not start your card application"
7175
+ );
7176
+ const sendKyc = () => run(
7177
+ "kyc",
7178
+ async () => {
7179
+ const address = { ...kyc.address };
7180
+ if (!address.line2) delete address.line2;
7181
+ setHolder(await getClient().submitCardKyc({ termsAccepted: terms, kyc: { ...kyc, address } }));
7182
+ },
7183
+ "Could not submit your information"
7184
+ );
7185
+ const issue = () => run(
7186
+ "issue",
7187
+ async () => {
7188
+ await getClient().issueCard(nickname.trim() ? { nickname: nickname.trim() } : {});
7189
+ await loadCardData();
7190
+ },
7191
+ "Could not issue your card"
7192
+ );
7193
+ const refresh = () => run(
7194
+ "refresh",
7195
+ async () => {
7196
+ await loadCardData();
7197
+ },
7198
+ "Could not refresh your card"
7199
+ );
7200
+ const reveal = () => run(
7201
+ "reveal",
7202
+ async () => {
7203
+ if (!card) return;
7204
+ const s = await getClient().revealCardSecrets(card.id);
7205
+ setSecrets(s);
7206
+ if (revealTimer.current) clearTimeout(revealTimer.current);
7207
+ revealTimer.current = setTimeout(() => setSecrets(null), REVEAL_MS);
7208
+ },
7209
+ "Could not show the card details"
7210
+ );
7211
+ const openFund = () => run(
7212
+ "fund",
7213
+ async () => {
7214
+ setFundings(await getClient().listCardFundings());
7215
+ setPanel("fund");
7216
+ },
7217
+ "Could not load your fundings"
7218
+ );
7219
+ const fund = () => run(
7220
+ "fund-send",
7221
+ async () => {
7222
+ const outcome = await getClient().fundCard({ amount: fundAmount.trim() });
7223
+ if (outcome.status === "cancelled") {
7224
+ setError("The payment was not signed.");
7225
+ return;
7226
+ }
7227
+ setFundings((cur) => [outcome.funding, ...(cur ?? []).filter((f) => f.id !== outcome.funding.id)]);
7228
+ setFundAmount("");
7229
+ },
7230
+ "Could not fund the card"
7231
+ );
7232
+ const showManualAddress = () => run(
7233
+ "fund-manual",
7234
+ async () => {
7235
+ if (!deposit) setDeposit(await getClient().getCardDepositAddresses());
7236
+ setShowManual(true);
7237
+ },
7238
+ "Could not load the deposit address"
7239
+ );
7240
+ const fundingsInflight = (fundings ?? []).some((f) => FUNDING_INFLIGHT.has(f.status));
7241
+ useEffect(() => {
7242
+ if (panel !== "fund" || !fundingsInflight) return;
7243
+ const id = setInterval(() => {
7244
+ getClient().listCardFundings().then((next) => {
7245
+ setFundings((previous) => {
7246
+ const credited = next.some(
7247
+ (f) => f.status === "CREDITED" && previous?.find((p) => p.id === f.id)?.status !== "CREDITED"
7248
+ );
7249
+ if (credited) void loadCardData().catch(() => {
7250
+ });
7251
+ return next;
7252
+ });
7253
+ }).catch(() => {
7254
+ });
7255
+ }, FUNDING_POLL_MS);
7256
+ return () => clearInterval(id);
7257
+ }, [panel, fundingsInflight, getClient, loadCardData]);
7258
+ const field = (key, label, extra = {}) => /* @__PURE__ */ jsxs("label", { className: "pollar-send-field", children: [
7259
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-label", children: label }),
7260
+ /* @__PURE__ */ jsx(
7261
+ "input",
7262
+ {
7263
+ className: "pollar-input",
7264
+ value: kyc[key],
7265
+ onChange: (e) => setKyc((k) => ({ ...k, [key]: e.target.value })),
7266
+ ...extra
7267
+ }
7268
+ )
7269
+ ] });
7270
+ const addressField = (key, label, extra = {}) => /* @__PURE__ */ jsxs("label", { className: "pollar-send-field", children: [
7271
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-label", children: label }),
7272
+ /* @__PURE__ */ jsx(
7273
+ "input",
7274
+ {
7275
+ className: "pollar-input",
7276
+ value: kyc.address[key] ?? "",
7277
+ onChange: (e) => setKyc((k) => ({ ...k, address: { ...k.address, [key]: e.target.value } })),
7278
+ ...extra
7279
+ }
7280
+ )
7281
+ ] });
7282
+ const rangeField = (key, label) => /* @__PURE__ */ jsxs("label", { className: "pollar-send-field", children: [
7283
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-label", children: label }),
7284
+ /* @__PURE__ */ jsx(
7285
+ "select",
7286
+ {
7287
+ className: "pollar-input pollar-send-select",
7288
+ value: kyc[key],
7289
+ onChange: (e) => setKyc((k) => ({ ...k, [key]: e.target.value })),
7290
+ children: INCOME_RANGES.map((r) => /* @__PURE__ */ jsx("option", { value: r.value, children: r.label }, r.value))
7291
+ }
7292
+ )
7293
+ ] });
7294
+ const kycComplete = kyc.firstName && kyc.lastName && /^\d{4}-\d{2}-\d{2}$/.test(kyc.birthDate) && kyc.nationalId && kyc.countryOfIssue.length === 2 && kyc.phoneCountryCode && kyc.phoneNumber && kyc.occupation && kyc.accountPurpose && kyc.address.line1 && kyc.address.city && kyc.address.region && kyc.address.postalCode && kyc.address.countryCode.length === 2;
7295
+ if (pendingStep) {
7296
+ const close = () => {
7297
+ stepAttempt.current = null;
7298
+ setPendingStep(null);
7299
+ };
7300
+ const done = () => {
7301
+ if (stepAttempt.current !== pendingStep) return;
7302
+ close();
7303
+ void afterStep();
7304
+ };
7305
+ const progress = pendingStep.progress ? { progress: pendingStep.progress } : {};
7306
+ if (pendingStep.type === "FORM") {
7307
+ return /* @__PURE__ */ jsx(RequirementFormModal, { formId: pendingStep.optionId, ...progress, onClose: close, onSubmitted: done });
7308
+ }
7309
+ if (pendingStep.type === "REGISTRY_CHECK") {
7310
+ return /* @__PURE__ */ jsx(RegistryCheckModal, { optionId: pendingStep.optionId, ...progress, onClose: close, onApproved: done });
7311
+ }
7312
+ if (pendingStep.type === "PROVIDER_REGISTRATION") {
7313
+ return /* @__PURE__ */ jsx(
7314
+ ProviderRegistrationModal,
7315
+ {
7316
+ cardProviderId: pendingStep.cardProviderId,
7317
+ ...progress,
7318
+ onClose: close,
7319
+ onRegistered: done
7320
+ }
7321
+ );
7322
+ }
7323
+ return /* @__PURE__ */ jsx(
7324
+ KycModal,
7325
+ {
7326
+ cardProviderId: pendingStep.cardProviderId,
7327
+ providerId: pendingStep.optionId,
7328
+ onClose: close,
7329
+ onApproved: done
7330
+ }
7331
+ );
7332
+ }
7333
+ const loading = providers === null || providers.length > 0 && (holder === void 0 || requirements === void 0) || holder?.kycStatus === "APPROVED" && cards === null && !error;
7334
+ const blocked = requirements?.next ? blockedStepMessage(requirements.next) : null;
7335
+ const stepsPending = !!requirements?.next;
7336
+ const title = panel === "fund" ? "Add funds" : card ? card.nickname ?? "Your card" : "Get a card";
7337
+ return /* @__PURE__ */ jsx("div", { className: "pollar-overlay", style: overlayStyle, onClick: onClose, children: /* @__PURE__ */ jsxs(
7338
+ "div",
7339
+ {
7340
+ className: "pollar-modal-card pollar-card-modal",
7341
+ "data-theme": theme,
7342
+ style: cssVars,
7343
+ onClick: (e) => e.stopPropagation(),
7344
+ children: [
7345
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header", children: [
7346
+ /* @__PURE__ */ jsxs("div", { className: "pollar-send-header-left", children: [
7347
+ panel === "fund" && /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: () => setPanel("card"), "aria-label": "Back", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M10 3L5 8l5 5", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) }) }),
7348
+ /* @__PURE__ */ jsx("h2", { className: "pollar-modal-title", children: title })
7349
+ ] }),
7350
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-header-actions", children: [
7351
+ card && panel === "card" && /* @__PURE__ */ jsx(
7352
+ "button",
7353
+ {
7354
+ type: "button",
7355
+ className: "pollar-modal-close",
7356
+ onClick: () => void refresh(),
7357
+ disabled: busy !== null,
7358
+ "aria-label": "Refresh",
7359
+ children: /* @__PURE__ */ jsx(
7360
+ "svg",
7361
+ {
7362
+ className: busy === "refresh" ? "pollar-modal-refresh-icon pollar-spinning" : "pollar-modal-refresh-icon",
7363
+ width: "16",
7364
+ height: "16",
7365
+ viewBox: "0 0 16 16",
7366
+ fill: "none",
7367
+ "aria-hidden": true,
7368
+ children: /* @__PURE__ */ jsx(
7369
+ "path",
7370
+ {
7371
+ d: "M13.5 8a5.5 5.5 0 1 1-1.6-3.9M13.5 2v3h-3",
7372
+ stroke: "currentColor",
7373
+ strokeWidth: "1.6",
7374
+ strokeLinecap: "round",
7375
+ strokeLinejoin: "round"
7376
+ }
7377
+ )
7378
+ }
7379
+ )
7380
+ }
7381
+ ),
7382
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-modal-close", onClick: onClose, "aria-label": "Close", children: /* @__PURE__ */ jsx("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", "aria-hidden": true, children: /* @__PURE__ */ jsx("path", { d: "M2 2l12 12M14 2L2 14", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round" }) }) })
7383
+ ] })
7384
+ ] }),
7385
+ loading && /* @__PURE__ */ jsx("div", { className: "pollar-loading-block", children: /* @__PURE__ */ jsx("div", { className: "pollar-spinner" }) }),
7386
+ !loading && providers?.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Cards are not available for this app." }),
7387
+ !loading && provider && !provider.available && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "Cards are not available right now." }),
7388
+ !loading && provider && provider.available && stage === "steps" && /* @__PURE__ */ jsxs(Fragment, { children: [
7389
+ /* @__PURE__ */ jsxs("p", { children: [
7390
+ "Get ",
7391
+ provider.cardLabel ?? `a ${provider.name} card`,
7392
+ " funded from your wallet",
7393
+ wallet ? "" : " once you sign in",
7394
+ ". You will verify your identity first; it takes a few minutes."
7395
+ ] }),
7396
+ requirements && requirements.total > 0 && /* @__PURE__ */ jsxs("p", { className: "pollar-card-note", children: [
7397
+ requirements.completed,
7398
+ " of ",
7399
+ requirements.total,
7400
+ " steps done"
7401
+ ] }),
7402
+ blocked && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: blocked }),
7403
+ /* @__PURE__ */ jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsx(
7404
+ "button",
7405
+ {
7406
+ type: "button",
7407
+ className: "pollar-btn-primary",
7408
+ onClick: () => void start(),
7409
+ disabled: busy !== null || !wallet || !!blocked,
7410
+ children: busy === "start" ? "Starting..." : stepsPending ? "Continue" : "Start"
7411
+ }
7412
+ ) })
7413
+ ] }),
7414
+ !loading && provider && stage === "provider-form" && /* @__PURE__ */ jsxs(Fragment, { children: [
7415
+ /* @__PURE__ */ jsx("p", { className: "pollar-card-section-title", children: "About you" }),
7416
+ /* @__PURE__ */ jsxs("div", { className: "pollar-card-grid", children: [
7417
+ field("firstName", "First name", { autoComplete: "given-name" }),
7418
+ field("lastName", "Last name", { autoComplete: "family-name" }),
7419
+ field("birthDate", "Birth date", { placeholder: "YYYY-MM-DD", autoComplete: "bday" }),
7420
+ field("nationalId", "ID number"),
7421
+ field("countryOfIssue", "ID country (2 letters)", { maxLength: 2, placeholder: "AR" }),
7422
+ /* @__PURE__ */ jsxs("label", { className: "pollar-send-field", children: [
7423
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-label", children: "Occupation" }),
7424
+ /* @__PURE__ */ jsxs(
7425
+ "select",
7426
+ {
7427
+ className: "pollar-input pollar-send-select",
7428
+ value: kyc.occupation,
7429
+ onChange: (e) => setKyc((k) => ({ ...k, occupation: e.target.value })),
7430
+ children: [
7431
+ /* @__PURE__ */ jsx("option", { value: "", children: "Select..." }),
7432
+ occupations.map((o) => /* @__PURE__ */ jsx("option", { value: o.code, children: o.label }, o.code))
7433
+ ]
7434
+ }
7435
+ )
7436
+ ] }),
7437
+ field("phoneCountryCode", "Phone country code", { placeholder: "54", inputMode: "numeric" }),
7438
+ field("phoneNumber", "Phone number", { placeholder: "91155551234", inputMode: "numeric" }),
7439
+ rangeField("annualSalary", "Annual income"),
7440
+ rangeField("expectedMonthlyVolume", "Expected monthly spend"),
7441
+ /* @__PURE__ */ jsx("div", { className: "pollar-card-grid-full", children: field("accountPurpose", "What will you use the card for?") })
7442
+ ] }),
7443
+ /* @__PURE__ */ jsx("p", { className: "pollar-card-section-title", children: "Address" }),
7444
+ /* @__PURE__ */ jsxs("div", { className: "pollar-card-grid", children: [
7445
+ /* @__PURE__ */ jsx("div", { className: "pollar-card-grid-full", children: addressField("line1", "Street and number", { autoComplete: "address-line1" }) }),
7446
+ /* @__PURE__ */ jsx("div", { className: "pollar-card-grid-full", children: addressField("line2", "Apartment, floor (optional)", { autoComplete: "address-line2" }) }),
7447
+ addressField("city", "City", { autoComplete: "address-level2" }),
7448
+ addressField("region", "State or province", { autoComplete: "address-level1" }),
7449
+ addressField("postalCode", "Postal code", { autoComplete: "postal-code" }),
7450
+ addressField("countryCode", "Country (2 letters)", { maxLength: 2, placeholder: "AR" })
7451
+ ] }),
7452
+ /* @__PURE__ */ jsxs("label", { className: "pollar-card-terms", children: [
7453
+ /* @__PURE__ */ jsx("input", { type: "checkbox", checked: terms, onChange: (e) => setTerms(e.target.checked) }),
7454
+ /* @__PURE__ */ jsxs("span", { children: [
7455
+ "I have read and accept the",
7456
+ " ",
7457
+ /* @__PURE__ */ jsxs("a", { className: "pollar-card-link", href: provider.termsUrl ?? "#", target: "_blank", rel: "noreferrer", children: [
7458
+ provider.name,
7459
+ " terms of service"
7460
+ ] }),
7461
+ provider.termsUrl ? "" : " (demo: the final terms link is pending)",
7462
+ "."
7463
+ ] })
7464
+ ] }),
7465
+ /* @__PURE__ */ jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsx(
7466
+ "button",
7467
+ {
7468
+ type: "button",
7469
+ className: "pollar-btn-primary",
7470
+ onClick: () => void sendKyc(),
7471
+ disabled: busy !== null || !terms || !kycComplete,
7472
+ children: busy === "kyc" ? "Sending..." : "Continue"
7473
+ }
7474
+ ) })
7475
+ ] }),
7476
+ !loading && holder && holder.kycStatus in KYC_PENDING_COPY && /* @__PURE__ */ jsxs(Fragment, { children: [
7477
+ /* @__PURE__ */ jsx("p", { children: KYC_PENDING_COPY[holder.kycStatus] }),
7478
+ holder.kycReason && /* @__PURE__ */ jsx("p", { className: "pollar-card-note", children: holder.kycReason }),
7479
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-actions", children: [
7480
+ holder.verificationLink && /* @__PURE__ */ jsx("a", { className: "pollar-btn-primary", href: holder.verificationLink, target: "_blank", rel: "noreferrer", children: "Verify my identity" }),
7481
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: () => void loadHolder().catch(() => {
7482
+ }), children: "I am done" })
7483
+ ] }),
7484
+ /* @__PURE__ */ jsx("p", { className: "pollar-card-note", children: "This screen updates on its own once the verification comes back." })
7485
+ ] }),
7486
+ !loading && holder && holder.kycStatus in KYC_FINAL_COPY && /* @__PURE__ */ jsxs("div", { className: "pollar-modal-error", children: [
7487
+ KYC_FINAL_COPY[holder.kycStatus],
7488
+ holder.kycReason ? ` ${holder.kycReason}` : ""
7489
+ ] }),
7490
+ !loading && provider && holder?.kycStatus === "APPROVED" && cards !== null && !card && /* @__PURE__ */ jsxs(Fragment, { children: [
7491
+ /* @__PURE__ */ jsx("p", { children: "Your identity is verified. Issue your virtual card to start." }),
7492
+ /* @__PURE__ */ jsxs("label", { className: "pollar-send-field", children: [
7493
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-label", children: "Card name (optional)" }),
7494
+ /* @__PURE__ */ jsx(
7495
+ "input",
7496
+ {
7497
+ className: "pollar-input",
7498
+ value: nickname,
7499
+ maxLength: 40,
7500
+ onChange: (e) => setNickname(e.target.value),
7501
+ placeholder: "Everyday card"
7502
+ }
7503
+ )
7504
+ ] }),
7505
+ /* @__PURE__ */ jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: () => void issue(), disabled: busy !== null, children: busy === "issue" ? "Issuing..." : "Issue my card" }) })
7506
+ ] }),
7507
+ !loading && provider && card && panel === "card" && /* @__PURE__ */ jsxs(Fragment, { children: [
7508
+ /* @__PURE__ */ jsxs("div", { className: "pollar-card-visual", children: [
7509
+ /* @__PURE__ */ jsxs("div", { className: "pollar-card-visual-top", children: [
7510
+ /* @__PURE__ */ jsxs("span", { className: "pollar-card-brand", children: [
7511
+ styles.logoUrl && /* @__PURE__ */ jsx("img", { src: styles.logoUrl, alt: "", className: "pollar-card-brand-logo" }),
7512
+ /* @__PURE__ */ jsx("span", { children: provider.cardLabel ?? provider.name })
7513
+ ] }),
7514
+ /* @__PURE__ */ jsx("span", { className: "pollar-card-status", children: card.status.toLowerCase() })
7515
+ ] }),
7516
+ /* @__PURE__ */ jsx("div", { className: "pollar-card-visual-chip" }),
7517
+ /* @__PURE__ */ jsx("div", { className: "pollar-card-visual-number", children: secrets ? groupPan(secrets.pan) : `\u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 \u2022\u2022\u2022\u2022 ${card.last4 ?? "\u2022\u2022\u2022\u2022"}` }),
7518
+ /* @__PURE__ */ jsxs("div", { className: "pollar-card-visual-bottom", children: [
7519
+ /* @__PURE__ */ jsxs("div", { children: [
7520
+ /* @__PURE__ */ jsx("span", { children: "Expires" }),
7521
+ /* @__PURE__ */ jsx("strong", { children: card.expMonth && card.expYear ? `${card.expMonth}/${card.expYear.slice(-2)}` : "--/--" })
7522
+ ] }),
7523
+ /* @__PURE__ */ jsxs("div", { children: [
7524
+ /* @__PURE__ */ jsx("span", { children: "CVC" }),
7525
+ /* @__PURE__ */ jsx("strong", { children: secrets ? secrets.cvc : "\u2022\u2022\u2022" })
7526
+ ] }),
7527
+ /* @__PURE__ */ jsxs("div", { children: [
7528
+ /* @__PURE__ */ jsx("span", { children: card.type.toLowerCase() }),
7529
+ /* @__PURE__ */ jsx("strong", { children: card.currency })
7530
+ ] })
7531
+ ] })
7532
+ ] }),
7533
+ /* @__PURE__ */ jsxs("div", { className: "pollar-card-balance", children: [
7534
+ /* @__PURE__ */ jsxs("div", { children: [
7535
+ /* @__PURE__ */ jsx("span", { children: "Available" }),
7536
+ /* @__PURE__ */ jsx("strong", { children: usd(balance?.spendingPowerCents) })
7537
+ ] }),
7538
+ /* @__PURE__ */ jsxs("div", { children: [
7539
+ /* @__PURE__ */ jsx("span", { children: "Limit" }),
7540
+ /* @__PURE__ */ jsx("strong", { children: usd(balance?.creditLimitCents) })
7541
+ ] }),
7542
+ /* @__PURE__ */ jsxs("div", { children: [
7543
+ /* @__PURE__ */ jsx("span", { children: "To pay" }),
7544
+ /* @__PURE__ */ jsx("strong", { children: usd(balance?.balanceDueCents) })
7545
+ ] })
7546
+ ] }),
7547
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-actions", children: [
7548
+ provider.supports.revealSecrets && (secrets ? /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: () => setSecrets(null), children: "Hide details" }) : /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: () => void reveal(), disabled: busy !== null, children: busy === "reveal" ? "Loading..." : "Show details" })),
7549
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-primary", onClick: () => void openFund(), disabled: busy !== null, children: "Add funds" })
7550
+ ] }),
7551
+ secrets && /* @__PURE__ */ jsx("p", { className: "pollar-card-note", children: "The details hide on their own in 30 seconds. Do not share them." }),
7552
+ /* @__PURE__ */ jsx("p", { className: "pollar-card-section-title", children: "Recent activity" }),
7553
+ transactions === null && /* @__PURE__ */ jsx("p", { className: "pollar-card-note", children: "Loading..." }),
7554
+ transactions?.length === 0 && /* @__PURE__ */ jsx("p", { className: "pollar-card-note", children: "No movements yet." }),
7555
+ transactions?.map((tx) => {
7556
+ const purchase = tx.purchase;
7557
+ const local = purchase?.localAmount && purchase.localCurrency && purchase.localCurrency !== "USD" ? money(String(purchase.localAmount), purchase.localCurrency) : null;
7558
+ return /* @__PURE__ */ jsxs("div", { className: "pollar-card-tx", children: [
7559
+ /* @__PURE__ */ jsxs("div", { children: [
7560
+ tx.merchantName ?? TX_LABELS[tx.type] ?? tx.type,
7561
+ /* @__PURE__ */ jsxs("span", { className: "pollar-card-tx-meta", children: [
7562
+ new Date(tx.occurredAt).toLocaleDateString(),
7563
+ tx.merchantName ? ` \xB7 ${TX_LABELS[tx.type] ?? tx.type}` : "",
7564
+ purchase?.status && purchase.status !== "completed" ? ` \xB7 ${purchase.status}` : ""
7565
+ ] })
7566
+ ] }),
7567
+ /* @__PURE__ */ jsxs("div", { className: "pollar-card-tx-amount", "data-direction": tx.direction ?? void 0, children: [
7568
+ tx.direction === "credit" ? "+" : tx.direction === "debit" ? "-" : "",
7569
+ money(tx.amount, tx.currency),
7570
+ local && /* @__PURE__ */ jsx("span", { className: "pollar-card-tx-meta", children: local })
7571
+ ] })
7572
+ ] }, tx.id);
7573
+ })
7574
+ ] }),
7575
+ !loading && provider && card && panel === "fund" && /* @__PURE__ */ jsxs(Fragment, { children: [
7576
+ /* @__PURE__ */ jsxs("p", { children: [
7577
+ "Move ",
7578
+ provider.fundingAssets.join(" or ") || "USDC",
7579
+ " from your wallet to your card. It takes a few minutes to cross to the card network."
7580
+ ] }),
7581
+ /* @__PURE__ */ jsxs("label", { className: "pollar-send-field", children: [
7582
+ /* @__PURE__ */ jsx("span", { className: "pollar-send-label", children: "Amount (USDC)" }),
7583
+ /* @__PURE__ */ jsx(
7584
+ "input",
7585
+ {
7586
+ className: "pollar-input",
7587
+ inputMode: "decimal",
7588
+ placeholder: "10",
7589
+ value: fundAmount,
7590
+ onChange: (e) => setFundAmount(e.target.value.replace(/[^0-9.]/g, ""))
7591
+ }
7592
+ )
7593
+ ] }),
7594
+ /* @__PURE__ */ jsx("div", { className: "pollar-modal-actions", children: /* @__PURE__ */ jsx(
7595
+ "button",
7596
+ {
7597
+ type: "button",
7598
+ className: "pollar-btn-primary",
7599
+ onClick: () => void fund(),
7600
+ disabled: busy !== null || !(Number(fundAmount) >= 1),
7601
+ children: busy === "fund-send" ? "Sending..." : "Fund from my wallet"
7602
+ }
7603
+ ) }),
7604
+ fundings && fundings.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
7605
+ /* @__PURE__ */ jsx("p", { className: "pollar-card-section-title", children: "Your fundings" }),
7606
+ fundings.map((f) => {
7607
+ const copy = FUNDING_COPY[f.status];
7608
+ const inflight = FUNDING_INFLIGHT.has(f.status);
7609
+ return /* @__PURE__ */ jsxs("div", { className: "pollar-card-tx", "aria-busy": inflight, children: [
7610
+ /* @__PURE__ */ jsxs("div", { children: [
7611
+ /* @__PURE__ */ jsxs("span", { className: "pollar-card-funding-title", children: [
7612
+ inflight && /* @__PURE__ */ jsx("span", { className: "pollar-spinner pollar-spinner-sm", "aria-hidden": true }),
7613
+ copy?.title ?? f.status
7614
+ ] }),
7615
+ inflight && copy?.step && /* @__PURE__ */ jsxs("span", { className: "pollar-card-tx-meta", role: "status", children: [
7616
+ "Step ",
7617
+ copy.step,
7618
+ " of ",
7619
+ FUNDING_STEPS,
7620
+ " \xB7 ",
7621
+ copy.hint
7622
+ ] }),
7623
+ /* @__PURE__ */ jsxs("span", { className: "pollar-card-tx-meta", children: [
7624
+ new Date(f.createdAt).toLocaleString(),
7625
+ f.status === "FAILED" && f.error ? ` \xB7 ${f.error}` : ""
7626
+ ] })
7627
+ ] }),
7628
+ /* @__PURE__ */ jsx("div", { className: "pollar-card-tx-amount", "data-direction": f.status === "CREDITED" ? "credit" : void 0, children: money(f.amount, "USD") })
7629
+ ] }, f.id);
7630
+ }),
7631
+ fundingsInflight && /* @__PURE__ */ jsx("p", { className: "pollar-card-note", children: "You can close this window: the funding keeps going and your card is credited when it finishes." })
7632
+ ] }),
7633
+ !showManual && /* @__PURE__ */ jsxs("p", { className: "pollar-card-note", children: [
7634
+ "Prefer to send from another wallet?",
7635
+ " ",
7636
+ /* @__PURE__ */ jsx(
7637
+ "button",
7638
+ {
7639
+ type: "button",
7640
+ className: "pollar-card-link",
7641
+ onClick: () => void showManualAddress(),
7642
+ disabled: busy !== null,
7643
+ children: "Show the deposit address"
7644
+ }
7645
+ )
7646
+ ] }),
7647
+ showManual && deposit?.map((d) => /* @__PURE__ */ jsxs("div", { className: "pollar-card-deposit", children: [
7648
+ /* @__PURE__ */ jsx("strong", { children: d.network }),
7649
+ " (chain ",
7650
+ d.chainId,
7651
+ ")",
7652
+ /* @__PURE__ */ jsx("code", { children: d.address }),
7653
+ /* @__PURE__ */ jsx(CopyButton, { value: d.address, label: "Copy address" }),
7654
+ /* @__PURE__ */ jsxs("p", { className: "pollar-card-note", children: [
7655
+ "Send only ",
7656
+ d.tokens.map((t) => (t.currency ?? "token").toUpperCase()).join(" or "),
7657
+ " on ",
7658
+ d.network,
7659
+ "; anything else can be lost."
7660
+ ] })
7661
+ ] }, d.network)),
7662
+ showManual && deposit?.length === 0 && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "The provider returned no deposit address." }),
7663
+ showManual && /* @__PURE__ */ jsx("p", { className: "pollar-card-note", children: /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-card-link", onClick: () => setShowManual(false), children: "Hide the deposit address" }) })
7664
+ ] }),
7665
+ error && /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: error }),
7666
+ /* @__PURE__ */ jsx(PollarModalFooter, {})
7667
+ ]
7668
+ }
7669
+ ) });
7670
+ }
6770
7671
  function describeDevice(s) {
6771
7672
  if (s.deviceLabel) return normalizeDeviceLabel(s.deviceLabel);
6772
7673
  if (!s.userAgent) return "Unknown device";
@@ -7783,9 +8684,30 @@ function PollarProvider({
7783
8684
  const [sendModalKey, setSendModalKey] = useState(0);
7784
8685
  const [swapModalKey, setSwapModalKey] = useState(0);
7785
8686
  const [earnModalKey, setEarnModalKey] = useState(0);
8687
+ const [cardModalOpen, setCardModalOpen] = useState(false);
8688
+ const [cardModalKey, setCardModalKey] = useState(0);
7786
8689
  const [receiveModalOpen, setReceiveModalOpen] = useState(false);
7787
8690
  const [sessionsModalOpen, setSessionsModalOpen] = useState(false);
7788
8691
  const [distributionRulesModalOpen, setDistributionRulesModalOpen] = useState(false);
8692
+ useEffect(
8693
+ () => pollarClient.onAuthStateChange((authState) => {
8694
+ if (authState.step !== "idle") return;
8695
+ setTransactionModalOpen(false);
8696
+ setKycModalOpen(false);
8697
+ setRampModalOpen(false);
8698
+ setTxHistoryModalOpen(false);
8699
+ setWalletBalanceModalOpen(false);
8700
+ setEnabledAssetsModalOpen(false);
8701
+ setSendModalOpen(false);
8702
+ setSwapModalOpen(false);
8703
+ setEarnModalOpen(false);
8704
+ setCardModalOpen(false);
8705
+ setReceiveModalOpen(false);
8706
+ setSessionsModalOpen(false);
8707
+ setDistributionRulesModalOpen(false);
8708
+ }),
8709
+ [pollarClient]
8710
+ );
7789
8711
  const walletAddress = sessionState?.wallet?.address || "";
7790
8712
  const walletProvisioning = sessionState?.wallet?.provisioning;
7791
8713
  const getClient = useCallback(() => pollarClient, [pollarClient]);
@@ -7855,6 +8777,11 @@ function PollarProvider({
7855
8777
  setEarnModalKey((k) => k + 1);
7856
8778
  setEarnModalOpen(true);
7857
8779
  },
8780
+ // cards
8781
+ openCardModal: () => {
8782
+ setCardModalKey((k) => k + 1);
8783
+ setCardModalOpen(true);
8784
+ },
7858
8785
  // sessions
7859
8786
  sessions,
7860
8787
  openSessionsModal: () => setSessionsModalOpen(true),
@@ -7929,6 +8856,8 @@ function PollarProvider({
7929
8856
  sendModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setSendModalOpen(false), children: /* @__PURE__ */ jsx(SendModal, { onClose: () => setSendModalOpen(false) }) }, sendModalKey),
7930
8857
  swapModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setSwapModalOpen(false), children: /* @__PURE__ */ jsx(SwapModal, { onClose: () => setSwapModalOpen(false) }) }, swapModalKey),
7931
8858
  earnModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setEarnModalOpen(false), children: /* @__PURE__ */ jsx(EarnModal, { onClose: () => setEarnModalOpen(false) }) }, earnModalKey),
8859
+ cardModalOpen && // Keyed by the wallet too: a different user, or signing in with it open, starts it from scratch.
8860
+ /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setCardModalOpen(false), children: /* @__PURE__ */ jsx(CardModal, { onClose: () => setCardModalOpen(false) }) }, `${cardModalKey}:${walletAddress}`),
7932
8861
  receiveModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setReceiveModalOpen(false), children: /* @__PURE__ */ jsx(ReceiveModal, { onClose: () => setReceiveModalOpen(false) }) }),
7933
8862
  sessionsModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setSessionsModalOpen(false), children: /* @__PURE__ */ jsx(SessionsModal, { onClose: () => setSessionsModalOpen(false) }) }),
7934
8863
  distributionRulesModalOpen && /* @__PURE__ */ jsx(ModalErrorBoundary, { onClose: () => setDistributionRulesModalOpen(false), children: /* @__PURE__ */ jsx(DistributionRulesModal, { onClose: () => setDistributionRulesModalOpen(false) }) })
@@ -8440,6 +9369,6 @@ function WalletButton() {
8440
9369
  );
8441
9370
  }
8442
9371
 
8443
- export { ChainSelect, DistributionRulesModal, DistributionRulesModalTemplate, EarnModal, EnabledAssetsModal, EnabledAssetsModalTemplate, KycModal, KycModalTemplate, KycStatus, LoginModalTemplate, PollarProvider, ProviderRegistrationModal, RampWidget, RampWidgetTemplate, ReceiveModal, ReceiveModalTemplate, RegistryCheckModal, RequirementFormModal, RouteDisplay, SendModal, SendModalTemplate, SessionsModal, SessionsModalTemplate, SwapModal, SwapModalTemplate, TransactionModalTemplate, TxHistoryModalTemplate, TxStatusView, WalletBalanceModal, WalletBalanceModalTemplate, WalletButton, WalletButtonTemplate, addressForChain, browserPasskeyCeremony, browserPasskeySigner, buildModalCssVars, chainsOf, createPollarAdapterHook, modalChrome, readableTextOn, resolveChain, useChains, usePollar, walletNotReadyReason };
9372
+ export { CardModal, ChainSelect, DistributionRulesModal, DistributionRulesModalTemplate, EarnModal, EnabledAssetsModal, EnabledAssetsModalTemplate, KycModal, KycModalTemplate, KycStatus, LoginModalTemplate, PollarProvider, ProviderRegistrationModal, RampWidget, RampWidgetTemplate, ReceiveModal, ReceiveModalTemplate, RegistryCheckModal, RequirementFormModal, RouteDisplay, SendModal, SendModalTemplate, SessionsModal, SessionsModalTemplate, SwapModal, SwapModalTemplate, TransactionModalTemplate, TxHistoryModalTemplate, TxStatusView, WalletBalanceModal, WalletBalanceModalTemplate, WalletButton, WalletButtonTemplate, addressForChain, browserPasskeyCeremony, browserPasskeySigner, buildModalCssVars, chainsOf, createPollarAdapterHook, modalChrome, readableTextOn, resolveChain, useChains, usePollar, walletNotReadyReason };
8444
9373
  //# sourceMappingURL=index.mjs.map
8445
9374
  //# sourceMappingURL=index.mjs.map