├── package.json ├── config.json ├── README.md └── app.js /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cosmos-faucet", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "app.js", 6 | "type": "module", 7 | "scripts": { 8 | "test": "echo \"Error: no test specified\" && exit 1" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "dependencies": { 14 | "@cosmostation/cosmosjs": "^0.10", 15 | "express": "^4.17.1" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "mnemonic":"one flight badge two kiwi adapt snap arrest make blast three wet...", 3 | "chainId":"bitcanna-testnet-1", 4 | "lcdUrl":"https://cosmos-testnet.bitcanna.io", 5 | "denom":"ubcna", 6 | "prefix":"bcna", 7 | "feeAmount":5000, 8 | "AmountSend":1000000, 9 | "memo":"Sent using Cosmostation-CosmoJS ;-)", 10 | "lport":8000, 11 | "gasLimit":200000 12 | 13 | } 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |
4 |10 | ⭐ Cosmos-faucet is a simple alternative to the tendermint/faucet script. This is an idea adapted for ➡️ Bitcanna and can be used for any project using cosmos. 11 | 12 |
13 | 14 | 15 | ## Prerequisites 16 | 17 | node version >=14.0.0 18 | 19 | ## Installation 20 | 21 | ```sh 22 | git clone https://github.com/BitCannaCommunity/cosmos-faucet.git 23 | cd cosmos-faucet 24 | npm install 25 | ``` 26 | ## Config 27 | ```sh 28 | nano config.json 29 | ``` 30 | Edit this part with your value: 31 | ``` 32 | { 33 | "mnemonic":"one flight badge two kiwi adapt snap arrest make blast three wet...", 34 | "chainId":"bitcanna-testnet-1", 35 | "lcdUrl":"https://cosmos-testnet.bitcanna.io", 36 | "denom":"ubcna", 37 | "prefix":"bcna", 38 | "feeAmount":5000, 39 | "AmountSend":1000000, 40 | "memo":"Sent using Cosmostation-CosmoJS ;-)", 41 | "lport":8000, 42 | "gasLimit":200000 43 | 44 | } 45 | ``` 46 | ## Run it (server side) 47 | ``` 48 | node --experimental-modules --es-module-specifier-resolution=node app.js 49 | ``` 50 | ## Client request 51 | ``` 52 | curl -s "http://testnet-faucet.bitcanna.io:8000/?address=bcna1xvuxv4znmmeu96ulxhldvyt32whp57vhyzg5vh" | jq 53 | ``` 54 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | /************************************/ 2 | /* Dev by atmon3r for Bitcanna Team */ 3 | /* Run: node --experimental-modules --es-module-specifier-resolution=node app.js */ 4 | /************************************/ 5 | 6 | import fs from 'fs'; 7 | import express from 'express'; 8 | import bodyParser from 'body-parser'; 9 | import { Cosmos } from "@cosmostation/cosmosjs"; 10 | import message from "@cosmostation/cosmosjs/src/messages/proto.js"; 11 | 12 | let rawdata = fs.readFileSync('config.json'); 13 | let config = JSON.parse(rawdata); 14 | 15 | // Cosmos config 16 | const mnemonic = config.mnemonic; 17 | const chainId = config.chainId; 18 | const lcdUrl = config.lcdUrl; 19 | const denom = config.denom; 20 | const cosmos = new Cosmos(lcdUrl, chainId); 21 | cosmos.setBech32MainPrefix(config.prefix); 22 | cosmos.setPath("m/44'/118'/0'/0/0"); 23 | const address = cosmos.getAddress(mnemonic); 24 | const privKey = cosmos.getECPairPriv(mnemonic); 25 | const pubKeyAny = cosmos.getPubKeyAny(privKey); 26 | 27 | // Express config 28 | const app = express() 29 | app.use(bodyParser.urlencoded({ extended: false })); 30 | 31 | function sendTx(addressTo,res) { 32 | cosmos.getAccounts(address).then(data => { 33 | // signDoc = (1)txBody + (2)authInfo 34 | // ---------------------------------- (1)txBody ---------------------------------- 35 | const msgSend = new message.cosmos.bank.v1beta1.MsgSend({ 36 | from_address: address, 37 | to_address: addressTo, 38 | amount: [{ denom: denom, amount: String(config.AmountSend) }] // 7 decimal places (1000000 ubcna = 1 BCNA) 39 | }); 40 | 41 | const msgSendAny = new message.google.protobuf.Any({ 42 | type_url: "/cosmos.bank.v1beta1.MsgSend", 43 | value: message.cosmos.bank.v1beta1.MsgSend.encode(msgSend).finish() 44 | }); 45 | 46 | //console.log("msgSendAny: ", msgSendAny); 47 | 48 | const txBody = new message.cosmos.tx.v1beta1.TxBody({ messages: [msgSendAny], memo: config.memo }); 49 | 50 | //console.log("txBody: ", txBody); 51 | //return; 52 | 53 | // --------------------------------- (2)authInfo --------------------------------- 54 | const signerInfo = new message.cosmos.tx.v1beta1.SignerInfo({ 55 | public_key: pubKeyAny, 56 | mode_info: { single: { mode: message.cosmos.tx.signing.v1beta1.SignMode.SIGN_MODE_DIRECT } }, 57 | sequence: data.account.sequence 58 | }); 59 | 60 | const feeValue = new message.cosmos.tx.v1beta1.Fee({ 61 | amount: [{ denom: denom, amount: String(config.feeAmount) }], 62 | gas_limit: config.gasLimit 63 | }); 64 | 65 | const authInfo = new message.cosmos.tx.v1beta1.AuthInfo({ signer_infos: [signerInfo], fee: feeValue }); 66 | 67 | // -------------------------------- sign -------------------------------- 68 | const signedTxBytes = cosmos.sign(txBody, authInfo, data.account.account_number, privKey); 69 | 70 | return cosmos.broadcast(signedTxBytes).then( 71 | function(response) {res.send({response}); console.log(response) } 72 | ); 73 | 74 | }); 75 | 76 | } 77 | 78 | // Routing 79 | app.get('/', function (req, res) { 80 | res.setHeader('Content-Type', 'application/json'); 81 | if (req.query.address === '') { 82 | console.log(false) 83 | res.send({error:'Already funded'}); 84 | } else { 85 | var rtnTx = sendTx(req.query.address,res) 86 | 87 | console.log(req.query.address) 88 | } 89 | }) 90 | 91 | app.listen(config.lport, function () { 92 | console.log('***********************************************') 93 | console.log('* Welcome on Cosmos-faucet') 94 | console.log('* Cosmos-faucet app listening on port '+config.lport) 95 | console.log('**********************************************') 96 | }) 97 | --------------------------------------------------------------------------------