diff --git a/src/blockchain/orderlib.js b/src/blockchain/orderlib.js
index f7e0680..fa18814 100644
--- a/src/blockchain/orderlib.js
+++ b/src/blockchain/orderlib.js
@@ -114,7 +114,7 @@ export function orderIsOpen(order) {
}
export function isOpen(state) {
- return state < 3
+ return state >= 1 && state < 3
}
export function parseOrderStatus(status) {
diff --git a/src/blockchain/token.js b/src/blockchain/token.js
index 16d53c6..ac3370e 100644
--- a/src/blockchain/token.js
+++ b/src/blockchain/token.js
@@ -19,9 +19,8 @@ export function token(chainId, addr) {
// async version doesnt return until it has a token value
export async function getToken(chainId, addr) {
- // todo deprecated. use metadataMap[chainId][addr]
const s = useStore()
- if (addr===undefined) {
+ if (addr===undefined) { // todo remove check
console.warn('getToken(addr) is deprecated. use getToken(chainId,addr)')
addr = chainId
chainId = s.chainId
@@ -38,7 +37,7 @@ export async function getToken(chainId, addr) {
const _inFlightLookups = {}
export async function addExtraToken(chainId, addr) {
- if (addr===undefined) {
+ if (addr===undefined) { // todo remove check
console.warn('addExtraToken(addr) is deprecated. use addExtraToken(chainId,addr)')
addr = chainId
chainId = s.chainId
diff --git a/src/blockchain/wallet.js b/src/blockchain/wallet.js
index b6e938f..0f2ad64 100644
--- a/src/blockchain/wallet.js
+++ b/src/blockchain/wallet.js
@@ -7,6 +7,7 @@ import {SingletonCoroutine} from "@/misc.js";
import {defineStore} from "pinia";
import {ref} from "vue";
import {metadata, metadataMap} from "@/version.js";
+import {OrderState} from "@/blockchain/orderlib.js";
export const useWalletStore = defineStore('wallet', ()=>{
@@ -17,7 +18,7 @@ export const useWalletStore = defineStore('wallet', ()=>{
// {
// chainId: 31337, // must never be null, even if no wallet plugin exists. chosen by app, not wallet.
// placementTime: Date.now(),
- // submitted: false // true after the order has started to be sent to the wallet
+ // state: PendingOrderState.Submitted
// tx: null // transaction ID
// vault: '0x...', // or null if account not logged in yet
// order: {tokenIn:..., tokenOut:..., ...} // blockchain binary order object
@@ -213,11 +214,12 @@ async function _discoverVaults(owner) {
}
if( s.account === owner ) { // double-check the account since it could have changed during our await
s.vaults = result
- if( useWalletStore().pendingOrders.length )
- if( result.length )
+ if( useWalletStore().pendingOrders.length ) {
+ if (result.length)
flushOrders(result[0])
else
ensureVault2(s.chainId, owner, 0)
+ }
}
}
@@ -257,20 +259,28 @@ async function doEnsureVault(chainId, owner, num) {
console.log(`requesting vault ${owner} ${num}`)
socket.emit('ensureVault', chainId, owner, num)
}
- // await sleep(5000) // prevent this process from running more than once every 5 seconds
}
+// await sleep(5000) // prevent this process from running more than once every 5 seconds
const ensureVaultRoutine = new SingletonCoroutine(doEnsureVault, 100)
+export const PendingOrderState = {
+ Submitted: 100, // user clicked Place Order but the tx isn't sent to the wallet yet
+ Signing: 0, // tx is sent to the wallet
+ Rejected: 101, // user refused to sign the tx
+ Sent: 102, // tx is awaiting blockchain mining
+}
+
+
export async function pendOrder(order) {
console.log('order', JSON.stringify(order))
const s = useStore()
useWalletStore().pendingOrders.push({
chainId: s.chainId,
- placementTime: new Date(),
+ placementTime: Date.now()/1000,
vault: s.vaults.length ? s.vaults[0] : null,
- submitted: false,
+ state: PendingOrderState.Submitted,
order
})
ensureVault()
@@ -303,12 +313,13 @@ export async function cancelAll(vault) {
export function flushOrders(vault) {
const ws = useWalletStore();
let needsFlush = false
- for( const order of ws.pendingOrders ) {
- if (order.vault === null)
- order.vault = vault
- if (!order.submitted) {
- pendOrderAsTransaction(order)
- order.submitted = true
+ for( const pend of ws.pendingOrders ) {
+ if (pend.vault === null)
+ pend.vault = vault
+ if (pend.state === PendingOrderState.Submitted) {
+ console.log('pending', pend)
+ pendOrderAsTransaction(pend)
+ pend.state = PendingOrderState.Signing
needsFlush = true
}
}
@@ -317,40 +328,46 @@ export function flushOrders(vault) {
}
-function pendOrderAsTransaction(order) {
+function pendOrderAsTransaction(pend) {
pendTransaction(async (signer)=> {
- const contract = contractOrNull(order.vault, vaultAbi, signer)
+ const contract = contractOrNull(pend.vault, vaultAbi, signer)
if( contract === null ) {
- console.error('vault contract was null while sending order transaction', order.vault)
+ console.error('vault contract was null while sending order transaction', pend.vault)
return null
}
- if (!await switchChain(order.chainId)) {
+ if (!await switchChain(pend.chainId)) {
console.log('user refused chain switch')
+ pend.state = PendingOrderState.Rejected
return null
}
- console.log('placing order', order)
- const tx = await contract.placeDexorder(order.order) // todo update status
- order.tx = tx
+ console.log('placing order', pend)
+ const tx = await contract.placeDexorder(pend.order) // todo update status
+ pend.tx = tx
tx.wait().then((txReceipt)=>{
const ws = useWalletStore();
- ws.pendingOrders = ws.pendingOrders.filter((o)=>o!==order)
+ ws.pendingOrders = ws.pendingOrders.filter((o)=>o!==pend)
})
return tx
+ },
+ (e) => {
+ if( e.info?.error?.code === 4001 ) {
+ console.log(`user rejected transaction`)
+ pend.state = PendingOrderState.Rejected
+ return true // returning true means we handled the error. any other return value will dump to console.
+ }
})
}
-export function pendTransaction(sender) {
+export function pendTransaction(sender, errHandler) {
const s = useStore()
- s.transactionSenders.push(sender)
+ s.transactionSenders.push([sender,errHandler])
flushTransactions()
}
const flushTransactionsRoutine = new SingletonCoroutine(asyncFlushTransactions,1)
-let flushing = 0 // semaphore
-
export function flushTransactions() {
flushTransactionsRoutine.invoke()
}
@@ -376,11 +393,12 @@ async function asyncFlushTransactions() {
console.log('signer denied')
return
}
- for (const sender of senders)
- doSendTransaction(sender, signer)
+ for (const [sender,errHandler] of senders)
+ doSendTransaction(sender, signer, errHandler)
+ s.transactionSenders = []
}
-function doSendTransaction(sender, signer) {
+function doSendTransaction(sender, signer, errHandler) {
const s = useStore();
s.removeTransactionSender(sender)
sender(signer).then((tx)=>{
@@ -388,11 +406,11 @@ function doSendTransaction(sender, signer) {
console.log('sent transaction', tx)
tx.wait().then((tr)=>console.log('tx receipt',tr))
}
- }).catch((e)=>{
- if( e.info?.error?.code === 4001 ) {
- console.log(`user rejected transaction`)
- }
- else {
+ }).catch(async (e)=>{
+ let dumpErr = true
+ if (errHandler!==undefined)
+ dumpErr = await errHandler(e) !== true
+ if (dumpErr) {
if( e.reason && e.info )
console.error('error sending transaction', e.reason, e.info)
else
diff --git a/src/components/NeedsProvider.vue b/src/components/NeedsProvider.vue
index 06387be..7720ce2 100644
--- a/src/components/NeedsProvider.vue
+++ b/src/components/NeedsProvider.vue
@@ -66,10 +66,7 @@ const s = useStore()
const walletOk = typeof window.ethereum !== 'undefined'
const providerOk = computed(()=>s.provider!==null)
const chainOk = computed(()=>providerOk.value && s.helper!==null)
-const ok = computed(()=>{
- console.log('recompute provider ok')
- return walletOk && providerOk.value && chainOk.value
-})
+const ok = computed(()=>walletOk && providerOk.value && chainOk.value)
function reload() {
window.location.reload()
}
diff --git a/src/components/Order.vue b/src/components/Order.vue
index 24b2c62..f180f94 100644
--- a/src/components/Order.vue
+++ b/src/components/Order.vue
@@ -11,7 +11,7 @@