@swype-org/deposit-mobile 0.2.0

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.
@@ -0,0 +1,70 @@
1
+ import { M as MobileDepositStatus, D as DepositResult, a as DepositError, c as DepositRequest, b as MobileDepositConfig } from './types-Df_KwICF.cjs';
2
+ export { j as getDisplayMessage } from './types-Df_KwICF.cjs';
3
+
4
+ interface UseBlinkMobileDepositReturn {
5
+ /** Current phase of the deposit flow. */
6
+ status: MobileDepositStatus;
7
+ /** Last successful deposit result, or `null`. */
8
+ result: DepositResult | null;
9
+ /** Last deposit error, or `null`. */
10
+ error: DepositError | null;
11
+ /** User-friendly error message derived from the current error, or `null`. */
12
+ displayMessage: string | null;
13
+ /** Whether a deposit flow is currently in progress. */
14
+ isActive: boolean;
15
+ /** Start a deposit flow. */
16
+ requestDeposit: (request: DepositRequest) => Promise<DepositResult>;
17
+ /**
18
+ * Pass an incoming deep link URL to the SDK. Returns `true` if the URL
19
+ * was a Swype callback, `false` otherwise.
20
+ *
21
+ * Call this from your deep link listener (e.g. `Linking.addEventListener`).
22
+ */
23
+ handleDeepLink: (url: string) => boolean;
24
+ /** Cancel the current flow and reset to idle. */
25
+ close: () => void;
26
+ }
27
+ /**
28
+ * React / React Native hook that wraps {@link MobileDeposit} with reactive state.
29
+ *
30
+ * ```tsx
31
+ * import { useBlinkMobileDeposit } from '@swype-org/deposit-mobile/react-native';
32
+ * import * as Linking from 'expo-linking';
33
+ * import * as WebBrowser from 'expo-web-browser';
34
+ *
35
+ * function DepositButton() {
36
+ * const { status, result, error, displayMessage, requestDeposit, handleDeepLink } =
37
+ * useBlinkMobileDeposit({
38
+ * signer: 'https://api.merchant.com/sign-payment',
39
+ * callbackScheme: 'myapp',
40
+ * openUrl: (url) => WebBrowser.openBrowserAsync(url).then(() => {}),
41
+ * });
42
+ *
43
+ * useEffect(() => {
44
+ * const sub = Linking.addEventListener('url', ({ url }) => handleDeepLink(url));
45
+ * return () => sub.remove();
46
+ * }, [handleDeepLink]);
47
+ *
48
+ * return (
49
+ * <>
50
+ * <Button
51
+ * title={status === 'signer-loading' ? 'Preparing…' : 'Deposit $50'}
52
+ * disabled={status === 'signer-loading'}
53
+ * onPress={() =>
54
+ * requestDeposit({ amount: 50, chainId: 8453, address: '0x...', token: 'USDC' })
55
+ * }
56
+ * />
57
+ * {error && <Text>{displayMessage}</Text>}
58
+ * {result && <Text>Transfer {result.transfer.id} complete!</Text>}
59
+ * </>
60
+ * );
61
+ * }
62
+ * ```
63
+ */
64
+ declare function useBlinkMobileDeposit(config: MobileDepositConfig): UseBlinkMobileDepositReturn;
65
+ /** @deprecated Use {@link useBlinkMobileDeposit} instead. */
66
+ declare const useSwypeMobileCheckout: typeof useBlinkMobileDeposit;
67
+ /** @deprecated Use {@link UseBlinkMobileDepositReturn} instead. */
68
+ type UseSwypeMobileCheckoutReturn = UseBlinkMobileDepositReturn;
69
+
70
+ export { DepositError, DepositRequest, DepositResult, MobileDepositConfig, MobileDepositStatus, type UseSwypeMobileCheckoutReturn, useBlinkMobileDeposit, useSwypeMobileCheckout };
@@ -0,0 +1,70 @@
1
+ import { M as MobileDepositStatus, D as DepositResult, a as DepositError, c as DepositRequest, b as MobileDepositConfig } from './types-Df_KwICF.js';
2
+ export { j as getDisplayMessage } from './types-Df_KwICF.js';
3
+
4
+ interface UseBlinkMobileDepositReturn {
5
+ /** Current phase of the deposit flow. */
6
+ status: MobileDepositStatus;
7
+ /** Last successful deposit result, or `null`. */
8
+ result: DepositResult | null;
9
+ /** Last deposit error, or `null`. */
10
+ error: DepositError | null;
11
+ /** User-friendly error message derived from the current error, or `null`. */
12
+ displayMessage: string | null;
13
+ /** Whether a deposit flow is currently in progress. */
14
+ isActive: boolean;
15
+ /** Start a deposit flow. */
16
+ requestDeposit: (request: DepositRequest) => Promise<DepositResult>;
17
+ /**
18
+ * Pass an incoming deep link URL to the SDK. Returns `true` if the URL
19
+ * was a Swype callback, `false` otherwise.
20
+ *
21
+ * Call this from your deep link listener (e.g. `Linking.addEventListener`).
22
+ */
23
+ handleDeepLink: (url: string) => boolean;
24
+ /** Cancel the current flow and reset to idle. */
25
+ close: () => void;
26
+ }
27
+ /**
28
+ * React / React Native hook that wraps {@link MobileDeposit} with reactive state.
29
+ *
30
+ * ```tsx
31
+ * import { useBlinkMobileDeposit } from '@swype-org/deposit-mobile/react-native';
32
+ * import * as Linking from 'expo-linking';
33
+ * import * as WebBrowser from 'expo-web-browser';
34
+ *
35
+ * function DepositButton() {
36
+ * const { status, result, error, displayMessage, requestDeposit, handleDeepLink } =
37
+ * useBlinkMobileDeposit({
38
+ * signer: 'https://api.merchant.com/sign-payment',
39
+ * callbackScheme: 'myapp',
40
+ * openUrl: (url) => WebBrowser.openBrowserAsync(url).then(() => {}),
41
+ * });
42
+ *
43
+ * useEffect(() => {
44
+ * const sub = Linking.addEventListener('url', ({ url }) => handleDeepLink(url));
45
+ * return () => sub.remove();
46
+ * }, [handleDeepLink]);
47
+ *
48
+ * return (
49
+ * <>
50
+ * <Button
51
+ * title={status === 'signer-loading' ? 'Preparing…' : 'Deposit $50'}
52
+ * disabled={status === 'signer-loading'}
53
+ * onPress={() =>
54
+ * requestDeposit({ amount: 50, chainId: 8453, address: '0x...', token: 'USDC' })
55
+ * }
56
+ * />
57
+ * {error && <Text>{displayMessage}</Text>}
58
+ * {result && <Text>Transfer {result.transfer.id} complete!</Text>}
59
+ * </>
60
+ * );
61
+ * }
62
+ * ```
63
+ */
64
+ declare function useBlinkMobileDeposit(config: MobileDepositConfig): UseBlinkMobileDepositReturn;
65
+ /** @deprecated Use {@link useBlinkMobileDeposit} instead. */
66
+ declare const useSwypeMobileCheckout: typeof useBlinkMobileDeposit;
67
+ /** @deprecated Use {@link UseBlinkMobileDepositReturn} instead. */
68
+ type UseSwypeMobileCheckoutReturn = UseBlinkMobileDepositReturn;
69
+
70
+ export { DepositError, DepositRequest, DepositResult, MobileDepositConfig, MobileDepositStatus, type UseSwypeMobileCheckoutReturn, useBlinkMobileDeposit, useSwypeMobileCheckout };
@@ -0,0 +1,49 @@
1
+ import { MobileDeposit, getDisplayMessage } from './chunk-QIPX2XQS.js';
2
+ export { DepositError, getDisplayMessage } from './chunk-QIPX2XQS.js';
3
+ import { useRef, useState, useEffect, useCallback } from 'react';
4
+
5
+ function useBlinkMobileDeposit(config) {
6
+ const depositRef = useRef(null);
7
+ const [status, setStatus] = useState("idle");
8
+ const [result, setResult] = useState(null);
9
+ const [error, setError] = useState(null);
10
+ if (!depositRef.current) {
11
+ depositRef.current = new MobileDeposit(config);
12
+ }
13
+ useEffect(() => {
14
+ const deposit = depositRef.current;
15
+ const onStatusChange = (s) => setStatus(s);
16
+ const onComplete = (r) => {
17
+ setResult(r);
18
+ setError(null);
19
+ };
20
+ const onError = (e) => setError(e);
21
+ deposit.on("status-change", onStatusChange);
22
+ deposit.on("complete", onComplete);
23
+ deposit.on("error", onError);
24
+ return () => {
25
+ deposit.off("status-change", onStatusChange);
26
+ deposit.off("complete", onComplete);
27
+ deposit.off("error", onError);
28
+ deposit.destroy();
29
+ depositRef.current = null;
30
+ };
31
+ }, []);
32
+ const requestDeposit = useCallback(
33
+ (request) => depositRef.current.requestDeposit(request),
34
+ []
35
+ );
36
+ const handleDeepLink = useCallback(
37
+ (url) => depositRef.current?.handleDeepLink(url) ?? false,
38
+ []
39
+ );
40
+ const close = useCallback(() => depositRef.current?.close(), []);
41
+ const displayMessage = error ? getDisplayMessage(error) : null;
42
+ const isActive = status === "signer-loading" || status === "browser-active";
43
+ return { status, result, error, displayMessage, isActive, requestDeposit, handleDeepLink, close };
44
+ }
45
+ var useSwypeMobileCheckout = useBlinkMobileDeposit;
46
+
47
+ export { useBlinkMobileDeposit, useSwypeMobileCheckout };
48
+ //# sourceMappingURL=react-native.js.map
49
+ //# sourceMappingURL=react-native.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react-native.ts"],"names":[],"mappings":";;;;AA2EO,SAAS,sBACd,MAAA,EAC6B;AAC7B,EAAA,MAAM,UAAA,GAAa,OAA6B,IAAI,CAAA;AACpD,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA8B,MAAM,CAAA;AAChE,EAAA,MAAM,CAAC,MAAA,EAAQ,SAAS,CAAA,GAAI,SAA+B,IAAI,CAAA;AAC/D,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAI,SAA8B,IAAI,CAAA;AAE5D,EAAA,IAAI,CAAC,WAAW,OAAA,EAAS;AACvB,IAAA,UAAA,CAAW,OAAA,GAAU,IAAI,aAAA,CAAc,MAAM,CAAA;AAAA,EAC/C;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAU,UAAA,CAAW,OAAA;AAE3B,IAAA,MAAM,cAAA,GAAiB,CAAC,CAAA,KAA2B,SAAA,CAAU,CAAC,CAAA;AAC9D,IAAA,MAAM,UAAA,GAAa,CAAC,CAAA,KAAqB;AACvC,MAAA,SAAA,CAAU,CAAC,CAAA;AACX,MAAA,QAAA,CAAS,IAAI,CAAA;AAAA,IACf,CAAA;AACA,IAAA,MAAM,OAAA,GAAU,CAAC,CAAA,KAAoB,QAAA,CAAS,CAAC,CAAA;AAE/C,IAAA,OAAA,CAAQ,EAAA,CAAG,iBAAiB,cAAc,CAAA;AAC1C,IAAA,OAAA,CAAQ,EAAA,CAAG,YAAY,UAAU,CAAA;AACjC,IAAA,OAAA,CAAQ,EAAA,CAAG,SAAS,OAAO,CAAA;AAE3B,IAAA,OAAO,MAAM;AACX,MAAA,OAAA,CAAQ,GAAA,CAAI,iBAAiB,cAAc,CAAA;AAC3C,MAAA,OAAA,CAAQ,GAAA,CAAI,YAAY,UAAU,CAAA;AAClC,MAAA,OAAA,CAAQ,GAAA,CAAI,SAAS,OAAO,CAAA;AAC5B,MAAA,OAAA,CAAQ,OAAA,EAAQ;AAChB,MAAA,UAAA,CAAW,OAAA,GAAU,IAAA;AAAA,IACvB,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IACrB,CAAC,OAAA,KAA4B,UAAA,CAAW,OAAA,CAAS,eAAe,OAAO,CAAA;AAAA,IACvE;AAAC,GACH;AAEA,EAAA,MAAM,cAAA,GAAiB,WAAA;AAAA,IACrB,CAAC,GAAA,KAAgB,UAAA,CAAW,OAAA,EAAS,cAAA,CAAe,GAAG,CAAA,IAAK,KAAA;AAAA,IAC5D;AAAC,GACH;AAEA,EAAA,MAAM,KAAA,GAAQ,YAAY,MAAM,UAAA,CAAW,SAAS,KAAA,EAAM,EAAG,EAAE,CAAA;AAE/D,EAAA,MAAM,cAAA,GAAiB,KAAA,GAAQ,iBAAA,CAAkB,KAAK,CAAA,GAAI,IAAA;AAC1D,EAAA,MAAM,QAAA,GAAW,MAAA,KAAW,gBAAA,IAAoB,MAAA,KAAW,gBAAA;AAE3D,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAQ,KAAA,EAAO,gBAAgB,QAAA,EAAU,cAAA,EAAgB,gBAAgB,KAAA,EAAM;AAClG;AAGO,IAAM,sBAAA,GAAyB","file":"react-native.js","sourcesContent":["import { useCallback, useEffect, useRef, useState } from 'react';\n\nimport { MobileDeposit } from './mobile-deposit.ts';\nimport { DepositError, getDisplayMessage } from './errors.ts';\nimport type {\n MobileDepositConfig,\n MobileDepositStatus,\n DepositRequest,\n DepositResult,\n} from './types.ts';\n\nexport type { MobileDepositConfig, MobileDepositStatus, DepositRequest, DepositResult };\nexport { DepositError, getDisplayMessage };\n\ninterface UseBlinkMobileDepositReturn {\n /** Current phase of the deposit flow. */\n status: MobileDepositStatus;\n /** Last successful deposit result, or `null`. */\n result: DepositResult | null;\n /** Last deposit error, or `null`. */\n error: DepositError | null;\n /** User-friendly error message derived from the current error, or `null`. */\n displayMessage: string | null;\n /** Whether a deposit flow is currently in progress. */\n isActive: boolean;\n /** Start a deposit flow. */\n requestDeposit: (request: DepositRequest) => Promise<DepositResult>;\n /**\n * Pass an incoming deep link URL to the SDK. Returns `true` if the URL\n * was a Swype callback, `false` otherwise.\n *\n * Call this from your deep link listener (e.g. `Linking.addEventListener`).\n */\n handleDeepLink: (url: string) => boolean;\n /** Cancel the current flow and reset to idle. */\n close: () => void;\n}\n\n/**\n * React / React Native hook that wraps {@link MobileDeposit} with reactive state.\n *\n * ```tsx\n * import { useBlinkMobileDeposit } from '@swype-org/deposit-mobile/react-native';\n * import * as Linking from 'expo-linking';\n * import * as WebBrowser from 'expo-web-browser';\n *\n * function DepositButton() {\n * const { status, result, error, displayMessage, requestDeposit, handleDeepLink } =\n * useBlinkMobileDeposit({\n * signer: 'https://api.merchant.com/sign-payment',\n * callbackScheme: 'myapp',\n * openUrl: (url) => WebBrowser.openBrowserAsync(url).then(() => {}),\n * });\n *\n * useEffect(() => {\n * const sub = Linking.addEventListener('url', ({ url }) => handleDeepLink(url));\n * return () => sub.remove();\n * }, [handleDeepLink]);\n *\n * return (\n * <>\n * <Button\n * title={status === 'signer-loading' ? 'Preparing…' : 'Deposit $50'}\n * disabled={status === 'signer-loading'}\n * onPress={() =>\n * requestDeposit({ amount: 50, chainId: 8453, address: '0x...', token: 'USDC' })\n * }\n * />\n * {error && <Text>{displayMessage}</Text>}\n * {result && <Text>Transfer {result.transfer.id} complete!</Text>}\n * </>\n * );\n * }\n * ```\n */\nexport function useBlinkMobileDeposit(\n config: MobileDepositConfig,\n): UseBlinkMobileDepositReturn {\n const depositRef = useRef<MobileDeposit | null>(null);\n const [status, setStatus] = useState<MobileDepositStatus>('idle');\n const [result, setResult] = useState<DepositResult | null>(null);\n const [error, setError] = useState<DepositError | null>(null);\n\n if (!depositRef.current) {\n depositRef.current = new MobileDeposit(config);\n }\n\n useEffect(() => {\n const deposit = depositRef.current!;\n\n const onStatusChange = (s: MobileDepositStatus) => setStatus(s);\n const onComplete = (r: DepositResult) => {\n setResult(r);\n setError(null);\n };\n const onError = (e: DepositError) => setError(e);\n\n deposit.on('status-change', onStatusChange);\n deposit.on('complete', onComplete);\n deposit.on('error', onError);\n\n return () => {\n deposit.off('status-change', onStatusChange);\n deposit.off('complete', onComplete);\n deposit.off('error', onError);\n deposit.destroy();\n depositRef.current = null;\n };\n }, []);\n\n const requestDeposit = useCallback(\n (request: DepositRequest) => depositRef.current!.requestDeposit(request),\n [],\n );\n\n const handleDeepLink = useCallback(\n (url: string) => depositRef.current?.handleDeepLink(url) ?? false,\n [],\n );\n\n const close = useCallback(() => depositRef.current?.close(), []);\n\n const displayMessage = error ? getDisplayMessage(error) : null;\n const isActive = status === 'signer-loading' || status === 'browser-active';\n\n return { status, result, error, displayMessage, isActive, requestDeposit, handleDeepLink, close };\n}\n\n/** @deprecated Use {@link useBlinkMobileDeposit} instead. */\nexport const useSwypeMobileCheckout = useBlinkMobileDeposit;\n\n/** @deprecated Use {@link UseBlinkMobileDepositReturn} instead. */\nexport type UseSwypeMobileCheckoutReturn = UseBlinkMobileDepositReturn;\n"]}
@@ -0,0 +1,179 @@
1
+ type DepositMobileErrorCode = 'BROWSER_FAILED' | 'BROWSER_DISMISSED' | 'DEEP_LINK_INVALID' | 'SIGNER_REQUEST_FAILED' | 'SIGNER_NETWORK_ERROR' | 'SIGNER_RESPONSE_INVALID' | 'SIGNER_TIMEOUT' | 'FLOW_TIMEOUT' | 'INVALID_REQUEST';
2
+ /**
3
+ * Structured error thrown by the mobile deposit SDK.
4
+ *
5
+ * Every error carries a machine-readable {@link code} so merchants can
6
+ * branch on failure mode without parsing message strings.
7
+ */
8
+ declare class DepositError extends Error {
9
+ readonly code: DepositMobileErrorCode;
10
+ constructor(code: DepositMobileErrorCode, message: string);
11
+ }
12
+ /**
13
+ * Return a user-friendly display string for a {@link DepositError}.
14
+ *
15
+ * Merchants can show this directly in their UI without maintaining their own
16
+ * copy for each error code.
17
+ */
18
+ declare function getDisplayMessage(error: DepositError): string;
19
+ /** @deprecated Use {@link DepositMobileErrorCode} instead. */
20
+ type CheckoutErrorCode = DepositMobileErrorCode;
21
+ /** @deprecated Use {@link DepositError} instead. */
22
+ declare const CheckoutError: typeof DepositError;
23
+
24
+ /** Current phase of the mobile deposit flow. */
25
+ type MobileDepositStatus = 'idle' | 'signer-loading' | 'browser-active' | 'completed' | 'error';
26
+ /** Configuration for the {@link MobileDeposit} instance. */
27
+ interface MobileDepositConfig {
28
+ /**
29
+ * Merchant signer — either a URL string or a custom async function.
30
+ *
31
+ * **String:** The SDK sends a `POST` with a JSON `SignerRequest` body to this
32
+ * URL and expects a `SignerResponse` back. This is the simplest integration.
33
+ *
34
+ * **Function:** The SDK calls the function with a `SignerRequest` and expects
35
+ * a `Promise<SignerResponse>`. Use this when you need control over the HTTP
36
+ * method, authentication headers, request transformation, or any other
37
+ * aspect of the signing request.
38
+ */
39
+ signer: string | SignerFunction;
40
+ /**
41
+ * Base URL of the hosted payment webview app.
42
+ *
43
+ * The SDK appends `merchantId`, `payload`, and `signature` query parameters
44
+ * to this URL and opens it in the in-app browser.
45
+ *
46
+ * @default 'https://pay-staging.tryblink.xyz'
47
+ */
48
+ webviewBaseUrl?: string;
49
+ /**
50
+ * Custom URL scheme registered by the mobile app (e.g. `'myapp'`).
51
+ *
52
+ * The hosted payment flow redirects to `{callbackScheme}://swype/callback?...`
53
+ * when the user completes or cancels the payment. The app must listen for
54
+ * this deep link and pass it to {@link MobileDeposit.handleDeepLink}.
55
+ */
56
+ callbackScheme: string;
57
+ /**
58
+ * Path component of the callback deep link.
59
+ *
60
+ * @default '/swype/callback'
61
+ */
62
+ callbackPath?: string;
63
+ /**
64
+ * Function that opens a URL in an in-app browser.
65
+ *
66
+ * The SDK calls this to launch the hosted payment flow. Use your preferred
67
+ * in-app browser implementation:
68
+ *
69
+ * - React Native: `expo-web-browser` (`WebBrowser.openBrowserAsync`)
70
+ * - iOS native: `SFSafariViewController`
71
+ * - Android native: `CustomTabsIntent`
72
+ *
73
+ * The returned promise should resolve when the browser is dismissed
74
+ * (regardless of whether the user completed payment — the actual result
75
+ * arrives via deep link).
76
+ */
77
+ openUrl: (url: string) => Promise<void>;
78
+ /**
79
+ * Maximum time in milliseconds to wait for the signer endpoint to respond.
80
+ *
81
+ * @default 15000
82
+ */
83
+ signerTimeoutMs?: number;
84
+ /**
85
+ * Maximum time in milliseconds for the entire deposit flow (signer + user
86
+ * completion). When exceeded the promise rejects with a `FLOW_TIMEOUT`
87
+ * error. `undefined` means no limit.
88
+ */
89
+ flowTimeoutMs?: number;
90
+ /**
91
+ * When `true`, the SDK logs lifecycle events to `console.debug`.
92
+ *
93
+ * @default false
94
+ */
95
+ debug?: boolean;
96
+ }
97
+ /** Parameters for a single deposit request. */
98
+ interface DepositRequest {
99
+ /** USD amount to deposit (must be > 0). */
100
+ amount: number;
101
+ /** EVM chain ID for the destination (e.g. 8453 for Base). */
102
+ chainId: number;
103
+ /** Destination wallet address (0x-prefixed, 40 hex chars). */
104
+ address: string;
105
+ /** Token contract address on the destination chain (e.g. `'0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'`). */
106
+ token: string;
107
+ /** Merchant order or invoice ID for reconciliation. */
108
+ reference?: string;
109
+ /** Arbitrary key-value pairs forwarded to the signer endpoint. */
110
+ metadata?: Record<string, string>;
111
+ }
112
+ /** Result returned when a deposit completes successfully. */
113
+ interface DepositResult {
114
+ transfer: TransferSummary;
115
+ /** Idempotency key from the signer response, if available. */
116
+ idempotencyKey?: string;
117
+ /** Signer preview echoed back for merchant-side display / logging. */
118
+ preview?: {
119
+ amount: number;
120
+ chainId: number;
121
+ address: string;
122
+ token: string;
123
+ };
124
+ }
125
+ /** Subset of transfer data returned from the hosted flow on completion. */
126
+ interface TransferSummary {
127
+ id: string;
128
+ status: string;
129
+ amount?: {
130
+ amount: number;
131
+ currency: string;
132
+ };
133
+ destinations?: Array<{
134
+ chainId: string;
135
+ address: string;
136
+ token?: {
137
+ address?: string;
138
+ symbol?: string;
139
+ };
140
+ }>;
141
+ }
142
+ /** Shape returned by the merchant signer. */
143
+ interface SignerResponse {
144
+ merchantId: string;
145
+ payload: string;
146
+ signature: string;
147
+ expiresAt?: string;
148
+ preview: {
149
+ amount: number;
150
+ chainId: number;
151
+ address: string;
152
+ token: string;
153
+ idempotencyKey: string;
154
+ };
155
+ }
156
+ /** Data passed to the merchant signer describing the payment to sign. */
157
+ interface SignerRequest {
158
+ amount: number;
159
+ chainId: number;
160
+ address: string;
161
+ token: string;
162
+ callbackScheme: string | null;
163
+ url: string;
164
+ version: 'v1';
165
+ reference?: string;
166
+ metadata?: Record<string, string>;
167
+ }
168
+ /**
169
+ * Async function that receives a {@link SignerRequest} and returns a
170
+ * {@link SignerResponse}. Use this when you need full control over how
171
+ * the signing request is made (custom HTTP method, auth headers, etc.).
172
+ */
173
+ type SignerFunction = (data: SignerRequest) => Promise<SignerResponse>;
174
+ /** @deprecated Use {@link MobileDepositStatus} instead. */
175
+ type MobileCheckoutStatus = MobileDepositStatus;
176
+ /** @deprecated Use {@link MobileDepositConfig} instead. */
177
+ type MobileCheckoutConfig = MobileDepositConfig;
178
+
179
+ export { CheckoutError as C, type DepositResult as D, type MobileDepositStatus as M, type SignerFunction as S, type TransferSummary as T, DepositError as a, type MobileDepositConfig as b, type DepositRequest as c, type CheckoutErrorCode as d, type DepositMobileErrorCode as e, type MobileCheckoutConfig as f, type MobileCheckoutStatus as g, type SignerRequest as h, type SignerResponse as i, getDisplayMessage as j };
@@ -0,0 +1,179 @@
1
+ type DepositMobileErrorCode = 'BROWSER_FAILED' | 'BROWSER_DISMISSED' | 'DEEP_LINK_INVALID' | 'SIGNER_REQUEST_FAILED' | 'SIGNER_NETWORK_ERROR' | 'SIGNER_RESPONSE_INVALID' | 'SIGNER_TIMEOUT' | 'FLOW_TIMEOUT' | 'INVALID_REQUEST';
2
+ /**
3
+ * Structured error thrown by the mobile deposit SDK.
4
+ *
5
+ * Every error carries a machine-readable {@link code} so merchants can
6
+ * branch on failure mode without parsing message strings.
7
+ */
8
+ declare class DepositError extends Error {
9
+ readonly code: DepositMobileErrorCode;
10
+ constructor(code: DepositMobileErrorCode, message: string);
11
+ }
12
+ /**
13
+ * Return a user-friendly display string for a {@link DepositError}.
14
+ *
15
+ * Merchants can show this directly in their UI without maintaining their own
16
+ * copy for each error code.
17
+ */
18
+ declare function getDisplayMessage(error: DepositError): string;
19
+ /** @deprecated Use {@link DepositMobileErrorCode} instead. */
20
+ type CheckoutErrorCode = DepositMobileErrorCode;
21
+ /** @deprecated Use {@link DepositError} instead. */
22
+ declare const CheckoutError: typeof DepositError;
23
+
24
+ /** Current phase of the mobile deposit flow. */
25
+ type MobileDepositStatus = 'idle' | 'signer-loading' | 'browser-active' | 'completed' | 'error';
26
+ /** Configuration for the {@link MobileDeposit} instance. */
27
+ interface MobileDepositConfig {
28
+ /**
29
+ * Merchant signer — either a URL string or a custom async function.
30
+ *
31
+ * **String:** The SDK sends a `POST` with a JSON `SignerRequest` body to this
32
+ * URL and expects a `SignerResponse` back. This is the simplest integration.
33
+ *
34
+ * **Function:** The SDK calls the function with a `SignerRequest` and expects
35
+ * a `Promise<SignerResponse>`. Use this when you need control over the HTTP
36
+ * method, authentication headers, request transformation, or any other
37
+ * aspect of the signing request.
38
+ */
39
+ signer: string | SignerFunction;
40
+ /**
41
+ * Base URL of the hosted payment webview app.
42
+ *
43
+ * The SDK appends `merchantId`, `payload`, and `signature` query parameters
44
+ * to this URL and opens it in the in-app browser.
45
+ *
46
+ * @default 'https://pay-staging.tryblink.xyz'
47
+ */
48
+ webviewBaseUrl?: string;
49
+ /**
50
+ * Custom URL scheme registered by the mobile app (e.g. `'myapp'`).
51
+ *
52
+ * The hosted payment flow redirects to `{callbackScheme}://swype/callback?...`
53
+ * when the user completes or cancels the payment. The app must listen for
54
+ * this deep link and pass it to {@link MobileDeposit.handleDeepLink}.
55
+ */
56
+ callbackScheme: string;
57
+ /**
58
+ * Path component of the callback deep link.
59
+ *
60
+ * @default '/swype/callback'
61
+ */
62
+ callbackPath?: string;
63
+ /**
64
+ * Function that opens a URL in an in-app browser.
65
+ *
66
+ * The SDK calls this to launch the hosted payment flow. Use your preferred
67
+ * in-app browser implementation:
68
+ *
69
+ * - React Native: `expo-web-browser` (`WebBrowser.openBrowserAsync`)
70
+ * - iOS native: `SFSafariViewController`
71
+ * - Android native: `CustomTabsIntent`
72
+ *
73
+ * The returned promise should resolve when the browser is dismissed
74
+ * (regardless of whether the user completed payment — the actual result
75
+ * arrives via deep link).
76
+ */
77
+ openUrl: (url: string) => Promise<void>;
78
+ /**
79
+ * Maximum time in milliseconds to wait for the signer endpoint to respond.
80
+ *
81
+ * @default 15000
82
+ */
83
+ signerTimeoutMs?: number;
84
+ /**
85
+ * Maximum time in milliseconds for the entire deposit flow (signer + user
86
+ * completion). When exceeded the promise rejects with a `FLOW_TIMEOUT`
87
+ * error. `undefined` means no limit.
88
+ */
89
+ flowTimeoutMs?: number;
90
+ /**
91
+ * When `true`, the SDK logs lifecycle events to `console.debug`.
92
+ *
93
+ * @default false
94
+ */
95
+ debug?: boolean;
96
+ }
97
+ /** Parameters for a single deposit request. */
98
+ interface DepositRequest {
99
+ /** USD amount to deposit (must be > 0). */
100
+ amount: number;
101
+ /** EVM chain ID for the destination (e.g. 8453 for Base). */
102
+ chainId: number;
103
+ /** Destination wallet address (0x-prefixed, 40 hex chars). */
104
+ address: string;
105
+ /** Token contract address on the destination chain (e.g. `'0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913'`). */
106
+ token: string;
107
+ /** Merchant order or invoice ID for reconciliation. */
108
+ reference?: string;
109
+ /** Arbitrary key-value pairs forwarded to the signer endpoint. */
110
+ metadata?: Record<string, string>;
111
+ }
112
+ /** Result returned when a deposit completes successfully. */
113
+ interface DepositResult {
114
+ transfer: TransferSummary;
115
+ /** Idempotency key from the signer response, if available. */
116
+ idempotencyKey?: string;
117
+ /** Signer preview echoed back for merchant-side display / logging. */
118
+ preview?: {
119
+ amount: number;
120
+ chainId: number;
121
+ address: string;
122
+ token: string;
123
+ };
124
+ }
125
+ /** Subset of transfer data returned from the hosted flow on completion. */
126
+ interface TransferSummary {
127
+ id: string;
128
+ status: string;
129
+ amount?: {
130
+ amount: number;
131
+ currency: string;
132
+ };
133
+ destinations?: Array<{
134
+ chainId: string;
135
+ address: string;
136
+ token?: {
137
+ address?: string;
138
+ symbol?: string;
139
+ };
140
+ }>;
141
+ }
142
+ /** Shape returned by the merchant signer. */
143
+ interface SignerResponse {
144
+ merchantId: string;
145
+ payload: string;
146
+ signature: string;
147
+ expiresAt?: string;
148
+ preview: {
149
+ amount: number;
150
+ chainId: number;
151
+ address: string;
152
+ token: string;
153
+ idempotencyKey: string;
154
+ };
155
+ }
156
+ /** Data passed to the merchant signer describing the payment to sign. */
157
+ interface SignerRequest {
158
+ amount: number;
159
+ chainId: number;
160
+ address: string;
161
+ token: string;
162
+ callbackScheme: string | null;
163
+ url: string;
164
+ version: 'v1';
165
+ reference?: string;
166
+ metadata?: Record<string, string>;
167
+ }
168
+ /**
169
+ * Async function that receives a {@link SignerRequest} and returns a
170
+ * {@link SignerResponse}. Use this when you need full control over how
171
+ * the signing request is made (custom HTTP method, auth headers, etc.).
172
+ */
173
+ type SignerFunction = (data: SignerRequest) => Promise<SignerResponse>;
174
+ /** @deprecated Use {@link MobileDepositStatus} instead. */
175
+ type MobileCheckoutStatus = MobileDepositStatus;
176
+ /** @deprecated Use {@link MobileDepositConfig} instead. */
177
+ type MobileCheckoutConfig = MobileDepositConfig;
178
+
179
+ export { CheckoutError as C, type DepositResult as D, type MobileDepositStatus as M, type SignerFunction as S, type TransferSummary as T, DepositError as a, type MobileDepositConfig as b, type DepositRequest as c, type CheckoutErrorCode as d, type DepositMobileErrorCode as e, type MobileCheckoutConfig as f, type MobileCheckoutStatus as g, type SignerRequest as h, type SignerResponse as i, getDisplayMessage as j };
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@swype-org/deposit-mobile",
3
+ "version": "0.2.0",
4
+ "description": "Lightweight mobile deposit SDK — open a hosted Swype payment flow via in-app browser, handle deep-link completion, zero runtime dependencies",
5
+ "type": "module",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./react-native": {
21
+ "import": {
22
+ "types": "./dist/react-native.d.ts",
23
+ "default": "./dist/react-native.js"
24
+ },
25
+ "require": {
26
+ "types": "./dist/react-native.d.cts",
27
+ "default": "./dist/react-native.cjs"
28
+ }
29
+ }
30
+ },
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "scripts": {
35
+ "build": "tsup",
36
+ "test": "node --experimental-strip-types --test src/*.test.ts",
37
+ "prepublishOnly": "npm run build"
38
+ },
39
+ "peerDependencies": {
40
+ "react": ">=18"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "react": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "devDependencies": {
48
+ "@types/react": "^19.2.14",
49
+ "tsup": "^8.4.0",
50
+ "typescript": "5.7.3"
51
+ },
52
+ "license": "MIT",
53
+ "repository": {
54
+ "type": "git",
55
+ "url": "https://github.com/swype-org/swype.git",
56
+ "directory": "deposit-mobile-sdk"
57
+ },
58
+ "keywords": [
59
+ "deposit",
60
+ "payments",
61
+ "sdk",
62
+ "merchant",
63
+ "mobile",
64
+ "react-native",
65
+ "deep-link"
66
+ ]
67
+ }