Skip to content

Commit

Permalink
refactor(rpc-client)!: provide method handlers instead of onMessage
Browse files Browse the repository at this point in the history
BREAKING CHANGE: `handlers` parameter is removed in RpcClient
Provide a `methods` parameter instead of `handlers[0]`.
Provide an `onDisconnect` parameter instead of `handlers[1]`.
  • Loading branch information
davidyuk committed May 27, 2022
1 parent e2b5186 commit 5f1a007
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 54 deletions.
20 changes: 8 additions & 12 deletions src/utils/aepp-wallet-communication/rpc/aepp-rpc.js
Expand Up @@ -11,6 +11,7 @@ import { v4 as uuid } from '@aeternity/uuid'
import AccountResolver from '../../../account/resolver'
import AccountRpc from '../../../account/rpc'
import { decode } from '../../encoder'
import { mapObject } from '../../other'
import RpcClient from './rpc-client'
import { METHODS, RPC_STATUS, VERSION } from '../schema'
import {
Expand All @@ -23,29 +24,23 @@ import {
} from '../../errors'
import Node from '../../../node'

const NOTIFICATIONS = {
[METHODS.updateAddress]: (instance, { params }) => {
const METHOD_HANDLERS = {
[METHODS.updateAddress]: (instance, params) => {
instance.rpcClient.accounts = params
instance.onAddressChange(params)
},
[METHODS.updateNetwork]: async (instance, { params }) => {
[METHODS.updateNetwork]: async (instance, params) => {
const { node } = params
if (node) instance.addNode(node.name, await Node(node), true)
instance.onNetworkChange(params)
},
[METHODS.closeConnection]: (instance, msg) => {
[METHODS.closeConnection]: (instance, params) => {
instance.disconnectWallet()
instance.onDisconnect(msg.params)
instance.onDisconnect(params)
},
[METHODS.readyToConnect]: () => {}
}

const handleMessage = async (instance, msg) => {
if (!msg.id) {
return NOTIFICATIONS[msg.method](instance, msg)
}
}

/**
* Contain functionality for wallet interaction and connect it to sdk
* @alias module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/aepp-rpc
Expand Down Expand Up @@ -113,7 +108,8 @@ export default AccountResolver.compose({
...walletInfo,
connection,
id: uuid(),
handlers: [handleMessage.bind(null, this), this.onDisconnect]
onDisconnect: this.onDisconnect,
methods: mapObject(METHOD_HANDLERS, ([key, value]) => [key, value.bind(null, this)])
})
const { node } = await this.sendConnectRequest(connectNode)
if (connectNode) {
Expand Down
22 changes: 15 additions & 7 deletions src/utils/aepp-wallet-communication/rpc/rpc-client.js
Expand Up @@ -23,13 +23,12 @@ import {
* @param {Object} param Init params object
* @param {String} param.name Client name
* @param {Object} param.connection Connection object
* @param {Function[]} param.handlers Array with two function for message handling
* @param {Function} param.handlers[0] Message handler
* @param {Function} param.handlers[1] Disconnect callback
* @param {Function} param.onDisconnect Disconnect callback
* @param {Object} param.methods Object containing handlers for each request by name
* @return {Object}
*/
export default stampit({
init ({ id, name, icons, connection, handlers: [onMessage, onDisconnect] }) {
init ({ id, name, icons, connection, onDisconnect, methods }) {
this.id = id
this.connection = connection
this.info = { name, icons }
Expand All @@ -47,12 +46,21 @@ export default stampit({

this._messageId = 0

const handleMessage = (msg, origin) => {
const handleMessage = async (msg, origin) => {
if (!msg || !msg.jsonrpc || msg.jsonrpc !== '2.0' || !msg.method) {
throw new InvalidRpcMessageError(msg)
}
if ((msg.result ?? msg.error) != null) this.processResponse(msg)
else onMessage(msg, origin)
if ((msg.result ?? msg.error) != null) {
this.processResponse(msg)
return
}

// TODO: remove methods as far it is not required in JSON RPC
const response = { id: msg.id, method: msg.method }
const { error, result } = await methods[msg.method](msg.params, origin)
if (error) response.error = error
else response.result = result
if (response.id) this.sendMessage(response, true)
}

const disconnect = (aepp, connection) => {
Expand Down
57 changes: 22 additions & 35 deletions src/utils/aepp-wallet-communication/rpc/wallet-rpc.js
Expand Up @@ -14,7 +14,7 @@ import RpcClient from './rpc-client'
import { ERRORS, METHODS, RPC_STATUS, VERSION } from '../schema'
import { ArgumentError, TypeError, UnknownRpcClientError } from '../../errors'
import { isAccountBase } from '../../../account/base'
import { filterObject } from '../../other'
import { filterObject, mapObject } from '../../other'
import { unpackTx } from '../../../tx/builder'

const resolveOnAccount = (addresses, onAccount, opt = {}) => {
Expand All @@ -25,14 +25,11 @@ const resolveOnAccount = (addresses, onAccount, opt = {}) => {
return onAccount
}

const NOTIFICATIONS = {
[METHODS.closeConnection]: async (instance, client, params) => {
const METHOD_HANDLERS = {
[METHODS.closeConnection]: async (callInstance, instance, client, params) => {
client.disconnect(true)
instance.onDisconnect(params, client)
}
}

const REQUESTS = {
},
// Store client info and prepare two fn for each client `connect` and `denyConnection`
// which automatically prepare and send response for that client
[METHODS.connect] (
Expand Down Expand Up @@ -185,29 +182,6 @@ const REQUESTS = {
}
}

const handleMessage = async (instance, client, { id, method, params }, origin) => {
if (!id) {
return NOTIFICATIONS[method](instance, client, params, origin)
}

const callInstance = (methodName, params, accept, deny) => new Promise(resolve => {
instance[methodName](
client,
{
id,
method,
params,
accept: (...args) => resolve(accept(...args)),
deny: (...args) => resolve(deny(...args))
},
origin
)
})
const response = await REQUESTS[method](callInstance, instance, client, params)
const { error, result } = response ?? {}
client.sendMessage({ id, method, ...error ? { error } : { result } }, true)
}

/**
* Contain functionality for aepp interaction and managing multiple aepps
* @alias module:@aeternity/aepp-sdk/es/utils/aepp-wallet-communication/rpc/wallet-rpc
Expand Down Expand Up @@ -322,15 +296,28 @@ export default Ae.compose(AccountMultiple, {
// @TODO detect if aepp has some history based on origin????
// if yes use this instance for connection
const id = uuid()
this.rpcClients[id] = RpcClient({
const client = RpcClient({
id,
info: { status: RPC_STATUS.WAITING_FOR_CONNECTION_REQUEST },
connection: clientConnection,
handlers: [
(message, origin) => handleMessage(this, this.rpcClients[id], message, origin),
this.onDisconnect
]
onDisconnect: this.onDisconnect,
methods: mapObject(METHOD_HANDLERS, ([key, value]) => [key, (params, origin) => {
const callInstance = (methodName, params, accept, deny) => new Promise(resolve => {
this[methodName](
client,
{
method: key,
params,
accept: (...args) => resolve(accept(...args)),
deny: (...args) => resolve(deny(...args))
},
origin
)
})
return value(callInstance, this, client, params)
}])
})
this.rpcClients[id] = client
return id
},
/**
Expand Down

0 comments on commit 5f1a007

Please sign in to comment.