/** * This file was automatically generated by @octalmage/terra-cosmwasm-typescript-gen@0.2.0. * DO NOT MODIFY IT BY HAND. Instead, modify the source JSONSchema file, * and run the @octalmage/terra-cosmwasm-typescript-gen generate command to regenerate this file. */ import { LCDClient, Coins, Wallet, MsgExecuteContract, TxInfo, WaitTxBroadcastResult, Msg, Fee, } from '@terra-money/terra.js'; import { ConnectedWallet } from '@terra-money/wallet-provider'; import { NETWORK } from '../../@types'; import { NETWORKS, taxCapUrl, taxRateUrl, UNIT, WAIT_TIME_IN_BLOCK } from '../../constant'; import { contractAddress } from '../address'; import fetch from 'cross-fetch'; function isConnectedWallet(x: Wallet | ConnectedWallet): x is ConnectedWallet { return typeof (x as Wallet).key === 'undefined'; } export async function waitForInclusionInBlock( lcd: LCDClient, txHash: string ): Promise { let res; for (let i = 0; i <= 50; i++) { try { res = await lcd.tx.txInfo(txHash); } catch (error) { // NOOP } if (res) { break; } await new Promise(resolve => setTimeout(resolve, 500)); } return res; } export interface AllAccountsResponse { accounts: string[]; [k: string]: unknown; } export type Uint128 = string; export type Expiration = | { at_height: number; } | { at_time: Timestamp; } | { never: { [k: string]: unknown; }; }; export type Timestamp = Uint64; export type Uint64 = string; export interface AllAllowancesResponse { allowances: AllowanceInfo[]; [k: string]: unknown; } export interface AllowanceInfo { allowance: Uint128; expires: Expiration; spender: string; [k: string]: unknown; } export interface AllowanceResponse { allowance: Uint128; expires: Expiration; [k: string]: unknown; } export interface BalanceResponse { balance: Uint128; [k: string]: unknown; } export type Binary = string; export interface DownloadLogoResponse { data: Binary; mime_type: string; [k: string]: unknown; } export type ExecuteMsg = | { deposit: { [k: string]: unknown; }; } | { redeem: { amount: Uint128; [k: string]: unknown; }; } | { transfer: { amount: Uint128; recipient: string; [k: string]: unknown; }; } | { burn: { amount: Uint128; [k: string]: unknown; }; } | { send: { amount: Uint128; contract: string; msg: Binary; [k: string]: unknown; }; } | { increase_allowance: { amount: Uint128; expires?: Expiration | null; spender: string; [k: string]: unknown; }; } | { decrease_allowance: { amount: Uint128; expires?: Expiration | null; spender: string; [k: string]: unknown; }; } | { transfer_from: { amount: Uint128; owner: string; recipient: string; [k: string]: unknown; }; } | { send_from: { amount: Uint128; contract: string; msg: Binary; owner: string; [k: string]: unknown; }; } | { burn_from: { amount: Uint128; owner: string; [k: string]: unknown; }; } | { update_minter: { new_minter?: string | null; [k: string]: unknown; }; } | { update_marketing: { description?: string | null; marketing?: string | null; project?: string | null; [k: string]: unknown; }; }; export type Logo = | { url: string; } | { embedded: EmbeddedLogo; }; export type EmbeddedLogo = | { svg: Binary; } | { png: Binary; }; export interface InstantiateMsg { decimals: number; initial_balances: Cw20Coin[]; marketing?: InstantiateMarketingInfo | null; mint?: MinterResponse | null; name: string; symbol: string; [k: string]: unknown; } export interface Cw20Coin { address: string; amount: Uint128; [k: string]: unknown; } export interface InstantiateMarketingInfo { description?: string | null; logo?: Logo | null; marketing?: string | null; project?: string | null; [k: string]: unknown; } export interface MinterResponse { cap?: Uint128 | null; minter: string; [k: string]: unknown; } export type LogoInfo = | 'embedded' | { url: string; }; export type Addr = string; export interface MarketingInfoResponse { description?: string | null; logo?: LogoInfo | null; marketing?: Addr | null; project?: string | null; [k: string]: unknown; } export type QueryMsg = | { balance: { address: string; [k: string]: unknown; }; } | { token_info: { [k: string]: unknown; }; } | { minter: { [k: string]: unknown; }; } | { allowance: { owner: string; spender: string; [k: string]: unknown; }; } | { all_allowances: { limit?: number | null; owner: string; start_after?: string | null; [k: string]: unknown; }; } | { all_accounts: { limit?: number | null; start_after?: string | null; [k: string]: unknown; }; } | { marketing_info: { [k: string]: unknown; }; } | { download_logo: { [k: string]: unknown; }; }; export interface TokenInfoResponse { decimals: number; name: string; symbol: string; total_supply: Uint128; [k: string]: unknown; } export interface WluncReadOnlyInterface { contractAddress: string; balanceQuery: ({ address }: { address: string }) => Promise; tokenInfoQuery: () => Promise; minterQuery: () => Promise; allowanceQuery: ({ owner, spender, }: { owner: string; spender: string; }) => Promise; allAllowancesQuery: ({ limit, owner, startAfter, }: { limit?: number; owner: string; startAfter?: string; }) => Promise; allAccountsQuery: ({ limit, startAfter, }: { limit?: number; startAfter?: string; }) => Promise; marketingInfoQuery: () => Promise; downloadLogoQuery: () => Promise; } export class WluncQueryClient implements WluncReadOnlyInterface { client: LCDClient; contractAddress: string; network: NETWORK = 'classic'; constructor(client: LCDClient) { this.client = client; this.network = this.setNetwork(); this.contractAddress = contractAddress('wlunc', this.network); this.balanceQuery = this.balanceQuery.bind(this); this.tokenInfoQuery = this.tokenInfoQuery.bind(this); this.minterQuery = this.minterQuery.bind(this); this.allowanceQuery = this.allowanceQuery.bind(this); this.allAllowancesQuery = this.allAllowancesQuery.bind(this); this.allAccountsQuery = this.allAccountsQuery.bind(this); this.marketingInfoQuery = this.marketingInfoQuery.bind(this); this.downloadLogoQuery = this.downloadLogoQuery.bind(this); } setNetwork = (): NETWORK => { let network: NETWORK = 'classic'; Object.entries(NETWORKS).map(([key, value]) => { if (value.chainId === this.client.config.chainID) { // @ts-ignore network = key; return; } }); return network; }; balanceQuery = async ({ address, }: { address: string; }): Promise => { return this.client.wasm.contractQuery(this.contractAddress, { balance: { address, }, }); }; tokenInfoQuery = async (): Promise => { return this.client.wasm.contractQuery(this.contractAddress, { token_info: {}, }); }; minterQuery = async (): Promise => { return this.client.wasm.contractQuery(this.contractAddress, { minter: {}, }); }; allowanceQuery = async ({ owner, spender, }: { owner: string; spender: string; }): Promise => { return this.client.wasm.contractQuery(this.contractAddress, { allowance: { owner, spender, }, }); }; allAllowancesQuery = async ({ limit, owner, startAfter, }: { limit?: number; owner: string; startAfter?: string; }): Promise => { return this.client.wasm.contractQuery(this.contractAddress, { all_allowances: { limit, owner, start_after: startAfter, }, }); }; allAccountsQuery = async ({ limit, startAfter, }: { limit?: number; startAfter?: string; }): Promise => { return this.client.wasm.contractQuery(this.contractAddress, { all_accounts: { limit, start_after: startAfter, }, }); }; marketingInfoQuery = async (): Promise => { return this.client.wasm.contractQuery(this.contractAddress, { marketing_info: {}, }); }; downloadLogoQuery = async (): Promise => { return this.client.wasm.contractQuery(this.contractAddress, { download_logo: {}, }); }; } export interface WluncInterface extends WluncReadOnlyInterface { contractAddress: string; deposit: (funds?: Coins) => Promise; redeem: ( { amount, }: { amount: string; }, funds?: Coins ) => Promise; transfer: ( { amount, recipient, }: { amount: string; recipient: string; }, funds?: Coins ) => Promise; burn: ( { amount, }: { amount: string; }, funds?: Coins ) => Promise; send: ( { amount, contract, msg, }: { amount: string; contract: string; msg: string; }, funds?: Coins ) => Promise; increaseAllowance: ( { amount, expires, spender, }: { amount: string; expires?: Expiration; spender: string; }, funds?: Coins ) => Promise; decreaseAllowance: ( { amount, expires, spender, }: { amount: string; expires?: Expiration; spender: string; }, funds?: Coins ) => Promise; transferFrom: ( { amount, owner, recipient, }: { amount: string; owner: string; recipient: string; }, funds?: Coins ) => Promise; sendFrom: ( { amount, contract, msg, owner, }: { amount: string; contract: string; msg: string; owner: string; }, funds?: Coins ) => Promise; burnFrom: ( { amount, owner, }: { amount: string; owner: string; }, funds?: Coins ) => Promise; } export class WluncClient extends WluncQueryClient implements WluncInterface { client: LCDClient; wallet: Wallet | ConnectedWallet; taxRate: any; taxCap: any; constructor(client: LCDClient, wallet: Wallet | ConnectedWallet) { super(client); this.client = client; this.wallet = wallet; this.deposit = this.deposit.bind(this); this.redeem = this.redeem.bind(this); this.transfer = this.transfer.bind(this); this.burn = this.burn.bind(this); this.send = this.send.bind(this); this.increaseAllowance = this.increaseAllowance.bind(this); this.decreaseAllowance = this.decreaseAllowance.bind(this); this.transferFrom = this.transferFrom.bind(this); this.sendFrom = this.sendFrom.bind(this); this.burnFrom = this.burnFrom.bind(this); this.calcFee = this.calcFee.bind(this); this.initGas(); } initGas = () => { // Retrieve current gas prices if (this.client.config.isClassic) { // @ts-ignore fetch(taxRateUrl).then(taxRateRaw => { taxRateRaw.json().then(res => { this.taxRate = res; }); }); // @ts-ignore fetch(taxCapUrl).then(taxCapRaw => { taxCapRaw.json().then(res => { this.taxCap = res; }); }); } }; calcFee = async (luncAmount: string, msgs: Msg[]) => { let txFee; try { // Estimate the gas amount and fee (without burn tax) for the message try { if (isConnectedWallet(this.wallet)) { const accountInfo = await this.client.auth.accountInfo( this.wallet.terraAddress ); const signerData = [ { sequenceNumber: accountInfo.getSequenceNumber() }, ]; txFee = await this.client.tx.estimateFee(signerData, { msgs: msgs, gasPrices: this.client.config.gasPrices, gasAdjustment: 3, feeDenoms: ['uluna'], }); } else { const walletInfo = await this.wallet.accountNumberAndSequence(); const signerData = [{ sequenceNumber: walletInfo.sequence }]; txFee = await this.client.tx.estimateFee(signerData, { msgs: msgs, gasPrices: this.client.config.gasPrices, gasAdjustment: 3, feeDenoms: ['uluna'], }); } } catch (e) { console.log('fee estimation error - estimateFee: ', e); txFee = new Fee(UNIT, { uluna: luncAmount }); } let fee = txFee; let taxAmount = 0; // Retrieve the tax rate and tax cap if (this.client.config.isClassic) { try { // Compute the burn tax amount for this transaction and convert to Coins taxAmount = Math.min( Math.ceil( parseFloat(luncAmount) * parseFloat(this.taxRate?.tax_rate) ), parseInt(this.taxCap?.tax_cap) ); const taxAmountCoins = new Coins({ uluna: taxAmount }); // Add the burn tax component to the estimated fee const totalFee = txFee.amount.add(taxAmountCoins); fee = new Fee(txFee.gas_limit, totalFee); } catch (e) { console.log('tax calculation error: ', e); } } return { fee, txFee, tax: taxAmount }; } catch (e) { console.log('fee estimation error: ', e); return { fee: new Fee(UNIT, { uluna: luncAmount }), txFee, tax: 0 }; } }; deposit = async ( funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { deposit: {}, }, funds ); const luncData = funds?.toData(); const { fee } = await this.calcFee(luncData?.[0].amount || '1', [execMsg]); const actualExecMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { deposit: {}, }, funds ); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [actualExecMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', feeDenoms: ['uluna'], fee, }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; redeem = async ( { amount, }: { amount: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { redeem: { amount, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', feeDenoms: ['uluna'], fee, }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; transfer = async ( { amount, recipient, }: { amount: string; recipient: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { transfer: { amount, recipient, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', feeDenoms: ['uluna'], fee, }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', feeDenoms: ['uluna'], fee, }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; burn = async ( { amount, }: { amount: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { burn: { amount, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; send = async ( { amount, contract, msg, }: { amount: string; contract: string; msg: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { send: { amount, contract, msg, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; increaseAllowance = async ( { amount, expires, spender, }: { amount: string; expires?: Expiration; spender: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { increase_allowance: { amount, expires, spender, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', feeDenoms: ['uluna'], fee, }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', feeDenoms: ['uluna'], fee, }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; decreaseAllowance = async ( { amount, expires, spender, }: { amount: string; expires?: Expiration; spender: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { decrease_allowance: { amount, expires, spender, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; transferFrom = async ( { amount, owner, recipient, }: { amount: string; owner: string; recipient: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { transfer_from: { amount, owner, recipient, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; sendFrom = async ( { amount, contract, msg, owner, }: { amount: string; contract: string; msg: string; owner: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { send_from: { amount, contract, msg, owner, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; burnFrom = async ( { amount, owner, }: { amount: string; owner: string; }, funds?: Coins ): Promise => { const senderAddress = isConnectedWallet(this.wallet) ? this.wallet.walletAddress : this.wallet.key.accAddress; const execMsg = new MsgExecuteContract( senderAddress, this.contractAddress, { burn_from: { amount, owner, }, }, funds ); const { fee } = await this.calcFee('0', [execMsg]); if (isConnectedWallet(this.wallet)) { const tx = await this.wallet.post({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return waitForInclusionInBlock(this.client, tx.result.txhash); } else { const execTx = await this.wallet.createAndSignTx({ msgs: [execMsg], // @ts-ignore isClassic: this.network === 'classic', fee: fee, feeDenoms: ['uluna'], }); return this.client.tx.broadcast(execTx, WAIT_TIME_IN_BLOCK); } }; }