|
|
|
@ -1,4 +1,176 @@ |
|
|
|
|
# Usage |
|
|
|
|
# About This Package |
|
|
|
|
|
|
|
|
|
`@harmony-js/account` is dealing with account related features. |
|
|
|
|
|
|
|
|
|
Developers can use this packages to: |
|
|
|
|
* create `Account` instance |
|
|
|
|
* create `Wallet` instance |
|
|
|
|
* sign `Transaction` |
|
|
|
|
* convert address format |
|
|
|
|
* manage `privateKey` or `mnemonic phrases` and do the `encrypt` and `decrypt` job |
|
|
|
|
|
|
|
|
|
There are 2 main classes in this package, `Account` and `Wallet`. |
|
|
|
|
|
|
|
|
|
The `Account` class is basic instance that contains most features mentioned above. |
|
|
|
|
The `Wallet` class is class that stores all `Account` instance, you can do CRUD on it. |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Usage of Account |
|
|
|
|
|
|
|
|
|
## Dependencies |
|
|
|
|
* "@harmony-js/network", |
|
|
|
|
* "@harmony-js/staking", |
|
|
|
|
* "@harmony-js/transaction", |
|
|
|
|
* "@harmony-js/utils" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## Examples |
|
|
|
|
|
|
|
|
|
### create a random account |
|
|
|
|
```typescript |
|
|
|
|
|
|
|
|
|
// import the Account class |
|
|
|
|
import {Account} from '@harmony-js/account' |
|
|
|
|
|
|
|
|
|
// Messenger is optional, by default, we have a defaultMessenger |
|
|
|
|
// If you like to change, you will import related package here. |
|
|
|
|
import { HttpProvider, Messenger } from '@harmony-js/network'; |
|
|
|
|
import { ChainType, ChainID } from '@harmony-js/utils'; |
|
|
|
|
|
|
|
|
|
// create a custom messenger |
|
|
|
|
const customMessenger = new Messenger( |
|
|
|
|
new HttpProvider('http://localhost:9500'), |
|
|
|
|
ChainType.Harmony, // if you are connected to Harmony's blockchain |
|
|
|
|
ChainID.HmyLocal, // check if the chainId is correct |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
// to create an Account with random privateKey |
|
|
|
|
// and you can setMessenger later |
|
|
|
|
const randomAccount = new Account() |
|
|
|
|
randomAccount.setMessenger(customMessenger) |
|
|
|
|
|
|
|
|
|
// or you can set messenger on `new` |
|
|
|
|
const randomAccountWithCustomMessenger = new Account(undefined, customMessenger) |
|
|
|
|
|
|
|
|
|
// you can display the account |
|
|
|
|
console.log({randomAccount,randomAccountWithCustomMessenger}) |
|
|
|
|
|
|
|
|
|
// or you can use static method to create an Account |
|
|
|
|
const staticCreatedAccount = Account.new() |
|
|
|
|
// but you have to set messenger manually after |
|
|
|
|
staticCreatedAccount.setMessenger(customMessenger) |
|
|
|
|
|
|
|
|
|
console.log({staticCreatedAccount}) |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
### import an existing privateKey to create Account |
|
|
|
|
|
|
|
|
|
```typescript |
|
|
|
|
|
|
|
|
|
// import the Account class |
|
|
|
|
import {Account} from '@harmony-js/account' |
|
|
|
|
|
|
|
|
|
// NOTED: Key with or without `0x` are accepted, makes no different |
|
|
|
|
// NOTED: DO NOT import `mnemonic phrase` using `Account` class, use `Wallet` instead |
|
|
|
|
const myPrivateKey = '0xe19d05c5452598e24caad4a0d85a49146f7be089515c905ae6a19e8a578a6930' |
|
|
|
|
|
|
|
|
|
const myAccountWithMyPrivateKey = new Account(myPrivateKey) |
|
|
|
|
|
|
|
|
|
// you can also import privateKey use static method |
|
|
|
|
const myAccountWithMyPrivateKeyUsingStatic = Account.add(myPrivateKey) |
|
|
|
|
|
|
|
|
|
console.log({ myAccountWithMyPrivateKey, myAccountWithMyPrivateKeyUsingStatic }) |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
### Encrypt/Export keyStore file, Decrypt/Import keyStore file |
|
|
|
|
|
|
|
|
|
```typescript |
|
|
|
|
|
|
|
|
|
// import the Account class |
|
|
|
|
import {Account} from '@harmony-js/account' |
|
|
|
|
|
|
|
|
|
// suppose we have an account |
|
|
|
|
const myPrivateKey = '0xe19d05c5452598e24caad4a0d85a49146f7be089515c905ae6a19e8a578a6930' |
|
|
|
|
const myAccountWithMyPrivateKey = new Account(myPrivateKey) |
|
|
|
|
|
|
|
|
|
// suppose we have a password, and we want to encrypt the account above |
|
|
|
|
const myStrongPassword = '123' |
|
|
|
|
|
|
|
|
|
async function encryptAndDecrypt(password) { |
|
|
|
|
// we get the privateKey before encrypted as comparison |
|
|
|
|
const unencryptedPrivateKey = myAccountWithMyPrivateKey.privateKey |
|
|
|
|
|
|
|
|
|
// export the account to keyStore string, which will make the privateKey encrpyted |
|
|
|
|
const keyStoreFile = await myAccountWithMyPrivateKey.toFile(password) |
|
|
|
|
// exported keyStoreFile |
|
|
|
|
console.log({ keyStoreFile }) |
|
|
|
|
// see if the account is encrypted |
|
|
|
|
console.log(`Is this account encrypted? \n ${myAccountWithMyPrivateKey.encrypted}`) |
|
|
|
|
// keystore file should be equal to encrypted privateKey |
|
|
|
|
console.log( |
|
|
|
|
`Is privateKey equal to keyStore string? \n ${keyStoreFile === |
|
|
|
|
myAccountWithMyPrivateKey.privateKey}`, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
encryptAndDecrypt(myStrongPassword) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// suppose we have keyStorefile, in this example, we just use same password and keystore string encrypted above |
|
|
|
|
const someKeyStoreFile = |
|
|
|
|
'{"version":3,"id":"62326332-3139-4839-b534-656134623066","address":"1fe3da351d9fc0c4f02de5412ad7def8aee956c5","Crypto":{"ciphertext":"b86ab81682c9f5a35738ad9bd38cd9b46c1b852ef33f16dd83068f79e20d5531","cipherparams":{"iv":"44efb5a514f34968e92cafad80566487"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"salt":"d70ae1f311601562113f98c8ebe382f52a332dca1588886e5ea91e2f8a647134","n":8192,"r":8,"p":1,"dklen":32},"mac":"7b63e4e31a75a22b7091291bb58302655b738539ef3e30b30a7a7f170f6163ef"}}' |
|
|
|
|
|
|
|
|
|
async function importKeyStoreFileAndDecrypt(keyStoreFile, password) { |
|
|
|
|
// import keyStore string and provide the password, remember to make a new Account first |
|
|
|
|
const importedAccount = await Account.new().fromFile(keyStoreFile, password) |
|
|
|
|
// the account should decypted which `Account.encrypted` is false |
|
|
|
|
console.log(`Is this account encrypted? \n ${importedAccount.encrypted}`) |
|
|
|
|
// see if the privatekey is equal to unencrypted one? |
|
|
|
|
console.log( |
|
|
|
|
`Is the account recovered from keystore? \n ${importedAccount.privateKey === myPrivateKey}`, |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
importKeyStoreFileAndDecrypt(someKeyStoreFile, myStrongPassword) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
### Address format getter |
|
|
|
|
|
|
|
|
|
```typescript |
|
|
|
|
|
|
|
|
|
// import the Account class |
|
|
|
|
import {Account} from '@harmony-js/account' |
|
|
|
|
|
|
|
|
|
// suppose we have an account |
|
|
|
|
const myPrivateKey = '0xe19d05c5452598e24caad4a0d85a49146f7be089515c905ae6a19e8a578a6930' |
|
|
|
|
const myAccountWithMyPrivateKey = new Account(myPrivateKey) |
|
|
|
|
|
|
|
|
|
// Account.address is bytes20/base16 address |
|
|
|
|
console.log(myAccountWithMyPrivateKey.address) |
|
|
|
|
// Account.bech32Address is bech32 format address, in Harmony, it's `one1` prefixed |
|
|
|
|
console.log(myAccountWithMyPrivateKey.bech32Address) |
|
|
|
|
// Account.bech32TestNetAddress is bech32 format address, in Harmony, it's `tone1` prefixed, used in testnet |
|
|
|
|
console.log(myAccountWithMyPrivateKey.bech32TestNetAddress) |
|
|
|
|
// Account.checksumAddress is checksumed address from base16 |
|
|
|
|
console.log(myAccountWithMyPrivateKey.checksumAddress) |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Usage of Wallet |
|
|
|
|
|
|
|
|
|
## Dependencies |
|
|
|
|
* "@harmony-js/crypto", |
|
|
|
|
* "@harmony-js/network", |
|
|
|
|
* "@harmony-js/staking", |
|
|
|
|
* "@harmony-js/transaction", |
|
|
|
|
* "@harmony-js/utils" |
|
|
|
|
|
|
|
|
|
```typescript |
|
|
|
|
|
|
|
|
@ -6,4 +178,7 @@ |
|
|
|
|
|
|
|
|
|
const wallet=new Wallet() |
|
|
|
|
|
|
|
|
|
``` |
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|