Skip to content

Commit

Permalink
:feat social login - 4- Views (#2275)
Browse files Browse the repository at this point in the history
  • Loading branch information
svenvoskamp authored May 17, 2024
1 parent 7904ba4 commit 93c66a3
Show file tree
Hide file tree
Showing 52 changed files with 1,487 additions and 306 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/ui_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ on:
required: false
TESTS_MAILSEC_API_KEY:
required: false
TESTS_SOCIAL_EMAIL:
required: false
TESTS_SOCIAL_PASSWORD:
required: false

jobs:
ui_tests:
Expand Down Expand Up @@ -81,6 +85,8 @@ jobs:
NEXTAUTH_SECRET: ${{ secrets.TESTS_NEXTAUTH_SECRET }}
MAILSAC_API_KEY: ${{ secrets.TESTS_MAILSEC_API_KEY }}
NEXT_PUBLIC_SECURE_SITE_SDK_URL: ${{ inputs.secure-site-url }}
SOCIAL_TEST_EMAIL: ${{ secrets.TESTS_SOCIAL_EMAIL }}
SOCIAL_TEST_PASSWORD: ${{ secrets.TESTS_SOCIAL_PASSWORD }}
- name: Install Playwright Browsers
if: steps.playwright-cache.outputs.cache-hit != 'true'
working-directory: ./apps/laboratory/
Expand All @@ -94,6 +100,8 @@ jobs:
NEXTAUTH_SECRET: ${{ secrets.TESTS_NEXTAUTH_SECRET }}
MAILSAC_API_KEY: ${{ secrets.TESTS_MAILSEC_API_KEY }}
NEXT_PUBLIC_SECURE_SITE_SDK_URL: ${{ inputs.secure-site-url }}
SOCIAL_TEST_EMAIL: ${{ secrets.TESTS_SOCIAL_EMAIL }}
SOCIAL_TEST_PASSWORD: ${{ secrets.TESTS_SOCIAL_PASSWORD }}
CI: true
working-directory: ./apps/laboratory/
run: npm run ${{ inputs.command }}
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ screenshots/
coverage
test-results
.vscode/*
apps/laboratory/playwright/.auth/user.json
2 changes: 2 additions & 0 deletions apps/laboratory/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,5 @@ MAILSAC_API_KEY=""
# Only needed when overriding default next-auth URL
# NEXTAUTH_URL=""
NEXT_PUBLIC_SECURE_SITE_SDK_URL=""
SOCIAL_TEST_EMAIL=""
SOCIAL_TEST_PASSWORD=""
2 changes: 2 additions & 0 deletions apps/laboratory/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
"playwright:test": "playwright test",
"playwright:test:wallet": "playwright test --grep 'connect-qr.spec.ts|wallet.spec.ts'",
"playwright:test:email": "playwright test --grep 'email.spec.ts'",
"playwright:test:social": "playwright test --grep 'social.spec.ts'",
"playwright:test:siwe": "playwright test --grep siwe.spec.ts",
"playwright:test:siwe-email": "playwright test --grep siwe-email.spec.ts",
"playwright:test:siwe-sa": "playwright test --grep siwe-smart-account.spec.ts",
Expand All @@ -20,6 +21,7 @@
"playwright:debug": "npm run playwright:test -- --debug",
"playwright:debug:wallet": "npm run playwright:test:wallet -- --debug",
"playwright:debug:email": "npm run playwright:test:email -- --debug",
"playwright:debug:social": "npm run playwright:test:social -- --debug",
"playwright:debug:siwe": "npm run playwright:test:siwe -- --debug",
"playwright:debug:siwe-email": "npm run playwright:test:siwe-email -- --debug",
"playwright:debug:siwe-sa": "npm run playwright:test:siwe-smart-account -- --debug",
Expand Down
5 changes: 4 additions & 1 deletion apps/laboratory/src/pages/library/ethers-email.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ const modal = createWeb3Modal({
metadata: ConstantsUtil.Metadata,
defaultChainId: 1,
rpcUrl: 'https://cloudflare-eth.com',
enableEmail: true
enableEmail: true,
auth: {
socials: ['google', 'x', 'discord', 'apple', 'github']
}
}),
chains: EthersConstants.chains,
projectId: ConstantsUtil.ProjectId,
Expand Down
5 changes: 4 additions & 1 deletion apps/laboratory/src/pages/library/ethers-wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ const modal = createWeb3Modal({
metadata: ConstantsUtil.Metadata,
defaultChainId: 1,
rpcUrl: 'https://cloudflare-eth.com',
enableEmail: true
enableEmail: true,
auth: {
socials: ['google', 'x', 'discord', 'apple', 'github']
}
}),
chains: EthersConstants.chains,
projectId: ConstantsUtil.ProjectId,
Expand Down
3 changes: 3 additions & 0 deletions apps/laboratory/src/pages/library/wagmi-email.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ export const wagmiConfig = defaultWagmiConfig({
projectId: ConstantsUtil.ProjectId,
metadata: ConstantsUtil.Metadata,
enableEmail: true,
auth: {
socials: ['google', 'x', 'discord', 'apple', 'github']
},
ssr: true
})

Expand Down
5 changes: 4 additions & 1 deletion apps/laboratory/src/pages/library/wagmi-wallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@ export const wagmiConfig = defaultWagmiConfig({
projectId: ConstantsUtil.ProjectId,
metadata: ConstantsUtil.Metadata,
enableEmail: true,
ssr: true
ssr: true,
auth: {
socials: ['google', 'x', 'discord', 'apple', 'github']
}
})

const modal = createWeb3Modal({
Expand Down
4 changes: 2 additions & 2 deletions apps/laboratory/src/utils/DataUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const wagmiSdkOptions = [
{
title: 'Wallet',
link: '/library/wagmi-wallet/',
description: 'Configuration using wagmi and implementing email wallet'
description: 'Configuration using wagmi and implementing social wallet'
}
]

Expand All @@ -60,7 +60,7 @@ export const ethersSdkOptions = [
{
title: 'Wallet',
link: '/library/ethers-wallet/',
description: 'Configuration using ethers and implementing email wallet'
description: 'Configuration using ethers and implementing social wallet'
}
]

Expand Down
28 changes: 28 additions & 0 deletions apps/laboratory/tests/shared/fixtures/w3m-social-fixture.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { ModalFixture } from './w3m-fixture'
import { ModalPage } from '../pages/ModalPage'
import { ModalValidator } from '../validators/ModalValidator'
import { timingFixture } from './timing-fixture'

export const testMSocial = timingFixture.extend<ModalFixture>({
library: ['wagmi', { option: true }],
modalPage: async ({ page, library }, use) => {
const modalPage = new ModalPage(page, library, 'email')
await modalPage.load()

const socialMail = process.env['SOCIAL_TEST_EMAIL']
if (!socialMail) {
throw new Error('SOCIAL_TEST_MAIL is not set')
}
const socialPass = process.env['SOCIAL_TEST_PASSWORD']
if (!socialPass) {
throw new Error('SOCIAL_TEST_PASSWORD is not set')
}

await modalPage.loginWithSocial(socialMail, socialPass)
await use(modalPage)
},
modalValidator: async ({ modalPage }, use) => {
const modalValidator = new ModalValidator(modalPage.page)
await use(modalValidator)
}
})
18 changes: 18 additions & 0 deletions apps/laboratory/tests/shared/pages/ModalPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,23 @@ export class ModalPage {
})
}

async loginWithSocial(socialMail: string, socialPass: string) {
const authFile = 'playwright/.auth/user.json'
await this.page
.getByTestId('connect-button')
.getByRole('button', { name: 'Connect Wallet' })
.click()
const discordPopupPromise = this.page.waitForEvent('popup')
await this.page.getByTestId('social-selector-discord').click()
const discordPopup = await discordPopupPromise
await discordPopup.fill('#uid_8', socialMail)
await discordPopup.fill('#uid_10', socialPass)
await discordPopup.locator('[type=submit]').click()
await discordPopup.locator('.footer_b96583 button:nth-child(2)').click()
await discordPopup.context().storageState({ path: authFile })
await discordPopup.waitForEvent('close')
}

async enterOTP(otp: string, headerTitle = 'Confirm Email') {
await expect(this.page.getByText(headerTitle)).toBeVisible({
timeout: 10_000
Expand Down Expand Up @@ -184,6 +201,7 @@ export class ModalPage {
})
await this.page.waitForTimeout(2000)
}

async clickSignatureRequestButton(name: string) {
await this.page.frameLocator('#w3m-iframe').getByRole('button', { name, exact: true }).click()
}
Expand Down
27 changes: 17 additions & 10 deletions apps/laboratory/tests/shared/utils/project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,36 +35,42 @@ const braveOptions: UseOptions = {
}

const customProjectProperties: CustomProjectProperties = {
'Desktop Chrome/ethers': {
testIgnore: /(?:social\.spec\.ts).*$/u
},
'Desktop Brave/ethers': {
testIgnore: /(?:email\.spec\.ts|smart-account\.spec\.ts).*$/u,
testIgnore: /(?:email\.spec\.ts|smart-account\.spec\.ts|social\.spec\.ts).*$/u,
useOptions: braveOptions
},
'Desktop Firefox/ethers': {
testIgnore: /(?:social\.spec\.ts).*$/u
},
'Desktop Brave/wagmi': {
testIgnore:
/(?:email\.spec\.ts|smart-account\.spec\.ts|siwe-email\.spec\.ts|siwe-smart-account\.spec\.ts).*$/u,
/(?:email\.spec\.ts|smart-account\.spec\.ts|siwe-email\.spec\.ts|siwe-smart-account\.spec\.ts|social\.spec\.ts).*$/u,
useOptions: braveOptions
},
'Desktop Chrome/wagmi': {
testIgnore:
/(?:email\.spec\.ts|smart-account\.spec\.ts|siwe-email\.spec\.ts|siwe-smart-account\.spec\.ts).*$/u
/(?:email\.spec\.ts|smart-account\.spec\.ts|siwe-email\.spec\.ts|siwe-smart-account\.spec\.ts|social\.spec\.ts).*$/u
},
'Desktop Firefox/wagmi': {
testIgnore:
/(?:email\.spec\.ts|smart-account\.spec\.ts|siwe-email\.spec\.ts|siwe-smart-account\.spec\.ts).*$/u
/(?:email\.spec\.ts|smart-account\.spec\.ts|siwe-email\.spec\.ts|siwe-smart-account\.spec\.ts|social\.spec\.ts).*$/u
},
// Exclude email.spec.ts, siwe.spec.ts, and canary.spec.ts from solana, not yet implemented
// Exclude social.spec.ts, email.spec.ts, siwe.spec.ts, and canary.spec.ts from solana, not yet implemented
'Desktop Chrome/solana': {
grep: /^(?!.*(?:email\.spec\.ts|siwe\.spec\.ts|canary\.spec\.ts|smart-account\.spec\.ts)).*$/u
grep: /^(?!.*(?:email\.spec\.ts|siwe\.spec\.ts|canary\.spec\.ts|smart-account\.spec\.ts|social\.spec\.ts)).*$/u
},
'Desktop Brave/solana': {
useOptions: braveOptions,
grep: /^(?!.*(?:email\.spec\.ts|siwe\.spec\.ts|canary\.spec\.ts|smart-account\.spec\.ts)).*$/u
grep: /^(?!.*(?:email\.spec\.ts|siwe\.spec\.ts|canary\.spec\.ts|smart-account\.spec\.ts|social\.spec\.ts)).*$/u
},
'Desktop Firefox/solana': {
grep: /^(?!.*(?:email\.spec\.ts|siwe\.spec\.ts|canary\.spec\.ts|smart-account\.spec\.ts)).*$/u
grep: /^(?!.*(?:email\.spec\.ts|siwe\.spec\.ts|canary\.spec\.ts|smart-account\.spec\.ts|social\.spec\.ts)).*$/u
},
'Desktop Safari/solana': {
grep: /^(?!.*(?:email\.spec\.ts|siwe\.spec\.ts|canary\.spec\.ts|smart-account\.spec\.ts)).*$/u
grep: /^(?!.*(?:email\.spec\.ts|siwe\.spec\.ts|canary\.spec\.ts|smart-account\.spec\.ts|social\.spec\.ts)).*$/u
}
}

Expand All @@ -78,7 +84,8 @@ export function getProjects() {
const deviceName = device === 'Desktop Brave' ? 'Desktop Chrome' : device
let project = {
name: `${device}/${library}`,
use: { ...devices[deviceName], library }
use: { ...devices[deviceName], library },
storageState: 'playwright/.auth/user.json'
}
const props = customProjectProperties[project.name]
if (props) {
Expand Down
40 changes: 40 additions & 0 deletions apps/laboratory/tests/social.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { testMSocial } from './shared/fixtures/w3m-social-fixture'

testMSocial.beforeEach(async ({ modalValidator }) => {
await modalValidator.expectConnected()
})

testMSocial('it should sign', async ({ modalPage, modalValidator }) => {
await modalPage.sign()
await modalPage.approveSign()
await modalValidator.expectAcceptedSign()
})

testMSocial('it should reject sign', async ({ modalPage, modalValidator }) => {
await modalPage.sign()
await modalPage.rejectSign()
await modalValidator.expectRejectedSign()
})

testMSocial('it should switch network and sign', async ({ modalPage, modalValidator }) => {
let targetChain = 'Polygon'
await modalPage.switchNetwork(targetChain)
await modalValidator.expectSwitchedNetwork(targetChain)
await modalPage.closeModal()
await modalPage.sign()
await modalPage.approveSign()
await modalValidator.expectAcceptedSign()

targetChain = 'Ethereum'
await modalPage.switchNetwork(targetChain)
await modalValidator.expectSwitchedNetwork(targetChain)
await modalPage.closeModal()
await modalPage.sign()
await modalPage.approveSign()
await modalValidator.expectAcceptedSign()
})

testMSocial('it should disconnect correctly', async ({ modalPage, modalValidator }) => {
await modalPage.disconnect()
await modalValidator.expectDisconnected()
})
10 changes: 9 additions & 1 deletion packages/core/src/controllers/AccountController.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { subscribeKey as subKey } from 'valtio/vanilla/utils'
import { proxy, ref, subscribe as sub } from 'valtio/vanilla'
import { CoreHelperUtil } from '../utils/CoreHelperUtil.js'
import type { CaipAddress, ConnectedWalletInfo } from '../utils/TypeUtil.js'
import type { CaipAddress, ConnectedWalletInfo, SocialProvider } from '../utils/TypeUtil.js'
import type { Balance } from '@web3modal/common'
import { BlockchainApiController } from './BlockchainApiController.js'
import { SnackController } from './SnackController.js'
Expand All @@ -22,6 +22,7 @@ export interface AccountControllerState {
profileImage?: string | null
addressExplorerUrl?: string
smartAccountDeployed?: boolean
socialProvider?: SocialProvider
tokenBalance?: Balance[]
connectedWalletInfo?: ConnectedWalletInfo
preferredAccountType?: W3mFrameTypes.AccountType
Expand Down Expand Up @@ -100,6 +101,12 @@ export const AccountController = {
state.preferredAccountType = preferredAccountType
},

setSocialProvider(socialProvider: AccountControllerState['socialProvider']) {
if (socialProvider) {
state.socialProvider = socialProvider
}
},

async fetchTokenBalance() {
const chainId = NetworkController.state.caipNetwork?.id

Expand Down Expand Up @@ -129,5 +136,6 @@ export const AccountController = {
state.tokenBalance = []
state.connectedWalletInfo = undefined
state.preferredAccountType = undefined
state.socialProvider = undefined
}
}
3 changes: 3 additions & 0 deletions packages/core/src/controllers/RouterController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ export interface RouterControllerState {
| 'ConnectingExternal'
| 'ConnectingWalletConnect'
| 'ConnectingSiwe'
| 'ConnectingSocial'
| 'ConnectSocials'
| 'ConnectWallets'
| 'Downloads'
| 'EmailVerifyOtp'
| 'EmailVerifyDevice'
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/utils/TypeUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export type Connector = {
provider?: unknown
email?: boolean
socials?: SocialProvider[]
showWallets?: boolean
}

export interface AuthConnector extends Connector {
Expand Down
3 changes: 2 additions & 1 deletion packages/ethers/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1360,7 +1360,8 @@ export class Web3Modal extends Web3ModalScaffold {
name: 'Auth',
provider: this.authProvider,
email,
socials: auth?.socials
socials: auth?.socials,
showWallets: auth?.showWallets === undefined ? true : auth.showWallets
})

super.setLoading(true)
Expand Down
1 change: 1 addition & 0 deletions packages/ethers/src/utils/defaultConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ConfigOptions {
enableEmail?: boolean
auth?: {
socials?: SocialProvider[]
showWallets?: boolean
}
enableInjected?: boolean
rpcUrl?: string
Expand Down
1 change: 1 addition & 0 deletions packages/scaffold-utils/src/EthersTypesUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type ProviderType = {
email?: boolean
auth?: {
socials?: SocialProvider[]
showWallets?: boolean
}
EIP6963?: boolean
metadata: Metadata
Expand Down
15 changes: 15 additions & 0 deletions packages/scaffold/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export * from './src/views/w3m-wallet-compatible-networks-view/index.js'
export * from './src/views/w3m-wallet-send-view/index.js'
export * from './src/views/w3m-wallet-send-select-token-view/index.js'
export * from './src/views/w3m-wallet-send-preview-view/index.js'
export * from './src/views/w3m-connect-wallets-view/index.js'
export * from './src/views/w3m-connect-socials-view/index.js'
export * from './src/views/w3m-connecting-social-view/index.js'

export * from './src/partials/w3m-all-wallets-list/index.js'
export * from './src/partials/w3m-all-wallets-search/index.js'
Expand Down Expand Up @@ -75,6 +78,18 @@ export * from './src/partials/w3m-input-address/index.js'
export * from './src/partials/w3m-wallet-send-details/index.js'
export * from './src/partials/w3m-tooltip/index.js'
export * from './src/partials/w3m-tooltip-trigger/index.js'
export * from './src/partials/w3m-social-login-widget/index.js'
export * from './src/partials/w3m-wallet-login-list/index.js'
export * from './src/partials/w3m-social-login-list/index.js'
export * from './src/partials/w3m-connect-announced-widget/index.js'
export * from './src/partials/w3m-connect-custom-widget/index.js'
export * from './src/partials/w3m-connect-external-widget/index.js'
export * from './src/partials/w3m-connect-featured-widget/index.js'
export * from './src/partials/w3m-connect-injected-widget/index.js'
export * from './src/partials/w3m-connect-recent-widget/index.js'
export * from './src/partials/w3m-connect-recommended-widget/index.js'
export * from './src/partials/w3m-connect-walletconnect-widget/index.js'
export * from './src/partials/w3m-all-wallets-widget/index.js'

export { Web3ModalScaffold } from './src/client.js'
export type { LibraryOptions, ScaffoldOptions } from './src/client.js'
Expand Down
Loading

0 comments on commit 93c66a3

Please sign in to comment.