'use client'
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var _tslib = require('../../../../../_virtual/_tslib.cjs');
var React = require('react');
var utils = require('@dynamic-labs/utils');
var walletConnectorCore = require('@dynamic-labs/wallet-connector-core');
require('@dynamic-labs-sdk/client/core');
require('@dynamic-labs/sdk-api-core');
require('../../../client/client.cjs');
require('@dynamic-labs-sdk/client');
require('../../../config/ApiEndpoint.cjs');
require('../../constants/values.cjs');
require('@dynamic-labs/multi-wallet');
require('react-international-phone');
var localStorage = require('../../constants/localStorage.cjs');
require('../../constants/colors.cjs');
require('@dynamic-labs/iconic');
require('react/jsx-runtime');
require('../../../context/ViewContext/ViewContext.cjs');
require('../../../shared/logger.cjs');
require('@dynamic-labs/wallet-book');
require('../../../shared/consts/index.cjs');
require('../../../store/state/nonce/nonce.cjs');
var embeddedWallets = require('../../../data/api/embeddedWallets/embeddedWallets.cjs');
require('@dynamic-labs/locale');
require('../../../store/state/dynamicContextProps/dynamicContextProps.cjs');
require('../../../store/state/primaryWalletId/primaryWalletId.cjs');
require('../../../store/state/connectedWalletsInfo/connectedWalletsInfo.cjs');
var keyService = require('../../functions/keyService/keyService.cjs');
var dynamicEvents = require('../../../events/dynamicEvents.cjs');
var useOnboardingCompleteUser = require('../../../client/extension/user/useOnboardingCompleteUser/useOnboardingCompleteUser.cjs');
var getTurnkeyWalletId = require('../../functions/getTurnkeyWalletId/getTurnkeyWalletId.cjs');
var embeddedWalletSessionKeysUtils = require('../../functions/embeddedWalletSessionKeysUtils/embeddedWalletSessionKeysUtils.cjs');

const useEmbeddedWalletSessionKeys = ({ environmentId, projectSettings, }) => {
    const user = useOnboardingCompleteUser.useOnboardingCompleteUserProfile();
    const getDecodedSessionKeys = React.useCallback(() => {
        const sessionKeysSS = utils.StorageService.getItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
        return sessionKeysSS
            ? JSON.parse(Buffer.from(sessionKeysSS, 'base64').toString())
            : undefined;
    }, []);
    const registerHelper = React.useCallback((_a) => _tslib.__awaiter(void 0, [_a], void 0, function* ({ walletId, environmentId, privateKey, privateKeyJwk, publicKey, prevSessionKeySignature, user, }) {
        let resp;
        const turnkeyWalletId = getTurnkeyWalletId.getTurnkeyWalletId(walletId, user.verifiedCredentials);
        try {
            resp = yield embeddedWallets.registerSessionKey({
                environmentId,
                prevSessionKeySignature,
                publicKey,
                walletId: turnkeyWalletId,
            });
        }
        catch (error) {
            if (error instanceof utils.InvalidEmbeddedWalletSessionKeyError) {
                // this can happen if the public key passed during initial registration
                // does not match the root session public key that the backend expects
                walletConnectorCore.logger.warn('Invalid embedded wallet session key. Re-authentication is required to create new session keys.');
                dynamicEvents.dynamicEvents.emit('triggerLogout');
            }
            walletConnectorCore.logger.error('Error registering session key', { error });
            throw error;
        }
        const expirationDate = new Date(resp.expiresAt * 1000);
        utils.tracing.logEvent('session-key', 'Created new session key', utils.tracing.formatObject({
            expirationDate,
            publicKey,
        }));
        utils.StorageService.setItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, keyService.toEncodedFormat(publicKey, privateKey, privateKeyJwk, true, expirationDate), localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
        return {
            expirationDate,
            privateKey,
            publicKey,
        };
    }), []);
    // scenario 1: first time session register on first transaction.
    // scenario 2: refresh/rerender page - session still active and registered (keys were previously generated
    //             but never registered with the backend)
    // scenario 3: session expired and needs to be refreshed
    // Helper to get decoded session keys from storage
    /**
     * @param ignoreRestore - if true, will not use the session keys if they are found in storage and didn't expire
     * @returns - the session key
     */
    const registerEmbeddedWalletSessionKey = React.useCallback((_b) => _tslib.__awaiter(void 0, [_b], void 0, function* ({ ignoreRestore = false, walletId, }) {
        if (!user) {
            throw new Error('User not found');
        }
        // check if session keys are already stored in session storage
        let existingSessionKey = getDecodedSessionKeys();
        utils.tracing.logEvent('session-key', 'registerEmbeddedWalletSessionKey', utils.tracing.formatObject({
            hasDecodedSessionKeys: Boolean(existingSessionKey),
            publicKey: existingSessionKey === null || existingSessionKey === void 0 ? void 0 : existingSessionKey.publicKey,
        }));
        if (!existingSessionKey) {
            // We should never be in a situation where we don't have session keys in storage.
            // But right now we are in a situation where we don't have session keys in storage,
            // in many situations.
            // but this is a fallback to ensure that we always have session keys
            // To note that this would only work if chaining is disabled in the backend
            // since the original key was registered for chaining, and now we don't have it
            // it will fail when interacting with the backend if chaining is enabled.
            // This logic will be removed and reverted back to logging out once we find
            // the culprit that cause many of these to happen.
            walletConnectorCore.logger.error('Session keys not found in storage. Generating new session keys.', { userId: user === null || user === void 0 ? void 0 : user.userId });
            existingSessionKey = yield embeddedWalletSessionKeysUtils.generateAndSaveSessionKey();
        }
        const isSessionKeyValid = existingSessionKey.registered &&
            existingSessionKey.expirationDate &&
            new Date() <= new Date(existingSessionKey.expirationDate) &&
            !ignoreRestore;
        utils.tracing.logEvent('session-key', 'isSessionKeyValid', utils.tracing.formatObject({
            isSessionKeyValid: Boolean(isSessionKeyValid),
        }));
        if (isSessionKeyValid) {
            // scenario 1 - session is valid and registered
            return existingSessionKey;
        }
        utils.tracing.logEvent('session-key', 'decodedSessionKeys', utils.tracing.formatObject({
            publicKey: existingSessionKey.publicKey,
            registered: existingSessionKey.registered,
        }));
        let publicKey;
        let privateKey;
        let privateKeyJwk;
        let prevSessionKeySignature = undefined;
        if (!existingSessionKey.registered) {
            // scenario 2 - session needs to be registered
            ({ publicKey, privateKey, privateKeyJwk } = existingSessionKey);
        }
        else {
            // scenario 3 - session expired singing with the old key and generating a new one
            prevSessionKeySignature = yield keyService.p256Sign(existingSessionKey.privateKeyJwk, user.sessionId);
            //  Note that the key is only generated here, it will get saved to storage in the registerHelper
            ({ publicKey, privateKey, privateKeyJwk } = yield embeddedWalletSessionKeysUtils.generateSessionKey());
            utils.tracing.logEvent('session-key', 'Loaded prevSessionKeySignature', utils.tracing.formatObject({ prevSessionKeySignature, publicKey }));
        }
        return registerHelper({
            environmentId,
            prevSessionKeySignature,
            privateKey,
            privateKeyJwk,
            publicKey,
            user,
            walletId,
        });
    }), [environmentId, getDecodedSessionKeys, registerHelper, user]);
    const getSessionPublicKey = React.useCallback(() => {
        const decodedSessionKeys = getDecodedSessionKeys();
        if (!(decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.publicKey)) {
            utils.tracing.logEvent('session-key', 'getSessionPublicKey', 'Could not find session keys.');
            throw new Error('Could not find session keys.');
        }
        utils.tracing.logEvent('session-key', 'getSessionPublicKey', utils.tracing.formatObject({
            publicKey: decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.publicKey,
        }));
        return decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.publicKey;
    }, [getDecodedSessionKeys]);
    // this is a temporary fix to ensure that session keys are registered on signin for all wallets
    // the user is undefined at this point in the auth flow and we cant check the users wallet version
    // so we just return true for now
    const shouldRegisterSessionKeysOnSignin = React.useCallback(() => true, []);
    const getSignedSessionId = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () {
        const sessionId = user === null || user === void 0 ? void 0 : user.sessionId;
        if (!sessionId) {
            throw new Error('Session ID not found');
        }
        const decodedSessionKeys = getDecodedSessionKeys();
        if (!(decodedSessionKeys === null || decodedSessionKeys === void 0 ? void 0 : decodedSessionKeys.privateKeyJwk)) {
            throw new Error('Private key JWK not found');
        }
        const signedSessionId = yield keyService.p256Sign(decodedSessionKeys.privateKeyJwk, sessionId);
        return signedSessionId;
    }), [getDecodedSessionKeys, user === null || user === void 0 ? void 0 : user.sessionId]);
    const removeSessionKey = React.useCallback(() => {
        utils.tracing.logEvent('session-key', 'removeSessionKey');
        utils.StorageService.removeItem(localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS, localStorage.SECURE_ENCLAVE_WALLET_SESSION_KEYS_STORAGE_OPTIONS);
    }, []);
    return {
        generateSessionKey: embeddedWalletSessionKeysUtils.generateAndSaveSessionKey,
        getSessionPublicKey,
        getSignedSessionId,
        registerEmbeddedWalletSessionKey,
        removeSessionKey,
        shouldRegisterSessionKeysOnSignin,
    };
};

exports.useEmbeddedWalletSessionKeys = useEmbeddedWalletSessionKeys;
