diff --git a/packages/billboard-client/src/service/dsManager/steps/getBillboardProfile.ts b/packages/billboard-client/src/service/dsManager/steps/getBillboardProfile.ts index abd04e51e..d2631ff19 100644 --- a/packages/billboard-client/src/service/dsManager/steps/getBillboardProfile.ts +++ b/packages/billboard-client/src/service/dsManager/steps/getBillboardProfile.ts @@ -24,6 +24,7 @@ export async function getBillboardProfile( const wallet = new ethers.Wallet(billboard.privateKey); const storageKeyCreationMessage = getStorageKeyCreationMessage( '0xca8f04fdc80d659997f69b02', + wallet.address, ); const storageKeySig = await wallet.signMessage( storageKeyCreationMessage, diff --git a/packages/billboard-client/test/helper/mockUserProfile.ts b/packages/billboard-client/test/helper/mockUserProfile.ts index df0c195e4..a5c710647 100644 --- a/packages/billboard-client/test/helper/mockUserProfile.ts +++ b/packages/billboard-client/test/helper/mockUserProfile.ts @@ -25,6 +25,7 @@ export const mockUserProfile = async ( }> => { const storageKeyCreationMessage = getStorageKeyCreationMessage( '0xca8f04fdc80d659997f69b02', + wallet.address, ); const storageKeySig = await wallet.signMessage(storageKeyCreationMessage); diff --git a/packages/lib/crypto/src/KeyCreation.ts b/packages/lib/crypto/src/KeyCreation.ts index 7039e2cbd..e9cd35a7b 100644 --- a/packages/lib/crypto/src/KeyCreation.ts +++ b/packages/lib/crypto/src/KeyCreation.ts @@ -25,11 +25,23 @@ export async function createSigningKeyPair(seed?: string): Promise { }; } -export function getStorageKeyCreationMessage(nonce: string) { +export function getStorageKeyCreationMessage(nonce: string, address: string) { + // TODO: during linked profile implementation these values should be fetched from env + const statement = + `Connect the DM3 MESSENGER with your wallet. Sign in with a signature. ` + + `Keys for secure communication are derived from this signature.\n\n` + + `(There is no paid transaction initiated. The signature is used off-chain only.)`; + const domain = 'dm3.chat'; + const uri = 'https://dm3.chat'; + const version = '1'; + return ( - `Connect the dm3 app with your wallet.` + - ` Keys for secure communication are derived from the signature.` + - ` No paid transaction will be executed.\nNonce: ${nonce}` + `${domain} wants you to sign in with your Ethereum account:\n` + + `${ethers.utils.getAddress(address)}\n\n` + + `${statement}\n\n` + + `URI: ${uri}\n` + + `Version: ${version}\n` + + `Nonce: ${nonce}` ); } diff --git a/packages/lib/profile/src/Profile.ts b/packages/lib/profile/src/Profile.ts index 7fc509964..545ab0d68 100644 --- a/packages/lib/profile/src/Profile.ts +++ b/packages/lib/profile/src/Profile.ts @@ -45,11 +45,22 @@ export const PROFILE_RECORD_NAME = 'network.dm3.profile'; * signs a profile with an ethereum account key * @param stringifiedProfile stringified dm3 user profile object */ -export function getProfileCreationMessage(stringifiedProfile: string) { +export function getProfileCreationMessage( + stringifiedProfile: string, + address: string, +) { + const domain = 'dm3.chat'; + const uri = 'https://dm3.chat'; + const version = '1'; + return ( - `Please sign this message to link your dm3 profile with your Wallet. ` + - `(This signature will not trigger any transaction or cost gas fees.) ` + - `Your dm3 profile:\n\n${stringifiedProfile}` + `${domain} wants you register your dm3 account with your Ethereum account:\n` + + `${ethers.utils.getAddress(address)}\n\n` + + `Register your dm3 profile. This is required only once!\n` + + `(There is no paid transaction initiated. The signature is used off-chain only.)\n\n` + + `URI: ${uri}\n` + + `Version: ${version}\n` + + `dm3 Profile: ${stringifiedProfile}` ); } @@ -116,6 +127,7 @@ export function checkUserProfileWithAddress( ): boolean { const createUserProfileMessage = getProfileCreationMessage( stringify(profile), + accountAddress, ); return ( @@ -192,12 +204,15 @@ export function isSameEnsName( async function createKeyPairsFromSig( sign: (msg: string) => Promise, - + address: string, nonce: string, storageKey?: string, ): Promise { if (!storageKey) { - const storageKeyCreationMessage = getStorageKeyCreationMessage(nonce); + const storageKeyCreationMessage = getStorageKeyCreationMessage( + nonce, + address, + ); const signature = await sign(storageKeyCreationMessage); const newStorageKey = await createStorageKey(signature); @@ -235,6 +250,7 @@ export async function createProfile( const keys = await createKeyPairsFromSig( (msg: string) => signer(msg, accountAddress), + accountAddress, nonce, storageKey, ); @@ -247,6 +263,7 @@ export async function createProfile( const profileCreationMessage = getProfileCreationMessage( stringify(profile), + accountAddress, ); const profileSig = await signer(profileCreationMessage, accountAddress); return { diff --git a/packages/messenger-widget/src/components/SignIn/bl.tsx b/packages/messenger-widget/src/components/SignIn/bl.tsx index 22fb9f8cb..1662f7dbc 100644 --- a/packages/messenger-widget/src/components/SignIn/bl.tsx +++ b/packages/messenger-widget/src/components/SignIn/bl.tsx @@ -98,8 +98,8 @@ export const checkState = async ( const browserDataFile = state.connection.account && state.uiState.browserStorageBackup ? await localforage.getItem( - getBrowserStorageKey(state.connection.account.ensName), - ) + getBrowserStorageKey(state.connection.account.ensName), + ) : null; const isCollectingSignInData = @@ -171,7 +171,10 @@ export async function createKeyPairsFromSignature( throw Error('No eth address'); } - const storageKeyCreationMessage = getStorageKeyCreationMessage(nonce); + const storageKeyCreationMessage = getStorageKeyCreationMessage( + nonce, + ethAddress, + ); const signature = await personalSign( provider, @@ -347,7 +350,7 @@ export async function signProfile( ): Promise { try { const profileCreationMessage = - getProfileCreationMessage(stringifiedProfile); + getProfileCreationMessage(stringifiedProfile, address); return await personalSign(provider, address, profileCreationMessage); } catch (error: any) { const err = error?.message.split(':'); @@ -481,12 +484,12 @@ export async function getDatabase( }> { return profileExists ? getExistingDatebase( - storageLocation, - storageToken, - state, - dispatch, - setSignInBtnContent, - ) + storageLocation, + storageToken, + state, + dispatch, + setSignInBtnContent, + ) : createNewDatabase(state, setSignInBtnContent); } @@ -814,16 +817,16 @@ export async function getWeb3Provider(provider: unknown): Promise<{ }> { return provider ? { - provider: new ethers.providers.Web3Provider( - provider as - | ethers.providers.ExternalProvider - | ethers.providers.JsonRpcFetchFunc, - ), - connectionState: ConnectionState.AccountConnectReady, - } + provider: new ethers.providers.Web3Provider( + provider as + | ethers.providers.ExternalProvider + | ethers.providers.JsonRpcFetchFunc, + ), + connectionState: ConnectionState.AccountConnectReady, + } : { - connectionState: ConnectionState.ConnectionRejected, - }; + connectionState: ConnectionState.ConnectionRejected, + }; } function handleNewProvider( diff --git a/packages/react/src/session/SignIn/signProfile.ts b/packages/react/src/session/SignIn/signProfile.ts index f725090c4..57b34ade2 100644 --- a/packages/react/src/session/SignIn/signProfile.ts +++ b/packages/react/src/session/SignIn/signProfile.ts @@ -9,8 +9,10 @@ export async function signProfile( stringifiedProfile: string, ): Promise { try { - const profileCreationMessage = - getProfileCreationMessage(stringifiedProfile); + const profileCreationMessage = getProfileCreationMessage( + stringifiedProfile, + address, + ); return await personalSign(provider, address, profileCreationMessage); } catch (e) { throw Error("Can't signIn profile"); diff --git a/packages/react/src/session/SignIn/signProfileKeyPair.ts b/packages/react/src/session/SignIn/signProfileKeyPair.ts index bca870f6d..3353f7619 100644 --- a/packages/react/src/session/SignIn/signProfileKeyPair.ts +++ b/packages/react/src/session/SignIn/signProfileKeyPair.ts @@ -18,7 +18,10 @@ export async function createKeyPairsFromSig( throw Error('No eth address'); } - const storageKeyCreationMessage = getStorageKeyCreationMessage(nonce); + const storageKeyCreationMessage = getStorageKeyCreationMessage( + nonce, + ethAddress, + ); const signature = await personalSign( provider,