1.3.1 • Published 2 years ago

assetmanagement v1.3.1

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

Blockchain Asset Management

npm version npm downloads MIT Licence

Test Coverage

StatementsBranchesFunctionsLines
StatementsBranchesFunctionsLines

Getting Started

  • This repository was created for the purpose of inquiring and utilizing the assets of DAO or their users.
  • An asset in the blockchain can be the contract itself or refers to various tokens issued by the contracts.
  • More specifically, a token is a concept that includes the key currency of each network, including varioud altcoins like UNI or LINK stored in the storage within the contract.

Installation

  1. Install the npm package
      npm install assetmanagement
  2. set .env file to your project
    1. Reference to .env.example file
    2. RPC URL can be found at https://infura.io/dashboard
    3. Testnet RPC also supports.
    ETHEREUM_MAINNET_RPC_URL=
    GOERLI_RPC_URL=
    POLYGON_MAINNET_RPC_URL=
    MUMBAI_RPC_URL=

Supports

Chains

 type TypeSupportChains = 'EthereumMainnet' | 'PolygonMainnet' | 'Goerli' | 'Mumbai';

ERC Interfaces

 type TypeSupportERCs = 'ERC165' | 'ERC20' | 'ERC721' | 'ERC777' | 'ERC1155';

Common

  • All APIs take an array as an argument.
  • All the requests in an array are requested concurrently to the blockchain provider.
    • Currently, rate limit is not considered for development convenience. (TBD)
  • All APIs support all specified chains.
    • Even if different chain is mixed in the input arguments, it automatically requests the value from the matching chain provider and response the result.
  • It should be considered that response time may be different depending on the load status of the blockchain provider. It usually takes about 1-3 seconds.

API summary

  1. checkERCInterfaces
    • Analyze the contract ERC Interfaces (it also queries the metadata of the contract such as name, symbol, and decimals )
  2. getContractsMetadata
    • returns contract metadata (name, symbol, decimals)
  3. getTokenBalances
    • returns the token balances such as LINK, BAYC for the addresses
  4. getNativeTokenBalances
    • returns the native token balances such as ETHER, MATIC for the addresses

Usage (APIs)

import bcAsset from "assetmanagement";

checkERCInterfaces

  1. It queries the ERC interfaces of the contract
  2. It takes an array as input and evaluates the ERC interfaces of multiple contracts at the same time.
  3. Whether the contract information in the array is Ethereum or polygon is automatically classified and evaluated for each network at once.
  4. key "tag" is optional.

       const CONTRACT_DATAS = [
          {
             tag: 'LINK',
             contractAddress:
                     '0x514910771AF9Ca656af840dff83E8264EcF986CA',
             chain: 'EthereumMainnet',
          },
    
          {
             tag: 'USDC',
             contractAddress:
                     '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
             chain: 'EthereumMainnet',
          },
          {
             tag: 'BNB',
             contractAddress:
                     '0x3BA4c387f786bFEE076A58914F5Bd38d668B42c3',
             chain: 'PolygonMainnet',
          },
    
          {
             tag: 'OMNUUM_V1',
             contractAddress:
                     '0xe118A2755632ae81fE3C14dE9b9CFe667985Ef58',
             chain: 'EthereumMainnet',
          },
          {
             tag: 'OMNUUM_V2',
             contractAddress:
                     '0xd1ca758e1be346caa2479cb84757a7cac8bcd94e',
             chain: 'EthereumMainnet',
          },
          {
             tag: 'Ninjana Panda',
             contractAddress:
                     '0xc28D9d9670ce7Df464a67b899395c754D4863D23',
             chain: 'PolygonMainnet',
          },
          {
             tag: 'DAI',
             contractAddress:
                     '0x6B175474E89094C44Da98b954EedeAC495271d0F',
             chain: 'EthereumMainnet',
          },
          {
             tag: 'BinanceUSD',
             contractAddress:
                     '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
             chain: 'EthereumMainnet',
          },
          {
             tag: 'Maker',
             contractAddress:
                     '0x6f7C932e7684666C9fd1d44527765433e01fF61d',
             chain: 'PolygonMainnet',
          },
          {
             tag: 'OpenSeaSharedStorefront',
             contractAddress:
                     '0x495f947276749ce646f68ac8c248420045cb7b5e',
             chain: 'EthereumMainnet',
          },
          {
             tag: 'SandBox',
             contractAddress:
                     '0xa342f5D851E866E18ff98F351f2c6637f4478dB5',
             chain: 'EthereumMainnet',
          },
          {
             tag: 'SandBox',
             contractAddress:
                     '0x9d305a42A3975Ee4c1C57555BeD5919889DCE63F',
             chain: 'PolygonMainnet',
          },
          {
             tag: 'Rarible',
             contractAddress:
                     '0xd07dc4262BCDbf85190C01c996b4C06a461d2430',
             chain: 'EthereumMainnet',
          },
       ]
    
       const response = await bcAsset.checkERCInterfaces(CONTRACT_DATAS);
       
       // response 
       [
          {
             tag: 'LINK',
             contractAddress: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
             chain: 'EthereumMainnet',
             metadata: { name: 'ChainLink Token', symbol: 'LINK', decimals: 18 },
             ERCInterfaces: [ 'ERC20' ]
          },
          {
             tag: 'USDC',
             contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48',
             chain: 'EthereumMainnet',
             metadata: { name: 'USD Coin', symbol: 'USDC', decimals: 6 },
             ERCInterfaces: [ 'ERC20' ]
          },
          {
             tag: 'BNB',
             contractAddress: '0x3BA4c387f786bFEE076A58914F5Bd38d668B42c3',
             chain: 'PolygonMainnet',
             metadata: { name: 'BNB (PoS)', symbol: 'BNB', decimals: 18 },
             ERCInterfaces: [ 'ERC20' ]
          },
          {
             tag: 'OMNUUM_V1',
             contractAddress: '0xe118A2755632ae81fE3C14dE9b9CFe667985Ef58',
             chain: 'EthereumMainnet',
             metadata: {},
             ERCInterfaces: [ 'ERC1155' ]
          },
          {
             tag: 'OMNUUM_V2',
             contractAddress: '0xd1ca758e1be346caa2479cb84757a7cac8bcd94e',
             chain: 'EthereumMainnet',
             metadata: { name: 'OMNUUM GENESIS', symbol: 'OG' },
             ERCInterfaces: [ 'ERC721' ]
          },
          {
             tag: 'Ninjana Panda',
             contractAddress: '0xc28D9d9670ce7Df464a67b899395c754D4863D23',
             chain: 'PolygonMainnet',
             metadata: { name: 'Ninjana Panda', symbol: 'NJNPA' },
             ERCInterfaces: [ 'ERC721' ]
          },
          {
             tag: 'DAI',
             contractAddress: '0x6B175474E89094C44Da98b954EedeAC495271d0F',
             chain: 'EthereumMainnet',
             metadata: { name: 'Dai Stablecoin', symbol: 'DAI', decimals: 18 },
             ERCInterfaces: [ 'ERC20' ]
          },
          {
             tag: 'BinanceUSD',
             contractAddress: '0x4Fabb145d64652a948d72533023f6E7A623C7C53',
             chain: 'EthereumMainnet',
             metadata: { name: 'Binance USD', symbol: 'BUSD', decimals: 18 },
             ERCInterfaces: [ 'ERC20' ]
          },
          {
             tag: 'Maker',
             contractAddress: '0x6f7C932e7684666C9fd1d44527765433e01fF61d',
             chain: 'PolygonMainnet',
             metadata: { name: 'MAKER (PoS)', symbol: 'MKR', decimals: 18 },
             ERCInterfaces: [ 'ERC20' ]
          },
          {
             tag: 'OpenSeaSharedStorefront',
             contractAddress: '0x495f947276749ce646f68ac8c248420045cb7b5e',
             chain: 'EthereumMainnet',
             metadata: { name: 'OpenSea Shared Storefront', symbol: 'OPENSTORE' },
             ERCInterfaces: [ 'ERC1155' ]
          },
          {
             tag: 'SandBox',
             contractAddress: '0xa342f5D851E866E18ff98F351f2c6637f4478dB5',
             chain: 'EthereumMainnet',
             metadata: { name: "Sandbox's ASSETs", symbol: 'ASSET' },
             ERCInterfaces: [ 'ERC721', 'ERC1155' ]
          },
          {
             tag: 'SandBox',
             contractAddress: '0x9d305a42A3975Ee4c1C57555BeD5919889DCE63F',
             chain: 'PolygonMainnet',
             metadata: { name: "Sandbox's LANDs", symbol: 'LAND' },
             ERCInterfaces: [ 'ERC721' ]
          },
          {
             tag: 'Rarible',
             contractAddress: '0xd07dc4262BCDbf85190C01c996b4C06a461d2430',
             chain: 'EthereumMainnet',
             metadata: { name: 'Rarible', symbol: 'RARI' },
             ERCInterfaces: [ 'ERC1155' ]
          }
       ]
  5. Error Checks

    1. Even if an error occurs, it does not throw an error, but returns an error value normally.
    2. If you find the 'error' key value in the result object, you can know the cause of the error.
    await bcAsset.checkERCInterfaces([
           {
             tag: 'notBytes',
             contractAddress: 'abcde',
             chain: 'EthereumMainnet',
        },
        {
             tag: 'shortAddress',
             contractAddress: '0x12345',
             chain: 'EthereumMainnet',
        },
        {
             tag: 'Not Supported ERCs (ex. UNISWAP V3 ROUTER)',
             contractAddress: '0xE592427A0AEce92De3Edee1F18E0157C05861564',
             chain: 'EthereumMainnet',
        },
        {
             tag: 'EOA',
             contractAddress: '0xF891E5556686b588269762d59466451FD7cE49B9',
             chain: 'EthereumMainnet',
        },
    ])
    
    // returns
     [{
         tag: 'notBytes',
         contractAddress: 'abcde',
         chain: 'EthereumMainnet',
         error: {
             code: '100',
             message: 'Contract address does not seem to hex bytes. Address must be start with "0x".',
             where: 'validateContractAddress'
         },
         metadata: {},
         ERCInterfaces: []
    },
     {
         tag: 'shortAddress',
         contractAddress: '0x12345',
         chain: 'EthereumMainnet',
         error: {
             code: '101',
             message: 'Contract address bytes length is not equal to 20 bytes.',
             where: 'validateContractAddress'
         },
         metadata: {},
         ERCInterfaces: []
    },
    {
         tag: 'Not Supported ERCs (ex. UNISWAP V3 ROUTER)',
         contractAddress: '0xE592427A0AEce92De3Edee1F18E0157C05861564',
         chain: 'EthereumMainnet',
         metadata: {},
         error: {
             code: '300',
             message: 'No supported ERC interface found.',
             where: 'determineERCInterface'
         },
         ERCInterfaces: []
    },
    {
         tag: 'EOA',
         contractAddress: '0xF891E5556686b588269762d59466451FD7cE49B9',
         chain: 'EthereumMainnet',
         metadata: {},
         error: {
             code: '300',
             message: 'No supported ERC interface found.',
             where: 'determineERCInterface'
         },
         ERCInterfaces: []
    }]

getContractsMetadata

  1. It returns contract metadata (name, symbol, and decimals)
  2. If the contract does not have metadata or some of them, it returns null as value

     
    const queryDatas = [
         {
             tag: 'BAYC',
             contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
             chain: 'EthereumMainnet'
         },
         {
             tag: 'LINK',
             contractAddress: '0x514910771AF9Ca656af840dff83E8264EcF986CA',
             chain: 'EthereumMainnet'
         },
    ]
    
    const response = await bcAsset.getContractsMetadata(queryDatas);
    
    // response
    [
         { name: 'BoredApeYachtClub', symbol: 'BAYC', decimals: null },
         { name: 'ChainLink Token', symbol: 'LINK', decimals: 18 }
    ]

getTokenBalances

  1. It returns the token balances of the addresses (address can be EOA or CA)

    import {getTokenBalances} from "./balance.blockchain";
    
    const queryDatas = [
        {
            balanceAddress: '0x680756B2794B4d4Ad265040B18539f19f90F13CC', // Exchange Contract
            contractAddress: '0x514910771AF9Ca656af840dff83E8264EcF986CA', // LINK token Contract
            chain: 'EthereumMainnet',
            ERCInterface: 'ERC20',
        },
        {
            balanceAddress: '0x040B4A13a044F8A07D454e862E2c580d6088a8B8', // Wallet
            contractAddress: '0xd1CA758e1Be346cAa2479Cb84757A7CaC8BcD94e', // Omnuum Genesis v2
            chain: 'EthereumMainnet',
            ERCInterface: 'ERC721',
        },
        {
            balanceAddress: 'omnuum.eth', // can parse ENS name
            contractAddress: '0xd1ca758e1be346caa2479cb84757a7cac8bcd94e',
            chain: 'EthereumMainnet',
            ERCInterface: 'ERC721',
        },
    ]
    
    const response = await bcAsset.getTokenBalances(queryDatas);
    
    // response
    [
        { balance: '94000000000000000000' },
        { balance: '1' },
        { balance: '7' },
    ]
  1. If the arguments inputs invalid, it does not throw error, but result contains an error.

    const queryDatas = [
        {
            // Wrong balance address
            balanceAddress: '0x1234', 
            contractAddress: '0x514910771AF9Ca656af840dff83E8264EcF986CA', 
            chain: 'EthereumMainnet',
            ERCInterface: 'ERC1155',
        },
        {
            balanceAddress: '0x040B4A13a044F8A07D454e862E2c580d6088a8B8',
            // Wrong contract address
            contractAddress: '0x9876', 
            chain: 'EthereumMainnet',
            ERCInterface: 'ERC721',
        },
        {
            // normal
            balanceAddress: '0x040B4A13a044F8A07D454e862E2c580d6088a8B8', 
            contractAddress: '0xd1CA758e1Be346cAa2479Cb84757A7CaC8BcD94e', 
            chain: 'EthereumMainnet',
            ERCInterface: 'ERC721',
        },
    ];
    
    const response = await bcAsset.getTokenBalances(queryDatas);
    // response
    [
        {
            balance: undefined,
            error: {
                code: 'INVALID_ARGUMENT',
                message: 'invalid address (address=0x1234)',
                where: 'queryBalance'
                }
        },
        {
            balance: undefined,
            error: {
                code: 'INVALID_ARGUMENT',
                message: 'invalid address (address=0x9876)',
                where: 'queryBalance'
            }
        },
        {
            balance: '1'
        }
    ]

getNativeTokenBalances

  1. It returns the native token balances of addresses. (ex. ETHER or MATIC)
  2. Since the native token balance is not related to the contract in which the balance data is stored, only the address and chain information are required as input arguments.

    const queryDatas = [
        {
            address: '0x8a54AaBCccf6299f138Ff3cabe6F637716449EB4',
            chain: 'EthereumMainnet',
        },
        {
            address: '0xF891E5556686b588269762d59466451FD7cE49B9',
            chain: 'Goerli',
        },
        {
            address: '0xF891E5556686b588269762d59466451FD7cE49B9',
            chain: 'PolygonMainnet',
        },
        {
            address: '0xF891E5556686b588269762d59466451FD7cE49B9',
            chain: 'Mumbai',
        }, 
        {
            address: 'omnuum.eth',  // can parse ENS name
            chain: 'EthereumMainnet',
        },  
    ]
    
    const response = await bcAsset.getNativeTokenBalances(queryDatas);
    
    // response
    [
        { balance: '708772165136697730' },
        { balance: '124254100374907974' },
        { balance: '0' },
        { balance: '2000000000000000000' },
        { balance: '708772165136697730' },
    
    ]
  3. If it cannot parse ENS name from ENS resolve, it returns error value with undefined balance.

    • ENS only supports Ethereum mainnet
    • ENS name can be parsed with regardless of case (case-insensitive)

      const queryDatas = [
          {
              address: 'wallet.omnuum.eth',
              chain: 'EthereumMainnet',
          },
          {
              address: 'Idontknow.omnuum.eth',
              chain: 'EthereumMainnet',
          },
          {
              address: 'MysteryChain.omnuum.eth',
              chain: 'PolygonMainnet',
          }, 
      ]
      
      const response = await bcAsset.getNativeTokenBalances(queryDatas);
      
      // response
       [
          { balance: '2484000000000000000' },
          {
            balance: undefined,
            error: {
                    code: 'UNSUPPORTED_OPERATION',
                    message: 'ENS name not configured',
                    where: 'queryNativeTokenBalances'
                   } 
          },
          {
            balance: undefined,
            error: {
                    code: 'UNSUPPORTED_OPERATION',
                    message: 'network does not support ENS',
                    where: 'queryNativeTokenBalances'
                   }
          }
       ]

ensNameToAddress

  1. Convert ENS name to address (case-insensitive)

    • If it cannot resolve ENS name, address null returns

      const queryDatas = [
          {
              ensName: 'omnuum.eth', // 0x8a54AaBCccf6299f138Ff3cabe6F637716449EB4
              chain: 'EthereumMainnet' as TypeSupportedEnsChain,
          },
          {
              ensName: 'wallet.omnuum.eth', // 0x6DEc671d53F33a4a7314Ea596A8E892F18ecEc91
              chain: 'EthereumMainnet' as TypeSupportedEnsChain,
          },
          {
              ensName: 'OMNUUM.ETH', // 0x8a54AaBCccf6299f138Ff3cabe6F637716449EB4
              chain: 'EthereumMainnet' as TypeSupportedEnsChain,
          },
          {
              ensName: 'WALLET.OmNuUm.EtH', // 0x6DEc671d53F33a4a7314Ea596A8E892F18ecEc91
              chain: 'EthereumMainnet' as TypeSupportedEnsChain,
          },
      ]
      
      const response = await bcAsset.ensNameToAddress(queryDatas);
      // response
      [
          { address: '0x8a54AaBCccf6299f138Ff3cabe6F637716449EB4' },
          { address: '0x6DEc671d53F33a4a7314Ea596A8E892F18ecEc91' },
          { address: '0x8a54AaBCccf6299f138Ff3cabe6F637716449EB4' },
          { address: '0x6DEc671d53F33a4a7314Ea596A8E892F18ecEc91' }
      ]
  2. Convert address to ENS name

    const queryDatas =
    [
         {
             address: '0x8a54AaBCccf6299f138Ff3cabe6F637716449EB4', // omnuum.eth
             chain: 'EthereumMainnet' as TypeSupportedEnsChain,
         },
         {
             address: '0x1234', // invalid address
             chain: 'EthereumMainnet' as TypeSupportedEnsChain,
         },
    ]
    
    const response = await bcAsset.addressToEnsName(queryDatas);
    // response
    [
         { ensName: 'omnuum.eth' },
         {
             ensName: undefined,
             error: {
                 code: 'INVALID_ARGUMENT',
                 message: 'invalid address (address=0x1234)',
                 where: 'addressToEnsName'
             }
         }
     ]

Errors

const assetErrorMsgs: IAssetErrorMessages = {
    // 1xx: validation check errors
    '100': `Contract address does not seem to hex bytes. Address must be start with "0x".`,
    '101': `Contract address bytes length is not equal to 20 bytes.`,
    '102': `EVM address checksum fail. (check EIP55: https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md)`,
    '103': `Unsupported chain.`,
    '104': `Wrong RPC url. Check .env file.`,

    // 3xx: ERC interfaces result errors
    '300': `No supported ERC interface found.`,
};
1.3.1

2 years ago

1.3.0

2 years ago

1.2.6

2 years ago

1.2.5

2 years ago

1.2.4

2 years ago

1.2.3

2 years ago

1.2.2

2 years ago

1.2.1

2 years ago

1.2.0

2 years ago

1.1.1

2 years ago

1.1.0

2 years ago

1.0.0

2 years ago

0.0.1

2 years ago