Skip to content

Commit

Permalink
Merge branch 'development' into rt/feature/dapp-template
Browse files Browse the repository at this point in the history
  • Loading branch information
razvantomegea authored Dec 19, 2024
2 parents 58cc80a + 7930928 commit a91dd83
Show file tree
Hide file tree
Showing 23 changed files with 599 additions and 74 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

- [Added provider constants and helpers](https://github.com/multiversx/mx-sdk-dapp-core/pull/50)
- [Added pending transactions](https://github.com/multiversx/mx-sdk-dapp-core/pull/48)
- [Added transaction manager](https://github.com/multiversx/mx-sdk-dapp-core/pull/41)
- [Added custom web socket url support](https://github.com/multiversx/mx-sdk-dapp-core/pull/35)
- [Metamask integration](https://github.com/multiversx/mx-sdk-dapp-core/pull/27)
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
"@lifeomic/axios-fetch": "3.0.1",
"@multiversx/sdk-extension-provider": "4.0.0",
"@multiversx/sdk-hw-provider": "7.0.0",
"@multiversx/sdk-metamask-provider": "0.0.7",
"@multiversx/sdk-metamask-provider": "1.0.0",
"@multiversx/sdk-native-auth-client": "^1.0.8",
"@multiversx/sdk-opera-provider": "1.0.0-alpha.1",
"@multiversx/sdk-wallet": "4.5.1",
Expand All @@ -51,7 +51,7 @@
"peerDependencies": {
"@multiversx/sdk-core": ">= 13.5.0",
"@multiversx/sdk-dapp-utils": ">= 1.0.0",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 2.0.1",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 2.0.4",
"axios": ">=1.6.5",
"bignumber.js": "9.x",
"immer": "10.x"
Expand All @@ -66,7 +66,7 @@
"@eslint/js": "9.15.0",
"@multiversx/sdk-core": ">= 13.5.0",
"@multiversx/sdk-dapp-utils": "1.0.0",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 2.0.1",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 2.0.4",
"@swc/core": "^1.4.17",
"@swc/jest": "^0.2.36",
"@types/jest": "29.5.13",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { IEventBus } from 'types/manager.types';
import {
IPendingTransactionsModalData,
PendingTransactionsEventsEnum
} from './types';

export class PendingTransactionsStateManager<
T extends
IEventBus<IPendingTransactionsModalData> = IEventBus<IPendingTransactionsModalData>
> {
private static instance: PendingTransactionsStateManager<
IEventBus<IPendingTransactionsModalData>
> | null = null;
private eventBus: T;

private initialData: IPendingTransactionsModalData = {
isPending: false,
title: '',
subtitle: '',
shouldClose: false
};

private data: IPendingTransactionsModalData = { ...this.initialData };

private constructor(eventBus: T) {
this.eventBus = eventBus;
}

public static getInstance<U extends IEventBus<IPendingTransactionsModalData>>(
eventBus: U
): PendingTransactionsStateManager<U> {
if (!PendingTransactionsStateManager.instance) {
PendingTransactionsStateManager.instance =
new PendingTransactionsStateManager(eventBus);
}
return PendingTransactionsStateManager.instance as PendingTransactionsStateManager<U>;
}

public closeAndReset(): void {
this.data.shouldClose = true;
this.notifyDataUpdate();
this.resetData();
}

private resetData(): void {
this.data = { ...this.initialData };
}

public updateData(newData: IPendingTransactionsModalData): void {
this.data = { ...this.data, ...newData };
this.notifyDataUpdate();
}

private notifyDataUpdate(): void {
this.eventBus.publish(PendingTransactionsEventsEnum.DATA_UPDATE, this.data);
}
}
2 changes: 2 additions & 0 deletions src/core/managers/PendingTransactionsStateManager/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './PendingTransactionsStateManagement';
export * from './types';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './pendingTransactions.types';
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// types here need to be synced with the types in sdk-dapp-core-ui
export enum PendingTransactionsEventsEnum {
'CLOSE' = 'CLOSE',
'DATA_UPDATE' = 'DATA_UPDATE'
}

export interface IPendingTransactionsModalData {
isPending: boolean;
title: string;
subtitle?: string;
shouldClose?: boolean;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@ import {
IWalletConnectModalData,
WalletConnectEventsEnum
} from 'core/providers/strategies/WalletConnectProviderStrategy/types';

interface IEventBus {
publish(event: string, data: any): void;
}

export class WalletConnectStateManager<T extends IEventBus = IEventBus> {
private static instance: WalletConnectStateManager<IEventBus> | null = null;
import { IEventBus } from 'types/manager.types';

export class WalletConnectStateManager<
T extends
IEventBus<IWalletConnectModalData> = IEventBus<IWalletConnectModalData>
> {
private static instance: WalletConnectStateManager<
IEventBus<IWalletConnectModalData>
> | null = null;
private eventBus: T;

private initialData: IWalletConnectModalData = {
Expand All @@ -22,7 +24,7 @@ export class WalletConnectStateManager<T extends IEventBus = IEventBus> {
this.eventBus = eventBus;
}

public static getInstance<U extends IEventBus>(
public static getInstance<U extends IEventBus<IWalletConnectModalData>>(
eventBus: U
): WalletConnectStateManager<U> {
if (!WalletConnectStateManager.instance) {
Expand Down
1 change: 1 addition & 0 deletions src/core/managers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ export * from './LedgerConnectStateManager';
export * from './SignTransactionsStateManager';
export * from './TransactionManager';
export * from './WalletConnectStateManager';
export * from './PendingTransactionsStateManager';
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
import { Message, Transaction } from '@multiversx/sdk-core/out';
import { isBrowserWithPopupConfirmation } from 'constants/browser.constants';
import {
PendingTransactionsStateManager,
PendingTransactionsEventsEnum
} from 'core/managers';
import { getAccount } from 'core/methods/account/getAccount';
import { getAddress } from 'core/methods/account/getAddress';
import { IProvider } from 'core/providers/types/providerFactory.types';
import { PendingTransactionsModal } from 'lib/sdkDappCoreUi';
import { CrossWindowProvider } from 'lib/sdkWebWalletCrossWindowProvider';
import { crossWindowConfigSelector } from 'store/selectors';
import { networkSelector } from 'store/selectors/networkSelectors';
import { getState } from 'store/store';
import { ProviderErrorsEnum } from 'types';
import { createModalElement } from 'utils/createModalElement';

type CrossWindowProviderProps = {
address?: string;
Expand Down Expand Up @@ -83,22 +89,69 @@ export class CrossWindowProviderStrategy {
throw new Error(ProviderErrorsEnum.notInitialized);
}

this.setPopupConsent();
const modalElement = await createModalElement<PendingTransactionsModal>(
'pending-transactions-modal'
);
const { eventBus, onClose, manager } =
await this.getModalHandlers(modalElement);

eventBus.subscribe(PendingTransactionsEventsEnum.CLOSE, onClose);

const signedTransactions: Transaction[] =
(await this._signTransactions(transactions)) ?? [];
manager.updateData({
isPending: true,
title: 'Confirm on MultiversX Web Wallet',
subtitle: 'Check your MultiversX Web Wallet to sign the transaction'
});

this.setPopupConsent();

// Guarded Transactions or Signed Transactions
return this.getTransactions(signedTransactions);
try {
const signedTransactions: Transaction[] =
(await this._signTransactions(transactions)) ?? [];

// Guarded Transactions or Signed Transactions
return this.getTransactions(signedTransactions);
} catch (error) {
this.provider.cancelAction();
throw error;
} finally {
onClose(false);
eventBus.unsubscribe(PendingTransactionsEventsEnum.CLOSE, onClose);
}
};

private signMessage = async (message: Message) => {
if (!this.provider || !this._signMessage) {
throw new Error(ProviderErrorsEnum.notInitialized);
}

const modalElement = await createModalElement<PendingTransactionsModal>(
'pending-transactions-modal'
);
const { eventBus, onClose, manager } =
await this.getModalHandlers(modalElement);

eventBus.subscribe(PendingTransactionsEventsEnum.CLOSE, onClose);

manager.updateData({
isPending: true,
title: 'Message Signing',
subtitle: 'Check your MultiversX Web Wallet to sign the message'
});

this.setPopupConsent();
return this._signMessage(message);

try {
const signedMessage = await this._signMessage(message);

return signedMessage;
} catch (error) {
this.provider.cancelAction();
throw error;
} finally {
onClose(false);
eventBus.unsubscribe(PendingTransactionsEventsEnum.CLOSE, onClose);
}
};

private setPopupConsent = () => {
Expand Down Expand Up @@ -159,4 +212,27 @@ export class CrossWindowProviderStrategy {
Boolean(tx.getGuardianSignature().toString('hex'))
);
};

private getModalHandlers = async (modalElement: PendingTransactionsModal) => {
const eventBus = await modalElement.getEventBus();

if (!eventBus) {
throw new Error(ProviderErrorsEnum.eventBusError);
}

const manager = PendingTransactionsStateManager.getInstance(eventBus);

const onClose = (cancelAction = true) => {
if (!this.provider) {
throw new Error(ProviderErrorsEnum.notInitialized);
}

if (cancelAction) {
this.provider.cancelAction();
}

manager.closeAndReset();
};
return { eventBus, manager, onClose };
};
}
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from './CrossWindowProviderStrategy';
export * from './types';
Loading

0 comments on commit a91dd83

Please sign in to comment.