transaction placement dialog
This commit is contained in:
@@ -1,21 +1,23 @@
|
||||
import {BrowserProvider, ethers} from "ethers";
|
||||
import {useStore} from "@/store/store";
|
||||
import {socket} from "@/socket.js";
|
||||
import {SingletonCoroutine, timestamp, uuid} from "@/misc.js";
|
||||
import {SingletonCoroutine, uuid} from "@/misc.js";
|
||||
import {newContract, vaultAddress, vaultContract} from "@/blockchain/contract.js";
|
||||
import {defineStore} from "pinia";
|
||||
import {ref} from "vue";
|
||||
import {metadataMap, version} from "@/version.js";
|
||||
import {CancelAllTransaction, TransactionState} from "@/blockchain/transaction.js";
|
||||
|
||||
|
||||
export let provider = null
|
||||
|
||||
|
||||
// DEPRECATED
|
||||
export const useWalletStore = defineStore('wallet', ()=>{
|
||||
// this is what the wallet is logged into. it could be different than the application's store.chainId.
|
||||
const chainId = ref(0)
|
||||
|
||||
// Pending Order Format
|
||||
// OLD Pending Order Format
|
||||
// {
|
||||
// chainId: 31337, // must never be null, even if no wallet plugin exists. chosen by app, not wallet.
|
||||
// placementTime: Date.now(),
|
||||
@@ -26,8 +28,11 @@ export const useWalletStore = defineStore('wallet', ()=>{
|
||||
// }
|
||||
const pendingOrders = ref([])
|
||||
|
||||
// NEW Format is a single Transaction class
|
||||
const transaction = ref(null)
|
||||
|
||||
return {
|
||||
chainId, pendingOrders,
|
||||
chainId, pendingOrders, transaction,
|
||||
}
|
||||
})
|
||||
|
||||
@@ -165,7 +170,7 @@ function discoverVaults(owner) {
|
||||
doDiscoverVaults.invoke(owner)
|
||||
}
|
||||
|
||||
const doDiscoverVaults = new SingletonCoroutine(_discoverVaults, 50, false)
|
||||
const doDiscoverVaults = new SingletonCoroutine(_discoverVaults, 50)
|
||||
async function _discoverVaults(owner) {
|
||||
const result = []
|
||||
const versions = []
|
||||
@@ -204,11 +209,12 @@ async function _discoverVaults(owner) {
|
||||
if( s.account === owner ) { // double-check the account since it could have changed during our await
|
||||
s.vaults = result
|
||||
s.vaultVersions = versions
|
||||
if( useWalletStore().pendingOrders.length ) {
|
||||
if( useWalletStore().transaction ) {
|
||||
const num = 0 // todo multiple vaults
|
||||
if (result.length)
|
||||
flushOrders(result[0])
|
||||
flushOrders(s.chainId, owner, num, result[0])
|
||||
else
|
||||
ensureVault2(s.chainId, owner, 0)
|
||||
ensureVault2(s.chainId, owner, num)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,7 +254,7 @@ async function doEnsureVault(chainId, owner, num) {
|
||||
if (s.vaults.length <= num)
|
||||
await _discoverVaults(owner)
|
||||
if( s.vaults[num] )
|
||||
flushOrders(s.vaults[num])
|
||||
flushOrders(chainId, owner, num, s.vaults[num])
|
||||
else {
|
||||
console.log(`requesting vault ${owner} ${num}`)
|
||||
socket.emit('ensureVault', chainId, owner, num)
|
||||
@@ -258,53 +264,6 @@ async function doEnsureVault(chainId, owner, num) {
|
||||
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
|
||||
}
|
||||
|
||||
// single order placement selector
|
||||
const placementFeeSelector = 'placementFee((address,address,(uint8,uint24),uint256,uint256,bool,bool,bool,uint64,(uint16,bool,bool,bool,bool,bool,bool,bool,bool,uint16,uint24,uint32,uint32,(uint32,uint32),(uint32,uint32))[]),(uint8,uint8,uint8,uint8,uint8))'
|
||||
|
||||
export async function placementFee(vault, order, window=300) {
|
||||
// If the fees are about to change within `window` seconds of now, we send the higher native amount of the two fees.
|
||||
// If the fees sent are too much, the vault will refund the sender.
|
||||
const v = await vaultContract(vault, provider)
|
||||
const feeManagerAddr = await v.feeManager()
|
||||
const feeManager = await newContract(feeManagerAddr, 'IFeeManager', provider)
|
||||
const [sched, changeTimestamp] = await Promise.all([feeManager.fees(), feeManager.proposedFeeActivationTime()])
|
||||
console.log('sched', order, sched)
|
||||
let [orderFee, gasFee] = await v[placementFeeSelector](order, [...sched])
|
||||
console.log('placementFee', orderFee, gasFee)
|
||||
if (Number(changeTimestamp) - timestamp() < window) {
|
||||
const nextSched = await feeManager.proposedFees()
|
||||
const [nextOrderFee, nextGasFee] = await v[placementFeeSelector](order, [...nextSched])
|
||||
if (nextOrderFee + nextGasFee > orderFee + gasFee)
|
||||
[orderFee, gasFee] = [nextOrderFee, nextGasFee]
|
||||
}
|
||||
return [orderFee, gasFee]
|
||||
}
|
||||
|
||||
|
||||
export async function pendOrder(order, fee=null) {
|
||||
const s = useStore()
|
||||
const pend = {
|
||||
id: uuid(),
|
||||
chainId: s.chainId,
|
||||
placementTime: Date.now()/1000,
|
||||
fee: fee, // dexorder place and gas fee total
|
||||
vault: s.vaults.length ? s.vaults[0] : null,
|
||||
state: PendingOrderState.Submitted,
|
||||
order
|
||||
};
|
||||
useWalletStore().pendingOrders.splice(0,0, pend)
|
||||
console.log('pended order', pend.id, JSON.stringify(order))
|
||||
ensureVault()
|
||||
}
|
||||
|
||||
|
||||
export async function cancelOrder(vault, orderIndex) {
|
||||
console.log('cancel order', vault, orderIndex)
|
||||
pendTransaction(async (signer)=> {
|
||||
@@ -318,18 +277,13 @@ export async function cancelOrder(vault, orderIndex) {
|
||||
}
|
||||
|
||||
export async function cancelAll(vault) {
|
||||
pendTransaction(async (signer)=> {
|
||||
const contract = await vaultContract(vault, signer)
|
||||
if( contract === null ) {
|
||||
console.error('vault contract was null while canceling order', vault)
|
||||
return null
|
||||
}
|
||||
return await contract.cancelAllDexorders()
|
||||
})
|
||||
new CancelAllTransaction(useStore().chainId, vault).submit()
|
||||
}
|
||||
|
||||
export function flushOrders(vault) {
|
||||
export function flushOrders(chainId, owner, num, vault) {
|
||||
const ws = useWalletStore();
|
||||
if (ws.transaction!==null && ws.transaction.state < TransactionState.Proposed)
|
||||
ws.transaction.propose(owner, vault)
|
||||
let needsFlush = false
|
||||
for( const pend of ws.pendingOrders ) {
|
||||
if (pend.vault === null)
|
||||
@@ -337,7 +291,7 @@ export function flushOrders(vault) {
|
||||
if (pend.state === PendingOrderState.Submitted) {
|
||||
console.log('flushing order', pend.id)
|
||||
pendOrderAsTransaction(pend)
|
||||
pend.state = PendingOrderState.Signing
|
||||
setPendState(pend, PendingOrderState.Signing)
|
||||
needsFlush = true
|
||||
}
|
||||
}
|
||||
@@ -363,7 +317,7 @@ function pendOrderAsTransaction(pend) {
|
||||
catch (e) {
|
||||
if(e.code===4001) {
|
||||
console.log('user refused chain switch')
|
||||
pend.state = PendingOrderState.Rejected
|
||||
setPendState(pend, PendingOrderState.Rejected)
|
||||
return null
|
||||
}
|
||||
else {
|
||||
@@ -378,7 +332,7 @@ function pendOrderAsTransaction(pend) {
|
||||
console.log('placing order', pend.id, pend.fee, pend.order)
|
||||
const tx = await contract.placeDexorder(pend.order, {value:pend.fee})
|
||||
pend.tx = tx
|
||||
pend.state = PendingOrderState.Sent
|
||||
setPendState(pend, PendingOrderState.Sent)
|
||||
console.log(`order ${pend.id} sent transaction`, tx)
|
||||
tx.wait().then((txReceipt)=>{
|
||||
console.log('mined order', pend.id, txReceipt)
|
||||
@@ -391,7 +345,7 @@ function pendOrderAsTransaction(pend) {
|
||||
(e) => {
|
||||
if( e.info?.error?.code === 4001 ) {
|
||||
console.log(`wallet refused order`, pend.id)
|
||||
pend.state = PendingOrderState.Rejected
|
||||
setPendState(pend, PendingOrderState.Rejected)
|
||||
return true // returning true means we handled the error. any other return value will dump to console.
|
||||
}
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user