Compare commits
No commits in common. 'master' and 'crypto_fix' have entirely different histories.
master
...
crypto_fix
@ -0,0 +1,5 @@ |
||||
GENESIS_PRIV_KEY=45e497bd45a9049bcb649016594489ac67b9f052a6cdf5cb74ee2427a60bf25e |
||||
HTTP_PROVIDER=http://localhost:9500 |
||||
CHAIN_TYPE=hmy |
||||
CHAIN_ID=2 |
||||
|
@ -1,70 +0,0 @@ |
||||
# Release Guidelines |
||||
## Before Release |
||||
1. Build source first |
||||
```bash |
||||
yarn build:ts |
||||
``` |
||||
2. Run unit tests |
||||
```bash |
||||
yarn test:src |
||||
``` |
||||
3. Run e2e tests |
||||
```bash |
||||
yarn test:e2e |
||||
``` |
||||
4. Clean and build bundle |
||||
```bash |
||||
yarn dist |
||||
``` |
||||
## Publish to npm using `dev:publish` |
||||
|
||||
The packages is to be published to npm, using `@next` tag using script in `package.json` |
||||
|
||||
Follow steps below to publish a npm verion using `@next` tag |
||||
|
||||
1. Commit all changes to github master |
||||
2. Run publish script |
||||
|
||||
```bash |
||||
yarn dev:publish |
||||
``` |
||||
|
||||
3. Select version and confirm all prompts with `Y` |
||||
4. See version changes in `npmjs.com` |
||||
|
||||
This will not change the release version of current npm packages(currently 0.0.7), developers have to use `@next` to install from npm. |
||||
|
||||
For example. |
||||
|
||||
```bash |
||||
npm install @woop-js/core@next |
||||
``` |
||||
|
||||
|
||||
|
||||
## Publish to npm with `lerna` |
||||
|
||||
Follow steps below to publish a npm verion with latest version |
||||
|
||||
1. Commit all changes to github master |
||||
2. Run `lerna publish`, `lerna` is required globally. |
||||
|
||||
```bash |
||||
lerna publish |
||||
``` |
||||
3. Select version and confirm all prompts with `Y` |
||||
4. See version changes in `npmjs.com` |
||||
|
||||
This will change the release version of current npm packages to the latest version, developers can install from npm directly |
||||
|
||||
For example. |
||||
|
||||
```bash |
||||
npm install @woop-js/core |
||||
``` |
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,100 +0,0 @@ |
||||
# Woop JS-SDK Documentation |
||||
|
||||
## [CLICK ME!!](https://woop-js-sdk-doc.s3-us-west-1.amazonaws.com/index.html) to see the documentation |
||||
|
||||
# metaDocumentation |
||||
## Summary |
||||
The following content demonstrate how to generate our documentation! |
||||
|
||||
## Step 1: Generate Documentation |
||||
|
||||
### Introduction of TypeDoc |
||||
[TypeDoc is used to generate HTML](https://typedoc.org/api/index.html) |
||||
> See [TypeDoc command line arguments](https://typedoc.org/guides/options/), to understand how to use them. |
||||
> Using `typedoc --help` to see them |
||||
> |
||||
> **For example:** |
||||
> `typedoc --name <Name>` to set the name of header |
||||
> `typedoc --theme <default | minimal | path/to/theme>` to set the theme of documation |
||||
> `typedoc --readme <path/to/readme | none>` path to readme file that should be displayed on the index page. |
||||
> `typedoc --ignoreCompilerErrors` Should TypeDoc generate documentation pages even after the compiler has returned errors? |
||||
|
||||
### Install TypeDoc |
||||
Local installation (prefered) |
||||
``` |
||||
$ npm install typedoc --save-dev |
||||
``` |
||||
|
||||
Golbal CLI installation |
||||
``` |
||||
$ npm install --global typedoc |
||||
``` |
||||
|
||||
### Install Environemnt |
||||
``` |
||||
$ npm install |
||||
``` |
||||
|
||||
### Generate HTML |
||||
``` |
||||
$ cd docs |
||||
$ npx typedoc --out ./build ../packages/ --ignoreCompilerErrors --theme default --name Woop_SDK_Doc --readme ../README.md |
||||
``` |
||||
|
||||
### See the generated doc at local |
||||
|
||||
>open the `index.html` under the path `sdk/docs/build/index.html` |
||||
|
||||
## Step 2: Deploy on AWS (woop core only!) |
||||
|
||||
### Create an AWS s3 bucket |
||||
Actually, there are just two points needed! |
||||
1. Create an AWS S3 bucket, **UNCHECK** `Block all public access` |
||||
2. Put the files into the bucket, and set the **public permission** to `Grant public read access to this object(s)` |
||||
|
||||
### Method 1: Use Console |
||||
|
||||
[Here](https://docs.aws.amazon.com/AmazonS3/latest/gsg/CreatingABucket.html) is the documentation of AWS, just follow it! |
||||
|
||||
>Don't forget the two points mentioned above |
||||
|
||||
### Method 2: Use AWS CLI |
||||
|
||||
Reference: [AWS CLI documentation](https://docs.aws.amazon.com/cli/latest/userguide/cli-services-s3-commands.html) |
||||
|
||||
If you have never used AWS CLI, you need follow these to set up your environment first! |
||||
- [Install the AWS CLI version 1](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html) |
||||
- [Configuring the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html) |
||||
|
||||
After that, use AWS CLI to do following |
||||
|
||||
1. Create a Bucket |
||||
``` |
||||
aws s3 mb s3://woop-js-sdk-doc |
||||
``` |
||||
|
||||
2. List all buckets you have created |
||||
``` |
||||
aws s3 ls |
||||
``` |
||||
|
||||
3. Uploade the files into bucket |
||||
``` |
||||
$ cd build |
||||
$ aws s3 cp ./ s3://your-bucket-name --grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers --recursive |
||||
``` |
||||
Here is some explanations |
||||
> **./account** |
||||
> the path of folder which we want to upload |
||||
> |
||||
> **s3://woop-js-sdk-doc** |
||||
> the bucket name on AWS S3 |
||||
> |
||||
> **--grants read=uri=http://acs.amazonaws.com/groups/global/AllUsers** |
||||
> Grant read access to all user |
||||
> |
||||
> **--recursive** |
||||
> Command is performed on all files or objects under the specified directory or prefix. |
||||
|
||||
4. Open the folder in S3 bucket and find `index.html`, get the |
||||
`Object URL`, then make it public! |
@ -1,169 +1,88 @@ |
||||
import fetch from 'jest-fetch-mock'; |
||||
import { woop, checkCalledMethod } from './woop'; |
||||
import {harmony} from './harmony'; |
||||
|
||||
import demoAccounts from '../fixtures/testAccount.json'; |
||||
import { RPCMethod } from '@woop-js/network'; |
||||
|
||||
const bc = woop.blockchain; |
||||
const bc = harmony.blockchain; |
||||
|
||||
const testAccount = demoAccounts.Accounts[1]; |
||||
|
||||
describe('e2e test blockchain', () => { |
||||
beforeEach(() => { |
||||
fetch.resetMocks(); |
||||
}); |
||||
// net_*
|
||||
it('should test net_peerCount', async () => { |
||||
fetch.mockResponseOnce( |
||||
JSON.stringify({"jsonrpc": "2.0", "id": 1, "result": "0x0"}), |
||||
); |
||||
const peerCount = await bc.net_peerCount(); |
||||
expect(checkCalledMethod(0, RPCMethod.PeerCount)).toEqual(true); |
||||
expect(woop.utils.isHex(peerCount.result)).toEqual(true); |
||||
expect(harmony.utils.isHex(peerCount.result)).toEqual(true); |
||||
}); |
||||
|
||||
it('should test net_version', async () => { |
||||
fetch.mockResponseOnce( |
||||
JSON.stringify({"jsonrpc": "2.0", "id": 1, "result": "5"}), |
||||
); |
||||
const netVersion = await bc.net_version(); |
||||
const versionNumber = parseInt(netVersion.result as string, 10); |
||||
expect(netVersion.result).toEqual(`${versionNumber}`); |
||||
expect(checkCalledMethod(0, RPCMethod.NetVersion)).toEqual(true); |
||||
}); |
||||
it('should test wiki_protocolVersion', async () => { |
||||
fetch.mockResponseOnce( |
||||
JSON.stringify({"jsonrpc": "2.0", "id": 1, "result": "0x10"}), |
||||
); |
||||
it('should test hmy_protocolVersion', async () => { |
||||
const protocolVersion = await bc.getProtocolVersion(); |
||||
expect(woop.utils.isHex(protocolVersion.result)).toEqual(true); |
||||
expect(checkCalledMethod(0, RPCMethod.ProtocolVersion)).toEqual(true); |
||||
expect(harmony.utils.isHex(protocolVersion.result)).toEqual(true); |
||||
}); |
||||
|
||||
// block chain info
|
||||
it('should test wiki_blockNumber', async () => { |
||||
fetch.mockResponseOnce( |
||||
JSON.stringify({"jsonrpc": "2.0", "id": 1, "result": "0x10"}), |
||||
); |
||||
it('should test hmy_blockNumber', async () => { |
||||
const res = await bc.getBlockNumber(); |
||||
expect(res.responseType).toEqual('raw'); |
||||
expect(woop.utils.isHex(res.result)).toEqual(true); |
||||
expect(checkCalledMethod(0, RPCMethod.BlockNumber)).toEqual(true); |
||||
expect(harmony.utils.isHex(res.result)).toEqual(true); |
||||
}); |
||||
|
||||
it('should test wiki_getBlockByNumber', async () => { |
||||
fetch.mockResponse( |
||||
JSON.stringify({ |
||||
"jsonrpc": "2.0", |
||||
"id": 1, |
||||
"result": { |
||||
"size": "0x1", |
||||
"difficulty": 5, |
||||
"extraData": "0x", |
||||
"gasLimit": "0x80", |
||||
"gasUsed": "0x40", |
||||
"hash": "0x8a3390ab500Fbca6514eB326d2fcD9B3BFCFbA7DA392593cB4885b8e3399a2D8", |
||||
"logsBloom": "0x0", |
||||
"miner": "one155jp2y76nazx8uw5sa94fr0m4s5aj8e5xm6fu3", |
||||
"mixHash": "0x3A7c1Ae14AfecFf55Da298F66b75F4FfB771c3EaBDeAa267FF33A77d4d0be220", |
||||
"nonce": 1, |
||||
"number": "0x1", |
||||
"parentHash": "0x7CebC07e456F0bCD09dbc9A6f271074d93E27B40A4C67Dcc402e6513e12B9aF9", |
||||
"receiptsRoot": "0x02B82e11eDC07775Dc6fCF706be2cdAF9165750Ea7bC1B3Eb48ea16Bb3072F4D", |
||||
"stateRoot": "0xAaDc89C8bA4e3fCfC140cFcc8D3efD3BE7a49ab31534A5a3F0E1DEA09aae0f4a", |
||||
"timestamp": "0x62c44c0a", |
||||
"transactionsRoot": "0xc4bfa888fDCC8ca70E2b0CcdCEcc2fF545acCC2D655Ba33DaF4aBc31cFDBd9Ac", |
||||
"uncles": [] |
||||
} |
||||
}), |
||||
); |
||||
const res = await bc.getBlockByNumber({ blockNumber: 'latest' }); |
||||
it('should test hmy_getBlockByNumber', async () => { |
||||
const res = await bc.getBlockByNumber({blockNumber: 'latest'}); |
||||
const size = res.result.size; |
||||
expect(res.responseType).toEqual('raw'); |
||||
expect(woop.utils.isHex(size)).toEqual(true); |
||||
expect(harmony.utils.isHex(size)).toEqual(true); |
||||
expect(checkBlockData(res.result)).toEqual(true); |
||||
const res2 = await bc.getBlockByNumber({ blockNumber: res.result.number }); |
||||
const res2 = await bc.getBlockByNumber({blockNumber: res.result.number}); |
||||
expect(res2.responseType).toEqual('raw'); |
||||
expect(woop.utils.isHex(res2.result.size)).toEqual(true); |
||||
expect(harmony.utils.isHex(res2.result.size)).toEqual(true); |
||||
expect(checkBlockData(res2.result)).toEqual(true); |
||||
const res3 = await bc.getBlockByNumber({ returnObject: true }); |
||||
const res3 = await bc.getBlockByNumber({returnObject: true}); |
||||
expect(res3.responseType).toEqual('raw'); |
||||
expect(checkBlockData(res3.result)).toEqual(true); |
||||
for(let i = 0; i < 3; i++) { |
||||
expect(checkCalledMethod(i, RPCMethod.GetBlockByNumber)).toEqual(true); |
||||
} |
||||
}); |
||||
|
||||
it('should test wiki_getBlockByHash', async () => { |
||||
fetch.mockResponse( |
||||
JSON.stringify({ |
||||
"jsonrpc": "2.0", |
||||
"id": 1, |
||||
"result": { |
||||
"size": "0x1", |
||||
"difficulty": 5, |
||||
"extraData": "0x", |
||||
"gasLimit": "0x80", |
||||
"gasUsed": "0x40", |
||||
"hash": "0x8a3390ab500Fbca6514eB326d2fcD9B3BFCFbA7DA392593cB4885b8e3399a2D8", |
||||
"logsBloom": "0x0", |
||||
"miner": "one155jp2y76nazx8uw5sa94fr0m4s5aj8e5xm6fu3", |
||||
"mixHash": "0x3A7c1Ae14AfecFf55Da298F66b75F4FfB771c3EaBDeAa267FF33A77d4d0be220", |
||||
"nonce": 1, |
||||
"number": "0x1", |
||||
"parentHash": "0x7CebC07e456F0bCD09dbc9A6f271074d93E27B40A4C67Dcc402e6513e12B9aF9", |
||||
"receiptsRoot": "0x02B82e11eDC07775Dc6fCF706be2cdAF9165750Ea7bC1B3Eb48ea16Bb3072F4D", |
||||
"stateRoot": "0xAaDc89C8bA4e3fCfC140cFcc8D3efD3BE7a49ab31534A5a3F0E1DEA09aae0f4a", |
||||
"timestamp": "0x62c44c0a", |
||||
"transactionsRoot": "0xc4bfa888fDCC8ca70E2b0CcdCEcc2fF545acCC2D655Ba33DaF4aBc31cFDBd9Ac", |
||||
"uncles": [] |
||||
} |
||||
}), |
||||
); |
||||
const latestBlock = await bc.getBlockByNumber({ blockNumber: 'latest' }); |
||||
const res = await bc.getBlockByHash({ blockHash: latestBlock.result.hash }); |
||||
it('should test hmy_getBlockByHash', async () => { |
||||
const latestBlock = await bc.getBlockByNumber({blockNumber: 'latest'}); |
||||
const res = await bc.getBlockByHash({blockHash: latestBlock.result.hash}); |
||||
expect(res.responseType).toEqual('raw'); |
||||
expect(latestBlock.result.hash).toEqual(res.result.hash); |
||||
expect(woop.utils.isHex(res.result.size)).toEqual(true); |
||||
expect(harmony.utils.isHex(res.result.size)).toEqual(true); |
||||
expect(checkBlockData(res.result)).toEqual(true); |
||||
expect(checkCalledMethod(0, RPCMethod.GetBlockByNumber)).toEqual(true); |
||||
expect(checkCalledMethod(1, RPCMethod.GetBlockByHash)).toEqual(true); |
||||
}); |
||||
|
||||
// account related
|
||||
it('should test wiki_getBalance', async () => { |
||||
fetch.mockResponseOnce( |
||||
JSON.stringify({"jsonrpc": "2.0", "id": 1, "result": "0x10"}), |
||||
); |
||||
const balance = await bc.getBalance({ address: testAccount.Address }); |
||||
expect(woop.utils.isHex(balance.result)).toEqual(true); |
||||
expect(checkCalledMethod(0, RPCMethod.GetBalance)).toEqual(true); |
||||
it('should test hmy_getBalance', async () => { |
||||
const balance = await bc.getBalance({address: testAccount.Address}); |
||||
expect(harmony.utils.isHex(balance.result)).toEqual(true); |
||||
}); |
||||
}); |
||||
|
||||
function checkBlockData(data: any) { |
||||
return woop.utils.validateArgs( |
||||
return harmony.utils.validateArgs( |
||||
data, |
||||
{ |
||||
difficulty: [woop.utils.isNumber], |
||||
difficulty: [harmony.utils.isNumber], |
||||
// tslint:disable-next-line: no-shadowed-variable
|
||||
extraData: [(data: any) => data === '0x' || woop.utils.isHex(data)], |
||||
gasLimit: [woop.utils.isHex], |
||||
gasUsed: [woop.utils.isHex], |
||||
hash: [woop.utils.isHash], |
||||
logsBloom: [woop.utils.isHex], |
||||
miner: [woop.utils.isBech32Address], |
||||
mixHash: [woop.utils.isHash], |
||||
nonce: [woop.utils.isNumber], |
||||
number: [woop.utils.isHex], |
||||
parentHash: [woop.utils.isHash], |
||||
receiptsRoot: [woop.utils.isHash], |
||||
size: [woop.utils.isHex], |
||||
stateRoot: [woop.utils.isHash], |
||||
timestamp: [woop.utils.isHex], |
||||
transactionsRoot: [woop.utils.isHash], |
||||
uncles: [woop.utils.isArray], |
||||
extraData: [(data: any) => data === '0x' || harmony.utils.isHex(data)], |
||||
gasLimit: [harmony.utils.isHex], |
||||
gasUsed: [harmony.utils.isHex], |
||||
hash: [harmony.utils.isHash], |
||||
logsBloom: [harmony.utils.isHex], |
||||
miner: [harmony.utils.isAddress], |
||||
mixHash: [harmony.utils.isHash], |
||||
nonce: [harmony.utils.isNumber], |
||||
number: [harmony.utils.isHex], |
||||
parentHash: [harmony.utils.isHash], |
||||
receiptsRoot: [harmony.utils.isHash], |
||||
size: [harmony.utils.isHex], |
||||
stateRoot: [harmony.utils.isHash], |
||||
timestamp: [harmony.utils.isHex], |
||||
transactionsRoot: [harmony.utils.isHash], |
||||
uncles: [harmony.utils.isArray], |
||||
}, |
||||
{ transactions: [woop.utils.isArray] }, |
||||
{transactions: [harmony.utils.isArray]}, |
||||
); |
||||
} |
||||
} |
||||
|
@ -0,0 +1,29 @@ |
||||
// tslint:disable-next-line: no-implicit-dependencies
|
||||
import { Harmony } from '@harmony-js/core'; |
||||
// tslint:disable-next-line: no-implicit-dependencies
|
||||
import { ChainType } from '@harmony-js/utils'; |
||||
// tslint:disable-next-line: no-implicit-dependencies
|
||||
import { Account } from '@harmony-js/account'; |
||||
|
||||
const CHAIN_ID: number = parseInt(process.env.CHAIN_ID as string, 10); |
||||
const CHAIN_TYPE: string = process.env.CHAIN_TYPE as string; |
||||
const HTTP_PROVIDER: string = process.env.HTTP_PROVIDER as string; |
||||
const GENESIS_PRIV_KEY: string = process.env.GENESIS_PRIV_KEY as string; |
||||
|
||||
let chainType: ChainType = ChainType.Harmony; |
||||
|
||||
if (CHAIN_TYPE === 'hmy') { |
||||
chainType = ChainType.Harmony; |
||||
} else if (CHAIN_TYPE === 'eth') { |
||||
chainType = ChainType.Ethereum; |
||||
} |
||||
|
||||
export const harmony: Harmony = new Harmony(HTTP_PROVIDER, { |
||||
chainId: CHAIN_ID, |
||||
chainType, |
||||
chainUrl: HTTP_PROVIDER, |
||||
}); |
||||
|
||||
export const myAccount: Account = harmony.wallet.addByPrivateKey( |
||||
GENESIS_PRIV_KEY, |
||||
); |
@ -1,39 +0,0 @@ |
||||
import fetch from 'jest-fetch-mock'; |
||||
// tslint:disable-next-line: no-implicit-dependencies
|
||||
import { Woop } from '@woop-js/core'; |
||||
// tslint:disable-next-line: no-implicit-dependencies
|
||||
import { ChainType } from '@woop-js/utils'; |
||||
// tslint:disable-next-line: no-implicit-dependencies
|
||||
import { Account } from '@woop-js/account'; |
||||
|
||||
const CHAIN_ID: number = 2; |
||||
const CHAIN_TYPE: string = 'wiki'; |
||||
const HTTP_PROVIDER: string = 'http://localhost:9500'; |
||||
const GENESIS_PRIV_KEY: string = '45e497bd45a9049bcb649016594489ac67b9f052a6cdf5cb74ee2427a60bf25e'; |
||||
|
||||
let chainType: ChainType = ChainType.Woop; |
||||
|
||||
if (CHAIN_TYPE === 'wiki') { |
||||
chainType = ChainType.Woop; |
||||
} else if (CHAIN_TYPE === 'eth') { |
||||
chainType = ChainType.Ethereum; |
||||
} |
||||
|
||||
export const woop: Woop = new Woop(HTTP_PROVIDER, { |
||||
chainId: CHAIN_ID, |
||||
chainType, |
||||
chainUrl: HTTP_PROVIDER, |
||||
}); |
||||
|
||||
export const myAccount: Account = woop.wallet.addByPrivateKey( |
||||
GENESIS_PRIV_KEY, |
||||
); |
||||
|
||||
export function checkCalledMethod(i: number, s: string) { |
||||
let params: (string | undefined) = fetch.mock.calls[i][1]?.body?.toString(); |
||||
if (params) { |
||||
let method: string = JSON.parse(params).method; |
||||
return method === s; |
||||
} |
||||
return false; |
||||
} |
@ -0,0 +1,31 @@ |
||||
const { Harmony } = require('@harmony-js/core'); |
||||
|
||||
// import or require settings
|
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
|
||||
const URL_TESTNET = `https://api.s0.b.hmny.io`; |
||||
const URL_MAINNET = `https://api.s0.t.hmny.io`; |
||||
|
||||
// 1. initialize the Harmony instance
|
||||
|
||||
const harmony = new Harmony( |
||||
// rpc url
|
||||
URL_TESTNET, |
||||
{ |
||||
// chainType set to Harmony
|
||||
chainType: ChainType.Harmony, |
||||
// chainType set to HmyLocal
|
||||
chainId: ChainID.HmyTestnet, |
||||
}, |
||||
); |
||||
|
||||
harmony.blockchain |
||||
.getBalance({ |
||||
address: `one1vjywuur8ckddmc4dsyx6qdgf590eu07ag9fg4a`, |
||||
}) |
||||
.then((res) => { |
||||
console.log(new harmony.utils.Unit(res.result).asWei().toEther()); |
||||
}) |
||||
.catch((err) => { |
||||
console.log(err); |
||||
}); |
@ -0,0 +1,45 @@ |
||||
// import the Account class
|
||||
const { Account } = require('@harmony-js/account'); |
||||
|
||||
// suppose we have an account
|
||||
const myPrivateKey = '0x831f0b3ff835d5ec4602878742fda25591b6d3bb2731366621ac83a05216bec8'; |
||||
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":"38326265-6165-4961-a338-353063643962","address":"1cc87010760602a576455d6d2f03a3bf92d2c2ca","crypto":{"ciphertext":"a4ee9120b27ba66fb9d3fabd6372fa3a11060cf439a6a1777ced1e6253de8c29","cipherparams":{"iv":"c18772a882ac461fffd1971e9ec57861"},"cipher":"aes-128-ctr","kdf":"scrypt","kdfparams":{"salt":"da4efedeca407279be65e02fc94b7c4b7c74c3396447c71e659c74a73a5d9131","n":8192,"r":8,"p":1,"dklen":32},"mac":"547ee6616dcdf424273c113ceb00728ccdda17ff6449f2cb84a1a8352c87b4e6"}}'; |
||||
|
||||
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); |
@ -0,0 +1,14 @@ |
||||
{ |
||||
"name": "example", |
||||
"version": "1.0.0", |
||||
"description": "", |
||||
"main": "test.js", |
||||
"scripts": { |
||||
"test": "echo \"Error: no test specified\" && exit 1" |
||||
}, |
||||
"author": "", |
||||
"license": "ISC", |
||||
"dependencies": { |
||||
"@harmony-js/core": "^0.1.32" |
||||
} |
||||
} |
@ -0,0 +1,79 @@ |
||||
const { Harmony } = require('@harmony-js/core'); |
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
const { |
||||
StakingTransaction, |
||||
CreateValidator, |
||||
Delegate, |
||||
Undelegate, |
||||
CollectRewards, |
||||
StakingFactory, |
||||
} = require('@harmony-js/staking'); |
||||
|
||||
const harmony = new Harmony('http://localhost:9500', { |
||||
chainId: ChainID.HmyLocal, |
||||
chainType: ChainType.Harmony, |
||||
}); |
||||
|
||||
const stakingTxn = harmony.stakings |
||||
.createValidator({ |
||||
validatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9', |
||||
description: { |
||||
name: 'Alice', |
||||
identity: 'alice', |
||||
website: 'alice.harmony.one', |
||||
securityContact: 'Bob', |
||||
details: "Don't mess with me!!!", |
||||
}, |
||||
commissionRate: { |
||||
rate: '0.1', |
||||
maxRate: '0.9', |
||||
maxChangeRate: '0.05', |
||||
}, |
||||
minSelfDelegation: '0xa', |
||||
maxTotalDelegation: '0x0bb8', |
||||
slotPubKeys: [ |
||||
'0xb9486167ab9087ab818dc4ce026edb5bf216863364c32e42df2af03c5ced1ad181e7d12f0e6dd5307a73b62247608611', |
||||
], |
||||
amount: '0x64', |
||||
}) |
||||
.setTxParams({ |
||||
nonce: '0x2', |
||||
gasPrice: '0x', |
||||
gasLimit: '0x64', |
||||
chainId: 0, |
||||
}) |
||||
.build(); |
||||
|
||||
stakingTxn |
||||
.sendTransaction() |
||||
.then(([stakingTxn, res]) => { |
||||
console.log(res); |
||||
}) |
||||
.catch((err) => { |
||||
console.log(err); |
||||
}); |
||||
|
||||
// const delegateMsg = Delegate({
|
||||
// delegatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// validatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// amount: '0xa',
|
||||
// });
|
||||
|
||||
// const stakingTxn = StakingTransaction({
|
||||
// directive: '0x2',
|
||||
// stakeMsg: delegateMsg,
|
||||
// nonce: '0x2',
|
||||
// gasPrice: '0x',
|
||||
// gasLimit: '0x64',
|
||||
// chainId: 0,
|
||||
// from: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// });
|
||||
|
||||
// stakingTxn
|
||||
// .sendTransaction()
|
||||
// .then((stakingTxn, res) => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err);
|
||||
// });
|
@ -0,0 +1,172 @@ |
||||
const { Harmony } = require('@harmony-js/core'); |
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
const { Delegate, StakingTransaction, StakingFactory } = require('@harmony-js/staking'); //../packages/harmony-staking
|
||||
const { TxStatus } = require('@harmony-js/transaction'); |
||||
|
||||
const LOCALNET = `http://localhost:9500`; |
||||
|
||||
// 1. initialize the Harmony instance
|
||||
|
||||
const harmony = new Harmony( |
||||
// rpc url
|
||||
LOCALNET, |
||||
{ |
||||
// chainType set to Harmony
|
||||
chainType: ChainType.Harmony, |
||||
// chainType set to HmyLocal
|
||||
chainId: ChainID.HmyLocal, |
||||
}, |
||||
); |
||||
|
||||
// 2. get wallet ready
|
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
const private = '63e35b761e9df0d50ddcdaa8e33c235b60c991bfed22925a12768b0c08ef822f'; |
||||
// one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy
|
||||
const sender = harmony.wallet.addByPrivateKey(private); |
||||
console.log(sender.address); |
||||
// const phrase =
|
||||
// 'genius cable radar memory high catch blossom correct middle wish gentle
|
||||
// fiscal';
|
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
// const sender = harmony.wallet.addByMnemonic(phrase);
|
||||
// let r =
|
||||
// '0xf8f180f8a4940b585f8daefbc68a311fbd4cb20d9174ad174016f83885416c69636585616c69636591616c6963652e6861726d6f6e792e6f6e6583426f6295446f6e2774206d6573732077697468206d65212121ddc988016345785d8a0000c9880c7d713b49da0000c887b1a2bc2ec500000a820bb8f1b0b9486167ab9087ab818dc4ce026edb5bf216863364c32e42df2af03c5ced1ad181e7d12f0e6dd5307a73b6224760861164008080830927c028a064b1b835f5b70a72228920db24e44c0a57d954c1d3dcac3b33c79d9593f96191a05577fd05064a37043a33ff7febb67ab126a8e1f0b67c92b7cab793a87ddf2c82';
|
||||
|
||||
// const delegateMsg = new Delegate(
|
||||
// 'one1pf75h0t4am90z8uv3y0dgunfqp4lj8wr3t5rsp', // from delegate command.
|
||||
// 'one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy', // fd416cb87dcf8ed187e85545d7734a192fc8e976f5b540e9e21e896ec2bc25c3
|
||||
// '0xde0b6b3a7640000', // 0x56BC75E2D63100000
|
||||
// );
|
||||
|
||||
// // one12fuf7x9rgtdgqg7vgq0962c556m3p7afsxgvll;
|
||||
|
||||
// const stakingTxn = new StakingTransaction(
|
||||
// '0x2',
|
||||
// delegateMsg,
|
||||
// '0x2',
|
||||
// '0x',
|
||||
// '0x0927c0',
|
||||
// ChainID.HmyLocal,
|
||||
// );
|
||||
|
||||
const stakingTxn = harmony.stakings |
||||
.delegate({ |
||||
delegatorAddress: 'one1pf75h0t4am90z8uv3y0dgunfqp4lj8wr3t5rsp', |
||||
validatorAddress: 'one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy', |
||||
amount: '0xde0b6b3a7640000', |
||||
}) |
||||
.setTxParams({ nonce: '0x2', gasPrice: '0x', gasLimit: '0x0927c0', chainId: ChainID.HmyLocal }) |
||||
.build(); |
||||
|
||||
// 3. get sharding info
|
||||
async function setSharding() { |
||||
// Harmony is a sharded blockchain, each endpoint have sharding structure,
|
||||
// However sharding structure is different between mainnet, testnet and local
|
||||
// testnet We need to get sharding info before doing cross-shard transaction
|
||||
const res = await harmony.blockchain.getShardingStructure(); |
||||
harmony.shardingStructures(res.result); |
||||
} |
||||
|
||||
async function execute() { |
||||
await setSharding(); |
||||
|
||||
const signedTxn = await harmony.wallet.signStaking(stakingTxn); |
||||
signedTxn |
||||
.observed() |
||||
.on('transactionHash', (txnHash) => { |
||||
console.log(''); |
||||
console.log('--- hash ---'); |
||||
console.log(''); |
||||
console.log(txnHash); |
||||
console.log(''); |
||||
}) |
||||
.on('receipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- receipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('cxReceipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- cxReceipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('error', (error) => { |
||||
console.log(''); |
||||
console.log('--- error ---'); |
||||
console.log(''); |
||||
console.log(error); |
||||
console.log(''); |
||||
}); |
||||
|
||||
// console.log(signedTxn);
|
||||
|
||||
const [sentTxn, txnHash] = await signedTxn.sendTransaction(); |
||||
// signedTxn.sendTransaction()
|
||||
// .then(res => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// .catch(err => {
|
||||
// console.log(err);
|
||||
// });
|
||||
|
||||
// to confirm the result if it is already there
|
||||
// console.log(txnHash);
|
||||
console.log(sentTxn); |
||||
|
||||
const confiremdTxn = await sentTxn.confirm(txnHash); |
||||
|
||||
// if the transactino is cross-shard transaction
|
||||
if (confiremdTxn.isConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Normal transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
// if (confiremdTxn.isConfirmed() && confiremdTxn.isCxConfirmed()) {
|
||||
// console.log('--- Result ---');
|
||||
// console.log('');
|
||||
// console.log('Cross-Shard transaction');
|
||||
// console.log(`${txnHash} is confirmed`);
|
||||
// console.log('');
|
||||
// process.exit();
|
||||
// }
|
||||
} |
||||
execute(); |
||||
// const delegateMsg = Delegate({
|
||||
// delegatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// validatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// amount: '0xa',
|
||||
// });
|
||||
|
||||
// const stakingTxn = StakingTransaction({
|
||||
// directive: '0x2',
|
||||
// stakeMsg: delegateMsg,
|
||||
// nonce: '0x2',
|
||||
// gasPrice: '0x',
|
||||
// gasLimit: '0x64',
|
||||
// chainId: 0,
|
||||
// from: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// });
|
||||
|
||||
// stakingTxn
|
||||
// .sendTransaction()
|
||||
// .then((stakingTxn, res) => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err);
|
||||
// });
|
@ -0,0 +1,74 @@ |
||||
const { Harmony } = require('@harmony-js/core'); |
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
const { StakingFactory } = require('@harmony-js/staking'); |
||||
|
||||
const harmony = new Harmony('http://localhost:9500', { |
||||
chainId: ChainID.HmyLocal, |
||||
chainType: ChainType.Harmony, |
||||
}); |
||||
|
||||
const createMsg = { |
||||
validatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9', |
||||
description: { |
||||
name: 'Alice', |
||||
identity: 'alice', |
||||
website: 'alice.harmony.one', |
||||
securityContact: 'Bob', |
||||
details: "Don't mess with me!!!", |
||||
}, |
||||
commissionRate: { |
||||
rate: '0.1', |
||||
maxRate: '0.9', |
||||
maxChangeRate: '0.05', |
||||
}, |
||||
minSelfDelegation: '0xa', |
||||
maxTotalDelegation: '0x0bb8', |
||||
slotPubKeys: [ |
||||
'0xb9486167ab9087ab818dc4ce026edb5bf216863364c32e42df2af03c5ced1ad181e7d12f0e6dd5307a73b62247608611', |
||||
], |
||||
amount: '0x64', |
||||
}; |
||||
|
||||
const stakingTxn = harmony.stakings |
||||
.createValidator(createMsg) |
||||
.setTxParams({ |
||||
nonce: '0x2', |
||||
gasPrice: '0x', |
||||
gasLimit: '0x64', |
||||
chainId: 0, |
||||
}) |
||||
.build(); |
||||
|
||||
stakingTxn |
||||
.sendTransaction() |
||||
.then(([stakingTxn, res]) => { |
||||
console.log(res); |
||||
}) |
||||
.catch((err) => { |
||||
console.log(err); |
||||
}); |
||||
|
||||
// const delegateMsg = Delegate({
|
||||
// delegatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// validatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// amount: '0xa',
|
||||
// });
|
||||
|
||||
// const stakingTxn = StakingTransaction({
|
||||
// directive: '0x2',
|
||||
// stakeMsg: delegateMsg,
|
||||
// nonce: '0x2',
|
||||
// gasPrice: '0x',
|
||||
// gasLimit: '0x64',
|
||||
// chainId: 0,
|
||||
// from: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// });
|
||||
|
||||
// stakingTxn
|
||||
// .sendTransaction()
|
||||
// .then((stakingTxn, res) => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err);
|
||||
// });
|
@ -0,0 +1,177 @@ |
||||
const { Harmony } = require('@harmony-js/core'); |
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
const { |
||||
Description, |
||||
Decimal, |
||||
CommissionRate, |
||||
StakingTransaction, |
||||
CreateValidator, |
||||
} = require('@harmony-js/staking'); //../packages/harmony-staking
|
||||
const { TxStatus } = require('@harmony-js/transaction'); |
||||
|
||||
const LOCALNET = `http://localhost:9500`; |
||||
|
||||
// 1. initialize the Harmony instance
|
||||
|
||||
const harmony = new Harmony( |
||||
// rpc url
|
||||
LOCALNET, |
||||
{ |
||||
// chainType set to Harmony
|
||||
chainType: ChainType.Harmony, |
||||
// chainType set to HmyLocal
|
||||
chainId: ChainID.HmyLocal, |
||||
}, |
||||
); |
||||
|
||||
// 2. get wallet ready
|
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
const private = 'fd416cb87dcf8ed187e85545d7734a192fc8e976f5b540e9e21e896ec2bc25c3'; |
||||
const sender = harmony.wallet.addByPrivateKey(private); |
||||
// const phrase =
|
||||
// 'genius cable radar memory high catch blossom correct middle wish gentle
|
||||
// fiscal';
|
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
// const sender = harmony.wallet.addByMnemonic(phrase);
|
||||
|
||||
const stakingTxn = harmony.stakings |
||||
.createValidator({ |
||||
validatorAddress: 'one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy', |
||||
description: { |
||||
name: 'Alice', |
||||
identity: 'alice', |
||||
website: 'alice.harmony.one', |
||||
securityContact: 'Bob', |
||||
details: "Don't mess with me!!", |
||||
}, |
||||
commissionRate: { rate: '0.1', maxRate: '0.9', maxChangeRate: '0.05' }, |
||||
minSelfDelegation: '0x8AC7230489E80000', |
||||
maxTotalDelegation: '0xA2A15D09519BE00000', |
||||
slotPubKeys: [ |
||||
'0xb9486167ab9087ab818dc4ce026edb5bf216863364c32e42df2af03c5ced1ad181e7d12f0e6dd5307a73b62247608611', |
||||
], |
||||
amount: '0x56BC75E2D63100000', |
||||
}) |
||||
.setTxParams({ |
||||
nonce: '0x2', |
||||
gasPrice: '0x', |
||||
gasLimit: '0x0927c0', |
||||
chainId: ChainID.HmyLocal, |
||||
}) |
||||
.build(); |
||||
|
||||
// 3. get sharding info
|
||||
async function setSharding() { |
||||
// Harmony is a sharded blockchain, each endpoint have sharding structure,
|
||||
// However sharding structure is different between mainnet, testnet and local
|
||||
// testnet We need to get sharding info before doing cross-shard transaction
|
||||
const res = await harmony.blockchain.getShardingStructure(); |
||||
harmony.shardingStructures(res.result); |
||||
} |
||||
|
||||
async function execute() { |
||||
await setSharding(); |
||||
|
||||
const signedTxn = await harmony.wallet.signStaking(stakingTxn); |
||||
signedTxn |
||||
.observed() |
||||
.on('transactionHash', (txnHash) => { |
||||
console.log(''); |
||||
console.log('--- hash ---'); |
||||
console.log(''); |
||||
console.log(txnHash); |
||||
console.log(''); |
||||
}) |
||||
.on('receipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- receipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('cxReceipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- cxReceipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('error', (error) => { |
||||
console.log(''); |
||||
console.log('--- error ---'); |
||||
console.log(''); |
||||
console.log(error); |
||||
console.log(''); |
||||
}); |
||||
|
||||
// console.log(signedTxn);
|
||||
|
||||
const [sentTxn, txnHash] = await signedTxn.sendTransaction(); |
||||
// signedTxn
|
||||
// .sendTransaction()
|
||||
// .then((res) => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err);
|
||||
// });
|
||||
|
||||
// to confirm the result if it is already there
|
||||
console.log(txnHash); |
||||
console.log(sentTxn); |
||||
|
||||
const confiremdTxn = await sentTxn.confirm(txnHash); |
||||
|
||||
// if the transactino is cross-shard transaction
|
||||
// if (!confiremdTxn.isCrossShard()) {
|
||||
if (confiremdTxn.isConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Staking transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
// }
|
||||
// if (confiremdTxn.isConfirmed() && confiremdTxn.isCxConfirmed()) {
|
||||
// console.log('--- Result ---');
|
||||
// console.log('');
|
||||
// console.log('Cross-Shard transaction');
|
||||
// console.log(`${txnHash} is confirmed`);
|
||||
// console.log('');
|
||||
// process.exit();
|
||||
// }
|
||||
} |
||||
execute(); |
||||
// const delegateMsg = Delegate({
|
||||
// delegatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// validatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// amount: '0xa',
|
||||
// });
|
||||
|
||||
// const stakingTxn = StakingTransaction({
|
||||
// directive: '0x2',
|
||||
// stakeMsg: delegateMsg,
|
||||
// nonce: '0x2',
|
||||
// gasPrice: '0x',
|
||||
// gasLimit: '0x64',
|
||||
// chainId: 0,
|
||||
// from: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// });
|
||||
|
||||
// stakingTxn
|
||||
// .sendTransaction()
|
||||
// .then((stakingTxn, res) => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err);
|
||||
// });
|
@ -0,0 +1,173 @@ |
||||
const { Harmony } = require('@harmony-js/core'); |
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
const { Undelegate, StakingTransaction, StakingFactory } = require('@harmony-js/staking'); //../packages/harmony-staking
|
||||
const { TxStatus } = require('@harmony-js/transaction'); |
||||
|
||||
const LOCALNET = `http://localhost:9500`; |
||||
|
||||
// 1. initialize the Harmony instance
|
||||
|
||||
const harmony = new Harmony( |
||||
// rpc url
|
||||
LOCALNET, |
||||
{ |
||||
// chainType set to Harmony
|
||||
chainType: ChainType.Harmony, |
||||
// chainType set to HmyLocal
|
||||
chainId: ChainID.HmyLocal, |
||||
}, |
||||
); |
||||
|
||||
// 2. get wallet ready
|
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
const private = '63e35b761e9df0d50ddcdaa8e33c235b60c991bfed22925a12768b0c08ef822f'; |
||||
const sender = harmony.wallet.addByPrivateKey(private); |
||||
// const phrase =
|
||||
// 'genius cable radar memory high catch blossom correct middle wish gentle
|
||||
// fiscal';
|
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
// const sender = harmony.wallet.addByMnemonic(phrase);
|
||||
// let r =
|
||||
// '0xf8f180f8a4940b585f8daefbc68a311fbd4cb20d9174ad174016f83885416c69636585616c69636591616c6963652e6861726d6f6e792e6f6e6583426f6295446f6e2774206d6573732077697468206d65212121ddc988016345785d8a0000c9880c7d713b49da0000c887b1a2bc2ec500000a820bb8f1b0b9486167ab9087ab818dc4ce026edb5bf216863364c32e42df2af03c5ced1ad181e7d12f0e6dd5307a73b6224760861164008080830927c028a064b1b835f5b70a72228920db24e44c0a57d954c1d3dcac3b33c79d9593f96191a05577fd05064a37043a33ff7febb67ab126a8e1f0b67c92b7cab793a87ddf2c82';
|
||||
|
||||
// const undelegateMsg = new Undelegate(
|
||||
// 'one1pf75h0t4am90z8uv3y0dgunfqp4lj8wr3t5rsp', // signed should match this
|
||||
// 'one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy',
|
||||
// '0x16345785d8a0000',
|
||||
// );
|
||||
|
||||
// const stakingTxn = new StakingTransaction(
|
||||
// '0x3',
|
||||
// undelegateMsg,
|
||||
// '0x2',
|
||||
// '0x',
|
||||
// '0x0927c0',
|
||||
// ChainID.HmyLocal,
|
||||
// );
|
||||
|
||||
const stakingTxn = harmony.stakings |
||||
.undelegate({ |
||||
delegatorAddress: 'one1pf75h0t4am90z8uv3y0dgunfqp4lj8wr3t5rsp', |
||||
validatorAddress: 'one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy', |
||||
amount: '0x16345785d8a0000', |
||||
}) |
||||
.setTxParams({ |
||||
nonce: '0x2', |
||||
gasPrice: '0x', |
||||
gasLimit: '0x0927c0', |
||||
chainId: ChainID.HmyLocal, |
||||
}) |
||||
.build(); |
||||
|
||||
// 3. get sharding info
|
||||
async function setSharding() { |
||||
// Harmony is a sharded blockchain, each endpoint have sharding structure,
|
||||
// However sharding structure is different between mainnet, testnet and local
|
||||
// testnet We need to get sharding info before doing cross-shard transaction
|
||||
const res = await harmony.blockchain.getShardingStructure(); |
||||
harmony.shardingStructures(res.result); |
||||
} |
||||
|
||||
async function execute() { |
||||
await setSharding(); |
||||
|
||||
const signedTxn = await harmony.wallet.signStaking(stakingTxn); |
||||
signedTxn |
||||
.observed() |
||||
.on('transactionHash', (txnHash) => { |
||||
console.log(''); |
||||
console.log('--- hash ---'); |
||||
console.log(''); |
||||
console.log(txnHash); |
||||
console.log(''); |
||||
}) |
||||
.on('receipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- receipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('cxReceipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- cxReceipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('error', (error) => { |
||||
console.log(''); |
||||
console.log('--- error ---'); |
||||
console.log(''); |
||||
console.log(error); |
||||
console.log(''); |
||||
}); |
||||
|
||||
// console.log(signedTxn);
|
||||
|
||||
const [sentTxn, txnHash] = await signedTxn.sendTransaction(); |
||||
// signedTxn.sendTransaction()
|
||||
// .then(res => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// .catch(err => {
|
||||
// console.log(err);
|
||||
// });
|
||||
|
||||
// to confirm the result if it is already there
|
||||
// console.log(txnHash);
|
||||
console.log(sentTxn); |
||||
|
||||
const confiremdTxn = await sentTxn.confirm(txnHash); |
||||
|
||||
// if the transactino is cross-shard transaction
|
||||
if (confiremdTxn.isConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Normal transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
// if (confiremdTxn.isConfirmed() && confiremdTxn.isCxConfirmed()) {
|
||||
// console.log('--- Result ---');
|
||||
// console.log('');
|
||||
// console.log('Cross-Shard transaction');
|
||||
// console.log(`${txnHash} is confirmed`);
|
||||
// console.log('');
|
||||
// process.exit();
|
||||
// }
|
||||
} |
||||
execute(); |
||||
// const delegateMsg = Delegate({
|
||||
// delegatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// validatorAddress: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// amount: '0xa',
|
||||
// });
|
||||
|
||||
// const stakingTxn = StakingTransaction({
|
||||
// directive: '0x2',
|
||||
// stakeMsg: delegateMsg,
|
||||
// nonce: '0x2',
|
||||
// gasPrice: '0x',
|
||||
// gasLimit: '0x64',
|
||||
// chainId: 0,
|
||||
// from: 'one1a0x3d6xpmr6f8wsyaxd9v36pytvp48zckswvv9',
|
||||
// });
|
||||
|
||||
// stakingTxn
|
||||
// .sendTransaction()
|
||||
// .then((stakingTxn, res) => {
|
||||
// console.log(res);
|
||||
// })
|
||||
// .catch((err) => {
|
||||
// console.log(err);
|
||||
// });
|
@ -0,0 +1,31 @@ |
||||
const { Harmony } = require('@harmony-js/core'); |
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
const { encryptPhrase, decryptPhrase } = require('@harmony-js/crypto'); |
||||
|
||||
const harmony = new Harmony('http://localhost:9500', { chainId: 2, chainType: 'hmy' }); |
||||
const myPhrase = harmony.wallet.newMnemonic(); |
||||
const pwd = '1234'; |
||||
|
||||
async function encryptThePhrase(phrase, pass) { |
||||
const result = await encryptPhrase(phrase, pass); |
||||
return result; |
||||
} |
||||
|
||||
async function decryptThePhrase(keystore, pass) { |
||||
const result = await decryptPhrase(keystore, pass); |
||||
return result; |
||||
} |
||||
|
||||
async function phraseKeyStore() { |
||||
const keyStore = await encryptThePhrase(myPhrase, pwd); |
||||
const recoveredPhrase = await decryptThePhrase(JSON.parse(keyStore), pwd); |
||||
return { myPhrase, keyStore, recoveredPhrase }; |
||||
} |
||||
|
||||
phraseKeyStore().then((result) => { |
||||
const { myPhrase, keyStore, recoveredPhrase } = result; |
||||
|
||||
harmony.wallet.addByMnemonic(myPhrase); |
||||
console.log({ myPhrase, keyStore, recoveredPhrase }); |
||||
console.log(harmony.wallet); |
||||
}); |
@ -0,0 +1,40 @@ |
||||
const { Harmony } = require('@harmony-js/core'); |
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
const { |
||||
randomBytes, |
||||
generatePrivateKey, |
||||
getAddress, |
||||
getAddressFromPrivateKey, |
||||
encryptPhrase, |
||||
decryptPhrase, |
||||
} = require('@harmony-js/crypto'); |
||||
|
||||
const harmony = new Harmony('http://localhost:9500', { chainId: 2, chainType: 'hmy' }); |
||||
const myPhrase = harmony.wallet.newMnemonic(); |
||||
const pwd = '1234'; |
||||
|
||||
async function encryptThePhrase(phrase, pass) { |
||||
const result = await encryptPhrase(phrase, pass); |
||||
return result; |
||||
} |
||||
|
||||
async function decryptThePhrase(keystore, pass) { |
||||
const result = await decryptPhrase(keystore, pass); |
||||
return result; |
||||
} |
||||
|
||||
async function phraseKeyStore() { |
||||
const keyStore = await encryptThePhrase(myPhrase, pwd); |
||||
const recoveredPhrase = await decryptThePhrase(JSON.parse(keyStore), pwd); |
||||
return { myPhrase, keyStore, recoveredPhrase }; |
||||
} |
||||
|
||||
phraseKeyStore().then((result) => { |
||||
const { myPhrase, keyStore, recoveredPhrase } = result; |
||||
|
||||
const anotherPhrase = 'wall public vague under poem acid jaguar describe net scene sponsor neck'; |
||||
harmony.wallet.addByMnemonic(myPhrase); |
||||
harmony.wallet.addByMnemonic(anotherPhrase); |
||||
console.log({ myPhrase, keyStore, recoveredPhrase }); |
||||
console.log(harmony.wallet); |
||||
}); |
@ -0,0 +1,153 @@ |
||||
// import or require Harmony class
|
||||
const { Harmony } = require('@harmony-js/core'); |
||||
|
||||
// import or require settings
|
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
|
||||
const URL_TESTNET = `https://api.s0.b.hmny.io`; |
||||
const URL_MAINNET = `https://api.s0.t.hmny.io`; |
||||
const URL_PANGAEA = 'https://api.s0.pga.hmny.io'; |
||||
|
||||
// 1. initialize the Harmony instance
|
||||
|
||||
const harmony = new Harmony( |
||||
// rpc url
|
||||
URL_PANGAEA, |
||||
{ |
||||
// chainType set to Harmony
|
||||
chainType: ChainType.Harmony, |
||||
// chainType set to HmyLocal
|
||||
chainId: ChainID.HmyPangaea, |
||||
}, |
||||
); |
||||
|
||||
// 2. get wallet ready
|
||||
// one18n8e7472pg5fqvcfcr5hg0npquha24wsxmjheg
|
||||
const phrase = 'genius cable radar memory high catch blossom correct middle wish gentle fiscal'; |
||||
// const phrase =
|
||||
// 'resemble rent deposit unique garment ripple burst negative else decorate menu theme';
|
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
|
||||
const privateKey = '63e35b761e9df0d50ddcdaa8e33c235b60c991bfed22925a12768b0c08ef822f'; |
||||
|
||||
const sender = harmony.wallet.addByMnemonic(phrase); |
||||
const sender2 = harmony.wallet.addByPrivateKey(privateKey); |
||||
|
||||
harmony.wallet.setSigner(sender2.address); |
||||
|
||||
console.log('sender2Address is : ', sender2.bech32Address); |
||||
|
||||
// 3. get sharding info
|
||||
async function setSharding() { |
||||
// Harmony is a sharded blockchain, each endpoint have sharding structure,
|
||||
// However sharding structure is different between mainnet, testnet and local testnet
|
||||
// We need to get sharding info before doing cross-shard transaction
|
||||
const res = await harmony.blockchain.getShardingStructure(); |
||||
|
||||
harmony.shardingStructures(res.result); |
||||
} |
||||
|
||||
// 4. get transaction payload ready
|
||||
|
||||
async function transfer(receiver) { |
||||
// run set sharding first, if you want to make a cross-shard transaction
|
||||
await setSharding(); |
||||
|
||||
//1e18
|
||||
const txn = harmony.transactions.newTx({ |
||||
// token send to
|
||||
to: receiver, |
||||
// amount to send
|
||||
value: '100000000', |
||||
// gas limit, you can use string
|
||||
gasLimit: '210000', |
||||
// send token from shardID
|
||||
shardID: 0, |
||||
// send token to toShardID
|
||||
toShardID: 1, |
||||
// gas Price, you can use Unit class, and use Gwei, then remember to use toWei(), which will be transformed to BN
|
||||
gasPrice: new harmony.utils.Unit('10').asGwei().toWei(), |
||||
}); |
||||
|
||||
// sign the transaction use wallet;
|
||||
|
||||
// This will happen at the chrome extension.
|
||||
const signedTxn = await harmony.wallet.signTransaction(txn); |
||||
|
||||
// Now you can use `Transaction.observed()` to listen events
|
||||
|
||||
// Frontend received back the signedTxn and do the followings to Send transaction.
|
||||
signedTxn |
||||
.observed() |
||||
.on('transactionHash', (txnHash) => { |
||||
console.log(''); |
||||
console.log('--- hash ---'); |
||||
console.log(''); |
||||
console.log(txnHash); |
||||
console.log(''); |
||||
}) |
||||
.on('receipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- receipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('cxReceipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- cxReceipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('error', (error) => { |
||||
console.log(''); |
||||
console.log('--- error ---'); |
||||
console.log(''); |
||||
console.log(error); |
||||
console.log(''); |
||||
}); |
||||
|
||||
// send the txn, get [Transaction, transactionHash] as result
|
||||
|
||||
const [sentTxn, txnHash] = await signedTxn.sendTransaction(); |
||||
|
||||
// to confirm the result if it is already there
|
||||
|
||||
const confiremdTxn = await sentTxn.confirm(txnHash); |
||||
|
||||
// if the transactino is cross-shard transaction
|
||||
if (!confiremdTxn.isCrossShard()) { |
||||
if (confiremdTxn.isConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Normal transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
console.log('please see detail in explorer:'); |
||||
console.log(''); |
||||
console.log('https://explorer.harmony.one/#/tx/' + txnHash); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
} |
||||
if (confiremdTxn.isConfirmed() && confiremdTxn.isCxConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Cross-Shard transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
console.log('please see detail in explorer:'); |
||||
console.log(''); |
||||
console.log('https://explorer.harmony.one/#/tx/' + txnHash); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
} |
||||
|
||||
// sending from one18n8e7472pg5fqvcfcr5hg0npquha24wsxmjheg to one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
(async () => await transfer('one1pf75h0t4am90z8uv3y0dgunfqp4lj8wr3t5rsp'))(); |
@ -0,0 +1,151 @@ |
||||
// import or require Harmony class
|
||||
const { Harmony } = require('@harmony-js/core'); |
||||
|
||||
// import or require settings
|
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
|
||||
// const URL_TESTNET = `https://api.s0.pga.hmny.io`;
|
||||
const URL_MAINNET = `https://api.s0.t.hmny.io`; |
||||
// const LOCAL_TESTNET = `http://localhost:9500`;
|
||||
const DEVNET = 'https://api.s0.pga.hmny.io'; |
||||
// 1. initialize the Harmony instance
|
||||
|
||||
const harmony = new Harmony( |
||||
// rpc url
|
||||
DEVNET, |
||||
{ |
||||
// chainType set to Harmony
|
||||
chainType: ChainType.Harmony, |
||||
// chainType set to HmyLocal
|
||||
chainId: ChainID.HmyPangaea, |
||||
}, |
||||
); |
||||
|
||||
// 2. get wallet ready
|
||||
// one18n8e7472pg5fqvcfcr5hg0npquha24wsxmjheg;
|
||||
const phrase = 'genius cable radar memory high catch blossom correct middle wish gentle fiscal'; |
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
// const sender = harmony.wallet.addByMnemonic(phrase);
|
||||
|
||||
// add privateKey to wallet
|
||||
const private = '63e35b761e9df0d50ddcdaa8e33c235b60c991bfed22925a12768b0c08ef822f'; |
||||
// one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy
|
||||
const sender = harmony.wallet.addByPrivateKey(private); |
||||
|
||||
// const sender = harmony.wallet.addByPrivateKey(
|
||||
// 'fd416cb87dcf8ed187e85545d7734a192fc8e976f5b540e9e21e896ec2bc25c3',
|
||||
// );
|
||||
|
||||
// 3. get sharding info
|
||||
async function setSharding() { |
||||
// Harmony is a sharded blockchain, each endpoint have sharding structure,
|
||||
// However sharding structure is different between mainnet, testnet and local testnet
|
||||
// We need to get sharding info before doing cross-shard transaction
|
||||
const res = await harmony.blockchain.getShardingStructure(); |
||||
harmony.shardingStructures(res.result); |
||||
} |
||||
|
||||
// 4. get transaction payload ready
|
||||
|
||||
async function transfer(receiver) { |
||||
// run set sharding first, if you want to make a cross-shard transaction
|
||||
await setSharding(); |
||||
|
||||
//1e18
|
||||
const txn = harmony.transactions.newTx({ |
||||
// token send to
|
||||
to: receiver, |
||||
// amount to send
|
||||
value: '100000000000000000', |
||||
// gas limit, you can use string
|
||||
gasLimit: '210000', |
||||
// send token from shardID
|
||||
shardID: 0, |
||||
// send token to toShardID
|
||||
toShardID: 0, |
||||
// gas Price, you can use Unit class, and use Gwei, then remember to use toWei(), which will be transformed to BN
|
||||
gasPrice: new harmony.utils.Unit('100').asGwei().toWei(), |
||||
}); |
||||
|
||||
// sign the transaction use wallet;
|
||||
|
||||
// This will happen at the chrome extension.
|
||||
const signedTxn = await harmony.wallet.signTransaction(txn); |
||||
|
||||
// Now you can use `Transaction.observed()` to listen events
|
||||
|
||||
// Frontend received back the signedTxn and do the followings to Send transaction.
|
||||
signedTxn |
||||
.observed() |
||||
.on('transactionHash', (txnHash) => { |
||||
console.log(''); |
||||
console.log('--- hash ---'); |
||||
console.log(''); |
||||
console.log(txnHash); |
||||
console.log(''); |
||||
}) |
||||
.on('receipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- receipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('cxReceipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- cxReceipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('error', (error) => { |
||||
console.log(''); |
||||
console.log('--- error ---'); |
||||
console.log(''); |
||||
console.log(error); |
||||
console.log(''); |
||||
}); |
||||
|
||||
// send the txn, get [Transaction, transactionHash] as result
|
||||
|
||||
const [sentTxn, txnHash] = await signedTxn.sendTransaction(); |
||||
|
||||
// to confirm the result if it is already there
|
||||
|
||||
const confiremdTxn = await sentTxn.confirm(txnHash); |
||||
|
||||
// if the transactino is cross-shard transaction
|
||||
// if (!confiremdTxn.isCrossShard()) {
|
||||
if (confiremdTxn.isConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Normal transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
console.log('please see detail in explorer:'); |
||||
console.log(''); |
||||
console.log('https://explorer.harmony.one/#/tx/' + txnHash); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
// }
|
||||
if (confiremdTxn.isConfirmed() && confiremdTxn.isCxConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Cross-Shard transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
console.log('please see detail in explorer:'); |
||||
console.log(''); |
||||
console.log('https://explorer.harmony.one/#/tx/' + txnHash); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
} |
||||
|
||||
// sending from one18n8e7472pg5fqvcfcr5hg0npquha24wsxmjheg to one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
(async () => await transfer('one1pdv9lrdwl0rg5vglh4xtyrv3wjk3wsqket7zxy'))(); |
@ -0,0 +1,137 @@ |
||||
// import or require Harmony class
|
||||
const { Harmony } = require('@harmony-js/core'); |
||||
|
||||
// import or require settings
|
||||
const { ChainID, ChainType } = require('@harmony-js/utils'); |
||||
|
||||
//const URL_TESTNET = `https://api.s0.b.hmny.io`;
|
||||
const URL_TESTNET = `localhost:9500`; |
||||
const URL_MAINNET = `https://api.s0.t.hmny.io`; |
||||
|
||||
// 1. initialize the Harmony instance
|
||||
|
||||
const harmony = new Harmony( |
||||
// rpc url
|
||||
URL_TESTNET, |
||||
{ |
||||
// chainType set to Harmony
|
||||
chainType: ChainType.Harmony, |
||||
// chainType set to HmyLocal
|
||||
chainId: ChainID.HmyTestnet, |
||||
}, |
||||
); |
||||
|
||||
// 2. get wallet ready
|
||||
// one18n8e7472pg5fqvcfcr5hg0npquha24wsxmjheg
|
||||
//const phrase = 'genius cable radar memory high catch blossom correct middle wish gentle fiscal';
|
||||
|
||||
// one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
// surge welcome lion goose gate consider taste injury health march debris kick
|
||||
|
||||
// add privateKey to wallet
|
||||
//const sender = harmony.wallet.addByMnemonic(phrase);
|
||||
// add privateKey to wallet
|
||||
const private = 'fd416cb87dcf8ed187e85545d7734a192fc8e976f5b540e9e21e896ec2bc25c3'; |
||||
const sender = harmony.wallet.addByPrivateKey(private); |
||||
|
||||
// 3. get sharding info
|
||||
async function setSharding() { |
||||
// Harmony is a sharded blockchain, each endpoint have sharding structure,
|
||||
// However sharding structure is different between mainnet, testnet and local testnet
|
||||
// We need to get sharding info before doing cross-shard transaction
|
||||
const res = await harmony.blockchain.getShardingStructure(); |
||||
harmony.shardingStructures(res.result); |
||||
} |
||||
|
||||
// 4. get transaction payload ready
|
||||
|
||||
async function transfer(receiver) { |
||||
// run set sharding first, if you want to make a cross-shard transaction
|
||||
await setSharding(); |
||||
|
||||
//1e18
|
||||
const txn = harmony.transactions.newTx({ |
||||
// token send to
|
||||
to: receiver, |
||||
// amount to send
|
||||
value: '100000000000000000', |
||||
// gas limit, you can use string
|
||||
gasLimit: '210000', |
||||
// send token from shardID
|
||||
shardID: 0, |
||||
// send token to toShardID
|
||||
toShardID: 0, |
||||
// gas Price, you can use Unit class, and use Gwei, then remember to use toWei(), which will be transformed to BN
|
||||
gasPrice: new harmony.utils.Unit('100').asGwei().toWei(), |
||||
}); |
||||
|
||||
// sign the transaction use wallet;
|
||||
|
||||
// This will happen at the chrome extension.
|
||||
const signedTxn = await harmony.wallet.signTransaction(txn); |
||||
|
||||
// Now you can use `Transaction.observed()` to listen events
|
||||
|
||||
// Frontend received back the signedTxn and do the followings to Send transaction.
|
||||
signedTxn |
||||
.observed() |
||||
.on('transactionHash', (txnHash) => { |
||||
console.log(''); |
||||
console.log('--- hash ---'); |
||||
console.log(''); |
||||
console.log(txnHash); |
||||
console.log(''); |
||||
}) |
||||
.on('receipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- receipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('cxReceipt', (receipt) => { |
||||
console.log(''); |
||||
console.log('--- cxReceipt ---'); |
||||
console.log(''); |
||||
console.log(receipt); |
||||
console.log(''); |
||||
}) |
||||
.on('error', (error) => { |
||||
console.log(''); |
||||
console.log('--- error ---'); |
||||
console.log(''); |
||||
console.log(error); |
||||
console.log(''); |
||||
}); |
||||
|
||||
// send the txn, get [Transaction, transactionHash] as result
|
||||
|
||||
const [sentTxn, txnHash] = await signedTxn.sendTransaction(); |
||||
|
||||
// to confirm the result if it is already there
|
||||
|
||||
const confiremdTxn = await sentTxn.confirm(txnHash); |
||||
|
||||
// if the transactino is cross-shard transaction
|
||||
if (!confiremdTxn.isCrossShard()) { |
||||
if (confiremdTxn.isConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Normal transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
} |
||||
if (confiremdTxn.isConfirmed() && confiremdTxn.isCxConfirmed()) { |
||||
console.log('--- Result ---'); |
||||
console.log(''); |
||||
console.log('Cross-Shard transaction'); |
||||
console.log(`${txnHash} is confirmed`); |
||||
console.log(''); |
||||
process.exit(); |
||||
} |
||||
} |
||||
|
||||
// sending from one18n8e7472pg5fqvcfcr5hg0npquha24wsxmjheg to one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65
|
||||
transfer('one1a2rhuaqjcvfu69met9sque2l3w5v9z6qcdcz65'); |
File diff suppressed because it is too large
Load Diff
@ -1,12 +0,0 @@ |
||||
# Packages available are: |
||||
|
||||
1. [@woop-js/core](https://github.com/woop-chain/sdk/tree/master/packages/woop-core) |
||||
2. [@woop-js/account](https://github.com/woop-chain/sdk/tree/master/packages/woop-account) |
||||
3. [@woop-js/crypto](https://github.com/woop-chain/sdk/tree/master/packages/woop-crypto) |
||||
4. [@woop-js/network](https://github.com/woop-chain/sdk/tree/master/packages/woop-network) |
||||
5. [@woop-js/utils](https://github.com/woop-chain/sdk/tree/master/packages/woop-utils) |
||||
6. [@woop-js/transaction](https://github.com/woop-chain/sdk/tree/master/packages/woop-transaction) |
||||
7. [@woop-js/contract](https://github.com/woop-chain/sdk/tree/master/packages/woop-contract) |
||||
8. [@woop-js/staking](https://github.com/woop-chain/sdk/tree/master/packages/woop-staking) |
||||
|
||||
<mark>Package level documentation and examples are inside each package</mark> |
@ -0,0 +1,259 @@ |
||||
|
||||
1. [About This Package](#about-this-package) |
||||
2. [Usage of Account](#usage-of-account) |
||||
1. [Dependencies](#dependencies) |
||||
2. [Examples](#examples) |
||||
1. [Create a random account](#create-a-random-account) |
||||
2. [Import an existing privateKey to create Account](#import-an-existing-privatekey-to-create-account) |
||||
3. [Encrypt/Export keyStore file, Decrypt/Import keyStore file](#encryptexport-keystore-file-decryptimport-keystore-file) |
||||
4. [Address format getter](#address-format-getter) |
||||
5. [Sign a transaction](#sign-a-transaction) |
||||
3. [Usage of Wallet](#usage-of-wallet) |
||||
1. [Dependencies](#dependencies-1) |
||||
|
||||
# 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) |
||||
|
||||
``` |
||||
|
||||
|
||||
### Sign a transaction |
||||
|
||||
```typescript |
||||
|
||||
// import the Account class |
||||
import {Account} from '@harmony-js/account' |
||||
|
||||
// import Transaction class from '@harmony-js/transaction' |
||||
import {Transaction} from '@harmony-js/transaction' |
||||
|
||||
// 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, Unit } 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 |
||||
) |
||||
// suppose we have an account |
||||
const myPrivateKey = '0xe19d05c5452598e24caad4a0d85a49146f7be089515c905ae6a19e8a578a6930' |
||||
const myAccountWithMyPrivateKey = new Account(myPrivateKey) |
||||
|
||||
|
||||
const txnObject = { |
||||
// token send to |
||||
to: 'one166axnkjmghkf3df7xfvd0hn4dft8kemrza4cd2', |
||||
// amount to send |
||||
value: '1000000000000000000000', |
||||
// gas limit, you can use string or use BN value |
||||
gasLimit: '210000', |
||||
// send token from shardID |
||||
shardID: 0, |
||||
// send token to toShardID |
||||
toShardID: 0, |
||||
// gas Price, you can use Unit class, and use Gwei, then remember to use toWei(), which will be transformed to BN |
||||
gasPrice: new Unit('100').asGwei().toWei(), |
||||
// if you set nonce manually here, and remember, the `updateNonce` of `Account.signTransaction` should be set to false |
||||
nonce: 0, |
||||
}; |
||||
|
||||
const txn = new Transaction(txnObject, customMessenger); |
||||
|
||||
async function signTheTxn() { |
||||
// Account.signTransaction(transaction: Transaction, updateNonce?: boolean, encodeMode?: string, blockNumber?: string): Promise<Transaction> |
||||
// If the 2nd parameter `updateNonce` is set to true, it will query and update account's nonce before it signs |
||||
const signedTxn = await myAccountWithMyPrivateKey.signTransaction(txn, false, 'rlp', 'latest'); |
||||
|
||||
// see if the transaction is signed |
||||
console.log(`\n see if transaction is signed: \n ${signedTxn.isSigned()} \n`); |
||||
|
||||
// get the tranaction bytes |
||||
console.log(`\n the signed bytes is: \n ${signedTxn.getRawTransaction()} \n`); |
||||
|
||||
return signTheTxn; |
||||
} |
||||
|
||||
signTheTxn(); |
||||
``` |
||||
|
||||
|
||||
# Usage of Wallet |
||||
|
||||
## Dependencies |
||||
* "@harmony-js/crypto", |
||||
* "@harmony-js/network", |
||||
* "@harmony-js/staking", |
||||
* "@harmony-js/transaction", |
||||
* "@harmony-js/utils" |
||||
|
||||
```typescript |
||||
|
||||
import {Wallet} from '@harmony-js/account' |
||||
|
||||
const wallet=new Wallet() |
||||
|
||||
``` |
||||
|
||||
|
||||
|
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-account |
||||
* @ignore |
||||
*/ |
||||
|
||||
export * from './account'; |
||||
export * from './wallet'; |
||||
export * from './types'; |
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-account |
||||
* @hidden |
||||
*/ |
||||
|
||||
/** |
||||
* test type docs |
||||
*/ |
@ -0,0 +1,8 @@ |
||||
import { HttpProvider, Messenger } from '@harmony-js/network'; |
||||
import { ChainType, ChainID } from '@harmony-js/utils'; |
||||
|
||||
export const defaultMessenger = new Messenger( |
||||
new HttpProvider('http://localhost:9500'), |
||||
ChainType.Harmony, |
||||
ChainID.HmyLocal, |
||||
); |
@ -0,0 +1,15 @@ |
||||
{ |
||||
"extends": "../../tsconfig.base.json", |
||||
"compilerOptions": { |
||||
"rootDir": "src", |
||||
"outDir": "dist" |
||||
}, |
||||
"include": ["src", "../../typings/**/*.d.ts"], |
||||
"references": [ |
||||
{ "path": "../harmony-crypto" }, |
||||
{ "path": "../harmony-utils" }, |
||||
{ "path": "../harmony-transaction" }, |
||||
{ "path": "../harmony-staking" }, |
||||
{ "path": "../harmony-network" } |
||||
] |
||||
} |
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-contract |
||||
* @hidden |
||||
*/ |
||||
|
||||
import { AbiCoderClass } from './api'; |
||||
import { AbiCoder as EtherCoder } from './abiCoder'; |
||||
|
@ -1,9 +1,4 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-contract |
||||
*/ |
||||
|
||||
import { Wallet } from '@woop-js/account'; |
||||
import { Wallet } from '@harmony-js/account'; |
||||
import { Contract } from './contract'; |
||||
import { ContractOptions } from './utils/options'; |
||||
|
@ -1,9 +1,4 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-contract |
||||
*/ |
||||
|
||||
import { LogSub } from '@woop-js/network'; |
||||
import { LogSub } from '@harmony-js/network'; |
||||
import { AbiItemModel } from '../models/types'; |
||||
import { Contract } from '../contract'; |
||||
import { decode as eventLogDecoder } from '../utils/decoder'; |
@ -0,0 +1,10 @@ |
||||
export * from './abi/index'; |
||||
export { |
||||
toUtf8Bytes, |
||||
toUtf8String, |
||||
formatBytes32String, |
||||
parseBytes32String, |
||||
} from './abi/abiCoder'; |
||||
|
||||
export { Contract } from './contract'; |
||||
export { ContractFactory } from './contractFactory'; |
@ -1,10 +1,4 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-contract |
||||
* @hidden |
||||
*/ |
||||
|
||||
import { isArray } from '@woop-js/utils'; |
||||
import { isArray } from '@harmony-js/utils'; |
||||
import { AbiItemModel, AbiOutput, AbiInput } from './types'; |
||||
|
||||
export class AbiItem { |
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-contract |
||||
* @hidden |
||||
*/ |
||||
|
||||
// defined by web3.js
|
||||
// fixed
|
||||
export interface AbiModel { |
@ -1,13 +1,11 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-contract |
||||
* @hidden |
||||
*/ |
||||
|
||||
import { AbiItemModel } from '../models/types'; |
||||
import { AbiCoderClass } from '../abi/api'; |
||||
|
||||
export const decode = (abiCoder: AbiCoderClass, abiItemModel: AbiItemModel, response: any) => { |
||||
export const decode = ( |
||||
abiCoder: AbiCoderClass, |
||||
abiItemModel: AbiItemModel, |
||||
response: any, |
||||
) => { |
||||
let argumentTopics = response.topics; |
||||
|
||||
if (!abiItemModel.anonymous) { |
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-contract |
||||
* @hidden |
||||
*/ |
||||
|
||||
export interface ContractOptions { |
||||
data?: string; |
||||
shardID?: number; |
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-contract |
||||
* @hidden |
||||
*/ |
||||
|
||||
export enum ContractStatus { |
||||
INITIALISED = 'initialised', |
||||
TESTED = 'tested', |
@ -1,11 +1,6 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @ignore |
||||
*/ |
||||
|
||||
import { AbiCoder } from '../src/abi/abiCoder'; |
||||
import { BN } from '@woop-js/crypto'; |
||||
import { isArray } from '@woop-js/utils'; |
||||
import { BN } from '@harmony-js/crypto'; |
||||
import { isArray } from '@harmony-js/utils'; |
||||
import { abis } from './fixtures/abiv2'; |
||||
|
||||
function getValues(object: any, format?: any, named?: any): any { |
File diff suppressed because one or more lines are too long
@ -0,0 +1,526 @@ |
||||
import { |
||||
RPCMethod, |
||||
Messenger, |
||||
ResponseMiddleware, |
||||
WSProvider, |
||||
NewPendingTransactions, |
||||
NewHeaders, |
||||
LogSub, |
||||
Syncing, |
||||
} from '@harmony-js/network'; |
||||
|
||||
import { |
||||
assertObject, |
||||
AssertType, |
||||
// HarmonyCore,
|
||||
DefaultBlockParams, |
||||
} from '@harmony-js/utils'; |
||||
|
||||
import { getAddress } from '@harmony-js/crypto'; |
||||
|
||||
import { Transaction } from '@harmony-js/transaction'; |
||||
import { StakingTransaction } from '@harmony-js/staking'; |
||||
|
||||
class Blockchain { |
||||
messenger: Messenger; |
||||
|
||||
constructor(messenger: Messenger) { |
||||
this.messenger = messenger; |
||||
} |
||||
setMessenger(messenger: Messenger) { |
||||
this.messenger = messenger; |
||||
} |
||||
getRpcResult(result: any) { |
||||
if (result instanceof ResponseMiddleware) { |
||||
return result.getRaw; |
||||
} else { |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
@assertObject({ |
||||
address: ['isValidAddress', AssertType.required], |
||||
blockNumber: ['isBlockNumber', AssertType.optional], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getBalance({ |
||||
address, |
||||
blockNumber = DefaultBlockParams.latest, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
address: string; |
||||
blockNumber?: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetBalance, |
||||
[getAddress(address).checksum, blockNumber], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
async getBlockNumber(shardID: number = this.messenger.currentShard) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.BlockNumber, |
||||
[], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
/** |
||||
* |
||||
*/ |
||||
@assertObject({ |
||||
blockHash: ['isHash', AssertType.required], |
||||
returnObject: ['isBoolean', AssertType.optional], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getBlockByHash({ |
||||
blockHash, |
||||
returnObject = true, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
blockHash: string; |
||||
returnObject?: boolean; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetBlockByHash, |
||||
[blockHash, returnObject], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
@assertObject({ |
||||
blockNumber: ['isBlockNumber', AssertType.optional], |
||||
returnObject: ['isBoolean', AssertType.optional], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getBlockByNumber({ |
||||
blockNumber = DefaultBlockParams.latest, |
||||
returnObject = true, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
blockNumber?: string; |
||||
returnObject?: boolean; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetBlockByNumber, |
||||
[blockNumber, returnObject], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
@assertObject({ |
||||
blockHash: ['isHash', AssertType.required], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getBlockTransactionCountByHash({ |
||||
blockHash, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
blockHash: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetBlockTransactionCountByHash, |
||||
[blockHash], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
@assertObject({ |
||||
blockNumber: ['isBlockNumber', AssertType.required], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getBlockTransactionCountByNumber({ |
||||
blockNumber, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
blockNumber: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetBlockTransactionCountByNumber, |
||||
[blockNumber], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
@assertObject({ |
||||
blockHash: ['isHash', AssertType.required], |
||||
index: ['isHex', AssertType.required], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getTransactionByBlockHashAndIndex({ |
||||
blockHash, |
||||
index, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
blockHash: string; |
||||
index: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetTransactionByBlockHashAndIndex, |
||||
[blockHash, index], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
@assertObject({ |
||||
blockNumber: ['isBlockNumber', AssertType.optional], |
||||
index: ['isHex', AssertType.required], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getTransactionByBlockNumberAndIndex({ |
||||
blockNumber = DefaultBlockParams.latest, |
||||
index, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
blockNumber?: string; |
||||
index: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetTransactionByBlockNumberAndIndex, |
||||
[blockNumber, index], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
@assertObject({ |
||||
txnHash: ['isHash', AssertType.required], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getTransactionByHash({ |
||||
txnHash, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
txnHash: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetTransactionByHash, |
||||
[txnHash], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
/** |
||||
* |
||||
*/ |
||||
@assertObject({ |
||||
txnHash: ['isString', AssertType.required], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getTransactionReceipt({ |
||||
txnHash, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
txnHash: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetTransactionReceipt, |
||||
[txnHash], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
@assertObject({ |
||||
txnHash: ['isString', AssertType.required], |
||||
shardID: ['isNumber', AssertType.required], |
||||
}) |
||||
async getCxReceiptByHash({ txnHash, shardID }: { txnHash: string; shardID: number }) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetCXReceiptByHash, |
||||
[txnHash], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
/** |
||||
* |
||||
*/ |
||||
@assertObject({ |
||||
address: ['isValidAddress', AssertType.required], |
||||
blockNumber: ['isBlockNumber', AssertType.optional], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getCode({ |
||||
address, |
||||
blockNumber = DefaultBlockParams.latest, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
address: string; |
||||
blockNumber?: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetCode, |
||||
[getAddress(address).checksum, blockNumber], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
async net_peerCount(shardID: number = this.messenger.currentShard) { |
||||
const result = await this.messenger.send(RPCMethod.PeerCount, [], 'net', shardID); |
||||
|
||||
return this.getRpcResult(result); |
||||
} |
||||
async net_version(shardID: number = this.messenger.currentShard) { |
||||
const result = await this.messenger.send(RPCMethod.NetVersion, [], 'net', shardID); |
||||
|
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
async getProtocolVersion(shardID: number = this.messenger.currentShard) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.ProtocolVersion, |
||||
[], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
@assertObject({ |
||||
address: ['isValidAddress', AssertType.required], |
||||
position: ['isHex', AssertType.required], |
||||
blockNumber: ['isBlockNumber', AssertType.optional], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getStorageAt({ |
||||
address, |
||||
position, |
||||
blockNumber = DefaultBlockParams.latest, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
address: string; |
||||
position: string; |
||||
blockNumber?: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetStorageAt, |
||||
[getAddress(address).checksum, position, blockNumber], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
@assertObject({ |
||||
address: ['isValidAddress', AssertType.required], |
||||
blockNumber: ['isBlockNumber', AssertType.optional], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async getTransactionCount({ |
||||
address, |
||||
blockNumber = DefaultBlockParams.latest, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
address: string; |
||||
blockNumber?: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetTransactionCount, |
||||
[getAddress(address).checksum, blockNumber], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
async getShardingStructure() { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GetShardingStructure, |
||||
[], |
||||
this.messenger.chainPrefix, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
async sendTransaction(transaction: Transaction) { |
||||
if (!transaction.isSigned() || !transaction) { |
||||
throw new Error('transaction is not signed or not exist'); |
||||
} |
||||
const result = await this.messenger.send( |
||||
RPCMethod.SendRawTransaction, |
||||
[transaction.getRawTransaction()], |
||||
this.messenger.chainPrefix, |
||||
typeof transaction.txParams.shardID === 'string' |
||||
? Number.parseInt(transaction.txParams.shardID, 10) |
||||
: transaction.txParams.shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
async sendRawTransaction(transaction: Transaction) { |
||||
if (!transaction.isSigned() || !transaction) { |
||||
throw new Error('transaction is not signed or not exist'); |
||||
} |
||||
const [txn, result] = await transaction.sendTransaction(); |
||||
if (txn.isPending()) { |
||||
return result; |
||||
} |
||||
} |
||||
|
||||
createObservedTransaction(transaction: Transaction) { |
||||
try { |
||||
transaction.sendTransaction().then((response: any) => { |
||||
const [txReturned, TranID] = response; |
||||
|
||||
txReturned.confirm(TranID).then((txConfirmed: Transaction) => { |
||||
transaction.emitter.resolve(txConfirmed); |
||||
}); |
||||
}); |
||||
return transaction.emitter; |
||||
} catch (err) { |
||||
throw err; |
||||
} |
||||
} |
||||
|
||||
async sendRawStakingTransaction(staking: StakingTransaction) { |
||||
if (!staking.isSigned() || !staking) { |
||||
throw new Error('staking transaction is not signed or not exist'); |
||||
} |
||||
const [txn, result] = await staking.sendTransaction(); |
||||
if (txn.isPending()) { |
||||
return result; |
||||
} |
||||
} |
||||
createObservedStakingTransaction(staking: StakingTransaction) { |
||||
try { |
||||
staking.sendTransaction().then((response: any) => { |
||||
const [txReturned, TranID] = response; |
||||
|
||||
txReturned.confirm(TranID).then((txConfirmed: StakingTransaction) => { |
||||
staking.emitter.resolve(txConfirmed); |
||||
}); |
||||
}); |
||||
return staking.emitter; |
||||
} catch (err) { |
||||
throw err; |
||||
} |
||||
} |
||||
|
||||
@assertObject({ |
||||
to: ['isValidAddress', AssertType.optional], |
||||
data: ['isHex', AssertType.optional], |
||||
shardID: ['isNumber', AssertType.optional], |
||||
}) |
||||
async estimateGas({ |
||||
to, |
||||
data, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
to: string; |
||||
data: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.EstimateGas, |
||||
[{ to: getAddress(to).checksum, data }], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
async gasPrice(shardID: number = this.messenger.currentShard) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.GasPrice, |
||||
[], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
async call({ |
||||
payload, |
||||
blockNumber = DefaultBlockParams.latest, |
||||
shardID = this.messenger.currentShard, |
||||
}: { |
||||
payload: any; |
||||
blockNumber?: string; |
||||
shardID?: number; |
||||
}) { |
||||
const result = await this.messenger.send( |
||||
RPCMethod.Call, |
||||
[payload, blockNumber], |
||||
this.messenger.chainPrefix, |
||||
shardID, |
||||
); |
||||
return this.getRpcResult(result); |
||||
} |
||||
|
||||
newPendingTransactions(shardID: number = this.messenger.currentShard) { |
||||
if (this.messenger.provider instanceof WSProvider) { |
||||
return new NewPendingTransactions(this.messenger, shardID); |
||||
} else { |
||||
throw new Error('HttpProvider does not support this feature'); |
||||
} |
||||
} |
||||
|
||||
newBlockHeaders(shardID: number = this.messenger.currentShard) { |
||||
if (this.messenger.provider instanceof WSProvider) { |
||||
return new NewHeaders(this.messenger, shardID); |
||||
} else { |
||||
throw new Error('HttpProvider does not support this feature'); |
||||
} |
||||
} |
||||
|
||||
syncing(shardID: number = this.messenger.currentShard) { |
||||
if (this.messenger.provider instanceof WSProvider) { |
||||
return new Syncing(this.messenger, shardID); |
||||
} else { |
||||
throw new Error('HttpProvider does not support this feature'); |
||||
} |
||||
} |
||||
|
||||
logs(options: any, shardID: number = this.messenger.currentShard) { |
||||
if (this.messenger.provider instanceof WSProvider) { |
||||
return new LogSub(options, this.messenger, shardID); |
||||
} else { |
||||
throw new Error('HttpProvider does not support this feature'); |
||||
} |
||||
} |
||||
} |
||||
|
||||
export { Blockchain }; |
@ -0,0 +1,103 @@ |
||||
import * as crypto from '@harmony-js/crypto'; |
||||
import * as utils from '@harmony-js/utils'; |
||||
|
||||
import { Provider, HttpProvider, Messenger, WSProvider, ShardingItem } from '@harmony-js/network'; |
||||
import { TransactionFactory, Transaction } from '@harmony-js/transaction'; |
||||
import { StakingTransaction, StakingFactory } from '@harmony-js/staking'; |
||||
import { ContractFactory, Contract } from '@harmony-js/contract'; |
||||
import { Wallet, Account } from '@harmony-js/account'; |
||||
import { Blockchain } from './blockchain'; |
||||
import { HarmonyConfig } from './util'; |
||||
|
||||
export class Harmony extends utils.HarmonyCore { |
||||
Modules = { |
||||
HttpProvider, |
||||
WSProvider, |
||||
Messenger, |
||||
Blockchain, |
||||
TransactionFactory, |
||||
StakingFactory, |
||||
Wallet, |
||||
Transaction, |
||||
StakingTransaction, |
||||
Account, |
||||
Contract, |
||||
}; |
||||
messenger: Messenger; |
||||
transactions: TransactionFactory; |
||||
stakings: StakingFactory; |
||||
wallet: Wallet; |
||||
blockchain: Blockchain; |
||||
contracts: ContractFactory; |
||||
crypto: any; |
||||
utils: any; |
||||
defaultShardID?: number; |
||||
private provider: HttpProvider | WSProvider; |
||||
|
||||
constructor( |
||||
url: string, |
||||
config: HarmonyConfig = { |
||||
chainId: utils.defaultConfig.Default.Chain_ID, |
||||
chainType: utils.defaultConfig.Default.Chain_Type, |
||||
}, |
||||
) { |
||||
super(config.chainType, config.chainId); |
||||
|
||||
const providerUrl = config.chainUrl || url || utils.defaultConfig.Default.Chain_URL; |
||||
|
||||
this.provider = new Provider(providerUrl).provider; |
||||
this.messenger = new Messenger(this.provider, this.chainType, this.chainId); |
||||
this.blockchain = new Blockchain(this.messenger); |
||||
this.transactions = new TransactionFactory(this.messenger); |
||||
this.stakings = new StakingFactory(this.messenger); |
||||
this.wallet = new Wallet(this.messenger); |
||||
this.contracts = new ContractFactory(this.wallet); |
||||
this.crypto = crypto; |
||||
this.utils = utils; |
||||
this.defaultShardID = config.shardID; |
||||
if (this.defaultShardID !== undefined) { |
||||
this.setShardID(this.defaultShardID); |
||||
} |
||||
} |
||||
public setProvider(provider: string | HttpProvider | WSProvider): void { |
||||
this.provider = new Provider(provider).provider; |
||||
this.messenger.setProvider(this.provider); |
||||
this.setMessenger(this.messenger); |
||||
} |
||||
|
||||
public setChainId(chainId: utils.ChainID) { |
||||
this.chainId = chainId; |
||||
this.messenger.setChainId(this.chainId); |
||||
this.setMessenger(this.messenger); |
||||
} |
||||
public setShardID(shardID: number) { |
||||
this.defaultShardID = shardID; |
||||
this.messenger.setDefaultShardID(this.defaultShardID); |
||||
this.setMessenger(this.messenger); |
||||
} |
||||
public setChainType(chainType: utils.ChainType) { |
||||
this.chainType = chainType; |
||||
this.messenger.setChainType(this.chainType); |
||||
this.setMessenger(this.messenger); |
||||
} |
||||
|
||||
public shardingStructures(shardingStructures: ShardingItem[]) { |
||||
for (const shard of shardingStructures) { |
||||
const shardID = |
||||
typeof shard.shardID === 'string' ? Number.parseInt(shard.shardID, 10) : shard.shardID; |
||||
this.messenger.shardProviders.set(shardID, { |
||||
current: shard.current !== undefined ? shard.current : false, |
||||
shardID, |
||||
http: shard.http, |
||||
ws: shard.ws, |
||||
}); |
||||
} |
||||
this.setMessenger(this.messenger); |
||||
} |
||||
private setMessenger(messenger: Messenger) { |
||||
this.blockchain.setMessenger(messenger); |
||||
this.wallet.setMessenger(messenger); |
||||
this.transactions.setMessenger(messenger); |
||||
this.stakings.setMessenger(messenger); |
||||
} |
||||
} |
@ -0,0 +1,5 @@ |
||||
export * from './harmony'; |
||||
export * from './blockchain'; |
||||
export * from './truffleProvider'; |
||||
export * from './harmonyExtension'; |
||||
export * from './types'; |
@ -0,0 +1,25 @@ |
||||
import { HttpProvider, Messenger } from '@harmony-js/network'; |
||||
import { TransactionFactory, Transaction } from '@harmony-js/transaction'; |
||||
import { Wallet, Account } from '@harmony-js/account'; |
||||
import { ChainType, ChainID } from '@harmony-js/utils'; |
||||
import { Blockchain } from './blockchain'; |
||||
|
||||
export interface HarmonyModule { |
||||
HttpProvider: HttpProvider; |
||||
Messenger: Messenger; |
||||
Blockchain: Blockchain; |
||||
TransactionFactory: TransactionFactory; |
||||
Wallet: Wallet; |
||||
Transaction: Transaction; |
||||
Account: Account; |
||||
} |
||||
|
||||
export const enum UrlType { |
||||
http, |
||||
ws, |
||||
} |
||||
|
||||
export interface HarmonySetting<T extends ChainType, I extends ChainID> { |
||||
type: T; |
||||
id: I; |
||||
} |
@ -0,0 +1,16 @@ |
||||
{ |
||||
"extends": "../../tsconfig.base.json", |
||||
"compilerOptions": { |
||||
"rootDir": "src", |
||||
"outDir": "dist" |
||||
}, |
||||
"include": ["src", "../../typings/**/*.d.ts", "../harmony-utils/src/core.ts"], |
||||
"references": [ |
||||
{"path": "../harmony-account"}, |
||||
{"path": "../harmony-crypto"}, |
||||
{"path": "../harmony-utils"}, |
||||
{"path": "../harmony-network"}, |
||||
{"path": "../harmony-transaction"}, |
||||
{"path": "../harmony-contract"} |
||||
] |
||||
} |
@ -0,0 +1,80 @@ |
||||
import { isAddress, isBech32Address, isBech32TestNetAddress } from '@harmony-js/utils'; |
||||
|
||||
import { toChecksumAddress } from './keyTool'; |
||||
import { fromBech32, toBech32, HRP, tHRP } from './bech32'; |
||||
|
||||
export class HarmonyAddress { |
||||
// static validator
|
||||
static isValidBasic(str: string) { |
||||
const toTest = new HarmonyAddress(str); |
||||
return toTest.raw === toTest.basic; |
||||
} |
||||
|
||||
// static validator
|
||||
static isValidChecksum(str: string) { |
||||
const toTest = new HarmonyAddress(str); |
||||
return toTest.raw === toTest.checksum; |
||||
} |
||||
|
||||
// static validator
|
||||
static isValidBech32(str: string) { |
||||
const toTest = new HarmonyAddress(str); |
||||
return toTest.raw === toTest.bech32; |
||||
} |
||||
// static validator
|
||||
static isValidBech32TestNet(str: string) { |
||||
const toTest = new HarmonyAddress(str); |
||||
return toTest.raw === toTest.bech32TestNet; |
||||
} |
||||
|
||||
raw: string; |
||||
basic: string; |
||||
get basicHex() { |
||||
return `0x${this.basic}`; |
||||
} |
||||
get checksum() { |
||||
return toChecksumAddress(`0x${this.basic}`); |
||||
} |
||||
|
||||
get bech32() { |
||||
return toBech32(this.basic, HRP); |
||||
} |
||||
get bech32TestNet() { |
||||
return toBech32(this.basic, tHRP); |
||||
} |
||||
|
||||
constructor(raw: string) { |
||||
this.raw = raw; |
||||
this.basic = this.getBasic(this.raw); |
||||
} |
||||
|
||||
private getBasic(addr: string) { |
||||
const basicBool = isAddress(addr); |
||||
const bech32Bool = isBech32Address(addr); |
||||
const bech32TestNetBool = isBech32TestNetAddress(addr); |
||||
|
||||
if (basicBool) { |
||||
return addr.replace('0x', '').toLowerCase(); |
||||
} |
||||
|
||||
if (bech32Bool) { |
||||
const fromB32 = fromBech32(addr, HRP); |
||||
return fromB32.replace('0x', '').toLowerCase(); |
||||
} |
||||
|
||||
if (bech32TestNetBool) { |
||||
const fromB32TestNet = fromBech32(addr, tHRP); |
||||
return fromB32TestNet.replace('0x', '').toLowerCase(); |
||||
} |
||||
|
||||
throw new Error(`"${addr}" is an invalid address format`); |
||||
} |
||||
} |
||||
|
||||
export function getAddress(address: string) { |
||||
try { |
||||
return new HarmonyAddress(address); |
||||
} catch (error) { |
||||
throw error; |
||||
} |
||||
} |
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-crypto |
||||
* @hidden |
||||
*/ |
||||
|
||||
// This file is ported from ether.js/src.ts/utils/bytes.ts
|
||||
// and done some fixes
|
||||
|
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-crypto |
||||
* @ignore |
||||
*/ |
||||
|
||||
import hdkey from 'hdkey'; |
||||
import bip39 from 'bip39'; |
||||
import BN from 'bn.js'; |
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-crypto |
||||
* @ignore |
||||
*/ |
||||
|
||||
// this file is ported from 'ether.js' and done some fixes
|
||||
import * as sha3 from 'js-sha3'; |
||||
|
@ -1,19 +1,18 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-crypto |
||||
*/ |
||||
|
||||
/** |
||||
* Uses JS-native CSPRNG to generate a specified number of bytes. |
||||
* @NOTE |
||||
* this method throws if no PRNG is available. |
||||
* @function randomBytes |
||||
* @description Uses JS-native CSPRNG to generate a specified number of bytes. |
||||
* NOTE: this method throws if no PRNG is available. |
||||
* @param {Number} bytes bytes number to generate |
||||
* @return {String} ramdom hex string |
||||
*/ |
||||
export const randomBytes = (bytes: number): string => { |
||||
let randBz: number[] | Uint8Array; |
||||
|
||||
if (typeof window !== 'undefined' && window.crypto && window.crypto.getRandomValues) { |
||||
if ( |
||||
typeof window !== 'undefined' && |
||||
window.crypto && |
||||
window.crypto.getRandomValues |
||||
) { |
||||
randBz = window.crypto.getRandomValues(new Uint8Array(bytes)); |
||||
} else if (typeof require !== 'undefined') { |
||||
randBz = require('crypto').randomBytes(bytes); |
@ -1,9 +1,3 @@ |
||||
/** |
||||
* @packageDocumentation |
||||
* @module woop-crypto |
||||
* @ignore |
||||
*/ |
||||
|
||||
export type KDF = 'pbkdf2' | 'scrypt'; |
||||
|
||||
export interface PBKDF2Params { |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue