@coinbase/cdp-react-native 0.0.0 → 0.0.82

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/README.md ADDED
@@ -0,0 +1,4 @@
1
+ # cdp-react-native
2
+
3
+ This package contains ready-made, customizable React Native UI components that wrap
4
+ the CDP frontend SDK.
@@ -0,0 +1,8 @@
1
+ import { ApplePayProvider as o } from "./index2.js";
2
+ import { useApplePay as t } from "./index3.js";
3
+ import { ApplePayButton as a } from "./index4.js";
4
+ export {
5
+ a as ApplePayButton,
6
+ o as ApplePayProvider,
7
+ t as useApplePay
8
+ };
@@ -0,0 +1,146 @@
1
+ import { createEndUserApplePayOnrampOrder as y, APIError as h } from "@coinbase/cdp-api-client";
2
+ import { useCurrentUser as f, useConfig as g } from "@coinbase/cdp-hooks";
3
+ import v, { createContext as b, useReducer as k, useCallback as n, useEffect as C } from "react";
4
+ import { checkUserVerification as U } from "./index5.js";
5
+ const x = b(null);
6
+ function q({ children: t }) {
7
+ const [s, r] = k(A, p), { currentUser: o } = f(), { config: i } = g(), c = n(() => {
8
+ if (!o)
9
+ return r({
10
+ type: "validation_error",
11
+ error: {
12
+ code: "user_not_authenticated"
13
+ }
14
+ }), null;
15
+ const { missingVerification: e } = U(o);
16
+ return e ? (r({
17
+ type: "validation_error",
18
+ error: {
19
+ code: e === "email" ? "requires_email" : "requires_sms"
20
+ }
21
+ }), null) : (r({ type: "reset" }), o);
22
+ }, [o]);
23
+ C(() => {
24
+ c();
25
+ }, [c]);
26
+ const d = n(
27
+ async (e) => {
28
+ const u = c();
29
+ if (u)
30
+ try {
31
+ r({ type: "purchase_requested" });
32
+ const a = await y(i.projectId, u.userId, {
33
+ agreementAcceptedAt: (/* @__PURE__ */ new Date()).toISOString(),
34
+ // TODO: Do we need to verify the user owns the destination address?
35
+ destination: e.destination,
36
+ payment: {
37
+ currency: e.payment.currency.toUpperCase()
38
+ },
39
+ purchase: {
40
+ amount: e.purchase.amount,
41
+ currency: e.purchase.currency.toUpperCase()
42
+ },
43
+ isSandbox: e.isSandbox
44
+ });
45
+ r({ type: "purchase_started", data: a });
46
+ } catch (a) {
47
+ a instanceof h ? r({
48
+ type: "purchase_error",
49
+ error: {
50
+ code: "api_error",
51
+ correlationId: a.correlationId,
52
+ message: a.errorMessage
53
+ }
54
+ }) : r({
55
+ type: "purchase_error",
56
+ error: {
57
+ message: a instanceof Error ? a.message : "Failed to create order"
58
+ }
59
+ });
60
+ }
61
+ },
62
+ [c]
63
+ ), l = n((e) => {
64
+ switch (e.type) {
65
+ case "onramp_api.load_error":
66
+ r({
67
+ type: "purchase_error",
68
+ error: e.error
69
+ });
70
+ break;
71
+ case "onramp_api.commit_error":
72
+ r({
73
+ type: "purchase_error",
74
+ error: e.error
75
+ });
76
+ break;
77
+ case "onramp_api.polling_error":
78
+ r({
79
+ type: "purchase_error",
80
+ error: e.error
81
+ });
82
+ break;
83
+ case "onramp_api.polling_success":
84
+ r({ type: "purchase_success" });
85
+ break;
86
+ case "onramp_api.cancel":
87
+ r({ type: "reset" });
88
+ break;
89
+ }
90
+ }, []), m = n(() => {
91
+ r({ type: "reset" });
92
+ }, []), _ = {
93
+ ...s,
94
+ createOrder: d,
95
+ paymentEventHandler: l,
96
+ reset: m
97
+ };
98
+ return /* @__PURE__ */ v.createElement(x.Provider, { value: _ }, t);
99
+ }
100
+ const p = {
101
+ status: "idle",
102
+ data: void 0,
103
+ error: void 0
104
+ };
105
+ function A(t, s) {
106
+ switch (s.type) {
107
+ case "validation_error":
108
+ return {
109
+ ...t,
110
+ status: "error",
111
+ error: s.error
112
+ };
113
+ case "purchase_requested":
114
+ return {
115
+ ...t,
116
+ status: "pending",
117
+ error: void 0
118
+ };
119
+ case "purchase_started":
120
+ return {
121
+ ...t,
122
+ status: "pending",
123
+ data: s.data,
124
+ error: void 0
125
+ };
126
+ case "purchase_success":
127
+ return {
128
+ ...t,
129
+ status: "success"
130
+ };
131
+ case "purchase_error":
132
+ return {
133
+ ...t,
134
+ status: "error",
135
+ error: s.error
136
+ };
137
+ case "reset":
138
+ return p;
139
+ default:
140
+ return t;
141
+ }
142
+ }
143
+ export {
144
+ x as ApplePayContext,
145
+ q as ApplePayProvider
146
+ };
@@ -0,0 +1,17 @@
1
+ import { useContext as r } from "react";
2
+ import { ApplePayContext as t } from "./index2.js";
3
+ function s() {
4
+ const e = r(t);
5
+ if (!e)
6
+ throw new Error("useApplePay must be used within an ApplePayProvider");
7
+ return {
8
+ createOrder: e.createOrder,
9
+ data: e.data,
10
+ status: e.status,
11
+ error: e.error,
12
+ reset: e.reset
13
+ };
14
+ }
15
+ export {
16
+ s as useApplePay
17
+ };
@@ -0,0 +1,125 @@
1
+ import a, { useContext as c, useCallback as d } from "react";
2
+ import { StyleSheet as p, Platform as l, View as g } from "react-native";
3
+ import { WebView as v } from "react-native-webview";
4
+ import { ApplePayContext as w } from "./index2.js";
5
+ import { parseWebViewMessage as f } from "./index6.js";
6
+ function N({ style: o }) {
7
+ const e = c(w);
8
+ if (!e)
9
+ throw new Error("ApplePayButton must be used within an ApplePayProvider");
10
+ const t = e.data?.paymentLink.url, s = d(
11
+ (r) => {
12
+ const n = f(r.nativeEvent.data);
13
+ n.success && e.paymentEventHandler(n.event);
14
+ },
15
+ [e.paymentEventHandler]
16
+ );
17
+ return l.OS !== "ios" ? (__DEV__ && console.warn("ApplePayButton is only available on iOS"), null) : t ? /* @__PURE__ */ a.createElement(g, { style: [i.container, o] }, /* @__PURE__ */ a.createElement(
18
+ v,
19
+ {
20
+ source: { uri: t },
21
+ injectedJavaScriptBeforeContentLoaded: u,
22
+ injectedJavaScript: m,
23
+ onMessage: s,
24
+ startInLoadingState: !0,
25
+ style: i.webView,
26
+ originWhitelist: ["https://*", "apple-pay://*"],
27
+ mixedContentMode: "compatibility"
28
+ }
29
+ )) : null;
30
+ }
31
+ const i = p.create({
32
+ container: {
33
+ height: 48,
34
+ width: "100%",
35
+ overflow: "hidden",
36
+ borderRadius: 8
37
+ },
38
+ webView: {
39
+ flex: 1,
40
+ backgroundColor: "transparent"
41
+ }
42
+ }), u = `
43
+ (function() {
44
+ // Flag to prevent duplicate installations
45
+ window.__cdpEventForwarderInstalled = true;
46
+
47
+ // Store original postMessage to intercept outgoing messages
48
+ var originalPostMessage = window.postMessage;
49
+ window.postMessage = function(message, targetOrigin, transfer) {
50
+ try {
51
+ if (message && (typeof message === 'object' || typeof message === 'string')) {
52
+ var msgStr = typeof message === 'object' ? JSON.stringify(message) : message;
53
+ if (window.ReactNativeWebView) {
54
+ window.ReactNativeWebView.postMessage(msgStr);
55
+ }
56
+ }
57
+ } catch (e) {
58
+ console.error('[CDP] Error intercepting postMessage:', e);
59
+ }
60
+ return originalPostMessage.apply(window, arguments);
61
+ };
62
+
63
+ // Listen for incoming postMessage events
64
+ window.addEventListener('message', function(event) {
65
+ try {
66
+ if (event.data && typeof event.data === 'object') {
67
+ window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
68
+ } else if (typeof event.data === 'string') {
69
+ window.ReactNativeWebView.postMessage(event.data);
70
+ }
71
+ } catch (e) {
72
+ console.error('[CDP] Error forwarding message:', e);
73
+ }
74
+ }, true);
75
+
76
+ // Listen for custom onramp events
77
+ document.addEventListener('onramp_event', function(event) {
78
+ if (event.detail) {
79
+ window.ReactNativeWebView.postMessage(JSON.stringify(event.detail));
80
+ }
81
+ }, true);
82
+
83
+ // Override dispatchEvent to catch custom events
84
+ var originalDispatchEvent = EventTarget.prototype.dispatchEvent;
85
+ EventTarget.prototype.dispatchEvent = function(event) {
86
+ if (event.type && event.type.includes('onramp')) {
87
+ try {
88
+ if (window.ReactNativeWebView) {
89
+ window.ReactNativeWebView.postMessage(JSON.stringify({
90
+ eventName: event.type,
91
+ data: event.detail
92
+ }));
93
+ }
94
+ } catch (e) {}
95
+ }
96
+ return originalDispatchEvent.apply(this, arguments);
97
+ };
98
+
99
+ true;
100
+ })();
101
+ `, m = `
102
+ (function() {
103
+ if (window.__cdpEventForwarderInstalled) {
104
+ return true;
105
+ }
106
+
107
+ // Fallback installation if beforeContentLoaded didn't run
108
+ window.addEventListener('message', function(event) {
109
+ try {
110
+ if (event.data && typeof event.data === 'object') {
111
+ window.ReactNativeWebView.postMessage(JSON.stringify(event.data));
112
+ } else if (typeof event.data === 'string') {
113
+ window.ReactNativeWebView.postMessage(event.data);
114
+ }
115
+ } catch (e) {
116
+ console.error('[CDP] Error forwarding message:', e);
117
+ }
118
+ }, true);
119
+
120
+ true;
121
+ })();
122
+ `;
123
+ export {
124
+ N as ApplePayButton
125
+ };
@@ -0,0 +1,7 @@
1
+ function s(i) {
2
+ const n = i.authenticationMethods?.email !== void 0, t = i.authenticationMethods?.sms !== void 0;
3
+ return n ? t ? { missingVerification: null } : { missingVerification: "sms" } : { missingVerification: "email" };
4
+ }
5
+ export {
6
+ s as checkUserVerification
7
+ };
@@ -0,0 +1,42 @@
1
+ const n = [
2
+ "onramp_api.load_pending",
3
+ "onramp_api.load_success",
4
+ "onramp_api.load_error",
5
+ "onramp_api.polling_success",
6
+ "onramp_api.commit_error",
7
+ "onramp_api.cancel"
8
+ ];
9
+ function o(s) {
10
+ let e;
11
+ try {
12
+ e = JSON.parse(s);
13
+ } catch {
14
+ return { success: !1, reason: "Invalid JSON" };
15
+ }
16
+ if (!a(e))
17
+ return { success: !1, reason: "Invalid message structure" };
18
+ const r = e.eventName ?? e.type;
19
+ return r ? t(r) ? {
20
+ success: !0,
21
+ event: {
22
+ type: r,
23
+ message: e.message,
24
+ error: {
25
+ code: e.data?.errorCode,
26
+ message: e.data?.errorMessage
27
+ }
28
+ }
29
+ } : { success: !1, reason: "Unknown event type" } : { success: !1, reason: "Missing event type" };
30
+ }
31
+ function a(s) {
32
+ if (typeof s != "object" || s === null)
33
+ return !1;
34
+ const e = s;
35
+ return typeof e.eventName == "string" || typeof e.type == "string";
36
+ }
37
+ function t(s) {
38
+ return n.includes(s);
39
+ }
40
+ export {
41
+ o as parseWebViewMessage
42
+ };
@@ -0,0 +1,75 @@
1
+ import { EndUserApplePayOnrampOrderCreateResponse } from '@coinbase/cdp-api-client';
2
+ import { JSX } from 'react';
3
+ import { Network } from '@coinbase/cdp-api-client';
4
+ import { ReactNode } from 'react';
5
+
6
+ export declare function ApplePayButton({ style }: ApplePayButtonProps): JSX.Element | null;
7
+
8
+ export declare interface ApplePayButtonProps {
9
+ style?: object;
10
+ }
11
+
12
+ export declare interface ApplePayContextValue {
13
+ createOrder: (options: CreateOrderOptions) => Promise<void>;
14
+ data: EndUserApplePayOnrampOrderCreateResponse | undefined;
15
+ status: ApplePayOnrampStatus;
16
+ error: OnrampError | undefined;
17
+ reset: () => void;
18
+ paymentEventHandler: (event: OnrampEvent) => void;
19
+ }
20
+
21
+ export declare type ApplePayOnrampStatus = "idle" | "pending" | "error" | "success";
22
+
23
+ export declare function ApplePayProvider({ children }: ApplePayProviderProps): JSX.Element;
24
+
25
+ export declare interface ApplePayProviderProps {
26
+ children: ReactNode;
27
+ }
28
+
29
+ export declare interface CreateOrderOptions {
30
+ destination: {
31
+ address: string;
32
+ network: Network;
33
+ };
34
+ purchase: {
35
+ amount: string;
36
+ currency: "usdc" | string;
37
+ };
38
+ payment: {
39
+ currency: "usd" | string;
40
+ };
41
+ isSandbox?: boolean;
42
+ }
43
+
44
+ export declare interface OnrampError {
45
+ correlationId?: string;
46
+ message?: string;
47
+ code?: string;
48
+ }
49
+
50
+ declare type OnrampErrorEvent = {
51
+ type: Extract<OnrampEventType, "onramp_api.load_error" | "onramp_api.commit_error" | "onramp_api.polling_error">;
52
+ error: {
53
+ code?: string;
54
+ message?: string;
55
+ };
56
+ };
57
+
58
+ declare type OnrampEvent = {
59
+ type: Exclude<OnrampEventType, "onramp_api.load_error" | "onramp_api.commit_error" | "onramp_api.polling_error">;
60
+ message?: string;
61
+ } | OnrampErrorEvent;
62
+
63
+ declare type OnrampEventType = "onramp_api.load_pending" | "onramp_api.load_success" | "onramp_api.load_error" | "onramp_api.commit_success" | "onramp_api.commit_error" | "onramp_api.cancel" | "onramp_api.polling_start" | "onramp_api.polling_success" | "onramp_api.polling_error";
64
+
65
+ export declare function useApplePay(): UseApplePayReturn;
66
+
67
+ export declare interface UseApplePayReturn {
68
+ createOrder: (options: CreateOrderOptions) => Promise<void>;
69
+ data: EndUserApplePayOnrampOrderCreateResponse | undefined;
70
+ status: ApplePayOnrampStatus;
71
+ error: OnrampError | undefined;
72
+ reset: () => void;
73
+ }
74
+
75
+ export { }
package/package.json CHANGED
@@ -1,8 +1,45 @@
1
1
  {
2
2
  "name": "@coinbase/cdp-react-native",
3
- "version": "0.0.0",
4
- "description": "Placeholder package",
5
- "main": "index.js",
6
- "author": "Coinbase Inc.",
7
- "license": "Apache-2.0"
8
- }
3
+ "version": "0.0.82",
4
+ "type": "module",
5
+ "peerDependencies": {
6
+ "react": ">=18.2.0",
7
+ "react-native": ">=0.70.0",
8
+ "react-native-webview": ">=13.0.0",
9
+ "@coinbase/cdp-core": "^0.0.82",
10
+ "@coinbase/cdp-hooks": "^0.0.82",
11
+ "@coinbase/cdp-api-client": "^0.0.82"
12
+ },
13
+ "devDependencies": {
14
+ "@testing-library/react": "^16.0.0",
15
+ "@types/react": "^19.0.0",
16
+ "react": "^19.1.2",
17
+ "react-dom": "^19.1.2",
18
+ "react-native": "^0.79.6",
19
+ "react-native-webview": "^13.13.5",
20
+ "@coinbase/cdp-api-client": "0.0.82",
21
+ "@coinbase/cdp-core": "0.0.82",
22
+ "@coinbase/cdp-hooks": "0.0.82"
23
+ },
24
+ "files": [
25
+ "dist/**",
26
+ "!dist/**/*.tsbuildinfo"
27
+ ],
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/types/index.d.ts",
31
+ "default": "./dist/esm/index.js"
32
+ },
33
+ "./package.json": "./package.json"
34
+ },
35
+ "scripts": {
36
+ "build": "pnpm run check:types && vite build --config ../../vite.config.base.ts",
37
+ "build:watch": "vite build --config ../../vite.config.base.ts --watch",
38
+ "check:types": "tsc --noEmit",
39
+ "clean": "rm -rf dist",
40
+ "clean:all": "pnpm clean && rm -rf node_modules",
41
+ "size-limit": "size-limit",
42
+ "test": "vitest",
43
+ "test:run": "vitest --run"
44
+ }
45
+ }
package/index.js DELETED
@@ -1 +0,0 @@
1
- console.log("Temporary package");