From 16e04b0f90f76be3838318d490a4eb2cc88ad6d6 Mon Sep 17 00:00:00 2001 From: Tim Olson <> Date: Wed, 1 Nov 2023 00:33:53 -0400 Subject: [PATCH] withdrawls --- src/blockchain/contract.js | 10 +- src/blockchain/token.js | 44 +++++++ src/blockchain/wallet.js | 113 ++++++++++------- src/components/Blockchain.vue | 34 ++++++ src/components/ConnectWallet.vue | 24 ---- src/components/CopyButton.vue | 11 +- src/components/NeedsProvider.vue | 52 ++++++++ src/components/NeedsQueryHelper.vue | 21 ---- .../{NeedsWallet.vue => NewOrder.vue} | 2 +- src/components/PhoneCard.vue | 9 +- src/components/TimedOrderEntry.vue | 27 +++-- src/components/TokenChoice.vue | 6 +- src/components/TokenRow.vue | 38 ++++-- src/components/Vault.vue | 114 ++++++++++-------- src/components/Withdraw.vue | 64 ++++++++++ src/layouts/default/View.vue | 3 +- src/misc.js | 11 +- src/store/store.js | 25 ++-- src/styles/style.scss | 7 +- src/styles/vars.scss | 12 +- 20 files changed, 438 insertions(+), 189 deletions(-) create mode 100644 src/blockchain/token.js create mode 100644 src/components/Blockchain.vue delete mode 100644 src/components/ConnectWallet.vue create mode 100644 src/components/NeedsProvider.vue delete mode 100644 src/components/NeedsQueryHelper.vue rename src/components/{NeedsWallet.vue => NewOrder.vue} (77%) create mode 100644 src/components/Withdraw.vue diff --git a/src/blockchain/contract.js b/src/blockchain/contract.js index 9f9bfef..6a6268f 100644 --- a/src/blockchain/contract.js +++ b/src/blockchain/contract.js @@ -1,7 +1,6 @@ import {ethers} from "ethers"; import {factoryAbi, queryHelperAbi, vaultAbi} from "@/blockchain/abi.js"; import {useStore} from "@/store/store.js"; -import {provider} from "@/blockchain/wallet.js"; export function vaultAddress( owner, num=0) { @@ -11,7 +10,7 @@ export function vaultAddress( owner, num=0) { } -function contractOrNull(addr,abi,provider) { +export function contractOrNull(addr,abi,provider) { try { return new ethers.Contract(addr,abi,provider) } @@ -22,16 +21,17 @@ function contractOrNull(addr,abi,provider) { export async function factoryContract() { const s = useStore() - return contractOrNull(s.factory, factoryAbi, provider) + return contractOrNull(s.factory, factoryAbi, s.provider) } export async function queryHelperContract() { const s = useStore() - return contractOrNull(s.helper, queryHelperAbi, provider) + return contractOrNull(s.helper, queryHelperAbi, s.provider) } export async function poolContract(addr) { - return contractOrNull(addr, poolAbi, provider) + const s = useStore() + return contractOrNull(addr, poolAbi, s.provider) } export async function vaultContract(num, signer) { diff --git a/src/blockchain/token.js b/src/blockchain/token.js new file mode 100644 index 0000000..d61f1d7 --- /dev/null +++ b/src/blockchain/token.js @@ -0,0 +1,44 @@ +import {socket} from "@/socket.js"; +import {useStore} from "@/store/store.js"; +import {erc20Abi} from "@/blockchain/abi.js"; +import {ethers} from "ethers"; + +export async function getToken(addr) { + const s = useStore() + if (!(addr in s.tokens)) + await addExtraToken(addr) + return s.tokens[addr] +} + +export async function addExtraToken(addr) { + const prom = new Promise((resolve) => { + const s = useStore() + const chainId = s.chainId + console.log('querying token', addr) + socket.emit('lookupToken', chainId, addr, (info) => { + console.log('server token info', info) + if (info !== null) { + s.addToken(chainId, info) + resolve(info) + } + else { + if( s.provider===null ) { + console.log('warning: token lookup cancelled due to null provider', addr) + resolve(null) + return + } + const token = new ethers.Contract(addr, erc20Abi, s.provider) + Promise.all( [token.symbol(), token.decimals()] ).then((symbol,decimals)=>{ + info = { + address: addr, + symbol: symbol, + decimals: decimals, + } + s.addToken(chainId, info) + resolve(info) + }) + } + }) + }) + return await prom +} diff --git a/src/blockchain/wallet.js b/src/blockchain/wallet.js index c43bc0f..4b63913 100644 --- a/src/blockchain/wallet.js +++ b/src/blockchain/wallet.js @@ -1,26 +1,26 @@ import {ethers} from "ethers"; -import {useStore} from "@/store/store"; +import {setProvider, useStore} from "@/store/store"; import {socket} from "@/socket.js"; -import {vaultContract} from "@/blockchain/contract.js"; +import {contractOrNull} from "@/blockchain/contract.js"; +import {vaultAbi} from "@/blockchain/abi.js"; -export let provider = null export function onChainChanged(chainId) { chainId = Number(chainId) console.log('chain changed', chainId) const store = useStore() if( chainId !== store.chainId ) { - store.chainId = chainId + const provider = new ethers.BrowserProvider(window.ethereum, chainId); + setProvider(provider, chainId) store.account = null - provider = new ethers.BrowserProvider(window.ethereum, chainId) provider.listAccounts().then(changeAccounts) - new ethers.Interface([ - // 'event DexorderSwapCreated' // todo - ]) + store.chainId = chainId // touch the chainId last. will cause any clients of the store's provider getter to refresh } } function changeAccounts(accounts) { + console.log('change accounts', accounts) + const store = useStore() if( accounts.length === 0 ) { store.account = null store.vaults = [] @@ -29,16 +29,15 @@ function changeAccounts(accounts) { else { const store = useStore() store.account = accounts[0].address - flushOrders() + flushTransactions() socket.emit('address', store.chainId, accounts[0].address) } } function onAccountsChanged(accounts) { - // console.log('accounts changed', accounts) const store = useStore() if (accounts.length === 0 || accounts[0] !== store.account) - changeAccounts(store, accounts); + changeAccounts(accounts); } export async function watchWallet() { @@ -82,31 +81,56 @@ const errorHandlingProxy = { export async function connectWallet() { - return provider.getSigner() + console.log('TODO connect wallet') + // eth_getaccounts } -export async function pendOrder(order) { +export function pendOrder(order) { console.log('order', JSON.stringify(order)) const s = useStore() - s.pendingOrders.push(order) - flushOrders() -} - - -export function flushOrders() { - // noinspection JSIgnoredPromiseFromCall - asyncFlushOrders() -} - -export async function asyncFlushOrders() { - const s = useStore() - const orders = s.pendingOrders - if (!orders.length) + const vault = s.vault; + if(vault === null ) { + console.error('vault was null during pendOrder') return + } + pendTransaction(async (signer)=> { + const contract = contractOrNull(vault, vaultAbi, signer) + if( contract === null ) { + console.error('vault contract was null while sending order transaction', vault) + return null + } + return await contract.placeOrder(order) + }) +} + + +export function pendTransaction(sender) { + const s = useStore() + s.transactionSenders.push(sender) + flushTransactions() +} + + +export function flushTransactions() { + // noinspection JSIgnoredPromiseFromCall + asyncFlushTransactions() +} + +export async function asyncFlushTransactions() { + // todo rework into flushTransactions() + const s = useStore() + if( s.provider === null ) { + console.log('warning: asyncFlushOrders() cancelled due to null provider') + return + } + const senders = s.transactionSenders + if (!senders.length) + return + console.log(`flushing ${s.transactionSenders.length} transactions`) let signer try { - signer = await provider.getSigner(); + signer = await s.provider.getSigner(); } catch (e) { // { // "code": -32002, @@ -119,28 +143,27 @@ export async function asyncFlushOrders() { socket.emit('ensureVault', s.chainId, await signer.getAddress(), 0) return } - const contract = await vaultContract(0, signer) - if (!contract) { - console.error(`no contract for vault 0 of ${signer.address}`) - return - } - for (const order of orders) - doPlaceOrder(s, contract, order) + for (const sender of senders) + doSendTransaction(sender, signer) } -function doPlaceOrder(s, contract, order) { - contract.placeOrder(order).then((tx)=>{ - console.log('placed order', tx) - s.removePendingOrder(order) +function doSendTransaction(sender, signer) { + const s = useStore(); + sender(signer).then((tx)=>{ + console.log('sent transaction', tx) + s.removeTransactionSender(sender) tx.wait().then((tr)=>console.log('tx receipt',tr)) }).catch((e)=>{ - if( e.info.error.code === 4001 ) { - console.log(`user rejected order`, order) - s.removePendingOrder(order) + if( e.info?.error?.code === 4001 ) { + console.log(`user rejected transaction`) + s.removeTransactionSender(sender) } else { - console.error('error placing order', order, e.reason, e.info) - s.removePendingOrder(order) + if( e.reason && e.info ) + console.error('error sending transaction', e.reason, e.info) + else + console.error('error sending transaction', e) + s.removeTransactionSender(sender) // todo retry? } }) @@ -150,5 +173,5 @@ socket.on('vaults', (vaults)=>{ const s = useStore() console.log('vaults', vaults) s.vaults = vaults - flushOrders() + flushTransactions() }) diff --git a/src/components/Blockchain.vue b/src/components/Blockchain.vue new file mode 100644 index 0000000..49aa0ce --- /dev/null +++ b/src/components/Blockchain.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/src/components/ConnectWallet.vue b/src/components/ConnectWallet.vue deleted file mode 100644 index ec154dd..0000000 --- a/src/components/ConnectWallet.vue +++ /dev/null @@ -1,24 +0,0 @@ - - - - - diff --git a/src/components/CopyButton.vue b/src/components/CopyButton.vue index a9f0f44..435b80d 100644 --- a/src/components/CopyButton.vue +++ b/src/components/CopyButton.vue @@ -1,7 +1,12 @@ + + diff --git a/src/components/NeedsQueryHelper.vue b/src/components/NeedsQueryHelper.vue deleted file mode 100644 index 0b09f65..0000000 --- a/src/components/NeedsQueryHelper.vue +++ /dev/null @@ -1,21 +0,0 @@ - - - - - diff --git a/src/components/NeedsWallet.vue b/src/components/NewOrder.vue similarity index 77% rename from src/components/NeedsWallet.vue rename to src/components/NewOrder.vue index bdc5bc8..9e138bb 100644 --- a/src/components/NeedsWallet.vue +++ b/src/components/NewOrder.vue @@ -1,5 +1,5 @@ diff --git a/src/components/TokenChoice.vue b/src/components/TokenChoice.vue index f27bfa0..e365d65 100644 --- a/src/components/TokenChoice.vue +++ b/src/components/TokenChoice.vue @@ -1,5 +1,5 @@