mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-11 14:09:15 +00:00
faucet: Update faucet and profile for Stargate
This commit is contained in:
parent
0dcf0ba490
commit
240c41e055
@ -1,14 +1,18 @@
|
||||
import {
|
||||
assertIsBroadcastTxSuccess,
|
||||
assertIsBroadcastTxSuccess as assertIsBroadcastTxSuccessLaunchpad,
|
||||
CosmosClient,
|
||||
OfflineSigner,
|
||||
SigningCosmosClient,
|
||||
} from "@cosmjs/launchpad";
|
||||
import {
|
||||
assertIsBroadcastTxSuccess as assertIsBroadcastTxSuccessStargate,
|
||||
SigningStargateClient,
|
||||
StargateClient,
|
||||
} from "@cosmjs/stargate";
|
||||
import { sleep } from "@cosmjs/utils";
|
||||
|
||||
import * as constants from "./constants";
|
||||
import { debugAccount, logAccountsState, logSendJob } from "./debugging";
|
||||
import { createWallets } from "./profile";
|
||||
import { createClients, createWallets } from "./profile";
|
||||
import { TokenConfiguration, TokenManager } from "./tokenmanager";
|
||||
import { MinimalAccount, SendJob } from "./types";
|
||||
|
||||
@ -23,10 +27,13 @@ export class Faucet {
|
||||
config: TokenConfiguration,
|
||||
mnemonic: string,
|
||||
numberOfDistributors: number,
|
||||
stargate = true,
|
||||
logging = false,
|
||||
): Promise<Faucet> {
|
||||
const wallets = await createWallets(mnemonic, addressPrefix, numberOfDistributors, logging);
|
||||
return new Faucet(apiUrl, addressPrefix, config, wallets, logging);
|
||||
const wallets = await createWallets(mnemonic, addressPrefix, numberOfDistributors, stargate, logging);
|
||||
const clients = await createClients(apiUrl, wallets);
|
||||
const readonlyClient = stargate ? await StargateClient.connect(apiUrl) : new CosmosClient(apiUrl);
|
||||
return new Faucet(addressPrefix, config, clients, readonlyClient, logging);
|
||||
}
|
||||
|
||||
public readonly addressPrefix: string;
|
||||
@ -35,39 +42,28 @@ export class Faucet {
|
||||
|
||||
private readonly tokenConfig: TokenConfiguration;
|
||||
private readonly tokenManager: TokenManager;
|
||||
private readonly readOnlyClient: CosmosClient;
|
||||
private readonly clients: { [senderAddress: string]: SigningCosmosClient };
|
||||
private readonly readOnlyClient: CosmosClient | StargateClient;
|
||||
private readonly clients: { [senderAddress: string]: SigningCosmosClient | SigningStargateClient };
|
||||
private readonly logging: boolean;
|
||||
private creditCount = 0;
|
||||
|
||||
private constructor(
|
||||
apiUrl: string,
|
||||
addressPrefix: string,
|
||||
config: TokenConfiguration,
|
||||
wallets: ReadonlyArray<readonly [string, OfflineSigner]>,
|
||||
clients: ReadonlyArray<readonly [string, SigningCosmosClient | SigningStargateClient]>,
|
||||
readonlyClient: CosmosClient | StargateClient,
|
||||
logging = false,
|
||||
) {
|
||||
this.addressPrefix = addressPrefix;
|
||||
this.tokenConfig = config;
|
||||
this.tokenManager = new TokenManager(config);
|
||||
|
||||
this.readOnlyClient = new CosmosClient(apiUrl);
|
||||
|
||||
this.holderAddress = wallets[0][0];
|
||||
this.distributorAddresses = wallets.slice(1).map((pair) => pair[0]);
|
||||
|
||||
// we need one client per sender
|
||||
const clients: { [senderAddress: string]: SigningCosmosClient } = {};
|
||||
for (const [senderAddress, wallet] of wallets) {
|
||||
clients[senderAddress] = new SigningCosmosClient(
|
||||
apiUrl,
|
||||
senderAddress,
|
||||
wallet,
|
||||
constants.gasPrice,
|
||||
constants.gasLimits,
|
||||
this.readOnlyClient = readonlyClient;
|
||||
[this.holderAddress, ...this.distributorAddresses] = clients.map(([address]) => address);
|
||||
this.clients = clients.reduce(
|
||||
(acc, [senderAddress, client]) => ({ ...acc, [senderAddress]: client }),
|
||||
{},
|
||||
);
|
||||
}
|
||||
this.clients = clients;
|
||||
this.logging = logging;
|
||||
}
|
||||
|
||||
@ -75,9 +71,7 @@ export class Faucet {
|
||||
* Returns a list of denoms of tokens owned by the the holder and configured in the faucet
|
||||
*/
|
||||
public async availableTokens(): Promise<string[]> {
|
||||
const holderAccount = await this.readOnlyClient.getAccount(this.holderAddress);
|
||||
const balance = holderAccount ? holderAccount.balance : [];
|
||||
|
||||
const { balance } = await this.loadAccount(this.holderAddress);
|
||||
return balance
|
||||
.filter((b) => b.amount !== "0")
|
||||
.map((b) => this.tokenConfig.bankTokens.find((token) => token == b.denom))
|
||||
@ -89,8 +83,13 @@ export class Faucet {
|
||||
* Throws an error if the transaction failed.
|
||||
*/
|
||||
public async send(job: SendJob): Promise<void> {
|
||||
const result = await this.clients[job.sender].sendTokens(job.recipient, [job.amount], constants.memo);
|
||||
assertIsBroadcastTxSuccess(result);
|
||||
const client = this.clients[job.sender];
|
||||
if (client instanceof SigningCosmosClient) {
|
||||
const result = await client.sendTokens(job.recipient, [job.amount], constants.memo);
|
||||
return assertIsBroadcastTxSuccessLaunchpad(result);
|
||||
}
|
||||
const result = await client.sendTokens(job.sender, job.recipient, [job.amount], constants.memo);
|
||||
assertIsBroadcastTxSuccessStargate(result);
|
||||
}
|
||||
|
||||
/** Use one of the distributor accounts to send tokens to user */
|
||||
@ -111,24 +110,21 @@ export class Faucet {
|
||||
return Array.from(this.tokenConfig.bankTokens);
|
||||
}
|
||||
|
||||
public async loadAccounts(): Promise<readonly MinimalAccount[]> {
|
||||
const addresses = [this.holderAddress, ...this.distributorAddresses];
|
||||
public async loadAccount(address: string): Promise<MinimalAccount> {
|
||||
const balance =
|
||||
this.readOnlyClient instanceof CosmosClient
|
||||
? (await this.readOnlyClient.getAccount(address))?.balance ?? []
|
||||
: await this.readOnlyClient.getAllBalancesUnverified(address);
|
||||
|
||||
return Promise.all(
|
||||
addresses.map(
|
||||
async (address): Promise<MinimalAccount> => {
|
||||
const response = await this.readOnlyClient.getAccount(address);
|
||||
if (response) {
|
||||
return response;
|
||||
} else {
|
||||
return {
|
||||
address: address,
|
||||
balance: [],
|
||||
balance: balance,
|
||||
};
|
||||
}
|
||||
},
|
||||
),
|
||||
);
|
||||
|
||||
public async loadAccounts(): Promise<readonly MinimalAccount[]> {
|
||||
const addresses = [this.holderAddress, ...this.distributorAddresses];
|
||||
return Promise.all(addresses.map(this.loadAccount.bind(this)));
|
||||
}
|
||||
|
||||
public async refill(): Promise<void> {
|
||||
|
@ -1,19 +1,25 @@
|
||||
import { pathToString } from "@cosmjs/crypto";
|
||||
import { makeCosmoshubPath, OfflineSigner, Secp256k1HdWallet } from "@cosmjs/launchpad";
|
||||
import { makeCosmoshubPath, Secp256k1HdWallet, SigningCosmosClient } from "@cosmjs/launchpad";
|
||||
import { DirectSecp256k1Wallet, isOfflineDirectSigner, OfflineSigner } from "@cosmjs/proto-signing";
|
||||
import { SigningStargateClient } from "@cosmjs/stargate";
|
||||
|
||||
import * as constants from "./constants";
|
||||
|
||||
export async function createWallets(
|
||||
mnemonic: string,
|
||||
addressPrefix: string,
|
||||
numberOfDistributors: number,
|
||||
stargate = true,
|
||||
logging = false,
|
||||
): Promise<ReadonlyArray<readonly [string, OfflineSigner]>> {
|
||||
const createWallet = stargate ? DirectSecp256k1Wallet.fromMnemonic : Secp256k1HdWallet.fromMnemonic;
|
||||
const wallets = new Array<readonly [string, OfflineSigner]>();
|
||||
|
||||
// first account is the token holder
|
||||
const numberOfIdentities = 1 + numberOfDistributors;
|
||||
for (let i = 0; i < numberOfIdentities; i++) {
|
||||
const path = makeCosmoshubPath(i);
|
||||
const wallet = await Secp256k1HdWallet.fromMnemonic(mnemonic, path, addressPrefix);
|
||||
const wallet = await createWallet(mnemonic, path, addressPrefix);
|
||||
const [{ address }] = await wallet.getAccounts();
|
||||
if (logging) {
|
||||
const role = i === 0 ? "token holder " : `distributor ${i}`;
|
||||
@ -24,3 +30,22 @@ export async function createWallets(
|
||||
|
||||
return wallets;
|
||||
}
|
||||
|
||||
export async function createClients(
|
||||
apiUrl: string,
|
||||
wallets: ReadonlyArray<readonly [string, OfflineSigner]>,
|
||||
): Promise<ReadonlyArray<readonly [string, SigningCosmosClient | SigningStargateClient]>> {
|
||||
// we need one client per sender
|
||||
return Promise.all(
|
||||
wallets.map(
|
||||
async ([senderAddress, wallet]): Promise<
|
||||
readonly [string, SigningCosmosClient | SigningStargateClient]
|
||||
> => [
|
||||
senderAddress,
|
||||
isOfflineDirectSigner(wallet)
|
||||
? await SigningStargateClient.connectWithWallet(apiUrl, wallet, {})
|
||||
: new SigningCosmosClient(apiUrl, senderAddress, wallet, constants.gasPrice, constants.gasLimits),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user