Skip to content

Commit

Permalink
Merge pull request #52 from dappforce/fix-balances
Browse files Browse the repository at this point in the history
Fix parsing balances
  • Loading branch information
olehmell authored Oct 23, 2023
2 parents f4dae6c + acca0c4 commit 4504dbd
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 24 deletions.
12 changes: 6 additions & 6 deletions src/connections/networks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ export const kusamaParachains: Networks = {
},
heiko: {
name: 'Parallel Heiko',
...resolveOnfinalityUrl('parallel-heiko'),
node: 'wss://heiko-rpc.parallel.fi',
icon: 'parallel.svg',
nativeToken: 'HKO',
paraId: 2085,
Expand Down Expand Up @@ -241,7 +241,7 @@ export const kusamaParachains: Networks = {
},
bitCountry: {
name: 'Bit.Country Pioneer',
...resolveOnfinalityUrl('pioneer'),
node: 'wss://pioneer-rpc-3.bit.country/wss',
icon: 'bitcountry.svg',
paraId: 2096,
vestingMethod: 'vesting.vest',
Expand Down Expand Up @@ -342,7 +342,7 @@ export const kusamaParachains: Networks = {
},
invArch: {
name: 'InvArch Tinkernet',
...resolveOnfinalityUrl('invarch-tinkernet'),
node: 'wss://tinkernet-rpc.dwellir.com',
nativeToken: 'TNKR',
paraId: 2125,
icon: 'invArch.png',
Expand Down Expand Up @@ -471,7 +471,7 @@ export const polkadotParachains: Networks = {
},
parallel: {
name: 'Parallel',
...resolveOnfinalityUrl('parallel'),
node: 'wss://parallel-rpc.dwellir.com',
icon: 'parallel.svg',
paraId: 2012,
vestingMethod: 'vesting.claim',
Expand Down Expand Up @@ -519,7 +519,7 @@ export const polkadotParachains: Networks = {
},
interlay: {
name: 'Interlay',
...resolveOnfinalityUrl('interlay'),
node: 'wss://interlay-rpc.dwellir.com',
icon: 'interlay.svg',
paraId: 2032,
nativeToken: 'INTR',
Expand Down Expand Up @@ -557,7 +557,7 @@ export const polkadotParachains: Networks = {
hydradx: {
name: 'HydraDX',
icon: 'snakenet.svg',
...resolveOnfinalityUrl('hydradx'),
node: 'wss://hydradx-rpc.dwellir.com',
paraId: 2034,
vestingMethod: 'vesting.claim',
isTransferable: true,
Expand Down
73 changes: 55 additions & 18 deletions src/services/balances/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,56 +3,87 @@ import BN from 'bn.js'
import { getGenshiroTokens } from './genshiro'
import { getOrUpdatePropertiesByNetwork } from '../properties'
import { asTypesGenerator } from '../../utils'
import { bnMax } from '@polkadot/util'

export type TokenBalances = Record<string, any>

const getNativeTokenBalance = async (api: ApiPromise, account: string) => {
const { data: { feeFrozen, free, miscFrozen, reserved } }: any =
await api.query.system.account(account)
const {
data: { free, frozen, reserved }
}: any = await api.query.system.account(account)

return parseBalances(free, reserved, feeFrozen, { frozenMisc: miscFrozen?.toString() })
const locks = await api.query.balances.locks(account)

const lockedBalance = locks.length && bnMax(...(locks.map(({ amount }) => amount)))

const totalBalance = reserved ? free.add(reserved) || 0 : free

const freeBalance = lockedBalance ? free.sub(lockedBalance) : free

return {
totalBalance: totalBalance?.toString(),
reservedBalance: reserved?.toString(),
frozenBalance: frozen?.toString(),
freeBalance: freeBalance?.toString(),
lockedBalance: lockedBalance?.toString()
}
}

type Balances = {
freeBalance: string
reservedBalance: string
frozenFee: string
frozen: string
totalBalance: string
}

export const parseBalances = (free?: BN, reserved?: BN, frozen?: BN, other?: Record<string, any>) => {
export const parseBalances = (
free?: BN,
reserved?: BN,
frozen?: BN,
other?: Record<string, any>
) => {
const totalBalance = reserved ? free.add(reserved) || 0 : free

return {
freeBalance: free?.toString(),
reservedBalance: reserved?.toString(),
frozenFee: frozen?.toString(),
frozen: frozen?.toString(),
totalBalance: totalBalance?.toString(),
...other
}
}

type GetBalancesType = (api: ApiPromise, network: string, account: string, tokens?: any[]) => Promise<TokenBalances>
type GetBalancesType = (
api: ApiPromise,
network: string,
account: string,
tokens?: any[]
) => Promise<TokenBalances>

type TokenBalanceData = {
free?: BN
frozen?: BN
reserved?: BN
}
function defaultOrmlTokenGetter (api: ApiPromise, { account, token }: { account: string, token: any }): Promise<TokenBalanceData> {
function defaultOrmlTokenGetter(
api: ApiPromise,
{ account, token }: { account: string; token: any }
): Promise<TokenBalanceData> {
return api.query.tokens.accounts(account, token) as any
}

const customOrmlTokenGetter = asTypesGenerator<
(...params: Parameters<typeof defaultOrmlTokenGetter>) => ReturnType<typeof defaultOrmlTokenGetter>
(
...params: Parameters<typeof defaultOrmlTokenGetter>
) => ReturnType<typeof defaultOrmlTokenGetter>
>()({
'assets.account': async (api, { account, token }) => {
const balancesCodec = await api.query.assets.account(token, account)
const data = balancesCodec.toPrimitive()
const { isFrozen, balance } = data || {} as any
const { isFrozen, balance } = data || ({} as any)
const balanceData: TokenBalanceData = {
free: new BN(0),
frozen: new BN(0),
frozen: new BN(0)
}
balanceData[isFrozen ? 'frozen' : 'free'] = new BN(balance)
return balanceData
Expand Down Expand Up @@ -87,7 +118,8 @@ const ormlTokenGetterNetworkMapper: { [key: string]: keyof typeof customOrmlToke
const getOrmlTokens: GetBalancesType = async (api, network, account, tokens) => {
const tokenBalances: TokenBalances = {}

const balanceGetter = customOrmlTokenGetter[ormlTokenGetterNetworkMapper[network] ?? ''] ?? defaultOrmlTokenGetter
const balanceGetter =
customOrmlTokenGetter[ormlTokenGetterNetworkMapper[network] ?? ''] ?? defaultOrmlTokenGetter
const balancePromise = tokens.map(async (token) => {
try {
let balances = {} as unknown as Balances
Expand All @@ -113,10 +145,10 @@ const getOrmlTokens: GetBalancesType = async (api, network, account, tokens) =>
return tokenBalances
}

const getOnlyOrmlTokens = async (api: ApiPromise, account: string, network: string) =>{
const getOnlyOrmlTokens = async (api: ApiPromise, account: string, network: string) => {
const props = await getOrUpdatePropertiesByNetwork(api, network)
const tokenSymbols = props?.tokenSymbols as string[] || []
const tokens = props?.assetsRegistry as Record<string, any> || {}
const tokenSymbols = (props?.tokenSymbols as string[]) || []
const tokens = (props?.assetsRegistry as Record<string, any>) || {}

return getOrmlTokens(api, network, account, [...tokenSymbols, ...Object.values(tokens)])
}
Expand All @@ -125,8 +157,8 @@ const getNativeAndOrmlTokens = async (api: ApiPromise, account: string, network:
const tokenBalances: TokenBalances = {}

const props = await getOrUpdatePropertiesByNetwork(api, network)
const tokenSymbols = props?.tokenSymbols as string[] || []
const tokens = props?.assetsRegistry as Record<string, any> || {}
const tokenSymbols = (props?.tokenSymbols as string[]) || []
const tokens = (props?.assetsRegistry as Record<string, any>) || {}
const [native] = tokenSymbols

tokenBalances[native] = await getNativeTokenBalance(api, account)
Expand All @@ -138,7 +170,12 @@ const getNativeAndOrmlTokens = async (api: ApiPromise, account: string, network:
}
}

type GetOrmlBalancesType = (api: ApiPromise, account: string, network: string, tokens?: any[]) => Promise<TokenBalances>
type GetOrmlBalancesType = (
api: ApiPromise,
account: string,
network: string,
tokens?: any[]
) => Promise<TokenBalances>

const customFetchBalancesByNetwork: Record<string, GetOrmlBalancesType> = {
kintsugi: getOnlyOrmlTokens,
Expand Down

0 comments on commit 4504dbd

Please sign in to comment.