Skip to content

Commit

Permalink
fix: verify pool units (#854)
Browse files Browse the repository at this point in the history
* fix: verify pool units

* fix: resolve promise in transaction page

* fix: update error message copy

* fix: return pool unit or resource

* fix: verify lsu 2 way linking

* chore: add error logging

* fix: update csp policy

* build: increase pod memory
  • Loading branch information
xstelea authored Dec 11, 2023
1 parent f3e3728 commit b51c218
Show file tree
Hide file tree
Showing 11 changed files with 500 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,27 @@ import { callApi } from '@api/gateway'
import { errorPage } from '../../../../stores'
import { resourcesCacheClient } from '@api/utils/resource-cache-client'
import type { NonFungible } from '@api/utils/nfts'
import { http } from '@common/http'
import type { EntityType } from '@common/ret'

const ERROR_MSG = 'Failed to load account data.'

const getEntityTypes = async (
addresses: string[]
): Promise<{ [address: string]: EntityType }> =>
http.post('/api/ret/entity-type', {
addresses
})

const getEntityDetailsFn = (stateVersion: number) => (addresses: string[]) =>
pipe(
() =>
callApi('getEntityDetailsVaultAggregated', addresses, undefined, {
state_version: stateVersion
}),
handleGatewayResult((_) => ERROR_MSG)
)()

const getPoolUnitData =
(stateVersion: number) => async (poolUnits: PoolUnit[]) => {
const poolAddresses = poolUnits.map(
Expand Down Expand Up @@ -206,11 +224,16 @@ export const load: LayoutLoad = ({ params }) => {
})
)
})

const poolData = pipe(
() => Promise.all([accountData, stateVersion]),
andThen(([{ fungible }, stateVersion]) =>
pipe(() => getPoolUnits(fungible), getPoolUnitData(stateVersion))()
pipe(() => {
return getPoolUnits(
fungible,
getEntityTypes,
getEntityDetailsFn(stateVersion)
)
}, andThen(getPoolUnitData(stateVersion)))()
)
)()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,43 @@ import {
} from '../../utils'
import { transformResource } from '@api/utils/entities/resource'
import { isNFTAddress } from '@utils'
import { isStakeUnit } from '@api/utils/entities/stake-unit'
import {
hasValidatorMetadataSet,
verifyStakeUnit
} from '@api/utils/entities/stake-unit'
import { redirect } from '@sveltejs/kit'
import type { PoolUnit } from '@api/utils/entities/pool-unit'
import { callApi } from '@api/gateway'
import { andThen, pipe } from 'ramda'
import { handleGatewayResult } from '../../../../utils'
import { getStringMetadata } from '@api/utils/metadata'
import type { EntityType } from '@common/ret'
import { http } from '@common/http'

const ERROR_MSG = 'Failed to load resource data.'

const getEntityTypes = async (
addresses: string[]
): Promise<{ [address: string]: EntityType }> =>
http.post('/api/ret/entity-type', {
addresses
})

const getEntityDetails = (stateVersion?: number) => (addresses: string[]) =>
pipe(
() =>
callApi(
'getEntityDetailsVaultAggregated',
addresses,
undefined,
stateVersion
? {
state_version: stateVersion
}
: undefined
),
handleGatewayResult((_) => ERROR_MSG)
)()

const getRedeemableTokens = async (poolUnit: PoolUnit) => {
const pool = poolUnit.metadata.standard.pool!.value
Expand All @@ -39,11 +69,16 @@ export const load: PageLoad = async ({ params }) => {

const resource = await getLookupEntity(params.resource)

if (await isStakeUnit(resource)) {
const isValidStakeUnit = await verifyStakeUnit(resource)

if (hasValidatorMetadataSet(resource) && isValidStakeUnit) {
throw redirect(308, `/stake_unit/${encodeURIComponent(params.resource)}`)
}

const transformedResource = transformResource(resource)
const transformedResource = await transformResource(
resource,
getEntityTypes,
getEntityDetails()
)

const redeemableTokens =
transformedResource.type === 'poolUnit'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,35 @@ import { getNftData } from '@api/utils/nft-data'
import { pipe } from 'ramda'
import { handleGatewayResult } from '../../../../utils'

import type { EntityType } from '@common/ret'
import { http } from '@common/http'
import { typedError } from '@utils'

const ERROR_MSG = 'Failed to load transaction data.'

const getEntityTypes = async (
addresses: string[]
): Promise<{ [address: string]: EntityType }> =>
http.post('/api/ret/entity-type', {
addresses
})

const getEntityDetails = (stateVersion?: number) => (addresses: string[]) =>
pipe(
() =>
callApi(
'getEntityDetailsVaultAggregated',
addresses,
undefined,
stateVersion
? {
state_version: stateVersion
}
: undefined
),
handleGatewayResult((_) => ERROR_MSG)
)()

export const load: LayoutLoad = ({ params, data }) => {
const details = pipe(
() => getTransactionDetailsNew(params.transaction),
Expand Down Expand Up @@ -47,14 +76,18 @@ export const load: LayoutLoad = ({ params, data }) => {

if (entitiesResult.isErr()) throw entitiesResult.error

const resourceInfo = entitiesResult.value
.map(transformResource)
.map((resource) => ({
resource,
icon: resource.metadata.standard.icon_url?.value,
name: resource.displayName,
address: resource.address
}))
const resources = await Promise.all(
entitiesResult.value.map((resource) =>
transformResource(resource, getEntityTypes, getEntityDetails())
)
)

const resourceInfo = resources.map((resource) => ({
resource,
icon: resource.metadata.standard.icon_url?.value,
name: resource.displayName,
address: resource.address
}))

const nftIds = tx.balanceChanges.non_fungible_balance_changes.map(
(change) => ({
Expand Down
5 changes: 4 additions & 1 deletion apps/dashboard/src/routes/api/auth/login/+server.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
import type { RequestHandler } from './$types'
import { error, json } from '@sveltejs/kit'
import { authController } from '../../../../server/auth/controller'
import { appLogger } from '@dashboard/server/helpers/logger'

/** @type {import('./$types').RequestHandler} */
export const POST: RequestHandler = async ({ request, cookies }) => {
const requestBody = await request.json()
const result = await authController.login(requestBody, cookies)

if (result.isErr())
if (result.isErr()) {
appLogger.error(result.error)
throw error(result.error.httpResponseCode, result.error.reason)
}

const { authToken, headers } = result.value.data

Expand Down
23 changes: 23 additions & 0 deletions apps/dashboard/src/routes/api/ret/entity-type/+server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { RadixEngineToolkit } from '@common/ret'
import { error, json } from '@sveltejs/kit'
import type { RequestEvent } from './$types'

export const POST = async ({ request }: RequestEvent) => {
const { addresses }: { addresses: string[] } = await request.json()

try {
const entityTypes = await Promise.all(
addresses.map((address) =>
RadixEngineToolkit.Address.entityType(address).then((entityType) => ({
[address]: entityType
}))
)
).then((entityTypes) => entityTypes.reduce((a, b) => ({ ...a, ...b }), {}))

return json(entityTypes, {
status: 200
})
} catch (e) {
return error(400)
}
}
4 changes: 2 additions & 2 deletions deploy/helm/dashboard/environments/pr/values.yaml.gotmpl
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,10 @@ dashboard:
resources:
limits:
cpu: 475m
memory: 128Mi
memory: 256Mi
requests:
cpu: 50m
memory: 128Mi
memory: 256Mi

developerAccess:
pod:
Expand Down
3 changes: 3 additions & 0 deletions packages/ui/src/api/utils/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import type {
StateEntityDetailsResponseComponentDetails,
StateEntityDetailsVaultResponseItem
} from '@common/gateway-sdk'
import type { EntityType } from '@common/ret'

export type Entity =
| Package
Expand Down Expand Up @@ -60,12 +61,14 @@ export const transformEntity =
address: string
metadata: StateEntityDetailsVaultResponseItem['metadata']
details?: StateEntityDetailsVaultResponseItem['details']
entityType?: EntityType
}
>(
entity: E
) => ({
address: entity.address,
entity,
entityType: entity.entityType,
metadata: transformMetadata(entity, standardMetadata),
auth: (entity.details as StateEntityDetailsResponseComponentDetails)
.role_assignments
Expand Down
Loading

0 comments on commit b51c218

Please sign in to comment.