mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-11 14:09:15 +00:00
Move send to Faucet; and test
This commit is contained in:
parent
d378df6b8c
commit
940c41ba64
@ -13,7 +13,6 @@ import {
|
||||
identitiesOfFirstWallet,
|
||||
loadAccounts,
|
||||
loadTokenTickers,
|
||||
send,
|
||||
} from "../../multichainhelpers";
|
||||
import { setSecretAndCreateIdentities } from "../../profile";
|
||||
import { SendJob } from "../../types";
|
||||
@ -138,7 +137,7 @@ export async function start(args: ReadonlyArray<string>): Promise<void> {
|
||||
tokenTicker: ticker,
|
||||
};
|
||||
logSendJob(job);
|
||||
await send(profile, connection, connector.codec, job);
|
||||
await faucet.send(profile, job);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
throw new HttpError(500, "Sending tokens failed");
|
||||
|
@ -1,5 +1,10 @@
|
||||
import { CosmWasmCodec, CosmWasmConnection, TokenConfiguration } from "@cosmwasm/bcp";
|
||||
import { CosmosAddressBech32Prefix } from "@cosmwasm/sdk";
|
||||
import { Address, ChainId, Identity, TokenTicker } from "@iov/bcp";
|
||||
import { Random } from "@iov/crypto";
|
||||
import { Bech32 } from "@iov/encoding";
|
||||
import { HdPaths, Secp256k1HdWallet, UserProfile } from "@iov/keycontrol";
|
||||
import { assert } from "@iov/utils";
|
||||
|
||||
import { Faucet } from "./faucet";
|
||||
|
||||
@ -13,22 +18,55 @@ const httpUrl = "http://localhost:1317";
|
||||
const defaultConfig: TokenConfiguration = {
|
||||
bankTokens: [
|
||||
{
|
||||
ticker: "TOKENZ",
|
||||
name: "The tokenz",
|
||||
fractionalDigits: 6,
|
||||
denom: "utokenz",
|
||||
name: "Fee Token",
|
||||
ticker: "COSM",
|
||||
denom: "ucosm",
|
||||
},
|
||||
{
|
||||
ticker: "TRASH",
|
||||
name: "Trash token",
|
||||
fractionalDigits: 3,
|
||||
denom: "mtrash",
|
||||
fractionalDigits: 6,
|
||||
name: "Staking Token",
|
||||
ticker: "STAKE",
|
||||
denom: "ustake",
|
||||
},
|
||||
],
|
||||
erc20Tokens: [
|
||||
// {
|
||||
// contractAddress: "cosmos18vd8fpwxzck93qlwghaj6arh4p7c5n89uzcee5",
|
||||
// fractionalDigits: 5,
|
||||
// ticker: "ASH",
|
||||
// name: "Ash Token",
|
||||
// },
|
||||
// {
|
||||
// contractAddress: "cosmos1hqrdl6wstt8qzshwc6mrumpjk9338k0lr4dqxd",
|
||||
// fractionalDigits: 0,
|
||||
// ticker: "BASH",
|
||||
// name: "Bash Token",
|
||||
// },
|
||||
],
|
||||
};
|
||||
const defaultPrefix = "cosmos" as CosmosAddressBech32Prefix;
|
||||
const defaultChainId = "cosmos:testing" as ChainId;
|
||||
const codec = new CosmWasmCodec(defaultPrefix, defaultConfig.bankTokens);
|
||||
|
||||
function makeRandomAddress(): Address {
|
||||
return Bech32.encode(defaultPrefix, Random.getBytes(20)) as Address;
|
||||
}
|
||||
|
||||
const faucetMnemonic =
|
||||
"economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone";
|
||||
const faucetPath = HdPaths.cosmos(0);
|
||||
|
||||
async function makeProfile(): Promise<{ readonly profile: UserProfile; readonly holder: Identity }> {
|
||||
const profile = new UserProfile();
|
||||
const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(faucetMnemonic));
|
||||
const holder = await profile.createIdentity(wallet.id, defaultChainId, faucetPath);
|
||||
return {
|
||||
profile: profile,
|
||||
holder: holder,
|
||||
};
|
||||
}
|
||||
|
||||
describe("Faucet", () => {
|
||||
describe("constructor", () => {
|
||||
it("can be constructed", async () => {
|
||||
@ -39,4 +77,34 @@ describe("Faucet", () => {
|
||||
connection.disconnect();
|
||||
});
|
||||
});
|
||||
|
||||
describe("send", () => {
|
||||
it("can send", async () => {
|
||||
pendingWithoutCosmos();
|
||||
const connection = await CosmWasmConnection.establish(httpUrl, defaultPrefix, defaultConfig);
|
||||
const { profile, holder } = await makeProfile();
|
||||
const faucet = new Faucet(defaultConfig, connection, codec);
|
||||
const recipient = makeRandomAddress();
|
||||
await faucet.send(profile, {
|
||||
amount: {
|
||||
quantity: "23456",
|
||||
fractionalDigits: 6,
|
||||
tokenTicker: "COSM" as TokenTicker,
|
||||
},
|
||||
tokenTicker: "COSM" as TokenTicker,
|
||||
sender: holder,
|
||||
recipient: recipient,
|
||||
});
|
||||
const account = await connection.getAccount({ address: recipient });
|
||||
assert(account);
|
||||
expect(account.balance).toEqual([
|
||||
{
|
||||
quantity: "23456",
|
||||
fractionalDigits: 6,
|
||||
tokenTicker: "COSM" as TokenTicker,
|
||||
},
|
||||
]);
|
||||
connection.disconnect();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,5 +1,11 @@
|
||||
import { TokenConfiguration } from "@cosmwasm/bcp";
|
||||
import { BlockchainConnection, TxCodec } from "@iov/bcp";
|
||||
import {
|
||||
BlockchainConnection,
|
||||
isBlockInfoFailed,
|
||||
isBlockInfoPending,
|
||||
SendTransaction,
|
||||
TxCodec,
|
||||
} from "@iov/bcp";
|
||||
import { UserProfile } from "@iov/keycontrol";
|
||||
import { sleep } from "@iov/utils";
|
||||
|
||||
@ -9,7 +15,6 @@ import {
|
||||
identitiesOfFirstWallet,
|
||||
loadAccounts,
|
||||
loadTokenTickers,
|
||||
send,
|
||||
} from "./multichainhelpers";
|
||||
import { TokenManager } from "./tokenmanager";
|
||||
import { SendJob } from "./types";
|
||||
@ -27,6 +32,30 @@ export class Faucet {
|
||||
this.codec = codec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and posts a send transaction. Then waits until the transaction is in a block.
|
||||
*/
|
||||
public async send(profile: UserProfile, job: SendJob): Promise<void> {
|
||||
const sendWithFee = await this.connection.withDefaultFee<SendTransaction>({
|
||||
kind: "bcp/send",
|
||||
chainId: this.connection.chainId(),
|
||||
sender: this.codec.identityToAddress(job.sender),
|
||||
senderPubkey: job.sender.pubkey,
|
||||
recipient: job.recipient,
|
||||
memo: "Make love, not war",
|
||||
amount: job.amount,
|
||||
});
|
||||
|
||||
const nonce = await this.connection.getNonce({ pubkey: job.sender.pubkey });
|
||||
const signed = await profile.signTransaction(job.sender, sendWithFee, this.codec, nonce);
|
||||
|
||||
const post = await this.connection.postTx(this.codec.bytesToPost(signed));
|
||||
const blockInfo = await post.blockInfo.waitFor(info => !isBlockInfoPending(info));
|
||||
if (isBlockInfoFailed(blockInfo)) {
|
||||
throw new Error(`Sending tokens failed. Code: ${blockInfo.code}, message: ${blockInfo.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
public async refill(profile: UserProfile): Promise<void> {
|
||||
console.info(`Connected to network: ${this.connection.chainId()}`);
|
||||
console.info(`Tokens on network: ${(await loadTokenTickers(this.connection)).join(", ")}`);
|
||||
@ -63,7 +92,7 @@ export class Faucet {
|
||||
if (jobs.length > 0) {
|
||||
for (const job of jobs) {
|
||||
logSendJob(job);
|
||||
await send(profile, this.connection, this.codec, job);
|
||||
await this.send(profile, job);
|
||||
await sleep(50);
|
||||
}
|
||||
|
||||
|
@ -1,17 +1,7 @@
|
||||
import {
|
||||
Account,
|
||||
BlockchainConnection,
|
||||
Identity,
|
||||
isBlockInfoFailed,
|
||||
isBlockInfoPending,
|
||||
SendTransaction,
|
||||
TokenTicker,
|
||||
TxCodec,
|
||||
} from "@iov/bcp";
|
||||
import { Account, BlockchainConnection, Identity, TokenTicker } from "@iov/bcp";
|
||||
import { UserProfile } from "@iov/keycontrol";
|
||||
|
||||
import { identityToAddress } from "./addresses";
|
||||
import { SendJob } from "./types";
|
||||
|
||||
export function identitiesOfFirstWallet(profile: UserProfile): ReadonlyArray<Identity> {
|
||||
const wallet = profile.wallets.value[0];
|
||||
@ -49,35 +39,6 @@ export async function loadTokenTickers(
|
||||
return (await connection.getAllTokens()).map(token => token.tokenTicker);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates and posts a send transaction. Then waits until the transaction is in a block.
|
||||
*/
|
||||
export async function send(
|
||||
profile: UserProfile,
|
||||
connection: BlockchainConnection,
|
||||
codec: TxCodec,
|
||||
job: SendJob,
|
||||
): Promise<void> {
|
||||
const sendWithFee = await connection.withDefaultFee<SendTransaction>({
|
||||
kind: "bcp/send",
|
||||
chainId: connection.chainId(),
|
||||
sender: codec.identityToAddress(job.sender),
|
||||
senderPubkey: job.sender.pubkey,
|
||||
recipient: job.recipient,
|
||||
memo: "We ❤️ developers – iov.one",
|
||||
amount: job.amount,
|
||||
});
|
||||
|
||||
const nonce = await connection.getNonce({ pubkey: job.sender.pubkey });
|
||||
const signed = await profile.signTransaction(job.sender, sendWithFee, codec, nonce);
|
||||
|
||||
const post = await connection.postTx(codec.bytesToPost(signed));
|
||||
const blockInfo = await post.blockInfo.waitFor(info => !isBlockInfoPending(info));
|
||||
if (isBlockInfoFailed(blockInfo)) {
|
||||
throw new Error(`Sending tokens failed. Code: ${blockInfo.code}, message: ${blockInfo.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
export function availableTokensFromHolder(holderAccount: Account): ReadonlyArray<TokenTicker> {
|
||||
return holderAccount.balance.map(coin => coin.tokenTicker);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user