Account Generation and Validation
The simplest way to generate new accounts, or addresses, on the POKT blockchain is to use the official Pocket client, PocketJS.
Creating a New Account
To create a new account on the POKT blockchain and export it:
import { Pocket } from '@pokt-network/pocket-js'
// PocketJS must always be initialized with at least one dispatcher.
const POCKET_DISPATCHER = '<URL_TO_DISPATCH_NODE>'
const pocket = new Pocket(POCKET_DISPATCHER)
// The passphrase used to encrypt the private key while in memory:
const PASSPHRASE = 'foobar'
const account = await pocket.keybase.createAccount(PASSPHRASE)
// The result of successful account creation:
console.log(account)
// Using the exportAccount function, you can obtain a plaintext private key.
const exportedAccountPrivateKey = await pocket.keybase.exportAccount(
account.address.toString('hex'),
PASSPHRASE
)
// This plaintext private key should be encrypted before storage.
console.log(exportedAccountPrivateKey.toString('hex'))
// You can also export an encrypted JSON version of the same private key.
// The passphrase used to encrypt this JSON file is separate from the
// previous PASSPHRASE.
const exportedPPK = await pocket.keybase.exportPPK(
exportedAccountPrivateKey,
// The PPK passphrase used to encrypt the JSON file
'foo',
// A hint for the PPK passphrase
'what comes before bar'
)
console.log(exportedPPK)
Importing an Existing Account
To import an existing account using either the raw private key or the encrypted JSON PPK:
import { Pocket } from '@pokt-network/pocket-js'
// PocketJS must always be initialized with at least one dispatcher.
const POCKET_DISPATCHER = '<URL_TO_DISPATCH_NODE>'
const pocket = new Pocket(POCKET_DISPATCHER)
// The passphrase used to encrypt the private key while in memory:
const PASSPHRASE = 'foobar'
const PRIVATE_KEY = '...'
// Import an existing account using the raw private key:
const importedAccount = await pocket.keybase.importAccount(
PRIVATEKEY,
// The passphrase to encrypt the private key while in memory
PASSPHRASE
)
// Import an account using the encrypted JSON PPK:
const importedPPKAccount = await pocket.keybase.importPPK(
// The PPK passphrase used when the key was exported
'foo',
exportedPPK.salt,
exportedPPK.secParam,
exportedPPK.hint,
exportedPPK.cypherText,
// The passphrase to encrypt the private key while in memory
PASSPHRASE,
)
Verifying an Address
To verify a POKT blockchain address, public key, or raw private key:
import {
validateAddressHex,
validatePrivateKey,
validatePublicKey
} from '@pokt-network/pocket-js'
// Validate a POKT blockchain address: returns undefined if valid.
// This should be wrapped in a try / catch block as it will throw the
// appropriate error if the address is not valid.
try {
const isValidAddress = !(
validateAddressHex(account.addressHex) instanceof Error
)
} catch (e) {
// Handle the error
}
// Validate a public key: returns true or false.
const isValidPublicKey = validatePublicKey(account.publicKey.toString('hex'))
// Validate a private key: returns true or false.
const isValidPrivateKey = validatePrivateKey(privateKey)
Transaction Construction
Sending a Transaction
To send a transaction on the POKT blockchain:
import { Pocket } from '@pokt-network/pocket-js'
const RECEIVER_ADDRESS = '...'
const SENDER_ADDRESS = '...'
const SENDER_PRIVATE_KEY = '...'
// The passphrase used to encrypt the private key while in memory:
const PASSPHRASE = 'foobar'
// PocketJS must always be initialized with at least one dispatcher.
const POCKET_DISPATCHER = '<URL_TO_DISPATCH_NODE>'
// To send a transaction, you can use one of the public RPCs or
// your own Pocket node.
const POCKET_RPC = '<URL_TO_RPC_NODE>'
const pocket = new Pocket(POCKET_DISPATCHER, POCKET_RPC)
// If you are using Pocket Mainnet, make sure to disable legacyCodec
pocket.configuration.useLegacyTxCodec = false;
// Create a transaction signer using the `withPrivateKey` method:
const txSigner = pocket.withPrivateKey(
SENDER_PRIVATE_KEY
)
const transactionResponse = await txSigner.send(
// Origin address for the send
SENDER_ADDRESS,
// Receiver address
RECEIVER_ADDRESS,
// 10 POKT
'10000000'
).submit(
'mainnet',
// The transaction fee is always 10,000 uPOKT
'10000'
)
// Check if the transaction returned an error:
if (typeGuard(transactionResponse, RpcError)) {
throw new Error(transactionResponse.message)
}
// You will be able to look up this transaction through this hash after the
// next block clears.
const { hash } = transactionResponse
console.log(hash)
Creating a Signed SEND Transaction Offline
To create a signed transaction that can be sent immediately or stored:
import { Pocket } from '@pokt-network/pocket-js'
const RECEIVER_ADDRESS = '...'
const SENDER_ADDRESS = '...'
const SENDER_PRIVATE_KEY = '...'
// The passphrase used to encrypt the private key while in memory:
const PASSPHRASE = 'foobar'
// PocketJS must always be initialized with at least one dispatcher.
const POCKET_DISPATCHER = '<URL_TO_DISPATCH_NODE>'
const pocket = new Pocket(POCKET_DISPATCHER)
// If you are using Pocket Mainnet, make sure to disable legacyCodec
pocket.configuration.useLegacyTxCodec = false;
// Create a transaction signer using the `withPrivateKey` method:
const txSigner = pocket.withPrivateKey(
SENDER_PRIVATE_KEY
)
// Now use the transaction signer to create a signed SEND transaction
const txSignerWithSendTransaction = txSigner.send(
// Origin address for the send
SENDER_ADDRESS,
// Receiver address
RECEIVER_ADDRESS,
// 10 POKT
'10000000'
)
// Generate offline signed send transaction
const sendTx = await txSignerWithSendTransaction.createTransaction(
'mainnet',
// The transaction fee is always 10,000 uPOKT
'10000'
)
console.log('Offline signed send transaction:', sendTx)
After calling .sendTransaction()
, you will get back a response with this format:
RawTxRequest {
address: "1e829f34ce5533c913638310408632242f6fbd43",
txHex: "d1010a4....bf8970d"
}
Calculate transaction hash from raw transaction bytes
const crypto = require('crypto');
// This is the raw transaction bytes obtained from offline signed transaction
const txHex = 'd1010a4....bf8970d'
const txHash = crypto.createHash('sha256').update(Buffer.from(txHex, 'hex')).digest('hex');
console.log(txHash)
Deserialize offline signed SEND transaction
You can also decode the raw transaction bytes generated offline (only works for SEND transactions):
// Only supported for versions >= 0.7.1
const { ProtoTxDecoder } = require('@pokt-network/pocket-js')
const ENCODED_TX_BYTES = Buffer.from('d1010a4....bf8970d', 'hex')
const protoTxDecoder = await pocket.withProtoTxDecoder()
const protoStdTx = await protoTxDecoder.unmarshalStdTx(ENCODED_TX_BYTES)
const data = await protoTxDecoder.decodeStdTxData(protoStdTx)
console.log('Deserialized transaction:', data)
Transaction Verification
Confirming that Funds have been Received
// The 64-character transaction hash is necessary to retrieve the transaction:
const tx = await pocket.query.getTX(hash)
if (typeGuard(tx, RpcError)) {
throw new Error(tx.message)
}
// The retrieved transaction object:
console.log(tx)
The return code of the transaction must be 0
— indicating success:
"tx_result": {
"code": 0,
"codespace": "",
"data": null,
"events": null,
"info": "",
"log": "",
"message_type": "send",
"recipient": "...",
"signer": "..."
}
Consult the error types in Pocket Core for information on failed transactions.