import { CurrencyId , TokenSymbol } from '@acala-network/types/interfaces' ; import { isArray } from 'lodash' ; import { STABLE_ASSET_POOLS , TokenType } from '.' ; import { ConvertToCurrencyIdFailed , ConvertToCurrencyNameFailed , NotDexShareName , NotForeignAssetName , NotLiquidCroadloanName , NotStableAssetPoolName } from './errors' ; import { Token } from './token' ; import { AnyApi , CurrencyObject , MaybeCurrency } from './types' ; /**
 *  we set a name with a prefix to all types of tokens for easy passing and use.
 *  e.g.
 *  { DexShare: [{ Token: KAR }, { Token: KSM }] } is lp://KAR/KSM
 *  { stableAsset: 0 } is sa://0
 *  { foreignAsset: 0 } is fa://0
 *  { ERC20: '0x100000000' } is erc20://0x10000
 *  we can also combine these name for complex types
 *  e.g.
 *  lp://${encode(lp://KAR/KSM)}/${encode(sa://0)} is { DexShare: [ { DexShare: [{ Token: 'KAR' }, { Token: 'KSM}] }, { stableAsset: 0 } ] }
 */ export function isBasicToken ( name ) { return name . search ( '//' ) < 0 ; } export function createDexShareName ( name1 , name2 ) { return `lp://${ encodeURIComponent ( name1 ) }/${ encodeURIComponent ( name2 ) }` ; } export function isDexShareName ( name ) { return name . startsWith ( 'lp://' ) ; } name description export function unzipDexShareName ( name ) { if ( ! isDexShareName ( name ) ) throw new NotDexShareName ( name ) ; const reg = /^lp:\/\/([^/]*)?\/([^/]*)$/ ; const result = reg . exec ( name ) ; if ( ! result ) throw new NotDexShareName ( name ) ; return [ decodeURIComponent ( result [ 1 ] ) , decodeURIComponent ( result [ 2 ] ) ] as [ string , string ] ; } export function createStableAssetName ( id ) { return `sa://${ id }` ; } export function isStableAssetName ( name ) { return name . startsWith ( 'sa://' ) ; } export function getStableAssetTokenName ( api , name ) { const chain = api . runtimeChain . toString ( ) ; const poolId = getStableAssetPoolIdFromName ( name ) ; return STABLE_ASSET_POOLS [ chain ] [ poolId ] . name ; } export function getStableAssetPoolIdFromName ( name ) { if ( ! isStableAssetName ( name ) ) throw new NotStableAssetPoolName ( name ) ; return parseInt ( name . replace ( 'sa://' , '' ) ) ; } export function createForeignAssetName ( id ) { return `fa://${ id }` ; } export function isForeignAssetName ( name ) { return name . startsWith ( 'fa://' ) ; } export function getForeignAssetIdFromName ( name ) { if ( ! isForeignAssetName ( name ) ) throw new NotForeignAssetName ( name ) ; return parseInt ( name . replace ( 'fa://' , '' ) ) ; } export function createLiquidCroadloanName ( id ) { return `lc://${ id }` ; } export function isLiquidCroadloanName ( name ) { return name . startsWith ( 'lc://' ) ; } export function getLiquidCroadloanIdFromName ( name ) { if ( ! isLiquidCroadloanName ( name ) ) throw new NotLiquidCroadloanName ( name ) ; return parseInt ( name . replace ( 'lc://' , '' ) ) ; } export function getCurrencyTypeByName ( name ) { if ( isStableAssetName ( name ) ) return TokenType . STABLE_ASSET_POOL_TOKEN ; if ( isDexShareName ( name ) ) return TokenType . DEX_SHARE ; if ( isForeignAssetName ( name ) ) return TokenType . FOREIGN_ASSET ; if ( isDexShareName ( name ) ) return TokenType . DEX_SHARE ; if ( isLiquidCroadloanName ( name ) ) return TokenType . LIQUID_CROADLOAN ; return TokenType . BASIC ; } export function getBasicCurrencyObject ( name ) { return { Token : name } ; } export function getStableAssetCurrencyObject ( name ) { return { StableAssetPoolToken : getStableAssetPoolIdFromName ( name ) } ; } export function getForeignAssetCurrencyObject ( name ) { return { ForeignAsset : getForeignAssetIdFromName ( name ) } ; } export function getLiquidCroadloanObject ( name ) { return { LiquidCroadloan : getLiquidCroadloanIdFromName ( name ) } ; } export function getDexShareCurrencyObject ( name ) { const inner = ( name ) : CurrencyObject => { if ( isDexShareName ( name ) ) { const [ name1 , name2 ] = unzipDexShareName ( name ) ; return { DexShare : [ inner ( name1 ) , inner ( name2 ) ] } ; } if ( isForeignAssetName ( name ) ) return getForeignAssetCurrencyObject ( name ) ; if ( isStableAssetName ( name ) ) return getStableAssetCurrencyObject ( name ) ; if ( isLiquidCroadloanName ( name ) ) return getLiquidCroadloanObject ( name ) ; return getBasicCurrencyObject ( name ) ; } ; return inner ( name ) ; } export function getCurrencyObject ( name ) { if ( isDexShareName ( name ) ) return getDexShareCurrencyObject ( name ) ; if ( isForeignAssetName ( name ) ) return getForeignAssetCurrencyObject ( name ) ; if ( isStableAssetName ( name ) ) return getStableAssetCurrencyObject ( name ) ; if ( isLiquidCroadloanName ( name ) ) return getLiquidCroadloanObject ( name ) ; return getBasicCurrencyObject ( name ) ; } name description export function forceToCurrencyName ( target ) { try { if ( typeof target === 'string' ) return target ; if ( Array . isArray ( target ) ) return createDexShareName ( target [ 0 ] , target [ 1 ] ) ; if ( target instanceof Token ) return target . toString ( ) ; if ( ( target as CurrencyId ) . isToken ) return ( target as CurrencyId ) . asToken . toString ( ) ; if ( ( target as CurrencyId ) . isDexShare ) { return createDexShareName ( forceToCurrencyName ( ( target as CurrencyId ) . asDexShare [ 0 ] as CurrencyId ) , forceToCurrencyName ( ( target as CurrencyId ) . asDexShare [ 1 ] as CurrencyId ) ) ; } if ( ( target as CurrencyId ) . isErc20 ) return ( target as CurrencyId ) . asErc20 . toString ( ) ; if ( ( target as CurrencyId ) . isStableAssetPoolToken ) return createStableAssetName ( ( target as CurrencyId ) . asStableAssetPoolToken . toNumber ( ) ) ; if ( ( target as CurrencyId ) . isForeignAsset ) return createForeignAssetName ( ( target as CurrencyId ) . asForeignAsset . toNumber ( ) ) ; if ( ( target as CurrencyId ) . isLiquidCroadloan ) return createLiquidCroadloanName ( ( target as CurrencyId ) . asLiquidCroadloan . toNumber ( ) ) ; return target . toString ( ) ; } catch ( e ) { throw new ConvertToCurrencyNameFailed ( target ) ; } } export function forceToCurrencyId ( api , target ) { try { const name = forceToCurrencyName ( target ) ; return api . createType ( 'AcalaPrimitivesCurrencyCurrencyId' , getCurrencyObject ( name ) ) as unknown as CurrencyId ; } catch ( e ) { throw new ConvertToCurrencyIdFailed ( origin ) ; } } export const forceToTokenSymbolCurrencyId = ( api , target ) : CurrencyId => { const name = target . toString ( ) ; return forceToCurrencyId ( api , name ) ; } ; export const forceToDexShareCurrencyId = ( api , target ) : CurrencyId => { let name = '' ; if ( isArray ( target ) ) { name = createDexShareName ( target [ 0 ] , target [ 1 ] ) ; } else { name = forceToCurrencyName ( target ) ; } return forceToCurrencyId ( api , name ) ; } ; export const forceToStableAssetCurrencyId = ( api , target ) : CurrencyId => { let name = '' ; if ( typeof target === 'number' ) { name = createStableAssetName ( target ) ; } else { name = forceToCurrencyName ( target ) ; } return forceToCurrencyId ( api , name ) ; } ; export const forceToForeignAssetCurrencyId = ( api , target ) : CurrencyId => { let name = '' ; if ( typeof target === 'number' ) { name = createForeignAssetName ( target ) ; } else { name = forceToCurrencyName ( target ) ; } return forceToCurrencyId ( api , name ) ; } ;