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

💉 Inject metadata into signer #3872

Merged
merged 23 commits into from
May 30, 2023
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion packages/ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"graphql-tag": "^2.12.5",
"i18next": "^21.6.3",
"i18next-browser-languagedetector": "^6.1.2",
"injectweb3-connect": "^1.1.1",
"injectweb3-connect": "^1.2.7",
"jsonpath": "^1.1.1",
"lodash": "^4.17.21",
"mime": "^2.4.4",
Expand Down
5 changes: 5 additions & 0 deletions packages/ui/src/api/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { getPolkadotApiChainInfo } from 'injectweb3-connect'

import { Awaited } from '@/common/types/helpers'

export type MetadataDef = Awaited<ReturnType<typeof getPolkadotApiChainInfo>>
14 changes: 14 additions & 0 deletions packages/ui/src/api/utils/getChainMetadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { ApiRx } from '@polkadot/api'
import { getPolkadotApiChainInfo } from 'injectweb3-connect'

import { ProxyApi } from '@/proxyApi'

import { MetadataDef } from '../types'

export const getChainMetadata = async (api: ProxyApi | ApiRx): Promise<MetadataDef> => {
if ('_async' in api) {
return await api._async.chainMetadata
} else {
return await getPolkadotApiChainInfo(api)
}
}
1 change: 1 addition & 0 deletions packages/ui/src/app/pages/Settings/Settings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ export const Settings = () => {
window.location.reload()
}
}

return (
<Container>
<PageLayout
Expand Down
15 changes: 14 additions & 1 deletion packages/ui/src/common/hooks/useSignAndSendTransaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { useCallback, useEffect, useState } from 'react'
import { ActorRef } from 'xstate'

import { useBalance } from '@/accounts/hooks/useBalance'
import { useMyAccounts } from '@/accounts/hooks/useMyAccounts'
import { useApi } from '@/api/hooks/useApi'
import { getChainMetadata } from '@/api/utils/getChainMetadata'
import { BN_ZERO } from '@/common/constants'
import { getFeeSpendableBalance } from '@/common/providers/transactionFees/provider'

Expand Down Expand Up @@ -44,8 +47,18 @@ export const useSignAndSendTransaction = ({
setBlockHash,
})
const queryNodeStatus = useQueryNodeTransactionStatus(isProcessing, blockHash, skipQueryNode)
const { wallet } = useMyAccounts()
const { api } = useApi()

const sign = useCallback(() => send('SIGN'), [service])
const sign = useCallback(() => {
if (wallet && api) {
getChainMetadata(api).then(async (metadata) => {
await wallet.updateMetadata(metadata)
send('SIGN')
})
}
send('SIGN')
}, [service, wallet])

useEffect(() => {
if (skipQueryNode && isProcessing) {
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/common/types/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export type Defined<T> = T extends undefined ? never : T
export type EnumTypeString<TEnum extends string> = { [key in string]: TEnum | string }

export type KeysOfUnion<T> = T extends T ? keyof T : never

export type Awaited<T> = T extends PromiseLike<infer U> ? U : T
3 changes: 3 additions & 0 deletions packages/ui/src/proxyApi/client/ProxyApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { deserializeMessage, serializePayload, WorkerProxyMessage } from '../mod
import { ClientMessage, PostMessage, RawWorkerMessageEvent, WorkerConnectMessage, WorkerInitMessage } from '../types'
import { workerApi as launchWorker } from '../worker'

import { AsyncProps, _async } from './_async'
import { query } from './query'
import { tx } from './tx'

Expand All @@ -19,6 +20,7 @@ export class ProxyApi extends Events {
rpc: ApiRx['rpc']
tx: ApiRx['tx']
consts: ApiRx['consts']
_async: AsyncProps

static create(providerEndpoint: string) {
const worker = launchWorker()
Expand Down Expand Up @@ -55,6 +57,7 @@ export class ProxyApi extends Events {
this.query = query('query', messages, postMessage)
this.rpc = query('rpc', messages, postMessage)
this.tx = tx(messages, postMessage)
this._async = _async(messages, postMessage)
}

messages
Expand Down
45 changes: 45 additions & 0 deletions packages/ui/src/proxyApi/client/_async.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { filter, firstValueFrom, map, Observable } from 'rxjs'

import { MetadataDef } from '@/api/types'

import { deserializeMessage } from '../models/payload'
import { PostMessage, RawWorkerMessageEvent } from '../types'

export type ClientAsyncMessage = {
messageType: 'chain-metadata'
payload: undefined
}

export type WorkerAsyncMessage = {
messageType: 'chain-metadata'
payload: MetadataDef
}

export interface AsyncProps {
chainMetadata: Promise<MetadataDef>
}

export const _async = (
messages: Observable<RawWorkerMessageEvent>,
postMessage: PostMessage<ClientAsyncMessage>
): AsyncProps => {
let chainMetadata: Promise<MetadataDef>

return {
get chainMetadata(): Promise<MetadataDef> {
if (!chainMetadata) chainMetadata = getAsync('chain-metadata')
return chainMetadata
},
}

function getAsync(messageType: ClientAsyncMessage['messageType']): Promise<WorkerAsyncMessage['payload']> {
postMessage({ messageType, payload: undefined })
return firstValueFrom(
messages.pipe(
filter(({ data }) => data.messageType === 'chain-metadata'),
deserializeMessage<WorkerAsyncMessage>(),
map(({ payload }) => payload)
)
)
}
}
11 changes: 9 additions & 2 deletions packages/ui/src/proxyApi/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { SubmittableExtrinsic } from '@polkadot/api/types'

import { ProxyApi } from '.'
import { ClientAsyncMessage, WorkerAsyncMessage } from './client/_async'
import { ClientQueryMessage, WorkerQueryMessage } from './client/query'
import { ClientTxMessage, WorkerTxMessage } from './client/tx'
import { ClientProxyMessage, WorkerProxyMessage } from './models/payload'
Expand Down Expand Up @@ -38,7 +39,13 @@ export type WorkerMessage =
| WorkerQueryMessage
| WorkerTxMessage
| WorkerProxyMessage

export type ClientMessage = ClientInitMessage | ClientQueryMessage | ClientTxMessage | ClientProxyMessage
| WorkerAsyncMessage

export type ClientMessage =
| ClientInitMessage
| ClientQueryMessage
| ClientTxMessage
| ClientProxyMessage
| ClientAsyncMessage

export type AnyMessage = WorkerMessage | ClientMessage
7 changes: 5 additions & 2 deletions packages/ui/src/proxyApi/worker/worker.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import '@joystream/types'
import { ApiRx, WsProvider } from '@polkadot/api'
import { getPolkadotApiChainInfo } from 'injectweb3-connect'
import { BehaviorSubject, filter, first, fromEvent, share } from 'rxjs'

import { isDefined } from '@/common/utils'
Expand Down Expand Up @@ -35,14 +36,13 @@ messages.subscribe(({ data }) => {
.subscribe((api) => {
postMessage({ messageType: 'init', payload: { consts: api.consts } })
postMessage({ messageType: 'isConnected', payload: true })

api.on('connected', () => self.postMessage({ messageType: 'isConnected', payload: true }))
api.on('disconnected', () => self.postMessage({ messageType: 'isConnected', payload: false }))

apiObserver.next(api)
})
} else {
apiObserver.pipe(firstWhere(isDefined)).subscribe((api) => {
apiObserver.pipe(firstWhere(isDefined)).subscribe(async (api) => {
switch (message.messageType) {
case 'derive':
return query('derive', api as ApiRx, message, postMessage)
Expand All @@ -55,6 +55,9 @@ messages.subscribe(({ data }) => {

case 'tx':
return tx(api as ApiRx, message, postMessage)

case 'chain-metadata':
return postMessage({ messageType: 'chain-metadata', payload: await getPolkadotApiChainInfo(api as ApiRx) })
}
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,11 @@ describe('UI: TransactionButton', () => {
stubTransaction(api, txPath)

beforeAll(async () => {
stubAccounts([{ ...alice, name: 'Alice Account' }], { wallet: new BaseDotsamaWallet({ title: 'ExtraWallet' }) })
const wallet = new BaseDotsamaWallet({ title: 'ExtraWallet' })
wallet.updateMetadata = () => Promise.resolve(true)
stubAccounts([{ ...alice, name: 'Alice Account' }], {
wallet,
})
await cryptoWaitReady()
})

Expand Down
11 changes: 6 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3440,7 +3440,7 @@ __metadata:
i18next: ^21.6.3
i18next-browser-languagedetector: ^6.1.2
i18next-json-csv-converter: ^0.2.0
injectweb3-connect: ^1.1.1
injectweb3-connect: ^1.2.7
jest: ^27.2.5
jest-transform-stub: ^2.0.0
jsdom: ^18.0.0
Expand Down Expand Up @@ -14372,15 +14372,16 @@ __metadata:
languageName: node
linkType: hard

"injectweb3-connect@npm:^1.1.1":
version: 1.1.1
resolution: "injectweb3-connect@npm:1.1.1"
"injectweb3-connect@npm:^1.2.7":
version: 1.2.7
resolution: "injectweb3-connect@npm:1.2.7"
dependencies:
"@polkadot/api": ^8.8.2
"@polkadot/extension-dapp": ^0.44.1
"@polkadot/extension-inject": ^0.44.1
"@polkadot/types-known": ^9.9.1
"@polkadot/util-crypto": ^9.4.1
checksum: b0ac017f918e2d752521081e88790d6679355a699c47927cff3ac1edfa891b02d2cd24bad5e786a29f935fab569dbc6e470fabd4250bf40b7c5fae67d7bf74c6
checksum: c69e40a508642a2d9b480b540f53bc587811e686c4b31b6f397f02b07b560c149c4b59fb7b850abbe292019d539abfec0a5e49791664f3db3df9c14b6a0e3251
languageName: node
linkType: hard

Expand Down