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

chore: siwe to siwx migration #3194

Merged
merged 44 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
4559f59
refactor: add params in getNonce function
zoruka Nov 4, 2024
4938fdb
feat: add map to siwx function
zoruka Nov 4, 2024
2ce57a2
refactor: apply siwx over siwe
zoruka Nov 4, 2024
07a6605
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 6, 2024
63c34ef
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 7, 2024
6e4cbed
fix: issues after rebase
zoruka Nov 7, 2024
2e01a07
chore: revert ts issue changes on solana adapter
zoruka Nov 7, 2024
04a1c90
fix: formating issue
zoruka Nov 7, 2024
3190dcf
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 7, 2024
36598e9
fix: missing siwx initialization
zoruka Nov 7, 2024
edb0fe5
refactor: move validation to LocalStorage to keep independent from si…
zoruka Nov 7, 2024
b72b68d
fix: fix LocalStorage validation
zoruka Nov 7, 2024
fc061f2
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 8, 2024
7bec91c
fix: missing setClientId
zoruka Nov 8, 2024
be32fb1
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 13, 2024
192067b
fix: siwx on handleClose
zoruka Nov 13, 2024
b40dc5f
fix: solana response for signMessage
zoruka Nov 13, 2024
92326a5
fix: correct solana signature for universal adapter
zoruka Nov 13, 2024
5791611
feat: handle siwx error
zoruka Nov 13, 2024
adce84e
refactor: change siwe condition to siwx
zoruka Nov 13, 2024
1f216f1
feat: add SIWXUtils functions and enable one click auth
zoruka Nov 13, 2024
c4fea48
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 13, 2024
f2fcb2c
fix: siwx types export
zoruka Nov 13, 2024
dddf0bd
fix: cacao to siwx data parsing
zoruka Nov 13, 2024
28e21c5
fix: remove unused import
zoruka Nov 13, 2024
0fb0ca3
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 14, 2024
d833588
refactor: move universal provider authentication to SIWXUtils
zoruka Nov 14, 2024
61431ca
refactor: remove siwx package from siwe
zoruka Nov 14, 2024
499562d
refactor: rename variable
zoruka Nov 14, 2024
11b47e6
refactor: setup siwx events instead of siwe events
zoruka Nov 14, 2024
5ce726d
fix: remove siwe references on appkit
zoruka Nov 14, 2024
be5f4fe
refactor: bring back sign button
zoruka Nov 14, 2024
b1d59a1
fix: missing siwe configuration flags on mapToSIWX
zoruka Nov 14, 2024
bcab8ea
fix: missing auth sign message opening
zoruka Nov 14, 2024
7677a16
refactor: remove file with functions not in use
zoruka Nov 15, 2024
b6c3ad5
fix: spread cacao instead of include line by line
zoruka Nov 15, 2024
03139c7
fix: remove inline experssion
zoruka Nov 15, 2024
50f156e
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 15, 2024
30e28f9
fix: siwe mapping for non evm chains
zoruka Nov 15, 2024
54c5552
test: fix tests
zoruka Nov 15, 2024
47e32c8
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 18, 2024
d1b5dde
chore: add changeset
zoruka Nov 18, 2024
b11becf
Merge branch 'main' of github.com:WalletConnect/web3modal into chore/…
zoruka Nov 18, 2024
7ed50aa
fix: missing to check option in map to siwx
zoruka Nov 18, 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
24 changes: 24 additions & 0 deletions .changeset/sour-timers-crash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
'@reown/appkit-adapter-solana': minor
'@reown/appkit-scaffold-ui': minor
'@apps/laboratory': minor
'@reown/appkit': minor
'@reown/appkit-core': minor
'@reown/appkit-siwe': minor
'@reown/appkit-siwx': minor
'@apps/demo': minor
'@apps/gallery': minor
'@reown/appkit-adapter-ethers': minor
'@reown/appkit-adapter-ethers5': minor
'@reown/appkit-adapter-polkadot': minor
'@reown/appkit-adapter-wagmi': minor
'@reown/appkit-utils': minor
'@reown/appkit-cdn': minor
'@reown/appkit-common': minor
'@reown/appkit-experimental': minor
'@reown/appkit-polyfills': minor
'@reown/appkit-ui': minor
'@reown/appkit-wallet': minor
---

Replace SIWE with new SIWX
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ test('it should switch to different namespace', async () => {
const chainName = 'Solana'

await page.switchNetwork(chainName)
await page.openNetworks()
await validator.expectUnauthenticated()
tomiir marked this conversation as resolved.
Show resolved Hide resolved
await validator.expectSwitchedNetwork(chainName)
await page.closeModal()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ test.beforeAll(async ({ browser }) => {
await modalPage.load()
await modalPage.qrCodeFlow(modalPage, walletPage)
await modalValidator.expectConnected()
await modalPage.promptSiwe()
await walletPage.handleRequest({ accept: true })
await modalValidator.expectAuthenticated()
tomiir marked this conversation as resolved.
Show resolved Hide resolved
})

test.afterAll(async () => {
Expand All @@ -53,5 +56,5 @@ test('it should switch networks and sign siwe', async () => {
test('it should switch to Solana and validate chain title', async () => {
const chainName = 'Solana'
await modalPage.switchNetwork(chainName)
await modalValidator.expectSwitchChainView(chainName.toLocaleLowerCase())
await modalValidator.expectSwitchedNetworkOnNetworksView(chainName)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, if the expected behavior is to keep switch chain view open after the chain is switched, this test was wrong.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how was it passing before?

})
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ test('it should switch to different namespace', async () => {
const chainName = 'Solana'

await page.switchNetwork(chainName)
await page.openNetworks()
await validator.expectUnauthenticated()
await validator.expectSwitchedNetwork(chainName)
await page.closeModal()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ test.beforeAll(async ({ browser }) => {
await modalPage.load()
await modalPage.qrCodeFlow(modalPage, walletPage)
await modalValidator.expectConnected()
await modalPage.promptSiwe()
await walletPage.handleRequest({ accept: true })
await modalValidator.expectAuthenticated()
})

test.afterAll(async () => {
Expand All @@ -52,5 +55,5 @@ test('it should switch networks and sign siwe', async () => {
test('it should switch to Solana and validate chain title', async () => {
const chainName = 'Solana'
await modalPage.switchNetwork(chainName)
await modalValidator.expectSwitchChainView(chainName.toLocaleLowerCase())
await modalValidator.expectSwitchedNetworkOnNetworksView(chainName)
})
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ test('it should switch to different namespace', async () => {

await page.switchNetwork(chainName)
await validator.expectUnauthenticated()
await page.closeModal()
await page.openAccount()
await page.openNetworks()
await validator.expectSwitchedNetwork(chainName)
await page.closeModal()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ test.beforeAll(async ({ browser }) => {
await modalPage.load()
await modalPage.qrCodeFlow(modalPage, walletPage)
await modalValidator.expectConnected()
await modalPage.promptSiwe()
await walletPage.handleRequest({ accept: true })
await modalValidator.expectAuthenticated()
})

test.afterAll(async () => {
Expand All @@ -53,5 +56,5 @@ test('it should switch networks and sign siwe', async () => {
test('it should switch to Solana and validate chain title', async () => {
const chainName = 'Solana'
await modalPage.switchNetwork(chainName)
await modalValidator.expectSwitchChainView(chainName.toLocaleLowerCase())
await modalValidator.expectSwitchedNetworkOnNetworksView(chainName)
})
3 changes: 2 additions & 1 deletion packages/adapters/solana/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import type { WalletStandardProvider } from './providers/WalletStandardProvider.
import { handleMobileWalletRedirection } from './utils/handleMobileWalletRedirection.js'
import type { BaseWalletAdapter } from '@solana/wallet-adapter-base'
import { WalletConnectProvider } from './providers/WalletConnectProvider.js'
import bs58 from 'bs58'

export interface AdapterOptions {
connectionSettings?: Commitment | ConnectionConfig
Expand Down Expand Up @@ -187,7 +188,7 @@ export class SolanaAdapter extends AdapterBlueprint {
)

return {
signature: new TextDecoder().decode(signature)
signature: bs58.encode(signature)
tomiir marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
110 changes: 30 additions & 80 deletions packages/appkit/src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ import {
type SendTransactionArgs,
type EstimateGasTransactionArgs,
type AccountControllerState,
type AdapterNetworkState
type AdapterNetworkState,
SIWXUtil
} from '@reown/appkit-core'
import {
AccountController,
Expand Down Expand Up @@ -649,8 +650,16 @@ export class AppKit {
// Set the SIWE client for EVM chains
if (evmAdapter) {
if (options.siweConfig) {
const { SIWEController } = await import('@reown/appkit-siwe')
SIWEController.setSIWEClient(options.siweConfig)
if (options.siwx) {
throw new Error('Cannot set both `siweConfig` and `siwx` options')
}

const siwe = await import('@reown/appkit-siwe')
if (typeof siwe.mapToSIWX !== 'function') {
throw new Error('Please update the `@reown/appkit-siwe` package to the latest version')
}

OptionsController.setSIWX(siwe.mapToSIWX(options.siweConfig))
}
}
}
Expand Down Expand Up @@ -699,78 +708,24 @@ export class AppKit {
onUri(uri)
})

if (this.options.siweConfig) {
const siweParams = await this.options.siweConfig?.getMessageParams?.()
const isSiweEnabled = this.options.siweConfig?.options?.enabled
const isProviderSupported = typeof this.universalProvider?.authenticate === 'function'
const isSiweParamsValid = siweParams && Object.keys(siweParams || {}).length > 0
const clientId = await this.universalProvider?.client?.core?.crypto?.getClientId()
if (clientId) {
this.setClientId(clientId)
if (
this.options.siweConfig &&
isSiweEnabled &&
siweParams &&
isProviderSupported &&
isSiweParamsValid &&
ChainController.state.activeChain === ConstantsUtil.CHAIN.EVM
) {
const { SIWEController, getDidChainId, getDidAddress } = await import(
'@reown/appkit-siwe'
)

const chains = this.caipNetworks
?.filter(network => network.chainNamespace === ConstantsUtil.CHAIN.EVM)
.map(chain => chain.caipNetworkId) as string[]

siweParams.chains = this.caipNetworks
?.filter(network => network.chainNamespace === ConstantsUtil.CHAIN.EVM)
.map(chain => chain.id) as number[]

const result = await this.universalProvider?.authenticate({
nonce: await this.options.siweConfig?.getNonce?.(),
methods: [...OPTIONAL_METHODS],
...siweParams,
chains
})
// Auths is an array of signed CACAO objects https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-74.md
const signedCacao = result?.auths?.[0]

if (signedCacao) {
const { p, s } = signedCacao
const cacaoChainId = getDidChainId(p.iss)
const address = getDidAddress(p.iss)
if (address && cacaoChainId) {
SIWEController.setSession({
address,
chainId: parseInt(cacaoChainId, 10)
})
}

try {
// Kicks off verifyMessage and populates external states
const message = this.universalProvider?.client.formatAuthMessage({
request: p,
iss: p.iss
})

await SIWEController.verifyMessage({
message: message as string,
signature: s.s,
cacao: signedCacao
})
} catch (error) {
// eslint-disable-next-line no-console
console.error('Error verifying message', error)
// eslint-disable-next-line no-console
await this.universalProvider?.disconnect().catch(console.error)
// eslint-disable-next-line no-console
await SIWEController.signOut().catch(console.error)
throw error
}
}
}
}
this.setClientId(
(await this.universalProvider?.client?.core?.crypto?.getClientId()) || null
)

let isAuthenticated = false

if (this.universalProvider) {
const chains = this.caipNetworks?.map(network => network.caipNetworkId) || []

isAuthenticated = await SIWXUtil.universalProviderAuthenticate({
universalProvider: this.universalProvider,
chains,
methods: OPTIONAL_METHODS
})
}

if (isAuthenticated) {
this.close()
} else {
await adapter?.connectWalletConnect(onUri, this.getCaipNetwork()?.id)
}
Expand Down Expand Up @@ -824,11 +779,6 @@ export class AppKit {
ChainController.state.activeChain as ChainNamespace
)

if (this.options.siweConfig?.options?.signOutOnDisconnect) {
const { SIWEController } = await import('@reown/appkit-siwe')
await SIWEController.signOut()
}

const providerType =
ProviderUtil.state.providerIds[ChainController.state.activeChain as ChainNamespace]

Expand Down
33 changes: 28 additions & 5 deletions packages/appkit/src/universal-adapter/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type UniversalProvider from '@walletconnect/universal-provider'
import { AdapterBlueprint } from '../adapters/ChainAdapterBlueprint.js'
import { WcHelpersUtil } from '../utils/index.js'
import { ChainController } from '@reown/appkit-core'
import bs58 from 'bs58'
import { ConstantsUtil } from '@reown/appkit-common'

export class UniversalAdapter extends AdapterBlueprint {
public async connectWalletConnect(onUri: (uri: string) => void) {
Expand Down Expand Up @@ -60,12 +63,32 @@ export class UniversalAdapter extends AdapterBlueprint {
throw new Error('UniversalAdapter:signMessage - provider is undefined')
}

const signature = await provider.request({
method: 'personal_sign',
params: [message, address]
})
let signature = ''

if (ChainController.state.activeCaipNetwork?.chainNamespace === ConstantsUtil.CHAIN.SOLANA) {
const response = await provider.request(
{
method: 'solana_signMessage',
params: {
message: bs58.encode(new TextEncoder().encode(message)),
pubkey: address
}
},
ChainController.state.activeCaipNetwork?.caipNetworkId
)

signature = (response as { signature: string }).signature
} else {
signature = await provider.request(
{
method: 'personal_sign',
params: [message, address]
},
ChainController.state.activeCaipNetwork?.caipNetworkId
)
}

return { signature: signature as `0x${string}` }
return { signature }
Comment on lines +68 to +91
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the more I think about it, this method should not exist on the adapters

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what to do about this 😞 if we don't do it, it will break the signature for solana

}

// -- Transaction methods ---------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions packages/core/exports/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export { CoreHelperUtil } from '../src/utils/CoreHelperUtil.js'
export { StorageUtil } from '../src/utils/StorageUtil.js'
export { RouterUtil } from '../src/utils/RouterUtil.js'
export { OptionsUtil } from '../src/utils/OptionsUtil.js'
export { SIWXUtil } from '../src/utils/SIWXUtil.js'

export type * from '../src/utils/TypeUtil.js'
export type * from '../src/utils/SIWXUtil.js'
5 changes: 0 additions & 5 deletions packages/core/src/controllers/AccountController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ export interface AccountControllerState {
farcasterUrl?: string
provider?: UniversalProvider | Provider | CombinedProvider
status?: 'reconnecting' | 'connected' | 'disconnected' | 'connecting'
siweStatus?: 'uninitialized' | 'ready' | 'loading' | 'success' | 'rejected' | 'error'
lastRetry?: number
}

Expand Down Expand Up @@ -262,9 +261,5 @@ export const AccountController = {

resetAccount(chain: ChainNamespace) {
ChainController.resetAccount(chain)
},

setSiweStatus(status: AccountControllerState['siweStatus']) {
ChainController.setAccountProp('siweStatus', status, ChainController.state.activeChain)
}
}
61 changes: 0 additions & 61 deletions packages/core/src/controllers/ConnectionController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,66 +266,5 @@ export const ConnectionController = {
} catch (error) {
throw new Error('Failed to disconnect')
}
},

/**
* @experimental - This is an experimental feature and may be subject to change.
* Initializes SIWX if available.
* This is not yet considering One Click Auth.
*/
async initializeSWIXIfAvailable() {
const siwx = OptionsController.state.siwx
const address = CoreHelperUtil.getPlainAddress(ChainController.getActiveCaipAddress())
const network = ChainController.getActiveCaipNetwork()

if (!(siwx && address && network)) {
return
}

if (OptionsController.state.isSiweEnabled) {
console.warn('SIWE is enabled skipping experimental SIWX initialization')

return
}

const client = this._getClient()

try {
const sessions = await siwx.getSessions(network.caipNetworkId, address)
if (sessions.length) {
return
}

await ModalController.open({
view:
StorageUtil.getConnectedConnector() === 'ID_AUTH'
? 'ApproveTransaction'
: 'SIWXSignMessage'
})

const siwxMessage = await siwx.createMessage({
chainId: network.caipNetworkId,
accountAddress: address
})

const message = siwxMessage.toString()

const signature = await client?.signMessage(message)

await siwx.addSession({
data: siwxMessage,
message,
signature: signature as `0x${string}`
})

ModalController.close()
} catch (error: unknown) {
// eslint-disable-next-line no-console
console.error('Failed to initialize SIWX', error)
ModalController.setLoading(true)
await client?.disconnect().finally(() => {
ModalController.setLoading(false)
})
}
}
}
Loading
Loading