@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
JavaScript
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