Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CrossWindow login #13

Merged
merged 12 commits into from
Aug 29, 2024
4 changes: 2 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]


- [Added sdk-web-wallet-cross-window-provider as peer dependency](https://github.com/multiversx/mx-sdk-dapp-core/pull/12)
- [CrossWindow login](https://github.com/multiversx/mx-sdk-dapp-core/pull/13)
- [Added sdk-web-wallet-cross-window-provider as peer dependency](https://github.com/multiversx/mx-sdk-dapp-core/pull/14)
- [Generic login + ExtensionProvider login](https://github.com/multiversx/mx-sdk-dapp-core/pull/12)
- [Make middlewares registration more scalable](https://github.com/multiversx/mx-sdk-dapp-core/pull/11)
- [Fix Node Polyfills](https://github.com/multiversx/mx-sdk-dapp-core/pull/10)
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
},
"peerDependencies": {
"@multiversx/sdk-core": ">= 13.0.0",
"@multiversx/sdk-dapp-utils": "^0.0.1",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 0.4.2",
"@multiversx/sdk-dapp-utils": ">= 0.1.0",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 1.0.0",
"axios": ">=1.6.5",
"bignumber.js": "9.x"
},
Expand All @@ -55,8 +55,8 @@
},
"devDependencies": {
"@multiversx/sdk-core": ">= 13.0.0",
"@multiversx/sdk-dapp-utils": "^0.0.1",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 0.4.2",
"@multiversx/sdk-dapp-utils": ">= 0.1.0",
"@multiversx/sdk-web-wallet-cross-window-provider": ">= 1.0.0",
"@swc/core": "^1.4.17",
"@swc/jest": "^0.2.36",
"@types/node": "20.12.8",
Expand Down
7 changes: 5 additions & 2 deletions src/apiCalls/accounts/getAccountFromApi.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import { ACCOUNTS_ENDPOINT } from 'apiCalls/endpoints';
import { axiosInstance } from 'apiCalls/utils/axiosInstance';
import { getCleanApiAddress } from 'apiCalls/utils/getCleanApiAddress';
import { AccountType } from 'types/account.types';

export const accountFetcher = (address: string | null) => {
const apiAddress = getCleanApiAddress();
const url = `${apiAddress}/${ACCOUNTS_ENDPOINT}/${address}?withGuardianInfo=true`;
// we need to get it with an axios instance because of cross-window user interaction issues
return axiosInstance.get(url);
return axiosInstance.get(url, {
baseURL: apiAddress
});
};

export const getAccountFromApi = async (address?: string) => {
Expand All @@ -16,7 +19,7 @@ export const getAccountFromApi = async (address?: string) => {

try {
const { data } = await accountFetcher(address);
return data;
return data as AccountType;
} catch (err) {
console.error('error fetching configuration for ', address);
}
Expand Down
50 changes: 42 additions & 8 deletions src/core/methods/init/init.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,64 @@
import { initStore } from 'store/store';
import { defaultStorageCallback, StorageCallback } from 'store/storage';
import { setTokenLoginNativeAuthTokenConfig } from 'store/actions/loginInfo/loginInfoActions';
import { setNativeAuthConfig } from 'store/actions/config/configActions';
import { initializeNetwork } from 'store/actions';
import { CustomNetworkType } from 'types/network.types';
import { EnvironmentsEnum } from 'types/enums.types';
import { NativeAuthConfigType } from 'services/nativeAuth/nativeAuth.types';
import { getDefaultNativeAuthConfig } from 'services/nativeAuth/methods/getDefaultNativeAuthConfig';

type InitAppType = {
storage?: {
getStorageCallback: StorageCallback;
};
nativeAuth?: boolean | NativeAuthConfigType;
dAppConfig?: {
nativeAuth?: boolean | NativeAuthConfigType;
network?: CustomNetworkType;
environment?: EnvironmentsEnum;
};
};
const defaultInitAppProps = {
storage: {
getStorageCallback: defaultStorageCallback
}
};
export const initializeDApp = (props?: InitAppType) => {
const { storage, nativeAuth } = { ...defaultInitAppProps, ...props };

/**
* Initializes the dApp with the given configuration.
* @param props - The configuration for the dApp initialization.
* @param props.storage - The storage configuration for the dApp.
* @param props.storage.getStorageCallback - The callback to get the storage (custom storage).
* @param props.nativeAuth - The native auth configuration for the dApp.
* @param props.nativeAuth - If set to `true`, will fallback on default configuration.
* @param props.nativeAuth - If set to `false`, will disable native auth.
* @param props.nativeAuth - If set to `NativeAuthConfigType`, will set the native auth configuration.
*
* !!! Avoid changing the configuration during the dApp lifecycle.
*
* @example
* ```ts
* initializeDApp({
* nativeAuth: true
* });
* ```
* */
export const initializeDApp = async (props?: InitAppType) => {
const { storage, dAppConfig } = { ...defaultInitAppProps, ...props };
initStore(storage.getStorageCallback);

if (nativeAuth) {
if (dAppConfig?.nativeAuth) {
const nativeAuthConfig: NativeAuthConfigType =
typeof nativeAuth === 'boolean'
typeof dAppConfig.nativeAuth === 'boolean'
? getDefaultNativeAuthConfig()
: nativeAuth;
: dAppConfig.nativeAuth;

setNativeAuthConfig(nativeAuthConfig);
}

setTokenLoginNativeAuthTokenConfig(nativeAuthConfig);
if (dAppConfig?.network) {
await initializeNetwork({
customNetworkConfig: dAppConfig.network,
environment: dAppConfig.environment ?? EnvironmentsEnum.devnet
});
}
};
6 changes: 6 additions & 0 deletions src/core/methods/login/helpers/getCallbackUrl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { getWindowLocation } from 'utils/window/getWindowLocation';

export function getCallbackUrl() {
const { origin, pathname } = getWindowLocation();
return encodeURIComponent(`${origin}${pathname}`);
}
35 changes: 35 additions & 0 deletions src/core/methods/login/helpers/getImpersonatedAccountDetails.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { getAccount } from 'utils/account/getAccount';
import { getModifiedLoginToken } from './getModifiedLoginToken';

interface GetImpersonatedAccountDetailsType {
address: string;
originalLoginToken?: string;
extraInfoData: {
multisig?: string;
impersonate?: string;
};
}

export const getImpersonatedAccountDetails = async ({
originalLoginToken,
extraInfoData,
address
}: GetImpersonatedAccountDetailsType) => {
const modifiedLoginToken = await getModifiedLoginToken({
loginToken: originalLoginToken,
extraInfoData
});

const tokenAddress =
extraInfoData.multisig || extraInfoData.impersonate || address;

const accountAddress = modifiedLoginToken != null ? tokenAddress : address;

const account = await getAccount(accountAddress);

return {
account,
address: accountAddress,
modifiedLoginToken
};
};
52 changes: 52 additions & 0 deletions src/core/methods/login/helpers/impersonateAccount.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { setAccount } from 'store/actions/account';
import { setLoginToken } from 'store/actions/loginInfo/loginInfoActions';
import { IProvider } from 'core/providers/types/providerFactory.types';
import { loginAction } from 'store/actions';
import { AccountType } from 'types/account.types';
import { getImpersonatedAccountDetails } from './getImpersonatedAccountDetails';
import { getLatestNonce } from 'core/methods/account/getLatestNonce';

export async function impersonateAccount({
loginToken,
extraInfoData,
address,
provider
}: {
loginToken: string;
extraInfoData: {
multisig?: string;
impersonate?: string;
};
address: string;
provider: IProvider;
}) {
const impersonationDetails = await getImpersonatedAccountDetails({
originalLoginToken: loginToken,
extraInfoData,
address
});

if (impersonationDetails.modifiedLoginToken) {
setLoginToken(impersonationDetails.modifiedLoginToken);
}

if (impersonationDetails.account) {
loginAction({
address: impersonationDetails.address,
providerType: provider.getType()
});

const newAccount: AccountType = {
...impersonationDetails.account,
nonce: getLatestNonce(impersonationDetails.account)
};

setAccount(newAccount);
return {
...impersonationDetails,
account: newAccount
};
}

return impersonationDetails;
}
52 changes: 0 additions & 52 deletions src/core/methods/login/helpers/processModifiedAccount.ts

This file was deleted.

Loading