@oobit/react-native-sdk 2.0.1 → 3.0.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.
- package/dist/WidgetSDK.d.ts +0 -2
- package/dist/WidgetSDK.d.ts.map +1 -1
- package/dist/WidgetSDK.js +26 -128
- package/dist/WidgetSDK.js.map +1 -1
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +15 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +1 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +41 -148
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -33
- package/dist/types.js.map +1 -1
- package/dist/walletUtils.d.ts.map +1 -1
- package/dist/walletUtils.js +16 -64
- package/dist/walletUtils.js.map +1 -1
- package/package.json +1 -10
- package/src/WidgetSDK.tsx +28 -155
- package/src/config.ts +15 -0
- package/src/index.ts +7 -9
- package/src/types.ts +42 -207
- package/src/walletUtils.ts +27 -42
package/dist/walletUtils.js
CHANGED
|
@@ -3,42 +3,8 @@
|
|
|
3
3
|
* Wallet Integration Utilities
|
|
4
4
|
* Handles opening Apple Wallet (iOS) and Google Wallet (Android)
|
|
5
5
|
*/
|
|
6
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
7
|
-
if (k2 === undefined) k2 = k;
|
|
8
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
9
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
10
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
11
|
-
}
|
|
12
|
-
Object.defineProperty(o, k2, desc);
|
|
13
|
-
}) : (function(o, m, k, k2) {
|
|
14
|
-
if (k2 === undefined) k2 = k;
|
|
15
|
-
o[k2] = m[k];
|
|
16
|
-
}));
|
|
17
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
18
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
19
|
-
}) : function(o, v) {
|
|
20
|
-
o["default"] = v;
|
|
21
|
-
});
|
|
22
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
23
|
-
var ownKeys = function(o) {
|
|
24
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
25
|
-
var ar = [];
|
|
26
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
27
|
-
return ar;
|
|
28
|
-
};
|
|
29
|
-
return ownKeys(o);
|
|
30
|
-
};
|
|
31
|
-
return function (mod) {
|
|
32
|
-
if (mod && mod.__esModule) return mod;
|
|
33
|
-
var result = {};
|
|
34
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
35
|
-
__setModuleDefault(result, mod);
|
|
36
|
-
return result;
|
|
37
|
-
};
|
|
38
|
-
})();
|
|
39
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
7
|
exports.isWalletAvailable = exports.openNativeWallet = void 0;
|
|
41
|
-
const IntentLauncher = __importStar(require("expo-intent-launcher"));
|
|
42
8
|
const react_native_1 = require("react-native");
|
|
43
9
|
const types_1 = require("./types");
|
|
44
10
|
/**
|
|
@@ -115,14 +81,13 @@ const openAppleWallet = async () => {
|
|
|
115
81
|
};
|
|
116
82
|
/**
|
|
117
83
|
* Opens Google Wallet on Android
|
|
118
|
-
*
|
|
84
|
+
* Uses Linking API to launch the app or fall back to Play Store
|
|
119
85
|
*/
|
|
120
86
|
const openGoogleWallet = async () => {
|
|
121
87
|
const GOOGLE_WALLET_PACKAGE = "com.google.android.apps.walletnfcrel";
|
|
122
88
|
try {
|
|
123
89
|
console.log("Attempting to open Google Wallet...");
|
|
124
|
-
//
|
|
125
|
-
// This is the most reliable way to open an installed app without knowing the exact activity
|
|
90
|
+
// Try using the market:// scheme to launch the app if it's installed
|
|
126
91
|
try {
|
|
127
92
|
const canOpen = await react_native_1.Linking.canOpenURL(`market://launch?id=${GOOGLE_WALLET_PACKAGE}`);
|
|
128
93
|
console.log("Can open market launch URL:", canOpen);
|
|
@@ -133,36 +98,23 @@ const openGoogleWallet = async () => {
|
|
|
133
98
|
}
|
|
134
99
|
}
|
|
135
100
|
catch (marketLaunchError) {
|
|
136
|
-
console.log("Market launch failed
|
|
101
|
+
console.log("Market launch failed:", marketLaunchError);
|
|
137
102
|
}
|
|
138
|
-
//
|
|
139
|
-
|
|
103
|
+
// App is not installed or market:// not available, open Play Store
|
|
104
|
+
console.log("Opening Play Store to install Google Wallet");
|
|
140
105
|
try {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
return true;
|
|
106
|
+
// Try native Play Store app first
|
|
107
|
+
const playStoreUrl = `market://details?id=${GOOGLE_WALLET_PACKAGE}`;
|
|
108
|
+
await react_native_1.Linking.openURL(playStoreUrl);
|
|
109
|
+
react_native_1.Alert.alert("Google Wallet", "Google Wallet is not installed. Opening Play Store to install the app.");
|
|
110
|
+
return false;
|
|
147
111
|
}
|
|
148
|
-
catch (
|
|
149
|
-
console.log("
|
|
150
|
-
//
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
const playStoreUrl = `market://details?id=${GOOGLE_WALLET_PACKAGE}`;
|
|
155
|
-
await react_native_1.Linking.openURL(playStoreUrl);
|
|
156
|
-
react_native_1.Alert.alert("Google Wallet", "Google Wallet is not installed. Opening Play Store to install the app.");
|
|
157
|
-
return false;
|
|
158
|
-
}
|
|
159
|
-
catch (marketError) {
|
|
160
|
-
console.log("Market URL failed, trying web Play Store:", marketError);
|
|
161
|
-
// Fallback to web Play Store
|
|
162
|
-
await react_native_1.Linking.openURL(`https://play.google.com/store/apps/details?id=${GOOGLE_WALLET_PACKAGE}`);
|
|
163
|
-
react_native_1.Alert.alert("Google Wallet", "Google Wallet is not installed. Opening Play Store to install the app.");
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
112
|
+
catch (marketError) {
|
|
113
|
+
console.log("Market URL failed, trying web Play Store:", marketError);
|
|
114
|
+
// Fallback to web Play Store
|
|
115
|
+
await react_native_1.Linking.openURL(`https://play.google.com/store/apps/details?id=${GOOGLE_WALLET_PACKAGE}`);
|
|
116
|
+
react_native_1.Alert.alert("Google Wallet", "Google Wallet is not installed. Opening Play Store to install the app.");
|
|
117
|
+
return false;
|
|
166
118
|
}
|
|
167
119
|
}
|
|
168
120
|
catch (error) {
|
package/dist/walletUtils.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletUtils.js","sourceRoot":"","sources":["../src/walletUtils.ts"],"names":[],"mappings":";AAAA;;;GAGG
|
|
1
|
+
{"version":3,"file":"walletUtils.js","sourceRoot":"","sources":["../src/walletUtils.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oobit/react-native-sdk",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.0",
|
|
4
4
|
"description": "React Native SDK for integrating Oobit crypto payments into wallet apps",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
"source": "src/index.ts",
|
|
19
19
|
"keywords": [
|
|
20
20
|
"react-native",
|
|
21
|
-
"expo",
|
|
22
21
|
"crypto",
|
|
23
22
|
"payments",
|
|
24
23
|
"wallet",
|
|
@@ -39,10 +38,6 @@
|
|
|
39
38
|
"url": "git+https://github.com/oobit-tech/react-native-SDK.git"
|
|
40
39
|
},
|
|
41
40
|
"peerDependencies": {
|
|
42
|
-
"expo-clipboard": ">=5.0.0",
|
|
43
|
-
"expo-intent-launcher": ">=6.0.0",
|
|
44
|
-
"expo-linking": ">=6.0.0",
|
|
45
|
-
"expo-local-authentication": ">=14.0.0",
|
|
46
41
|
"react": ">=18.0.0",
|
|
47
42
|
"react-native": ">=0.70.0",
|
|
48
43
|
"react-native-webview": ">=13.0.0"
|
|
@@ -56,10 +51,6 @@
|
|
|
56
51
|
"@typescript-eslint/eslint-plugin": "^8.47.0",
|
|
57
52
|
"@typescript-eslint/parser": "^8.47.0",
|
|
58
53
|
"eslint": "^9.39.1",
|
|
59
|
-
"expo-clipboard": "~8.0.8",
|
|
60
|
-
"expo-intent-launcher": "~13.0.7",
|
|
61
|
-
"expo-linking": "~8.0.8",
|
|
62
|
-
"expo-local-authentication": "~15.0.2",
|
|
63
54
|
"react": "19.1.0",
|
|
64
55
|
"react-native": "0.81.5",
|
|
65
56
|
"react-native-webview": "13.15.0",
|
package/src/WidgetSDK.tsx
CHANGED
|
@@ -20,27 +20,18 @@ import {
|
|
|
20
20
|
View,
|
|
21
21
|
} from "react-native";
|
|
22
22
|
import { WebView, WebViewMessageEvent } from "react-native-webview";
|
|
23
|
-
import { getWidgetUrl } from "./config";
|
|
24
|
-
import {
|
|
23
|
+
import { getWidgetUrl, stripTokenPrefix } from "./config";
|
|
24
|
+
import { WidgetMessage, WidgetSDKConfig } from "./types";
|
|
25
25
|
import { isWalletAvailable, openNativeWallet } from "./walletUtils";
|
|
26
|
-
import * as Clipboard from "expo-clipboard";
|
|
27
26
|
|
|
28
27
|
export interface WidgetSDKRef {
|
|
29
|
-
/** Navigate back within the widget */
|
|
30
28
|
navigateBack: () => void;
|
|
31
|
-
/** Reload the widget */
|
|
32
29
|
reload: () => void;
|
|
33
30
|
}
|
|
34
31
|
|
|
35
32
|
export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
36
33
|
(
|
|
37
|
-
{
|
|
38
|
-
accessToken,
|
|
39
|
-
userWalletAddress,
|
|
40
|
-
onError,
|
|
41
|
-
onClose,
|
|
42
|
-
onTransactionRequested,
|
|
43
|
-
},
|
|
34
|
+
{ accessToken, userWalletAddress, onClose, onTransactionRequested },
|
|
44
35
|
ref
|
|
45
36
|
) => {
|
|
46
37
|
const webViewRef = useRef<WebView>(null);
|
|
@@ -48,37 +39,23 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
48
39
|
const [isLoading, setIsLoading] = useState(true);
|
|
49
40
|
const hasLoadedOnce = useRef(false);
|
|
50
41
|
|
|
51
|
-
// Check wallet availability on mount
|
|
52
42
|
useEffect(() => {
|
|
53
|
-
|
|
43
|
+
isWalletAvailable().then(setWalletAvailable);
|
|
54
44
|
}, []);
|
|
55
45
|
|
|
56
|
-
// Handle Android hardware back button
|
|
57
46
|
useEffect(() => {
|
|
58
47
|
const backHandler = BackHandler.addEventListener(
|
|
59
48
|
"hardwareBackPress",
|
|
60
49
|
() => {
|
|
61
|
-
|
|
62
|
-
sendMessageToWidget({
|
|
63
|
-
type: "native:back-pressed",
|
|
64
|
-
timestamp: Date.now(),
|
|
65
|
-
});
|
|
66
|
-
// Return true to prevent default back behavior
|
|
50
|
+
sendMessageToWidget({ type: "native:back-pressed" });
|
|
67
51
|
return true;
|
|
68
52
|
}
|
|
69
53
|
);
|
|
70
|
-
|
|
71
54
|
return () => backHandler.remove();
|
|
72
55
|
}, []);
|
|
73
56
|
|
|
74
|
-
// Expose methods via ref
|
|
75
57
|
useImperativeHandle(ref, () => ({
|
|
76
|
-
navigateBack: () => {
|
|
77
|
-
sendMessageToWidget({
|
|
78
|
-
type: "native:navigate-back",
|
|
79
|
-
timestamp: Date.now(),
|
|
80
|
-
});
|
|
81
|
-
},
|
|
58
|
+
navigateBack: () => sendMessageToWidget({ type: "native:navigate-back" }),
|
|
82
59
|
reload: () => {
|
|
83
60
|
setIsLoading(true);
|
|
84
61
|
hasLoadedOnce.current = false;
|
|
@@ -86,29 +63,25 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
86
63
|
},
|
|
87
64
|
}));
|
|
88
65
|
|
|
89
|
-
const checkWalletAvailability = async () => {
|
|
90
|
-
const available = await isWalletAvailable();
|
|
91
|
-
setWalletAvailable(available);
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Handle messages from the web widget
|
|
96
|
-
*/
|
|
97
66
|
const handleMessage = (event: WebViewMessageEvent) => {
|
|
98
67
|
try {
|
|
99
68
|
const message: WidgetMessage = JSON.parse(event.nativeEvent.data);
|
|
100
69
|
|
|
101
70
|
switch (message.type) {
|
|
102
71
|
case "widget:ready":
|
|
103
|
-
|
|
72
|
+
sendMessageToWidget({
|
|
73
|
+
type: "native:platform-info",
|
|
74
|
+
payload: { platform: Platform.OS, walletAvailable },
|
|
75
|
+
});
|
|
104
76
|
break;
|
|
105
77
|
|
|
106
78
|
case "widget:open-wallet":
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
79
|
+
openNativeWallet().then((success) => {
|
|
80
|
+
sendMessageToWidget({
|
|
81
|
+
type: "native:wallet-opened",
|
|
82
|
+
payload: { success },
|
|
83
|
+
});
|
|
84
|
+
});
|
|
112
85
|
break;
|
|
113
86
|
|
|
114
87
|
case "widget:close":
|
|
@@ -116,111 +89,27 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
116
89
|
break;
|
|
117
90
|
|
|
118
91
|
case "widget:transaction-requested":
|
|
119
|
-
|
|
120
|
-
break;
|
|
121
|
-
|
|
122
|
-
case "widget:token-expired":
|
|
123
|
-
onError?.("TOKEN_EXPIRED", "Access token has expired");
|
|
124
|
-
break;
|
|
125
|
-
|
|
126
|
-
case "widget:copy-to-clipboard":
|
|
127
|
-
handleCopyToClipboard(message as CopyToClipboardMessage);
|
|
92
|
+
onTransactionRequested(message.payload);
|
|
128
93
|
break;
|
|
129
94
|
}
|
|
130
95
|
} catch {
|
|
131
|
-
|
|
96
|
+
// Ignore parse errors
|
|
132
97
|
}
|
|
133
98
|
};
|
|
134
99
|
|
|
135
|
-
const handleReady = () => {
|
|
136
|
-
// Send platform info to widget
|
|
137
|
-
sendMessageToWidget({
|
|
138
|
-
type: "native:platform-info",
|
|
139
|
-
payload: {
|
|
140
|
-
platform: Platform.OS,
|
|
141
|
-
walletAvailable,
|
|
142
|
-
},
|
|
143
|
-
});
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
const handleOpenWallet = async () => {
|
|
147
|
-
const success = await openNativeWallet();
|
|
148
|
-
|
|
149
|
-
// Notify widget of result
|
|
150
|
-
sendMessageToWidget({
|
|
151
|
-
type: "native:wallet-opened",
|
|
152
|
-
payload: { success },
|
|
153
|
-
});
|
|
154
|
-
};
|
|
155
|
-
|
|
156
|
-
const handleError = (message: WidgetMessage) => {
|
|
157
|
-
if (message.type !== "widget:error") return;
|
|
158
|
-
|
|
159
|
-
const { code, message: errorMessage } = message.payload;
|
|
160
|
-
onError?.(code, errorMessage);
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const handleTransactionRequested = (message: WidgetMessage) => {
|
|
164
|
-
if (message.type !== "widget:transaction-requested") return;
|
|
165
|
-
|
|
166
|
-
const { token, cryptoAmount, depositAddress, depositAddressTag } =
|
|
167
|
-
message.payload;
|
|
168
|
-
|
|
169
|
-
onTransactionRequested(
|
|
170
|
-
token,
|
|
171
|
-
cryptoAmount,
|
|
172
|
-
depositAddress,
|
|
173
|
-
depositAddressTag
|
|
174
|
-
);
|
|
175
|
-
};
|
|
176
|
-
|
|
177
|
-
/**
|
|
178
|
-
* Handle clipboard copy request from widget
|
|
179
|
-
*/
|
|
180
|
-
const handleCopyToClipboard = async (message: CopyToClipboardMessage) => {
|
|
181
|
-
const { text, label } = message.payload;
|
|
182
|
-
|
|
183
|
-
try {
|
|
184
|
-
await Clipboard.setStringAsync(text);
|
|
185
|
-
sendMessageToWidget({
|
|
186
|
-
type: "native:clipboard-result",
|
|
187
|
-
payload: { success: true, label },
|
|
188
|
-
});
|
|
189
|
-
} catch {
|
|
190
|
-
sendMessageToWidget({
|
|
191
|
-
type: "native:clipboard-result",
|
|
192
|
-
payload: {
|
|
193
|
-
success: false,
|
|
194
|
-
label,
|
|
195
|
-
error: "Clipboard operation failed",
|
|
196
|
-
},
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
/**
|
|
202
|
-
* Send message to the web widget
|
|
203
|
-
*/
|
|
204
100
|
const sendMessageToWidget = (message: unknown) => {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
`;
|
|
209
|
-
|
|
210
|
-
webViewRef.current?.injectJavaScript(js);
|
|
101
|
+
webViewRef.current?.injectJavaScript(
|
|
102
|
+
`window.postMessage(${JSON.stringify(message)}, '*'); true;`
|
|
103
|
+
);
|
|
211
104
|
};
|
|
212
105
|
|
|
213
|
-
/**
|
|
214
|
-
* Build the widget URL with query parameters
|
|
215
|
-
*/
|
|
216
106
|
const finalWidgetUrl = useMemo(() => {
|
|
217
107
|
const baseUrl = getWidgetUrl(accessToken);
|
|
218
108
|
const params = new URLSearchParams({
|
|
219
|
-
token: accessToken,
|
|
109
|
+
token: stripTokenPrefix(accessToken),
|
|
220
110
|
platform: Platform.OS,
|
|
221
|
-
userWalletAddress
|
|
111
|
+
userWalletAddress,
|
|
222
112
|
});
|
|
223
|
-
|
|
224
113
|
return `${baseUrl}?${params.toString()}`;
|
|
225
114
|
}, [accessToken, userWalletAddress]);
|
|
226
115
|
|
|
@@ -237,36 +126,24 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
237
126
|
setIsLoading(false);
|
|
238
127
|
}
|
|
239
128
|
}}
|
|
240
|
-
onError={() => {
|
|
241
|
-
setIsLoading(false);
|
|
242
|
-
onError?.("WEBVIEW_ERROR", "Failed to load widget");
|
|
243
|
-
}}
|
|
244
|
-
// Allow external URLs to open in native apps
|
|
245
129
|
onShouldStartLoadWithRequest={(request) => {
|
|
246
130
|
const { url } = request;
|
|
247
|
-
|
|
248
|
-
// Allow wallet URLs to open in native apps
|
|
249
131
|
if (
|
|
250
|
-
url.startsWith("shoebox://") ||
|
|
251
|
-
url.includes("pay.google.com") ||
|
|
132
|
+
url.startsWith("shoebox://") ||
|
|
133
|
+
url.includes("pay.google.com") ||
|
|
252
134
|
url.includes("wallet.google.com") ||
|
|
253
135
|
url.includes("wallet.apple.com")
|
|
254
136
|
) {
|
|
255
137
|
Linking.openURL(url).catch(() => {});
|
|
256
|
-
return false;
|
|
138
|
+
return false;
|
|
257
139
|
}
|
|
258
|
-
|
|
259
|
-
// Allow normal widget navigation
|
|
260
140
|
return true;
|
|
261
141
|
}}
|
|
262
|
-
// Security settings
|
|
263
142
|
javaScriptEnabled={true}
|
|
264
143
|
domStorageEnabled={true}
|
|
265
144
|
allowsInlineMediaPlayback={true}
|
|
266
|
-
// iOS specific
|
|
267
145
|
bounces={false}
|
|
268
146
|
allowsBackForwardNavigationGestures={true}
|
|
269
|
-
// Android specific
|
|
270
147
|
mixedContentMode="always"
|
|
271
148
|
/>
|
|
272
149
|
{isLoading && (
|
|
@@ -280,12 +157,8 @@ export const WidgetSDK = forwardRef<WidgetSDKRef, WidgetSDKConfig>(
|
|
|
280
157
|
);
|
|
281
158
|
|
|
282
159
|
const styles = StyleSheet.create({
|
|
283
|
-
container: {
|
|
284
|
-
|
|
285
|
-
},
|
|
286
|
-
webview: {
|
|
287
|
-
flex: 1,
|
|
288
|
-
},
|
|
160
|
+
container: { flex: 1 },
|
|
161
|
+
webview: { flex: 1 },
|
|
289
162
|
loadingOverlay: {
|
|
290
163
|
...StyleSheet.absoluteFillObject,
|
|
291
164
|
backgroundColor: "rgba(255, 255, 255, 0.9)",
|
package/src/config.ts
CHANGED
|
@@ -34,3 +34,18 @@ export function getWidgetUrl(accessToken: string): string {
|
|
|
34
34
|
// Default to production for backwards compatibility
|
|
35
35
|
return WIDGET_URLS.production;
|
|
36
36
|
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Strip the environment prefix from an access token
|
|
40
|
+
* @param accessToken - The access token (prefixed with sbx_ or prod_)
|
|
41
|
+
* @returns The token without the environment prefix
|
|
42
|
+
*/
|
|
43
|
+
export function stripTokenPrefix(accessToken: string): string {
|
|
44
|
+
if (accessToken.startsWith(TOKEN_PREFIX.SANDBOX)) {
|
|
45
|
+
return accessToken.slice(TOKEN_PREFIX.SANDBOX.length);
|
|
46
|
+
}
|
|
47
|
+
if (accessToken.startsWith(TOKEN_PREFIX.PRODUCTION)) {
|
|
48
|
+
return accessToken.slice(TOKEN_PREFIX.PRODUCTION.length);
|
|
49
|
+
}
|
|
50
|
+
return accessToken;
|
|
51
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Widget SDK - Public API
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { WidgetSDK } from "./WidgetSDK";
|
|
6
|
-
export type { WidgetSDKRef } from "./WidgetSDK";
|
|
7
|
-
|
|
8
1
|
export type {
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
EvmTransactionData,
|
|
3
|
+
EvmTransactionRequest,
|
|
4
|
+
SolanaTransactionRequest,
|
|
5
|
+
TransactionRequest,
|
|
6
|
+
TransactionTokenMetadata,
|
|
11
7
|
WidgetSDKConfig,
|
|
12
8
|
} from "./types";
|
|
9
|
+
export { WidgetSDK } from "./WidgetSDK";
|
|
10
|
+
export type { WidgetSDKRef } from "./WidgetSDK";
|