Skip to content

Commit

Permalink
Remove useUsers dependency and offload to useTestUser temporarily
Browse files Browse the repository at this point in the history
  • Loading branch information
ccali11 committed Sep 12, 2023
1 parent 3c05391 commit 1b2b214
Show file tree
Hide file tree
Showing 9 changed files with 448 additions and 509 deletions.
24 changes: 0 additions & 24 deletions apps/web/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,30 +1,6 @@
<script lang="ts" setup>
import { RouterView } from 'vue-router'
import DefaultLayout from '@/layouts/default-layout.vue'
import useTxData from '@/mockData/mock_transaction_data'
import { onMounted, watch } from 'vue'
import useUsers from '@/composables/users'
const { mockData } = useTxData()
// Need this to fix initilizing bug between user.ts and ssv.ts
const { user } = useUsers()
const runMockData = () =>{
if(user.value?.accounts.length && user.value?.accounts.length > 0){
const walletAddresses = user.value?.accounts.map(item => {
return item.address
}) as string[]
mockData(walletAddresses)
}
}
watch(user, () =>{
runMockData()
})
onMounted(() => {
runMockData()
})
</script>

<template>
Expand Down
10 changes: 0 additions & 10 deletions apps/web/src/composables/contracts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,7 @@ import ICasimirViewsAbi from '@casimir/ethereum/build/abi/ICasimirViews.json'
import useEnvironment from './environment'
import useEthers from '@/composables/ethers'
import useLedger from '@/composables/ledger'
import usePrice from '@/composables/price'
import useTrezor from '@/composables/trezor'
import useUsers from '@/composables/users'
import useFormat from '@/composables/format'
import useWalletConnectV2 from './walletConnectV2'
import { Account, BreakdownAmount, BreakdownString, ContractEventsByAddress, Pool, ProviderString, RegisteredOperator, UserWithAccountsAndOperators } from '@casimir/types'
import { Operator, Scanner } from '@casimir/ssv'
Expand All @@ -35,11 +32,8 @@ const loadingRegisteredOperators = ref(false)

export default function useContracts() {
const { ethersProviderList, getEthersBalance, getEthersBrowserSigner } = useEthers()
const { formatNumber } = useFormat()
const { getEthersLedgerSigner } = useLedger()
const { getCurrentPrice } = usePrice()
const { getEthersTrezorSigner } = useTrezor()
const { user } = useUsers()
const { getWalletConnectSignerV2, nonReactiveWalletConnectWeb3Provider } = useWalletConnectV2()

async function deposit({ amount, walletProvider }: { amount: string, walletProvider: ProviderString }) {
Expand All @@ -65,9 +59,6 @@ export default function useContracts() {
console.log('fees :>> ', fees)
const depositAmount = parseFloat(amount) * ((100 + fees) / 100)
console.log('depositAmount :>> ', depositAmount)
// Get wallet balance to check if user has enough funds to deposit
const walletBalance = await getEthersBalance((user.value as UserWithAccountsAndOperators).accounts[0].address)
console.log('walletBalance :>> ', walletBalance)
const value = ethers.utils.parseEther(depositAmount.toString())
console.log('value :>> ', value)
const result = await managerSigner.depositStake({ value, type: 2 })
Expand Down Expand Up @@ -138,7 +129,6 @@ export default function useContracts() {
})

onUnmounted(() => {
stopListeningForContractEvents()
isMounted.value = false
})

Expand Down
219 changes: 207 additions & 12 deletions apps/web/src/composables/testUser.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { onMounted, onUnmounted, readonly, ref, watch } from 'vue'
import * as Session from 'supertokens-web-js/recipe/session'
import { ethers } from 'ethers'
import { Account, BreakdownAmount, BreakdownString, ContractEventsByAddress, Currency, LoginCredentials, Pool, ProviderString, RegisteredOperator, User, UserWithAccountsAndOperators } from '@casimir/types'
import { Account, BreakdownAmount, BreakdownString, ContractEventsByAddress, Currency, LoginCredentials, Pool, ProviderString, RegisteredOperator, User, UserAnalyticsData, UserWithAccountsAndOperators } from '@casimir/types'
import useContracts from '@/composables/contracts'
import useEnvironment from '@/composables/environment'
import useEthers from '@/composables/ethers'
Expand All @@ -22,10 +22,29 @@ const { getCurrentPrice } = usePrice()
const { loginWithWalletConnectV2 } = useWalletConnect()

const initializeComposable = ref(false)
const user = ref<UserWithAccountsAndOperators | undefined>(undefined)
const nonregisteredOperators = ref<Operator[]>([])
const provider = new ethers.providers.JsonRpcProvider(ethereumUrl)
const rawUserAnalytics = ref<any>(null)
const registeredOperators = ref<Operator[]>([])
const nonregisteredOperators = ref<Operator[]>([])
const user = ref<UserWithAccountsAndOperators | undefined>(undefined)
const userAnalytics = ref<UserAnalyticsData>({
oneMonth: {
labels: [],
data: []
},
sixMonth: {
labels: [],
data: []
},
oneYear: {
labels: [],
data: []
},
historical: {
labels: [],
data: []
}
})

const currentStaked = ref<BreakdownAmount>({
usd: '$0.00',
Expand Down Expand Up @@ -74,6 +93,23 @@ export default function useTestUser() {
}
}

async function addOperator({ address, nodeUrl }: { address: string, nodeUrl: string }) {
try {
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ address, nodeUrl })
}
const response = await fetch(`${usersUrl}/user/add-operator`, requestOptions)
const { error, message } = await response.json()
return { error, message }
} catch (error: any) {
throw new Error(error.message || 'Error adding operator')
}
}

async function blockListener(blockNumber: number) {
console.log('blockNumber :>> ', blockNumber)
const addresses = (user.value as UserWithAccountsAndOperators).accounts.map((account: Account) => account.address) as string[]
Expand All @@ -95,6 +131,117 @@ export default function useTestUser() {
await Promise.all(txs)
}

function computeUserAnalytics() {
// const result = userAnalytics.value
console.log('rawUserAnalytics in computeAnalytics :>> ', rawUserAnalytics)
const sortedTransactions = rawUserAnalytics.value.sort((a: any, b: any) => {
new Date(a.receivedAt).getTime() - new Date(b.receivedAt).getTime()
})

let earliest: any = null
const latest: any = new Date().getTime()
const oneYear = new Date().getTime() - 31536000000
const sixMonths = new Date().getTime() - 15768000000
const oneMonth = new Date().getTime() - 2628000000
sortedTransactions.forEach((tx: any) => {
const receivedAt = new Date(tx.receivedAt)
if (!earliest) earliest = receivedAt.getTime()
if (receivedAt.getTime() < earliest) earliest = receivedAt.getTime()
})
const historicalInterval = (latest - earliest) / 11

sortedTransactions.forEach((tx: any) => {
const { receivedAt, walletAddress, walletBalance } = tx
/* Historical */
let historicalDataIndex = userAnalytics.value.historical.data.findIndex((obj: any) => obj.walletAddress === walletAddress)
if (historicalDataIndex === -1) {
const dataLength = userAnalytics.value.historical.data.push({ walletAddress, walletBalance: Array(12).fill(0) })
historicalDataIndex = dataLength - 1
}
// Determine which interval the receivedAt falls into
const intervalIndex = Math.floor((new Date(receivedAt).getTime() - earliest) / historicalInterval)
// Set the value of the intervalIndex to the walletBalance
userAnalytics.value.historical.data[historicalDataIndex].walletBalance[intervalIndex] = walletBalance

/* One Year */
if (new Date(receivedAt).getTime() > oneYear) {
let oneYearDataIndex = userAnalytics.value.oneYear.data.findIndex((obj: any) => obj.walletAddress === walletAddress)
if (oneYearDataIndex === -1) {
const dataLength = userAnalytics.value.oneYear.data.push({ walletAddress, walletBalance: Array(12).fill(0) })
oneYearDataIndex = dataLength - 1
}
const monthsAgo = (new Date().getFullYear() - new Date(receivedAt).getFullYear()) * 12 + (new Date().getMonth() - new Date(receivedAt).getMonth())
const intervalIndex = 11 - monthsAgo
userAnalytics.value.oneYear.data[oneYearDataIndex].walletBalance[intervalIndex] = walletBalance
}

/* Six Months */
if (new Date(receivedAt).getTime() > sixMonths) {
let sixMonthDataIndex = userAnalytics.value.sixMonth.data.findIndex((obj: any) => obj.walletAddress === walletAddress)
if (sixMonthDataIndex === -1) {
const dataLength = userAnalytics.value.sixMonth.data.push({ walletAddress, walletBalance: Array(6).fill(0) })
sixMonthDataIndex = dataLength - 1
}
const monthsAgo = (new Date().getFullYear() - new Date(receivedAt).getFullYear()) * 12 + (new Date().getMonth() - new Date(receivedAt).getMonth())
const intervalIndex = 5 - monthsAgo
userAnalytics.value.sixMonth.data[sixMonthDataIndex].walletBalance[intervalIndex] = walletBalance
}

/* One Month */
if (new Date(receivedAt).getTime() > oneMonth) {
let oneMonthDataIndex = userAnalytics.value.oneMonth.data.findIndex((obj: any) => obj.walletAddress === walletAddress)
if (oneMonthDataIndex === -1) {
const dataLength = userAnalytics.value.oneMonth.data.push({ walletAddress, walletBalance: Array(30).fill(0) })
oneMonthDataIndex = dataLength - 1
}
const daysAgo = Math.floor((new Date().getTime() - new Date(receivedAt).getTime()) / 86400000)
const intervalIndex = 29 - daysAgo
userAnalytics.value.oneMonth.data[oneMonthDataIndex].walletBalance[intervalIndex] = walletBalance
}
})

const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']

// Set the historical labels array to the interval labels
let previousMonth: any = null
userAnalytics.value.historical.labels = Array(12).fill(0).map((_, i) => {
const date = new Date(earliest + (historicalInterval * i))
const currentMonth = date.getMonth()
if (!previousMonth) {
previousMonth = currentMonth
return date.getMonth() === 0 ? `${date.getFullYear()} ${months[date.getMonth()]} ${date.getDate()}` : `${months[date.getMonth()]} ${date.getDate()}`
} else if (currentMonth < previousMonth) {
previousMonth = currentMonth
return `${date.getFullYear()} ${months[date.getMonth()]} ${date.getDate()}`
} else {
previousMonth = currentMonth
return `${months[date.getMonth()]} ${date.getDate()}`
}
})

// Set the oneYear labels array to the interval labels
userAnalytics.value.oneYear.labels = Array(12).fill(0).map((_, i) => {
const date = new Date (new Date().setDate(1))
const monthIndex = new Date(date.setMonth(date.getMonth() - (11 - i)))
return `${months[monthIndex.getMonth()]} ${monthIndex.getFullYear()}`
})

// Set the sixMonth labels array to the interval labels
userAnalytics.value.sixMonth.labels = Array(6).fill(0).map((_, i) => {
const date = new Date (new Date().setDate(1))
const monthIndex = new Date(date.setMonth(date.getMonth() - (5 - i)))
return `${months[monthIndex.getMonth()]} ${monthIndex.getFullYear()}`
})

// Set the oneMonth labels array to the interval labels
userAnalytics.value.oneMonth.labels = []
for (let i = 30; i > 0; i--) {
const date = new Date().getTime() - ((i - 1) * 86400000)
userAnalytics.value.oneMonth.labels.push(`${new Date(date).getMonth() + 1}/${new Date(date).getDate()}`)
}
// userAnalytics.value = result
}

async function getAllTimeStakingRewards() : Promise<BreakdownAmount> {
try {
/* Get User's Current Stake */
Expand Down Expand Up @@ -241,6 +388,40 @@ export default function useTestUser() {
}
}

async function getUserAnalytics() {
try {
const requestOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}
// TODO: Re-enable this when athena is ready
const response = await fetch(`${usersUrl}/analytics`, requestOptions)
const { error, message, data } = await response.json()
console.log('data from analytics :>> ', data)
// const error = false
// const message = 'User analytics found'

// TODO: Get events, actions, and contract data from the API
// Then format the data to be used in the charts (see computeUserAnalytics) and give to Steve.

// We get the user's analytics (wallet balance) data here.
// const data = txData.value

if (error) throw new Error(message)

// TODO: Pass data from above when the API / data is ready
rawUserAnalytics.value = data

// This compute's the user's wallet balance over time
computeUserAnalytics()
return { error, message, data }
} catch (error: any) {
throw new Error(error.message || 'Error getting user analytics')
}
}

async function getUserOperators(): Promise<void> {
const userAddresses = (user.value as UserWithAccountsAndOperators).accounts.map((account: Account) => account.address) as string[]

Expand Down Expand Up @@ -296,10 +477,9 @@ export default function useTestUser() {
}

async function initializeUser() {
// Update user accounts, operators, analytics
listenForContractEvents()
listenForTransactions()
await refreshBreakdown()
await Promise.all([refreshBreakdown(), getUserOperators(), getUserAnalytics()])
}

function listenForContractEvents() {
Expand Down Expand Up @@ -334,13 +514,13 @@ export default function useTestUser() {
const { provider, address, currency } = loginCredentials
try {
if (ethersProviderList.includes(provider)) {
return await loginWithEthers(loginCredentials)
await loginWithEthers(loginCredentials)
} else if (provider === 'Ledger') {
return await loginWithLedger(loginCredentials, JSON.stringify(pathIndex))
await loginWithLedger(loginCredentials, JSON.stringify(pathIndex))
} else if (provider === 'Trezor') {
return await loginWithTrezor(loginCredentials, JSON.stringify(pathIndex))
await loginWithTrezor(loginCredentials, JSON.stringify(pathIndex))
} else if (provider === 'WalletConnect'){
return await loginWithWalletConnectV2(loginCredentials)
await loginWithWalletConnectV2(loginCredentials)
} else {
// TODO: Implement this for other providers
console.log('Sign up not yet supported for this wallet provider')
Expand Down Expand Up @@ -504,20 +684,35 @@ export default function useTestUser() {
return await fetch(`${usersUrl}/user/update-primary-account`, requestOptions)
}

async function updateUserAgreement(agreed: boolean) {
const requestOptions = {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ agreed })
}
return await fetch(`${usersUrl}/user/update-user-agreement/${user.value?.id}`, requestOptions)
}

const stakeDepositedListener = async () => await refreshBreakdown()
const stakeRebalancedListener = async () => await refreshBreakdown()
const withdrawalInitiatedListener = async () => await refreshBreakdown()

return {
currentStaked: readonly(currentStaked),
nonregisteredOperators: readonly(nonregisteredOperators),
rawUserAnalytics: readonly(rawUserAnalytics),
registeredOperators: readonly(registeredOperators),
stakingRewards: readonly(stakingRewards),
totalWalletBalance: readonly(totalWalletBalance),
user: readonly(user),
nonregisteredOperators: readonly(nonregisteredOperators),
registeredOperators: readonly(registeredOperators),
userAnalytics: readonly(userAnalytics),
addAccountToUser,
addOperator,
login,
logout
logout,
updateUserAgreement
}
}

Expand Down
Loading

0 comments on commit 1b2b214

Please sign in to comment.