Skip to content

Commit

Permalink
Keep state for LN > LQ swaps (#513)
Browse files Browse the repository at this point in the history
* This commit:
- splits receiving in lightning into 2 differet routes:
  - insert amount
  - show invoice
- stores on local storage amount inserted and swap data
- if the user already inserted an amount, when coming back will see that page with previous amount
- if user closes the popup before ending the claiming (ie receiving LN), he can now re-open it and the app will remember and finalize the claim tx

* adds lightning error component

* adds message: don't close this window

* lint
  • Loading branch information
bordalix authored Mar 4, 2024
1 parent e2368f9 commit 2e3dfab
Show file tree
Hide file tree
Showing 12 changed files with 389 additions and 132 deletions.
24 changes: 23 additions & 1 deletion src/domain/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
import { mnemonicToSeed } from 'bip39';
import { SLIP77Factory } from 'slip77';
import type { BlockHeader, ChainSource } from './chainsource';
import type { SwapData } from '../infrastructure/storage/receive-flow-repository';

export interface AppStatus {
isMnemonicVerified: boolean;
Expand Down Expand Up @@ -188,6 +189,22 @@ export interface OnboardingRepository {
flush(): Promise<void>; // flush all data
}

export enum ReceiveFlowStep {
None,
AmountInserted,
SwapRunning,
}

// this repository is used to cache data during the UI send flow
export interface ReceiveFlowRepository {
reset(): Promise<void>; // reset all data in the send flow repository
getAmount(): Promise<number | undefined>;
setAmount(amount: number): Promise<void>;
getStep(): Promise<ReceiveFlowStep>;
getSwapData(): Promise<SwapData | undefined>;
setSwapData(data: any): Promise<any>;
}

export enum SendFlowStep {
None,
AssetSelected,
Expand Down Expand Up @@ -218,8 +235,13 @@ export interface BlockheadersRepository {
onNewBlockHeader: EventEmitter<[network: NetworkString, blockHeader: BlockHeader]>;
}

export async function init(appRepository: AppRepository, sendFlowRepository: SendFlowRepository) {
export async function init(
appRepository: AppRepository,
receiveFlowRepository: ReceiveFlowRepository,
sendFlowRepository: SendFlowRepository
) {
await Browser.storage.local.clear();
await receiveFlowRepository.reset();
await sendFlowRepository.reset();
await appRepository.setNetwork('liquid');
}
Expand Down
2 changes: 2 additions & 0 deletions src/extension/components/shell-popup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const ShellPopUp: React.FC<Props> = ({
assetRepository,
blockHeadersRepository,
appRepository,
receiveFlowRepository,
sendFlowRepository,
refundableSwapsRepository,
cache,
Expand Down Expand Up @@ -63,6 +64,7 @@ const ShellPopUp: React.FC<Props> = ({

const goToHome = async () => {
if (history.location.pathname === DEFAULT_ROUTE) return;
await receiveFlowRepository.reset();
await sendFlowRepository.reset();
history.push(DEFAULT_ROUTE);
};
Expand Down
6 changes: 6 additions & 0 deletions src/extension/context/storage-context.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type {
AssetRepository,
BlockheadersRepository,
OnboardingRepository,
ReceiveFlowRepository,
SendFlowRepository,
RefundSwapFlowRepository,
RefundableSwapsRepository,
Expand All @@ -14,6 +15,7 @@ import { AppStorageAPI } from '../../infrastructure/storage/app-repository';
import { AssetStorageAPI } from '../../infrastructure/storage/asset-repository';
import { BlockHeadersAPI } from '../../infrastructure/storage/blockheaders-repository';
import { OnboardingStorageAPI } from '../../infrastructure/storage/onboarding-repository';
import { ReceiveFlowStorageAPI } from '../../infrastructure/storage/receive-flow-repository';
import { SendFlowStorageAPI } from '../../infrastructure/storage/send-flow-repository';
import { TaxiStorageAPI } from '../../infrastructure/storage/taxi-repository';
import { WalletStorageAPI } from '../../infrastructure/storage/wallet-repository';
Expand All @@ -28,6 +30,7 @@ const appRepository = new AppStorageAPI();
const assetRepository = new AssetStorageAPI(walletRepository);
const taxiRepository = new TaxiStorageAPI(assetRepository, appRepository);
const onboardingRepository = new OnboardingStorageAPI();
const receiveFlowRepository = new ReceiveFlowStorageAPI();
const sendFlowRepository = new SendFlowStorageAPI();
const blockHeadersRepository = new BlockHeadersAPI();
const refundableSwapsRepository = new RefundableSwapsStorageAPI();
Expand All @@ -39,6 +42,7 @@ interface StorageContextProps {
assetRepository: AssetRepository;
taxiRepository: TaxiRepository;
onboardingRepository: OnboardingRepository;
receiveFlowRepository: ReceiveFlowRepository;
sendFlowRepository: SendFlowRepository;
blockHeadersRepository: BlockheadersRepository;
cache?: PresentationCache;
Expand All @@ -52,6 +56,7 @@ const StorageContext = createContext<StorageContextProps>({
assetRepository,
taxiRepository,
onboardingRepository,
receiveFlowRepository,
sendFlowRepository,
blockHeadersRepository,
refundableSwapsRepository,
Expand Down Expand Up @@ -91,6 +96,7 @@ export const StorageProvider = ({ children }: { children: React.ReactNode }) =>
assetRepository,
taxiRepository,
onboardingRepository,
receiveFlowRepository,
sendFlowRepository,
blockHeadersRepository,
cache,
Expand Down
5 changes: 3 additions & 2 deletions src/extension/onboarding/wallet-create/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ import { INITIALIZE_SEED_PHRASE_ROUTE } from '../../routes/constants';
import OnboardingForm from '../onboarding-form';

const WalletCreate: React.FC = () => {
const { appRepository, sendFlowRepository, onboardingRepository } = useStorageContext();
const { appRepository, receiveFlowRepository, sendFlowRepository, onboardingRepository } =
useStorageContext();
const history = useHistory();

const onSubmit = async ({ password }: { password: string }) => {
await init(appRepository, sendFlowRepository);
await init(appRepository, receiveFlowRepository, sendFlowRepository);
await onboardingRepository.setOnboardingPasswordAndMnemonic(password, generateMnemonic());
history.push(INITIALIZE_SEED_PHRASE_ROUTE);
};
Expand Down
5 changes: 3 additions & 2 deletions src/extension/onboarding/wallet-restore/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import { extractErrorMessage } from '../../utility/error';
import { useStorageContext } from '../../context/storage-context';

const WalletRestore: React.FC = () => {
const { appRepository, sendFlowRepository, onboardingRepository } = useStorageContext();
const { appRepository, receiveFlowRepository, sendFlowRepository, onboardingRepository } =
useStorageContext();
const history = useHistory();
const [mnemonic, setMnemonic] = useState<string>('');
const [restoration, setRestoration] = useState<RestorationJSONDictionary>();
Expand All @@ -22,7 +23,7 @@ const WalletRestore: React.FC = () => {
const onSubmit = async ({ password }: { password: string }) => {
if (mnemonic === '' || !validateMnemonic(mnemonic.trim()))
throw new Error('need a valid mnemonic');
await init(appRepository, sendFlowRepository);
await init(appRepository, receiveFlowRepository, sendFlowRepository);
await onboardingRepository.setOnboardingPasswordAndMnemonic(password, mnemonic.trim());
await appRepository.updateStatus({ isMnemonicVerified: true }); // set the mnemonic as verified cause we are in the restore mnemonic flow
if (restoration) await onboardingRepository.setRestorationJSONDictionary(restoration);
Expand Down
2 changes: 2 additions & 0 deletions src/extension/routes/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const SEND_PAYMENT_ERROR_ROUTE = '/send/payment-error';

// Lightning Receive
const LIGHTNING_ENTER_AMOUNT_ROUTE = '/lightning/invoice-amount';
const LIGHTNING_SHOW_INVOICE_ROUTE = '/lightning/invoice-show';
const LIGHTNING_ENTER_INVOICE_ROUTE = '/lightning/invoice';

// Settings
Expand Down Expand Up @@ -90,6 +91,7 @@ export {
SEND_PAYMENT_ERROR_ROUTE,
// Lightning Receive
LIGHTNING_ENTER_AMOUNT_ROUTE,
LIGHTNING_SHOW_INVOICE_ROUTE,
LIGHTNING_ENTER_INVOICE_ROUTE,
// Settings
SETTINGS_MENU_SECURITY_ROUTE,
Expand Down
5 changes: 4 additions & 1 deletion src/extension/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {
SETTINGS_EXPLORER_CUSTOM_ROUTE,
SETTINGS_ACCOUNTS_RESTORE_IONIO_ROUTE,
LIGHTNING_ENTER_AMOUNT_ROUTE,
LIGHTNING_SHOW_INVOICE_ROUTE,
LIGHTNING_ENTER_INVOICE_ROUTE,
SETTINGS_MENU_SWAPS_ROUTE,
} from './constants';
Expand All @@ -62,6 +63,8 @@ import BackUpUnlock from '../onboarding/backup-unlock';
import LogIn from '../wallet/log-in';
import PaymentError from '../wallet/send/payment-error';
import LightningAmount from '../wallet/receive/lightning-enter-amount';
import LightningShowInvoice from '../wallet/receive/lightning-show-invoice';
import LightningInvoice from '../wallet/send/lightning-enter-invoice';
// Settings
import SettingsMenuSecurity from '../settings/menu-security';
import SettingsMenuSettings from '../settings/menu-settings';
Expand Down Expand Up @@ -90,7 +93,6 @@ import SettingsNetworksView from '../settings/networks';
import SettingsDeepRestorer from '../settings/deep-restorer';
import SettingsAccounts from '../settings/accounts';
import SettingsAccountsRestoreIonio from '../settings/accounts-restore-ionio';
import LightningInvoice from '../wallet/send/lightning-enter-invoice';
import SettingsMenuSwaps from '../settings/menu-swaps';

const Routes: React.FC = () => {
Expand Down Expand Up @@ -120,6 +122,7 @@ const Routes: React.FC = () => {
<Route exact path={SEND_PAYMENT_ERROR_ROUTE} component={PaymentError} />
{/*Lightning*/}
<Route exact path={LIGHTNING_ENTER_AMOUNT_ROUTE} component={LightningAmount} />
<Route exact path={LIGHTNING_SHOW_INVOICE_ROUTE} component={LightningShowInvoice} />
<Route exact path={LIGHTNING_ENTER_INVOICE_ROUTE} component={LightningInvoice} />
{/*Settings*/}
<Route exact path={SETTINGS_MENU_SECURITY_ROUTE} component={SettingsMenuSecurity} />
Expand Down
22 changes: 18 additions & 4 deletions src/extension/wallet/home/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ import {
TRANSACTIONS_ROUTE,
LOGIN_ROUTE,
LIGHTNING_ENTER_INVOICE_ROUTE,
LIGHTNING_ENTER_AMOUNT_ROUTE,
LIGHTNING_SHOW_INVOICE_ROUTE,
} from '../../routes/constants';
import Balance from '../../components/balance';
import ButtonAsset from '../../components/button-asset';
import ButtonList from '../../components/button-list';
import ShellPopUp from '../../components/shell-popup';
import ButtonsSendReceive from '../../components/buttons-send-receive';
import { fromSatoshiWithSpaces } from '../../utility';
import { SendFlowStep } from '../../../domain/repository';
import { ReceiveFlowStep, SendFlowStep } from '../../../domain/repository';
import type { Asset } from 'marina-provider';
import { networks } from 'liquidjs-lib';
import { useStorageContext } from '../../context/storage-context';
Expand All @@ -30,6 +32,7 @@ const Home: React.FC = () => {
assetRepository,
blockHeadersRepository,
appRepository,
receiveFlowRepository,
sendFlowRepository,
refundableSwapsRepository,
cache,
Expand Down Expand Up @@ -73,6 +76,7 @@ const Home: React.FC = () => {
// update everytime the user comes back to home
// this also works when user re-opens the wallet
useEffect(() => {
if (!cache?.network) return;
(async () => {
const updater = new UpdaterService(
walletRepository,
Expand All @@ -86,7 +90,7 @@ const Home: React.FC = () => {
await updater.checkAndFixMissingTransactionsData(cache.network);
await updater.checkRefundableSwaps(cache.network);
})().catch(console.error);
}, [cache?.authenticated]);
}, [cache?.authenticated, cache?.network]);

useEffect(() => {
(async () => {
Expand All @@ -100,8 +104,18 @@ const Home: React.FC = () => {
return;
}

const step = await sendFlowRepository.getStep();
switch (step) {
const receiveStep = await receiveFlowRepository.getStep();
switch (receiveStep) {
case ReceiveFlowStep.SwapRunning:
safeHistoryPush(LIGHTNING_SHOW_INVOICE_ROUTE);
break;
case ReceiveFlowStep.AmountInserted:
safeHistoryPush(LIGHTNING_ENTER_AMOUNT_ROUTE);
break;
}

const sendStep = await sendFlowRepository.getStep();
switch (sendStep) {
case SendFlowStep.AssetSelected:
safeHistoryPush(SEND_ADDRESS_AMOUNT_ROUTE);
break;
Expand Down
Loading

0 comments on commit 2e3dfab

Please sign in to comment.