@pollar/react 0.10.1-rc.1 → 0.10.1-rc.2

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
@@ -1033,7 +1033,7 @@ var PollarModalFooter = () => {
1033
1033
  /* @__PURE__ */ jsx("span", { className: "pollar-footer-name", children: "Pollar" }),
1034
1034
  /* @__PURE__ */ jsxs("span", { className: "pollar-footer-version", children: [
1035
1035
  "v",
1036
- "0.10.1-rc.1"
1036
+ "0.10.1-rc.2"
1037
1037
  ] })
1038
1038
  ] })
1039
1039
  ] });
@@ -2469,6 +2469,33 @@ var STATUS_LABEL = {
2469
2469
  completed: "Completed",
2470
2470
  failed: "Failed"
2471
2471
  };
2472
+ var INSTRUCTION_LABELS = {
2473
+ br_code: "Pix code",
2474
+ account_holder_name: "Account holder",
2475
+ bank_name: "Bank",
2476
+ bank_address: "Bank address",
2477
+ bank_account_number: "Account number",
2478
+ bank_routing_number: "Routing number",
2479
+ iban: "IBAN",
2480
+ bic: "BIC",
2481
+ clabe: "CLABE",
2482
+ amount: "Amount",
2483
+ currency: "Currency",
2484
+ payment_rails: "Rails"
2485
+ };
2486
+ function flattenInstructions(instr) {
2487
+ const out = [];
2488
+ for (const [k, v] of Object.entries(instr)) {
2489
+ let value = "";
2490
+ if (typeof v === "string" || typeof v === "number") value = String(v);
2491
+ else if (Array.isArray(v))
2492
+ value = v.filter((x) => typeof x === "string" || typeof x === "number").join(", ");
2493
+ else continue;
2494
+ if (!value) continue;
2495
+ out.push({ key: k, label: INSTRUCTION_LABELS[k] ?? k, value });
2496
+ }
2497
+ return out;
2498
+ }
2472
2499
  function RampWidgetTemplate({
2473
2500
  theme,
2474
2501
  accentColor,
@@ -2477,6 +2504,8 @@ function RampWidgetTemplate({
2477
2504
  amount,
2478
2505
  currency,
2479
2506
  country,
2507
+ email,
2508
+ fullName,
2480
2509
  countries,
2481
2510
  countriesLoading,
2482
2511
  refreshing,
@@ -2486,15 +2515,18 @@ function RampWidgetTemplate({
2486
2515
  txStatus,
2487
2516
  kycUrl,
2488
2517
  stellarTxHash,
2518
+ depositInstructions,
2489
2519
  canComplete,
2490
2520
  completing,
2491
2521
  errorMsg,
2492
2522
  onDirectionChange,
2493
2523
  onAmountChange,
2494
- onCurrencyChange,
2524
+ onEmailChange,
2525
+ onFullNameChange,
2495
2526
  onCountryChange,
2496
2527
  onFindRoute,
2497
2528
  onSelectQuote,
2529
+ onContactContinue,
2498
2530
  onOpenKyc,
2499
2531
  onCompleteWithdraw,
2500
2532
  onRetry,
@@ -2526,6 +2558,7 @@ function RampWidgetTemplate({
2526
2558
  input: direction === "onramp" ? "Buy crypto" : "Sell crypto",
2527
2559
  loading_quote: "Finding best route",
2528
2560
  select_route: "Select provider",
2561
+ contact: "Your details",
2529
2562
  status: direction === "onramp" ? "Complete your deposit" : "Complete your withdrawal",
2530
2563
  error: "Something went wrong"
2531
2564
  };
@@ -2533,6 +2566,7 @@ function RampWidgetTemplate({
2533
2566
  input: direction === "onramp" ? "Enter the amount you want to deposit" : "Enter the amount you want to withdraw",
2534
2567
  loading_quote: "Comparing providers in real time\u2026",
2535
2568
  select_route: "All prices include fees",
2569
+ contact: `${provider || "This provider"} needs your name and email to verify you`,
2536
2570
  status: `Finish the flow at ${provider || "the provider"} to continue`,
2537
2571
  error: "Please try again"
2538
2572
  };
@@ -2590,36 +2624,6 @@ function RampWidgetTemplate({
2590
2624
  }
2591
2625
  )
2592
2626
  ] }),
2593
- /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-input-row", children: [
2594
- /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-field", children: [
2595
- /* @__PURE__ */ jsx("label", { className: "pollar-ramp-label", children: "Amount" }),
2596
- /* @__PURE__ */ jsx(
2597
- "input",
2598
- {
2599
- type: "number",
2600
- className: "pollar-ramp-input",
2601
- placeholder: "0.00",
2602
- value: amount,
2603
- min: "0",
2604
- onChange: (e) => onAmountChange(e.target.value)
2605
- }
2606
- )
2607
- ] }),
2608
- /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-field", style: { maxWidth: 90 }, children: [
2609
- /* @__PURE__ */ jsx("label", { className: "pollar-ramp-label", children: "Currency" }),
2610
- /* @__PURE__ */ jsx(
2611
- "input",
2612
- {
2613
- type: "text",
2614
- className: "pollar-ramp-input",
2615
- placeholder: "MXN",
2616
- value: currency,
2617
- maxLength: 5,
2618
- onChange: (e) => onCurrencyChange(e.target.value.toUpperCase())
2619
- }
2620
- )
2621
- ] })
2622
- ] }),
2623
2627
  /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-field", children: [
2624
2628
  /* @__PURE__ */ jsx("label", { className: "pollar-ramp-label", children: "Country" }),
2625
2629
  countriesLoading ? /* @__PURE__ */ jsx("div", { className: "pollar-ramp-input pollar-ramp-input-loading", children: "Loading countries\u2026" }) : countries.length === 0 ? /* @__PURE__ */ jsx("div", { className: "pollar-modal-error", children: "No ramp providers available on this network yet." }) : /* @__PURE__ */ jsx("select", { className: "pollar-ramp-input", value: country, onChange: (e) => onCountryChange(e.target.value), children: countries.map((c) => /* @__PURE__ */ jsxs("option", { value: c.code, children: [
@@ -2629,6 +2633,23 @@ function RampWidgetTemplate({
2629
2633
  c.currency ? ` \u2014 ${c.currency}` : ""
2630
2634
  ] }, c.code)) })
2631
2635
  ] }),
2636
+ /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-field", children: [
2637
+ /* @__PURE__ */ jsxs("label", { className: "pollar-ramp-label", children: [
2638
+ "Amount",
2639
+ currency ? ` (${currency})` : ""
2640
+ ] }),
2641
+ /* @__PURE__ */ jsx(
2642
+ "input",
2643
+ {
2644
+ type: "number",
2645
+ className: "pollar-ramp-input",
2646
+ placeholder: "0.00",
2647
+ value: amount,
2648
+ min: "0",
2649
+ onChange: (e) => onAmountChange(e.target.value)
2650
+ }
2651
+ )
2652
+ ] }),
2632
2653
  /* @__PURE__ */ jsxs("div", { className: "pollar-modal-actions", children: [
2633
2654
  /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" }),
2634
2655
  /* @__PURE__ */ jsx(
@@ -2651,6 +2672,48 @@ function RampWidgetTemplate({
2651
2672
  /* @__PURE__ */ jsx("div", { className: "pollar-ramp-route-list", children: quotes.map((q, i) => /* @__PURE__ */ jsx(RouteDisplay, { quote: q, onSelect: onSelectQuote }, i)) }),
2652
2673
  /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onClose, children: "Cancel" })
2653
2674
  ] }),
2675
+ step === "contact" && /* @__PURE__ */ jsxs(Fragment, { children: [
2676
+ /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-field", children: [
2677
+ /* @__PURE__ */ jsx("label", { className: "pollar-ramp-label", children: "Full name" }),
2678
+ /* @__PURE__ */ jsx(
2679
+ "input",
2680
+ {
2681
+ type: "text",
2682
+ className: "pollar-ramp-input",
2683
+ placeholder: "Jane Doe",
2684
+ value: fullName,
2685
+ onChange: (e) => onFullNameChange(e.target.value)
2686
+ }
2687
+ )
2688
+ ] }),
2689
+ /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-field", children: [
2690
+ /* @__PURE__ */ jsx("label", { className: "pollar-ramp-label", children: "Email" }),
2691
+ /* @__PURE__ */ jsx(
2692
+ "input",
2693
+ {
2694
+ type: "email",
2695
+ className: "pollar-ramp-input",
2696
+ placeholder: "jane@example.com",
2697
+ value: email,
2698
+ autoComplete: "email",
2699
+ onChange: (e) => onEmailChange(e.target.value)
2700
+ }
2701
+ )
2702
+ ] }),
2703
+ /* @__PURE__ */ jsxs("div", { className: "pollar-modal-actions", children: [
2704
+ /* @__PURE__ */ jsx("button", { type: "button", className: "pollar-btn-secondary", onClick: onRetry, children: "Back" }),
2705
+ /* @__PURE__ */ jsx(
2706
+ "button",
2707
+ {
2708
+ type: "button",
2709
+ className: "pollar-btn-primary",
2710
+ disabled: !fullName.trim() || !email.trim() || isLoading,
2711
+ onClick: onContactContinue,
2712
+ children: isLoading ? "Starting\u2026" : "Continue"
2713
+ }
2714
+ )
2715
+ ] })
2716
+ ] }),
2654
2717
  step === "status" && /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-payment", children: [
2655
2718
  /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-payment-field", children: [
2656
2719
  /* @__PURE__ */ jsx("span", { className: "pollar-ramp-payment-label", children: "Provider" }),
@@ -2668,6 +2731,10 @@ function RampWidgetTemplate({
2668
2731
  stellarTxHash.slice(-8)
2669
2732
  ] }) })
2670
2733
  ] }),
2734
+ depositInstructions && txStatus !== "completed" && flattenInstructions(depositInstructions).map(({ key, label, value }) => /* @__PURE__ */ jsxs("div", { className: "pollar-ramp-payment-field", children: [
2735
+ /* @__PURE__ */ jsx("span", { className: "pollar-ramp-payment-label", children: label }),
2736
+ /* @__PURE__ */ jsx("div", { className: "pollar-ramp-payment-value", children: /* @__PURE__ */ jsx("code", { style: { wordBreak: "break-all" }, children: value }) })
2737
+ ] }, key)),
2671
2738
  kycUrl && txStatus !== "completed" && /* @__PURE__ */ jsxs("button", { type: "button", className: "pollar-btn-primary", onClick: onOpenKyc, children: [
2672
2739
  "Continue at ",
2673
2740
  provider
@@ -2696,16 +2763,20 @@ function RampWidget({ onClose }) {
2696
2763
  const [amount, setAmount] = useState("");
2697
2764
  const [currency, setCurrency] = useState("");
2698
2765
  const [country, setCountry] = useState("");
2766
+ const [email, setEmail] = useState("");
2767
+ const [fullName, setFullName] = useState("");
2699
2768
  const [countries, setCountries] = useState([]);
2700
2769
  const [countriesLoading, setCountriesLoading] = useState(true);
2701
2770
  const [refreshing, setRefreshing] = useState(false);
2702
2771
  const [quotes, setQuotes] = useState([]);
2772
+ const [selectedQuote, setSelectedQuote] = useState(null);
2703
2773
  const [isLoading, setIsLoading] = useState(false);
2704
2774
  const [txId, setTxId] = useState(null);
2705
2775
  const [provider, setProvider] = useState("");
2706
2776
  const [kycUrl, setKycUrl] = useState(null);
2707
2777
  const [txStatus, setTxStatus] = useState(null);
2708
2778
  const [stellarTxHash, setStellarTxHash] = useState(null);
2779
+ const [depositInstructions, setDepositInstructions] = useState(null);
2709
2780
  const [completing, setCompleting] = useState(false);
2710
2781
  const [errorMsg, setErrorMsg] = useState(null);
2711
2782
  const directionRef = useRef(direction);
@@ -2721,6 +2792,8 @@ function RampWidget({ onClose }) {
2721
2792
  setTxStatus(tx.status);
2722
2793
  if (tx.stellarTxHash) setStellarTxHash(tx.stellarTxHash);
2723
2794
  if (tx.kycUrl) setKycUrl(tx.kycUrl);
2795
+ const di = tx.depositInstructions;
2796
+ if (di) setDepositInstructions(di);
2724
2797
  if (TERMINAL.includes(tx.status)) clearInterval(id);
2725
2798
  } catch {
2726
2799
  }
@@ -2768,6 +2841,8 @@ function RampWidget({ onClose }) {
2768
2841
  setTxStatus(tx.status);
2769
2842
  if (tx.stellarTxHash) setStellarTxHash(tx.stellarTxHash);
2770
2843
  if (tx.kycUrl) setKycUrl(tx.kycUrl);
2844
+ const di = tx.depositInstructions;
2845
+ if (di) setDepositInstructions(di);
2771
2846
  }
2772
2847
  } catch {
2773
2848
  } finally {
@@ -2777,11 +2852,13 @@ function RampWidget({ onClose }) {
2777
2852
  function resetToInput() {
2778
2853
  setStep("input");
2779
2854
  setQuotes([]);
2855
+ setSelectedQuote(null);
2780
2856
  setTxId(null);
2781
2857
  setProvider("");
2782
2858
  setKycUrl(null);
2783
2859
  setTxStatus(null);
2784
2860
  setStellarTxHash(null);
2861
+ setDepositInstructions(null);
2785
2862
  setErrorMsg(null);
2786
2863
  }
2787
2864
  async function resumeWithSignature(id, ps) {
@@ -2807,6 +2884,7 @@ function RampWidget({ onClose }) {
2807
2884
  setKycUrl(result.kycUrl ?? null);
2808
2885
  setTxStatus(result.status);
2809
2886
  setStellarTxHash(result.stellarTxHash ?? null);
2887
+ setDepositInstructions(result.depositInstructions ?? null);
2810
2888
  setStep("status");
2811
2889
  }
2812
2890
  async function handleFindRoute() {
@@ -2830,12 +2908,33 @@ function RampWidget({ onClose }) {
2830
2908
  setIsLoading(false);
2831
2909
  }
2832
2910
  }
2833
- async function handleSelectQuote(quote) {
2911
+ function handleSelectQuote(quote) {
2912
+ setSelectedQuote(quote);
2913
+ setErrorMsg(null);
2914
+ const requiresContact = quote.requiresContact ?? false;
2915
+ if (requiresContact && (!email.trim() || !fullName.trim())) {
2916
+ setStep("contact");
2917
+ return;
2918
+ }
2919
+ void startRamp(quote);
2920
+ }
2921
+ function handleContactContinue() {
2922
+ if (selectedQuote) void startRamp(selectedQuote);
2923
+ }
2924
+ async function startRamp(quote) {
2834
2925
  setIsLoading(true);
2835
2926
  setErrorMsg(null);
2836
2927
  try {
2837
- const base = { quoteId: quote.quoteId, amount: Number(amount), currency, country };
2838
- const result = direction === "onramp" ? await client.createOnRamp({ ...base, ...walletAddress ? { walletAddress } : {} }) : await client.createOffRamp({ ...base, ...walletAddress ? { walletAddress } : {} });
2928
+ const base = {
2929
+ quoteId: quote.quoteId,
2930
+ amount: Number(amount),
2931
+ currency,
2932
+ country,
2933
+ ...email.trim() ? { email: email.trim() } : {},
2934
+ ...fullName.trim() ? { fullName: fullName.trim() } : {},
2935
+ ...walletAddress ? { walletAddress } : {}
2936
+ };
2937
+ const result = direction === "onramp" ? await client.createOnRamp(base) : await client.createOffRamp(base);
2839
2938
  await applyResult(result);
2840
2939
  } catch (e) {
2841
2940
  setErrorMsg(e instanceof Error ? e.message : "Failed to start the ramp.");
@@ -2879,6 +2978,8 @@ function RampWidget({ onClose }) {
2879
2978
  amount,
2880
2979
  currency,
2881
2980
  country,
2981
+ email,
2982
+ fullName,
2882
2983
  countries,
2883
2984
  countriesLoading,
2884
2985
  refreshing,
@@ -2888,15 +2989,18 @@ function RampWidget({ onClose }) {
2888
2989
  txStatus,
2889
2990
  kycUrl,
2890
2991
  stellarTxHash,
2992
+ depositInstructions,
2891
2993
  canComplete,
2892
2994
  completing,
2893
2995
  errorMsg,
2894
2996
  onDirectionChange: setDirection,
2895
2997
  onAmountChange: setAmount,
2896
- onCurrencyChange: setCurrency,
2998
+ onEmailChange: setEmail,
2999
+ onFullNameChange: setFullName,
2897
3000
  onCountryChange: handleCountryChange,
2898
3001
  onFindRoute: handleFindRoute,
2899
3002
  onSelectQuote: handleSelectQuote,
3003
+ onContactContinue: handleContactContinue,
2900
3004
  onOpenKyc: handleOpenKyc,
2901
3005
  onCompleteWithdraw: handleCompleteWithdraw,
2902
3006
  onRetry: resetToInput,
@@ -4549,6 +4653,10 @@ function TxHistoryModalTemplate({
4549
4653
  /* @__PURE__ */ jsx(StatusBadge, { status: record.status }),
4550
4654
  /* @__PURE__ */ jsxs("span", { className: "pollar-hist-item-meta", children: [
4551
4655
  /* @__PURE__ */ jsx("span", { children: record.operation }),
4656
+ typeof record.details?.sponsored === "boolean" && /* @__PURE__ */ jsxs("span", { children: [
4657
+ "\xB7 ",
4658
+ record.details.sponsored ? "Sponsored" : "Self-paid"
4659
+ ] }),
4552
4660
  record.feeXlm && /* @__PURE__ */ jsxs("span", { children: [
4553
4661
  "\xB7 ",
4554
4662
  record.feeXlm,