Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save the-frey/ebecfbb8aa89a4d7b072ac20f8694113 to your computer and use it in GitHub Desktop.
Save the-frey/ebecfbb8aa89a4d7b072ac20f8694113 to your computer and use it in GitHub Desktop.
CW20 stargate cosmos
import axios from "axios"
import { SigningCosmWasmClient } from "@cosmjs/cosmwasm-stargate";
// TODO: Extract to separate folder: interfaces and funcs
interface Balances {
readonly address: string
readonly amount: string // decimal as string
}
interface MintInfo {
readonly minter: string
readonly cap?: string // decimal as string
}
type Expiration = {readonly at_height: number} | {readonly at_time: number} | {readonly never: {}};
interface AllowanceResponse {
readonly allowance: string; // integer as string
readonly expires: Expiration;
}
interface AllowanceInfo {
readonly allowance: string; // integer as string
readonly spender: string; // bech32 address
readonly expires: Expiration;
}
interface AllAllowancesResponse {
readonly allowances: readonly AllowanceInfo[];
}
interface AllAccountsResponse {
// list of bech32 address that have a balance
readonly accounts: readonly string[];
}
interface CW20Instance {
readonly contractAddress: string
// queries
balance: (address?: string) => Promise<string>
allowance: (owner: string, spender: string) => Promise<AllowanceResponse>
allAllowances: (owner: string, startAfter?: string, limit?: number) => Promise<AllAllowancesResponse>
allAccounts: (startAfter?: string, limit?: number) => Promise<readonly string[]>
tokenInfo: () => Promise<any>
minter: () => Promise<any>
// actions
mint: (txSigner: string, recipient: string, amount: string) => Promise<string>
transfer: (txSigner: string, recipient: string, amount: string) => Promise<string>
burn: (txSigner: string, amount: string) => Promise<string>
increaseAllowance: (txSigner: string, recipient: string, amount: string) => Promise<string>
decreaseAllowance: (txSigner: string, recipient: string, amount: string) => Promise<string>
transferFrom: (txSigner: string, owner: string, recipient: string, amount: string) => Promise<string>
}
interface CW20Contract {
// upload a code blob and returns a codeId
upload: (txSigner: string) => Promise<number>
// instantiates a cw20 contract
// codeId must come from a previous deploy
// label is the public name of the contract in listing
// if you set admin, you can run migrations on this contract (likely client.senderAddress)
instantiate: (txSigner: string, codeId: number, initMsg: Record<string, unknown>, label: string, admin?: string) => Promise<CW20Instance>
use: (contractAddress: string) => CW20Instance
}
export const CW20 = (client: SigningCosmWasmClient): CW20Contract => {
const use = (contractAddress: string): CW20Instance => {
const balance = async (account: string): Promise<string> => {
const result = await client.queryContractSmart(contractAddress, {balance: { account }});
return result.balance;
};
const allowance = async (owner: string, spender: string): Promise<AllowanceResponse> => {
return client.queryContractSmart(contractAddress, {allowance: { owner, spender }});
};
const allAllowances = async (owner: string, startAfter?: string, limit?: number): Promise<AllAllowancesResponse> => {
return client.queryContractSmart(contractAddress, {all_allowances: { owner, start_after: startAfter, limit }});
};
const allAccounts = async (startAfter?: string, limit?: number): Promise<readonly string[]> => {
const accounts: AllAccountsResponse = await client.queryContractSmart(contractAddress, {all_accounts: { start_after: startAfter, limit }});
return accounts.accounts;
};
const tokenInfo = async (): Promise<any> => {
return client.queryContractSmart(contractAddress, {token_info: { }});
};
const minter = async (): Promise<any> => {
return client.queryContractSmart(contractAddress, {minter: { }});
};
// mints tokens, returns transactionHash
const mint = async (senderAddress: string, recipient: string, amount: string): Promise<string> => {
const result = await client.execute(senderAddress, contractAddress, {mint: {recipient, amount}});
return result.transactionHash;
}
// transfers tokens, returns transactionHash
const transfer = async (senderAddress: string, recipient: string, amount: string): Promise<string> => {
const result = await client.execute(senderAddress, contractAddress, {transfer: {recipient, amount}});
return result.transactionHash;
}
// burns tokens, returns transactionHash
const burn = async (senderAddress: string, amount: string): Promise<string> => {
const result = await client.execute(senderAddress, contractAddress, {burn: {amount}});
return result.transactionHash;
}
const increaseAllowance = async (senderAddress: string, spender: string, amount: string): Promise<string> => {
const result = await client.execute(senderAddress, contractAddress, {increase_allowance: {spender, amount}});
return result.transactionHash;
}
const decreaseAllowance = async (senderAddress: string, spender: string, amount: string): Promise<string> => {
const result = await client.execute(senderAddress, contractAddress, {decrease_allowance: {spender, amount}});
return result.transactionHash;
}
const transferFrom = async (senderAddress: string, owner: string, recipient: string, amount: string): Promise<string> => {
const result = await client.execute(senderAddress, contractAddress, {transfer_from: {owner, recipient, amount}});
return result.transactionHash;
}
return {
contractAddress,
balance,
allowance,
allAllowances,
allAccounts,
tokenInfo,
minter,
mint,
transfer,
burn,
increaseAllowance,
decreaseAllowance,
transferFrom,
};
}
const downloadWasm = async (url: string): Promise<Uint8Array> => {
const r = await axios.get(url, { responseType: 'arraybuffer' })
if (r.status !== 200) {
throw new Error(`Download error: ${r.status}`)
}
return r.data
}
const upload = async (senderAddress: string): Promise<number> => {
const meta = {
source: "https://github.com/CosmWasm/cosmwasm-plus/tree/v0.6.2/contracts/cw20-base",
builder: "cosmwasm/workspace-optimizer:0.10.7"
};
const sourceUrl = "https://github.com/CosmWasm/cosmwasm-plus/releases/download/v0.6.2/cw20_base.wasm";
const wasm = await downloadWasm(sourceUrl);
const result = await client.upload(senderAddress, wasm, meta);
return result.codeId;
}
const instantiate = async (senderAddress: string, codeId: number, initMsg: Record<string, unknown>, label: string, admin?: string): Promise<CW20Instance> => {
const result = await client.instantiate(senderAddress, codeId, initMsg, label, { memo: `Init ${label}`, admin});
return use(result.contractAddress);
}
return { upload, instantiate, use };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment