import * as vaultSecp256k1 from '@zippie/vault-api/src/secp256k1'
import vaultweb3 from '@zippie/vault-web3-provider'
import * as constants from './util/constants'
import { fetchDataFromPermaStore } from './util/zippieBackend'
import { initDatabase } from './util/zippieDatabase'
import {
updateSubWallet,
fetchBlankCheck,
claimBlankCheckNoPending,
initZippieMultisigAccounts,
getTokenBalanceFromWeb3,
initZippieMultisigContract,
initErc20TokenContract,
createBlankCheck,
addNewMultisigAccount,
getMultisigAccountForToken
} from './util/zippieWallet'
import Web3 from 'web3'
/** @module zippie-api/Wallet */
const WALLET_SERVICE_TAG = 'wallet'
var context
export async function init (vault) {
context = vault
var provider = vaultweb3.init(vault, vaultSecp256k1, constants.web3Parameters)
window.web3 = new Web3(provider)
const zippieMultisigContract = initZippieMultisigContract(vault)
window.zippieMultisigContract = zippieMultisigContract
const erc20TokenContract = initErc20TokenContract()
window.erc20TokenContract = erc20TokenContract
await initDatabase()
const address = await vaultweb3.addAccount(constants.signerAccountDerive)
window.zippieSignerAddress = address
initZippieMultisigAccounts(vault)
const ipc = vault.ipc.createService(WALLET_SERVICE_TAG)
ipc.addReceiver(createAccountForToken, 'createAccountForToken')
ipc.addReceiver(getAccountForToken, 'getAccountForToken')
ipc.addReceiver(getTokenBalance, 'getTokenBalance')
ipc.addReceiver(getPaymentInfo, 'getPaymentInfo')
ipc.addReceiver(createPayment, 'createPayment')
ipc.addReceiver(redeemPayment, 'redeemPayment')
// DEPRECATED
ipc.addReceiver(function (token, amount, message) {
console.warn('[WAPI]: DEPRECATED API CALL USAGE')
return createPayment(token, amount, message)
}, 'createPaymentLink')
// DEPRECATED
ipc.addReceiver(function (payment) {
console.warn('[WAPI]: DEPRECATED API CALL USAGE')
return redeemPayment(payment)
}, 'claimPayment')
ipc.ready()
}
/**
* Create a whitelisted multisig account for a particular ERC20 token
* for use by this application.
*
* @param {string} token ERC20 Token contract address
* @returns {Promise} Resolves with WalletAccount on success
*/
async function createAccountForToken (token) {
let account = await getMultisigAccountForToken(token)
if(account === undefined) {
account = await addNewMultisigAccount(context, token, this.origin)
console.info('[WAPI createAccountForToken - [New Account] ', account)
}
console.info('[WAPI] createAccountForToken', account)
return account
}
/**
* Get a users' ERC20 multisig account associated with a specific token
* contract address.
* @param {*} address ERC20 Token contract address
* @returns {Promise} Resolves with WalletAccount on success
*/
async function getAccountForToken (address) {
console.info('[WAPI] getAccountForToken - ', address)
let data = await fetchDataFromPermaStore(context, constants.permaStoreMultisigAccountsDerive)
if(data !== undefined && address in data) {
console.info('[WAPI] getAccountForToken', data)
var tokenAccount = data[address][0].accountAddress
}
console.info('[WAPI] getAccountForToken - ', tokenAccount)
return tokenAccount || null
}
/**
* Get the users' balance for specified Token.
* @param {*} token ERC20 Token contract address
* @returns {Promise} Resolves with account balance in BN string format.
*/
async function getTokenBalance (token) {
let walletInfo = await updateSubWallet(context, token)
let data = await getTokenBalanceFromWeb3(token, walletInfo.accountAddress)
console.info('[WAPI]: getTokenBalance - ', data)
return data
}
/**
* Downloads and decrypts payment object from IPFS and returns payment object.
* @param {string} ipfshash IPFS content address and decryption key tuple.
* @returns {Promise} Resolves PaymentObject on success.
*/
async function getPaymentInfo (ipfshash) {
let data = await fetchBlankCheck(ipfshash)
console.info('[WAPI] fetchBlankCheck ', data)
return data
}
/**
* Creates a new payment object and stores encrypted into IPFS.
* @param {string} token ERC20 Token contract address
* @param {string} amount Amount to send, in wei
* @param {string} message Customisable user message
* @returns {Promise} Resolves to IPFS hash and key tuple on success.
*/
async function createPayment (token, amount, message = '') {
console.info('[WAPI] createPaymentLink ', token, amount, message)
// TODO: check token
// TODO: Any further validation?
let multisig = await getMultisigAccountForToken(token)
console.info('[WAPI] createPaymentLink ', multisig)
if(this.origin !== multisig.dappUri) {
console.warn('[WAPI]: Permission denied, origin has to be:', multisig.dappUri)
return { error: 'Permission Denied' }
}
return await createBlankCheck(context, multisig, amount, message)
}
/**
* Redeems a PaymentObject payment into the appropriate users' wallet account.
* @param {PaymentObject} payment
* @returns {Promise} Resolves on success.
*/
async function redeemPayment (payment) {
let data = await claimBlankCheckNoPending(context, payment, this.origin)
console.info('[WAPI]: claimBlankCheck - ', data)
return data
}