UNPKG

@turnkey/react-wallet-kit

Version:

The easiest and most powerful way to integrate Turnkey's Embedded Wallets into your React applications.

324 lines (321 loc) 20 kB
import { slicedToArray as _slicedToArray, asyncToGenerator as _asyncToGenerator, regeneratorRuntime as _regeneratorRuntime } from '../../_virtual/_rollupPluginBabelHelpers.mjs'; import { jsxs, jsx } from 'react/jsx-runtime'; import { useState, useEffect } from 'react'; import { useModal } from '../../providers/modal/Hook.mjs'; import { useTurnkey } from '../../providers/client/Hook.mjs'; import { IframeStamper } from '@turnkey/iframe-stamper'; import { TurnkeyError, TurnkeyErrorCodes } from '@turnkey/sdk-types'; import { ActionButton } from '../design/Buttons.mjs'; import { Input } from '@headlessui/react'; import { generateWalletAccountsFromAddressFormat } from '@turnkey/core'; import { SuccessPage } from '../design/Success.mjs'; import clsx from 'clsx'; var TurnkeyImportIframeContainerId = "turnkey-import-iframe-container-id"; var TurnkeyIframeElementId = "turnkey-default-iframe-element-id"; var TurnkeyIframeClassNames = "w-full h-full overflow-hidden border-none !text-base bg-icon-background-light dark:bg-icon-background-dark"; // IMPORTANT: These colors need to match --icon-text-light, --icon-background-light, --icon-background-dark and --icon-text-dark in index.css var iconBackgroundLight = "#e5e7eb"; var iconBackgroundDark = "#333336"; var iconTextLight = "#828282"; var iconTextDark = "#a3a3a5"; function ImportComponent(params) { var _config$ui11, _config$ui12, _config$ui12$colors, _config$ui12$colors$d, _config$ui13, _config$ui13$colors, _config$ui13$colors$l, _config$ui14, _config$ui15, _config$ui15$colors, _config$ui15$colors$d, _config$ui16, _config$ui16$colors, _config$ui16$colors$l, _error$cause; var onSuccess = params.onSuccess, onError = params.onError, defaultWalletAccounts = params.defaultWalletAccounts, successPageDuration = params.successPageDuration, stampWith = params.stampWith; var _useTurnkey = useTurnkey(), config = _useTurnkey.config, session = _useTurnkey.session, importWallet = _useTurnkey.importWallet, httpClient = _useTurnkey.httpClient; var _useState = useState(""), _useState2 = _slicedToArray(_useState, 2), walletName = _useState2[0], setWalletName = _useState2[1]; var _useState3 = useState(false), _useState4 = _slicedToArray(_useState3, 2), isLoading = _useState4[0], setIsLoading = _useState4[1]; var _useState5 = useState(null), _useState6 = _slicedToArray(_useState5, 2), error = _useState6[0], setError = _useState6[1]; var _useState7 = useState(false), _useState8 = _slicedToArray(_useState7, 2), shaking = _useState8[0], setShaking = _useState8[1]; var shakeInput = function shakeInput() { setShaking(true); setTimeout(function () { return setShaking(false); }, 250); }; var apiBaseUrl = config === null || config === void 0 ? void 0 : config.apiBaseUrl; var importIframeUrl = config === null || config === void 0 ? void 0 : config.importIframeUrl; var _useModal = useModal(), closeModal = _useModal.closeModal, pushPage = _useModal.pushPage, isMobile = _useModal.isMobile; var _useState9 = useState(null), _useState0 = _slicedToArray(_useState9, 2), importIframeClient = _useState0[0], setImportIframeClient = _useState0[1]; if (!apiBaseUrl) { throw new TurnkeyError("API base URL is not configured. Please set it in the Turnkey configuration."); } useEffect(function () { var initIframe = /*#__PURE__*/function () { var _ref = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() { var _config$ui, _config$ui2, _config$ui2$colors, _config$ui2$colors$da, _config$ui3, _config$ui3$colors, _config$ui3$colors$li, _config$ui4, _config$ui5, _config$ui5$colors, _config$ui5$colors$da, _config$ui6, _config$ui6$colors, _config$ui6$colors$li, newImportIframeClient; return _regeneratorRuntime().wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: _context.prev = 0; newImportIframeClient = new IframeStamper({ iframeUrl: importIframeUrl, iframeElementId: TurnkeyIframeElementId, iframeContainer: document.getElementById(TurnkeyImportIframeContainerId) }); _context.next = 4; return newImportIframeClient.init(); case 4: _context.next = 6; return newImportIframeClient.applySettings({ styles: { fontSize: "16px", // IMPORTANT: These colors need to match --icon-text-light and --icon-text-dark in index.css backgroundColor: config !== null && config !== void 0 && (_config$ui = config.ui) !== null && _config$ui !== void 0 && _config$ui.darkMode ? (config === null || config === void 0 ? void 0 : (_config$ui2 = config.ui) === null || _config$ui2 === void 0 ? void 0 : (_config$ui2$colors = _config$ui2.colors) === null || _config$ui2$colors === void 0 ? void 0 : (_config$ui2$colors$da = _config$ui2$colors.dark) === null || _config$ui2$colors$da === void 0 ? void 0 : _config$ui2$colors$da.iconBackground) || iconBackgroundDark : (config === null || config === void 0 ? void 0 : (_config$ui3 = config.ui) === null || _config$ui3 === void 0 ? void 0 : (_config$ui3$colors = _config$ui3.colors) === null || _config$ui3$colors === void 0 ? void 0 : (_config$ui3$colors$li = _config$ui3$colors.light) === null || _config$ui3$colors$li === void 0 ? void 0 : _config$ui3$colors$li.iconBackground) || iconBackgroundLight, color: config !== null && config !== void 0 && (_config$ui4 = config.ui) !== null && _config$ui4 !== void 0 && _config$ui4.darkMode ? (config === null || config === void 0 ? void 0 : (_config$ui5 = config.ui) === null || _config$ui5 === void 0 ? void 0 : (_config$ui5$colors = _config$ui5.colors) === null || _config$ui5$colors === void 0 ? void 0 : (_config$ui5$colors$da = _config$ui5$colors.dark) === null || _config$ui5$colors$da === void 0 ? void 0 : _config$ui5$colors$da.iconText) || iconTextDark : (config === null || config === void 0 ? void 0 : (_config$ui6 = config.ui) === null || _config$ui6 === void 0 ? void 0 : (_config$ui6$colors = _config$ui6.colors) === null || _config$ui6$colors === void 0 ? void 0 : (_config$ui6$colors$li = _config$ui6$colors.light) === null || _config$ui6$colors$li === void 0 ? void 0 : _config$ui6$colors$li.iconText) || iconTextLight } }); case 6: setImportIframeClient(newImportIframeClient); _context.next = 12; break; case 9: _context.prev = 9; _context.t0 = _context["catch"](0); throw new TurnkeyError("Error initializing IframeStamper", TurnkeyErrorCodes.INTERNAL_ERROR, _context.t0); case 12: case "end": return _context.stop(); } }, _callee, null, [[0, 9]]); })); return function initIframe() { return _ref.apply(this, arguments); }; }(); var existingIframe = document.getElementById(TurnkeyIframeElementId); if (!existingIframe) { initIframe(); } var iframeElement = document.getElementById(TurnkeyIframeElementId); if (iframeElement) { iframeElement.className = TurnkeyIframeClassNames; } return function () { handleImportModalClose(); }; }, []); useEffect(function () { var reapplyIframeStyles = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2() { var _config$ui7, _config$ui8, _config$ui8$colors, _config$ui8$colors$da, _config$ui9, _config$ui9$colors, _config$ui9$colors$li, _config$ui0, _config$ui1, _config$ui1$colors, _config$ui1$colors$da, _config$ui10, _config$ui10$colors, _config$ui10$colors$l; return _regeneratorRuntime().wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: _context2.next = 2; return importIframeClient === null || importIframeClient === void 0 ? void 0 : importIframeClient.applySettings({ styles: { fontSize: "16px", backgroundColor: config !== null && config !== void 0 && (_config$ui7 = config.ui) !== null && _config$ui7 !== void 0 && _config$ui7.darkMode ? (config === null || config === void 0 ? void 0 : (_config$ui8 = config.ui) === null || _config$ui8 === void 0 ? void 0 : (_config$ui8$colors = _config$ui8.colors) === null || _config$ui8$colors === void 0 ? void 0 : (_config$ui8$colors$da = _config$ui8$colors.dark) === null || _config$ui8$colors$da === void 0 ? void 0 : _config$ui8$colors$da.iconBackground) || iconBackgroundDark : (config === null || config === void 0 ? void 0 : (_config$ui9 = config.ui) === null || _config$ui9 === void 0 ? void 0 : (_config$ui9$colors = _config$ui9.colors) === null || _config$ui9$colors === void 0 ? void 0 : (_config$ui9$colors$li = _config$ui9$colors.light) === null || _config$ui9$colors$li === void 0 ? void 0 : _config$ui9$colors$li.iconBackground) || iconBackgroundLight, color: config !== null && config !== void 0 && (_config$ui0 = config.ui) !== null && _config$ui0 !== void 0 && _config$ui0.darkMode ? (config === null || config === void 0 ? void 0 : (_config$ui1 = config.ui) === null || _config$ui1 === void 0 ? void 0 : (_config$ui1$colors = _config$ui1.colors) === null || _config$ui1$colors === void 0 ? void 0 : (_config$ui1$colors$da = _config$ui1$colors.dark) === null || _config$ui1$colors$da === void 0 ? void 0 : _config$ui1$colors$da.iconText) || iconTextDark : (config === null || config === void 0 ? void 0 : (_config$ui10 = config.ui) === null || _config$ui10 === void 0 ? void 0 : (_config$ui10$colors = _config$ui10.colors) === null || _config$ui10$colors === void 0 ? void 0 : (_config$ui10$colors$l = _config$ui10$colors.light) === null || _config$ui10$colors$l === void 0 ? void 0 : _config$ui10$colors$l.iconText) || iconTextLight } }); case 2: case "end": return _context2.stop(); } }, _callee2); })); return function reapplyIframeStyles() { return _ref2.apply(this, arguments); }; }(); reapplyIframeStyles(); }, [config.ui]); function handleImportModalClose() { if (importIframeClient) { setImportIframeClient(null); var existingIframe = document.getElementById(TurnkeyIframeElementId); if (existingIframe) { existingIframe.remove(); } } } function handleImport() { return _handleImport.apply(this, arguments); } function _handleImport() { _handleImport = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3() { var _defaultWalletAccount, initResult, injected, encryptedBundle, accounts, response; return _regeneratorRuntime().wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: setIsLoading(true); _context3.prev = 1; if (importIframeClient) { _context3.next = 4; break; } throw new TurnkeyError("Import iframe client not initialized", TurnkeyErrorCodes.INTERNAL_ERROR); case 4: _context3.next = 6; return httpClient === null || httpClient === void 0 ? void 0 : httpClient.initImportWallet({ organizationId: session === null || session === void 0 ? void 0 : session.organizationId, userId: session === null || session === void 0 ? void 0 : session.userId }); case 6: initResult = _context3.sent; if (!(!initResult || !initResult.importBundle)) { _context3.next = 9; break; } throw new TurnkeyError("Failed to retrieve import bundle", TurnkeyErrorCodes.IMPORT_WALLET_ERROR); case 9: _context3.next = 11; return importIframeClient.injectImportBundle(initResult.importBundle, session === null || session === void 0 ? void 0 : session.organizationId, session === null || session === void 0 ? void 0 : session.userId); case 11: injected = _context3.sent; if (injected) { _context3.next = 14; break; } throw new TurnkeyError("Failed to inject import bundle", TurnkeyErrorCodes.IMPORT_WALLET_ERROR); case 14: _context3.next = 16; return importIframeClient.extractWalletEncryptedBundle(); case 16: encryptedBundle = _context3.sent; if (!(!encryptedBundle || encryptedBundle.trim() === "")) { _context3.next = 19; break; } throw new TurnkeyError("Encrypted bundle is empty", TurnkeyErrorCodes.IMPORT_WALLET_ERROR); case 19: accounts = []; if (Array.isArray(defaultWalletAccounts) && defaultWalletAccounts.length > 0 && ((_defaultWalletAccount = defaultWalletAccounts[0]) === null || _defaultWalletAccount === void 0 ? void 0 : _defaultWalletAccount.addressFormat) === undefined) { accounts = generateWalletAccountsFromAddressFormat({ addresses: defaultWalletAccounts }); } else if (Array.isArray(defaultWalletAccounts)) { accounts = defaultWalletAccounts; } _context3.next = 23; return importWallet({ walletName: walletName, accounts: accounts, encryptedBundle: encryptedBundle, stampWith: stampWith }); case 23: response = _context3.sent; if (!response) { _context3.next = 30; break; } onSuccess(response); if (successPageDuration && successPageDuration !== 0) { pushPage({ key: "success", content: jsx(SuccessPage, { text: "Wallet imported successfully!", duration: successPageDuration, onComplete: function onComplete() { handleImportModalClose(); closeModal(); } }), preventBack: true, showTitle: false }); } else { handleImportModalClose(); closeModal(); } handleImportModalClose(); _context3.next = 33; break; case 30: _context3.next = 32; return importIframeClient.clear(); case 32: throw new TurnkeyError("Failed to import wallet", TurnkeyErrorCodes.IMPORT_WALLET_ERROR); case 33: _context3.next = 41; break; case 35: _context3.prev = 35; _context3.t0 = _context3["catch"](1); shakeInput(); setError(_context3.t0 instanceof TurnkeyError ? _context3.t0 : new TurnkeyError("Error importing wallet", TurnkeyErrorCodes.IMPORT_WALLET_ERROR, _context3.t0)); if (_context3.t0 instanceof TurnkeyError) onError(_context3.t0); throw new TurnkeyError("Error importing wallet", TurnkeyErrorCodes.IMPORT_WALLET_ERROR, _context3.t0); case 41: _context3.prev = 41; setIsLoading(false); return _context3.finish(41); case 44: case "end": return _context3.stop(); } }, _callee3, null, [[1, 35, 41, 44]]); })); return _handleImport.apply(this, arguments); } return jsxs("div", { className: clsx("flex flex-col items-center pt-4", isMobile ? "w-full" : "w-[21rem]"), children: [jsx("p", { className: "text-sm text-icon-text-light dark:text-icon-text-dark", children: "Enter your seed phrase. Seed phrases are typically 12-24 words." }), jsx("div", { id: TurnkeyImportIframeContainerId, style: { height: "100%", overflow: "hidden", display: "block", backgroundColor: config !== null && config !== void 0 && (_config$ui11 = config.ui) !== null && _config$ui11 !== void 0 && _config$ui11.darkMode ? (config === null || config === void 0 ? void 0 : (_config$ui12 = config.ui) === null || _config$ui12 === void 0 ? void 0 : (_config$ui12$colors = _config$ui12.colors) === null || _config$ui12$colors === void 0 ? void 0 : (_config$ui12$colors$d = _config$ui12$colors.dark) === null || _config$ui12$colors$d === void 0 ? void 0 : _config$ui12$colors$d.iconBackground) || iconBackgroundDark : (config === null || config === void 0 ? void 0 : (_config$ui13 = config.ui) === null || _config$ui13 === void 0 ? void 0 : (_config$ui13$colors = _config$ui13.colors) === null || _config$ui13$colors === void 0 ? void 0 : (_config$ui13$colors$l = _config$ui13$colors.light) === null || _config$ui13$colors$l === void 0 ? void 0 : _config$ui13$colors$l.iconBackground) || iconBackgroundLight, width: "100%", boxSizing: "border-box", padding: "5px", borderStyle: "solid", borderWidth: "1px", borderRadius: "8px", borderColor: config !== null && config !== void 0 && (_config$ui14 = config.ui) !== null && _config$ui14 !== void 0 && _config$ui14.darkMode ? (config === null || config === void 0 ? void 0 : (_config$ui15 = config.ui) === null || _config$ui15 === void 0 ? void 0 : (_config$ui15$colors = _config$ui15.colors) === null || _config$ui15$colors === void 0 ? void 0 : (_config$ui15$colors$d = _config$ui15$colors.dark) === null || _config$ui15$colors$d === void 0 ? void 0 : _config$ui15$colors$d.iconText) || iconTextDark : (config === null || config === void 0 ? void 0 : (_config$ui16 = config.ui) === null || _config$ui16 === void 0 ? void 0 : (_config$ui16$colors = _config$ui16.colors) === null || _config$ui16$colors === void 0 ? void 0 : (_config$ui16$colors$l = _config$ui16$colors.light) === null || _config$ui16$colors$l === void 0 ? void 0 : _config$ui16$colors$l.iconText) || iconTextLight }, className: "transition-all ".concat(shaking ? "animate-shake" : "") }), jsx(Input, { type: "text", placeholder: "Enter your wallet name", value: walletName, onChange: function onChange(e) { return setWalletName(e.target.value); }, className: "placeholder:text-icon-text-light dark:placeholder:text-icon-text-dark w-full my-2 py-3 px-3 rounded-md text-inherit bg-icon-background-light dark:bg-icon-background-dark border border-modal-background-dark/20 dark:border-modal-background-light/20 focus:outline-primary-light focus:dark:outline-primary-dark focus:outline-[1px] focus:outline-offset-0 box-border" }), jsx(ActionButton, { loading: isLoading, spinnerClassName: "text-primary-text-light dark:text-primary-text-dark", onClick: handleImport, className: "bg-primary-light dark:bg-primary-dark text-primary-text-light dark:text-primary-text-dark", children: "Import" }), jsxs("p", { className: clsx("text-sm text-red-500 transition-opacity delay-75 line-clamp-2 w-full", error ? "opacity-100 pointer-events-auto mt-2" : "opacity-0 pointer-events-none absolute"), children: [error === null || error === void 0 ? void 0 : error.message, ":", " ", (error === null || error === void 0 ? void 0 : error.cause) instanceof TurnkeyError ? error === null || error === void 0 ? void 0 : error.cause.message : (error === null || error === void 0 ? void 0 : (_error$cause = error.cause) === null || _error$cause === void 0 ? void 0 : _error$cause.toString()) || "Unknown error"] })] }); } export { ImportComponent }; //# sourceMappingURL=Import.mjs.map