11 Commits

25 changed files with 8009 additions and 1109 deletions

View File

@@ -1,2 +1,2 @@
VITE_WS_URL=wss://ws.dexorder.com
VITE_SHARE_URL=https://dexorder.com
VITE_SHARE_URL=https://app.dexorder.com

5731
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -15,9 +15,10 @@
"dependencies": {
"@isaacs/ttlcache": "^1.4.1",
"@mdi/font": "6.9.96",
"@web3modal/ethers": "^5.1.11",
"color": "^4.2.3",
"core-js": "^3.29.0",
"ethers": "^6.7.1",
"ethers": "^6.16.0",
"flexsearch": "^0.7.43",
"lru-cache": "^11.0.2",
"luxon": "^3.4.4",

View File

@@ -22,6 +22,7 @@ export class Transaction {
}
submit() {
console.log('submitting transaction', this.type)
const ws = useWalletStore();
if ( ws.transaction !== null ) {
console.error('Transaction already in progress', ws.transaction)
@@ -32,6 +33,7 @@ export class Transaction {
// "propose" means attach the transaction to a specific vault
propose(owner, vault) {
console.log('transaction bind', owner, vault)
if (this.vault !== null && this.vault !== vault) {
this.failed('proposed vault did not match withdrawl vault', vault, this.vault)
return

View File

@@ -9,6 +9,7 @@ import {metadataMap, version} from "@/version.js";
import {TransactionState, TransactionType} from "@/blockchain/transactionDecl.js";
import {track} from "@/track.js";
import {socket} from "@/socket.js";
import {web3modal} from "@/blockchain/web3modal.js";
export const useWalletStore = defineStore('wallet', ()=>{
@@ -33,12 +34,14 @@ export const useWalletStore = defineStore('wallet', ()=>{
set(v) {
_tx.value = v;
if (v===null) {
console.log('clear transaction')
if (progressionInvoker!==null) {
clearTimeout(progressionInvoker)
progressionInvoker = null
}
}
else {
console.log('set transaction', v)
transactionProgressor.invoke();
if (progressionInvoker===null)
progressionInvoker = setInterval(()=>transactionProgressor.invoke(), 1000)
@@ -129,7 +132,8 @@ export function detectChain() {
}
}
detectChain()
// Commented out - Web3Modal handles wallet detection now
// detectChain()
const errorHandlingProxy = {
get(target, prop, proxy) {
@@ -164,29 +168,123 @@ const errorHandlingProxy = {
export async function connectWallet(chainId) {
console.log('connectWallet', chainId)
console.log('connectWallet via Web3Modal', chainId)
// Return a promise that resolves when connection is complete
return new Promise((resolve, reject) => {
let resolved = false
let unsubscribeProvider = null
let unsubscribeState = null
// Subscribe to provider changes (fires when wallet connects)
unsubscribeProvider = web3modal.subscribeProvider(async (newState) => {
console.log('Provider state changed:', newState)
if (newState.provider && !resolved) {
resolved = true
unsubscribeProvider?.()
unsubscribeState?.()
try {
await switchChain(chainId)
console.log('getSigner')
const p = new BrowserProvider(window.ethereum, chainId)
await p.getSigner()
await updateAccounts(chainId, p)
const walletProvider = newState.provider
// Create ethers provider from Web3Modal provider
const p = new BrowserProvider(walletProvider)
setProvider(p)
// Get network info from the provider
const network = await p.getNetwork()
const connectedChainId = Number(network.chainId)
console.log('Connected to chain', connectedChainId)
// Update wallet store
const ws = useWalletStore()
ws.chainId = connectedChainId
// Get accounts
await updateAccounts(connectedChainId, p)
// Subscribe to Web3Modal provider events
subscribeToProviderEvents(walletProvider)
resolve()
} catch (e) {
console.error('Error after connection', e)
reject(e)
}
catch (e) {
console.log('connectWallet error', e.reason, e)
if (e.reason==='rejected') {
}
})
// Subscribe to modal state (fires when modal opens/closes)
unsubscribeState = web3modal.subscribeState((state) => {
// If modal closes without connection, resolve the promise
if (state.open === false && !resolved) {
console.log('Modal closed without connection')
resolved = true
unsubscribeProvider?.()
unsubscribeState?.()
resolve() // Resolve (not reject) so the button re-enables
}
})
// Open the modal
web3modal.open().catch((e) => {
if (!resolved) {
resolved = true
unsubscribeProvider?.()
unsubscribeState?.()
if (e.reason === 'rejected' || e.message?.includes('rejected')) {
const ws = useWalletStore();
const tx = ws.transaction
if (tx) {
tx.state = TransactionState.Rejected
ws.transaction = null
}
}
else {
console.error(e, e.reason)
throw e
resolve() // Don't reject on user cancellation
} else {
reject(e)
}
}
})
// Timeout after 60 seconds
setTimeout(() => {
if (!resolved) {
resolved = true
unsubscribeProvider?.()
unsubscribeState?.()
console.log('Connection timeout')
resolve() // Resolve instead of reject so button re-enables
}
}, 60000)
})
}
// Subscribe to provider events from Web3Modal
function subscribeToProviderEvents(walletProvider) {
// Handle account changes
walletProvider.on('accountsChanged', (accounts) => {
console.log('accountsChanged from Web3Modal', accounts)
if (accounts.length === 0) {
disconnectWallet()
} else {
onAccountsChanged(accounts)
}
})
// Handle chain changes
walletProvider.on('chainChanged', (chainId) => {
console.log('chainChanged from Web3Modal', chainId)
onChainChanged(chainId)
})
// Handle disconnect
walletProvider.on('disconnect', () => {
console.log('Provider disconnected from Web3Modal')
disconnectWallet()
})
}
@@ -242,7 +340,7 @@ async function _discoverVaults(owner) {
if( useWalletStore().transaction ) {
const num = 0 // todo multiple vaults
if (result.length)
flushOrders(s.chainId, owner, num, result[0])
flushWalletTransactions(s.chainId, owner, num, result[0])
else
ensureVault2(s.chainId, owner, num)
}
@@ -284,7 +382,7 @@ async function doEnsureVault(chainId, owner, num) {
if (s.vaults.length <= num)
await _discoverVaults(owner)
if( s.vaults[num] )
flushOrders(chainId, owner, num, s.vaults[num])
flushWalletTransactions(chainId, owner, num, s.vaults[num])
else {
console.log(`requesting vault ${owner} ${num}`)
socket.emit('ensureVault', chainId, owner, num)
@@ -309,11 +407,13 @@ export async function cancelOrder(vault, orderIndex) {
async function progressTransactions() {
const s = useStore()
const ws = useWalletStore();
console.log('progressTransactions', ws.transaction)
if( ws.transaction===null )
return
if( s.account === null ) {
let signer = null
try {
console.log('account is null. requesting sign-in.')
signer = await provider.getSigner()
}
catch (e) {
@@ -333,11 +433,27 @@ async function progressTransactions() {
}
}
if( s.vault === null ) {
console.log('vault is null. requesting vault creation.')
ensureVault()
return
}
if( ws.transaction.state < TransactionState.Proposed )
ws.transaction.propose(s.account, s.vault)
if( ws.transaction.type === TransactionType.PlaceOrder ) {
flushOrders(s.chainId, s.account, 0, s.vault)
flushWalletTransactions(s.chainId, s.account, 0, s.vault)
}
else {
console.log('flushing transaction', ws.transaction.type)
if (ws.transaction.state < TransactionState.Proposed) {
pendTransaction(async (signer) => {
if (signer.address !== ws.transaction.owner) {
console.error('signer address does not match transaction owner', signer.address, ws.transaction.owner)
return
}
const contract = await vaultContract(ws.transaction.vault, signer)
return await ws.transaction.createTx(contract)
})
}
}
}
@@ -346,12 +462,10 @@ const transactionProgressor = new SingletonCoroutine(progressTransactions, 10)
let progressionInvoker = null
export function flushOrders(chainId, owner, num, vault) {
export function flushWalletTransactions(chainId, owner, num, vault) {
const ws = useWalletStore();
console.log('flushOrders', chainId, owner, num, vault)
if (ws.transaction!==null && ws.transaction.type === TransactionType.PlaceOrder && ws.transaction.state < TransactionState.Proposed)
ws.transaction.propose(owner, vault)
let needsFlush = false
console.log('flushWalletTransactions', chainId, owner, num, vault)
let needsFlush = ws.transaction !== null && ws.transaction.type !== TransactionType.PlaceOrder
for( const pend of ws.pendingOrders ) {
if (pend.vault === null)
pend.vault = vault
@@ -420,6 +534,7 @@ function pendOrderAsTransaction(pend) {
export function pendTransaction(sender, errHandler) {
console.log('pendTransaction')
const s = useStore()
s.transactionSenders.push([sender,errHandler])
flushTransactions()
@@ -438,6 +553,7 @@ async function asyncFlushTransactions() {
console.log('flushTransactions', ws.transaction, s.vault)
if (ws.transaction !== null) {
if (s.vault === null) {
console.log('transaction doesn\'t have a vault. creating one.')
await ensureVault()
if (s.vault === null) {
console.error('vault could not be created')
@@ -455,8 +571,10 @@ async function asyncFlushTransactions() {
return
}
const senders = s.transactionSenders
if (!senders.length)
if (!senders.length) {
console.log('no transactionSenders!')
return
}
console.log(`flushing ${senders.length} transactions`)
let signer
try {
@@ -615,21 +733,7 @@ export async function addNetwork(chainId) {
}
export async function addNetworkAndConnectWallet(chainId) {
try {
await switchChain(chainId)
} catch (e) {
if (e.code === 4001) {
// explicit user rejection
return
} else if (e.code === 4902) {
try {
await addNetwork(chainId)
} catch (e) {
console.log(`Could not add network ${chainId}`)
}
} else
console.log('switchChain() failure', e)
}
try {
await connectWallet(chainId)
} catch (e) {
@@ -637,3 +741,44 @@ export async function addNetworkAndConnectWallet(chainId) {
console.log('connectWallet() failed', e)
}
}
export async function disconnectWallet() {
console.log('disconnectWallet')
const store = useStore()
const ws = useWalletStore()
// Disconnect from Web3Modal
try {
await web3modal.disconnect()
} catch (e) {
console.log('Web3Modal disconnect error (ignoring)', e)
}
// Clear provider
setProvider(null)
// Clear account and vaults
store.account = null
store.vaults = []
store.vaultVersions = []
// Clear any pending transactions
if (ws.transaction !== null) {
ws.transaction = null
}
ws.pendingOrders = []
// Clear transaction senders
store.transactionSenders = []
// Emit socket disconnect
socket.emit('address', ws.chainId, null)
track('logout', {chainId: ws.chainId})
console.log('Wallet disconnected')
}
// Make it globally accessible from console
if (typeof window !== 'undefined') {
window.disconnectWallet = disconnectWallet
}

View File

@@ -0,0 +1,53 @@
// src/blockchain/web3modal.js
import { createWeb3Modal, defaultConfig } from '@web3modal/ethers'
const projectId = 'a2302c95fedb32f4c64672a41159df37' // Get from https://cloud.walletconnect.com
const chains = [
{
chainId: 42161,
name: 'Arbitrum One',
currency: 'ETH',
explorerUrl: 'https://arbiscan.io',
rpcUrl: 'https://arbitrum-mainnet.infura.io'
},
{
chainId: 1337,
name: 'Dexorder Alpha Testnet',
currency: 'TETH',
explorerUrl: '',
rpcUrl: 'https://rpc.alpha.dexorder.com'
},
{
chainId: 31337,
name: 'Mockchain',
currency: 'TETH',
explorerUrl: '',
rpcUrl: 'http://localhost:8545'
}
]
const ethersConfig = defaultConfig({
metadata: {
name: 'Dexorder',
description: 'Dexorder Trading Platform',
url: window.location.origin,
icons: ['https://your-icon-url.com']
},
defaultChainId: 42161,
enableEIP6963: false, // Disable to prevent wallets from auto-announcing
enableInjected: true,
enableCoinbase: true,
rpcUrl: 'https://arbitrum-mainnet.infura.io'
})
export const web3modal = createWeb3Modal({
ethersConfig,
chains,
projectId,
enableAnalytics: false,
themeMode: 'dark',
featuredWalletIds: [
'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96' // MetaMask
],
})

View File

@@ -158,6 +158,7 @@ export function initTVButtons() {
}
export function initWidget(el) {
getAllSymbols()
const symbol = prefs.selectedTicker === null ? 'default' : prefs.selectedTicker
const interval = prefs.selectedTimeframe === null ? '15' : prefs.selectedTimeframe
widget = window.tvWidget = new TradingView.widget({

View File

@@ -6,7 +6,7 @@ import {useChartOrderStore} from "@/orderbuild.js";
import {useStore} from "@/store/store.js";
import {subOHLC, unsubOHLC} from "@/blockchain/ohlcs.js";
import {ohlcStart} from "@/charts/chart-misc.js";
import {timestamp} from "@/common.js";
import {timestamp, withTimeout} from "@/common.js";
import {erc20Contract} from "@/blockchain/contract.js";
import {track} from "@/track.js";
@@ -140,7 +140,7 @@ function addSymbol(chainId, p, base, quote, inverted) {
// console.log(`invertedDefault(${symbolInfo.base.s}, ${symbolInfo.quote.s})`,invertedDefault(symbolInfo.base.a, symbolInfo.quote.a))
// }
if (defaultSymbol===null && !invertedDefault(symbolInfo.base.a, symbolInfo.quote.a)) {
// console.log('setting default symbol', symbolInfo.base.s, symbolInfo.quote.s, symbolInfo.base.a, symbolInfo.quote.a)
console.log('setting default symbol', symbolInfo.base.s, symbolInfo.quote.s, symbolInfo.base.a, symbolInfo.quote.a)
defaultSymbol = _symbols[ticker]
}
log('new symbol', ticker, _symbols[ticker])
@@ -335,6 +335,14 @@ class RealtimeSubscription {
}
async function getLiquidities(markToken, symbolItem) {
const token = await erc20Contract(markToken.a, provider)
const liquidities = await Promise.all(symbolItem.feeGroup.map(
async ([addr, fee]) => await token.balanceOf(addr)
))
return liquidities;
}
export const DataFeed = {
onReady(callback) {
log('[onReady]: Method call');
@@ -381,9 +389,12 @@ export const DataFeed = {
onResolveErrorCallback,
extension
) {
// console.log('[resolveSymbol]: Method call', symbolName);
console.log('resolveSymbol', symbolName);
const symbols = getAllSymbols();
const symbolItem = symbolName === 'default' ? defaultSymbol : symbols[symbolName]
if (symbolName==='default') {
console.log('using default symbol', defaultSymbol)
}
if (!symbolItem) {
console.log('[resolveSymbol]: Cannot resolve symbol', symbolName);
onResolveErrorCallback('cannot resolve symbol');
@@ -399,10 +410,11 @@ export const DataFeed = {
const inv = invertedDefault(symbolItem.base.a, symbolItem.quote.a)
const markToken = inv ? symbolItem.base : symbolItem.quote
const mark = useStore().markPrice(markToken.a)
const token = await erc20Contract(markToken.a, provider)
const liquidities = await Promise.all(symbolItem.feeGroup.map(
async ([addr, fee]) => await token.balanceOf(addr)
))
const liquidities = await withTimeout(
getLiquidities(markToken, symbolItem),
3000,
'liquidity fetch timeout'
)
symbolItem.liquidities = liquidities.map(l => Number(l / 10n ** BigInt(markToken.d)))
if (mark) {
symbolItem.liquidities = symbolItem.liquidities.map(l => l * mark)

View File

@@ -178,3 +178,13 @@ export function decodeBase62(str) {
return str.split('').reverse().reduce((acc, char, i) =>
acc + base62charset.indexOf(char) * Math.pow(62, i), 0);
}
export function withTimeout(promise, timeoutDuration, fallbackErrorMessage) {
return Promise.race([
promise,
new Promise((_, reject) =>
setTimeout(() => reject(new Error(fallbackErrorMessage)), timeoutDuration)
),
]);
}

View File

@@ -1,4 +1,5 @@
<template>
<v-alert class="d-sm-none" type="info" title="Mobile Screen" text="Dexorder is designed for desktop. Mobile coming soon!" rounded="0"/>
<v-alert v-if='!s.connected' icon="mdi-wifi-off" type="error" title="Not Connected" class="mb-3" rounded="0" density="compact"/>
<v-alert v-for="e in s.errors" icon="mdi-alert" type="error" :title="e.title" :text="e.text" class="mb-3" :closable="e.closeable" rounded="0"/>
</template>

View File

@@ -0,0 +1,142 @@
<template>
<div
ref="floatingDiv"
:style="divStyle"
@mousedown="startDrag"
>
<slot></slot>
</div>
</template>
<script setup>
import { ref, reactive, onMounted, onBeforeUnmount } from 'vue';
const props = defineProps({
id: {
type: String,
required: false,
}
});
const floatingDiv = ref(null);
const position = reactive({ x: 0, y: 0 });
const isDragging = ref(false);
const isFloating = ref(false);
const dragStartOffset = reactive({ x: 0, y: 0 });
const divStyle = reactive({
position: "",
top: "",
left: "",
zIndex: "",
cursor: "default",
});
let activeComponent = null;
function positionKey() {
return props.id ? `floating-div-pos:${props.id}` : null;
}
function savePosition() {
if (props.id) {
localStorage.setItem(
positionKey(),
JSON.stringify({ x: position.x, y: position.y })
);
}
}
function loadPosition() {
if (props.id) {
const data = localStorage.getItem(positionKey());
if (data) {
try {
const { x, y } = JSON.parse(data);
position.x = x;
position.y = y;
divStyle.position = "fixed";
divStyle.top = `${position.y}px`;
divStyle.left = `${position.x}px`;
divStyle.zIndex = 9999;
isFloating.value = true;
} catch {
// Ignore corrupted data
}
}
}
}
const startDrag = (event) => {
if (event.shiftKey || event.ctrlKey) {
if (!isFloating.value) {
const rect = floatingDiv.value.getBoundingClientRect();
position.x = rect.left;
position.y = rect.top;
divStyle.position = "fixed";
divStyle.top = `${position.y}px`;
divStyle.left = `${position.x}px`;
divStyle.zIndex = 9999;
isFloating.value = true;
}
isDragging.value = true;
dragStartOffset.x = event.clientX - position.x;
dragStartOffset.y = event.clientY - position.y;
divStyle.cursor = "move";
document.body.style.userSelect = "none";
activeComponent = floatingDiv;
window.addEventListener("mousemove", handleDrag);
window.addEventListener("mouseup", stopDrag);
}
};
const handleDrag = (event) => {
if (isDragging.value && activeComponent === floatingDiv) {
position.x = event.clientX - dragStartOffset.x;
position.y = event.clientY - dragStartOffset.y;
divStyle.top = `${position.y}px`;
divStyle.left = `${position.x}px`;
}
};
const stopDrag = () => {
if (isDragging.value && activeComponent === floatingDiv) {
isDragging.value = false;
divStyle.cursor = "default";
document.body.style.userSelect = "auto";
activeComponent = null;
savePosition();
window.removeEventListener("mousemove", handleDrag);
window.removeEventListener("mouseup", stopDrag);
}
};
const handleOutsideDrag = (event) => {
if (event.key === "Shift" || event.key === "Control") {
stopDrag();
}
};
onMounted(() => {
document.addEventListener("keyup", handleOutsideDrag);
loadPosition();
});
onBeforeUnmount(() => {
document.removeEventListener("keyup", handleOutsideDrag);
window.removeEventListener("mousemove", handleDrag);
window.removeEventListener("mouseup", stopDrag);
});
</script>
<style>
div[ref="floatingDiv"] {
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 4px 8px rgba(0,0,0,0.2);
}
</style>

View File

@@ -28,8 +28,8 @@
</div>
<v-card-actions v-if="status>Status.NEEDS_PLUGIN">
<btn v-if="pluginOk" icon="mdi-wallet-outline" color="warning" variant="outlined"
@click="connect" :disabled="disabled" text="Connect Wallet"/>
<btn v-if="pluginOk" icon="mdi-wallet-outline" color="green-accent-4" variant="flat"
@click="connect" :disabled="disabled" text="Connect Wallet" class="connect-wallet-btn"/>
</v-card-actions>
</v-card>
@@ -87,4 +87,16 @@ async function connect() {
#manualsetup tr td:last-child {
padding-left: 1em;
}
:deep(.connect-wallet-btn) {
background-color: #00ff41 !important;
color: #000 !important;
font-weight: 600;
box-shadow: 0 0 8px rgba(0, 255, 65, 0.3) !important;
}
:deep(.connect-wallet-btn:hover) {
background-color: #00cc34 !important;
box-shadow: 0 0 12px rgba(0, 255, 65, 0.4) !important;
}
</style>

View File

@@ -3,6 +3,6 @@
<script setup>
if(window.location.hostname !== 'localhost') {
window.$crisp = [];window.CRISP_WEBSITE_ID = "b153f30a-4b0b-49cc-8a38-989409a73acb";(function () {const d = document;const s = d.createElement("script");s.src = "https://client.crisp.chat/l.js";s.async = 1;d.getElementsByTagName("head")[0].appendChild(s);})();
window.$crisp=[];window.CRISP_WEBSITE_ID="a88f707f-adee-4960-b6de-c328c9d86945";(function(){const d=document;const s=d.createElement("script");s.src="https://client.crisp.chat/l.js";s.async=1;d.getElementsByTagName("head")[0].appendChild(s);})();
}
</script>

View File

@@ -5,7 +5,7 @@
<v-card-text class="text-center">Last Updated November 18, 2024</v-card-text>
<v-card-text>
Please read these Terms of Service (the <b>Terms</b>) and our <a href="https://www.dexorder.com/privacy-policy" target="dexorder">Privacy Policy</a> carefully because they govern your
Please read these Terms of Service (the <b>Terms</b>) and our <a href="https://dexorder.com/privacy-policy" target="dexorder">Privacy Policy</a> carefully because they govern your
use of the
website (and all subdomains and subpages thereon) located at dexorder.com, including without limitation the
subdomains app.dexorder.com and www.dexorder.com (collectively, the <b>Site</b>), and the Dexorder web
@@ -205,7 +205,7 @@
(i) Subject to your compliance with these Terms, Dexorder will use its commercially
reasonable efforts to provide you with access to the Dexorder Service and to cause your Interactions to be
executed on the applicable DEX in accordance with Dexorders Execution Policy located at
<a href="https://www.dexorder.com/execution-policy">https://www.dexorder.com/execution-policy</a>
<a href="https://dexorder.com/execution-policy">https://dexorder.com/execution-policy</a>
(<b>Execution Policy</b>), however from time to time the Site and the Dexorder Service may be inaccessible or
inoperable for any
reason, including, without limitation: (a) if an Interaction repeatedly fails to be executed (such as due to an

View File

@@ -34,10 +34,10 @@
<v-card-item v-if="!empty">
<v-table>
<tbody>
<native-row v-if="nativeBalance" :chain-id="s.chainId" :addr="s.vault" :amount="nativeBalance"
<native-row v-if="nativeBalance && BigInt(nativeBalance)>0n" :chain-id="s.chainId" :addr="s.vault" :amount="nativeBalance"
:on-withdraw="onWithdrawNative" :on-wrap="()=>wrapShow=true"/>
<suspense v-for="(amount,addr) of balances">
<token-row v-if="BigInt(amount)>0n" :chain-id="s.chainId" :addr="addr" :amount="amount" :onWithdraw="onWithdraw"/>
<token-row v-if="amount && BigInt(amount)>0n" :chain-id="s.chainId" :addr="addr" :amount="amount" :onWithdraw="onWithdraw"/>
</suspense>
</tbody>
</v-table>
@@ -90,7 +90,7 @@ const hasVault = computed(()=>s.vault!==null)
const withdrawToken = ref(null)
const withdrawShow = ref(false)
async function onWithdraw(token) {
console.log('withdraw', addr, token)
console.log('withdraw', addr.value, token)
withdrawToken.value = token
withdrawShow.value = true
}

View File

@@ -59,7 +59,7 @@ function tryIt() {
function learnMore() {
track('learn-more')
window.open('https://www.dexorder.com/introduction.html', 'dexorderwww')
window.open('https://dexorder.com/introduction.html', 'dexorderwww')
modelValue.value = false
}

View File

@@ -11,7 +11,7 @@
<v-btn variant="text" text="max" @click="floatAmount=balanceFloat"/>
</template>
<template v-slot:append-inner>
<span>{{ token.s }}</span>
<span style="max-width: 6em">{{ token.s }}</span>
</template>
</v-text-field>
<v-card-actions>
@@ -36,11 +36,17 @@ const s = useStore()
const props = defineProps(['modelValue', 'vault', 'token'])
const emit = defineEmits(['update:modelValue'])
const balance = computed(() => {
console.log('balance', props.vault, props.token, s.vaultBalances)
const b = s.vaultBalances[props.vault][props.token.address];
const b = s.getBalance(props.token?.a)
console.log('balance', b)
// const b = s.vaultBalances[props.vault][props.token.address];
return b === undefined ? 0n : BigInt(b)
})
const balanceFloat = computed(() => tokenFloat(props.token, balance.value))
const balanceFloat = computed(() => {
let balance = tokenFloat(props.token, s.getBalance(props.token?.a))
balance /= 10**props.token.d
console.log('balanceFloat', balance, s.getBalance(props.token?.a), props.token)
return balance
})
const floatAmount = ref(0)
function withdraw() {

View File

@@ -132,7 +132,7 @@ const flippedSign = computed(()=>props.flip?-1:1)
const balance100 = computed( {
get() {return flippedSign.value*props.builder.balance*100},
set(v) {
if (v<-60) v = -60;
// if (v<-60) v = -60;
props.builder.balance = flippedSign.value*v/100; }
} )

View File

@@ -10,7 +10,7 @@
<toolbar-button tooltip="Assets" icon="mdi-currency-btc" route="Assets"/>
<!-- mdi-format-list-checks mdi-format-list-bulleted-square -->
<toolbar-button tooltip="Status" icon="mdi-format-list-checks" route="Status"/>
<toolbar-button tooltip="About" icon="mdi-information-outline" href="https://www.dexorder.com/" target="dexorderwww"/>
<toolbar-button tooltip="About" icon="mdi-information-outline" href="https://dexorder.com/" target="dexorderwww"/>
</div>
</div>
</template>

View File

@@ -4,7 +4,7 @@
<script setup>
function openApp() {
window.open('https://dexorder.com/', 'dexorderapp')
window.open('https://app.dexorder.com/', 'dexorderapp')
}
</script>

View File

@@ -24,7 +24,7 @@ import {router} from "@/router/router.js";
const theme = useTheme().current
function openApp() {
window.open('https://dexorder.com/', 'dexorderapp')
window.open('https://app.dexorder.com/', 'dexorderapp')
}
</script>

View File

@@ -15,6 +15,11 @@ import { registerPlugins } from '@/plugins'
import '@/styles/style.scss'
import "./socketInit.js"
import "./version.js"
import { web3modal } from '@/blockchain/web3modal.js'
import { BrowserProvider } from 'ethers'
import { setProvider } from '@/blockchain/provider.js'
import { updateAccounts } from '@/blockchain/wallet.js'
import { useWalletStore } from '@/blockchain/wallet.js'
BigInt.prototype.toJSON = function() { return this.toString() }
@@ -22,3 +27,24 @@ const app = createApp(App)
registerPlugins(app)
app.mount('#app')
window.$vuetify = app
// Check if Web3Modal has an existing connection on app start
web3modal.subscribeProvider(async (state) => {
if (state.isConnected && state.provider) {
try {
console.log('Restoring existing Web3Modal connection')
const p = new BrowserProvider(state.provider)
setProvider(p)
const network = await p.getNetwork()
const chainId = Number(network.chainId)
const ws = useWalletStore()
ws.chainId = chainId
await updateAccounts(chainId, p)
} catch (e) {
console.log('Error restoring connection', e)
}
}
})

View File

@@ -66,7 +66,9 @@ export const uint32max = 4294967295
export const uint64max = 18446744073709551615n
export function tokenNumber(token, balance) {
return FixedNumber.fromValue(balance, token.decimals, {decimals: token.decimals, width: 256})
const dec = token ? token.decimals : 0
console.log('token dec', dec, balance)
return FixedNumber.fromValue(balance, dec, {decimals: dec, width: 256})
}
export function tokenFloat(token, balance) {

View File

@@ -1,6 +1,6 @@
import {socket} from "@/socket.js";
import {useStore} from "@/store/store.js";
import {flushOrders} from "@/blockchain/wallet.js";
import {flushWalletTransactions} from "@/blockchain/wallet.js";
import {parseElaboratedOrderStatus} from "@/blockchain/orderlib.js";
import {DataFeed} from "./charts/datafeed";
import {notifyFillEvent} from "@/notify.js";
@@ -76,7 +76,7 @@ socket.on('vaults', (chainId, owner, vaults)=>{
s.vaults = vaults
if( vaults.length ) {
const vault = vaults[0]
flushOrders(chainId, owner, 0, vault)
flushWalletTransactions(chainId, owner, 0, vault)
}
}
})

2822
yarn.lock

File diff suppressed because it is too large Load Diff