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

Feat: smart account init #2014

Merged
merged 30 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
2ad3559
feat: add user operation related rpc methods
tomiir Feb 15, 2024
f4b4c7a
chore: add changeset versions for canary
tomiir Feb 15, 2024
2dc4939
chore: manually point to secure site prev
tomiir Feb 16, 2024
ceeff4d
chore: remove preemptive canary tag
tomiir Feb 16, 2024
1aec6bf
fix: rollback type changes
tomiir Feb 16, 2024
3845a99
feat: send usdc button
tomiir Feb 16, 2024
29a3ab9
Merge branch 'V4' into feat/smart-accounts
tomiir Feb 19, 2024
5af5c17
chore: reset secure-site url and vitalik address
tomiir Feb 19, 2024
d974ad5
fix: secure site url
tomiir Feb 20, 2024
8449bed
Merge branch 'V4' of github.com:WalletConnect/web3modal into feat/sma…
tomiir Feb 22, 2024
28876ec
chore: update secure site dev url
tomiir Feb 22, 2024
76ec887
chore: clean lab imports
tomiir Feb 22, 2024
c4bcb7b
fix: secure sdk url
tomiir Feb 22, 2024
605cc5b
feat: add rpc methods for sa enabled networks
tomiir Feb 28, 2024
387aa6a
feat: add initSmartAccount Handler
tomiir Feb 29, 2024
da8a5d0
feat: refactor flow to check for enabled networks and check sa deploy…
tomiir Feb 29, 2024
e8f2d04
feat: add upgrade to smart account screen
tomiir Feb 29, 2024
203dd72
feat: add smart account initialization to ethers
tomiir Feb 29, 2024
16cfe74
chore: refactor for code clarity
tomiir Mar 1, 2024
2cd4846
feat: add set preferred account handlers
tomiir Mar 1, 2024
24583bd
feat: serialize type in response and persist in storage
tomiir Mar 1, 2024
5c921d8
Merge branch 'V4' of github.com:WalletConnect/web3modal into feat/sma…
tomiir Mar 1, 2024
417ed09
chore: reset secure site url
tomiir Mar 1, 2024
796184b
chore: remove core usage on client side
tomiir Mar 1, 2024
0c59f84
chore: remove test logs
tomiir Mar 1, 2024
95b35e1
chore: canary version update
tomiir Mar 4, 2024
9fd8ef1
chore: exit pre mode
tomiir Mar 4, 2024
bd59e51
Merge branch 'V4' of github.com:WalletConnect/web3modal into feat/sma…
tomiir Mar 4, 2024
6d0cab2
feat: added enableSmartAccounts feature flag
tomiir Mar 4, 2024
129eb74
chore: bump version to 4.0.12
tomiir Mar 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions .changeset/pre.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"mode": "pre",
"tag": "2ad35598",
"initialVersions": {
"@apps/gallery": "4.0.5",
"@apps/laboratory": "4.0.5",
"@examples/html-ethers5": "4.0.5",
"@examples/html-wagmi": "4.0.5",
"@examples/next-wagmi": "4.0.5",
"@examples/react-ethers5": "4.0.5",
"@examples/react-wagmi": "4.0.5",
"@examples/vue-ethers5": "4.0.5",
"@examples/vue-wagmi": "4.0.5",
"@web3modal/common": "4.0.5",
"@web3modal/core": "4.0.5",
"@web3modal/ethers": "4.0.5",
"@web3modal/ethers5": "4.0.5",
"@web3modal/polyfills": "4.0.5",
"@web3modal/scaffold": "4.0.5",
"@web3modal/scaffold-react": "4.0.5",
"@web3modal/scaffold-utils": "4.0.5",
"@web3modal/scaffold-vue": "4.0.5",
"@web3modal/siwe": "4.0.5",
"@web3modal/ui": "4.0.5",
"@web3modal/wagmi": "4.0.5",
"@web3modal/wallet": "4.0.5"
},
"changesets": []
}
103 changes: 103 additions & 0 deletions apps/laboratory/src/components/Wagmi/WagmiSendUSDCTest.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import { Button, useToast, Stack, Link, Text, Spacer, Input } from '@chakra-ui/react'
import { useAccount, useWriteContract } from 'wagmi'
import { useCallback, useState } from 'react'
import { sepolia } from 'wagmi/chains'

const minTokenAbi = [
{
inputs: [
{ internalType: 'address', name: 'to', type: 'address' },
{ internalType: 'uint256', name: 'value', type: 'uint256' }
],
name: 'transfer',
outputs: [{ internalType: 'bool', name: '', type: 'bool' }],
stateMutability: 'nonpayable',
type: 'function'
},
{
inputs: [{ internalType: 'address', name: 'account', type: 'address' }],
name: 'balanceOf',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function'
},
{
inputs: [],
name: 'decimals',
outputs: [{ internalType: 'uint8', name: '', type: 'uint8' }],
stateMutability: 'view',
type: 'function'
}
]

export function WagmiSendUSDCTest() {
const [isLoading, setLoading] = useState(false)
const [address, setAddress] = useState('')
const [amount, setAmount] = useState('')
const { status, chain } = useAccount()
const toast = useToast()

const { writeContract } = useWriteContract({
mutation: {
onSuccess: hash => {
setLoading(false)
toast({
title: 'Transaction Success',
description: hash,
status: 'success',
isClosable: true
})
},
onError: () => {
setLoading(false)
toast({
title: 'Error',
description: 'Failed to send transaction',
status: 'error',
isClosable: true
})
}
}
})

const onSendTransaction = useCallback(() => {
setLoading(true)
writeContract({
abi: minTokenAbi,
functionName: 'transfer',
args: [address, amount],
address: '0x1c7d4b196cb0c7b01d743fbc6116a902379c7238'
})
}, [writeContract, address, amount])

return chain?.id === sepolia.id && status === 'connected' ? (
<Stack direction={['column', 'column', 'row']}>
<Button
data-test-id="sign-transaction-button"
onClick={onSendTransaction}
disabled={!writeContract}
isDisabled={isLoading}
>
Send USDC
</Button>

<Spacer />
<Input placeholder="0xf34ffa..." onChange={e => setAddress(e.target.value)} value={address} />
<Input
placeholder="Enter an amount"
onChange={e => setAmount(e.target.value)}
value={amount}
type="number"
/>
<Link isExternal href="https://faucet.circle.com">
<Button variant="outline" colorScheme="blue" isDisabled={isLoading}>
USDC Faucet
</Button>
</Link>
</Stack>
) : (
<Text fontSize="md" color="yellow">
Switch to Sepolia Ethereum Testnet to test this feature
</Text>
)
}
7 changes: 7 additions & 0 deletions apps/laboratory/src/components/Wagmi/WagmiTests.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { WagmiSignMessageTest } from './WagmiSignMessageTest'
import { WagmiSignTypedDataTest } from './WagmiSignTypedDataTest'
import { StackDivider, Card, CardHeader, Heading, CardBody, Box, Stack } from '@chakra-ui/react'
import { WagmiWriteContractTest } from './WagmiWriteContractTest'
import { WagmiSendUSDCTest } from './WagmiSendUSDCTest'

export function WagmiTests() {
return (
Expand Down Expand Up @@ -39,6 +40,12 @@ export function WagmiTests() {
</Heading>
<WagmiWriteContractTest />
</Box>
<Box>
<Heading size="xs" textTransform="uppercase" pb="2">
USDC Send
</Heading>
<WagmiSendUSDCTest />
</Box>
</Stack>
</CardBody>
</Card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { sepolia } from 'wagmi/chains'

const TEST_TX = {
to: vitalikEthAddress as Address,
value: parseGwei('0.0002')
value: parseGwei('0.3')
}
tomiir marked this conversation as resolved.
Show resolved Hide resolved

export function WagmiTransactionTest() {
Expand Down
5 changes: 5 additions & 0 deletions packages/core/src/controllers/AccountController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface AccountControllerState {
profileName?: string | null
profileImage?: string | null
addressExplorerUrl?: string
smartAccountDeployed?: boolean
}

type StateKey = keyof AccountControllerState
Expand Down Expand Up @@ -63,6 +64,10 @@ export const AccountController = {
state.addressExplorerUrl = explorerUrl
},

setSmartAccountDeployed(isDeployed: boolean) {
state.smartAccountDeployed = isDeployed
},

resetAccount() {
state.isConnected = false
state.caipAddress = undefined
Expand Down
1 change: 1 addition & 0 deletions packages/core/src/controllers/RouterController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface RouterControllerState {
| 'UpdateEmailPrimaryOtp'
| 'UpdateEmailSecondaryOtp'
| 'UpgradeEmailWallet'
| 'UpgradeToSmartAccount'
| 'WhatIsANetwork'
| 'WhatIsAWallet'
| 'WhatIsABuy'
Expand Down
26 changes: 25 additions & 1 deletion packages/ethers/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import type { EthereumProviderOptions } from '@walletconnect/ethereum-provider'
import type { Eip1193Provider } from 'ethers'
import { W3mFrameProvider, W3mFrameHelpers } from '@web3modal/wallet'
import type { CombinedProvider } from '@web3modal/scaffold-utils/ethers'
import { AccountController } from '@web3modal/core'

// -- Types ---------------------------------------------------------------------
export interface Web3ModalClientOptions extends Omit<LibraryOptions, 'defaultChain' | 'tokens'> {
Expand Down Expand Up @@ -589,6 +590,22 @@ export class Web3Modal extends Web3ModalScaffold {
}
}

private async initSmartAccount(
chainId: number
): Promise<{ isDeployed: boolean; address?: string }> {
if (!this.emailProvider) {
return { isDeployed: false }
}
const { smartAccountEnabledNetworks } =
await this.emailProvider.getSmartAccountEnabledNetworks()

if (!smartAccountEnabledNetworks.includes(chainId)) {
return { isDeployed: false }
}

return await this.emailProvider.initSmartAccount()
}

private async setEmailProvider() {
window?.localStorage.setItem(EthersConstantsUtil.WALLET_ID, ConstantsUtil.EMAIL_CONNECTOR_ID)

Expand All @@ -600,7 +617,14 @@ export class Web3Modal extends Web3ModalScaffold {
EthersStoreUtil.setProviderType(ConstantsUtil.EMAIL_CONNECTOR_ID as 'w3mEmail')
EthersStoreUtil.setProvider(this.emailProvider as unknown as CombinedProvider)
EthersStoreUtil.setIsConnected(true)
EthersStoreUtil.setAddress(address as Address)
const { isDeployed, address: smartAccountAddress } = await this.initSmartAccount(chainId)
AccountController.setSmartAccountDeployed(isDeployed)
if (isDeployed && smartAccountAddress) {
EthersStoreUtil.setAddress(smartAccountAddress as Address)
} else {
EthersStoreUtil.setAddress(address as Address)
}

this.watchEmail()
this.watchModal()
}
Expand Down
1 change: 1 addition & 0 deletions packages/scaffold/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export * from './src/views/w3m-email-verify-otp-view/index.js'
export * from './src/views/w3m-email-verify-device-view/index.js'
export * from './src/views/w3m-approve-transaction-view/index.js'
export * from './src/views/w3m-upgrade-wallet-view/index.js'
export * from './src/views/w3m-upgrade-to-smart-account-view/index.js'
export * from './src/views/w3m-update-email-wallet-view/index.js'
export * from './src/views/w3m-update-email-primary-otp-view/index.js'
export * from './src/views/w3m-update-email-secondary-otp-view/index.js'
Expand Down
2 changes: 2 additions & 0 deletions packages/scaffold/src/modal/w3m-router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ export class W3mRouter extends LitElement {
return html`<w3m-transactions-view></w3m-transactions-view>`
case 'UpgradeEmailWallet':
return html`<w3m-upgrade-wallet-view></w3m-upgrade-wallet-view>`
case 'UpgradeToSmartAccount':
return html`<w3m-upgrade-to-smart-account-view></w3m-upgrade-to-smart-account-view>`
case 'UpdateEmailWallet':
return html`<w3m-update-email-wallet-view></w3m-update-email-wallet-view>`
case 'UpdateEmailPrimaryOtp':
Expand Down
6 changes: 5 additions & 1 deletion packages/scaffold/src/partials/w3m-header/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ function headings() {
ApproveTransaction: 'Approve Transaction',
Transactions: 'Activity',
UpgradeEmailWallet: 'Upgrade your Wallet',
UpgradeToSmartAccount: undefined,
UpdateEmailWallet: 'Edit Email',
UpdateEmailPrimaryOtp: 'Confirm Current Email',
UpdateEmailSecondaryOtp: 'Confirm New Email',
Expand Down Expand Up @@ -121,8 +122,11 @@ export class W3mHeader extends LitElement {
const { view } = RouterController.state
const isConnectHelp = view === 'Connect'
const isApproveTransaction = view === 'ApproveTransaction'
const isUpgradeToSmartAccounts = view === 'UpgradeToSmartAccount'

if (this.showBack && !isApproveTransaction) {
const shouldHideBack = isApproveTransaction || isUpgradeToSmartAccounts

if (this.showBack && !shouldHideBack) {
return html`<wui-icon-link
id="dynamic"
icon="chevronLeft"
Expand Down
28 changes: 28 additions & 0 deletions packages/scaffold/src/views/w3m-account-view/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export class W3mAccountView extends LitElement {

@state() private balanceSymbol = AccountController.state.balanceSymbol

@state() private smartAccountDeployed = AccountController.state.smartAccountDeployed

public constructor() {
super()
this.unsubscribe.push(
Expand All @@ -52,6 +54,7 @@ export class W3mAccountView extends LitElement {
this.profileName = val.profileName
this.balance = val.balance
this.balanceSymbol = val.balanceSymbol
this.smartAccountDeployed = val.smartAccountDeployed
} else {
ModalController.close()
}
Expand Down Expand Up @@ -118,6 +121,7 @@ export class W3mAccountView extends LitElement {
>
</wui-flex>
${this.explorerBtnTemplate()}
<!-- ${this.upgradeToSmartAccountTemplate()} -->
</wui-flex>

<wui-flex flexDirection="column" gap="xs" .padding=${['0', 's', 's', 's'] as const}>
Expand Down Expand Up @@ -219,6 +223,30 @@ export class W3mAccountView extends LitElement {
`
}

private upgradeToSmartAccountTemplate() {
const type = StorageUtil.getConnectedConnector()
const emailConnector = ConnectorController.getEmailConnector()
if (!emailConnector || type !== 'EMAIL') {
return null
}

if (this.smartAccountDeployed) {
return null
}

return html`
<wui-button
size="sm"
variant="shade"
@click=${() => RouterController.push('UpgradeToSmartAccount')}
>
<wui-icon size="sm" color="inherit" slot="iconLeft" name="compass"></wui-icon>
Activate your smart account
<wui-icon size="sm" color="inherit" slot="iconRight" name="externalLink"></wui-icon>
</wui-button>
`
}

private emailBtnTemplate() {
const type = StorageUtil.getConnectedConnector()
const emailConnector = ConnectorController.getEmailConnector()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { customElement } from '@web3modal/ui'
import { RouterController } from '@web3modal/core'
import { LitElement, html } from 'lit'

@customElement('w3m-upgrade-to-smart-account-view')
export class W3mUpgradeToSmartAccountView extends LitElement {
// -- Render -------------------------------------------- //
public override render() {
return html`
<wui-flex
flexDirection="column"
alignItems="center"
gap="xxl"
.padding=${['0', '0', 'l', '0'] as const}
>
${this.onboardingTemplate()} ${this.buttonsTemplate()}
<wui-link @click=${() => console.log('TODO: link to documentation')}>

Check failure on line 17 in packages/scaffold/src/views/w3m-upgrade-to-smart-account-view/index.ts

View workflow job for this annotation

GitHub Actions / code_style (lint)

Unexpected console statement
Learn more
<wui-icon color="inherit" slot="iconRight" name="externalLink"></wui-icon>
</wui-link>
</wui-flex>
`
}

// -- Private ------------------------------------------- //
private onboardingTemplate() {
return html` <wui-flex
flexDirection="column"
gap="xxl"
alignItems="center"
.padding=${['0', 'xxl', '0', 'xxl'] as const}
>
<wui-flex gap="s" alignItems="center" justifyContent="center">
<wui-visual name="onrampCard"></wui-visual>
<wui-visual name="onrampCard"></wui-visual>
<wui-visual name="onrampCard"></wui-visual>
</wui-flex>
<wui-flex flexDirection="column" alignItems="center" gap="s">
<wui-text align="center" variant="medium-600" color="fg-100">
Discover Smart Accounts
</wui-text>
<wui-text align="center" variant="paragraph-400" color="fg-100">
Access advanced features such as username, social login, improved security and a smoother
user experience!
</wui-text>
</wui-flex>
</wui-flex>`
}

private buttonsTemplate() {
return html`<wui-flex .padding=${['0', '2l', '0', '2l'] as const} gap="s">
<wui-button variant="accentBg" @click=${RouterController.goBack} size="lg" borderRadius="xs">
Do it later
</wui-button>
<wui-button @click=${() => console.log('continue')} size="lg" borderRadius="xs">

Check failure on line 55 in packages/scaffold/src/views/w3m-upgrade-to-smart-account-view/index.ts

View workflow job for this annotation

GitHub Actions / code_style (lint)

Unexpected console statement
Continue
</wui-button>
</wui-flex>`
}
}

declare global {
interface HTMLElementTagNameMap {
'w3m-upgrade-to-smart-account-view': W3mUpgradeToSmartAccountView
}
}
Loading
Loading