121 lines
4.0 KiB
JavaScript
121 lines
4.0 KiB
JavaScript
import {ethers} from "ethers";
|
|
import {getAbi} from "./abi.js";
|
|
import {getProvider, getSigner} from "./blockchain.js";
|
|
import {vaultBalances, vaults} from './cache.js';
|
|
import {chainInfo, VAULT_INIT_CODE_HASH} from "./chain.js";
|
|
import {sendVaultOrders} from "./order.js";
|
|
import {faucet} from "./faucet.js";
|
|
|
|
// Vault
|
|
// address owner
|
|
// balances { tokenAddress: amount }
|
|
// recentOrders []
|
|
|
|
const vaultAbi = await getAbi('Vault')
|
|
const factoryAbi = await getAbi('Factory')
|
|
|
|
|
|
export function vaultAddress(chainId, owner, num=0) {
|
|
try {
|
|
const salt = ethers.solidityPackedKeccak256(['address','uint8'],[owner,num])
|
|
const result = ethers.getCreate2Address(chainInfo[chainId].factory, salt, VAULT_INIT_CODE_HASH)
|
|
// console.log('vaultAddress', chainId, owner, num, chainInfo[chainId].factory, salt, VAULT_INIT_CODE_HASH, result)
|
|
return result
|
|
}
|
|
catch (e) {
|
|
console.error('Could not generate vault address',chainId,owner,num)
|
|
return null
|
|
}
|
|
}
|
|
|
|
|
|
async function emitBalances(socket, chainId, vault) {
|
|
const balances = await vaultBalances.get(chainId, vault);
|
|
socket.emit('vb', chainId, vault, balances !== null ? balances : '{}')
|
|
return balances;
|
|
}
|
|
|
|
|
|
async function sendVaultInfo(socket, chainId, owner) {
|
|
const found = []
|
|
for (let num = 0; ; num++) {
|
|
const vault = vaultAddress(chainId, owner, num)
|
|
if (vault !== null && await vaults.contains(chainId, vault)) {
|
|
found.push(vault)
|
|
const balances = await emitBalances(socket, chainId, vault);
|
|
console.log('found vault', vault, balances)
|
|
} else
|
|
break
|
|
}
|
|
socket.emit('vaults', chainId, owner, found)
|
|
for (const vault of found)
|
|
sendVaultOrders(socket, chainId, vault)
|
|
}
|
|
|
|
export async function loginAddress(socket, chainId, address) {
|
|
if( socket.user_room !== undefined)
|
|
socket.leave(socket.user_room)
|
|
if( address ) {
|
|
socket.user_room = `${chainId}|${address}`
|
|
socket.join(socket.user_room)
|
|
console.log('joined user room', socket.user_room)
|
|
await sendVaultInfo(socket, chainId, address);
|
|
}
|
|
}
|
|
|
|
const ensuring = {}
|
|
|
|
export async function ensureVault(socket, chainId, owner, num) {
|
|
const key = [chainId, owner, num]
|
|
if( key in ensuring )
|
|
return
|
|
ensuring[key] = true
|
|
console.log('ensureVault', chainId, owner, num)
|
|
if( chainId in chainInfo ) {
|
|
const address = vaultAddress(chainId, owner, num)
|
|
if (!await vaults.contains(chainId,address)) {
|
|
try {
|
|
const vault = await createVault(chainId, owner, num)
|
|
console.log(vault)
|
|
if (vault !== null) {
|
|
socket.emit('vaults', chainId, owner, [vault])
|
|
await emitBalances(socket, chainId, vault)
|
|
}
|
|
else
|
|
console.error('got null vault for chainId', chainId)
|
|
} catch {
|
|
}
|
|
}
|
|
else
|
|
console.log('ensureVault', owner, 'exists:', address)
|
|
}
|
|
await sendVaultInfo(socket, chainId, owner)
|
|
delete ensuring[key]
|
|
}
|
|
|
|
|
|
async function createVault(chainId, owner, num) {
|
|
console.log('createVault', chainId, owner, num )
|
|
const signer = getSigner(chainId);
|
|
const deployer = new ethers.Contract(chainInfo[chainId].factory, factoryAbi, signer)
|
|
const vaultAddr = vaultAddress(chainId, owner, num)
|
|
console.log(' ==>', vaultAddr )
|
|
try {
|
|
const tx = await deployer.deployVault(owner, num)
|
|
// console.log(`deploying vault for ${owner} #${num} with tx ${tx.hash}`)
|
|
await tx.wait()
|
|
}
|
|
catch (e) {
|
|
const vault = new ethers.Contract(vaultAddr, vaultAbi, getProvider(chainId))
|
|
try {
|
|
const ver = await vault.version()
|
|
console.log(`vault already deployed at ${vaultAddr} with version ${ver}`)
|
|
}
|
|
catch (e2) {
|
|
console.error('could not deploy vault:',e)
|
|
return null
|
|
}
|
|
}
|
|
return vaultAddr
|
|
}
|