diff --git a/src/utils/aepp-wallet-communication/rpc/rpc-client.js b/src/utils/aepp-wallet-communication/rpc/rpc-client.js index cdb061bb86..9713a41fd8 100644 --- a/src/utils/aepp-wallet-communication/rpc/rpc-client.js +++ b/src/utils/aepp-wallet-communication/rpc/rpc-client.js @@ -8,7 +8,7 @@ */ import stampit from '@stamp/it' -import { METHODS, RpcError, RpcInternalError } from '../schema' +import { RpcError, RpcInternalError } from '../schema' import { InvalidRpcMessageError, MissingCallbackError } from '../../errors' /** @@ -30,11 +30,6 @@ export default stampit({ // [msg.id]: { resolve, reject } // } this.callbacks = {} - // { - // connected: { [pub]: {...meta} }, - // current: { [pub]: {...meta} } - // } - this.accounts = {} this._messageId = 0 @@ -59,26 +54,6 @@ export default stampit({ connection.connect(handleMessage, onDisconnect) }, - propertyDescriptors: { - currentAccount: { - enumerable: true, - configurable: false, - get () { - return this.isHasAccounts() - ? Object.keys(this.accounts.current)[0] - : undefined - } - }, - addresses: { - enumerable: true, - configurable: false, - get () { - return this.isHasAccounts() - ? [...Object.keys(this.accounts.current), ...Object.keys(this.accounts.connected)] - : [] - } - } - }, methods: { _sendMessage ({ id, method, params, result, error }, isNotificationOrResponse = false) { if (!isNotificationOrResponse) this._messageId += 1 @@ -96,43 +71,6 @@ export default stampit({ }) return id }, - isHasAccounts () { - return typeof this.accounts === 'object' && - typeof this.accounts.connected === 'object' && - typeof this.accounts.current === 'object' - }, - /** - * Check if aepp has access to account - * @function hasAccessToAccount - * @instance - * @rtype (address: String) => Boolean - * @param {String} address Account address - * @return {Boolean} is connected - */ - hasAccessToAccount (address) { - return !!address && this.addresses.find(a => a === address) - }, - /** - * Get selected account - * @function getCurrentAccount - * @instance - * @rtype ({ onAccount } = {}) => String - * @param {Object} options Options - * @return {String} - */ - getCurrentAccount ({ onAccount } = {}) { - return onAccount || Object.keys(this.accounts.current)[0] - }, - /** - * Update accounts and sent `update.address` notification to AEPP - * @param {{ current: Object, connected: Object }} accounts Current and connected accounts - * @param {Object} [options] - * @param {Boolean} [options.forceNotification] Don't sent update notification to AEPP - */ - setAccounts (accounts, { forceNotification } = {}) { - this.accounts = accounts - if (!forceNotification) this.notify(METHODS.updateAddress, this.accounts) - }, /** * Make a request * @function request diff --git a/src/utils/aepp-wallet-communication/rpc/wallet-rpc.js b/src/utils/aepp-wallet-communication/rpc/wallet-rpc.js index 721cb35b34..23f721b56f 100644 --- a/src/utils/aepp-wallet-communication/rpc/wallet-rpc.js +++ b/src/utils/aepp-wallet-communication/rpc/wallet-rpc.js @@ -17,7 +17,7 @@ import { RpcNotAuthorizeError, RpcPermissionDenyError, RpcUnsupportedProtocolError, SUBSCRIPTION_TYPES } from '../schema' import { ArgumentError, UnknownRpcClientError } from '../../errors' -import { filterObject, mapObject } from '../../other' +import { mapObject } from '../../other' import { unpackTx } from '../../../tx/builder' const METHOD_HANDLERS = { @@ -45,8 +45,7 @@ const METHOD_HANDLERS = { async [METHODS.subscribeAddress] (callInstance, instance, client, clientInfo, { type, value }) { if (!instance._isRpcClientConnected(client.id)) throw new RpcNotAuthorizeError() - const accounts = await callInstance('onSubscription', { type, value }) - const clientAccounts = accounts || instance.getAccounts() + await callInstance('onSubscription', { type, value }) switch (type) { case SUBSCRIPTION_TYPES.subscribe: @@ -57,22 +56,22 @@ const METHOD_HANDLERS = { break } - client.setAccounts(clientAccounts, { forceNotification: true }) return { subscription: Array.from(clientInfo.addressSubscription), - address: clientAccounts + address: instance.getAccounts() } }, async [METHODS.address] (callInstance, instance, client) { if (!instance._isRpcClientSubscribed(client.id)) throw new RpcNotAuthorizeError() - - const accounts = await callInstance('onAskAccounts') ?? client.accounts - return [...Object.keys(accounts.current), ...Object.keys(accounts.connected)] + await callInstance('onAskAccounts') + return instance.addresses() }, - async [METHODS.sign] (callInstance, instance, client, clientInfo, { tx, onAccount, returnSigned }) { - onAccount ??= client.currentAccount + async [METHODS.sign] ( + callInstance, instance, client, clientInfo, { tx, onAccount, returnSigned } + ) { if (!instance._isRpcClientConnected(client.id)) throw new RpcNotAuthorizeError() - if (!client.hasAccessToAccount(onAccount)) throw new RpcPermissionDenyError(onAccount) + onAccount ??= await instance.address() + if (!instance.addresses().includes(onAccount)) throw new RpcPermissionDenyError(onAccount) const overrides = await callInstance( 'onSign', { tx, returnSigned, onAccount, txObject: unpackTx(tx) } @@ -92,8 +91,8 @@ const METHOD_HANDLERS = { }, async [METHODS.signMessage] (callInstance, instance, client, clientInfo, { message, onAccount }) { if (!instance._isRpcClientConnected(client.id)) throw new RpcNotAuthorizeError() - onAccount ??= client.currentAccount - if (!client.hasAccessToAccount(onAccount)) throw new RpcPermissionDenyError(onAccount) + onAccount ??= await instance.address() + if (!instance.addresses().includes(onAccount)) throw new RpcPermissionDenyError(onAccount) const overrides = await callInstance('onMessageSign', { message, onAccount }) onAccount = overrides?.onAccount ?? onAccount @@ -142,35 +141,17 @@ export default Ae.compose(AccountMultiple, { const _addAccount = this.addAccount.bind(this) const _selectNode = this.selectNode.bind(this) + const pushAccountsToApps = () => Object.keys(this.rpcClients) + .filter(clientId => this._isRpcClientSubscribed(clientId)) + .map(clientId => this.rpcClients[clientId]) + .forEach(client => client.notify(METHODS.updateAddress, this.getAccounts())) this.selectAccount = (address) => { _selectAccount(address) - Object.keys(this.rpcClients) - .filter(clientId => { - return this._isRpcClientSubscribed(clientId) && - this.rpcClients[clientId].hasAccessToAccount(address) - }) - .map(clientId => this.rpcClients[clientId]) - .forEach(client => client.setAccounts({ - current: { [address]: {} }, - connected: { - ...client.accounts.current, - ...filterObject(client.accounts.connected, ([k]) => k !== address) - } - })) + pushAccountsToApps() } this.addAccount = async (account, { select } = {}) => { await _addAccount(account, { select }) - const address = await account.address() - Object.keys(this.rpcClients) - .filter(clientId => this._isRpcClientSubscribed(clientId)) - .map(clientId => this.rpcClients[clientId]) - .forEach(client => client.setAccounts({ - current: { ...select ? { [address]: {} } : client.accounts.current }, - connected: { - ...select ? client.accounts.current : { [address]: {} }, - ...client.accounts.connected - } - })) + pushAccountsToApps() } this.selectNode = (name) => { _selectNode(name) @@ -200,7 +181,6 @@ export default Ae.compose(AccountMultiple, { const clientInfo = this._rpcClientsInfo[clientId] if (client == null || clientInfo == null) throw new UnknownRpcClientError(clientId) client.connection.disconnect() - client.accounts = {} clientInfo.status = RPC_STATUS.DISCONNECTED clientInfo.addressSubscription = new Set() }, diff --git a/test/integration/rpc.js b/test/integration/rpc.js index 7e271b3ef9..9ef162fc67 100644 --- a/test/integration/rpc.js +++ b/test/integration/rpc.js @@ -68,7 +68,9 @@ describe('Aepp<->Wallet', function () { await spendPromise wallet = await RpcWallet({ compilerUrl, - accounts: [MemoryAccount({ keypair: account })], + accounts: [ + MemoryAccount({ keypair: account }), MemoryAccount({ keypair: generateKeyPair() }) + ], nodes: [{ name: 'local', instance: node }], id: 'test', type: WALLET_TYPE.window, @@ -150,13 +152,7 @@ describe('Aepp<->Wallet', function () { }) it('Subscribe to address: wallet accept', async () => { - const accounts = { - connected: { [keypair.publicKey]: {} }, - current: wallet.addresses().reduce((acc, v) => ({ ...acc, [v]: {} }), {}) - } - wallet.onSubscription = () => { - return accounts - } + wallet.onSubscription = () => {} await aepp.subscribeAddress('subscribe', 'connected') await aepp.subscribeAddress('unsubscribe', 'connected') const subscriptionResponse = await aepp.subscribeAddress('subscribe', 'connected') @@ -230,7 +226,7 @@ describe('Aepp<->Wallet', function () { amount: 0, payload: 'zerospend' }) - await expect(aepp.signTransaction(tx, { onAccount: keypair.publicKey })) + await expect(aepp.signTransaction(tx, { onAccount: account.publicKey })) .to.be.rejectedWith('The peer failed to execute your request due to unknown error') }) @@ -299,21 +295,13 @@ describe('Aepp<->Wallet', function () { isValid.should.be.equal(true) }) - it('Sign message using account not from sdk instance: do not provide account', async () => { - wallet.onMessageSign = () => {} - const onAccount = aepp.addresses()[1] - await expect(aepp.signMessage('test', { onAccount })).to.be.eventually - .rejectedWith('The peer failed to execute your request due to unknown error') - .with.property('code', 12) - }) - - it('Sign message using account not from sdk instance', async () => { + it('Sign message using custom account', async () => { wallet.onMessageSign = (aepp, action) => { - if (action.params.onAccount === keypair.publicKey) { - return { onAccount: MemoryAccount({ keypair }) } + if (action.params.onAccount === account.publicKey) { + return { onAccount: MemoryAccount({ keypair: account }) } } } - const onAccount = keypair.publicKey + const onAccount = account.publicKey const messageSig = await aepp.signMessage('test', { onAccount }) messageSig.should.be.instanceof(Buffer) const isValid = await aepp.verifyMessage('test', messageSig, { onAccount }) @@ -476,7 +464,7 @@ describe('Aepp<->Wallet', function () { subscriptionResponse.address.current.should.be.an('object') Object.keys(subscriptionResponse.address.current)[0].should.be.equal(account.publicKey) subscriptionResponse.address.connected.should.be.an('object') - Object.keys(subscriptionResponse.address.connected).length.should.be.equal(1) + Object.keys(subscriptionResponse.address.connected).length.should.be.equal(0) }) it('Sign by wallet and broadcast transaction by aepp ', async () => {