mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-11 14:09:15 +00:00
commit
065b1883ed
@ -27,6 +27,7 @@
|
||||
"import/no-cycle": "warn",
|
||||
"simple-import-sort/sort": "warn",
|
||||
"@typescript-eslint/explicit-function-return-type": ["warn", { "allowExpressions": true }],
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-empty-interface": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }],
|
||||
|
@ -21,7 +21,7 @@ FAUCET_CREDIT_AMOUNT_COSM=10 \
|
||||
FAUCET_CREDIT_AMOUNT_STAKE=5 \
|
||||
FAUCET_CONCURRENCY=3 \
|
||||
FAUCET_MNEMONIC="economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone" \
|
||||
./bin/cosmwasm-faucet start cosmwasm "http://localhost:1317"
|
||||
./bin/cosmwasm-faucet start "http://localhost:1317"
|
||||
```
|
||||
|
||||
## Usage
|
||||
@ -36,12 +36,10 @@ help Shows a help text and exits
|
||||
version Prints the version and exits
|
||||
|
||||
generate Generates a random mnemonic, shows derived faucet addresses and exits
|
||||
1 Codec
|
||||
2 Chain ID
|
||||
1 Chain ID
|
||||
|
||||
start Starts the faucet
|
||||
1 Codec
|
||||
2 Node base URL, e.g. wss://bov.friendnet-fast.iov.one
|
||||
1 Node base URL, e.g. http://localhost:1317
|
||||
|
||||
Environment variables
|
||||
|
||||
@ -99,7 +97,7 @@ DOCKER_HOST_IP=$(docker run --read-only --rm alpine ip route | awk 'NR==1 {print
|
||||
-e FAUCET_CONCURRENCY \
|
||||
-p 8000:8000 \
|
||||
cosmwasm/faucet:manual \
|
||||
start cosmwasm "http://$DOCKER_HOST_IP:1317"
|
||||
start "http://$DOCKER_HOST_IP:1317"
|
||||
```
|
||||
|
||||
### Using the faucet
|
||||
|
@ -21,7 +21,7 @@
|
||||
"access": "public"
|
||||
},
|
||||
"scripts": {
|
||||
"dev-start": "FAUCET_CREDIT_AMOUNT_COSM=10 FAUCET_CREDIT_AMOUNT_STAKE=5 FAUCET_CONCURRENCY=3 FAUCET_MNEMONIC=\"economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone\" ./bin/cosmwasm-faucet start cosmwasm \"http://localhost:1317\"",
|
||||
"dev-start": "FAUCET_CREDIT_AMOUNT_COSM=10 FAUCET_CREDIT_AMOUNT_STAKE=5 FAUCET_CONCURRENCY=3 FAUCET_MNEMONIC=\"economy stock theory fatal elder harbor betray wasp final emotion task crumble siren bottom lizard educate guess current outdoor pair theory focus wife stone\" ./bin/cosmwasm-faucet start \"http://localhost:1317\"",
|
||||
"docs": "shx rm -rf docs && typedoc --options typedoc.js",
|
||||
"format": "prettier --write --loglevel warn \"./src/**/*.ts\"",
|
||||
"lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && tslint -t verbose --project .",
|
||||
@ -36,8 +36,7 @@
|
||||
"@iov/bcp": "^2.0.0-alpha.7",
|
||||
"@iov/crypto": "^2.0.0-alpha.7",
|
||||
"@iov/encoding": "^2.0.0-alpha.7",
|
||||
"@iov/lisk": "^2.0.0-alpha.7",
|
||||
"@iov/multichain": "^2.0.0-alpha.7",
|
||||
"@iov/keycontrol": "^2.0.0-alpha.7",
|
||||
"@koa/cors": "^3.0.0",
|
||||
"axios": "^0.19.0",
|
||||
"fast-deep-equal": "^3.1.1",
|
||||
|
@ -2,22 +2,21 @@ import { ChainId } from "@iov/bcp";
|
||||
import { Bip39, Random } from "@iov/crypto";
|
||||
import { UserProfile } from "@iov/keycontrol";
|
||||
|
||||
import { codecFromString } from "../codec";
|
||||
import * as constants from "../constants";
|
||||
import { setSecretAndCreateIdentities } from "../profile";
|
||||
|
||||
export async function generate(args: ReadonlyArray<string>): Promise<void> {
|
||||
if (args.length < 2) {
|
||||
if (args.length < 1) {
|
||||
throw Error(
|
||||
`Not enough arguments for action 'generate'. See '${constants.binaryName} help' or README for arguments.`,
|
||||
);
|
||||
}
|
||||
const codecName = codecFromString(args[0]);
|
||||
const chainId = args[1] as ChainId;
|
||||
|
||||
const chainId = args[0] as ChainId;
|
||||
|
||||
const mnemonic = Bip39.encode(Random.getBytes(16)).toString();
|
||||
console.info(`FAUCET_MNEMONIC="${mnemonic}"`);
|
||||
|
||||
const profile = new UserProfile();
|
||||
await setSecretAndCreateIdentities(profile, mnemonic, chainId, codecName);
|
||||
await setSecretAndCreateIdentities(profile, mnemonic, chainId);
|
||||
}
|
||||
|
@ -11,12 +11,10 @@ help Shows a help text and exits
|
||||
version Prints the version and exits
|
||||
|
||||
generate Generates a random mnemonic, shows derived faucet addresses and exits
|
||||
1 Codec
|
||||
2 Chain ID
|
||||
1 Chain ID
|
||||
|
||||
start Starts the faucet
|
||||
1 Codec
|
||||
2 Node base URL, e.g. wss://bov.friendnet-fast.iov.one
|
||||
1 Node base URL, e.g. http://localhost:1317
|
||||
|
||||
Environment variables
|
||||
|
||||
|
@ -1,26 +1,20 @@
|
||||
// tslint:disable: no-object-mutation
|
||||
import { UserProfile } from "@iov/keycontrol";
|
||||
import { MultiChainSigner } from "@iov/multichain";
|
||||
import cors = require("@koa/cors");
|
||||
import Koa from "koa";
|
||||
import bodyParser from "koa-bodyparser";
|
||||
|
||||
import { creditAmount, setFractionalDigits } from "../../cashflow";
|
||||
import {
|
||||
codecDefaultFractionalDigits,
|
||||
codecFromString,
|
||||
codecImplementation,
|
||||
createChainConnector,
|
||||
} from "../../codec";
|
||||
import { codecDefaultFractionalDigits, codecImplementation, establishConnection } from "../../codec";
|
||||
import * as constants from "../../constants";
|
||||
import { logAccountsState, logSendJob } from "../../debugging";
|
||||
import {
|
||||
accountsOfFirstChain,
|
||||
availableTokensFromHolder,
|
||||
identitiesOfFirstWallet,
|
||||
refillFirstChain,
|
||||
sendOnFirstChain,
|
||||
tokenTickersOfFirstChain,
|
||||
loadAccounts,
|
||||
loadTokenTickers,
|
||||
refill,
|
||||
send,
|
||||
} from "../../multichainhelpers";
|
||||
import { setSecretAndCreateIdentities } from "../../profile";
|
||||
import { SendJob } from "../../types";
|
||||
@ -35,13 +29,13 @@ function getCount(): number {
|
||||
}
|
||||
|
||||
export async function start(args: ReadonlyArray<string>): Promise<void> {
|
||||
if (args.length < 2) {
|
||||
if (args.length < 1) {
|
||||
throw Error(
|
||||
`Not enough arguments for action 'start'. See '${constants.binaryName} help' or README for arguments.`,
|
||||
);
|
||||
}
|
||||
const codec = codecFromString(args[0]);
|
||||
const blockchainBaseUrl: string = args[1];
|
||||
|
||||
const blockchainBaseUrl = args[0];
|
||||
|
||||
const port = constants.port;
|
||||
|
||||
@ -49,34 +43,33 @@ export async function start(args: ReadonlyArray<string>): Promise<void> {
|
||||
if (!constants.mnemonic) {
|
||||
throw new Error("The FAUCET_MNEMONIC environment variable is not set");
|
||||
}
|
||||
const signer = new MultiChainSigner(profile);
|
||||
console.info(`Connecting to blockchain ${blockchainBaseUrl} ...`);
|
||||
const connection = (await signer.addChain(createChainConnector(codec, blockchainBaseUrl))).connection;
|
||||
const connection = await establishConnection(blockchainBaseUrl);
|
||||
|
||||
const connectedChainId = connection.chainId();
|
||||
console.info(`Connected to network: ${connectedChainId}`);
|
||||
|
||||
setFractionalDigits(codecDefaultFractionalDigits(codec));
|
||||
await setSecretAndCreateIdentities(profile, constants.mnemonic, connectedChainId, codec);
|
||||
setFractionalDigits(codecDefaultFractionalDigits());
|
||||
await setSecretAndCreateIdentities(profile, constants.mnemonic, connectedChainId);
|
||||
|
||||
const chainTokens = await tokenTickersOfFirstChain(signer);
|
||||
const chainTokens = await loadTokenTickers(connection);
|
||||
console.info("Chain tokens:", chainTokens);
|
||||
|
||||
const accounts = await accountsOfFirstChain(profile, signer);
|
||||
const accounts = await loadAccounts(profile, connection);
|
||||
logAccountsState(accounts);
|
||||
|
||||
let availableTokens = availableTokensFromHolder(accounts[0]);
|
||||
console.info("Available tokens:", availableTokens);
|
||||
setInterval(async () => {
|
||||
const updatedAccounts = await accountsOfFirstChain(profile, signer);
|
||||
const updatedAccounts = await loadAccounts(profile, connection);
|
||||
availableTokens = availableTokensFromHolder(updatedAccounts[0]);
|
||||
console.info("Available tokens:", availableTokens);
|
||||
}, 60_000);
|
||||
|
||||
const distibutorIdentities = identitiesOfFirstWallet(profile).slice(1);
|
||||
|
||||
await refillFirstChain(profile, signer);
|
||||
setInterval(async () => refillFirstChain(profile, signer), 60_000); // ever 60 seconds
|
||||
await refill(profile, connection);
|
||||
setInterval(async () => refill(profile, connection), 60_000); // ever 60 seconds
|
||||
|
||||
console.info("Creating webserver ...");
|
||||
const api = new Koa();
|
||||
@ -95,7 +88,7 @@ export async function start(args: ReadonlyArray<string>): Promise<void> {
|
||||
"See https://github.com/iov-one/iov-faucet for all further information.\n";
|
||||
break;
|
||||
case "/status": {
|
||||
const updatedAccounts = await accountsOfFirstChain(profile, signer);
|
||||
const updatedAccounts = await loadAccounts(profile, connection);
|
||||
context.response.body = {
|
||||
status: "ok",
|
||||
nodeUrl: blockchainBaseUrl,
|
||||
@ -120,7 +113,7 @@ export async function start(args: ReadonlyArray<string>): Promise<void> {
|
||||
const requestBody = (context.request as any).body;
|
||||
const { address, ticker } = RequestParser.parseCreditBody(requestBody);
|
||||
|
||||
if (!codecImplementation(codec).isValidAddress(address)) {
|
||||
if (!codecImplementation().isValidAddress(address)) {
|
||||
throw new HttpError(400, "Address is not in the expected format for this chain.");
|
||||
}
|
||||
|
||||
@ -138,8 +131,8 @@ export async function start(args: ReadonlyArray<string>): Promise<void> {
|
||||
amount: creditAmount(ticker),
|
||||
tokenTicker: ticker,
|
||||
};
|
||||
logSendJob(signer, job);
|
||||
await sendOnFirstChain(profile, signer, job);
|
||||
logSendJob(job);
|
||||
await send(profile, connection, job);
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
throw new HttpError(500, "Sending tokens failed");
|
||||
|
@ -1,14 +1 @@
|
||||
import { Codec, codecFromString } from "./codec";
|
||||
|
||||
describe("Codec", () => {
|
||||
it("can convert string to codec", () => {
|
||||
expect(codecFromString("lisk")).toEqual(Codec.Lisk);
|
||||
expect(codecFromString("cosmwasm")).toEqual(Codec.CosmWasm);
|
||||
|
||||
expect(() => codecFromString("")).toThrowError(/not supported/i);
|
||||
expect(() => codecFromString("bns")).toThrowError(/not supported/i);
|
||||
expect(() => codecFromString("abc")).toThrowError(/not supported/i);
|
||||
expect(() => codecFromString("LISK")).toThrowError(/not supported/i);
|
||||
expect(() => codecFromString("CosmWasm")).toThrowError(/not supported/i);
|
||||
});
|
||||
});
|
||||
describe("codec", () => {});
|
||||
|
@ -1,44 +1,7 @@
|
||||
import { createCosmWasmConnector, TokenInfo } from "@cosmwasm/bcp";
|
||||
import { ChainConnector, TokenTicker, TxCodec } from "@iov/bcp";
|
||||
import { Slip10RawIndex } from "@iov/crypto";
|
||||
import { HdPaths } from "@iov/keycontrol";
|
||||
import { createLiskConnector } from "@iov/lisk";
|
||||
import { CosmWasmCodec, CosmWasmConnection, TokenInfo } from "@cosmwasm/bcp";
|
||||
import { TokenTicker, TxCodec } from "@iov/bcp";
|
||||
|
||||
export const enum Codec {
|
||||
Lisk,
|
||||
CosmWasm,
|
||||
}
|
||||
|
||||
export function codecFromString(input: string): Codec {
|
||||
switch (input) {
|
||||
case "lisk":
|
||||
return Codec.Lisk;
|
||||
case "cosmwasm":
|
||||
return Codec.CosmWasm;
|
||||
default:
|
||||
throw new Error(`Codec '${input}' not supported`);
|
||||
}
|
||||
}
|
||||
|
||||
export function createPathBuilderForCodec(codec: Codec): (derivation: number) => readonly Slip10RawIndex[] {
|
||||
const pathBuilder = (accountIndex: number): readonly Slip10RawIndex[] => {
|
||||
switch (codec) {
|
||||
case Codec.Lisk:
|
||||
return HdPaths.bip44Like(134, accountIndex);
|
||||
case Codec.CosmWasm:
|
||||
return HdPaths.cosmos(accountIndex);
|
||||
default:
|
||||
throw new Error("No path builder for this codec found");
|
||||
}
|
||||
};
|
||||
return pathBuilder;
|
||||
}
|
||||
|
||||
export function createChainConnector(codec: Codec, url: string): ChainConnector {
|
||||
switch (codec) {
|
||||
case Codec.Lisk:
|
||||
return createLiskConnector(url);
|
||||
case Codec.CosmWasm: {
|
||||
const prefix = "cosmos";
|
||||
const tokens: readonly TokenInfo[] = [
|
||||
{
|
||||
fractionalDigits: 6,
|
||||
@ -53,24 +16,15 @@ export function createChainConnector(codec: Codec, url: string): ChainConnector
|
||||
denom: "stake",
|
||||
},
|
||||
];
|
||||
return createCosmWasmConnector(url, "cosmos", tokens);
|
||||
}
|
||||
default:
|
||||
throw new Error("No connector for this codec found");
|
||||
}
|
||||
|
||||
export async function establishConnection(url: string): Promise<CosmWasmConnection> {
|
||||
return CosmWasmConnection.establish(url, prefix, tokens);
|
||||
}
|
||||
|
||||
export function codecImplementation(codec: Codec): TxCodec {
|
||||
return createChainConnector(codec, "unused dummy url").codec;
|
||||
export function codecImplementation(): TxCodec {
|
||||
return new CosmWasmCodec(prefix, tokens);
|
||||
}
|
||||
|
||||
export function codecDefaultFractionalDigits(codec: Codec): number {
|
||||
switch (codec) {
|
||||
case Codec.Lisk:
|
||||
return 8;
|
||||
case Codec.CosmWasm:
|
||||
export function codecDefaultFractionalDigits(): number {
|
||||
return 6;
|
||||
default:
|
||||
throw new Error("Unknown codec");
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +0,0 @@
|
||||
import { Ed25519HdWallet, Secp256k1HdWallet, Wallet } from "@iov/keycontrol";
|
||||
|
||||
import { Codec } from "./codec";
|
||||
|
||||
export function createWalletForCodec(input: Codec, mnemonic: string): Wallet {
|
||||
switch (input) {
|
||||
case Codec.Lisk:
|
||||
return Ed25519HdWallet.fromMnemonic(mnemonic);
|
||||
case Codec.CosmWasm:
|
||||
return Secp256k1HdWallet.fromMnemonic(mnemonic);
|
||||
default:
|
||||
throw new Error(`Codec '${input}' not supported`);
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
import { Account, Amount } from "@iov/bcp";
|
||||
import { Decimal } from "@iov/encoding";
|
||||
import { MultiChainSigner } from "@iov/multichain";
|
||||
|
||||
import { codecImplementation } from "./codec";
|
||||
import { SendJob } from "./types";
|
||||
|
||||
/** A string representation of a coin in a human-readable format that can change at any time */
|
||||
@ -30,8 +30,8 @@ export function logAccountsState(accounts: ReadonlyArray<Account>): void {
|
||||
console.info("Distributors:\n" + distributors.map(r => ` ${debugAccount(r)}`).join("\n"));
|
||||
}
|
||||
|
||||
export function logSendJob(signer: MultiChainSigner, job: SendJob): void {
|
||||
const from = signer.identityToAddress(job.sender);
|
||||
export function logSendJob(job: SendJob): void {
|
||||
const from = codecImplementation().identityToAddress(job.sender);
|
||||
const to = job.recipient;
|
||||
const amount = debugAmount(job.amount);
|
||||
console.info(`Sending ${amount} from ${from} to ${to} ...`);
|
||||
|
@ -1,5 +1,6 @@
|
||||
import {
|
||||
Account,
|
||||
BlockchainConnection,
|
||||
Identity,
|
||||
isBlockInfoFailed,
|
||||
isBlockInfoPending,
|
||||
@ -7,9 +8,9 @@ import {
|
||||
TokenTicker,
|
||||
} from "@iov/bcp";
|
||||
import { UserProfile } from "@iov/keycontrol";
|
||||
import { MultiChainSigner } from "@iov/multichain";
|
||||
|
||||
import { needsRefill, refillAmount } from "./cashflow";
|
||||
import { codecImplementation } from "./codec";
|
||||
import { debugAccount, logAccountsState, logSendJob } from "./debugging";
|
||||
import { SendJob } from "./types";
|
||||
|
||||
@ -22,17 +23,17 @@ export function identitiesOfFirstWallet(profile: UserProfile): ReadonlyArray<Ide
|
||||
return profile.getIdentities(wallet.id);
|
||||
}
|
||||
|
||||
export async function accountsOfFirstChain(
|
||||
export async function loadAccounts(
|
||||
profile: UserProfile,
|
||||
signer: MultiChainSigner,
|
||||
connection: BlockchainConnection,
|
||||
): Promise<ReadonlyArray<Account>> {
|
||||
const addresses = identitiesOfFirstWallet(profile).map(identity => signer.identityToAddress(identity));
|
||||
const chainId = signer.chainIds()[0];
|
||||
const codec = codecImplementation();
|
||||
const addresses = identitiesOfFirstWallet(profile).map(identity => codec.identityToAddress(identity));
|
||||
|
||||
// tslint:disable-next-line: readonly-array
|
||||
const out: Account[] = [];
|
||||
for (const address of addresses) {
|
||||
const response = await signer.connection(chainId).getAccount({ address: address });
|
||||
const response = await connection.getAccount({ address: address });
|
||||
if (response) {
|
||||
out.push({
|
||||
address: response.address,
|
||||
@ -49,35 +50,36 @@ export async function accountsOfFirstChain(
|
||||
return out;
|
||||
}
|
||||
|
||||
export async function tokenTickersOfFirstChain(
|
||||
signer: MultiChainSigner,
|
||||
export async function loadTokenTickers(
|
||||
connection: BlockchainConnection,
|
||||
): Promise<ReadonlyArray<TokenTicker>> {
|
||||
const chainId = signer.chainIds()[0];
|
||||
return (await signer.connection(chainId).getAllTokens()).map(token => token.tokenTicker);
|
||||
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 sendOnFirstChain(
|
||||
export async function send(
|
||||
profile: UserProfile,
|
||||
signer: MultiChainSigner,
|
||||
connection: BlockchainConnection,
|
||||
job: SendJob,
|
||||
): Promise<void> {
|
||||
const chainId = signer.chainIds()[0];
|
||||
const connection = signer.connection(chainId);
|
||||
const codec = codecImplementation();
|
||||
|
||||
const sendWithFee = await connection.withDefaultFee<SendTransaction>({
|
||||
kind: "bcp/send",
|
||||
chainId: chainId,
|
||||
sender: signer.identityToAddress(job.sender),
|
||||
chainId: connection.chainId(),
|
||||
sender: codec.identityToAddress(job.sender),
|
||||
senderPubkey: job.sender.pubkey,
|
||||
recipient: job.recipient,
|
||||
memo: "We ❤️ developers – iov.one",
|
||||
amount: job.amount,
|
||||
});
|
||||
|
||||
const post = await signer.signAndPost(job.sender, sendWithFee);
|
||||
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}`);
|
||||
@ -88,15 +90,13 @@ export function availableTokensFromHolder(holderAccount: Account): ReadonlyArray
|
||||
return holderAccount.balance.map(coin => coin.tokenTicker);
|
||||
}
|
||||
|
||||
export async function refillFirstChain(profile: UserProfile, signer: MultiChainSigner): Promise<void> {
|
||||
const chainId = signer.chainIds()[0];
|
||||
|
||||
console.info(`Connected to network: ${chainId}`);
|
||||
console.info(`Tokens on network: ${(await tokenTickersOfFirstChain(signer)).join(", ")}`);
|
||||
export async function refill(profile: UserProfile, connection: BlockchainConnection): Promise<void> {
|
||||
console.info(`Connected to network: ${connection.chainId()}`);
|
||||
console.info(`Tokens on network: ${(await loadTokenTickers(connection)).join(", ")}`);
|
||||
|
||||
const holderIdentity = identitiesOfFirstWallet(profile)[0];
|
||||
|
||||
const accounts = await accountsOfFirstChain(profile, signer);
|
||||
const accounts = await loadAccounts(profile, connection);
|
||||
logAccountsState(accounts);
|
||||
const holderAccount = accounts[0];
|
||||
const distributorAccounts = accounts.slice(1);
|
||||
@ -124,13 +124,13 @@ export async function refillFirstChain(profile: UserProfile, signer: MultiChainS
|
||||
}
|
||||
if (jobs.length > 0) {
|
||||
for (const job of jobs) {
|
||||
logSendJob(signer, job);
|
||||
await sendOnFirstChain(profile, signer, job);
|
||||
logSendJob(job);
|
||||
await send(profile, connection, job);
|
||||
await sleep(50);
|
||||
}
|
||||
|
||||
console.info("Done refilling accounts.");
|
||||
logAccountsState(await accountsOfFirstChain(profile, signer));
|
||||
logAccountsState(await loadAccounts(profile, connection));
|
||||
} else {
|
||||
console.info("Nothing to be done. Anyways, thanks for checking.");
|
||||
}
|
||||
|
@ -1,34 +1,30 @@
|
||||
import { ChainId } from "@iov/bcp";
|
||||
import { UserProfile } from "@iov/keycontrol";
|
||||
import { HdPaths, Secp256k1HdWallet, UserProfile } from "@iov/keycontrol";
|
||||
|
||||
import { Codec, codecImplementation, createPathBuilderForCodec } from "./codec";
|
||||
import { codecImplementation } from "./codec";
|
||||
import * as constants from "./constants";
|
||||
import { createWalletForCodec } from "./crypto";
|
||||
import { debugPath } from "./hdpaths";
|
||||
|
||||
export async function setSecretAndCreateIdentities(
|
||||
profile: UserProfile,
|
||||
mnemonic: string,
|
||||
chainId: ChainId,
|
||||
codecName: Codec,
|
||||
): Promise<void> {
|
||||
if (profile.wallets.value.length !== 0) {
|
||||
throw new Error("Profile already contains wallets");
|
||||
}
|
||||
const wallet = profile.addWallet(createWalletForCodec(codecName, mnemonic));
|
||||
|
||||
const pathBuilder = createPathBuilderForCodec(codecName);
|
||||
const wallet = profile.addWallet(Secp256k1HdWallet.fromMnemonic(mnemonic));
|
||||
|
||||
// first account is the token holder
|
||||
const numberOfIdentities = 1 + constants.concurrency;
|
||||
for (let i = 0; i < numberOfIdentities; i++) {
|
||||
// create
|
||||
const path = pathBuilder(i);
|
||||
const path = HdPaths.cosmos(i);
|
||||
const identity = await profile.createIdentity(wallet.id, chainId, path);
|
||||
|
||||
// log
|
||||
const role = i === 0 ? "token holder " : `distributor ${i}`;
|
||||
const address = codecImplementation(codecName).identityToAddress(identity);
|
||||
const address = codecImplementation().identityToAddress(identity);
|
||||
console.info(`Created ${role} (${debugPath(path)}): ${address}`);
|
||||
}
|
||||
}
|
||||
|
43
yarn.lock
43
yarn.lock
@ -130,15 +130,6 @@
|
||||
bn.js "^4.11.8"
|
||||
readonly-date "^1.0.0"
|
||||
|
||||
"@iov/jsonrpc@^2.0.0-alpha.7":
|
||||
version "2.0.0-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/@iov/jsonrpc/-/jsonrpc-2.0.0-alpha.7.tgz#7bff8e1f21d52ff07482212ded8cc00e01dda964"
|
||||
integrity sha512-eVCfNi3Zg4ZUEXOxhzRb3kcoBupBGQWmU4pYu7OYBi3uvuUz8KP6kcIdsy+51+y/nqrnk3H2Ur7MWCzwsu215w==
|
||||
dependencies:
|
||||
"@iov/encoding" "^2.0.0-alpha.7"
|
||||
"@iov/stream" "^2.0.0-alpha.7"
|
||||
xstream "^11.10.0"
|
||||
|
||||
"@iov/keycontrol@^2.0.0-alpha.7":
|
||||
version "2.0.0-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/@iov/keycontrol/-/keycontrol-2.0.0-alpha.7.tgz#d115a1b536664afb64b40a6db87aaf19f8d07afd"
|
||||
@ -159,35 +150,6 @@
|
||||
type-tagger "^1.0.0"
|
||||
xstream "^11.10.0"
|
||||
|
||||
"@iov/lisk@^2.0.0-alpha.7":
|
||||
version "2.0.0-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/@iov/lisk/-/lisk-2.0.0-alpha.7.tgz#5ff6c617ac00e6be736ada34ad68dce0efd64637"
|
||||
integrity sha512-m5mr2NDU7pxuS8d6SBXCZ1WBtCSXtV+EWqMEIuPSCJwZxnwmWotowX+WhSYn+dGyuvgTd7DpfQ5C6pliAyhcyQ==
|
||||
dependencies:
|
||||
"@iov/bcp" "^2.0.0-alpha.7"
|
||||
"@iov/crypto" "^2.0.0-alpha.7"
|
||||
"@iov/encoding" "^2.0.0-alpha.7"
|
||||
"@iov/keycontrol" "^2.0.0-alpha.7"
|
||||
"@iov/stream" "^2.0.0-alpha.7"
|
||||
"@types/long" "^4.0.0"
|
||||
axios "^0.19.0"
|
||||
fast-deep-equal "^3.1.1"
|
||||
long "^4.0.0"
|
||||
readonly-date "^1.0.0"
|
||||
xstream "^11.10.0"
|
||||
|
||||
"@iov/multichain@^2.0.0-alpha.7":
|
||||
version "2.0.0-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/@iov/multichain/-/multichain-2.0.0-alpha.7.tgz#29ec9f61ec2fa60c17d462c9be48feb7196c28ba"
|
||||
integrity sha512-hhEyqalADrQa4JS99JqawM7jWLYGqb52Ipq/49Zz5eDG9/nj9QyLn5nayWLTbm60ZXzHvvGr5oJpZx8Xb2PzfA==
|
||||
dependencies:
|
||||
"@iov/bcp" "^2.0.0-alpha.7"
|
||||
"@iov/encoding" "^2.0.0-alpha.7"
|
||||
"@iov/jsonrpc" "^2.0.0-alpha.7"
|
||||
"@iov/keycontrol" "^2.0.0-alpha.7"
|
||||
"@types/long" "^4.0.0"
|
||||
long "^4.0.0"
|
||||
|
||||
"@iov/stream@^2.0.0-alpha.7":
|
||||
version "2.0.0-alpha.7"
|
||||
resolved "https://registry.yarnpkg.com/@iov/stream/-/stream-2.0.0-alpha.7.tgz#212c3f684f592ec04ac43e166183d946a49b895c"
|
||||
@ -1124,11 +1086,6 @@
|
||||
"@types/abstract-leveldown" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/long@^4.0.0":
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9"
|
||||
integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==
|
||||
|
||||
"@types/memdown@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/memdown/-/memdown-3.0.0.tgz#2d909cb507afd341e3132d77dafa213347e47455"
|
||||
|
Loading…
x
Reference in New Issue
Block a user