@methodfi/opal-react 0.0.1

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,67 @@
1
+ # @methodfi/opal-react
2
+
3
+ React SDK for integrating Method Opal into your web applications.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @methodfi/opal-react
9
+ # or
10
+ yarn add @methodfi/opal-react
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ ### 1. Provider Setup
16
+
17
+ Wrap your app with the `OpalProvider`:
18
+
19
+ ```tsx
20
+ import { OpalProvider } from '@methodfi/opal-react';
21
+
22
+ export default function App() {
23
+ return (
24
+ <OpalProvider>
25
+ <YourAppContent />
26
+ </OpalProvider>
27
+ );
28
+ }
29
+ ```
30
+
31
+ ### 2. Hook Usage
32
+
33
+ Use the `useOpal` hook in your components:
34
+
35
+ ```tsx
36
+ import { useOpal } from '@methodfi/opal-react';
37
+
38
+ function Screen() {
39
+ const { open } = useOpal({
40
+ env: 'dev',
41
+ onOpen: () => {},
42
+ onExit: () => {},
43
+ onError: (error) => console.error('Error:', error),
44
+ onEvent: (event) => {
45
+ switch (event.type) {
46
+ case 'opal.session.started': { /* ... */ }
47
+ case 'opal.session.errored': { /* ... */ }
48
+ case 'opal.session.exited': { /* ... */ }
49
+ case 'card_connect.card.verified': { /* ... */ }
50
+ // See events section
51
+ }
52
+ },
53
+ });
54
+
55
+ const onLaunchOpal = async () => {
56
+ // Resulting token from POST /opal/token (otkn_*)
57
+ const token = await getOpalToken();
58
+ open({ token });
59
+ };
60
+
61
+ return (
62
+ <button onClick={onLaunchOpal}>
63
+ Launch Opal
64
+ </button>
65
+ );
66
+ }
67
+ ```
@@ -0,0 +1,3 @@
1
+ import { OpalIframeProps } from '../types';
2
+ export declare function OpalIframe({ token, opalUrl, onMessage, style, }: OpalIframeProps): import("react/jsx-runtime").JSX.Element | null;
3
+ //# sourceMappingURL=OpalIframe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpalIframe.d.ts","sourceRoot":"","sources":["../../src/components/OpalIframe.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,OAAO,EACP,SAAS,EACT,KAAK,GACN,EAAE,eAAe,kDAuDjB"}
@@ -0,0 +1,34 @@
1
+ import { ReactNode } from 'react';
2
+ import { OpalConfig, OpalOpenOptions, OpalError, OpalErrorData } from '../types';
3
+ interface OpalContextType {
4
+ isOpen: boolean;
5
+ isReady: boolean;
6
+ error: OpalError | OpalErrorData | null;
7
+ open: (options: OpalOpenOptions) => void;
8
+ close: () => void;
9
+ updateConfig: (config: OpalConfig) => void;
10
+ }
11
+ interface OpalProviderProps {
12
+ children: ReactNode;
13
+ }
14
+ /**
15
+ * Provider component that wraps your app to enable Opal functionality.
16
+ * This component manages the Opal iframe state and provides context to child components.
17
+ *
18
+ * @example
19
+ * ```tsx
20
+ * import { OpalProvider } from '@methodfi/opal-react';
21
+ *
22
+ * export default function App() {
23
+ * return (
24
+ * <OpalProvider>
25
+ * <YourAppContent />
26
+ * </OpalProvider>
27
+ * );
28
+ * }
29
+ * ```
30
+ */
31
+ export declare function OpalProvider({ children }: OpalProviderProps): JSX.Element;
32
+ export declare function useOpalContext(): OpalContextType;
33
+ export {};
34
+ //# sourceMappingURL=OpalProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OpalProvider.d.ts","sourceRoot":"","sources":["../../src/components/OpalProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAuC,SAAS,EAAE,MAAM,OAAO,CAAC;AAEvE,OAAO,EACL,UAAU,EACV,eAAe,EAEf,SAAS,EACT,aAAa,EACd,MAAM,UAAU,CAAC;AAGlB,UAAU,eAAe;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,SAAS,GAAG,aAAa,GAAG,IAAI,CAAC;IACxC,IAAI,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IACzC,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,YAAY,EAAE,CAAC,MAAM,EAAE,UAAU,KAAK,IAAI,CAAC;CAC5C;AAID,UAAU,iBAAiB;IACzB,QAAQ,EAAE,SAAS,CAAC;CACrB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,EAAE,iBAAiB,GAAG,GAAG,CAAC,OAAO,CAyFzE;AAED,wBAAgB,cAAc,IAAI,eAAe,CAMhD"}
@@ -0,0 +1,4 @@
1
+ import { OpalEnvironment } from '../types';
2
+ export declare const OPAL_URLS: Record<OpalEnvironment, string>;
3
+ export declare const IFRAME_SCRIPT = "\n (function() {\n // Listen for events from the Opal JS SDK and forward them to the parent window\n window.addEventListener('message', function(event) {\n // Only listen to events from Opal origins\n const allowedOrigins = [\n 'https://opal.production.methodfi.com',\n 'https://opal.sandbox.methodfi.com', \n 'https://opal.dev.methodfi.com',\n 'http://localhost:3000'\n ];\n\n if (!allowedOrigins.includes(event.origin)) return;\n\n // Forward all events from JS SDK to parent window\n if (event.data?.type) {\n window.parent.postMessage(event.data, '*');\n }\n });\n })();\n";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE3C,eAAO,MAAM,SAAS,EAAE,MAAM,CAAC,eAAe,EAAE,MAAM,CAKrD,CAAC;AAEF,eAAO,MAAM,aAAa,spBAoBzB,CAAC"}
@@ -0,0 +1,37 @@
1
+ import { OpalConfig, UseOpalReturn } from '../types';
2
+ /**
3
+ * Hook for interacting with Opal within an OpalProvider context.
4
+ * This hook allows you to configure event handlers and open/close Opal sessions.
5
+ * Supports multiple modes (card_connect, connect, etc.) with flexible event handling.
6
+ *
7
+ * @example
8
+ * ```tsx
9
+ * const { open, close, isReady, isOpen, error } = useOpal({
10
+ * env: 'dev',
11
+ * onOpen: () => console.log('Opal opened'),
12
+ * onExit: () => console.log('Opal closed'),
13
+ * onEvent: (event) => {
14
+ * switch (event.type) {
15
+ * case 'opal.session.started':
16
+ * console.log('Session started');
17
+ * break;
18
+ * case 'card_connect.card.verified':
19
+ * console.log('Card verified:', event.data);
20
+ * break;
21
+ * }
22
+ * },
23
+ * onError: (error) => console.error('Opal error:', error),
24
+ * });
25
+ *
26
+ * // Open Opal with a token
27
+ * const handleOpenOpal = async () => {
28
+ * const token = await getOpalToken(); // Your token fetching logic
29
+ * open({ token });
30
+ * };
31
+ * ```
32
+ *
33
+ * @param config Configuration object with event handlers and environment settings
34
+ * @returns Object with open function and current state
35
+ */
36
+ export declare function useOpal(config?: OpalConfig): UseOpalReturn;
37
+ //# sourceMappingURL=useOpal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOpal.d.ts","sourceRoot":"","sources":["../../src/hooks/useOpal.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAErD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,OAAO,CAAC,MAAM,GAAE,UAAe,GAAG,aAAa,CAe9D"}
@@ -0,0 +1,210 @@
1
+ import { ReactNode } from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
+
4
+ type OpalEnvironment = 'local' | 'dev' | 'sandbox' | 'production';
5
+ type OpalMode = 'opal' | 'card_connect' | 'account_verification' | string;
6
+ type OpalEventObject = 'session' | 'card' | 'account' | 'bank' | string;
7
+ type OpalEventAction = 'started' | 'errored' | 'exited' | 'verified' | 'completed' | string;
8
+ type OpalEventType = 'opal.session.started' | 'opal.session.errored' | 'opal.session.exited' | 'card_connect.session.started' | 'card_connect.session.errored' | 'card_connect.card.verified' | 'account_verification.session.started' | 'account_verification.session.errored' | 'account_verification.account.verified' | string;
9
+ /**
10
+ * Structured event object matching Method's Opal event format
11
+ * Events follow the pattern: <mode>.<object>.<action>
12
+ */
13
+ interface OpalEvent {
14
+ /** The type of event, formatted as <mode>.<object>.<action> */
15
+ type: OpalEventType;
16
+ /** The operational mode associated with the event (e.g., 'card_connect') */
17
+ mode: OpalMode;
18
+ /** The object the event is related to (e.g., 'card', 'session') */
19
+ object: OpalEventObject;
20
+ /** The action that occurred (e.g., 'started', 'verified', 'errored') */
21
+ action: OpalEventAction;
22
+ /** The ISO 8601 timestamp of when the event occurred */
23
+ timestamp: string;
24
+ /** Additional context or details related to the event (varies by event type) */
25
+ data?: OpalEventData | null;
26
+ }
27
+ /**
28
+ * Error data structure for Opal session errors
29
+ */
30
+ interface OpalErrorData {
31
+ /** Error type identifier */
32
+ type: string;
33
+ /** Error sub-type for more specific categorization */
34
+ sub_type?: string;
35
+ /** Human-readable error message */
36
+ message: string;
37
+ }
38
+ /**
39
+ * Card verification event data
40
+ */
41
+ interface CardVerifiedEventData {
42
+ /** The account ID of the verified card */
43
+ account: string;
44
+ /** Additional metadata about the card verification */
45
+ metadata?: Record<string, any>;
46
+ }
47
+ /**
48
+ * Account verification event data
49
+ */
50
+ interface AccountVerifiedEventData {
51
+ /** The account ID of the verified account */
52
+ account: string;
53
+ /** Account verification details */
54
+ account_verification?: {
55
+ account_id: string;
56
+ type: string;
57
+ [key: string]: any;
58
+ };
59
+ /** Additional metadata */
60
+ metadata?: Record<string, any>;
61
+ }
62
+ /**
63
+ * Union type for all possible event data structures
64
+ */
65
+ type OpalEventData = OpalErrorData | CardVerifiedEventData | AccountVerifiedEventData | Record<string, any>;
66
+ /**
67
+ * Legacy error interface for backward compatibility
68
+ */
69
+ interface OpalError {
70
+ code: string;
71
+ message: string;
72
+ type: 'api_error' | 'connection_error' | 'validation_error';
73
+ }
74
+ /**
75
+ * Configuration object for the useOpal hook
76
+ */
77
+ interface OpalConfig {
78
+ /** Environment to connect to (default: 'production') */
79
+ env?: OpalEnvironment;
80
+ /** Called when Opal opens */
81
+ onOpen?: () => void;
82
+ /** Called when Opal closes */
83
+ onExit?: (data?: any) => void;
84
+ /** Called for all Opal events with properly typed event object */
85
+ onEvent?: (event: OpalEvent) => void;
86
+ /** Called when an error occurs */
87
+ onError?: (error: OpalErrorData) => void;
88
+ /** Called on successful completion */
89
+ onSuccess?: (data: OpalSuccessData) => void;
90
+ }
91
+ /**
92
+ * Success data structure for completed Opal sessions
93
+ */
94
+ interface OpalSuccessData {
95
+ /** The session ID of the completed session */
96
+ sessionId: string;
97
+ /** Additional metadata from the session */
98
+ metadata?: Record<string, any>;
99
+ }
100
+ /**
101
+ * Options for opening an Opal session
102
+ */
103
+ interface OpalOpenOptions {
104
+ /** The Opal token (otkn_*) obtained from POST /opal/token */
105
+ token: string;
106
+ }
107
+ /**
108
+ * Legacy message interface - use OpalEvent instead
109
+ * @deprecated Use OpalEvent for better type safety
110
+ */
111
+ interface OpalMessage {
112
+ type: string;
113
+ mode: string;
114
+ object: string;
115
+ action: string;
116
+ timestamp: string;
117
+ }
118
+ /**
119
+ * Return type for the useOpal hook
120
+ */
121
+ interface UseOpalReturn {
122
+ /** Opens Opal with the provided token and options */
123
+ open: (options: OpalOpenOptions) => void;
124
+ /** Closes the current Opal session */
125
+ close: () => void;
126
+ /** Whether Opal is loaded and ready for interaction */
127
+ isReady: boolean;
128
+ /** Whether Opal is currently open */
129
+ isOpen: boolean;
130
+ /** Current error state, if any */
131
+ error: OpalError | OpalErrorData | null;
132
+ }
133
+ /**
134
+ * Props for the OpalIframe component
135
+ */
136
+ interface OpalIframeProps {
137
+ /** The Opal token */
138
+ token: string;
139
+ /** The full Opal URL with token */
140
+ opalUrl: string;
141
+ /** Callback for handling iframe messages */
142
+ onMessage: (message: OpalEvent) => void;
143
+ /** Callback for when the iframe should be closed */
144
+ onClose: () => void;
145
+ /** Optional styles for the iframe container */
146
+ style?: React.CSSProperties;
147
+ }
148
+
149
+ interface OpalProviderProps {
150
+ children: ReactNode;
151
+ }
152
+ /**
153
+ * Provider component that wraps your app to enable Opal functionality.
154
+ * This component manages the Opal iframe state and provides context to child components.
155
+ *
156
+ * @example
157
+ * ```tsx
158
+ * import { OpalProvider } from '@methodfi/opal-react';
159
+ *
160
+ * export default function App() {
161
+ * return (
162
+ * <OpalProvider>
163
+ * <YourAppContent />
164
+ * </OpalProvider>
165
+ * );
166
+ * }
167
+ * ```
168
+ */
169
+ declare function OpalProvider({ children }: OpalProviderProps): JSX.Element;
170
+
171
+ /**
172
+ * Hook for interacting with Opal within an OpalProvider context.
173
+ * This hook allows you to configure event handlers and open/close Opal sessions.
174
+ * Supports multiple modes (card_connect, connect, etc.) with flexible event handling.
175
+ *
176
+ * @example
177
+ * ```tsx
178
+ * const { open, close, isReady, isOpen, error } = useOpal({
179
+ * env: 'dev',
180
+ * onOpen: () => console.log('Opal opened'),
181
+ * onExit: () => console.log('Opal closed'),
182
+ * onEvent: (event) => {
183
+ * switch (event.type) {
184
+ * case 'opal.session.started':
185
+ * console.log('Session started');
186
+ * break;
187
+ * case 'card_connect.card.verified':
188
+ * console.log('Card verified:', event.data);
189
+ * break;
190
+ * }
191
+ * },
192
+ * onError: (error) => console.error('Opal error:', error),
193
+ * });
194
+ *
195
+ * // Open Opal with a token
196
+ * const handleOpenOpal = async () => {
197
+ * const token = await getOpalToken(); // Your token fetching logic
198
+ * open({ token });
199
+ * };
200
+ * ```
201
+ *
202
+ * @param config Configuration object with event handlers and environment settings
203
+ * @returns Object with open function and current state
204
+ */
205
+ declare function useOpal(config?: OpalConfig): UseOpalReturn;
206
+
207
+ declare function OpalIframe({ token, opalUrl, onMessage, style, }: OpalIframeProps): react_jsx_runtime.JSX.Element | null;
208
+
209
+ export { OpalIframe, OpalProvider, useOpal };
210
+ export type { AccountVerifiedEventData, CardVerifiedEventData, OpalConfig, OpalEnvironment, OpalError, OpalErrorData, OpalEvent, OpalEventAction, OpalEventData, OpalEventObject, OpalEventType, OpalIframeProps, OpalMessage, OpalMode, OpalOpenOptions, OpalSuccessData, UseOpalReturn };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AAC1C,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC"}