mirror of
https://github.com/cosmos/cosmjs.git
synced 2025-03-11 14:09:15 +00:00
Add support for CosmWasm in faucet
This commit is contained in:
parent
f01c48b7e1
commit
bf22ee313f
99
packages/faucet/README.md
Normal file
99
packages/faucet/README.md
Normal 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
|
||||||
|
```
|
@ -21,6 +21,7 @@
|
|||||||
"access": "public"
|
"access": "public"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"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",
|
"docs": "shx rm -rf docs && typedoc --options typedoc.js",
|
||||||
"format": "prettier --write --loglevel warn \"./src/**/*.ts\"",
|
"format": "prettier --write --loglevel warn \"./src/**/*.ts\"",
|
||||||
"lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && tslint -t verbose --project .",
|
"lint": "eslint --max-warnings 0 \"**/*.{js,ts}\" && tslint -t verbose --project .",
|
||||||
@ -31,6 +32,7 @@
|
|||||||
"test": "yarn build-or-skip && yarn test-node"
|
"test": "yarn build-or-skip && yarn test-node"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@cosmwasm/bcp": "^0.0.1",
|
||||||
"@iov/bcp": "^2.0.0-alpha.7",
|
"@iov/bcp": "^2.0.0-alpha.7",
|
||||||
"@iov/bns": "^2.0.0-alpha.7",
|
"@iov/bns": "^2.0.0-alpha.7",
|
||||||
"@iov/crypto": "^2.0.0-alpha.7",
|
"@iov/crypto": "^2.0.0-alpha.7",
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
|
const binaryName = "cosmwasm-faucet";
|
||||||
|
|
||||||
export function help(): void {
|
export function help(): void {
|
||||||
const out = `
|
const out = `
|
||||||
Usage: iov-faucet action [arguments...]
|
Usage: ${binaryName} action [arguments...]
|
||||||
|
|
||||||
Positional arguments per action are listed below. Arguments in parentheses are optional.
|
Positional arguments per action are listed below. Arguments in parentheses are optional.
|
||||||
|
|
||||||
|
@ -66,6 +66,7 @@ export function gasPrice(codec: Codec): Amount | undefined {
|
|||||||
switch (codec) {
|
switch (codec) {
|
||||||
case Codec.Bns:
|
case Codec.Bns:
|
||||||
case Codec.Lisk:
|
case Codec.Lisk:
|
||||||
|
case Codec.CosmWasm:
|
||||||
return undefined;
|
return undefined;
|
||||||
case Codec.Ethereum:
|
case Codec.Ethereum:
|
||||||
return {
|
return {
|
||||||
@ -74,7 +75,7 @@ export function gasPrice(codec: Codec): Amount | undefined {
|
|||||||
tokenTicker: "ETH" as TokenTicker,
|
tokenTicker: "ETH" as TokenTicker,
|
||||||
};
|
};
|
||||||
default:
|
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) {
|
switch (codec) {
|
||||||
case Codec.Bns:
|
case Codec.Bns:
|
||||||
case Codec.Lisk:
|
case Codec.Lisk:
|
||||||
|
case Codec.CosmWasm:
|
||||||
return undefined;
|
return undefined;
|
||||||
case Codec.Ethereum:
|
case Codec.Ethereum:
|
||||||
return {
|
return {
|
||||||
@ -90,6 +92,6 @@ export function gasLimit(codec: Codec): Amount | undefined {
|
|||||||
tokenTicker: "ETH" as TokenTicker,
|
tokenTicker: "ETH" as TokenTicker,
|
||||||
};
|
};
|
||||||
default:
|
default:
|
||||||
throw new Error("Codec not supported");
|
throw new Error("No gasLimit imlementation found for this codec");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,16 @@
|
|||||||
import { ChainConnector, TxCodec } from "@iov/bcp";
|
import { createCosmWasmConnector, TokenInfo } from "@cosmwasm/bcp";
|
||||||
import { bnsCodec, createBnsConnector } from "@iov/bns";
|
import { ChainConnector, TokenTicker, TxCodec } from "@iov/bcp";
|
||||||
|
import { createBnsConnector } from "@iov/bns";
|
||||||
import { Slip10RawIndex } from "@iov/crypto";
|
import { Slip10RawIndex } from "@iov/crypto";
|
||||||
import { createEthereumConnector, ethereumCodec } from "@iov/ethereum";
|
import { createEthereumConnector } from "@iov/ethereum";
|
||||||
import { HdPaths } from "@iov/keycontrol";
|
import { HdPaths } from "@iov/keycontrol";
|
||||||
import { createLiskConnector, liskCodec } from "@iov/lisk";
|
import { createLiskConnector } from "@iov/lisk";
|
||||||
|
|
||||||
export const enum Codec {
|
export const enum Codec {
|
||||||
Bns,
|
Bns,
|
||||||
Lisk,
|
Lisk,
|
||||||
Ethereum,
|
Ethereum,
|
||||||
|
CosmWasm,
|
||||||
}
|
}
|
||||||
|
|
||||||
export function codecFromString(input: string): Codec {
|
export function codecFromString(input: string): Codec {
|
||||||
@ -19,24 +21,13 @@ export function codecFromString(input: string): Codec {
|
|||||||
return Codec.Lisk;
|
return Codec.Lisk;
|
||||||
case "ethereum":
|
case "ethereum":
|
||||||
return Codec.Ethereum;
|
return Codec.Ethereum;
|
||||||
|
case "cosmwasm":
|
||||||
|
return Codec.CosmWasm;
|
||||||
default:
|
default:
|
||||||
throw new Error(`Codec '${input}' not supported`);
|
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[] {
|
export function createPathBuilderForCodec(codec: Codec): (derivation: number) => readonly Slip10RawIndex[] {
|
||||||
const pathBuilder = (accountIndex: number): readonly Slip10RawIndex[] => {
|
const pathBuilder = (accountIndex: number): readonly Slip10RawIndex[] => {
|
||||||
switch (codec) {
|
switch (codec) {
|
||||||
@ -46,6 +37,8 @@ export function createPathBuilderForCodec(codec: Codec): (derivation: number) =>
|
|||||||
return HdPaths.bip44Like(134, accountIndex);
|
return HdPaths.bip44Like(134, accountIndex);
|
||||||
case Codec.Ethereum:
|
case Codec.Ethereum:
|
||||||
return HdPaths.ethereum(accountIndex);
|
return HdPaths.ethereum(accountIndex);
|
||||||
|
case Codec.CosmWasm:
|
||||||
|
return HdPaths.cosmos(accountIndex);
|
||||||
default:
|
default:
|
||||||
throw new Error("No path builder for this codec found");
|
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);
|
return createLiskConnector(url);
|
||||||
case Codec.Ethereum:
|
case Codec.Ethereum:
|
||||||
return createEthereumConnector(url, {});
|
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:
|
default:
|
||||||
throw new Error("No connector for this codec found");
|
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 {
|
export function codecDefaultFractionalDigits(codec: Codec): number {
|
||||||
switch (codec) {
|
switch (codec) {
|
||||||
case Codec.Bns:
|
case Codec.Bns:
|
||||||
@ -74,6 +88,8 @@ export function codecDefaultFractionalDigits(codec: Codec): number {
|
|||||||
return 8;
|
return 8;
|
||||||
case Codec.Ethereum:
|
case Codec.Ethereum:
|
||||||
return 18;
|
return 18;
|
||||||
|
case Codec.CosmWasm:
|
||||||
|
return 6;
|
||||||
default:
|
default:
|
||||||
throw new Error("Unknown codec");
|
throw new Error("Unknown codec");
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ export function createWalletForCodec(input: Codec, mnemonic: string): Wallet {
|
|||||||
case Codec.Lisk:
|
case Codec.Lisk:
|
||||||
return Ed25519HdWallet.fromMnemonic(mnemonic);
|
return Ed25519HdWallet.fromMnemonic(mnemonic);
|
||||||
case Codec.Ethereum:
|
case Codec.Ethereum:
|
||||||
|
case Codec.CosmWasm:
|
||||||
return Secp256k1HdWallet.fromMnemonic(mnemonic);
|
return Secp256k1HdWallet.fromMnemonic(mnemonic);
|
||||||
default:
|
default:
|
||||||
throw new Error(`Codec '${input}' not supported`);
|
throw new Error(`Codec '${input}' not supported`);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user