Skip to content

Commit

Permalink
:feat add send wallet feature (#2038)
Browse files Browse the repository at this point in the history
  • Loading branch information
svenvoskamp authored Mar 14, 2024
1 parent b9f54cb commit 5f44461
Show file tree
Hide file tree
Showing 43 changed files with 1,484 additions and 10 deletions.
2 changes: 1 addition & 1 deletion apps/gallery/stories/composites/wui-button.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default {
},
argTypes: {
size: {
options: ['sm', 'md'],
options: ['sm', 'md', 'lg'],
control: { type: 'select' }
},
variant: {
Expand Down
28 changes: 28 additions & 0 deletions apps/gallery/stories/composites/wui-input-amount.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import type { Meta } from '@storybook/web-components'
import '@web3modal/ui/src/composites/wui-input-amount'
import type { WuiInputAmount } from '@web3modal/ui/src/composites/wui-input-amount'
import { html } from 'lit'
import '../../components/gallery-container'

type Component = Meta<WuiInputAmount>

export default {
title: 'Composites/wui-input-amount',
args: {
disabled: false,
placeholder: '0'
},
argTypes: {
disabled: {
control: { type: 'boolean' }
}
}
} as Component

export const Default: Component = {
render: args =>
html` <wui-input-amount
placeholder=${args.placeholder}
?disabled=${args.disabled}
></wui-input-amount>`
}
34 changes: 34 additions & 0 deletions apps/gallery/stories/composites/wui-preview-item.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import type { Meta } from '@storybook/web-components'
import '@web3modal/ui/src/composites/wui-preview-item'
import type { WuiPreviewItem } from '@web3modal/ui/src/composites/wui-preview-item'
import { html } from 'lit'
import { address, networkImageSrc } from '../../utils/PresetUtils'

type Component = Meta<WuiPreviewItem>

export default {
title: 'Composites/wui-preview-item',
args: {
imageSrc: networkImageSrc,
address,
text: '0.2 ETH',
isAddress: false
},
argTypes: {
isAddress: {
control: { type: 'boolean' }
}
}
} as Component

export const Default: Component = {
render: args => html`
<wui-preview-item
text=${args.text}
?isAddress=${args.isAddress}
.address=${args.address}
.imageSrc=${args.imageSrc}
>
</wui-preview-item>
`
}
9 changes: 7 additions & 2 deletions apps/gallery/stories/composites/wui-tag.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,21 @@ type Component = Meta<WuiTag>
export default {
title: 'Composites/wui-tag',
args: {
variant: 'main'
variant: 'main',
size: 'lg'
},
argTypes: {
variant: {
options: tagOptions,
control: { type: 'select' }
},
size: {
options: ['lg', 'md'],
control: { type: 'select' }
}
}
} as Component

export const Default: Component = {
render: args => html`<wui-tag variant=${args.variant}>Recent</wui-tag>`
render: args => html`<wui-tag size=${args.size} variant=${args.variant}>Recent</wui-tag>`
}
20 changes: 20 additions & 0 deletions apps/gallery/stories/composites/wui-token-button.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import type { Meta } from '@storybook/web-components'
import '@web3modal/ui/src/composites/wui-token-button'
import type { WuiTokenButton } from '@web3modal/ui/src/composites/wui-token-button'
import { html } from 'lit'
import { networkImageSrc } from '../../utils/PresetUtils'

type Component = Meta<WuiTokenButton>

export default {
title: 'Composites/wui-token-button',
args: {
text: 'ETH',
imageSrc: networkImageSrc
}
} as Component

export const Default: Component = {
render: args =>
html`<wui-token-button text=${args.text} .imageSrc=${args.imageSrc}>Recent</wui-token-button>`
}
2 changes: 2 additions & 0 deletions apps/gallery/utils/PresetUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export const colorOptions: ColorType[] = [
'accent-100',
'error-100',
'fg-100',
'fg-150',
'fg-200',
'fg-300',
'inherit',
Expand All @@ -49,6 +50,7 @@ export const textOptions: TextType[] = [
'tiny-600',
'small-500',
'small-600',
'medium-400',
'paragraph-400',
'paragraph-500',
'paragraph-600',
Expand Down
3 changes: 3 additions & 0 deletions packages/core/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ export type { EventsControllerState } from './src/controllers/EventsController.j
export { TransactionsController } from './src/controllers/TransactionsController.js'
export type { TransactionsControllerState } from './src/controllers/TransactionsController.js'

export { SendController } from './src/controllers/SendController.js'
export type { SendControllerState } from './src/controllers/SendController.js'

// -- Utils -------------------------------------------------------------------
export { AssetUtil } from './src/utils/AssetUtil.js'
export { ConstantsUtil } from './src/utils/ConstantsUtil.js'
Expand Down
5 changes: 4 additions & 1 deletion packages/core/src/controllers/RouterController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ export interface RouterControllerState {
| 'OnRampFiatSelect'
| 'OnRampProviders'
| 'OnRampTokenSelect'
| 'WalletReceive'
| 'SwitchNetwork'
| 'Transactions'
| 'UnsupportedChain'
Expand All @@ -33,6 +32,10 @@ export interface RouterControllerState {
| 'UpdateEmailSecondaryOtp'
| 'UpgradeEmailWallet'
| 'UpgradeToSmartAccount'
| 'WalletReceive'
| 'WalletSend'
| 'WalletSendPreview'
| 'WalletSendSelectToken'
| 'WhatIsANetwork'
| 'WhatIsAWallet'
| 'WhatIsABuy'
Expand Down
62 changes: 62 additions & 0 deletions packages/core/src/controllers/SendController.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { subscribeKey as subKey } from 'valtio/utils'
import { proxy, ref, subscribe as sub } from 'valtio/vanilla'
import type { Balance } from '@web3modal/common'

// -- Types --------------------------------------------- //
export interface SendControllerState {
token?: Balance
sendTokenAmount?: number
receiverAddress?: string
receiverProfileName?: string
receiverProfileImageUrl?: string
}

type StateKey = keyof SendControllerState

// -- State --------------------------------------------- //
const state = proxy<SendControllerState>({})

// -- Controller ---------------------------------------- //
export const SendController = {
state,

subscribe(callback: (newState: SendControllerState) => void) {
return sub(state, () => callback(state))
},

subscribeKey<K extends StateKey>(key: K, callback: (value: SendControllerState[K]) => void) {
return subKey(state, key, callback)
},

setToken(token: SendControllerState['token']) {
if (token) {
state.token = ref(token)
}
},

setTokenAmount(sendTokenAmount: SendControllerState['sendTokenAmount']) {
state.sendTokenAmount = sendTokenAmount
},

setReceiverAddress(receiverAddress: SendControllerState['receiverAddress']) {
state.receiverAddress = receiverAddress
},

setReceiverProfileImageUrl(
receiverProfileImageUrl: SendControllerState['receiverProfileImageUrl']
) {
state.receiverProfileImageUrl = receiverProfileImageUrl
},

setReceiverProfileName(receiverProfileName: SendControllerState['receiverProfileName']) {
state.receiverProfileName = receiverProfileName
},

resetSend() {
state.token = undefined
state.sendTokenAmount = undefined
state.receiverAddress = undefined
state.receiverProfileImageUrl = undefined
state.receiverProfileName = undefined
}
}
9 changes: 9 additions & 0 deletions packages/core/src/utils/CoreHelperUtil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -257,5 +257,14 @@ export const CoreHelperUtil = {
const [dollars, pennies] = roundedNumber.split('.')

return { dollars, pennies }
},
isAddress(address: string): boolean {
if (!/^(?:0x)?[0-9a-f]{40}$/iu.test(address)) {
return false
} else if (/^(?:0x)?[0-9a-f]{40}$/iu.test(address) || /^(?:0x)?[0-9A-F]{40}$/iu.test(address)) {
return true
}

return false
}
}
57 changes: 57 additions & 0 deletions packages/core/tests/controllers/SendController.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { describe, expect, it } from 'vitest'
import { SendController } from '../../index.js'

// -- Setup --------------------------------------------------------------------
const token = {
name: 'Optimism',
symbol: 'OP',
chainId: 'eip155:10',
value: 6.05441523113072,
price: 4.5340112,
quantity: {
decimals: '18',
numeric: '1.335333100000000000'
},
iconUrl: 'https://token-icons.s3.amazonaws.com/0x4200000000000000000000000000000000000042.png'
}
const sendTokenAmount = 0.1
const receiverAddress = '0xd8da6bf26964af9d7eed9e03e53415d37aa96045'
const receiverProfileName = 'john.eth'
const receiverProfileImageUrl = 'https://ipfs.com/0x123.png'

// -- Tests --------------------------------------------------------------------
describe('SendController', () => {
it('should have valid default state', () => {
expect(SendController.state).toEqual({})
})

it('should update state correctly on setToken()', () => {
SendController.setToken(token)
expect(SendController.state.token).toEqual(token)
})

it('should update state correctly on setTokenAmount()', () => {
SendController.setTokenAmount(sendTokenAmount)
expect(SendController.state.sendTokenAmount).toEqual(sendTokenAmount)
})

it('should update state correctly on receiverAddress()', () => {
SendController.setReceiverAddress(receiverAddress)
expect(SendController.state.receiverAddress).toEqual(receiverAddress)
})

it('should update state correctly on receiverProfileName()', () => {
SendController.setReceiverProfileName(receiverProfileName)
expect(SendController.state.receiverProfileName).toEqual(receiverProfileName)
})

it('should update state correctly on receiverProfileName()', () => {
SendController.setReceiverProfileImageUrl(receiverProfileImageUrl)
expect(SendController.state.receiverProfileImageUrl).toEqual(receiverProfileImageUrl)
})

it('should update state correctly on resetSend()', () => {
SendController.resetSend()
expect(SendController.state).toEqual({})
})
})
6 changes: 6 additions & 0 deletions packages/scaffold/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ export * from './src/views/w3m-update-email-secondary-otp-view/index.js'
export * from './src/views/w3m-unsupported-chain-view/index.js'
export * from './src/views/w3m-wallet-receive-view/index.js'
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/partials/w3m-all-wallets-list/index.js'
export * from './src/partials/w3m-all-wallets-search/index.js'
Expand All @@ -60,6 +63,9 @@ export * from './src/partials/w3m-account-activity-widget/index.js'
export * from './src/partials/w3m-account-nfts-widget/index.js'
export * from './src/partials/w3m-account-tokens-widget/index.js'
export * from './src/partials/w3m-activity-list/index.js'
export * from './src/partials/w3m-input-token/index.js'
export * from './src/partials/w3m-input-address/index.js'
export * from './src/partials/w3m-wallet-send-details/index.js'

export { Web3ModalScaffold } from './src/client.js'
export type { LibraryOptions, ScaffoldOptions } from './src/client.js'
Expand Down
6 changes: 6 additions & 0 deletions packages/scaffold/src/modal/w3m-router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,12 @@ export class W3mRouter extends LitElement {
return html`<w3m-wallet-receive-view></w3m-wallet-receive-view>`
case 'WalletCompatibleNetworks':
return html`<w3m-wallet-compatible-networks-view></w3m-wallet-compatible-networks-view>`
case 'WalletSend':
return html`<w3m-wallet-send-view></w3m-wallet-send-view>`
case 'WalletSendSelectToken':
return html`<w3m-wallet-send-select-token-view></w3m-wallet-send-select-token-view>`
case 'WalletSendPreview':
return html`<w3m-wallet-send-preview-view></w3m-wallet-send-preview-view>`
default:
return html`<w3m-connect-view></w3m-connect-view>`
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,11 @@ export class W3mAccountWalletFeaturesWidget extends LitElement {
text="Receive"
icon="arrowBottomCircle"
></wui-tooltip-select>
<wui-tooltip-select text="Send" icon="send"></wui-tooltip-select>
<wui-tooltip-select
@click=${this.onSendClick.bind(this)}
text="Send"
icon="send"
></wui-tooltip-select>
</wui-flex>
<wui-tabs
Expand Down Expand Up @@ -158,6 +162,10 @@ export class W3mAccountWalletFeaturesWidget extends LitElement {
private onReceiveClick() {
RouterController.push('WalletReceive')
}

private onSendClick() {
RouterController.push('WalletSend')
}
}

declare global {
Expand Down
5 changes: 4 additions & 1 deletion packages/scaffold/src/partials/w3m-header/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,10 @@ function headings() {
OnRampTokenSelect: 'Select Token',
OnRampFiatSelect: 'Select Currency',
WalletReceive: 'Receive',
WalletCompatibleNetworks: 'Compatible Networks'
WalletCompatibleNetworks: 'Compatible Networks',
WalletSend: 'Send',
WalletSendPreview: 'Review send',
WalletSendSelectToken: 'Select Token'
}
}

Expand Down
Loading

0 comments on commit 5f44461

Please sign in to comment.