# Open-Attestation Token

This library facilitates ERC721 Token interactions using OpenAttestation wrapped documents as token identifiers.
EthersJS is heavily used in this library and unless otherwise stated all Ethereum-related interfaces are expected to be derived from EthersJS.

## Install

        $ npm install @govtechsg/oa-token or yarn @govtechsg/oa-token

## Initialize

        import { ReadOnlyToken, WriteableToken } from "@govtechsg/oa-token";
        const tokenInstance = new ReadOnlyToken({document: wrappedDocument});

## Save Web3 Provider or Wallet

        import { WriteableToken, setWeb3Provider, setWallet } from "@govtechsg/oa-token";

        setWeb3Provider(provider)
        setWallet(wallet)

        const token = new WriteableToken({document}) // Don't need to provider wallet or provider again here

## Get the owner of the contract

        await tokenInstance.getOwner();

returns a promise for a class instance that allows interaction with the owner of the token.

## Types of Owners

#### EthereumAccountOwner

`EthereumAccountOwner` are simply objects with a `.address` property. This owner class is instantiated when the owner of the Token is simply an externally owned Ethereum Account - i.e, not a smart contract.

#### TitleEscrowOwner

`TitleEscrowOwner` is instantiated when the owner of the Token is a TitleEscrow smart contract, which governs the transfer of ownership according to [UN/MLETR](https://uncitral.un.org/en/texts/ecommerce/modellaw/electronic_transferable_records).

It allows the reading of the properties, `holder` and `beneficiary`.

Usage:

    const tokenInstance = new ReadOnlyToken({document: wrappedDocument});
    const tokenOwner = tokenInstance.getOwner()

    if (tokenOwner.isTitleEscrow()) {
       const beneficiary = tokenOwner.beneficiary();
       const holder = tokenOwner.holder();

       console.log(
         `Token ID: ${
           Token.tokenId
         } is owned by TitleEscrow at ${tokenOwner.address}. Has beneficiary ${beneficiary} and held by ${holder}`
       );
     } else {
       console.log(`Token ID: ${Token.tokenId}, owned by ${tokenOwner.address}`);
    }

#### WriteableTitleEscrowOwner

`WriteableTitleEscrowOwner` is the writeable extension of `TitleEscrowOwner`, it allows for calling the smart contract functions which change the state of the system, in addition to everything `TitleEscrowOwner` has.

It has the additional methods `changeHolder(newHolder: EthereumAddress)`, `endorseTransfer(newBeneficiary: EthereumAddress)` , `transferTo(newBeneficiary: EthereumAddress), mint(to: EthereumAddress)`.

There are also additional helper methods to make a transfer or mint to a new TitleEscrow contract `transferToNewEscrow(beneficiary: EthereumAddress, holder: EthereumAddress) and mintToEscrow(beneficiary: EthereumAddress, holder: EthereumAddress)`. These methods first deploy a `TitleEscrow` contract then executes the transfer or mint function to that `TitleEscrow`'s address.

These methods all return a promise that resolves to the transaction hash when the transaction has been confirmed.

Usage:

    const writeableTokenInstance = new WriteableToken({document: wrappedDocument, web3Provider, wallet})
    const tokenOwner = writeableTokenInstance.getOwner()

    const transactionHash = await tokenOwner.changeHolder(newHolder);

## Transfer the token ownership

Writeable token instance initialisation requires an EthersJS type wallet that has write permissions for that token.

        const writeableTokenInstance = new WriteableToken({document: wrappedDocument, web3Provider, wallet})
        await token.transferOwnership("NEW_OWNER_ADDRESS");

returns a transaction hash after the transaction has been mined.

# Development

## Logging

Turn on debugging by using the DEBUG environment variable for Node.js and using localStorage.debug in the browser.

E.g:

```bash
DEBUG="PLACEHOLDER_PROJECT_NAME:*" npm run dev
```

## Commit message format

This boiler plate uses the **semantic-release** package to manage versioning. Once it has been set up, version numbers and Github release changelogs will be automatically managed. **semantic-release** uses the commit messages to determine the type of changes in the codebase. Following formalized conventions for commit messages, **semantic-release** automatically determines the next [semantic version](https://semver.org) number, generates a changelog and publishes the release.

Use `npm run commit` instead of `git commit` in order to invoke Commitizen commit helper that helps with writing properly formatted commit messages.

## API

<!-- Generated by documentation.js. Update this documentation by updating the source code. -->

### Table of Contents

## License

MIT © [Sumit Chaudhari](https://github.com/sumitnitsurat)
