Commit 90032235 authored by Bitcoin Please's avatar Bitcoin Please

Refactored assurance pledge building.

parent 703dc148
......@@ -3,11 +3,13 @@ import getAsset from './campaigns/getters/getAsset'
import getCampaign from './campaigns/getters/getCampaign'
import getCampaigns from './campaigns/getters/getCampaigns'
import getFullfillment from './campaigns/getters/getFullfillment'
import getSighashDigest from './campaigns/getters/getSighashDigest'
import getSummary from './campaigns/getters/getSummary'
/* Import modules (actions). */
import addAssurance from './campaigns/actions/addAssurance'
import addPayout from './campaigns/actions/addPayout'
import buildPledgeAuth from './campaigns/actions/buildPledgeAuth'
import updateAsset from './campaigns/actions/updateAsset'
import updateCampaign from './campaigns/actions/updateCampaign'
......@@ -32,6 +34,7 @@ const getters = {
getCampaign,
getCampaigns,
getFullfillment,
getSighashDigest,
getSummary,
}
......@@ -39,6 +42,7 @@ const getters = {
const actions = {
addAssurance,
addPayout,
buildPledgeAuth,
updateAsset,
updateCampaign,
}
......
/* Import modules. */
import moment from 'moment'
import Nito from 'nitojs'
/* Set maximum integer value. */
const INT_MAX = 4294967295 // NOTE: 0xFFFFFFFF | 32-bit max int
/**
* Build Pledge Authorization
*/
const buildPledgeAuth = async ({ getters, rootGetters, dispatch }, _pkg) => {
/* Set coin. */
const coin = _pkg.coin
// console.log('COIN', coin)
/* Set user pledge. */
const userPledge = _pkg.userPledge
// console.log('USER PLEDGE', userPledge)
/* Set platform source. */
const source = _pkg.source
// console.log('PLATFORM SOURCE', source)
/* Validate coin. */
if (!coin.txid || !coin.satoshis) {
return console.error('No UTXO available for pledge.') // eslint-disable-line no-console
}
/* Initialize verification key. */
const verificationKey = Nito.Purse.fromWIF(coin.wif)
// console.log('verificationKey', verificationKey, coin.wif)
/* Set public key. */
const publicKey = verificationKey.publicKey.toString()
// console.log('\nPublic key:', publicKey)
/* Set cash address. */
const cashAddress = Nito.Address.toCashAddress(verificationKey)
// console.log('FLIPSTARTER (pledge address)', cashAddress)
const alias = userPledge.data.alias
// console.log('ALIAS:', alias)
const comment = userPledge.data.comment
// console.log('COMMENT:', comment)
const expires = userPledge.expires
// console.log('EXPIRES:', expires)
/* Set previous transaction hash. */
const previousTransactionHash = Buffer.from(coin.txid, 'hex')
/* Set previous transaction output value. */
const previousTransactionOutputValue = Buffer.from(
Nito.Utils.encodeNumber(coin.satoshis), 'hex')
/* Set previous transaction output index (vout). */
const previousTransactionOutputIndex = Buffer.allocUnsafe(4)
previousTransactionOutputIndex.writeUIntLE(coin.vout, 0, 4)
/* Set input lock script. */
const inputLockScript = Buffer.from(
Nito.Address.toPubKeyHash(cashAddress), 'hex')
/* Request commitment message. */
const verificationMessage = getters.getSighashDigest(
previousTransactionHash,
previousTransactionOutputIndex,
previousTransactionOutputValue,
inputLockScript,
userPledge,
)
// console.log('verificationMessage', verificationMessage.toString('hex'))
/* Sign commitment message. */
const pledgeSig = Nito.Account.sign(verificationMessage, verificationKey)
// console.log('PLEDGE SIGNATURE', pledgeSig.toString())
/* Set previous out transaction hash. */
const previous_output_transaction_hash = coin.txid
/* Set previous output index. */
const previous_output_index = coin.vout
/* Set sequence number. */
const sequence_number = INT_MAX
/* Build unlocking script. */
const unlocking_script =
(pledgeSig.toString().slice(2, 4) === '44' ? '47' : '48') + // FIXME??
pledgeSig.toString() +
'c1' + // NOTE: sigHashType
'21' +
publicKey
// console.log('UNLOCKING SCRIPT:', unlocking_script)
/* Build assurance output. */
const assuranceOutput = {
inputs: [{
previous_output_transaction_hash,
previous_output_index,
sequence_number,
unlocking_script,
}],
data: {
alias,
comment,
},
data_signature: null
}
console.info('Assurance output:', assuranceOutput) // eslint-disable-line no-console
/* Encode assurance pledge. */
const encodedPledge = Buffer
.from(JSON.stringify(assuranceOutput))
.toString('base64')
console.info('Flipstarter encoded pledge (base64):', encodedPledge) // eslint-disable-line no-console
/* Initialize meta. */
let meta = await rootGetters['profile/getMeta']
console.log('MAKE PLEDGE (meta):', meta)
/* Validate metadata. */
// NOTE: Added to schema on 2020.7.27
if (!meta) {
meta = {}
}
/* Validate coins. */
// NOTE: Added to schema on 2020.7.27
if (!meta.coins) {
meta.coins = {}
}
/* Set coin id. */
const coinid = `${coin.txid}:${coin.vout}`
/* Update meta data. */
meta['coins'][coinid] = {
label: alias,
comment,
lock: {
isActive: true,
source,
createdAt: moment().unix(),
expiresAt: expires,
}
}
/* Update metadata. */
const metaUpdate = await dispatch('profile/updateMeta', meta, { root: true })
console.log('FLIPSTARTER (metaUpdate):', metaUpdate)
/* Return encoded pledge. */
return encodedPledge
}
/* Export module. */
export default buildPledgeAuth
/* Import modules. */
import Nito from 'nitojs'
/**
* Assemble Signature Hash Digest
*/
const getSighashDigest = () => (
previousTransactionHash,
previousTransactionOutputIndex,
previousTransactionOutputValue,
inputLockScript,
userPledge,
) => {
/* Initialize an empty array of outpoints. */
const transactionOutpoints = []
/* Initialize value. */
let value = null
/* Set value. */
value = Nito.Utils
.encodeNumber(userPledge.outputs[0].value)
// console.log('Encoded value:', value)
/* Set locking script. */
const locking_script = Nito.Address
.toPubKeyHash(userPledge.outputs[0].address)
// console.log('Campaign (locking_script):', locking_script)
/* Set current output. */
// NOTE: This is the pledge recipient.
// FIXME: Allow multiple pledge recipients.
const thisOutputs = [{ value, locking_script }]
/* Add each output in the current contract. */
for (const currentOutput in thisOutputs) {
// Add the output value.
transactionOutpoints.push(thisOutputs[currentOutput].value)
// Add the output lockscript.
transactionOutpoints.push(
Nito.Utils.varBuf(thisOutputs[currentOutput].locking_script)
)
}
// console.log('Transaction outpoints:', transactionOutpoints)
/* Set version. */
const nVersion = Buffer.from('02000000', 'hex')
/* Set hash previous output. */
const hashPrevouts = Buffer.from(''.padStart(64, '0'), 'hex')
/* Set hash sequence. */
const hashSequence = Buffer.from(''.padStart(64, '0'), 'hex')
/* Set outpoint. */
const outpoint = Buffer.concat([
Nito.Utils.reverseBuffer(previousTransactionHash),
previousTransactionOutputIndex,
])
/* Set script code. */
const scriptCode = Buffer.concat([
Buffer.from('19', 'hex'),
inputLockScript,
])
/* Set (transaction) value. */
value = previousTransactionOutputValue
/* Set sequence. */
const nSequence = Buffer.from('FFFFFFFF', 'hex')
/* Set hash outputs. */
const hashOutputs = Nito.Crypto
.hash(Buffer.concat(transactionOutpoints), 'sha256sha256')
/* Set locktime. */
const nLocktime = Buffer.from('00000000', 'hex')
/* Set signature hash type. */
const sighashType = Buffer.from('c1000000', 'hex')
/* Construct signature hash message. */
const sighashMessage = Buffer.concat([
nVersion,
hashPrevouts,
hashSequence,
outpoint,
scriptCode,
value,
nSequence,
hashOutputs,
nLocktime,
sighashType,
])
// console.log('sighashMessage', sighashMessage.toString('hex'));
/* Create signature hash digest (of message). */
const sighashDigest = Nito.Crypto.hash(sighashMessage, 'sha256sha256')
// console.log('sighashDigest', sighashDigest.toString('hex'));
/* Return signature hash digest. */
return sighashDigest
}
/* Export module. */
export default getSighashDigest
......@@ -3,8 +3,8 @@
*
* Adds new coin details to its respective session.
*/
const addCoin = ({ commit, getters }, _pkg) => {
console.info('Adding new coin...', _pkg) // eslint-disable-line no-console
const addCoin = ({ commit, getters }, _coin) => {
console.info('Adding new coin...', _coin) // eslint-disable-line no-console
/* Request indices. */
const indices = getters.getIndices
......@@ -16,7 +16,7 @@ const addCoin = ({ commit, getters }, _pkg) => {
}
/* Set chain id. */
const chainid = _pkg.chainid
const chainid = _coin.chainid
// console.log('ADD NEW COIN (chainid):', chainid)
/* Increment deposit account. */
......@@ -48,12 +48,11 @@ const addCoin = ({ commit, getters }, _pkg) => {
return
}
/* Set coin. */
const coin = _pkg.coin
// console.log('ADD NEW COIN (coin):', coin)
/* Set coin id. */
const coinid = `${_coin.txid}:${_coin.vout}`
/* Add coin to wallet. */
coins[`${coin.txid}:${coin.vout}`] = coin
coins[coinid] = _coin
/* Commit updated indices`. */
commit('setIndices', indices)
......
......@@ -148,8 +148,15 @@ const updateCoins = async ({ dispatch, getters, rootGetters }) => {
const satoshis = output.satoshis
// console.log('UPDATE COINS (satoshis)', satoshis)
/* Validate satoshis. */
if (satoshis === 0) {
// FIXME: Is it okay to skip zero value outputs??
return
}
/* Set script public key. */
const scriptPubKey = output.script
// console.log('UPDATE COINS (scriptPubKey)', scriptPubKey)
/* Validate script. */
if (!scriptPubKey) {
......@@ -196,26 +203,20 @@ const updateCoins = async ({ dispatch, getters, rootGetters }) => {
txid,
vout: index,
satoshis,
chainid,
wif,
cashAddress: searchAddr,
legacyAddress: Nito.Address.toLegacyAddress(searchAddr),
}
// console.log('UPDATE COINS (coin)', coin)
// const coins = getters.getCoinsBySessionId(sessionId)
// console.log('COINS', sessionId, coins)
/* Set coin id. */
const coinid = `${coin.txid}:${coin.vout}`
/* Validate new coin. */
if (coins && !coins[`${coin.txid}:${coin.vout}`]) {
/* Create coin package. */
const pkg = {
// sessionId,
chainid,
coin,
}
if (coins && !coins[coinid]) {
/* Add new coin. */
dispatch('addCoin', pkg)
dispatch('addCoin', coin)
try {
/* Initialize coins. */
......
This diff is collapsed.
......@@ -293,11 +293,27 @@ export default {
'getAsset',
]),
...mapGetters('profile', [
'getNickname',
]),
...mapGetters('utils', [
'getCategoryDisplay',
'getMarkdown',
]),
/**
* Has Authorization
*/
hasAuth() {
// TODO: Improve authorization scheme.
if (this.getNickname) {
return true
} else {
return false
}
},
/**
* Category
*/
......@@ -767,6 +783,12 @@ export default {
* Add My Support
*/
addMySupport() {
/* Validate user authorization. */
if (!this.hasAuth) {
/* Show error notif. */
return this.toast(['Oops!', 'Please sign in first to add your support', 'error'])
}
/* Hide actions. */
this.showActions = false
......
......@@ -157,6 +157,7 @@ import { mapActions, mapGetters } from 'vuex'
import Nito from 'nitojs'
import numeral from 'numeral'
import QRCode from 'qrcode'
import Swal from 'sweetalert2'
export default {
props: {
......@@ -289,7 +290,6 @@ export default {
const paymentUrl = `${this.pledgeAddress}?amount=${amount}`
QRCode.toString(paymentUrl, params, (err, value) => {
// QRCode.toString(this.getAddress('causes'), params, (err, value) => {
if (err) {
return console.error('QR Code ERROR:', err)
}
......@@ -308,14 +308,22 @@ export default {
'addAssurance',
]),
...mapActions('profile', [
'updateMeta',
]),
...mapActions('utils', [
'setClipboard',
'toast',
]),
...mapActions('wallet', [
'updateCoins',
]),
_setPledgeUSD(_satoshis) {
/* Calculate USD. */
const usd = (_satoshis / 100000000) * this.usd
const usd = parseFloat(_satoshis / 10000000.0) * this.usd
/* Set (formatted) value. */
this.pledgeUSD = numeral(usd).format('$0,0.00')
......@@ -397,10 +405,21 @@ export default {
}
/* Set message. */
const message = `Your pledge has been accepted!`
// const message = ``
/* Display notification. */
this.toast(['Done!', message, 'success'])
// this.toast(['Done!', message, 'success'])
Swal.fire({
title: 'Thank you!',
text: 'Your generous pledge has been successfully accepted!',
icon: 'info',
// showConfirmButton: false,
// allowOutsideClick: false,
// allowEscapeKey: false,
timer: 5000,
timerProgressBar: true,
})
} catch (err) {
console.error(err)
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment