Skip to content

Commit

Permalink
Integrate Metamask (#27)
Browse files Browse the repository at this point in the history
* Integrate Metamask

* Turn consts into functions
  • Loading branch information
arhtudormorar authored Oct 11, 2024
1 parent 3a160bd commit 695d294
Show file tree
Hide file tree
Showing 32 changed files with 626 additions and 539 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

- [Metamask integration](https://github.com/multiversx/mx-sdk-dapp-core/pull/27)
- [Extension integration](https://github.com/multiversx/mx-sdk-dapp-core/pull/26)
- [Ledger integration](https://github.com/multiversx/mx-sdk-dapp-core/pull/22)
- [Added sign, send, & track transactions with websocket connection](https://github.com/multiversx/mx-sdk-dapp-core/pull/21)
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
"url": "git+https://github.com/multiversx/mx-sdk-dapp-core.git"
},
"scripts": {
"unpublish-verdaccio": "npm unpublish @multiversx/[email protected] --registry http://localhost:4873",
"publish-verdaccio": "npm run unpublish-verdaccio && npm run compile && npm publish --registry http://localhost:4873/",
"compile": "tsc && tsc-alias",
"build-esbuild": "rimraf out && node esbuild.js",
"publish-verdaccio": "npm unpublish --registry http://localhost:4873 @multiversx/[email protected] && rimraf out && yarn compile && npm publish --registry http://localhost:4873",
"build": "yarn build-esbuild && yarn compile",
"test": "jest",
"compile-next": "rimraf out && tsc --p tsconfig.next.json && tsc-alias --project tsconfig.next.json"
Expand All @@ -38,6 +39,7 @@
"@multiversx/sdk-opera-provider": "1.0.0-alpha.1",
"@multiversx/sdk-wallet": "4.5.1",
"@multiversx/sdk-wallet-connect-provider": "4.1.2",
"@multiversx/sdk-web-wallet-iframe-provider": "2.0.1",
"@multiversx/sdk-web-wallet-provider": "3.2.1",
"isomorphic-fetch": "3.0.0",
"lodash": "4.17.21",
Expand Down
3 changes: 3 additions & 0 deletions src/constants/network.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +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',
xAliasAddress: 'https://devnet.xalias.com',
apiAddress: 'https://devnet-api.multiversx.com',
explorerAddress: 'http://devnet-explorer.multiversx.com',
Expand All @@ -37,6 +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',
xAliasAddress: 'https://testnet.xalias.com',
apiAddress: 'https://testnet-api.multiversx.com',
explorerAddress: 'http://testnet-explorer.multiversx.com',
Expand All @@ -56,6 +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',
xAliasAddress: 'https://xalias.com',
apiAddress: 'https://api.multiversx.com',
explorerAddress: 'https://explorer.multiversx.com',
Expand Down
4 changes: 2 additions & 2 deletions src/core/methods/account/getLatestNonce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import { accountNonceSelector } from 'store/selectors/accountSelectors';
import { getState } from 'store/store';
import { AccountType } from 'types/account.types';

export const getLatestNonce = (account: AccountType | null) => {
export function getLatestNonce(account: AccountType | null) {
const currentAccountNonce = accountNonceSelector(getState());
if (!account) {
return currentAccountNonce;
}
return currentAccountNonce && !isNaN(currentAccountNonce)
? Math.max(currentAccountNonce, account.nonce)
: account.nonce;
};
}
4 changes: 2 additions & 2 deletions src/core/methods/account/getWebviewToken.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { getWindowLocation } from 'utils/window/getWindowLocation';

export const getWebviewToken = () => {
export function getWebviewToken() {
const { search } = getWindowLocation();
const urlSearchParams = new URLSearchParams(search) as any;
const searchParams = Object.fromEntries(urlSearchParams);

return searchParams?.accessToken;
};
}
6 changes: 3 additions & 3 deletions src/core/methods/initApp/initApp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ const defaultInitAppProps = {
});
* ```
* */
export const initApp = async ({
export async function initApp({
storage = defaultInitAppProps.storage,
dAppConfig
}: InitAppType) => {
}: InitAppType) {
initStore(storage.getStorageCallback);

const shouldEnableTransactionTracker =
Expand Down Expand Up @@ -61,4 +61,4 @@ export const initApp = async ({
await restoreProvider();
await registerWebsocketListener();
}
};
}
4 changes: 2 additions & 2 deletions src/core/methods/initApp/websocket/registerWebsocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getAccount } from 'core/methods/account/getAccount';
let localAddress = '';
let closeConnectionRef: () => void;

export const registerWebsocketListener = async () => {
export async function registerWebsocketListener() {
const store = getStore();
const account = getAccount();
localAddress = account.address;
Expand All @@ -22,4 +22,4 @@ export const registerWebsocketListener = async () => {
closeConnectionRef = closeConnection;
}
});
};
}
16 changes: 9 additions & 7 deletions src/core/methods/login/helpers/extractAccountFromToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,22 @@ import { AccountType } from 'types/account.types';
import { getAccountFromToken } from './getAccountFromToken';
import { getLatestNonce } from 'core/methods/account/getLatestNonce';

export async function extractAccountFromToken({
loginToken,
extraInfoData,
address,
provider
}: {
interface IExtractAccountFromTokenProps {
loginToken: string;
extraInfoData: {
multisig?: string;
impersonate?: string;
};
address: string;
provider: IProvider;
}) {
}

export async function extractAccountFromToken({
loginToken,
extraInfoData,
address,
provider
}: IExtractAccountFromTokenProps) {
const accountDetails = await getAccountFromToken({
originalLoginToken: loginToken,
extraInfoData,
Expand Down
6 changes: 3 additions & 3 deletions src/core/methods/login/helpers/getAccountFromToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ interface GetAccountFromTokenType {
};
}

export const getAccountFromToken = async ({
export async function getAccountFromToken({
originalLoginToken,
extraInfoData,
address
}: GetAccountFromTokenType) => {
}: GetAccountFromTokenType) {
const modifiedLoginToken = await getModifiedLoginToken({
loginToken: originalLoginToken,
extraInfoData
Expand All @@ -32,4 +32,4 @@ export const getAccountFromToken = async ({
address: accountAddress,
modifiedLoginToken
};
};
}
4 changes: 2 additions & 2 deletions src/core/methods/login/helpers/getLoginService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const getApiAddress = (
return config.apiAddress ?? apiAddress;
};

export const getLoginService = (config?: OnProviderLoginType['nativeAuth']) => {
export function getLoginService(config?: OnProviderLoginType['nativeAuth']) {
const network = networkSelector(getState());

const tokenLogin = tokenLoginSelector(getState());
Expand Down Expand Up @@ -138,4 +138,4 @@ export const getLoginService = (config?: OnProviderLoginType['nativeAuth']) => {
setTokenLoginInfo,
refreshNativeAuthTokenLogin
};
};
}
6 changes: 3 additions & 3 deletions src/core/methods/login/helpers/getModifiedLoginToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ export interface GetMultiSigLoginTokenType {
};
}

export const getModifiedLoginToken = async ({
export async function getModifiedLoginToken({
loginToken,
extraInfoData
}: GetMultiSigLoginTokenType) => {
}: GetMultiSigLoginTokenType) {
if (loginToken == null || Object.keys(extraInfoData).length === 0) {
return null;
}
Expand All @@ -40,4 +40,4 @@ export const getModifiedLoginToken = async ({
});

return tokenLogin;
};
}
6 changes: 3 additions & 3 deletions src/core/methods/login/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,11 +104,11 @@ async function loginWithNativeToken(
};
}

export const login = async ({
export async function login({
providerConfig
}: {
providerConfig: IProviderFactory;
}) => {
}) {
const loggedIn = getIsLoggedIn();

if (loggedIn) {
Expand Down Expand Up @@ -138,4 +138,4 @@ export const login = async ({
await registerWebsocketListener();

return data;
};
}
7 changes: 3 additions & 4 deletions src/core/methods/sendTransactions/sendTransactions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { Transaction } from '@multiversx/sdk-core/out';
import { AxiosError } from 'axios';
import { sendSignedTransactions } from './helpers/sendSignedTransactions';
import { SignedTransactionType } from 'types/transactions.types';
import { createTransactionsSession } from 'store/actions/transactions/transactionsActions';

export const sendTransactions = async (
export async function sendTransactions(
transactions: Transaction[] = []
): Promise<string | null> => {
): Promise<string | null> {
if (transactions.length === 0) {
return null;
}
Expand All @@ -24,4 +23,4 @@ export const sendTransactions = async (
);
throw responseData?.message ?? (error as any).message;
}
};
}
4 changes: 2 additions & 2 deletions src/core/methods/signMessage/getVerifier.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Address } from '@multiversx/sdk-core/out';
import { UserPublicKey, UserVerifier } from '@multiversx/sdk-wallet';

export const getVerifier = (address: string) => {
export function getVerifier(address: string) {
const publicKey = new UserPublicKey(Address.fromString(address).pubkey());

return new UserVerifier(publicKey);
};
}
6 changes: 3 additions & 3 deletions src/core/methods/signMessage/signMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ export interface SignMessageType {
};
}

export const signMessage = async ({
export async function signMessage({
message,
options
}: SignMessageType): Promise<Nullable<Message>> => {
}: SignMessageType): Promise<Nullable<Message>> {
const address = getAddress();
const provider = getAccountProvider();
const providerType = getProviderType(provider);
Expand All @@ -42,4 +42,4 @@ export const signMessage = async ({

// TODO upgrade sdk-dapp-utils to return Message instead of SignableMessage and remove the cast
return signedMessage as Nullable<Message>;
};
}
5 changes: 3 additions & 2 deletions src/core/methods/signMessage/verifyMessage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Address, SignableMessage } from '@multiversx/sdk-core/out';
import { getVerifier } from './getVerifier';

export const verifyMessage = (signedMessage: string) => {
// TODO: upgrade
export function verifyMessage(signedMessage: string) {
try {
const { message, address, signature } = JSON.parse(signedMessage);

Expand Down Expand Up @@ -32,4 +33,4 @@ export const verifyMessage = (signedMessage: string) => {
address: ''
};
}
};
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { Transaction } from '@multiversx/sdk-core/out';

export const getAreAllTransactionsSignedByGuardian = ({
transactions,
isGuarded
}: {
interface IGetAreAllTransactionsSignedByGuardian {
transactions: Transaction[];
isGuarded?: boolean;
}) => {
}

export function getAreAllTransactionsSignedByGuardian({
transactions,
isGuarded
}: IGetAreAllTransactionsSignedByGuardian) {
if (!isGuarded) {
return true;
}
Expand All @@ -18,4 +20,4 @@ export const getAreAllTransactionsSignedByGuardian = ({
return transactions.every((tx) =>
Boolean(tx.getGuardianSignature().toString('hex'))
);
};
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { Transaction } from '@multiversx/sdk-core';
import { getAreAllTransactionsSignedByGuardian } from './getAreAllTransactionsSignedByGuardian';
import { ProviderFactory } from 'core/providers/ProviderFactory';
import { getAccount } from 'core/methods/account/getAccount';
import { walletAddressSelector } from 'store/selectors';
import { getState } from 'store/store';
import { createCrossWindowProvider } from 'core/providers/helpers/crossWindow/createCrossWindowProvider';

export const getGuardedTransactions = async ({
export async function getGuardedTransactions({
transactions
}: {
transactions: Transaction[];
}): Promise<Transaction[]> => {
}): Promise<Transaction[]> {
const { isGuarded, address } = getAccount();
const walletAddress = walletAddressSelector(getState());

Expand All @@ -22,8 +22,7 @@ export const getGuardedTransactions = async ({
return transactions;
}

const factory = new ProviderFactory();
const provider = await factory.createCrossWindowProvider({
const provider = await createCrossWindowProvider({
address,
walletAddress
});
Expand All @@ -32,4 +31,4 @@ export const getGuardedTransactions = async ({
const guardedTransactions = await provider.guardTransactions(transactions);

return guardedTransactions;
};
}
8 changes: 4 additions & 4 deletions src/core/methods/signTransactions/signTransactions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ type SignTransactionsOptionsType = {
skipGuardian?: boolean;
};

export const signTransactions = async (
export async function signTransactions(
transactions: Transaction[],
options: SignTransactionsOptionsType = {}
): Promise<Transaction[]> => {
): Promise<Transaction[]> {
const provider = getAccountProvider();
const { isGuarded, activeGuardianAddress } = getAccount();

const transacitonsToSign =
activeGuardianAddress && !options.skipGuardian
activeGuardianAddress && isGuarded && !options.skipGuardian
? transactions?.map((transaction) => {
transaction.setVersion(TransactionVersion.withTxOptions());
transaction.setOptions(
Expand All @@ -39,4 +39,4 @@ export const signTransactions = async (
: signedTransactions;

return guardedTransactions;
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { TRANSACTIONS_STATUS_POLLING_INTERVAL_MS } from 'constants/transactions.
import { roundDurationSelectorSelector } from 'store/selectors';
import { getState } from 'store/store';

export const getPollingInterval = () => {
export function getPollingInterval() {
const roundDuration = roundDurationSelectorSelector(getState());

if (!roundDuration) {
Expand All @@ -11,4 +11,4 @@ export const getPollingInterval = () => {

// Polling interval should not be less than 1s
return Math.max(1000, roundDuration / 2);
};
}
Loading

0 comments on commit 695d294

Please sign in to comment.