"use strict";
/**
 * @file COMP
 * @desc These methods facilitate interactions with the COMP token smart
 *     contract.
 */
Object.defineProperty(exports, "__esModule", { value: true });
const ethers_1 = require("ethers");
const keccak256 = ethers_1.ethers.keccak256;
/**
 * Applies the EIP-55 checksum to an Ethereum address.
 *
 * @param {string} _address The Ethereum address to apply the checksum.
 *
 * @returns {string} Returns a string of the Ethereum address.
 */
function toChecksumAddress(_address) {
    const chars = _address.toLowerCase().substring(2).split('');
    const expanded = new Uint8Array(40);
    for (let i = 0; i < 40; i++) {
        expanded[i] = chars[i].charCodeAt(0);
    }
    const hash = keccak256(expanded);
    let ret = '';
    for (let i = 0; i < _address.length; i++) {
        if (parseInt(hash[i], 16) >= 8) {
            ret += _address[i].toUpperCase();
        }
        else {
            ret += _address[i];
        }
    }
    return ret;
}
/**
 * Get the balance of COMP tokens held by an address.
 *
 * @param {string} _address The address in which to find the COMP balance.
 * @param {Provider | string} [_provider] An Ethers.js provider or valid network
 *     name string.
 *
 * @returns {string} Returns a string of the numeric balance of COMP. The value
 *     is scaled up by 18 decimal places.
 *
 * @example
 *
 * ```
 * (async function () {
 *   const bal = await Sumer.comp.getCompBalance('0x2775b1c75658Be0F640272CCb8c72ac986009e38');
 *   console.log('Balance', bal);
 * })().catch(console.error);
 * ```
 */
// export async function getCompBalance(_address: string, _provider: Provider | string = 'mainnet'): Promise<string> {
//   const provider = await eth._createProvider({ provider: _provider })
//   const net = await eth.getProviderNetwork(provider)
//   const errorPrefix = 'Sumer [getCompBalance] | '
//   if (typeof _address !== 'string') {
//     throw Error(errorPrefix + 'Argument `_address` must be a string.')
//   }
//   try {
//     _address = toChecksumAddress(_address)
//   } catch (e) {
//     throw Error(errorPrefix + 'Argument `_address` must be a valid Ethereum address.')
//   }
//   const compAddress = getAddress(net.name, 'COMP')
//   const parameters = [_address]
//   const trxOptions: CallOptions = {
//     _sumerProvider: provider,
//     abi: abi.COMP,
//   }
//   const result = await eth.read(compAddress, 'balanceOf', parameters, trxOptions)
//   return result.toString()
// }
// /**
//  * Get the amount of COMP tokens accrued but not yet claimed by an address.
//  *
//  * @param {string} _address The address in which to find the COMP accrued.
//  * @param {Provider | string} [_provider] An Ethers.js provider or valid network
//  *     name string.
//  *
//  * @returns {string} Returns a string of the numeric accruement of COMP. The
//  *     value is scaled up by 18 decimal places.
//  *
//  * @example
//  *
//  * ```
//  * (async function () {
//  *   const acc = await Sumer.comp.getCompAccrued('0x4Ddc2D193948926D02f9B1fE9e1daa0718270ED5');
//  *   console.log('Accrued', acc);
//  * })().catch(console.error);
//  * ```
//  */
// export async function getCompAccrued(_address: string, _provider: Provider | string = 'mainnet'): Promise<string> {
//   const provider = await eth._createProvider({ provider: _provider })
//   const net = await eth.getProviderNetwork(provider)
//   const errorPrefix = 'Sumer [getCompAccrued] | '
//   if (typeof _address !== 'string') {
//     throw Error(errorPrefix + 'Argument `_address` must be a string.')
//   }
//   try {
//     _address = toChecksumAddress(_address)
//   } catch (e) {
//     throw Error(errorPrefix + 'Argument `_address` must be a valid Ethereum address.')
//   }
//   const lensAddress = getAddress(net.name, 'CompoundLens')
//   const compAddress = getAddress(net.name, 'COMP')
//   const comptrollerAddress = getAddress(net.name, 'Comptroller')
//   const parameters = [compAddress, comptrollerAddress, _address]
//   const trxOptions: CallOptions = {
//     _sumerProvider: provider,
//     abi: abi.CompoundLens,
//   }
//   const result = await eth.read(lensAddress, 'getCompBalanceMetadataExt', parameters, trxOptions)
//   return result.allocated.toString()
// }
// /**
//  * Create a transaction to claim accrued COMP tokens for the user.
//  *
//  * @param {CallOptions} [options] Options to set for a transaction and Ethers.js
//  *     method overrides.
//  *
//  * @returns {object} Returns an Ethers.js transaction object of the vote
//  *     transaction.
//  *
//  * @example
//  *
//  * ```
//  * const sumer = new Sumer(window.ethereum);
//  *
//  * (async function() {
//  *
//  *   console.log('Claiming COMP...');
//  *   const trx = await sumer.claimComp();
//  *   console.log('Ethers.js transaction object', trx);
//  *
//  * })().catch(console.error);
//  * ```
//  */
// export async function claimComp(options: CallOptions = {}): Promise<TrxResponse> {
//   await netId(this)
//   try {
//     let userAddress = this._provider.address
//     if (!userAddress && this._provider.getAddress) {
//       userAddress = await this._provider.getAddress()
//     }
//     const comptrollerAddress = getAddress(this._network.name, 'Comptroller')
//     const trxOptions: CallOptions = {
//       ...options,
//       _sumerProvider: this._provider,
//       abi: abi.Comptroller,
//     }
//     const parameters = [userAddress]
//     const method = 'claimComp(address)'
//     return eth.trx(comptrollerAddress, method, parameters, trxOptions)
//   } catch (e) {
//     const errorPrefix = 'Sumer [claimComp] | '
//     e.message = errorPrefix + e.message
//     return e
//   }
// }
// /**
//  * Create a transaction to delegate Sumer Governance voting rights to an
//  *     address.
//  *
//  * @param {string} _address The address in which to delegate voting rights to.
//  * @param {CallOptions} [options] Options to set for `eth_call`, optional ABI
//  *     (as JSON object), and Ethers.js method overrides. The ABI can be a string
//  *     of the single intended method, an array of many methods, or a JSON object
//  *     of the ABI generated by a Solidity compiler.
//  *
//  * @returns {object} Returns an Ethers.js transaction object of the vote
//  *     transaction.
//  *
//  * @example
//  *
//  * ```
//  * const sumer = new Sumer(window.ethereum);
//  *
//  * (async function() {
//  *   const delegateTx = await sumer.delegate('0xa0df350d2637096571F7A701CBc1C5fdE30dF76A');
//  *   console.log('Ethers.js transaction object', delegateTx);
//  * })().catch(console.error);
//  * ```
//  */
// export async function delegate(_address: string, options: CallOptions = {}): Promise<TrxResponse> {
//   await netId(this)
//   const errorPrefix = 'Sumer [delegate] | '
//   if (typeof _address !== 'string') {
//     throw Error(errorPrefix + 'Argument `_address` must be a string.')
//   }
//   try {
//     _address = toChecksumAddress(_address)
//   } catch (e) {
//     throw Error(errorPrefix + 'Argument `_address` must be a valid Ethereum address.')
//   }
//   const compAddress = getAddress(this._network.name, 'COMP')
//   const trxOptions: CallOptions = {
//     ...options,
//     _sumerProvider: this._provider,
//     abi: abi.COMP,
//   }
//   const parameters = [_address]
//   const method = 'delegate'
//   return eth.trx(compAddress, method, parameters, trxOptions)
// }
// /**
//  * Delegate voting rights in Sumer Governance using an EIP-712 signature.
//  *
//  * @param {string} _address The address to delegate the user's voting rights to.
//  * @param {number} nonce The contract state required to match the signature.
//  *     This can be retrieved from the COMP contract's public nonces mapping.
//  * @param {number} expiry The time at which to expire the signature. A block
//  *     timestamp as seconds since the unix epoch.
//  * @param {object} signature An object that contains the v, r, and, s values of
//  *     an EIP-712 signature.
//  * @param {CallOptions} [options] Options to set for `eth_call`, optional ABI
//  *     (as JSON object), and Ethers.js method overrides. The ABI can be a string
//  *     of the single intended method, an array of many methods, or a JSON object
//  *     of the ABI generated by a Solidity compiler.
//  *
//  * @returns {object} Returns an Ethers.js transaction object of the vote
//  *     transaction.
//  *
//  * @example
//  *
//  * ```
//  * const sumer = new Sumer(window.ethereum);
//  *
//  * (async function() {
//  *   const delegateTx = await sumer.delegateBySig(
//  *     '0xa0df350d2637096571F7A701CBc1C5fdE30dF76A',
//  *     42,
//  *     9999999999,
//  *     {
//  *       v: '0x1b',
//  *       r: '0x130dbca2fafa07424c033b4479687cc1deeb65f08809e3ab397988cc4c6f2e78',
//  *       s: '0x1debeb8250262f23906b1177161f0c7c9aa3641e8bff5b6f5c88a6bb78d5d8cd'
//  *     }
//  *   );
//  *   console.log('Ethers.js transaction object', delegateTx);
//  * })().catch(console.error);
//  * ```
//  */
// export async function delegateBySig(
//   _address: string,
//   nonce: number,
//   expiry: number,
//   signature: Signature = { v: '', r: '', s: '' },
//   options: CallOptions = {},
// ): Promise<TrxResponse> {
//   await netId(this)
//   const errorPrefix = 'Sumer [delegateBySig] | '
//   if (typeof _address !== 'string') {
//     throw Error(errorPrefix + 'Argument `_address` must be a string.')
//   }
//   try {
//     _address = toChecksumAddress(_address)
//   } catch (e) {
//     throw Error(errorPrefix + 'Argument `_address` must be a valid Ethereum address.')
//   }
//   if (typeof nonce !== 'number') {
//     throw Error(errorPrefix + 'Argument `nonce` must be an integer.')
//   }
//   if (typeof expiry !== 'number') {
//     throw Error(errorPrefix + 'Argument `expiry` must be an integer.')
//   }
//   if (!Object.isExtensible(signature) || !signature.v || !signature.r || !signature.s) {
//     throw Error(
//       errorPrefix +
//         'Argument `signature` must be an object that ' +
//         'contains the v, r, and s pieces of an EIP-712 signature.',
//     )
//   }
//   const compAddress = getAddress(this._network.name, 'COMP')
//   const trxOptions: CallOptions = {
//     ...options,
//     _sumerProvider: this._provider,
//     abi: abi.COMP,
//   }
//   const { v, r, s } = signature
//   const parameters = [_address, nonce, expiry, v, r, s]
//   const method = 'delegateBySig'
//   return eth.trx(compAddress, method, parameters, trxOptions)
// }
// /**
//  * Create a delegate signature for Sumer Governance using EIP-712. The
//  *     signature can be created without burning gas. Anyone can post it to the
//  *     blockchain using the `delegateBySig` method, which does have gas costs.
//  *
//  * @param {string} delegatee The address to delegate the user's voting rights
//  *     to.
//  * @param {number} [expiry] The time at which to expire the signature. A block
//  *     timestamp as seconds since the unix epoch. Defaults to `10e9`.
//  *
//  * @returns {object} Returns an object that contains the `v`, `r`, and `s`
//  *     components of an Ethereum signature as hexadecimal strings.
//  *
//  * @example
//  *
//  * ```
//  * const sumer = new Sumer(window.ethereum);
//  *
//  * (async () => {
//  *
//  *   const delegateSignature = await sumer.createDelegateSignature('0xa0df350d2637096571F7A701CBc1C5fdE30dF76A');
//  *   console.log('delegateSignature', delegateSignature);
//  *
//  * })().catch(console.error);
//  * ```
//  */
// export async function createDelegateSignature(delegatee: string, expiry = 10e9): Promise<Signature> {
//   await netId(this)
//   const provider = this._provider
//   const compAddress = getAddress(this._network.name, 'COMP')
//   const chainId = this._network.id
//   let userAddress = this._provider.address
//   if (!userAddress && this._provider.getAddress) {
//     userAddress = await this._provider.getAddress()
//   }
//   const originalProvider = this._originalProvider
//   const nonce = +(
//     await eth.read(compAddress, 'function nonces(address) returns (uint)', [userAddress], {
//       provider: originalProvider,
//     })
//   ).toString()
//   const domain: EIP712Domain = {
//     name: 'Sumer',
//     chainId,
//     verifyingContract: compAddress,
//   }
//   const primaryType = 'Delegation'
//   const message: DelegateSignatureMessage = { delegatee, nonce, expiry }
//   const types: DelegateTypes = {
//     EIP712Domain: [
//       { name: 'name', type: 'string' },
//       { name: 'chainId', type: 'uint256' },
//       { name: 'verifyingContract', type: 'address' },
//     ],
//     Delegation: [
//       { name: 'delegatee', type: 'address' },
//       { name: 'nonce', type: 'uint256' },
//       { name: 'expiry', type: 'uint256' },
//     ],
//   }
//   const signer = provider.getSigner ? provider.getSigner() : provider
//   const signature = await sign(domain, primaryType, message, types, signer)
//   return signature
// }
//# sourceMappingURL=comp.js.map