Skip to content

Commit

Permalink
Update to shared lib
Browse files Browse the repository at this point in the history
  • Loading branch information
jribbink committed Aug 7, 2024
1 parent 7cab0cc commit 7ddb98b
Show file tree
Hide file tree
Showing 11 changed files with 107 additions and 69 deletions.
5 changes: 3 additions & 2 deletions components/views/ConnectExtension.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { Button, Heading, Spinner, Stack, Text } from '@chakra-ui/react'
import { Wallet } from '../../data/wallets'
import { useEffect, useRef, useState } from 'react'
import { Service } from '../../types'
import { FCL_SERVICE_METHODS, FclRpcMethod } from '../../helpers/constants'
import { FCL_SERVICE_METHODS } from '../../helpers/constants'
import { useRpc } from '../../contexts/FclContext'
import { FclRequest } from '../../helpers/rpc'
import WalletIcon from '../Icons/WalletIcon'

type ConnectExtensionProps = {
Expand All @@ -20,7 +21,7 @@ export default function ConnectExtension({ wallet }: ConnectExtensionProps) {
wallet.services.forEach(service => {
if (service.method === FCL_SERVICE_METHODS.EXT) {
rpc
.request(FclRpcMethod.EXEC_SERVICE, { service })
.request(FclRequest.EXEC_SERVICE, { service })
.catch(e => {
console.error('Failed to connect to extension', e)
})
Expand Down
18 changes: 13 additions & 5 deletions components/views/ScanConnect.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Box, Flex, Spinner, Stack, Text } from '@chakra-ui/react'
import { Box, Button, Flex, Spinner, Stack, Text } from '@chakra-ui/react'
import { Wallet } from '../../data/wallets'
import QRCode from '../QRCode'
import CopyButton from '../CopyButton'
Expand Down Expand Up @@ -52,12 +52,20 @@ export default function ScanConnect({ wallet, onGetWallet }: ScanConnectProps) {
</Flex>
)}
{error && (
<Flex boxSize="20rem" justifyContent="center" alignItems="center">
<Stack
boxSize="20rem"
justifyContent="center"
alignItems="center"
spacing={2}
>
<Text textStyle="body2" colorScheme="red">
An error has occurred while generating the QR code. Please try
again.
{`An error has occurred while generating the QR code. Please try again.`}
</Text>
</Flex>

<Button variant="primary" size="sm" onClick={() => onGetWallet()}>
Try WalletConnect QR//TODO: fix it
</Button>
</Stack>
)}
</Box>

Expand Down
6 changes: 3 additions & 3 deletions contexts/FclContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { createContext, useContext } from 'react'
import { FclConfig } from '../hooks/useFcl'
import { RpcClient } from './rpc/rpc-client'
import { DiscoveryRpcMethods, FclRpcMethods } from '../helpers/constants'
import { FclRpcClient } from '../helpers/rpc'

export type DiscoveryConfig = FclConfig & {
network: string
Expand All @@ -10,15 +10,15 @@ export type DiscoveryConfig = FclConfig & {

export type FclContextType = {
config: DiscoveryConfig
rpc: RpcClient<FclRpcMethods, DiscoveryRpcMethods>
rpc: FclRpcClient
}

export const FclContext = createContext<FclContextType | null>(null)

interface ConfigProviderProps {
children: React.ReactNode
config: DiscoveryConfig
rpc: RpcClient<FclRpcMethods, DiscoveryRpcMethods>
rpc: FclRpcClient
}

export function FclProvider({ children, config, rpc }: ConfigProviderProps) {
Expand Down
13 changes: 12 additions & 1 deletion contexts/rpc/rpc-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ type OnlyNotifications<T> = {

export type IsRpcRequest<T> = T extends RpcRequest<any, any> ? true : false

enum ReservedRpcMethods {
GET_METHODS = 'rpc_getMethods',
}

export class RpcClient<
PeerRpcMethods extends RpcMethodMap,
LocalRpcMethods extends RpcMethodMap
Expand All @@ -74,7 +78,11 @@ export class RpcClient<
> = {} as any
private messageListeners: ((msg: any) => void)[] = []

private constructor(private send: (msg: RpcMessage) => void) {}
private constructor(private send: (msg: RpcMessage) => void) {
this.on(ReservedRpcMethods.GET_METHODS, () => {
return Object.keys(this.handlers)
})
}

static create<
PeerRpcMethods extends RpcMethodMap,
Expand Down Expand Up @@ -183,6 +191,9 @@ export class RpcClient<
method: R,
handler: (params: OnlyRequests<LocalRpcMethods>[R]['params']) => void
) {
if (this.handlers[method]) {
throw new Error(`Handler for method ${method} already exists`)
}
this.handlers[method] = handler
}

Expand Down
26 changes: 1 addition & 25 deletions helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,4 @@ export const BROWSERS = {
},
} as const

export const CUSTOM_IPC = 'FCL:VIEW:CUSTOM_IPC'

export enum DiscoveryRpcMethod {
NOTIFY_QR_EXPIRY = 'notify_qr_expiry',
NOTIFY_QR_ERROR = 'notify_qr_error',
GET_METHODS = 'get_methods',
}

export enum FclRpcMethod {
EXEC_SERVICE = 'exec_service',
REQUEST_URI = 'request_uri',
GET_METHODS = 'get_methods',
}

export type DiscoveryRpcMethods = {
[DiscoveryRpcMethod.NOTIFY_QR_EXPIRY]: RpcNotification<{ uri: string }>
[DiscoveryRpcMethod.NOTIFY_QR_ERROR]: RpcNotification<{ error: string }>
[DiscoveryRpcMethod.GET_METHODS]: RpcRequest<{}, { methods: string[] }>
}

export type FclRpcMethods = {
[FclRpcMethod.EXEC_SERVICE]: RpcRequest<{ service: Service }, {}>
[FclRpcMethod.REQUEST_URI]: RpcRequest<{ service: Service }, { uri: string }>
[FclRpcMethod.GET_METHODS]: RpcRequest<{}, { methods: string[] }>
}
export const CUSTOM_RPC = 'FCL:VIEW:CUSTOM_RPC'
19 changes: 19 additions & 0 deletions helpers/rpc.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { RpcClient, RpcRequest } from "@onflow/util-rpc"
import { Service } from "../types"

export enum DiscoveryNotification {
NOTIFY_QRCODE_EXPIRY = 'notifyQRCodeExpiry',
NOTIFY_QRCODE_ERROR = 'notifyQRCodeError',
}

export enum FclRequest {
REQUEST_WALLETCONNECT_QRCODE = 'requestWalletConnectQRCode',
EXEC_SERVICE = 'execService',
}

export type FclRequests = {
[FclRequest.REQUEST_WALLETCONNECT_QRCODE]: RpcRequest<{}, { uri: string }>
[FclRequest.EXEC_SERVICE]: RpcRequest<{ service: Service }, {}>
}

export type FclRpcClient = RpcClient<FclRequests, {}>
59 changes: 30 additions & 29 deletions hooks/useFcl.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
import { useEffect, useRef, useState } from 'react'
import { WalletUtils } from '@onflow/fcl'
import { RpcClient } from '@onflow/util-rpc'
import { Service, Strategy } from '../types'
import { CUSTOM_RPC } from '../helpers/constants'
import {
CUSTOM_IPC,
FclRpcMethods,
DiscoveryRpcMethods,
DiscoveryRpcMethod,
FclRpcMethod,
} from '../helpers/constants'
import { RpcClient } from '../contexts/rpc/rpc-client'
import { mutate } from 'swr'
import { genGetUriKey } from './useUri'
DiscoveryNotification,
FclRequests,
FclRpcClient,
} from '../helpers/rpc'

type WalletUtilsProps = {
fclVersion: string
Expand All @@ -32,31 +29,40 @@ export function useFcl() {
const [config, setConfig] = useState<FclConfig | null>(null)
const [error, setError] = useState<string | null>(null)
const timeout = useRef<NodeJS.Timeout | null>(null)
const rpcRef = useRef<RpcClient<FclRpcMethods, DiscoveryRpcMethods> | null>(
null
)
const rpcRef = useRef<FclRpcClient | null>(null)
const rpc = rpcRef.current

function initFclRpc() {
const { rpc: rpcClient, receive: receiveRpc } = RpcClient.create<
FclRpcMethods,
DiscoveryRpcMethods
>((msg: any) => {
WalletUtils.sendMsgToFCL(CUSTOM_IPC, { payload: msg })
useEffect(() => {
if (!!rpc) return
const _rpc = new RpcClient<FclRequests, {}>({
notifications: Object.values(DiscoveryNotification),
})

// Bind receiver for messages from FCL
const unsubFcl = WalletUtils.onMessageFromFCL(
CUSTOM_IPC,
CUSTOM_RPC,
({ payload: msg }: { payload: any }) => {
receiveRpc(msg)
_rpc.receive(msg)
}
)

return {
rpc: rpcClient,
teardown: unsubFcl,
// Bind sender for messages to FCL
_rpc.connect({
send: msg => {
WalletUtils.sendMsgToFCL(CUSTOM_RPC, { payload: msg })
},
})

window.addEventListener('message', e => {
console.log('evt', e)
})

rpcRef.current = _rpc

return () => {
unsubFcl()
}
}
}, [])

useEffect(() => {
try {
Expand Down Expand Up @@ -104,13 +110,8 @@ export function useFcl() {
)
}

// Initialize RPC
const { teardown: teardownRpcListener, rpc: rpcClient } = initFclRpc()
rpcRef.current = rpcClient

return () => {
clearTimeout(timeout.current)
teardownRpcListener()
}
}, [])

Expand Down
19 changes: 15 additions & 4 deletions hooks/useUri.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import useSWR from 'swr'
import { useRpc } from '../contexts/FclContext'
import { Service } from '../types'
import { DiscoveryRpcMethod, FclRpcMethod } from '../helpers/constants'
import { DiscoveryNotification, FclRequest } from '../helpers/rpc'

export const genGetUriKey = (service: Service) => [
'get-uri',
Expand All @@ -15,16 +15,27 @@ export function useUri(service: Service) {
error,
mutate,
} = useSWR(genGetUriKey(service), async () => {
const { uri } = await rpc.request(FclRpcMethod.REQUEST_URI, { service })
const { uri } = await rpc.request(FclRequest.REQUEST_WALLETCONNECT_QRCODE, {
service,
})

// Subscribe to QR expiry notifications
const onExpire = ({ uri: _refUri }) => {
if (_refUri === uri) {
mutate()
rpc.unsubscribe(DiscoveryRpcMethod.NOTIFY_QR_EXPIRY, onExpire)
rpc.unsubscribe(DiscoveryNotification.NOTIFY_QRCODE_EXPIRY, onExpire)
}
}
rpc.subscribe(DiscoveryRpcMethod.NOTIFY_QR_EXPIRY, onExpire)
rpc.subscribe(DiscoveryNotification.NOTIFY_QRCODE_EXPIRY, onExpire)

// Subscribe to QR error notifications
const onError = ({ error: _error }) => {
if (_error === uri) {
mutate()
rpc.unsubscribe(DiscoveryNotification.NOTIFY_QRCODE_ERROR, onError)
}
}
rpc.subscribe(DiscoveryNotification.NOTIFY_QRCODE_ERROR, onError)

return uri
})
Expand Down
Binary file added onflow-util-rpc-0.0.1.tgz
Binary file not shown.
10 changes: 10 additions & 0 deletions package-lock.json

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

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"@emotion/react": "^11.10.5",
"@emotion/styled": "^11.10.5",
"@onflow/fcl": "1.0.2",
"@onflow/util-rpc": "file:onflow-util-rpc-0.0.1.tgz",
"@sentry/nextjs": "^8.20.0",
"cors": "^2.8.5",
"enum-xyz": "^0.3.1",
Expand Down

0 comments on commit 7ddb98b

Please sign in to comment.