aboutsummaryrefslogtreecommitdiffstats
path: root/app/scripts/lib
diff options
context:
space:
mode:
authorDan Finlay <542863+danfinlay@users.noreply.github.com>2017-10-10 03:18:43 +0800
committerGitHub <noreply@github.com>2017-10-10 03:18:43 +0800
commit7f70c866c3a74fadbc34f9b979902b89bba666f5 (patch)
tree421c1a11d5a7422f0137d898446c628cce398d97 /app/scripts/lib
parent4a4338c1f4669f621fc39d34b06a77f247c7ce65 (diff)
parent53bb4bebb11b355f2655b2be0116005df573e907 (diff)
downloadtangerine-wallet-browser-7f70c866c3a74fadbc34f9b979902b89bba666f5.tar.gz
tangerine-wallet-browser-7f70c866c3a74fadbc34f9b979902b89bba666f5.tar.zst
tangerine-wallet-browser-7f70c866c3a74fadbc34f9b979902b89bba666f5.zip
Merge pull request #2223 from ukstv/master
Add eth_signTypedData handler
Diffstat (limited to 'app/scripts/lib')
-rw-r--r--app/scripts/lib/typed-message-manager.js123
1 files changed, 123 insertions, 0 deletions
diff --git a/app/scripts/lib/typed-message-manager.js b/app/scripts/lib/typed-message-manager.js
new file mode 100644
index 000000000..8b760790e
--- /dev/null
+++ b/app/scripts/lib/typed-message-manager.js
@@ -0,0 +1,123 @@
+const EventEmitter = require('events')
+const ObservableStore = require('obs-store')
+const createId = require('./random-id')
+const assert = require('assert')
+const sigUtil = require('eth-sig-util')
+
+
+module.exports = class TypedMessageManager extends EventEmitter {
+ constructor (opts) {
+ super()
+ this.memStore = new ObservableStore({
+ unapprovedTypedMessages: {},
+ unapprovedTypedMessagesCount: 0,
+ })
+ this.messages = []
+ }
+
+ get unapprovedTypedMessagesCount () {
+ return Object.keys(this.getUnapprovedMsgs()).length
+ }
+
+ getUnapprovedMsgs () {
+ return this.messages.filter(msg => msg.status === 'unapproved')
+ .reduce((result, msg) => { result[msg.id] = msg; return result }, {})
+ }
+
+ addUnapprovedMessage (msgParams) {
+ this.validateParams(msgParams)
+
+ log.debug(`TypedMessageManager addUnapprovedMessage: ${JSON.stringify(msgParams)}`)
+ // create txData obj with parameters and meta data
+ var time = (new Date()).getTime()
+ var msgId = createId()
+ var msgData = {
+ id: msgId,
+ msgParams: msgParams,
+ time: time,
+ status: 'unapproved',
+ type: 'eth_signTypedData',
+ }
+ this.addMsg(msgData)
+
+ // signal update
+ this.emit('update')
+ return msgId
+ }
+
+ validateParams (params) {
+ assert.equal(typeof params, 'object', 'Params should ben an object.')
+ assert.ok('data' in params, 'Params must include a data field.')
+ assert.ok('from' in params, 'Params must include a from field.')
+ assert.ok(Array.isArray(params.data), 'Data should be an array.')
+ assert.equal(typeof params.from, 'string', 'From field must be a string.')
+ assert.doesNotThrow(() => {
+ sigUtil.typedSignatureHash(params.data)
+ }, 'Expected EIP712 typed data')
+ }
+
+ addMsg (msg) {
+ this.messages.push(msg)
+ this._saveMsgList()
+ }
+
+ getMsg (msgId) {
+ return this.messages.find(msg => msg.id === msgId)
+ }
+
+ approveMessage (msgParams) {
+ this.setMsgStatusApproved(msgParams.metamaskId)
+ return this.prepMsgForSigning(msgParams)
+ }
+
+ setMsgStatusApproved (msgId) {
+ this._setMsgStatus(msgId, 'approved')
+ }
+
+ setMsgStatusSigned (msgId, rawSig) {
+ const msg = this.getMsg(msgId)
+ msg.rawSig = rawSig
+ this._updateMsg(msg)
+ this._setMsgStatus(msgId, 'signed')
+ }
+
+ prepMsgForSigning (msgParams) {
+ delete msgParams.metamaskId
+ return Promise.resolve(msgParams)
+ }
+
+ rejectMsg (msgId) {
+ this._setMsgStatus(msgId, 'rejected')
+ }
+
+ //
+ // PRIVATE METHODS
+ //
+
+ _setMsgStatus (msgId, status) {
+ const msg = this.getMsg(msgId)
+ if (!msg) throw new Error('TypedMessageManager - Message not found for id: "${msgId}".')
+ msg.status = status
+ this._updateMsg(msg)
+ this.emit(`${msgId}:${status}`, msg)
+ if (status === 'rejected' || status === 'signed') {
+ this.emit(`${msgId}:finished`, msg)
+ }
+ }
+
+ _updateMsg (msg) {
+ const index = this.messages.findIndex((message) => message.id === msg.id)
+ if (index !== -1) {
+ this.messages[index] = msg
+ }
+ this._saveMsgList()
+ }
+
+ _saveMsgList () {
+ const unapprovedTypedMessages = this.getUnapprovedMsgs()
+ const unapprovedTypedMessagesCount = Object.keys(unapprovedTypedMessages).length
+ this.memStore.updateState({ unapprovedTypedMessages, unapprovedTypedMessagesCount })
+ this.emit('updateBadge')
+ }
+
+}