Naval Pilgrim's Mayflower

    blindbox-sdk
    TypeScript icon, indicating that this package has built-in type declarations

    0.4.0 • Public • Published

    SDK Package

    npm version

    Install

    yarn add blindbox-sdk
    yarn upgrade blindbox-sdk

    Browser with Metamask

    import React from "react";
    import logo from "./logo.svg";
    import "./App.css";
    import { BigNumber, ethers, Signer } from "ethers";
    import { Web3Provider } from "@ethersproject/providers";
    import detectEthereumProvider from "@metamask/detect-provider";
    import {
      riverBoxProvider,
      RiverBoxClient,
      RiverBoxExClient,
      ContractBuyResult,
      ContractFuseResult,
      ContractTokenDetail,
      ContractDealDetail,
      riverBoxExProvider,
    } from "blindbox-sdk";
    const RIVERBOX_CONTRACT_ADDRESS = "0x2Fc70F46000eC3Ea67aDBd701068dB82616F4772"; // v 0.3.0 contract deployed on BSC-Testnet 
    const RIVERBOX_EX_CONTRACT_ADDRESS = "0x0AA6f3C6Add473628D60F1f87B186D041dc15b62"; // v 0.1.0 exchange contract deployed on BSC-Testnet 
    function App() {
      const [sym, setSym] = React.useState("");
      // eslint-disable-next-line react-hooks/exhaustive-deps
      React.useEffect(() => {
        const fetchSym = async () => {
          const winProvider: any = await detectEthereumProvider();
          if (winProvider) {
            const provider: Web3Provider = new ethers.providers.Web3Provider(
              winProvider as any
            );
    
            // onchain client
            const client: RiverBoxClient = riverBoxProvider(false);
            const exClient: RiverBoxExClient = riverBoxExProvider(false);
    
            // call read only methods
            client.connectProvider(RIVERBOX_CONTRACT_ADDRESS, provider);
            exClient.connectProvider(RIVERBOX_EX_CONTRACT_ADDRESS, provider);
    
            try {
              console.log(await provider.getSigner().getAddress());
            } catch (error) {
              // throw error when no account is connected
              console.log(error);
            }
    
            try {
              const sym = (await client.symbol()) + (await client.totalSupply());
              setSym(sym);
              console.log(sym);
            } catch (error) {
              console.log(error);
            }
    
            //  sand transaction requires a void signer
            client.setWaitConfirmations(1); // set number of confirmations to wait default is 5 blocks
            await winProvider.request({ method: "eth_requestAccounts" }); // metamask API - ask for connecting an account
    
            console.log(await provider.getSigner().getAddress());
            const signer: Signer = provider.getSigner();
    
            try {
              const currentPrice = await client.connectSigner(signer).boxPrice();
              console.log("currentPrice:", currentPrice.toString(), "wei");
              const ret: ContractBuyResult = await client
                .connectSigner(signer)
                .buy(BigNumber.from(10), { value: currentPrice.mul(10) });
              console.log(ret);
    
              const currentPaidBoxes = await client
                .connectSigner(signer)
                .paidBoxes(await signer.getAddress());
              console.log("currentPaidBoxes:", currentPaidBoxes.toString());
    
              // post a deal
              const tokenId = ret.newTokenIds[0];
              const postDealResult = await exClient.connectSigner(signer).postDeal(tokenId, currentPrice.mul(2))
              console.log(postDealResult);
            } catch (error) {
              console.log(error);
            }
          }
        };
        fetchSym();
      }, []);
      return (
        <div className="App">
          <header className="App-header">
            <img src={logo} className="App-logo" alt="logo" />
            <p>
              Edit <code>src/App.tsx</code> and save to reload.
            </p>
            <a
              className="App-link"
              href="https://reactjs.org"
              target="_blank"
              rel="noopener noreferrer"
            >
              Learn React {sym}
            </a>
          </header>
        </div>
      );
    }
    
    export default App;

    Node with Ethers Provider

    JsonRpcProvider or WebSocketProvider or APIProviders: Use low-level etherjs contract interface directly

    import {
      RiverBox,
      RiverBox__factory,
      RiverBoxExchange,
      RiverBoxExchange__factory,
    } from "blindbox-sdk";
    import { JsonRpcProvider } from "@ethersproject/providers";
    import { ethers, Signer, Wallet } from "ethers";
    
    const RIVERBOX_CONTRACT_ADDRESS = "0x2Fc70F46000eC3Ea67aDBd701068dB82616F4772"; // v 0.3.0 contract deployed on BSC-Testnet
    const RIVERBOX_EX_CONTRACT_ADDRESS =
      "0x0AA6f3C6Add473628D60F1f87B186D041dc15b62"; // v 0.2.0 exchange contract deployed on BSC-Testnet
    
    const PRIVATE_KEY =
      "c1c9223e46ba4b7e3c5bc221fa92cba079999f853d6fb683b95579007fd8c873";
    
    const provider: JsonRpcProvider = new ethers.providers.JsonRpcProvider(
      "https://data-seed-prebsc-1-s1.binance.org:8545/"
    );
    const signer: Wallet = new Wallet(PRIVATE_KEY).connect(provider);
    
    async function main() {
      const riverBox: RiverBox = RiverBox__factory.connect(
        RIVERBOX_CONTRACT_ADDRESS,
        signer
      );
      console.log(`total balance ${await riverBox.totalSupply()}`);
      const riverBoxEx: RiverBoxExchange = RiverBoxExchange__factory.connect(
        RIVERBOX_EX_CONTRACT_ADDRESS,
        signer
      );
      console.log(`total deals ${await riverBoxEx.totalDeals()}`);
    }
    main();

    API Reference:

    Interface

    RiverBox Interface

    riverbox-client.ts

    export interface RiverBoxClient {
      connectProvider(address: string, provider: Provider): RiverBoxClient;
    
      connectSigner(signer: Signer): RiverBoxClient;
    
      setWaitConfirmations(num: number): void;
    
      /* Backup interface
       * @return RiverBox typechain interface for RiverBox contract
       */
      riverBoxContract?(): Promise<RiverBox>;
    
      /*======== RiverBox specific ======*/
    
      /* view */
      /**
       * Return on current box price
       */
      boxPrice(): Promise<BigNumber>;
    
      /**
       * Return on chain item detail information
       * @param tokenId
       * @param config ethers PayableOverrides
       * @returns produceDetail on chain item detail data structure
       */
      tokenDetail(
        tokenId: BigNumber,
        config?: PayableOverrides
      ): Promise<ContractTokenDetail>;
    
      /**
       * Verify if a given list of tokenId can be used to fuse a new item
       * @param tokenIds list of tokenId
       * @param config ethers PayableOverrides
       * @return boolean
       */
      verifyFusion(
        tokenIds: BigNumber[],
        config?: PayableOverrides
      ): Promise<boolean>;
    
      /**
       * Fetch tokenIds from a giver owner by index pagination
       * @param owner owner address
       * @param startIndex
       * @param length endIndex =  min(startIndex + length, maxLength)
       * @param config ethers PayableOverrides
       * @return A list of tokenId
       */
      tokenOfOwnerByIndexPagination(
        owner: string,
        startIndex: BigNumber,
        length: BigNumber,
        config?: PayableOverrides
      ): Promise<BigNumber[]>;
    
      /**
       * Fetch tokenIds from all tokens by index pagination
       * @param startIndex
       * @param length endIndex =  min(startIndex + length, maxLength)
       * @param config ethers PayableOverrides
       * @return A list of tokenId
       */
      tokenOfIndexPagination(
        startIndex: BigNumber,
        length: BigNumber,
        config?: PayableOverrides
      ): Promise<BigNumber[]>;
    
      /**
       * Fetch number of paid boxes
       * @param address
       * @return number of paid boxes
       */
      paidBoxes(account: string, config?: PayableOverrides): Promise<BigNumber>;
      /* transactions */
    
      /**
       * Buy N boxes (N <= 10 for current setup)
       * @param quality number of boxes, will trigger Web3Provider to send transaction in browser
       * @param config ethers PayableOverrides
       * @return BuyResult including transactionHash and a list of awarded tokenIds
       */
      buy(
        quality: BigNumber,
        config?: PayableOverrides
      ): Promise<ContractBuyResult>;
    
      /**
       * Fuse a set of items
       * @param tokenIds a list of tokenId
       * @param config ethers PayableOverrides
       * @return FuseResult including transactionHash and tokenId of new fused item
       */
      fuse(
        tokenIds: BigNumber[],
        config?: PayableOverrides
      ): Promise<ContractFuseResult>;
    
      /*======== ERC721 standard API ======*/
      /* Refer to https://docs.openzeppelin.com/contracts/3.x/api/token/erc721#ERC721 */
      /* view function */
      balanceOf(owner: string, config?: PayableOverrides): Promise<BigNumber>;
      ownerOf(tokenId: BigNumber, config?: PayableOverrides): Promise<string>;
      name(config?: PayableOverrides): Promise<string>;
      symbol(config?: PayableOverrides): Promise<string>;
      tokenURI(tokenId: BigNumber, config?: PayableOverrides): Promise<string>;
      tokenOfOwnerByIndex(
        owner: string,
        index: BigNumber,
        config?: PayableOverrides
      ): Promise<BigNumber>;
      totalSupply(config?: PayableOverrides): Promise<BigNumber>;
      tokenByIndex(index: BigNumber, config?: PayableOverrides): Promise<BigNumber>;
    }

    RiverBoxEx Interface

    riverbox-ex-client.ts

    export interface RiverBoxExClient {
      connectProvider(address: string, provider: Provider): RiverBoxExClient;
    
      connectSigner(signer: Signer): RiverBoxExClient;
    
      setWaitConfirmations(num: number): void;
    
      /**
       * Backup interface
       * @return RiverBox typechain interface for RiverBox contract
       */
      contract?(): Promise<RiverBoxExchange>;
    
      /** 
       * Post a new deal
       * @param tokenId 
       * @param price in BNB wei 18d
       * @param config ethers PayableOverrides
       * @return ContractPostDealResult {dealId, transactionHash}
       */
      postDeal(tokenId: BigNumber, price: BigNumber, config?: PayableOverrides): Promise<ContractPostDealResult>;
    
      /** 
       * Cancel an existing deal
       * @param dealId
       * @param config ethers PayableOverrides
       * @return transactionHash
       */
      cancelDeal(dealId: BigNumber, config?: PayableOverrides): Promise<string>;
    
      /** 
       * Buy a deal 
       * @param dealId
       * @param config ethers PayableOverrides {value: should >= deal price}
       * @return dealId
       */
      buyDeal(dealId: BigNumber, config?: PayableOverrides): Promise<string>;
    }

    MockClient Example

    Usage - (MockClient (sdk-mock.spec.ts) output shown by test console output)

    (base) ➜  sdk git:(main) ✗ yarn run test
    yarn run v1.22.10
    $ mocha
    
    
      RiverBox
        view functions
    ====================================
    {
      locationId: BigNumber { _hex: '0x01', _isBigNumber: true },
      signature: '1111111111111',
      creationTime: BigNumber { _hex: '0x0179c141fdd4', _isBigNumber: true },
      fused: BigNumber { _hex: '0x00', _isBigNumber: true },
      parts: []
    }
          ✓ test: tokenDetails(BigNumber.from(0))
    ====================================
    Mock client: ids.length <= 1 -> false, ids.length > 1 -> true
    false
          ✓ test: verifyFusion([BigNumber.from(0)])
    ====================================
    Mock client: ids.length <= 1 -> false, ids.length > 1 -> true
    true
          ✓ test: verifyFusion([BigNumber.from(0), BigNumber.from(1)])
    ====================================
    [
      BigNumber { _hex: '0x64', _isBigNumber: true },
      BigNumber { _hex: '0x65', _isBigNumber: true },
      BigNumber { _hex: '0x66', _isBigNumber: true },
      BigNumber { _hex: '0x67', _isBigNumber: true },
      BigNumber { _hex: '0x68', _isBigNumber: true }
    ]
          ✓ test: client.tokenOfOwnerByIndexPagination(FAKE_ACCOUNT, BigNumber.from(0), BigNumber.from(5))
    ====================================
    [
      BigNumber { _hex: '0x64', _isBigNumber: true },
      BigNumber { _hex: '0x65', _isBigNumber: true },
      BigNumber { _hex: '0x66', _isBigNumber: true },
      BigNumber { _hex: '0x67', _isBigNumber: true },
      BigNumber { _hex: '0x68', _isBigNumber: true }
    ]
          ✓ test: client.tokenOfIndexPagination(BigNumber.from(0), BigNumber.from(5))
    ====================================
    BigNumber { _hex: '0x64', _isBigNumber: true }
          ✓ test: client.balanceOf(FAKE_ACCOUNT)
    ====================================
    0x000000000000000000000000000000000000000000
          ✓ test: client.ownerOf(BigNumber.from(0))
    ====================================
    RiverBox
          ✓ test: client.name()
    ====================================
    RB
          ✓ test: client.symbol()
    ====================================
    http://metadata.resolve/0
          ✓ test: client.tokenURI(BigNumber.from(0))
    ====================================
    BigNumber { _hex: '0x6e', _isBigNumber: true }
          ✓ test: client.tokenOfOwnerByIndex(FAKE_ACCOUNT, BigNumber.from(10))
    ====================================
    BigNumber { _hex: '0x64', _isBigNumber: true }
          ✓ test: client.totalSupply()
    ====================================
    BigNumber { _hex: '0x6e', _isBigNumber: true }
          ✓ test: client.tokenByIndex(BigNumber.from(10))
    ====================================
          ✓ clean up
        transactions
    ====================================
    {
      transactionHash: '0x1111111111111111111111111111111111111111111111111111111111111111',
      newTokenIds: [
        BigNumber { _hex: '0xc8', _isBigNumber: true },
        BigNumber { _hex: '0xc9', _isBigNumber: true },
        BigNumber { _hex: '0xca', _isBigNumber: true }
      ]
    }
          ✓ test: buy(BigNumber.from(3))
    ====================================
    {
      transactionHash: '0x1111111111111111111111111111111111111111111111111111111111111111',
      newTokenId: BigNumber { _hex: '0xcb', _isBigNumber: true }
    }
          ✓ test: fuse([BigNumber.from(0), BigNumber.from(1)])
    ====================================
          ✓ clean up
    

    SDK-Package:

    Build:

    yarn run build

    Test:

    Start local hardhat node first and deploy the contract

    CONTRACT_ADDRESS={ADDRESS} yarn run test

    Keywords

    none

    Install

    npm i blindbox-sdk

    DownloadsWeekly Downloads

    31

    Version

    0.4.0

    License

    MIT

    Unpacked Size

    1.76 MB

    Total Files

    273

    Last publish

    Collaborators

    • lucklyric