Add support for CosmWasm in faucet

This commit is contained in:
Simon Warta 2020-01-29 14:37:55 +01:00
parent f01c48b7e1
commit bf22ee313f
6 changed files with 142 additions and 20 deletions

99
packages/faucet/README.md Normal file
View File

@ -0,0 +1,99 @@
# @cosmwasm/faucet
The faucet is built as part of the monorepo. In the repo root do:
```
yarn install
yarn build
```
Then start it for a Wasmd development blockchain using:
```
cd packages/faucet
yarn dev-start
```
Advanced users that want to provide their custom config can start as follows:
```
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/cosm-faucet start cosmwasm "http://localhost:1317"
```
## Usage
```
sage: cosmwasm-faucet action [arguments...]
Positional arguments per action are listed below. Arguments in parentheses are optional.
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
start Starts the faucet
1 Codec
2 Node base URL, e.g. wss://bov.friendnet-fast.iov.one
Environment variables
FAUCET_CONCURRENCY Number of distributor accounts. Defaults to 5.
FAUCET_PORT Port of the webserver. Defaults to 8000.
FAUCET_MNEMONIC Secret mnemonic that serves as the base secret for the
faucet HD accounts
FAUCET_CREDIT_AMOUNT_TKN Send this amount of TKN to a user requesting TKN. TKN is
a placeholder for the token ticker. Defaults to 10.
FAUCET_REFILL_FACTOR Send factor times credit amount on refilling. Defauls to 8.
FAUCET_REFILL_THRESHOLD Refill when balance gets below factor times credit amount.
Defaults to 20.
```
### Faucet HD wallet
The faucet uses standard HD paths for each blockchain, e.g.
```
IOV m/44'/234'/a'
Lisk m/44'/134'/a'
Ethereum m/44'/60'/0'/0/a
CosmWasm m/44'/118'/0'/0/a
```
where `a` is a 0-based index of the account. Account 0 is the token holder and
account 1...FAUCET_CONCURRENCY are the distributor accounts.
This means the token holder account can be accessed using the Neuma wallet when
the same mnemonic is used. Accessing the distributor accounts will be possible
as soon as there is
[multi account support](https://github.com/iov-one/ponferrada/milestone/3).
### Using the faucet
Now that the faucet has been started up, you can send credit requests to it.
This can be done with a simple http POST request. These commands assume the
faucet is running locally, be sure to change it from `localhost` if your
situation is different.
```
curl --header "Content-Type: application/json" \
--request POST \
--data '{"ticker":"CASH","address":"tiov1k898u78hgs36uqw68dg7va5nfkgstu5z0fhz3f"}' \
http://localhost:8000/credit
```
### Checking the faucets status
The faucet provides a simple status check in the form of an http GET request. As
above, make sure to adjust the URL as necessary.
```
curl http://localhost:8000/status
```

View File

@ -21,6 +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/cosm-faucet start cosmwasm \"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 .",
@ -31,6 +32,7 @@
"test": "yarn build-or-skip && yarn test-node"
},
"dependencies": {
"@cosmwasm/bcp": "^0.0.1",
"@iov/bcp": "^2.0.0-alpha.7",
"@iov/bns": "^2.0.0-alpha.7",
"@iov/crypto": "^2.0.0-alpha.7",

View File

@ -1,6 +1,8 @@
const binaryName = "cosmwasm-faucet";
export function help(): void {
const out = `
Usage: iov-faucet action [arguments...]
Usage: ${binaryName} action [arguments...]
Positional arguments per action are listed below. Arguments in parentheses are optional.

View File

@ -66,6 +66,7 @@ export function gasPrice(codec: Codec): Amount | undefined {
switch (codec) {
case Codec.Bns:
case Codec.Lisk:
case Codec.CosmWasm:
return undefined;
case Codec.Ethereum:
return {
@ -74,7 +75,7 @@ export function gasPrice(codec: Codec): Amount | undefined {
tokenTicker: "ETH" as TokenTicker,
};
default:
throw new Error("No codec imlementation for this codec found");
throw new Error("No gasPrice imlementation found for this codec");
}
}
@ -82,6 +83,7 @@ export function gasLimit(codec: Codec): Amount | undefined {
switch (codec) {
case Codec.Bns:
case Codec.Lisk:
case Codec.CosmWasm:
return undefined;
case Codec.Ethereum:
return {
@ -90,6 +92,6 @@ export function gasLimit(codec: Codec): Amount | undefined {
tokenTicker: "ETH" as TokenTicker,
};
default:
throw new Error("Codec not supported");
throw new Error("No gasLimit imlementation found for this codec");
}
}

View File

@ -1,14 +1,16 @@
import { ChainConnector, TxCodec } from "@iov/bcp";
import { bnsCodec, createBnsConnector } from "@iov/bns";
import { createCosmWasmConnector, TokenInfo } from "@cosmwasm/bcp";
import { ChainConnector, TokenTicker, TxCodec } from "@iov/bcp";
import { createBnsConnector } from "@iov/bns";
import { Slip10RawIndex } from "@iov/crypto";
import { createEthereumConnector, ethereumCodec } from "@iov/ethereum";
import { createEthereumConnector } from "@iov/ethereum";
import { HdPaths } from "@iov/keycontrol";
import { createLiskConnector, liskCodec } from "@iov/lisk";
import { createLiskConnector } from "@iov/lisk";
export const enum Codec {
Bns,
Lisk,
Ethereum,
CosmWasm,
}
export function codecFromString(input: string): Codec {
@ -19,24 +21,13 @@ export function codecFromString(input: string): Codec {
return Codec.Lisk;
case "ethereum":
return Codec.Ethereum;
case "cosmwasm":
return Codec.CosmWasm;
default:
throw new Error(`Codec '${input}' not supported`);
}
}
export function codecImplementation(codec: Codec): TxCodec {
switch (codec) {
case Codec.Bns:
return bnsCodec;
case Codec.Lisk:
return liskCodec;
case Codec.Ethereum:
return ethereumCodec;
default:
throw new Error("No codec implementation for this codec found");
}
}
export function createPathBuilderForCodec(codec: Codec): (derivation: number) => readonly Slip10RawIndex[] {
const pathBuilder = (accountIndex: number): readonly Slip10RawIndex[] => {
switch (codec) {
@ -46,6 +37,8 @@ export function createPathBuilderForCodec(codec: Codec): (derivation: number) =>
return HdPaths.bip44Like(134, accountIndex);
case Codec.Ethereum:
return HdPaths.ethereum(accountIndex);
case Codec.CosmWasm:
return HdPaths.cosmos(accountIndex);
default:
throw new Error("No path builder for this codec found");
}
@ -61,11 +54,32 @@ export function createChainConnector(codec: Codec, url: string): ChainConnector
return createLiskConnector(url);
case Codec.Ethereum:
return createEthereumConnector(url, {});
case Codec.CosmWasm: {
const tokens: readonly TokenInfo[] = [
{
fractionalDigits: 6,
tokenName: "Fee Token",
tokenTicker: "COSM" as TokenTicker,
denom: "cosm",
},
{
fractionalDigits: 6,
tokenName: "Staking Token",
tokenTicker: "STAKE" as TokenTicker,
denom: "stake",
},
];
return createCosmWasmConnector(url, "cosmos", tokens);
}
default:
throw new Error("No connector for this codec found");
}
}
export function codecImplementation(codec: Codec): TxCodec {
return createChainConnector(codec, "unused dummy url").codec;
}
export function codecDefaultFractionalDigits(codec: Codec): number {
switch (codec) {
case Codec.Bns:
@ -74,6 +88,8 @@ export function codecDefaultFractionalDigits(codec: Codec): number {
return 8;
case Codec.Ethereum:
return 18;
case Codec.CosmWasm:
return 6;
default:
throw new Error("Unknown codec");
}

View File

@ -8,6 +8,7 @@ export function createWalletForCodec(input: Codec, mnemonic: string): Wallet {
case Codec.Lisk:
return Ed25519HdWallet.fromMnemonic(mnemonic);
case Codec.Ethereum:
case Codec.CosmWasm:
return Secp256k1HdWallet.fromMnemonic(mnemonic);
default:
throw new Error(`Codec '${input}' not supported`);