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

Dependencies (1)

Dev Dependencies (11)

Package Sidebar

Install

npm i blindbox-sdk

Weekly Downloads

0

Version

0.4.0

License

MIT

Unpacked Size

1.76 MB

Total Files

273

Last publish

Collaborators

  • lucklyric