transaction placement dialog

This commit is contained in:
tim
2024-11-11 20:55:28 -04:00
parent 43891434c5
commit a9bf23ddbb
18 changed files with 439 additions and 122 deletions

View File

@@ -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.
}
})