@swype-org/react-sdk 0.1.26 → 0.1.28

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.cjs CHANGED
@@ -77,6 +77,26 @@ var wagmiConfig = wagmi.createConfig({
77
77
  [chains.base.id]: wagmi.http()
78
78
  }
79
79
  });
80
+ var PRIVY_MODAL_CENTER_CSS = `
81
+ @media (max-width: 440px) {
82
+ #privy-dialog [data-headlessui-state] {
83
+ position: static !important;
84
+ bottom: auto !important;
85
+ margin: auto !important;
86
+ width: 360px !important;
87
+ max-width: calc(100vw - 32px) !important;
88
+ box-shadow: 0px 8px 36px rgba(55, 65, 81, 0.15) !important;
89
+ border-radius: var(--privy-border-radius-lg) !important;
90
+ transform: none !important;
91
+ transition: opacity 100ms ease-in !important;
92
+ }
93
+ #privy-dialog [data-headlessui-state].entering,
94
+ #privy-dialog [data-headlessui-state].leaving {
95
+ opacity: 0 !important;
96
+ transform: none !important;
97
+ }
98
+ }
99
+ `;
80
100
  var SwypeContext = react.createContext(null);
81
101
  function SwypeProvider({
82
102
  apiBaseUrl,
@@ -87,6 +107,15 @@ function SwypeProvider({
87
107
  if (!queryClientRef.current) {
88
108
  queryClientRef.current = new reactQuery.QueryClient();
89
109
  }
110
+ react.useEffect(() => {
111
+ const style = document.createElement("style");
112
+ style.setAttribute("data-swype", "privy-modal-center");
113
+ style.textContent = PRIVY_MODAL_CENTER_CSS;
114
+ document.head.appendChild(style);
115
+ return () => {
116
+ style.remove();
117
+ };
118
+ }, []);
90
119
  const [depositAmount, setDepositAmountRaw] = react.useState(null);
91
120
  const setDepositAmount = react.useCallback((amount) => {
92
121
  setDepositAmountRaw(amount);
@@ -190,7 +219,7 @@ async function fetchAccounts(apiBaseUrl, token, credentialId) {
190
219
  }
191
220
  async function createTransfer(apiBaseUrl, token, params) {
192
221
  const body = {
193
- id: crypto.randomUUID(),
222
+ id: params.id ?? crypto.randomUUID(),
194
223
  credentialId: params.credentialId,
195
224
  sources: [{ [params.sourceType]: params.sourceId }],
196
225
  destinations: [
@@ -787,6 +816,11 @@ async function createPasskeyCredential(params) {
787
816
  };
788
817
  }
789
818
  async function deviceHasPasskey(credentialId) {
819
+ const found = await findDevicePasskey([credentialId]);
820
+ return found != null;
821
+ }
822
+ async function findDevicePasskey(credentialIds) {
823
+ if (credentialIds.length === 0) return null;
790
824
  try {
791
825
  const challenge = new Uint8Array(32);
792
826
  crypto.getRandomValues(challenge);
@@ -795,17 +829,18 @@ async function deviceHasPasskey(credentialId) {
795
829
  publicKey: {
796
830
  challenge,
797
831
  rpId: resolvePasskeyRpId(),
798
- allowCredentials: [{
832
+ allowCredentials: credentialIds.map((id) => ({
799
833
  type: "public-key",
800
- id: base64ToBytes(credentialId)
801
- }],
834
+ id: base64ToBytes(id)
835
+ })),
802
836
  userVerification: "discouraged",
803
837
  timeout: 3e4
804
838
  }
805
839
  });
806
- return assertion != null;
840
+ if (!assertion) return null;
841
+ return toBase64(assertion.rawId);
807
842
  } catch {
808
- return false;
843
+ return null;
809
844
  }
810
845
  }
811
846
  function useTransferPolling(intervalMs = 3e3) {
@@ -2170,7 +2205,8 @@ function SwypePayment({
2170
2205
  destination,
2171
2206
  onComplete,
2172
2207
  onError,
2173
- useWalletConnector
2208
+ useWalletConnector,
2209
+ idempotencyKey
2174
2210
  }) {
2175
2211
  const { apiBaseUrl, tokens, depositAmount } = useSwypeConfig();
2176
2212
  const { ready, authenticated, user, login, logout, getAccessToken } = reactAuth.usePrivy();
@@ -2237,20 +2273,20 @@ function SwypePayment({
2237
2273
  }
2238
2274
  return;
2239
2275
  }
2240
- for (const pk of allPasskeys) {
2241
- if (cancelled) return;
2242
- if (await deviceHasPasskey(pk.credentialId)) {
2243
- setActiveCredentialId(pk.credentialId);
2244
- window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, pk.credentialId);
2245
- if (depositAmount != null && depositAmount > 0) {
2246
- setStep("ready");
2247
- } else {
2248
- setStep("enter-amount");
2249
- }
2250
- return;
2276
+ if (cancelled) return;
2277
+ const credentialIds = allPasskeys.map((p) => p.credentialId);
2278
+ const matched = await findDevicePasskey(credentialIds);
2279
+ if (cancelled) return;
2280
+ if (matched) {
2281
+ setActiveCredentialId(matched);
2282
+ window.localStorage.setItem(ACTIVE_CREDENTIAL_STORAGE_KEY, matched);
2283
+ if (depositAmount != null && depositAmount > 0) {
2284
+ setStep("ready");
2285
+ } else {
2286
+ setStep("enter-amount");
2251
2287
  }
2288
+ return;
2252
2289
  }
2253
- if (cancelled) return;
2254
2290
  setStep("register-passkey");
2255
2291
  } catch {
2256
2292
  if (!cancelled) {
@@ -2484,6 +2520,7 @@ function SwypePayment({
2484
2520
  }
2485
2521
  }
2486
2522
  const t = await createTransfer(apiBaseUrl, token, {
2523
+ id: idempotencyKey,
2487
2524
  credentialId: activeCredentialId,
2488
2525
  sourceType: effectiveSourceType,
2489
2526
  sourceId: effectiveSourceId,
@@ -3025,7 +3062,7 @@ function SwypePayment({
3025
3062
  ]
3026
3063
  }
3027
3064
  ),
3028
- /* @__PURE__ */ jsxRuntime.jsxs(
3065
+ /* @__PURE__ */ jsxRuntime.jsx(
3029
3066
  "div",
3030
3067
  {
3031
3068
  style: {
@@ -3038,74 +3075,39 @@ function SwypePayment({
3038
3075
  border: `1px solid ${tokens.border}`,
3039
3076
  lineHeight: 1.7
3040
3077
  },
3041
- children: [
3042
- /* @__PURE__ */ jsxRuntime.jsxs(
3043
- "div",
3044
- {
3045
- style: { display: "flex", justifyContent: "space-between" },
3046
- children: [
3047
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "To" }),
3048
- /* @__PURE__ */ jsxRuntime.jsxs(
3049
- "span",
3050
- {
3051
- style: {
3052
- fontFamily: '"SF Mono", "Fira Code", monospace',
3053
- fontSize: "0.8rem"
3054
- },
3055
- children: [
3056
- destination.address.slice(0, 6),
3057
- "...",
3058
- destination.address.slice(-4)
3059
- ]
3060
- }
3061
- )
3062
- ]
3063
- }
3064
- ),
3065
- /* @__PURE__ */ jsxRuntime.jsxs(
3066
- "div",
3067
- {
3068
- style: { display: "flex", justifyContent: "space-between" },
3069
- children: [
3070
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Token" }),
3071
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 600 }, children: destination.token.symbol })
3072
- ]
3073
- }
3074
- ),
3075
- /* @__PURE__ */ jsxRuntime.jsxs(
3076
- "div",
3077
- {
3078
- style: {
3079
- display: "flex",
3080
- justifyContent: "space-between",
3081
- alignItems: "center"
3082
- },
3083
- children: [
3084
- /* @__PURE__ */ jsxRuntime.jsx("span", { children: "From" }),
3085
- noAccounts ? /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontWeight: 500, color: tokens.textMuted }, children: "New account" }) : /* @__PURE__ */ jsxRuntime.jsx(
3086
- AccountDropdown,
3087
- {
3088
- accounts,
3089
- selectedAccountId,
3090
- selectedWalletId,
3091
- onSelect: (id) => {
3092
- setSelectedAccountId(id);
3093
- setSelectedWalletId(null);
3094
- setConnectingNewAccount(false);
3095
- setSelectedProviderId(null);
3096
- },
3097
- onWalletSelect: (accountId, walletId) => {
3098
- setSelectedAccountId(accountId);
3099
- setSelectedWalletId(walletId);
3100
- setConnectingNewAccount(false);
3101
- setSelectedProviderId(null);
3102
- }
3078
+ children: /* @__PURE__ */ jsxRuntime.jsx(
3079
+ "div",
3080
+ {
3081
+ style: {
3082
+ display: "flex",
3083
+ justifyContent: "space-between",
3084
+ alignItems: "center"
3085
+ },
3086
+ children: noAccounts ? /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, {}) : /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
3087
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "From" }),
3088
+ /* @__PURE__ */ jsxRuntime.jsx(
3089
+ AccountDropdown,
3090
+ {
3091
+ accounts,
3092
+ selectedAccountId,
3093
+ selectedWalletId,
3094
+ onSelect: (id) => {
3095
+ setSelectedAccountId(id);
3096
+ setSelectedWalletId(null);
3097
+ setConnectingNewAccount(false);
3098
+ setSelectedProviderId(null);
3099
+ },
3100
+ onWalletSelect: (accountId, walletId) => {
3101
+ setSelectedAccountId(accountId);
3102
+ setSelectedWalletId(walletId);
3103
+ setConnectingNewAccount(false);
3104
+ setSelectedProviderId(null);
3103
3105
  }
3104
- )
3105
- ]
3106
- }
3107
- )
3108
- ]
3106
+ }
3107
+ )
3108
+ ] })
3109
+ }
3110
+ )
3109
3111
  }
3110
3112
  ),
3111
3113
  noAccounts && /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { marginBottom: "16px" }, children: [
@@ -3371,10 +3373,9 @@ function SwypePayment({
3371
3373
  }
3372
3374
  };
3373
3375
  const regMsg = getRegistrationMessage();
3374
- const transferStatus = getDisplayTransferStatus(polling.transfer, transfer);
3375
- const transferIdSuffix = getTransferIdSuffix(polling.transfer, transfer);
3376
- const statusLabel = creatingTransfer ? "Creating transfer..." : mobileFlow ? "Waiting for authorization..." : authExecutor.executing && regMsg.label ? regMsg.label : authExecutor.executing ? "Authorizing..." : transferSigning.signing ? "Preparing transfer..." : polling.isPolling ? "Processing payment..." : "Please wait...";
3377
- const statusDescription = creatingTransfer ? "Setting up your transfer..." : mobileFlow ? "Complete the authorization in your wallet app, then return here." : authExecutor.executing && regMsg.description ? regMsg.description : authExecutor.executing ? "Complete the wallet prompts to authorize this payment." : transferSigning.signing ? "Waiting for backend to prepare your transfer payload..." : polling.isPolling ? "Your payment is being processed. This usually takes a few moments." : "Hang tight...";
3376
+ getDisplayTransferStatus(polling.transfer, transfer);
3377
+ getTransferIdSuffix(polling.transfer, transfer);
3378
+ const statusLabel = creatingTransfer ? "Creating Transfer" : mobileFlow ? "Waiting for Authorization" : authExecutor.executing && regMsg.label ? regMsg.label : authExecutor.executing ? "Authorizing" : transferSigning.signing ? "Sending transfer" : polling.isPolling ? "Transfer Sent" : "Please wait...";
3378
3379
  return /* @__PURE__ */ jsxRuntime.jsx("div", { style: cardStyle, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { textAlign: "center", padding: "16px 0" }, children: [
3379
3380
  /* @__PURE__ */ jsxRuntime.jsx(Spinner, { size: 48 }),
3380
3381
  /* @__PURE__ */ jsxRuntime.jsx(
@@ -3388,36 +3389,6 @@ function SwypePayment({
3388
3389
  children: statusLabel
3389
3390
  }
3390
3391
  ),
3391
- /* @__PURE__ */ jsxRuntime.jsx(
3392
- "p",
3393
- {
3394
- style: {
3395
- fontSize: "0.85rem",
3396
- color: tokens.textSecondary,
3397
- margin: 0,
3398
- lineHeight: 1.5
3399
- },
3400
- children: statusDescription
3401
- }
3402
- ),
3403
- /* @__PURE__ */ jsxRuntime.jsxs(
3404
- "p",
3405
- {
3406
- style: {
3407
- marginTop: "12px",
3408
- marginBottom: 0,
3409
- fontSize: "0.8rem",
3410
- color: tokens.textSecondary
3411
- },
3412
- children: [
3413
- "Current status: ",
3414
- /* @__PURE__ */ jsxRuntime.jsx("strong", { style: { color: tokens.text }, children: transferStatus }),
3415
- " \xB7 ",
3416
- "Transfer: ",
3417
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { color: tokens.textMuted }, children: transferIdSuffix })
3418
- ]
3419
- }
3420
- ),
3421
3392
  polling.error && /* @__PURE__ */ jsxRuntime.jsxs(
3422
3393
  "p",
3423
3394
  {
@@ -3588,6 +3559,7 @@ exports.SwypeProvider = SwypeProvider;
3588
3559
  exports.createPasskeyCredential = createPasskeyCredential;
3589
3560
  exports.darkTheme = darkTheme;
3590
3561
  exports.deviceHasPasskey = deviceHasPasskey;
3562
+ exports.findDevicePasskey = findDevicePasskey;
3591
3563
  exports.getTheme = getTheme;
3592
3564
  exports.lightTheme = lightTheme;
3593
3565
  exports.swypeApi = api_exports;