Skip to content

Commit

Permalink
CrossWindow login (#13)
Browse files Browse the repository at this point in the history
* wip crosswindow provider login

* implement login with crosswindow provider, fix network config initialization and relogin

* apply specific condition for crosswindow at the generic login

* add todos

* revert minification changes

* fix todo

* todo fix

* changelog update

* rebasing on top of development branch

* cleanup

* upgrade sdk=dapp-utils and cross-window-provider

* 0.0.0-alpha.9
  • Loading branch information
CiprianDraghici authored Aug 29, 2024
1 parent a2aaf05 commit c912e08
Show file tree
Hide file tree
Showing 42 changed files with 354 additions and 493 deletions.
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
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@multiversx/sdk-dapp-core",
"version": "0.0.0-alpha.7",
"version": "0.0.0-alpha.9",
"main": "out/index.js",
"module": "out/index.js",
"types": "out/index.d.ts",
Expand Down 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
File renamed without changes.
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

0 comments on commit c912e08

Please sign in to comment.