Skip to content

Commit

Permalink
Merge pull request #292 from alephium/clean-before-init
Browse files Browse the repository at this point in the history
Clean storage before SignClient init
  • Loading branch information
Lbqds authored Dec 22, 2023
2 parents 40d72d3 + 89b6ff9 commit 2837dc0
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 13 deletions.
2 changes: 2 additions & 0 deletions packages/walletconnect/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"@walletconnect/sign-client": "2.10.6",
"@walletconnect/types": "2.10.6",
"@walletconnect/utils": "2.10.6",
"@walletconnect/core": "2.10.6",
"@walletconnect/keyvaluestorage": "1.1.1",
"eventemitter3": "^4.0.7"
},
"devDependencies": {
Expand Down
112 changes: 99 additions & 13 deletions packages/walletconnect/src/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,15 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
import EventEmitter from 'eventemitter3'
import { SessionTypes } from '@walletconnect/types'
import SignClient from '@walletconnect/sign-client'
import { SESSION_CONTEXT, SIGN_CLIENT_STORAGE_PREFIX } from '@walletconnect/sign-client'
import { isBrowser } from '@walletconnect/utils'
import { getChainsFromNamespaces, getAccountsFromNamespaces, getSdkError } from '@walletconnect/utils'
import {
getChainsFromNamespaces,
getAccountsFromNamespaces,
getSdkError,
mapToObj,
objToMap
} from '@walletconnect/utils'
import {
SignerProvider,
Account,
Expand Down Expand Up @@ -55,6 +62,17 @@ import {
ChainInfo
} from './types'
import { isMobile } from './utils'
import {
CORE_STORAGE_PREFIX,
CORE_STORAGE_OPTIONS,
HISTORY_STORAGE_VERSION,
HISTORY_CONTEXT,
STORE_STORAGE_VERSION,
MESSAGES_STORAGE_VERSION,
MESSAGES_CONTEXT
} from '@walletconnect/core'
import { KeyValueStorage } from '@walletconnect/keyvaluestorage'
import { JsonRpcRecord, MessageRecord } from '@walletconnect/types'

export interface ProviderOptions extends EnableOptionsBase {
// Alephium options
Expand Down Expand Up @@ -135,7 +153,7 @@ export class WalletConnectProvider extends SignerProvider {
} else {
this.updateNamespace(this.session.namespaces)
}
await this.client.core.relayer.messages.del(this.session.topic)
await this.cleanMessages()
}

public async disconnect(): Promise<void> {
Expand Down Expand Up @@ -207,24 +225,91 @@ export class WalletConnectProvider extends SignerProvider {

// ---------- Private ----------------------------------------------- //

private cleanHistory(checkResponse: boolean) {
const records = this.client.core.history.records
for (const [id, record] of records) {
if (checkResponse && record.response === undefined) {
continue
private getWCStorageKey(prefix: string, version: string, name: string): string {
return prefix + version + '//' + name
}

private async getSessionTopics(storage: KeyValueStorage): Promise<string[]> {
const sessionKey = this.getWCStorageKey(SIGN_CLIENT_STORAGE_PREFIX, STORE_STORAGE_VERSION, SESSION_CONTEXT)
const sessions = await storage.getItem<SessionTypes.Struct[]>(sessionKey)
if (sessions === undefined) {
return []
}
return sessions
.filter((session) => {
const chains = getChainsFromNamespaces(session.namespaces, [PROVIDER_NAMESPACE])
return chains.length > 0 && chains.every((c) => c.startsWith(PROVIDER_NAMESPACE))
})
.map((session) => session.topic)
}

// clean the `history` and `messages` storage before `SignClient` init
private async cleanBeforeInit() {
console.log('Clean storage before SignClient init')
const storage = new KeyValueStorage({ ...CORE_STORAGE_OPTIONS })
const historyStorageKey = this.getWCStorageKey(CORE_STORAGE_PREFIX, HISTORY_STORAGE_VERSION, HISTORY_CONTEXT)
const historyRecords = await storage.getItem<JsonRpcRecord[]>(historyStorageKey)
if (historyRecords !== undefined) {
const remainRecords = historyRecords.filter((record) => !this.needToDeleteHistory(record))
await storage.setItem<JsonRpcRecord[]>(historyStorageKey, remainRecords)
}

const topics = await this.getSessionTopics(storage)
if (topics.length > 0) {
const messageStorageKey = this.getWCStorageKey(CORE_STORAGE_PREFIX, MESSAGES_STORAGE_VERSION, MESSAGES_CONTEXT)
const messages = await storage.getItem<Record<string, MessageRecord>>(messageStorageKey)
if (messages === undefined) {
return
}
const request = record.request
if (request.method !== 'wc_sessionRequest') {
continue

const messagesMap = objToMap(messages)
topics.forEach((topic) => messagesMap.delete(topic))
await storage.setItem<Record<string, MessageRecord>>(messageStorageKey, mapToObj(messagesMap))
console.log(`Clean topics from messages storage: ${topics.join(',')}`)
}
}

private needToDeleteHistory(record: JsonRpcRecord): boolean {
const request = record.request
if (request.method !== 'wc_sessionRequest') {
return false
}
const alphRequestMethod = request.params?.request?.method
return alphRequestMethod === 'alph_requestNodeApi' || alphRequestMethod === 'alph_requestExplorerApi'
}

private cleanHistory(checkResponse: boolean) {
try {
const records = this.client.core.history.records
for (const [id, record] of records) {
if (checkResponse && record.response === undefined) {
continue
}
if (this.needToDeleteHistory(record)) {
this.client.core.history.delete(record.topic, id)
}
}
const alphRequestMethod = request.params?.request?.method
if (alphRequestMethod === 'alph_requestNodeApi' || alphRequestMethod === 'alph_requestExplorerApi') {
this.client.core.history.delete(record.topic, id)
} catch (error) {
console.error(`Failed to clean history, error: ${error}`)
}
}

private async cleanMessages() {
if (this.session !== undefined) {
try {
await this.client.core.relayer.messages.del(this.session.topic)
} catch (error) {
console.error(`Failed to clean messages, error: ${error}, topic: ${this.session.topic}`)
}
}
}

private async initialize() {
try {
await this.cleanBeforeInit()
} catch (error) {
console.error(`Failed to clean storage, error: ${error}`)
}
await this.createClient()
this.cleanHistory(false)
this.checkStorage()
Expand Down Expand Up @@ -333,6 +418,7 @@ export class WalletConnectProvider extends SignerProvider {
if (!isSignRequest) {
this.cleanHistory(true)
}
await this.cleanMessages()
return response
} catch (error: any) {
if (error.message) {
Expand Down
4 changes: 4 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 2837dc0

Please sign in to comment.