Commit 0d794e19 authored by Bitcoin Please's avatar Bitcoin Please
Browse files

Lots of refactoring, plus added encrypted metadata backup to cloud.

parent 73af60ac
pragma cashscript ^0.4.0;
/**
* Mecenas Oracle (v1 - Fixed Blocks)
/*******************************************************************************
*
* (last updated: 2020.7.29)
* Copyright (c) 2020 Bitcoin Cash Please
* Released under the MIT License.
*
* This contract enforces a fiat market price for daily payouts to the
* Mecenas Oracle (Fixed Blocks)
*
* Version 20.8.3
*
* https://bchplease.org
* support@bchplease.org
*
* This contract enforces a fiat-based market price for daily payouts to the
* contract's receipient.
*
* recipient : party whom will will receive the payouts
......
pragma cashscript ^0.4.0;
/**
* Mecenas Oracle (v2 - Streaming Blocks)
/*******************************************************************************
*
* Copyright (c) 2020 Bitcoin Cash Please
* Released under the MIT License.
*
* Mecenas Oracle (Streaming Blocks)
*
* Version 20.8.3
*
* https://bchplease.org
* support@bchplease.org
*
* This contract enforces a specific market price for payouts to the
* contract's receipient.
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Asset
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Asset
......
......@@ -5,6 +5,7 @@
import getAvatar from './profile/getters/getAvatar'
import getEmail from './profile/getters/getEmail'
import getMasterSeed from './profile/getters/getMasterSeed'
import getMeta from './profile/getters/getMeta'
import getNickname from './profile/getters/getNickname'
import getSignedMessage from './profile/getters/getSignedMessage'
......@@ -13,12 +14,14 @@ import destroyProfile from './profile/actions/destroyProfile'
import initProfile from './profile/actions/initProfile'
import updateEmail from './profile/actions/updateEmail'
import updateMasterSeed from './profile/actions/updateMasterSeed'
import updateMeta from './profile/actions/updateMeta'
import updateNickname from './profile/actions/updateNickname'
/* Import modules (mutations). */
import setEmail from './profile/mutations/setEmail'
import setEmptyProfile from './profile/mutations/setEmptyProfile'
import setMasterSeed from './profile/mutations/setMasterSeed'
import setMeta from './profile/mutations/setMeta'
import setNickname from './profile/mutations/setNickname'
/* Initialize state. */
......@@ -38,6 +41,22 @@ const state = {
*/
masterSeed: null,
/**
* Metadata
*
* Used to store (user-defined) data for:
* 1. Individual accounts
* 2. Individual unspent transaction outputs (UXTOs)
*
* NOTE: Metadata MUST be used sparingly, to avoid data storage bloat;
* and should be deleted when no longer needed.
*
* TODO: Allow this data to be stored on-chain using:
* 1. Bitcoin Files Protocol (BFP) (https://bitcoinfiles.com/)
* 2. Telr Locker (https://locker.telr.io)
*/
meta: null,
/**
* Nickname
*
......@@ -54,6 +73,7 @@ const getters = {
getAvatar,
getEmail,
getMasterSeed,
getMeta,
getNickname,
getSignedMessage,
}
......@@ -64,6 +84,7 @@ const actions = {
initProfile,
updateEmail,
updateMasterSeed,
updateMeta,
updateNickname,
}
......@@ -72,6 +93,7 @@ const mutations = {
setEmail,
setEmptyProfile,
setMasterSeed, // WARNING: This is the highest risk attack vector.
setMeta,
setNickname,
}
......
/* Import modules. */
const crypto = require('crypto')
import superagent from 'superagent'
/**
* Encrypt
*
* Uses AES-256-CBC to encrypt a plaintext string.
*/
function _encrypt(_plaintext, _key, _algo = 'aes-256-cbc') {
/* Generate initilization vector. */
const iv = crypto.randomBytes(16)
/* Initialize cipher. */
const cipher = crypto.createCipheriv(_algo, Buffer.from(_key), iv)
/* Update cipher. */
let encrypted = cipher.update(_plaintext)
/* Finalize cipher. */
encrypted = Buffer.concat([encrypted, cipher.final()])
/* Return encrypted package. */
return {
iv: iv.toString('hex'),
body: encrypted.toString('hex')
}
}
/**
* Update Metadata
*
* Metadata is used to store details about addresses.
*/
const updateMeta = async ({ commit, getters }, _meta) => {
/* Commit metadata. */
commit('setMeta', _meta)
/**
* Encrypt Metadata
*
* For convenience reasons, all metadata is stored in the platform's
* data repository. For privacy reasons, ALL metadata is first encrypted
* with a key ONLY know to this profile.
*/
const encrypted = _encrypt(JSON.stringify(_meta))
console.log('UPDATE META (encrypted):', encrypted)
const signedPkg = getters.getSignedMessage(encrypted)
// console.log('SIGNED PACKAGE', signedPkg)
/* Set api target. */
const target = 'http://localhost:6767/v1/meta'
// const target = 'https://api.causes.cash/v1/meta'
const result = await superagent
.post(target)
.send(signedPkg)
console.log('RESULT', result)
}
/* Export module. */
export default updateMeta
/**
*
* {
* "addresses": [{
......@@ -55,10 +117,3 @@
* }]
* }
*/
const updateMeta = ({ commit }, _meta) => {
/* Commit metadata. */
commit('setMeta', _meta)
}
/* Export module. */
export default updateMeta
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Email Address
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Master Seed
......
/* Import modules. */
import msgpack from 'msgpack-lite'
import Nito from 'nitojs'
import superagent from 'superagent'
/**
* Decrypt
*
* Recovers the plaintext string from AES-256-CBC encrypted message.
*/
function _decrypt(_encrypted, _key) {
/* Set initilization vector. */
const iv = Buffer.from(_encrypted.iv, 'hex')
const encryptedText = Buffer.from(_encrypted.body, 'hex')
const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(_key), iv)
let decrypted = decipher.update(encryptedText)
decrypted = Buffer.concat([decrypted, decipher.final()])
/* Return decrypted string. */
return decrypted.toString()
}
/**
* Get Metadata
*/
const getMeta = async (state, getters, rootState, rootGetters) => {
/* Validate state. */
if (!state || !state.meta) {
// TODO: Attempt to retrieve metadata from cloud.
/* Set profile index. */
const profileIndex = 0
// console.log('GET ADDRESS (profileIndex):', profileIndex)
/* Set chain. */
const chain = 0 // receiving account
/* Set derivation path. */
const path = rootGetters['wallet/getDerivationPath'](chain, profileIndex)
// console.log('GET ADDRESS (path)', path)
/* Initialize HD node. */
const hdNode = rootGetters['wallet/getHDNode']
/* Initialize child node. */
const childNode = hdNode.deriveChild(path)
/* Set (profile) address. */
const address = Nito.Address.toCashAddress(childNode)
// console.log('GET SIGNED MESSAGE (address):', address)
/* Set target. */
const target = `http://localhost:6767/v1/meta/${address}`
// const target = `https://api.causes.cash/v1/meta/${ownerAddress}`
/* Set contract path. */
const response = await superagent.get(target)
console.log('GET META', response)
console.log('GET META (decrypted)', _decrypt(response))
return null
} else {
/* Return metadata. */
return msgpack.decode(Buffer.from(state.meta, 'hex'))
}
}
/* Export module. */
export default getMeta
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Nickname
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Email Address
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Metadata
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Nickname
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Asset Source
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Flags
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Locale
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Assets
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Flags
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Locale
......
......@@ -8,7 +8,6 @@ import getDustAmount from './wallet/getters/getDustAmount'
import getHDNode from './wallet/getters/getHDNode'
import getHistory from './wallet/getters/getHistory'
import getMasterSeed from './wallet/getters/getMasterSeed'
import getMeta from './wallet/getters/getMeta'
import getMnemonic from './wallet/getters/getMnemonic'
import getWallet from './wallet/getters/getWallet'
......@@ -18,32 +17,14 @@ import destroyWallet from './wallet/actions/destroyWallet'
import initWallet from './wallet/actions/initWallet'
import updateCoin from './wallet/actions/updateCoin'
import updateCoins from './wallet/actions/updateCoins'
import updateMeta from './wallet/actions/updateMeta'
import updateOutbox from './wallet/actions/updateOutbox'
/* Import modules (mutations). */
import setEmptyWallet from './wallet/mutations/setEmptyWallet'
import setMeta from './wallet/mutations/setMeta'
import setWallet from './wallet/mutations/setWallet'
/* Initialize state. */
const state = {
/**
* Metadata
*
* Used to store (user-defined) data for:
* 1. Individual accounts
* 2. Individual unspent transaction outputs (UXTOs)
*
* NOTE: Metadata MUST be used sparingly, to avoid data storage bloat;
* and should be deleted when no longer needed.
*
* TODO: Allow this data to be stored on-chain using:
* 1. Bitcoin Files Protocol (BFP) (https://bitcoinfiles.com/)
* 2. Telr Locker (https://locker.telr.io)
*/
meta: null,
/**
* Coins waiting to be sent out from the wallet.
*/
......@@ -75,7 +56,6 @@ const getters = {
getHDNode,
getHistory,
getMasterSeed,
getMeta,
getMnemonic,
getWallet,
}
......@@ -87,14 +67,12 @@ const actions = {
initWallet,
updateCoin,
updateCoins,
updateMeta,
updateOutbox,
}
/* Mutations. */
const mutations = {
setEmptyWallet,
setMeta,
setWallet,
}
......
......@@ -59,7 +59,7 @@ const updateStatus = (_coins, _meta, dispatch) => {
/**
* Update Coins (for ALL sessions)
*/
const updateCoins = async ({ dispatch, getters }) => {
const updateCoins = async ({ dispatch, getters, rootGetters }) => {
/* Set wallet. */
const wallet = getters.getWallet
// console.log('UPDATE COINS (wallet)', wallet)
......@@ -74,7 +74,7 @@ const updateCoins = async ({ dispatch, getters }) => {
// console.log('UPDATE COINS (coins)', coins)
/* Retrieve metadata. */
const meta = getters.getMeta
const meta = await rootGetters['profile/getMeta']
console.log('UPDATE COINS (meta):', meta)
/* Update status. */
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
const Nito = require('nitojs')
/**
......
/* Import modules. */
const msgpack = require('msgpack-lite')
/**
* Get Metadata
*/
const getMeta = (state) => {
/* Validate state. */
if (!state || !state.meta) {
return null
}
/* Initialize metadata. */
const meta = msgpack.decode(Buffer.from(state.meta, 'hex'))
/* Return metadata. */
return meta
}
/* Export module. */
export default getMeta
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Outbox
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Get Wallet
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Outbox
......
/* Import modules. */
const msgpack = require('msgpack-lite')
import msgpack from 'msgpack-lite'
/**
* Set Wallet
......
......@@ -170,12 +170,15 @@ export default {
}
},
computed: {
...mapGetters('profile', [
'getMeta',
]),
...mapGetters('wallet', [
'getAddress',
'getBalance',
'getDerivationPath',
'getHDNode',
'getMeta',
'getWallet',
]),
......@@ -475,7 +478,7 @@ export default {
// console.log('WALLET', wallet)
/* Initialize meta. */
const meta = this.getMeta
const meta = await this.getMeta
console.log('META', meta)
/* Set accounts. */
......@@ -594,7 +597,7 @@ export default {
/**
* Make Pledge
*/
makePledge(_coin) {
async makePledge(_coin) {
/* Initialize verification key. */
const verificationKey = Nito.Purse.fromWIF(_coin.wif)
console.log('verificationKey', verificationKey, _coin.wif)
......@@ -671,7 +674,7 @@ export default {
this.pledgeAuth = encodedPledge
/* Initialize meta. */
const meta = this.getMeta
const meta = await this.getMeta
console.log('META', meta)
/* Set coin id. */
......
......@@ -218,6 +218,10 @@ export default {
'getHelp',
]),
...mapGetters('profile', [
'getMeta',
]),
...mapGetters('utils', [
'getFormattedValue',
]),
......@@ -225,7 +229,6 @@ export default {
...mapGetters('wallet', [
'getAddress',
'getBalance',
'getMeta',
'getMnemonic',
'getWallet',
]),
......@@ -560,9 +563,9 @@ export default {
/**
* Unlock
*/
unlock(_coinid) {
async unlock(_coinid) {
/* Request metadata. */
const meta = this.getMeta
const meta = await this.getMeta
/* Initialize coins. */
const coins = this.getWallet.coins
......
......@@ -164,8 +164,11 @@ import { mapActions, mapGetters } from 'vuex'