Skip to content

Commit

Permalink
CU-86dt27bzj - Create a WcSdk method to wipe all requests from a dapp
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonardoDizConde committed Apr 16, 2024
1 parent 56f20e7 commit cc5d957
Show file tree
Hide file tree
Showing 11 changed files with 161 additions and 36 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cityofzion/wallet-connect-sdk-core",
"comment": "Implemented wipe methods",
"type": "minor"
}
],
"packageName": "@cityofzion/wallet-connect-sdk-core"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cityofzion/wallet-connect-sdk-react",
"comment": "Implemented wipe methods",
"type": "minor"
}
],
"packageName": "@cityofzion/wallet-connect-sdk-react"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cityofzion/wallet-connect-sdk-svelte",
"comment": "Implemented wipe methods",
"type": "minor"
}
],
"packageName": "@cityofzion/wallet-connect-sdk-svelte"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"changes": [
{
"packageName": "@cityofzion/wallet-connect-sdk-wallet-core",
"comment": "Implemented wipe methods",
"type": "minor"
}
],
"packageName": "@cityofzion/wallet-connect-sdk-wallet-core"
}
18 changes: 18 additions & 0 deletions e2e/tests/DappMethods.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,21 @@ test('Test Sign Transaction on dapp (React)', async ({ context }) => {
const response = await getAnyFromInnerHTML(dappPage.page.getByTestId('hello-world__method-response'))
expect(response).toBeDefined() // Verify if the response had a return
})

test('Test Wipe Methods on dapp (React)', async ({ context }) => {
// Define the dapp and wallet pages
const dappPage = DAPP_REACT
const walletPage = WALLET_REACT
await connectReactDappToNewReactAccount(context, dappPage, walletPage)
await dappPage.page.waitForLoadState('networkidle') // Wait to load request
await dappPage.awaitSeconds(5) // Wait for 5 seconds
for (let i = 0; i <= 3; i++) {
// Click on Sign Transaction button 3 times
await dappPage.page.getByTestId('hello-world__sign-transaction').click()
await dappPage.awaitSeconds(0.5)
}
await dappPage.page.getByTestId('hello-world__wipe-methods').click() // Click on Wipe Methods button
await dappPage.awaitSeconds(2) // Wait for 2 seconds
const pendingRequests = await walletPage.page.getByTestId('default-card__pending-request').all()
expect(pendingRequests.length).toBe(0) // Verify if the response had a return
})
58 changes: 29 additions & 29 deletions examples/wc-dapp-react/src/components/HelloWorld.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react'
import { TypeChecker } from '@cityofzion/neon-dappkit-types'
import { NetworkType, useWalletConnect, SignMessageVersion } from '@cityofzion/wallet-connect-sdk-react'
import { NetworkType, useWalletConnect, SignMessageVersion, Method } from '@cityofzion/wallet-connect-sdk-react'

const networks: Record<NetworkType, { name: string }> = {
'neo3:mainnet': {
Expand All @@ -13,6 +13,21 @@ const networks: Record<NetworkType, { name: string }> = {
name: 'Private Network',
},
}
const dappMethods: Method[] = [
'invokeFunction',
'testInvoke',
'signMessage',
'verifyMessage',
'traverseIterator',
'getWalletInfo',
'getNetworkVersion',
'decrypt',
'encrypt',
'decryptFromArray',
'calculateFee',
'signTransaction',
'wipeRequests',
]

function HelloWorld() {
const [dappUri, setDappUri] = useState('')
Expand All @@ -21,37 +36,11 @@ function HelloWorld() {
const [networkType, setNetworkType] = React.useState<NetworkType>('neo3:testnet')

const connect = async (): Promise<void> => {
await wcSdk.connect(networkType, [
'invokeFunction',
'testInvoke',
'signMessage',
'verifyMessage',
'traverseIterator',
'getWalletInfo',
'getNetworkVersion',
'decrypt',
'encrypt',
'decryptFromArray',
'calculateFee',
'signTransaction',
])
await wcSdk.connect(networkType, dappMethods)
}

const getUri = async (): Promise<void> => {
const { uri, approval } = await wcSdk.createConnection('neo3:testnet', [
'invokeFunction',
'testInvoke',
'signMessage',
'verifyMessage',
'traverseIterator',
'getWalletInfo',
'getNetworkVersion',
'decrypt',
'encrypt',
'decryptFromArray',
'calculateFee',
'signTransaction',
])
const { uri, approval } = await wcSdk.createConnection('neo3:testnet', dappMethods)
if (uri) {
setDappUri(uri)
await navigator.clipboard.writeText(uri)
Expand Down Expand Up @@ -409,6 +398,14 @@ function HelloWorld() {
// you can grab this response and do an invokeFunction using owner account (eg.: NhGomBpYnKXArr55nHRQ5rzy79TwKVXZbr)
}

const wipeMethods = async () => {
try {
await wcSdk.wipeRequests()
} catch (error) {
console.log(error)
}
}

return (
<div>
{!wcSdk && <span>Loading...</span>}
Expand Down Expand Up @@ -491,6 +488,9 @@ function HelloWorld() {
<button data-testid="hello-world__sign-transaction" onClick={signTransaction}>
Sign Transaction
</button>
<button data-testid="hello-world__wipe-methods" onClick={wipeMethods}>
Wipe Methods
</button>
<br></br>
<span>Response:</span>
<br></br>
Expand Down
1 change: 1 addition & 0 deletions examples/wc-wallet-react/src/constants/default.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const DEFAULT_METHODS: Method[] = [
'decryptFromArray',
'calculateFee',
'signTransaction',
'wipeRequests',
]

export const DEFAULT_LOGGER = 'error'
Expand Down
22 changes: 22 additions & 0 deletions packages/wallet-connect-sdk-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ export type Method =
| 'decryptFromArray'
| 'calculateFee'
| 'signTransaction'
| 'wipeRequests'

/**
* A number that will be compared by the wallet to check if it is compatible with the dApp
Expand Down Expand Up @@ -77,6 +78,7 @@ export const DEFAULT_AUTO_ACCEPT_METHODS: Method[] = [
'traverseIterator',
'getNetworkVersion',
'calculateFee',
'wipeRequests',
]

export class WcSdkError extends Error {
Expand Down Expand Up @@ -658,6 +660,26 @@ class WcSdk implements Neo3Invoker, Neo3Signer {
return resp as DecryptFromArrayResult
}

async wipeRequests(): Promise<string[]> {
const request = {
id: 1,
jsonrpc: '2.0',
method: 'wipeRequests',
params: [],
}
const resp = await this.signClient.request({
topic: this.session?.topic ?? '',
chainId: this.getChainId() ?? '',
request,
})

if (!resp) {
throw new WcSdkError(resp)
}

return resp as string[]
}

private validateContractInvocationMulti(request: ContractInvocationMulti): boolean {
// verify fields
this.objectValidation(request, ['signers', 'invocations'])
Expand Down
7 changes: 7 additions & 0 deletions packages/wallet-connect-sdk-react/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ interface IWalletConnectContext extends Neo3Invoker, Neo3Signer {
* @return network information
*/
getNetworkVersion: () => Promise<NetworkVersion>

wipeRequests: () => Promise<string[]>
}

export const WalletConnectContext = React.createContext({} as IWalletConnectContext)
Expand Down Expand Up @@ -257,6 +259,10 @@ export const WalletConnectProvider: React.FC<{
[getSdkOrError],
)

const wipeRequests = useCallback(() => {
return getSdkOrError().wipeRequests()
}, [getSdkOrError])

const setupWcClient = useCallback(async () => {
if (!options) return
const wcSdk = await WcSdk.init(options)
Expand Down Expand Up @@ -301,6 +307,7 @@ export const WalletConnectProvider: React.FC<{
decryptFromArray,
signTransaction,
calculateFee,
wipeRequests,
}

return <WalletConnectContext.Provider value={contextValue}>{children}</WalletConnectContext.Provider>
Expand Down
4 changes: 4 additions & 0 deletions packages/wallet-connect-sdk-svelte/src/WcSdkStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,10 @@ export class WCSDKStore implements IWalletConnectStore {
this.sessionWritable.set(result)
}

async wipeRequests(): Promise<string[]> {
return await this.SdkOrError.wipeRequests()
}

get session() {
return derived(this.sessionWritable, (session) => session)
}
Expand Down
47 changes: 40 additions & 7 deletions packages/wallet-connect-sdk-wallet-core/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export class WcWalletSDK {
private _proposals: TSessionProposal[] = []
private _requests: TSessionRequest[] = []
private _status: EStatus = EStatus.NOT_STARTED
private _permissibleWalletRequestMethods: Record<string, (args: TAdapterMethodParam) => Promise<any>>

private wccvs: Map<string, number> = new Map()

Expand All @@ -56,6 +57,9 @@ export class WcWalletSDK {
constructor(options: TInitOptions) {
this.clientOptions = options.clientOptions
this.blockchainsOptions = options.blockchains
this._permissibleWalletRequestMethods = {
wipeRequests: this.wipeRequests.bind(this),
}
}

/**
Expand Down Expand Up @@ -319,18 +323,24 @@ export class WcWalletSDK {
const session = this.sessions.find((session) => session.topic === request.topic)
if (!session) throw new Error('Session not found')

let result: any = null

const method = request.params.request.method
if (!blockchainOptions.methods.includes(method)) throw new Error('Invalid request method')
const permissibleWalletRequestMethod = this._permissibleWalletRequestMethods[method]

const adapterMethod = blockchainOptions.adapter[method] as (params: TAdapterMethodParam) => Promise<any>
if (!adapterMethod || typeof adapterMethod !== 'function') throw new Error('Invalid request method')
if (permissibleWalletRequestMethod) {
result = await permissibleWalletRequestMethod.apply(this, [{ request, session }])
} else if (blockchainOptions.methods.includes(method)) {
const adapterMethod = blockchainOptions.adapter[method] as (params: TAdapterMethodParam) => Promise<any>
if (!adapterMethod || typeof adapterMethod !== 'function') throw new Error('Invalid request method')

const startExecutionTime = performance.now()
const startExecutionTime = performance.now()

const result = await adapterMethod.apply(blockchainOptions.adapter, [{ request, session }])
result = await adapterMethod.apply(blockchainOptions.adapter, [{ request, session }])

const executionTime = performance.now() - startExecutionTime
if (executionTime < MIN_TIME_OF_EXECUTION) await sleep(MIN_TIME_OF_EXECUTION - executionTime)
const executionTime = performance.now() - startExecutionTime
if (executionTime < MIN_TIME_OF_EXECUTION) await sleep(MIN_TIME_OF_EXECUTION - executionTime)
} else throw new Error('Invalid request method')

response = {
id: request.id,
Expand Down Expand Up @@ -377,4 +387,27 @@ export class WcWalletSDK {
this.requests = filteredRequests
}
}

private async wipeRequests({ session, request }: TAdapterMethodParam): Promise<string[]> {
const result: string[] = []
const dappRequests: TSessionRequest[] = (this._requests.filter(
(dappRequest: TSessionRequest) => dappRequest.topic === session.topic && dappRequest.id !== request.id,
) ?? []) as TSessionRequest[]

for (const dappRequest of dappRequests) {
try {
await this.signClient.respond({
topic: dappRequest.topic,
response: formatJsonRpcError(dappRequest.id, {
code: 1,
message: 'rejected by the dapp',
}),
})
} finally {
this.requests = this.requests.filter(({ id }) => id !== dappRequest.id)
result.push(dappRequest.params.request.method)
}
}
return result
}
}

0 comments on commit cc5d957

Please sign in to comment.