Skip to content

Commit

Permalink
Implement add/remove account
Browse files Browse the repository at this point in the history
  • Loading branch information
ccali11 committed Mar 28, 2023
1 parent 0931a86 commit 8bcf7af
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 48 deletions.
28 changes: 12 additions & 16 deletions apps/web/src/composables/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import useSSV from '@/composables/ssv'
import useWallet from '@/composables/wallet'
import { onMounted, ref } from 'vue'
import { User } from '@casimir/types'
import { Account } from '@casimir/types'
import { Currency } from '@casimir/types'
import { AddAccountOptions } from '@casimir/types'
import { RemoveAccountOptions } from '@casimir/types'
import { ProviderString } from '@casimir/types'

const { usersBaseURL, ethereumURL } = useEnvironment()
Expand Down Expand Up @@ -60,42 +60,38 @@ export default function useUsers () {
// subscribeToUserEvents()
// })

async function addAccount(provider: ProviderString, address: string, currency: Currency): Promise<{ error: boolean, message: string, data: User | null }> {
address = address.toLowerCase()
const accountToAdd = {
address,
walletProvider: provider,
ownerAddress: user.value?.Address,
}
async function addAccount(account: AddAccountOptions): Promise<{ error: boolean, message: string, data: User | null }> {
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ account: accountToAdd })
body: JSON.stringify({ account })
}
const response = await fetch(`${usersBaseURL}/user/add-sub-account`, requestOptions)
const { data: userAccount } = await response.json()
user.value = userAccount
return { error: false, message: `Account added to user: ${userAccount}`, data: userAccount }
}

// TODO: Refactor this next. 2/14
async function removeAccount(provider: ProviderString, address: string, currency: Currency) {
async function removeAccount({ address, currency, ownerAddress, walletProvider }: RemoveAccountOptions) {
address = address.toLowerCase()
const requestOptions = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
primaryAddress: user.value?.address,
provider,
address,
currency
currency,
ownerAddress,
walletProvider,
})
}
return await fetch(`${usersBaseURL}/user/remove-sub-account`, requestOptions)
const response = await fetch(`${usersBaseURL}/user/remove-sub-account`, requestOptions)
const { data: userAccount } = await response.json()
user.value = userAccount
return { error: false, message: `Account removed from user: ${userAccount}`, data: userAccount }
}

async function getMessage(address: string) {
Expand Down
32 changes: 23 additions & 9 deletions apps/web/src/composables/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,25 +124,33 @@ export default function useWallet() {
}
loadingUserWallets.value = false
} else { // Add account
console.log('already logged in! attempting to add account')
console.log('already logged in')
console.log('checking if account exists on user')
const connectedAddress = await getConnectedAddressFromProvider(provider, currency) // TODO: Remove currency from here? Maybe not.
const connectedCurrency = await detectCurrencyInProvider(provider, currency) as Currency
const accountExists = user.value?.Accounts?.some((account: Account) => account.address === connectedAddress && account.wallet_provider === provider)
console.log('accountExists :>> ', accountExists)
if (accountExists) {
alert('Account already exists; setting provider, address, and currency')
setSelectedProvider(provider)
setSelectedAddress(connectedAddress)
setSelectedCurrency(connectedCurrency)
return user.value
} else {
// If no, add account using users api
const response = await addAccount(provider, connectedAddress, connectedCurrency)
console.log('adding sub account')
const account = {
address: connectedAddress.toLowerCase(),
currency: connectedCurrency,
ownerAddress: user?.value?.Address.toLowerCase(),
walletProvider: provider
}
const response = await addAccount(account)
// If api query is successful, set the user.value = to the response data (which should be the user)
if (!response?.error) {
setSelectedProvider(provider)
setSelectedAddress(connectedAddress)
setSelectedCurrency(connectedCurrency)
primaryAddress.value = response.data?.address as string
primaryAddress.value = response.data?.Address as string
}
}
}
Expand Down Expand Up @@ -236,11 +244,17 @@ export default function useWallet() {
if (selectedAddress.value === primaryAddress.value) {
return alert('Cannot remove primary account')
} else if (ethersProviderList.includes(selectedProvider.value)) {
const result = await removeAccount(selectedProvider.value, selectedAddress.value, selectedCurrency.value)
const json = await result.json()
if (!json.error) {
setSelectedAddress(json.data.address)
json.data.accounts.forEach((account: Account) => {
const opts = {
address: selectedAddress.value,
currency: selectedCurrency.value,
ownerAddress: primaryAddress.value,
walletProvider: selectedProvider.value
}
const result = await removeAccount(opts)
console.log('result :>> ', result)
if (!result.error) {
setSelectedAddress(result.data.address)
result.data.Accounts.forEach((account: Account) => {
if (account.address === selectedAddress.value) {
setSelectedProvider(account.walletProvider as ProviderString)
setSelectedCurrency(account.currency as Currency)
Expand Down
25 changes: 20 additions & 5 deletions services/users/src/providers/db.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Postgres } from '@casimir/data'
import { pascalCase } from '@casimir/helpers'
import { Account, User, UserAddedSuccess } from '@casimir/types'
import { Account, RemoveAccountOptions, User, UserAddedSuccess } from '@casimir/types'

const postgres = new Postgres({
// These will become environment variables
Expand All @@ -21,9 +21,9 @@ export default function useDB() {
*/
async function addAccount(account: Account, createdAt?: string) : Promise<Account> {
if (!createdAt) createdAt = new Date().toISOString()
const { address, ownerAddress, walletProvider } = account
const text = 'INSERT INTO accounts (address, owner_address, wallet_provider, created_at) VALUES ($1, $2, $3, $4) RETURNING *;'
const params = [address, ownerAddress, walletProvider, createdAt]
const { address, currency, ownerAddress, walletProvider } = account
const text = 'INSERT INTO accounts (address, currency, owner_address, wallet_provider, created_at) VALUES ($1, $2, $3, $4, $5) RETURNING *;'
const params = [address, currency, ownerAddress, walletProvider, createdAt]
const rows = await postgres.query(text, params)
return rows[0] as Account
}
Expand Down Expand Up @@ -60,6 +60,21 @@ export default function useDB() {
return formatResult(user) as User
}

/**
* Remove an account.
* @param address - The account's address (pk)
* @param ownerAddress - The account's owner address
* @param walletProvider - The account's wallet provider
* @param currency - The account's currency
* @returns The removed account if found, otherwise undefined
*/
async function removeAccount({ address, currency, ownerAddress, walletProvider } : RemoveAccountOptions) {
const text = 'DELETE FROM accounts WHERE address = $1 AND owner_address = $2 AND wallet_provider = $3 AND currency = $4 RETURNING *;'
const params = [address, ownerAddress, walletProvider, currency]
const rows = await postgres.query(text, params)
return rows[0] as Account
}

/**
* Add or update nonce for an address.
* @param address - The address
Expand Down Expand Up @@ -99,7 +114,7 @@ export default function useDB() {
}
}

return { addAccount, addUser, getUser, upsertNonce }
return { addAccount, addUser, getUser, removeAccount, upsertNonce }
}

/**
Expand Down
1 change: 1 addition & 0 deletions services/users/src/routes/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ router.post('/login', async (req: express.Request, res: express.Response) => {
}
const account = {
address,
currency,
ownerAddress: address,
walletProvider: provider,
} as Account
Expand Down
38 changes: 20 additions & 18 deletions services/users/src/routes/user.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { SessionRequest } from 'supertokens-node/framework/express'
import useDB from '../providers/db'

const router = express.Router()
const { getUser, addAccount } = useDB()
const { addAccount, getUser, removeAccount } = useDB()

router.get('/', verifySession(), async (req: SessionRequest, res: express.Response) => {
const address = req.session?.getUserId() as string
Expand Down Expand Up @@ -57,38 +57,40 @@ router.post('/add-sub-account', verifySession(), async (req: SessionRequest, res
}
})

router.post('/remove-sub-account', verifySession(), async (req: express.Request, res: express.Response) => {
router.post('/remove-sub-account', verifySession(), async (req: SessionRequest, res: express.Response) => {
try {
const { provider, address, currency } = req.body
let { primaryAddress } = req.body
primaryAddress = primaryAddress.toLowerCase()
const existingUser = userCollection.find(user => user.address === primaryAddress)
let accountedRemoved = false
if (existingUser) {
existingUser.accounts = existingUser.accounts?.filter(account => {
const notAddress = account.walletProvider !== provider || account.address !== address || account.currency !== currency
if (!notAddress) {
accountedRemoved = true
} else {
return account
}
console.log('REMOVING ACCOUNT!')
const { address, currency, ownerAddress, walletProvider } = req.body
const userSessionsAddress = req.session?.getUserId()
const validatedAddress = validateAddress(userSessionsAddress, ownerAddress)
if (!validatedAddress) {
res.setHeader('Content-Type', 'application/json')
res.status(200)
res.json({
message: 'Address does not match session',
error: true,
data: null
})
return
}
if (accountedRemoved) {
const accountRemoved = await removeAccount({ address, currency, ownerAddress, walletProvider })
const user = await getUser(ownerAddress)

if (accountRemoved) {
res.setHeader('Content-Type', 'application/json')
res.status(200)
res.json({
message: 'Account removed',
error: false,
data: existingUser
data: user
})
} else {
res.setHeader('Content-Type', 'application/json')
res.status(200)
res.json({
message: 'Account not found',
error: true,
data: existingUser
data: user
})
}
} catch (err) {
Expand Down

0 comments on commit 8bcf7af

Please sign in to comment.