Skip to content

Instantly share code, notes, and snippets.

@cellog
Created February 20, 2019 18:16
Show Gist options
  • Save cellog/94bbed0b5c9da39482806ddb6fe015d9 to your computer and use it in GitHub Desktop.
Save cellog/94bbed0b5c9da39482806ddb6fe015d9 to your computer and use it in GitHub Desktop.
Version 1 - key purchase
export function sendNewKeyPurchaseTransaction({
to,
from,
data,
value,
gas,
wallet,
newTransaction,
mineTransaction,
failTransaction,
setHash,
setError,
}) {
const transaction = wallet.eth.sendTransaction({
to,
from,
value,
data,
gas,
})
transaction
.once('transactionHash', hash => {
setHash(hash)
newTransaction()
})
.on('confirmation', confirmationNumber => {
mineTransaction(confirmationNumber)
})
.on('error', error => {
failTransaction()
})
.once('transactionHash', hash => {
setHash(hash)
})
.on('error', error => setError(error))
}
import { useState, useReducer } from 'react'
import Web3Utils from 'web3-utils'
import LockContract from '../artifacts/contracts/PublicLock.json'
import useAccount from './web3/useAccount'
import { TRANSACTION_TYPES } from '../constants'
import useWallet from './web3/useWallet'
import useConfig from './utils/useConfig'
import {
sendNewKeyPurchaseTransaction,
} from './asyncActions/keyPurchaseTransactions'
export function handleTransactionUpdates(transaction, update) {
const { type, info } = update
// triggered on key purchase, prior to sending the transaction, after retrieving the hash
if (type === 'new') {
const { lock, account } = info
return {
...transaction,
lock,
account,
status: 'pending',
type: TRANSACTION_TYPES.KEY_PURCHASE,
confirmations: 0,
asOf: Number.MAX_SAFE_INTEGER, // Assign the largest block number for sorting purposes
}
}
// triggered when we get the transaction hash before the transaction is sent to the miners
if (type === 'hash') {
const { hash } = info
return { ...transaction, hash }
}
// transaction has been mined, is on the chain, and a new block has been mined
if (type === 'mined') {
const { confirmations, requiredConfirmations } = info
return {
...transaction,
status: confirmations < requiredConfirmations ? 'confirming' : 'mined',
confirmations,
}
}
// transaction receipt showed the transaction was not propagated for some error
if (type === 'failed') {
return {
...transaction,
status: 'failed',
}
}
return transaction
}
export default function useKeyPurchaseTransaction(window, lock) {
const wallet = useWallet()
const [error, setError] = useState()
const { requiredConfirmations } = useConfig()
const [transaction, updateTransaction] = useReducer(
handleTransactionUpdates,
{ status: 'inactive', confirmations: 0 }
)
const { account } = useAccount(window)
// transaction reducer action creators
const setHash = hash => updateTransaction({ type: 'hash', info: { hash } })
const newTransaction = () =>
updateTransaction({ type: 'new', info: { lock: lock.address, account } })
const mineTransaction = confirmations =>
updateTransaction({
type: 'mined',
info: { confirmations, requiredConfirmations },
})
const failTransaction = () => updateTransaction({ type: 'fail' })
const purchaseKey = () => {
if (!lock || !account || transaction.status !== 'inactive') return
// when we enable transfer of existing keys, data will be the existing key's data
const data = ''
const lockContract = new wallet.eth.Contract(LockContract.abi, lock.address)
const abi = lockContract.methods
// when we enable transfer of existing keys, the account will be the existing key's owner
.purchaseFor(account, Web3Utils.utf8ToHex(data || ''))
.encodeABI()
sendNewKeyPurchaseTransaction({
wallet,
to: lock.address,
from: account,
data: abi,
gas: 1000000,
value: Web3Utils.toWei(lock.keyPrice, 'ether'),
contract: LockContract,
newTransaction,
mineTransaction,
failTransaction,
setHash,
setError,
})
}
if (error) throw error
// updateTransaction is returned strictly for testing purposes
return { purchaseKey, transaction, updateTransaction }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment