Skip to content

Commit

Permalink
Update providers
Browse files Browse the repository at this point in the history
  • Loading branch information
mgavrila committed Dec 12, 2024
1 parent 64c86cd commit 9832acc
Show file tree
Hide file tree
Showing 13 changed files with 177 additions and 131 deletions.
6 changes: 3 additions & 3 deletions src/constants/network.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const fallbackNetworkConfigurations: Record<
walletConnectBridgeAddresses: ['https://bridge.walletconnect.org'],
walletConnectV2RelayAddresses: ['wss://relay.walletconnect.com'],
walletAddress: 'https://devnet-wallet.multiversx.com',
metamaskSnapWalletAddress: 'https://devnet-snap-wallet.multiversx.com',
iframeWalletAddress: 'https://devnet-snap-wallet.multiversx.com',
xAliasAddress: 'https://devnet.xalias.com',
apiAddress: 'https://devnet-api.multiversx.com',
explorerAddress: 'http://devnet-explorer.multiversx.com',
Expand All @@ -38,7 +38,7 @@ export const fallbackNetworkConfigurations: Record<
walletConnectBridgeAddresses: ['https://bridge.walletconnect.org'],
walletConnectV2RelayAddresses: ['wss://relay.walletconnect.com'],
walletAddress: 'https://testnet-wallet.multiversx.com',
metamaskSnapWalletAddress: 'https://testnet-snap-wallet.multiversx.com',
iframeWalletAddress: 'https://testnet-snap-wallet.multiversx.com',
xAliasAddress: 'https://testnet.xalias.com',
apiAddress: 'https://testnet-api.multiversx.com',
explorerAddress: 'http://testnet-explorer.multiversx.com',
Expand All @@ -58,7 +58,7 @@ export const fallbackNetworkConfigurations: Record<
walletConnectBridgeAddresses: ['https://bridge.walletconnect.org'],
walletConnectV2RelayAddresses: ['wss://relay.walletconnect.com'],
walletAddress: 'https://wallet.multiversx.com',
metamaskSnapWalletAddress: 'https://snap-wallet.multiversx.com',
iframeWalletAddress: 'https://snap-wallet.multiversx.com',
xAliasAddress: 'https://xalias.com',
apiAddress: 'https://api.multiversx.com',
explorerAddress: 'https://explorer.multiversx.com',
Expand Down
110 changes: 99 additions & 11 deletions src/core/providers-strategy/CrossWindowProviderStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,21 @@
import { Message, Transaction } from '@multiversx/sdk-core/out';
import { isBrowserWithPopupConfirmation } from 'constants/browser.constants';
import { getAccount } from 'core/methods/account/getAccount';
import { IProvider } from 'core/providers/types/providerFactory.types';
import { CrossWindowProvider } from 'lib/sdkWebWalletCrossWindowProvider';
import { networkSelector } from 'store/selectors/networkSelectors';
import { getState } from 'store/store';
import { ProviderError } from 'types';

export class CrossWindowProviderStrategy {
private provider: CrossWindowProvider | null = null;
private address: string = '';
private walletAddress: string = '';
private cwSignTransactions:
| ((transactions: Transaction[]) => Promise<Transaction[]>)
| null = null;
private cwSignMessage: ((messageToSign: Message) => Promise<Message>) | null =
null;

constructor(
address: string | undefined,
Expand All @@ -18,33 +26,113 @@ export class CrossWindowProviderStrategy {
}

public createProvider = async (): Promise<IProvider> => {
this.createCrossWindowProvider();

return this.buildProvider();
};

// Need to be used inside getGuardedTransactions
public createCrossWindowProvider = async () => {
const network = networkSelector(getState());

if (!this.provider) {
this.provider = CrossWindowProvider.getInstance();
this.provider.init();
}

// Bind in order to break reference
this.cwSignTransactions = this.provider.signTransactions.bind(
this.provider
);
this.cwSignMessage = this.provider.signMessage.bind(this.provider);

this.provider.setWalletUrl(this.walletAddress || network.walletAddress);
this.provider.setAddress(this.address);

if (isBrowserWithPopupConfirmation) {
this.provider.setShouldShowConsentPopup(true);
}
this.setPopupConsent();

return this.provider;
return this.buildProvider();
};

private buildProvider = () => {
if (!this.provider) {
throw new Error(ProviderError.notInitialized);
}

const provider = this.provider as unknown as IProvider;
provider.signTransactions = this.signTransactions;
provider.signMessage = this.signMessage;

return provider;
};

private signTransactions = async (transactions: Transaction[]) => {
if (!this.provider || !this.cwSignTransactions) {
throw new Error(ProviderError.notInitialized);
}

this.setPopupConsent();

const signedTransactions: Transaction[] =
(await this.cwSignTransactions(transactions)) ?? [];

// Guarded Transactions or Signed Transactions
return this.getTransactions(signedTransactions);
};

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

this.setPopupConsent();
return this.cwSignMessage(message);
};

private setPopupConsent = () => {
if (!this.provider) {
throw new Error(ProviderError.notInitialized);
}

if (!isBrowserWithPopupConfirmation) {
return;
}

this.provider.setShouldShowConsentPopup(true);
};

private getTransactions = async (transactions: Transaction[]) => {
if (!this.provider) {
throw new Error(ProviderError.notInitialized);
}

const { isGuarded } = getAccount();

const allSignedByGuardian = this.getAreAllTransactionsSignedByGuardian({
isGuarded,
transactions
});

if (!isGuarded || allSignedByGuardian) {
return transactions;
}

const guardedTransactions =
await this.provider.guardTransactions(transactions);

return guardedTransactions;
};

private getAreAllTransactionsSignedByGuardian = ({
transactions,
isGuarded
}: {
transactions: Transaction[];
isGuarded?: boolean;
}) => {
if (!isGuarded) {
return true;
}

if (transactions.length === 0) {
return false;
}

return transactions.every((tx) =>
Boolean(tx.getGuardianSignature().toString('hex'))
);
};
}
7 changes: 4 additions & 3 deletions src/core/providers-strategy/CustomProviderStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,19 @@ import {
IProviderConfig,
ProviderTypeEnum
} from 'core/providers/types/providerFactory.types';
import { ProviderError } from 'types';

export class CustomProviderStrategy {
private provider: ICustomProvider<ProviderTypeEnum> | null = null;
private type: string = '';
private type: ICustomProvider['type'] = '';
private config: IProviderConfig = {};

constructor({
type,
customProvider,
config
}: {
type: string;
type: ICustomProvider['type'];
customProvider: ICustomProvider<ProviderTypeEnum>;
config: IProviderConfig;
}) {
Expand All @@ -38,7 +39,7 @@ export class CustomProviderStrategy {
const provider = await this.provider?.constructor(this.config);

if (!provider) {
throw new Error('Provider is not initialized');
throw new Error(ProviderError.notInitialized);
}

return provider;
Expand Down
7 changes: 5 additions & 2 deletions src/core/providers-strategy/ExtensionProviderStrategy.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ExtensionProvider } from '@multiversx/sdk-extension-provider/out/extensionProvider';
import { IProvider } from 'core/providers/types/providerFactory.types';
import { ProviderError } from 'types';

export class ExtensionProviderStrategy {
private provider: ExtensionProvider | null = null;
Expand All @@ -14,8 +15,10 @@ export class ExtensionProviderStrategy {
};

private buildProvider = () => {
const provider = this.provider as unknown as IProvider;
if (!this.provider) {
throw new Error(ProviderError.notInitialized);
}

return provider;
return this.provider as unknown as IProvider;
};
}
19 changes: 16 additions & 3 deletions src/core/providers-strategy/IFrameProviderStrategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,45 @@ import { IframeLoginTypes } from '@multiversx/sdk-web-wallet-iframe-provider/out
import { IProvider } from 'core/providers/types/providerFactory.types';
import { networkSelector } from 'store/selectors/networkSelectors';
import { getState } from 'store/store';
import { ProviderError } from 'types';

type IFrameProviderType = {
type: IframeLoginTypes | null;
address?: string;
};
export class IFrameProviderStrategy {
private provider: IframeProvider | null = null;
private address: string = '';
private type: IframeLoginTypes = IframeLoginTypes.metamask;
private type: IframeLoginTypes | null = null;

constructor(type: IframeLoginTypes, address: string | undefined = '') {
constructor({ type, address = '' }: IFrameProviderType) {
this.type = type;
this.address = address;
}

public createProvider = async (): Promise<IProvider> => {
const network = networkSelector(getState());

if (!this.type) {
throw new Error('Provider type is not configured.');
}

if (!this.provider) {
this.provider = IframeProvider.getInstance();
await this.provider.init();
}

this.provider.setLoginType(this.type);
this.provider.setWalletUrl(String(network.metamaskSnapWalletAddress));
this.provider.setWalletUrl(String(network.iframeWalletAddress));

return this.buildProvider();
};

private buildProvider = () => {
if (!this.provider) {
throw new Error(ProviderError.notInitialized);
}

const provider = this.provider as unknown as IProvider;

if (this.address) {
Expand Down
Loading

0 comments on commit 9832acc

Please sign in to comment.