Feat/react native sdk - #53
Merged
Merged
Conversation
…, regenerate API reference
…cto-connect Regenerating from a fork (or any checkout whose git 'origin' doesn't resolve to this repo) rewrote every 'Defined in' link and made the docs-freshness CI check fail on an unrelated diff. Also regenerates react-native.mdx, which had drifted from the export-order change in the preceding biome format commit.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a React Native SDK to Pacto Connect — a WebView-hosted checkout, deep-link return handling, and an escrow event hook, all reusing
@pacto-connect/core's existing handshake/session model instead of reimplementing the checkout UI natively.packages/connect-react-native(new):PactoCheckoutSheet(Modal + WebView, the RN counterpart tomountFrame()in@pacto-connect/elements), awebview-bridgelayer that translates the existingpostMessagebridge protocol onto WebView's one-way JS-string channel while preserving origin validation,usePactoDeepLink(custom-scheme + universal-link return handling viaLinking, warm and cold-start), andusePactoEscrowEvents(SSE whenReadableStreamis available, a documented polling fallback when it isn't — plusAppState-aware reconnect on foreground and transparentPactoSession.refresh()before expiry, since mobile sessions live far longer than a web checkout tab).buildAppleAppSiteAssociation/buildAndroidAssetLinksgenerate the two platform verification file bodies, wired intoapps/example-rn/app.json'sassociatedDomains/intentFilters— a custom scheme still works out of the box with no hosting required.apps/example-rn(new): a real Expo app exercising the package end-to-end (checkout sheet, deep-link return, escrow hook).@pacto-connect/react-nativeAPI reference (generated), a Security guide section covering the WebView bridge's origin model and universal-link setup, README/CI updated to include the new package.apps/docs's lockfile was missingstyled-jsx/@next/env(pre-existing, unrelated to this change) and silently brokenext build— pinnedstyled-jsxso the whole workspace builds again.Why this shape
The security model matters more here than in a typical wrapper: a WebView has no
MessageEvent.origin, soonMessagepayloads are validated against the WebView's current page URL instead, using the sameisOriginAllowedallow-list the DOM bridge already uses.parentOriginis pointed at the checkout page's own origin rather than an app scheme, because a same-windowpostMessageis only delivered when the target origin matches the receiving window's — there is no real parent window inside a WebView. External navigation (bank/3-D Secure redirects) is handed off to the system browser viaonShouldStartLoadWithRequestrather than loaded inside the captive WebView. No merchant secret key is ever a prop on any exported component or hook — onlypublishableKey, matching the web SDKs.Acceptance criteria coverage
onComplete/onDisputeonPactoCheckoutSheet, demonstrated inapps/example-rn/App.tsx).usePactoDeepLink+ realassociatedDomains/intentFiltersconfig, not just a custom scheme).connect-core's SSE client where the platform allows, with a documented polling fallback where it doesn't (usePactoEscrowEvents).sk_value regardless of input.apps/example-rntype-checks and builds cleanly; running it live in Expo Go/a simulator is the one thing I couldn't verify myself.Test plan
npm run check # biome — 0 errors, whole workspace
npm run type-check # turbo — 11/11 packages
npm run build # turbo — 6/6 packages, apps/docs builds incl. new API reference page
npm run test # turbo — 9/9 packages, 387 tests total, 0 regressions
Closes #38