import { EthApi , requireAccount } from "@joincivil/ethapi" ; import { CivilErrors , getDefaultFromBlock } from "@joincivil/utils" ; import { BigNumber } from "@joincivil/typescript-types" ; import { Observable } from "rxjs" ; import { EthAddress } from "../../types" ; import { BaseWrapper } from "../basewrapper" ; import { CVLTokenMultisigProxy } from "../generated/multisig/c_v_l_token" ; import { CVLTokenContract } from "../generated/wrappers/c_v_l_token" ; import { CivilTokenControllerContract } from "../generated/wrappers/civil_token_controller" ; import { MultisigProxyTransaction } from "../multisig/basemultisigproxy" ; /**
 * CVLToken allows user to interface with token.
 *
 * NOTE: If instantiated with a multisig wallet, all transactions are proxied through multisig, and all functions default to multisig address as the "current" user.
 */ export class CVLToken extends BaseWrapper < CVLTokenContract > { public static async atUntrusted ( web3wrapper , address , multisigAddress ? ) { const instance = CVLTokenContract . atUntrusted ( web3wrapper , address ) ; const multisigProxy = await CVLTokenMultisigProxy . create ( web3wrapper , instance , multisigAddress ) ; const tokenController = await CivilTokenControllerContract . singletonTrusted ( web3wrapper ) ; if ( ! tokenController ) { throw new Error ( CivilErrors . UnsupportedNetwork ) ; } const defaultBlock = getDefaultFromBlock ( await web3wrapper . network ( ) ) ; return new CVLToken ( web3wrapper , instance , multisigProxy , tokenController , defaultBlock ) ; } public static async singletonTrusted ( web3wrapper , multisigAddress ? ) { const instance = ( await CVLTokenContract . singletonTrusted ( web3wrapper ) ) ! ; const multisigProxy = await CVLTokenMultisigProxy . create ( web3wrapper , instance , multisigAddress ) ; const tokenController = await CivilTokenControllerContract . singletonTrusted ( web3wrapper ) ; if ( ! tokenController ) { throw new Error ( CivilErrors . UnsupportedNetwork ) ; } const defaultBlock = getDefaultFromBlock ( await web3wrapper . network ( ) ) ; return new CVLToken ( web3wrapper , instance , multisigProxy , tokenController , defaultBlock ) ; } /** If instantiated with `multisigAddress` undefined, proxy will send transactions directly to the contract instance. */ private multisigProxy : CVLTokenMultisigProxy ; private tokenController : CivilTokenControllerContract ; private constructor ( ethApi , instance , multisigProxy , tokenController , defaultBlock ) { super ( ethApi , instance , defaultBlock ) ; this . multisigProxy = multisigProxy ; this . tokenController = tokenController ; } /**
     * Contract Transactions
     */ param spender param numTokens public async approveSpender ( spender , numTokens ) { return this . multisigProxy . approve . sendTransactionAsync ( spender , numTokens . toString ( ) ) ; } public balanceUpdate ( fromBlock = this . defaultBlock , user ) { return this . instance . TransferStream ( { from : user } , { fromBlock } ) . merge ( this . instance . TransferStream ( { to : user } , { fromBlock } ) ) . concatMap ( async ( ) => this . getBalance ( user ) ) ; } /**
     * Contract Getters
     */ param spender param tokenOwner public async getApprovedTokensForSpender ( spender , tokenOwner ? ) { let who = tokenOwner ; if ( ! who ) { who = await this . getDefaultCurrentAddress ( ) ; } return this . instance . allowance . callAsync ( who , spender ) . then ( e => new BigNumber ( e ) ) ; } param tokenOwner public async getBalance ( tokenOwner ? ) { let who = tokenOwner ; if ( ! who ) { who = await this . getDefaultCurrentAddress ( ) ; } return this . instance . balanceOf . callAsync ( who ) . then ( e => new BigNumber ( e ) ) ; } public async isTransferAllowed ( to , from ? ) { let who = from ; if ( ! who ) { who = await this . getDefaultCurrentAddress ( ) ; } const code = await this . tokenController . detectTransferRestriction . callAsync ( who , to , "1" ) ; return code === "0" ; } public async isCivilian ( user ) { return this . tokenController . civilianList . callAsync ( user ) ; } public async isUnlocked ( user ) { return this . tokenController . unlockedList . callAsync ( user ) ; } param recipient param numTokens public async transfer ( recipient , numTokens ) { return this . multisigProxy . transfer . sendTransactionAsync ( recipient , numTokens . toString ( ) ) ; } public async transferToSelf ( numTokens ) { const recipient = await requireAccount ( this . ethApi ) . toPromise ( ) ; return this . multisigProxy . transfer . sendTransactionAsync ( recipient , numTokens . toString ( ) ) ; } private async getDefaultCurrentAddress ( ) { let who ; if ( this . multisigProxy . multisigEnabled ) { who = await this . multisigProxy . getMultisigAddress ( ) ; } if ( ! who ) { who = await requireAccount ( this . ethApi ) . toPromise ( ) ; } return who ; } }