diff --git a/index.html b/index.html
index ad36e49..cd32b0b 100644
--- a/index.html
+++ b/index.html
@@ -11,7 +11,6 @@
-
diff --git a/public/generated.js b/public/generated.js
deleted file mode 100644
index dcd071c..0000000
--- a/public/generated.js
+++ /dev/null
@@ -1,91 +0,0 @@
-known_chains = [
- {
- name: 'Arbitrum One',
- id: 42161,
- icon: null,
- }
-]
-
-_known_tokens = {
- 42161: [ // Arbitrum
- {
- name: 'Wrapped Ether',
- symbol: 'WETH',
- decimals: 18,
- icon: null,
- address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
- },
- {
- name: 'Tether USD',
- symbol: 'USDT',
- decimals: 6,
- icon: null,
- address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
- },
- {
- name: 'USD Coin',
- symbol: 'USDC',
- decimals: 6,
- icon: null,
- address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
- },
- {
- name: 'Wrapped Bitcoin',
- symbol: 'WBTC',
- decimals: 8,
- icon: null,
- address: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',
- },
- {
- name: 'DAI Stablecoin',
- symbol: 'DAI',
- decimals: 18,
- icon: null,
- address: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
- },
- {
- name: 'Uniswap',
- symbol: 'UNI',
- decimals: 18,
- icon: null,
- address: '0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0',
- },
- {
- name: 'Chainlink Token',
- symbol: 'LINK',
- decimals: 18,
- icon: null,
- address: '0xf97f4df75117a78c1A5a0DBb814Af92458539FB4',
- },
- {
- name: 'TrueUSD',
- symbol: 'TUSD',
- decimals: 18,
- icon: null,
- address: '0x4D15a3A2286D883AF0AA1B3f21367843FAc63E07',
- },
- {
- name: 'Lido DAO Token',
- symbol: 'LDO',
- decimals: 18,
- icon: null,
- address: '0x13Ad51ed4F1B7e9Dc168d8a00cB3f4dDD85EfA60',
- },
- {
- name: 'Arbitrum',
- symbol: 'ARB',
- decimals: 18,
- icon: null,
- address: '0x912CE59144191C1204E64559FE8253a0e49E6548',
- },
-
- ]
-};
-
-known_tokens = {}
-
-for( const chainId in _known_tokens ) {
- known_tokens[chainId] = {}
- for( const info of _known_tokens[chainId] )
- known_tokens[chainId][info.address] = info
-}
diff --git a/src/blockchain/abi.js b/src/blockchain/abi.js
index 4e758b1..89be73b 100644
--- a/src/blockchain/abi.js
+++ b/src/blockchain/abi.js
@@ -1,3 +1,34 @@
+
+export const factoryAbi = [
+]
+
+export const queryHelperAbi = [
+ 'function getRoutes(address tokenA,address tokenB) view returns((uint8,uint24,address)[])',
+]
+
+export const poolAbi = [
+ // {
+ // // the current price
+ // uint160 sqrtPriceX96;
+ // // the current tick
+ // int24 tick;
+ // // the most-recently updated index of the observations array
+ // uint16 observationIndex;
+ // // the current maximum number of observations that are being stored
+ // uint16 observationCardinality;
+ // // the next maximum number of observations to store, triggered in observations.write
+ // uint16 observationCardinalityNext;
+ // // the current protocol fee as a percentage of the swap fee taken on withdrawal
+ // // represented as an integer denominator (1/x)%
+ // uint8 feeProtocol;
+ // // whether the pool is locked
+ // bool unlocked;
+ // }
+ 'function slot0() view returns(uint160,int24,uint16,uint16,uint16,uint8,bool)',
+ 'function token0() view returns(address)',
+ 'function token1() view returns(address)',
+]
+
export const erc20Abi = [
'function name() view returns (string)',
'function symbol() view returns (string)',
@@ -38,5 +69,6 @@ export const timedOrderAbi = [
export const abi = {
'ERC20': erc20Abi,
'TimedOrder': timedOrderAbi,
+ 'QueryHelper': queryHelperAbi,
}
diff --git a/src/blockchain/contract.js b/src/blockchain/contract.js
new file mode 100644
index 0000000..6983e1f
--- /dev/null
+++ b/src/blockchain/contract.js
@@ -0,0 +1,20 @@
+import {ethers} from "ethers";
+import {factoryAbi, queryHelperAbi} from "@/blockchain/abi.js";
+import {useStore} from "@/store/store.js";
+import {provider} from "@/blockchain/wallet.js";
+
+
+export async function factoryContract() {
+ const s = useStore()
+ return new ethers.Contract(s.helper, factoryAbi, provider)
+}
+
+export async function queryHelperContract() {
+ const s = useStore()
+ return new ethers.Contract(s.helper, queryHelperAbi, provider)
+}
+
+export async function poolContract(addr) {
+ const s = useStore()
+ return new ethers.Contract(addr, poolAbi, provider)
+}
diff --git a/src/blockchain/wallet.js b/src/blockchain/wallet.js
index f4d5be1..710ac99 100644
--- a/src/blockchain/wallet.js
+++ b/src/blockchain/wallet.js
@@ -1,86 +1,36 @@
import {ethers} from "ethers";
import {useStore} from "@/store/store";
-const store = useStore()
+export let provider = null
+function onChainChanged(chainId) {
+ chainId = Number(chainId)
+ console.log('chain changed', chainId)
+ const store = useStore()
+ store.chainId = chainId
+ provider = new ethers.BrowserProvider(window.ethereum, chainId)
+}
-class Wallet {
-
- connected = false
- _provider = null
- _signer = null
- _onSignerInits = {}
- _enabled = true // prevents tight loops on errors
-
- async connect() {
- this._enabled = true
- if( !this.connected )
- await this.signer()
+function onAccountsChanged(accounts) {
+ console.log('accounts changed', accounts)
+ const store = useStore()
+ if( accounts.length === 0 ) {
+ store.account = null
}
-
- async provider() {
- if (this._provider === null && this._enabled) {
- console.log('creating provider')
- const provider = new ethers.BrowserProvider(window.ethereum, store.chain.id)
- await provider.getNetwork() // this invokes a check on having the correct network connected
- this._provider = provider
- console.log('wallet connected')
- }
- return this._provider
- }
-
- async signer() {
-/*
- if( !store.geo.approved ) {
- console.log('not approved')
- this._connected(false)
- return null
- }
-*/
- const provider = await this.provider()
- if( provider === null ) {
- console.log('provider null')
- this._connected(false)
- return null
- }
- const signer = await provider.getSigner()
- if( this._signer?.address !== signer.address ) {
- console.log('new signer', signer.address)
- this._signer = signer
- for (const key in this._onSignerInits) {
- try {
- await this._onSignerInits[key](signer)
- }
- catch (e) {
- console.log('during onSignerInit', e)
- }
- }
- console.log('wallet connected')
- }
- this._connected(true)
- return signer
- }
-
- async address() {
- const signer = await this.signer()
- if( signer === null )
- return null
- return await signer.getAddress()
- }
-
- _connected(value) {
- this.connected = value
- store.$patch({wallet:{connected:value}})
- }
-
- onSignerInit(id, cb) {
- this._onSignerInits[id] = cb
+ else if (accounts[0] !== store.account) {
+ store.account = accounts[0]
}
+}
+export async function watchWallet() {
+ const chainId = (await new ethers.BrowserProvider(window.ethereum).getNetwork()).chainId
+ onChainChanged(chainId)
+ window.ethereum.on('chainChanged', onChainChanged);
+ window.ethereum.on('accountsChanged', onAccountsChanged);
}
-const handler = {
+const errorHandlingProxy = {
get(target, prop, proxy) {
const got = Reflect.get(target, prop, proxy);
if( typeof got !== 'function' ) {
@@ -95,8 +45,11 @@ const handler = {
target._connected(false)
target._enabled = false
if( x.code === 'NETWORK_ERROR' ) {
- store.error('Wrong Blockchain', 'Your wallet is connected to a different blockchain. Please select '+import.meta.env.VITE_CHAIN_NAME+' in your wallet.')
- console.log('wallet network error', x)
+ // todo available chain names
+ // store.error('Wrong Blockchain', 'Your wallet is connected to a different blockchain. Please select Arbitrum in your wallet.') // todo hardcoded arb
+ console.log('wallet chain error', x)
+ // store.chainId = store.chainInfo[]
+ throw x
}
else {
console.log('wallet error')
@@ -109,4 +62,4 @@ const handler = {
}
-export default new Proxy(new Wallet(), handler)
+// const wallet = new Proxy(new Wallet(), errorHandlingProxy);
diff --git a/src/components/Alerts.vue b/src/components/Alerts.vue
new file mode 100644
index 0000000..0022ef5
--- /dev/null
+++ b/src/components/Alerts.vue
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
diff --git a/src/components/ConnectWallet.vue b/src/components/ConnectWallet.vue
new file mode 100644
index 0000000..ec154dd
--- /dev/null
+++ b/src/components/ConnectWallet.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/src/components/NeedsQueryHelper.vue b/src/components/NeedsQueryHelper.vue
new file mode 100644
index 0000000..0668896
--- /dev/null
+++ b/src/components/NeedsQueryHelper.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
diff --git a/src/components/NeedsWallet.vue b/src/components/NeedsWallet.vue
new file mode 100644
index 0000000..bdc5bc8
--- /dev/null
+++ b/src/components/NeedsWallet.vue
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
diff --git a/src/components/PairEntry.vue b/src/components/PairEntry.vue
index b2b0c99..c485a82 100644
--- a/src/components/PairEntry.vue
+++ b/src/components/PairEntry.vue
@@ -1,14 +1,14 @@
-
+
-
+
-
+
-
+
@@ -16,15 +16,52 @@
diff --git a/src/components/PhoneCard.vue b/src/components/PhoneCard.vue
new file mode 100644
index 0000000..a584187
--- /dev/null
+++ b/src/components/PhoneCard.vue
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/TimedOrderEntry.vue b/src/components/TimedOrderEntry.vue
index 279b284..c11ddb8 100644
--- a/src/components/TimedOrderEntry.vue
+++ b/src/components/TimedOrderEntry.vue
@@ -1,80 +1,124 @@
-
-
-
-
-
-
- {{ amountIsBase ? pair.tokenA.symbol : pair.tokenB.symbol }}
-
-
-
-
-
-
-
- {{ amountIsTotal ? 'Split into' : 'Times' }}
-
-
- tranches
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{ inverted ? pair.tokenB.symbol + '/' + pair.tokenA.symbol : pair.tokenA.symbol + '/' + pair.tokenB.symbol }}
-
-
-
-
+
+
+ DCA / TWAP
+ Split order across time
+
-
+
-
- Cancel
- Place Order
-
-
+
+ {{ s.chain.name }}
+
+ v3
+ {{pairSymbol}} {{r.fee/10000}}%
+
+
+
+ Searching for {{pairSymbol}} pools...
+
+
+
+
+
+
+
+
+ {{ amountIsBase ? pair.tokenA.symbol : pair.tokenB.symbol }}
+
+
+
+
+
+
+
+
+ tranches
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{
+ inverted ? pair.tokenB.symbol + '/' + pair.tokenA.symbol : pair.tokenA.symbol + '/' + pair.tokenB.symbol
+ }}
+
+
+
+
+
+
+
+
+
+ Cancel
+ Place Order
+
+
+
+
+
diff --git a/src/main.js b/src/main.js
index f90c7aa..37b67a9 100644
--- a/src/main.js
+++ b/src/main.js
@@ -13,14 +13,11 @@ import { createApp } from 'vue'
// Plugins
import { registerPlugins } from '@/plugins'
import '@/styles/style.scss'
-import {useStore} from "@/store/store.js";
+import {watchWallet} from "@/blockchain/wallet.js";
+import "./socket.js"
const app = createApp(App)
registerPlugins(app)
-const s = useStore()
-s.chains = known_chains
-s.chain = known_chains[0]
-
app.mount('#app')
-
+await watchWallet()
diff --git a/src/misc.js b/src/misc.js
new file mode 100644
index 0000000..3636d89
--- /dev/null
+++ b/src/misc.js
@@ -0,0 +1,35 @@
+
+export class SingletonCoroutine {
+ constructor(f, delay=10, retry=true) {
+ this.f = f
+ this.delay = delay
+ this.timeout = null
+ this.args = null
+ }
+
+ pending() {
+ return this.timeout !== null
+ }
+
+ invoke(/*arguments*/) {
+ this.args = arguments
+ if( this.timeout !== null )
+ clearTimeout(this.timeout)
+ this.timeout = setTimeout(this.onTimeout, this.delay, this)
+ }
+
+ async onTimeout(self) {
+ self.timeout = null
+ console.log('invoking', self.f, self.args)
+ try {
+ await self.f(...self.args)
+ }
+ catch (e) {
+ if( self.retry )
+ self.invoke(self.args)
+ else
+ console.error(e)
+ }
+ }
+
+}
diff --git a/src/plugins/webfontloader.js b/src/plugins/webfontloader.js
index ab2fa89..0db0831 100644
--- a/src/plugins/webfontloader.js
+++ b/src/plugins/webfontloader.js
@@ -5,8 +5,8 @@
*/
// todo choose
-const displayFonts = ['Tektur', 'Turret Road', 'Chakra Petch', 'Orbitron', 'Quantico', 'Geo']
-const bodyFonts = ['Victor Mono', 'Nunito', 'Manrope', 'Sofia Sans']
+const displayFonts = ['Orbitron', 'Tektur', 'Turret Road', 'Chakra Petch', 'Quantico', 'Geo']
+const bodyFonts = ['Exo 2', 'Victor Mono', 'Nunito', 'Manrope', 'Sofia Sans', 'Dosis', 'PT Sans', 'Space Grotesk', 'Rajdhani', 'Saira Semi Condensed', 'Jura']
export async function loadFonts () {
const webFontLoader = await import(/* webpackChunkName: "webfontloader" */'webfontloader')
diff --git a/src/socket.js b/src/socket.js
index bc64f4b..7d4a619 100644
--- a/src/socket.js
+++ b/src/socket.js
@@ -1,4 +1,5 @@
import {io} from "socket.io-client";
+import {useStore} from "@/store/store.js";
export const socket = io(import.meta.env.VITE_WS_URL || undefined, { transports: ["websocket"] })
@@ -14,3 +15,7 @@ socket.on('welcome', (data)=>{
console.log('welcome',data)
})
+socket.on('chainInfo', async (chainInfo)=>{
+ const s = useStore()
+ s.chainInfo = chainInfo
+})
diff --git a/src/store/store.js b/src/store/store.js
index aa35c9e..0d9ccd3 100644
--- a/src/store/store.js
+++ b/src/store/store.js
@@ -1,33 +1,44 @@
// Utilities
import { defineStore } from 'pinia'
+import {knownTokens} from "@/tokens.js";
export const useStore = defineStore('app', {
state: () => ({
- chain: {name:'Not Connected', id:0, icon:''},
- wallet: {
- connected: false,
- },
- errors: [],
- extraTokens: {},
+ chainInfo: null,
+ chainId: null,
+ account: null,
vault: null,
+ errors: [{
+ title: 'DANGER!',
+ text: 'This is early development (alpha) software, which could have severe bugs that lose all your money. Thank you for testing a SMALL amount!',
+ closeable: false
+ }],
+ extraTokens: {},
}),
getters: {
+ chain: (s)=> !s.chainInfo ? null : (s.chainInfo[s.chainId] || null),
tokens: (s)=>{
- const extras = s.extraTokens[s.chain.id]
- return extras === undefined ? Object.values(known_tokens[s.chain.id])
- : [...Object.values(known_tokens[s.chain.id]), ...Object.values(extras)]
+ console.log('tokensget',s)
+ let known = knownTokens[s.chainId]
+ known = known ? Object.values(known) : []
+ let extras = s.extraTokens[s.chainId]
+ extras = extras ? Object.values(extras) : []
+ console.log('tokens for chainId',s.chainId, known, extras)
+ return [...known, ...extras]
},
+ factory: (s)=>!s.chain?null:s.chain.factory,
+ helper: (s)=>!s.chain?null:s.chain.helper,
},
actions: {
- error(title, message) {
- this.errors.push({title:title, message:message})
+ error(title, text, closeable=true) {
+ this.errors.push({title, text, closeable})
},
- closeError(title, message) {
- console.log('closing error', title, message)
+ closeError(title, text) {
+ console.log('closing error', title, text)
const result = []
- this.errors.forEach((i)=>{if(i.title!==title && i.message!==message) result.push(i)})
+ this.errors.forEach((i)=>{if(i.title!==title && i.text!==text) result.push(i)})
this.errors = result
},
- }
+ },
})
diff --git a/src/styles/settings.scss b/src/styles/settings.scss
index 724e646..d93f624 100644
--- a/src/styles/settings.scss
+++ b/src/styles/settings.scss
@@ -11,4 +11,6 @@
//$variable: false,
$body-font-family: v.$body-font-family,
$heading-font-family: v.$heading-font-family,
+ $card-title-font-size: 24px,
+ $app-bar-title-font-size: 32px,
);
diff --git a/src/styles/style.scss b/src/styles/style.scss
index 93d3248..46dc307 100644
--- a/src/styles/style.scss
+++ b/src/styles/style.scss
@@ -18,9 +18,17 @@
.v-list-subheader {
font-family: v.$heading-font-family;
}
+
+ input {
+ text-align: center;
+ }
+
+ .v-field__input {
+ justify-content: center;
+ }
+
}
-
-.sc {
- font-family: v.$heading-font-family;
+.uniswap-pink {
+ color: v.$uniswap-pink;
}
diff --git a/src/styles/vars.scss b/src/styles/vars.scss
index 5da18a8..71eced0 100644
--- a/src/styles/vars.scss
+++ b/src/styles/vars.scss
@@ -7,6 +7,8 @@ $blue: #0033CC;
$white: #fffefd; // just a touch green
$black: #000102;
+$uniswap-pink: #ff007a;
+
$primary: $blue;
$primary-50: transparentize($primary,0.5);
$primary-25: transparentize($primary,0.75);
@@ -29,10 +31,19 @@ $all-colors: (
green: $green,
yellow: $yellow,
red: $red,
+ uniswap: $uniswap-pink,
);
+$body-font-family: 'Saira Semi Condensed', monospace, sans-serif; // fairly geometric, horizontal s's, clean sans, readable
+//$body-font-family: 'Exo 2', monospace, sans-serif; // good, works with Orbitron
+//$body-font-family: 'Jura', monospace, sans-serif; // interesting numbers, zero dot. l-foot but the s is too twisty with light serifs
+//$body-font-family: 'Manrope', monospace, sans-serif; // readable, clean, works with Orbitron
//$body-font-family: 'Victor Mono', monospace, sans-serif;
-$body-font-family: 'Manrope', monospace, sans-serif;
+//$body-font-family: 'Space Grotesk', monospace, sans-serif; // silly serifs on caps
+//$body-font-family: 'Rajdhani', monospace, sans-serif; // very thin a little hard to read
+//$body-font-family: 'Dosis', monospace, sans-serif; // a little informal, to Dilbert-y
+//$body-font-family: 'PT Sans', monospace, sans-serif; // not bad but numbers are too seriffy
+//$body-font-family: 'Cairo', monospace, sans-serif; // number baseline is jagged
//$body-font-family: 'Nunito', monospace, sans-serif;
//$body-font-family: 'Sofia Sans', monospace, sans-serif;
//$body-font-family: 'Quantico', sans-serif;
@@ -43,4 +54,4 @@ $heading-font-family: 'Orbitron', sans-serif;
//$heading-font-family: 'Chakra Petch', sans-serif;
$sm-breakpoint: 600px;
-$card-maxw: 30rem;
+$card-maxw: 40em;
diff --git a/src/tokens.js b/src/tokens.js
new file mode 100644
index 0000000..8aca02e
--- /dev/null
+++ b/src/tokens.js
@@ -0,0 +1,94 @@
+export const knownTokens = {};
+
+const known_chains = [
+ {
+ name: 'Arbitrum One',
+ id: 42161,
+ icon: null,
+ }
+]
+
+const arbitrumTokens = [
+ {
+ name: 'Wrapped Ether',
+ symbol: 'WETH',
+ decimals: 18,
+ icon: null,
+ address: '0x82aF49447D8a07e3bd95BD0d56f35241523fBab1',
+ },
+ {
+ name: 'Tether USD',
+ symbol: 'USDT',
+ decimals: 6,
+ icon: null,
+ address: '0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9',
+ },
+ {
+ name: 'USD Coin',
+ symbol: 'USDC',
+ decimals: 6,
+ icon: null,
+ address: '0xaf88d065e77c8cC2239327C5EDb3A432268e5831',
+ },
+ {
+ name: 'Wrapped Bitcoin',
+ symbol: 'WBTC',
+ decimals: 8,
+ icon: null,
+ address: '0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f',
+ },
+ {
+ name: 'DAI Stablecoin',
+ symbol: 'DAI',
+ decimals: 18,
+ icon: null,
+ address: '0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1',
+ },
+ {
+ name: 'Uniswap',
+ symbol: 'UNI',
+ decimals: 18,
+ icon: null,
+ address: '0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0',
+ },
+ {
+ name: 'Chainlink Token',
+ symbol: 'LINK',
+ decimals: 18,
+ icon: null,
+ address: '0xf97f4df75117a78c1A5a0DBb814Af92458539FB4',
+ },
+ {
+ name: 'TrueUSD',
+ symbol: 'TUSD',
+ decimals: 18,
+ icon: null,
+ address: '0x4D15a3A2286D883AF0AA1B3f21367843FAc63E07',
+ },
+ {
+ name: 'Lido DAO Token',
+ symbol: 'LDO',
+ decimals: 18,
+ icon: null,
+ address: '0x13Ad51ed4F1B7e9Dc168d8a00cB3f4dDD85EfA60',
+ },
+ {
+ name: 'Arbitrum',
+ symbol: 'ARB',
+ decimals: 18,
+ icon: null,
+ address: '0x912CE59144191C1204E64559FE8253a0e49E6548',
+ },
+];
+
+const _knownTokens = {
+ 42161: arbitrumTokens,
+ 1338: arbitrumTokens,
+};
+
+for( const chainId in _knownTokens ) {
+ knownTokens[chainId] = {}
+ for( const info of _knownTokens[chainId] )
+ knownTokens[chainId][info.address] = info
+}
+