Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore(examples): improve examples readme + add dotenv for mnemonic lo…
…ading
  • Loading branch information
baktun14 committed Jan 17, 2025
commit f769298ef735f9587bf92534e286297cbabdd3bc
1 change: 1 addition & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
MNEMONIC='<your wallet mnemonic>'
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -23,3 +23,4 @@ yarn-error.log
.coverage/
coverage/

.env
233 changes: 109 additions & 124 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -2,6 +2,8 @@

This directory contains several examples of how to interact with the Akash networking using AkashJS and CosmJS.

## Setup

You can integrate the following examples in either a nodejs environment with self managed keys/wallet or in the browser using wallet extensions.

- [How to setup for node.js](#how-to-setup-for-nodejs)
@@ -11,6 +13,12 @@ Once you have a wallet setup, you need to fund it with $AKT tokens to pay for tr

- [Purchasing Akash Tokens](https://akash.network/docs/getting-started/token-and-wallets/#purchasing-akash-tokens)

Environment variable setup:

- Create an `.env` file at the root of the repo following the [.env.sample](../.env.sample)

## Code examples

Please follow the following examples to interact with the Akash Network:

- [Create wallet](./create_wallet.ts)
@@ -34,6 +42,8 @@ To run an example, you need to make the required changes to the code and use typ

```bash
npm run example create_deployment.ts
// or other examples
npm run example <name_of_the_example.ts>
```

## How to setup for nodejs
@@ -44,7 +54,27 @@ First you need a wallet. You can either [create one](#wallet-creation) with prog

We strongly recommend to use [cosmos-kit](https://docs.cosmology.zone/cosmos-kit/get-started), which supports multiple wallet extensions and a lot of utility functions. Follow their get started guide to setup your React application to be able to interact with a wallet extension and broadcast transactions.

### Wallet Creation
## Dependencies installation

Install the following dependencies for general usage and signing transactions with an existing wallet

```bash
npm i @akashnetwork/akash-api @akashnetwork/akashjs @cosmjs/stargate @cosmjs/proto-signing
```

If you want to create wallets

```bash
npm i @cosmjs/launchpad
```

For [amino encoding](https://docs.cosmos.network/main/learn/advanced/encoding#encoding-1)

```bash
npm i @cosmjs/amino
```

### Wallet Creation

The following code shows an example of the process for creating a new Akash wallet. The wallet can be used to access accounts which contain private/public key pairs and their associated addresses.

@@ -54,18 +84,15 @@ A new wallet can be initialized by calling `Secp256k1HdWallet.generate` from @co
import { Secp256k1HdWallet } from "@cosmjs/launchpad";

// the first parameter for generate is the size of the mnemonic, default is 12
const wallet = await Secp256k1HdWallet
.generate(undefined, { prefix: "akash" });

const wallet = await Secp256k1HdWallet.generate(undefined, { prefix: "akash" });
```

After the wallet is created, specific private/public key pairs are available via `getAccounts`.

```ts
import { Secp256k1HdWallet } from "@cosmjs/launchpad";

const wallet = await Secp256k1HdWallet
.generate(undefined, { prefix: "akash" });
const wallet = await Secp256k1HdWallet.generate(undefined, { prefix: "akash" });

// gets the first account
const [account] = await wallet.getAccounts();
@@ -76,8 +103,7 @@ The account address, as well as its public key, are available as properties on t
```ts
import { Secp256k1HdWallet } from "@cosmjs/launchpad";

const wallet = await Secp256k1HdWallet
.generate(undefined, { prefix: "akash" });
const wallet = await Secp256k1HdWallet.generate(undefined, { prefix: "akash" });

const [account] = await wallet.getAccounts();

@@ -96,16 +122,12 @@ function getMessage(): StdSignDoc {
// implements custom message
}

const wallet = await Secp256k1HdWallet
.generate(undefined, { prefix: "akash" });
const wallet = await Secp256k1HdWallet.generate(undefined, { prefix: "akash" });

const [account] = await wallet.getAccounts();
const msg = getMessage(); // your custom message

const signedMessage = await wallet.signAmino(
account.address,
msg
);
const signedMessage = await wallet.signAmino(account.address, msg);
```

## Signed Transactions
@@ -116,7 +138,6 @@ To create the message, the appropriate _type_ can be imported from `akashjs`.

```ts
import { MsgCloseDeployment } from "@akashnetwork/akashjs/build/src/protobuf/akash/deployment/v1beta1/deployment";

```

This type contains the methods needed to construct a message that can then be passed into a Stargate client to be signed and broadcast.
@@ -131,53 +152,42 @@ const [account] = await wallet.getAccounts();

// Use the encode method for the message to wrap the data
const message = MsgCloseDeployment.fromPartial({
id: {
dseq: "555555",
owner: account.address,
}
id: {
dseq: "555555",
owner: account.address
}
});

// Set the appropriate typeUrl and attach the encoded message as the value
const msgAny = {
typeUrl: getTypeUrl(MsgCloseDeployment),
value: message
typeUrl: getTypeUrl(MsgCloseDeployment),
value: message
};

// You can use your own RPC node, or get a list of public nodes from akashjs
const rpcEndpoint = "http://rpc.akashnet.net";

// The akash types need to be registered with the client
const myRegistry = new Registry(
getAkashTypeRegistry()
);
const myRegistry = new Registry(getAkashTypeRegistry());

// Instantiate the signer client
const client = await SigningStargateClient.connectWithSigner(
rpcEndpoint,
wallet,
{
registry: myRegistry
}
);
const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet, {
registry: myRegistry
});

// Create the fee object to pay for the transaction
const fee = {
amount: [
{
denom: "uakt",
amount: "5000",
},
],
gas: "800000",
amount: [
{
denom: "uakt",
amount: "5000"
}
],
gas: "800000"
};

// Sign and broadcast the transaction
const signedMessage = await client.signAndBroadcast(
account.address,
[msgAny],
fee,
"take down deployment"
);
const signedMessage = await client.signAndBroadcast(account.address, [msgAny], fee, "take down deployment");
```

## Signing MsgSend
@@ -197,97 +207,76 @@ const [account] = await wallet.getAccounts();
// Setup a send message manually. See the appropriate repo (cosmjs in this case)
// for the specific shape of the message.
const message = {
fromAddress: account.address,
toAddress: "akash123...",
amount: coins(10, "akt"),
fromAddress: account.address,
toAddress: "akash123...",
amount: coins(10, "akt")
};

// Set the appropriate typeUrl and attach the encoded message as the value
const msgAny = {
typeUrl: '/cosmos.bank.v1beta1.MsgSend',
value: message
typeUrl: "/cosmos.bank.v1beta1.MsgSend",
value: message
};

// You can use your own RPC node, or get a list of public nodes from akashjs
const rpcEndpoint = "http://your.rpc.node";

const myRegistry = new Registry(
defaultRegistryTypes
);
const myRegistry = new Registry(defaultRegistryTypes);

const client = await SigningStargateClient.connectWithSigner(
rpcEndpoint,
wallet,
{
registry: myRegistry
}
);
const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet, {
registry: myRegistry
});

const fee = {
amount: [
{
denom: "uakt",
amount: "5000",
},
],
gas: "800000",
amount: [
{
denom: "uakt",
amount: "5000"
}
],
gas: "800000"
};

const msg = await client.sign(
account.address,
[msgAny],
fee,
"send some tokens"
);
const msg = await client.sign(account.address, [msgAny], fee, "send some tokens");
```

## Estimating Gas

When sending transactions, it can be useful to get an estimate of the gas required for a given message. This can be done using the `simulate` method of the signing client which will send the passed in message to an RPC node which will return the estimated gas for that transaction. Before is an example of doing this for the same transaction as shown above.

```ts
const mnemonic = "your wallet mnemonic";
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: "akash" });

// get first account
const [account] = await wallet.getAccounts();

// Use the encode method for the message to wrap the data
const message = MsgCloseDeployment.fromPartial({
id: {
dseq: "555555",
owner: account.address,
}
});

// Set the appropriate typeUrl and attach the encoded message as the value
const msgAny = {
typeUrl: getTypeUrl(MsgCloseDeployment),
value: message
};

// You can use your own RPC node, or get a list of public nodes from akashjs
const rpcEndpoint = "http://my.rpc.node";

const myRegistry = new Registry(
getAkashTypeRegistry()
);

const client = await SigningStargateClient.connectWithSigner(
rpcEndpoint,
wallet,
{
registry: myRegistry
}
);

const gas = await client.simulate(
account.address,
[msgAny],
"take down deployment"
);

console.log(gas);
const mnemonic = "your wallet mnemonic";
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: "akash" });

// get first account
const [account] = await wallet.getAccounts();

// Use the encode method for the message to wrap the data
const message = MsgCloseDeployment.fromPartial({
id: {
dseq: "555555",
owner: account.address
}
});

// Set the appropriate typeUrl and attach the encoded message as the value
const msgAny = {
typeUrl: getTypeUrl(MsgCloseDeployment),
value: message
};

// You can use your own RPC node, or get a list of public nodes from akashjs
const rpcEndpoint = "http://rpc.akashnet.net";

const myRegistry = new Registry(getAkashTypeRegistry());

const client = await SigningStargateClient.connectWithSigner(rpcEndpoint, wallet, {
registry: myRegistry
});

const gas = await client.simulate(account.address, [msgAny], "take down deployment");

console.log(gas);
```

## Querying on chain data
@@ -297,17 +286,13 @@ Querying on-chain data can be done using the basic RPC capabilities build into `
For example, to query the list of deployments, an RPC request can be created as such.

```ts
import {
QueryDeploymentsResponse,
QueryDeploymentsRequest,
QueryClientImpl
} from "@akashnetwork/akashjs/build/protobuf/akash/deployment/v1beta1/query";
import { getRpc } from "@akashnetwork/akashjs/build/rpc"
import { QueryDeploymentsResponse, QueryDeploymentsRequest, QueryClientImpl } from "@akashnetwork/akashjs/build/protobuf/akash/deployment/v1beta1/query";
import { getRpc } from "@akashnetwork/akashjs/build/rpc";

const request = QueryDeploymentsRequest.fromJSON({
filters: {
owner: "akashSomeOwnerAddress",
}
filters: {
owner: "akashSomeOwnerAddress"
}
});
```

@@ -317,4 +302,4 @@ Once the request has been created, it can be passed to the appropriate <Service>
const client = new QueryClientImpl(await getRpc("https://rpc.akashnet.net")); // This can also be your own custom rpc node
const response = await client.Deployments(request);
const data = QueryDeploymentsResponse.toJSON(response);
```
```
14 changes: 10 additions & 4 deletions examples/create_deployment.ts
Original file line number Diff line number Diff line change
@@ -12,15 +12,21 @@ import { getAkashTypeRegistry } from "@akashnetwork/akashjs/build/stargate";
import { CertificatePem } from "@akashnetwork/akashjs/build/certificates/certificate-manager/CertificateManager";
import { certificateManager } from "@akashnetwork/akashjs/build/certificates/certificate-manager";
import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing";
import dotenv from "dotenv";

dotenv.config({ path: "../.env" });

// In case you want to test on a sandbox environment, uncomment the following line and comment the following line
const rpcEndpoint = "https://rpc.sandbox-01.aksh.pw";
// const rpcEndpoint = "https://rpc.sandbox-01.aksh.pw";

// Update this with your RPC endpoint
// const rpcEndpoint = "https://rpc.akashnet.net:443";
const rpcEndpoint = "https://rpc.akashnet.net:443";

// Update this with your wallet mnemonic
const mnemonic = fs.readFileSync(path.resolve(__dirname, "./fixtures/mnemonic.txt"), "utf8").trim();
// Update this environment variable with your wallet mnemonic
const mnemonic = process.env.MNEMONIC || "";
if (!mnemonic) {
throw new Error("MNEMONIC environment variable is not set. Please set the environment variable in the .env file. See .env.sample for more information.");
}

// Update this with your SDL file
const rawSDL = fs.readFileSync(path.resolve(__dirname, "./fixtures/example.sdl.yaml"), "utf8");
2 changes: 1 addition & 1 deletion examples/details_of_single_provider.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { QueryClientImpl, QueryProviderRequest, QueryProviderResponse } from "@a
import { getRpc } from "@akashnetwork/akashjs/build/rpc";

async function main() {
const client = new QueryClientImpl(await getRpc("http://your.rpc.node"));
const client = new QueryClientImpl(await getRpc("http://rpc.akashnet.net"));

const getProviderInfoRequest = QueryProviderRequest.fromPartial({
owner: "akashSomeProviderAddress"
10 changes: 8 additions & 2 deletions examples/estimate_gas.ts
Original file line number Diff line number Diff line change
@@ -2,9 +2,15 @@ import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing";
import { SigningStargateClient } from "@cosmjs/stargate";
import { MsgCloseDeployment } from "@akashnetwork/akash-api/akash/deployment/v1beta3";
import { getAkashTypeRegistry, getTypeUrl } from "@akashnetwork/akashjs/build/stargate";
import dotenv from "dotenv";

dotenv.config({ path: "../.env" });

async function main() {
const mnemonic = "your wallet mnemonic";
const mnemonic = process.env.MNEMONIC || "";
if (!mnemonic) {
throw new Error("MNEMONIC environment variable is not set. Please set the environment variable in the .env file. See .env.sample for more information.");
}
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: "akash" });

// get first account
@@ -25,7 +31,7 @@ async function main() {
};

// You can use your own RPC node, or get a list of public nodes from akashjs
const rpcEndpoint = "http://my.rpc.node";
const rpcEndpoint = "http://rpc.akashnet.net";

const myRegistry = new Registry(getAkashTypeRegistry());

1 change: 1 addition & 0 deletions examples/fixtures/cert.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"cert":"-----BEGIN CERTIFICATE-----\r\nMIIBmzCCAUGgAwIBAgIHBivoizeG2DAKBggqhkjOPQQDAjA3MTUwMwYDVQQDDCxh\r\na2FzaDFwMmU3M3ZwaHk5dW1zeDAyeTZ4cXI0OXlldTBkbjlzM3B5dGt2azAeFw0y\r\nNTAxMTcxNTI3MDhaFw0yNjAxMTcxNTI3MDhaMDcxNTAzBgNVBAMMLGFrYXNoMXAy\r\nZTczdnBoeTl1bXN4MDJ5NnhxcjQ5eWV1MGRuOXMzcHl0a3ZrMFkwEwYHKoZIzj0C\r\nAQYIKoZIzj0DAQcDQgAEzMqJ29jDG6EZGDLL1g9TX1kjE4qGPWhkGfa9AUMQFsdY\r\njVHwV8bZI1UxfZLWrkhRMZ5+23iHmV6OL01Df8yUlqM4MDYwDgYDVR0PAQH/BAQD\r\nAgQwMBMGA1UdJQQMMAoGCCsGAQUFBwMCMA8GA1UdEwEB/wQFMAMBAf8wCgYIKoZI\r\nzj0EAwIDSAAwRQIgX8ewEpsdIqIWveH4wemnGUSvts8jIh89NtcZV2gQHWECIQCX\r\ncNF7U+0wZaJ+7PQmUCEoZ/4dsMCL4LiZmspr0akChg==\r\n-----END CERTIFICATE-----\r\n","publicKey":"-----BEGIN EC PUBLIC KEY-----\r\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEzMqJ29jDG6EZGDLL1g9TX1kjE4qG\r\nPWhkGfa9AUMQFsdYjVHwV8bZI1UxfZLWrkhRMZ5+23iHmV6OL01Df8yUlg==\r\n-----END EC PUBLIC KEY-----\r\n","privateKey":"-----BEGIN PRIVATE KEY-----\r\nMIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgfUA//ul4AYxdOeCX\r\nsI4vEb14P3c/jnNboJNFsaVrVIehRANCAATMyonb2MMboRkYMsvWD1NfWSMTioY9\r\naGQZ9r0BQxAWx1iNUfBXxtkjVTF9ktauSFExnn7beIeZXo4vTUN/zJSW\r\n-----END PRIVATE KEY-----\r\n"}
1 change: 0 additions & 1 deletion examples/fixtures/mnemonic.txt

This file was deleted.

2 changes: 1 addition & 1 deletion examples/get_deployments.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ async function main() {
}
});

const client = new QueryClientImpl(await getRpc("http://your.rpc.node"));
const client = new QueryClientImpl(await getRpc("http://rpc.akashnet.net"));
const response = await client.Deployments(request);
const data = QueryDeploymentsResponse.toJSON(response);

2 changes: 1 addition & 1 deletion examples/get_lease_status.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { QueryClientImpl, QueryLeaseRequest, QueryLeaseResponse } from "@akashne
import { getRpc } from "@akashnetwork/akashjs/build/rpc";

async function main() {
const client = new QueryClientImpl(await getRpc("http://your.rpc.node"));
const client = new QueryClientImpl(await getRpc("http://rpc.akashnet.net"));

const getLeaseStatusRequest = QueryLeaseRequest.fromPartial({
id: {
2 changes: 1 addition & 1 deletion examples/list_all_providers.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { QueryClientImpl, QueryProvidersRequest, QueryProvidersResponse } from "
import { getRpc } from "@akashnetwork/akashjs/build/rpc";

async function main() {
const client = new QueryClientImpl(await getRpc("http://your.rpc.node"));
const client = new QueryClientImpl(await getRpc("http://rpc.akashnet.net"));

const providersRequest = QueryProvidersRequest.fromPartial({
pagination: {
8 changes: 7 additions & 1 deletion examples/signed_msg_send.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import { coins, DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing";
import { defaultRegistryTypes, SigningStargateClient } from "@cosmjs/stargate";
import dotenv from "dotenv";

dotenv.config({ path: "../.env" });

async function main() {
const mnemonic = "your wallet mnemonic";
const mnemonic = process.env.MNEMONIC || "";
if (!mnemonic) {
throw new Error("MNEMONIC environment variable is not set. Please set the environment variable in the .env file. See .env.sample for more information.");
}
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: "akash" });

// get first account
12 changes: 9 additions & 3 deletions examples/take_down_deployment.ts
Original file line number Diff line number Diff line change
@@ -2,9 +2,15 @@ import { DirectSecp256k1HdWallet, Registry } from "@cosmjs/proto-signing";
import { SigningStargateClient } from "@cosmjs/stargate";
import { getAkashTypeRegistry, getTypeUrl } from "@akashnetwork/akashjs/build/stargate";
import { MsgCloseDeployment } from "@akashnetwork/akash-api/akash/deployment/v1beta3";
import dotenv from "dotenv";

dotenv.config({ path: "../.env" });

async function main() {
const mnemonic = "your wallet mnemonic";
const mnemonic = process.env.MNEMONIC || "";
if (!mnemonic) {
throw new Error("MNEMONIC environment variable is not set. Please set the environment variable in the .env file. See .env.sample for more information.");
}
const wallet = await DirectSecp256k1HdWallet.fromMnemonic(mnemonic, { prefix: "akash" });

// get first account
@@ -13,7 +19,7 @@ async function main() {
// Use the encode method for the message to wrap the data
const message = MsgCloseDeployment.fromPartial({
id: {
dseq: "555555",
dseq: "19837048",
owner: account.address
}
});
@@ -25,7 +31,7 @@ async function main() {
};

// You can use your own RPC node, or get a list of public nodes from akashjs
const rpcEndpoint = "http://my.rpc.node";
const rpcEndpoint = "http://rpc.akashnet.net";

const myRegistry = new Registry(getAkashTypeRegistry());

13 changes: 13 additions & 0 deletions package-lock.json
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -57,17 +57,18 @@
"atob": "^2.1.2",
"axios": "^0.24.0",
"console-browserify": "^1.2.0",
"dotenv": "^16.4.7",
"js-yaml": "^4.1.0",
"json-stable-stringify": "^1.0.2",
"jsrsasign": "^11.1.0",
"keytar": "^7.7.0",
"lodash": "^4.17.21",
"node-fetch": "2",
"pkijs": "^3.0.0",
"process": "^0.11.10",
"pvutils": "^1.0.17",
"simple-jsonrpc-js": "^1.2.0",
"sort-json": "^2.0.1",
"lodash": "^4.17.21"
"sort-json": "^2.0.1"
},
"devDependencies": {
"@commitlint/cli": "^19.2.2",