Hethers
Search…
Getting Started

Installing

Hethers' various Classes and Functions are available to import manually from sub-packages under the @hethers organization but for most projects, the umbrella package is the easiest way to get started.
1
npm install --save @hashgraph/hethers
Copied!

Importing

NodeJS
1
// node.js require
2
const { hethers } = require('@hashgraph/hethers');
3
4
// ES6 or TypeScript
5
import { hethers } from '@hashgraph/hethers';
Copied!
Web Browser
1
// ES6 in the Browser
2
<script type="module">
3
import { hethers } from "hethers.esm.min.js";
4
// Your code here...
5
</script>
6
7
// ES3(UMD) in the Browser
8
<script src="<link>hethers.umd.min.js" type="application/javascript"></script>
Copied!

Common terminology

Name
Purpose
Provider
A Provider (in hethers) is a class which provides an abstraction for a connection to the Hedera Network.
Signer
A Signer is a class that (usually) in some way directly or indirectly has access to a private key, which can sign messages and transactions to authorize the network to charge your account hbar to perform operations.
Contract
A Contract is an abstraction that represents a connection to a specific contract on the Hedera Network, so that applications can use it as a normal JavaScript object.

Connecting to Hedera Providers

1
// available default providers ['mainnet', 'testnet', 'previewnet']
2
const defaultProvider = hethers.providers.getDefaultProvider('testnet');
3
4
// or you can define the connection properties by yourself
5
const customProvider = new hethers.providers.HederaProvider(
6
nodeId, // AccountLike
7
consensusNodeUrl, // string
8
mirrorNodeUrl // string
9
);
Copied!

Querying

Once you have a Provider, you have a read-only connection to the blockchain, which you can use to query the current state, fetch historic logs, look up deployed code and so on.
1
const provider = hethers.providers.getDefaultProvider('testnet');
2
3
const balance = await provider.getBalance('0.0.29562194');
4
5
const bytecode = await provider.getCode('0x0000000000000000000000000000000001d5a8f0');
Copied!

Writing

1
const tx = signer.sendTransaction({
2
to: '0.0.29562194',
3
value: hethers.utils.parseHbar("1.2")
4
});
Copied!

Contracts

A Contract is an abstraction of program code that lives on the Hedera Hashgraph Smart Contract Service.
The Contract object makes it easier to use an on-chain Contract as a normal JavaScript object, with the methods mapped to encoding and decoding data for you.
If you are familiar with Databases, this is similar to an Object Relational Mapper (ORM).
In order to communicate with the Contract on-chain, this class needs to know what methods are available and how to encode and decode the data, which is what the Application Binary Interface (ABI) provides.
This class is a meta-class, which means its methods are constructed at runtime, and when you pass in the ABI to the constructor it uses it to determine which methods to add.
While an on-chain Contract may have many methods available, you can safely ignore any methods you don't need or use, providing a smaller subset of the ABI to the contract.
An ABI often comes from the Solidity compiler, but you can use the Human-Readable ABI in code, which the following examples use.
1
const provider = hethers.providers.getDefaultProvider('testnet');
2
3
// The contract address
4
const erc20Address = '0x0000000000000000000000000000000001d5a8f0';
5
6
// The ERC-20 Contract ABI, which is a common contract interface
7
// for tokens (this is the Human-Readable ABI format)
8
const erc20Abi = [
9
// Some details about the token
10
'function name() view returns (string)',
11
'function symbol() view returns (string)',
12
13
// Get the account balance
14
'function balanceOf(address) view returns (uint)',
15
16
// Send some of your tokens to someone else
17
'function transfer(address to, uint amount)',
18
19
// An event triggered whenever anyone transfers to someone else
20
'event Transfer(address indexed from, address indexed to, uint amount)'
21
];
22
23
// The Contract object
24
const contract = new hethers.Contract(erc20Address, erc20Abi, provider);
Copied!

Read-Only Methods

1
// The Contract is currently connected to the Provider.
2
// You need to connect to a Signer, so
3
// that you can pay for ContractLocalCall transactions.
4
const contractWithSigner = contract.connect(signer);
5
6
// Get the ERC-20 token name
7
await contractWithSigner.name({gasLimit: 30000});
8
// 'My Token Name'
9
10
// Get the ERC-20 token symbol (for tickers and UIs)
11
await contractWithSigner.symbol({gasLimit: 30000});
12
// 'MTN'
13
14
// Get the balance of an address
15
await contractWithSigner.balanceOf(contractWallet.address, {gasLimit: 30000});
16
// BigNumber { _hex: '0x2710', _isBigNumber: true }
Copied!

State Changing Methods

1
const amount = hethers.utils.parseUnits('1.0');
2
3
// Send 10**8 amount of tokens to the recipient's address
4
const tx = contractWithSigner.transfer(
5
'0x0000000000000000000000000000000001d5a949',
6
amount,
7
{gasLimit: 50000}
8
);
Copied!

Listening to Events

1
// Receive an event when ANY transfer occurs
2
contract.on('Transfer', (from, to, amount, event) => {
3
console.log(`${from} sent ${formatHbar(amount)} to ${to}`);
4
});
5
6
// A filter for when a specific address receives tokens
7
const filter = contract.filters.Transfer(null, signer.address);
8
// {
9
// address: '0x0000000000000000000000000000000001c4fff6',
10
// topics: [
11
// '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
12
// null,
13
// '0x0000000000000000000000000000000000000000000000000000000001c42506'
14
// ]
15
// }
16
17
// Receive an event when that filter occurs
18
contract.on(filter, (from, to, amount, event) => {
19
// The to will always be "address"
20
console.log(`I got ${formatHbar(amount)} from ${from}.`);
21
});
Copied!

Query Historic Events

1
// filter from
2
const filter = contract.filters.Transfer(signer.address);
3
// {
4
// address: '0x0000000000000000000000000000000001c4fff6',
5
// topics: [
6
// '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
7
// '0x0000000000000000000000000000000000000000000000000000000001c31552'
8
// ]
9
// }
10
11
const fromTimestamp = '1645110013.000000000';
12
const toTimestamp = '1645110014.000000000';
13
await contract.queryFilter(filter, fromTimestamp, toTimestamp);
14
// [
15
// {
16
// timestamp: '1645110013.250941000',
17
// address: '0x0000000000000000000000000000000001C4ffF6',
18
// data: '0x0000000000000000000000000000000000000000000000000000000000000064',
19
// topics: [
20
// '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef',
21
// '0x0000000000000000000000000000000000000000000000000000000001c31552',
22
// '0x0000000000000000000000000000000000000000000000000000000001c42506'
23
// ],
24
// logIndex: 0,
25
// transactionIndex: 0,
26
// removeListener: [Function (anonymous)],
27
// getTransaction: [Function (anonymous)],
28
// getTransactionReceipt: [Function (anonymous)],
29
// event: 'Transfer',
30
// eventSignature: 'Transfer(address,address,uint256)',
31
// decode: [Function (anonymous)],
32
// args: [
33
// '0x0000000000000000000000000000000001C31552',
34
// '0x0000000000000000000000000000000001C42506',
35
// [BigNumber],
36
// from: '0x0000000000000000000000000000000001C31552',
37
// to: '0x0000000000000000000000000000000001C42506',
38
// value: [BigNumber]
39
// ]
40
// }
41
// ]
Copied!

Signing Messages

1
// To sign a simple string, which are used for
2
// logging into a service, pass the string in.
3
signer.signMessage('message');
4
// '0xe1c58c8ea54a270eb99c14e1e6f7bbb14f2a16225556e5e7cc27e77d0f57cad4611fd46c747430e6b9df9cd51fa8430c993f664789034525629742f3ebb0be6d1c'
5
6
// A common case is also signing a hash, which is 32
7
// bytes. It is important to note, that to sign binary
8
// data it MUST be an Array (or TypedArray)
9
10
// This string is 66 characters long
11
const message = '0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef';
12
13
// This array representation is 32 bytes long
14
const messageBytes = hethers.utils.arrayify(message);
15
16
// To sign a hash, you most often want to sign the bytes
17
const signature = await signer.signMessage(messageBytes);
18
// '0x6a8241ec5885dd54f59dd0a4219490bba63e19473de9ba6895c5bfa5fb4fe0c03e761e79f1a5655b2b8e7119adbd1ec09df829884a4d514d45ec89b66eb951791b'
Copied!