ara-util

Utility functions for common Ara tasks

Usage no npm install needed!

<script type="module">
  import araUtil from 'https://cdn.skypack.dev/ara-util';
</script>

README

ara-util

Common utility functions to be used in various Ara modules.

Status

This project is in active development.

Stability

Stability: 2 - Stable. Compatibility with the npm ecosystem is a high priority.

Installation

$ npm install ara-util --save

Dependencies

API

Most of the functions exported by this module will check for input correctness. If given incorrect input, a function will throw a TypeError with a message describing the error.

Transform

Web3

Contract

Tx

ABI

async util.getAFSOwnerIdentity(opts)

Returns the owner DID of a given AFS DID, used for resolving the document of the identity that created an AFS.

  • opts
    • did - DID of the document to resolve the owner for
    • mnemonic - mnemonic of the owning identity
    • password - password for the owner
    • keyringOpts - optional Keyring options
const identity = await aid.create({ password })
const { mnemonic, did } = identity
const { did: owner } = did
const { afs } = await createAFS({ owner, password })
const resolvedOwner = await util.getAFSOwnerIdentity({ did: afs.did, mnemonic, password })

async util.getAddressFromDID(did, keyringOpts)

Retrieves the Ethereum address associated with a DID.

  • did - The DID from which to obtain the Ethereum address
  • keyringOpts - optional Keyring options
const address = await util.getAddressFromDID(did)

async util.isCorrectPassword(opts)

Validates if an identity's password is correct by attempting to decrypt the Ara keystore (keystore/ara). The identity must be archived locally for this function to work. To recover an existing identity, see aid.recover.

  • opts
    • ddo - document to validate password for
    • password - password to validate against
const password = 'myPass'
const isCorrect = await util.isCorrectPassword({ ddo, password })

async util.validate(opts)

Validates that a resolved document based on a DID can be decrypted with the password, proving ownership. This uses util.isCorrectPassword internally after resolving the document and throws if the password is incorrect or the keystore is not locally accessible.

  • opts
    • did - DID of identity to validate
    • password - password of the identity
    • ddo - optional DDO to use for validation (instead of resolving)
    • keyringOpts - optional Keyring options

Returns object:

  • did - The identifier portion of the DID that was passed in
  • ddo - The DDO that the did and password were authenticated against
const password = 'myPass'
const did = 'did:ara:41dd7aabfa3763306d8ec69559508c0635bbc2bb591fb217905f8e9a9676a7ec'
const { did: didIdentifier, ddo } = await util.validate({ did, password })

util.checkAFSExistence(opts)

Checks if an AFS exists locally.

  • opts
    • did - The DID of the AFS to check

Returns a boolean indicating whether the AFS exists locally.

const exists = util.checkAFSExistence({ did })

util.getDocumentKeyHex(ddo)

Returns the publicKeyHex of the first publicKey entry within a document.

  • ddo - Document to retreive publicKeyHex from
const publicKeyHex = util.getDocumentKeyHex(ddo) // 41dd7aabfa3763306d8ec69559508c0635bbc2bb591fb217905f8e9a9676a7ec

util.getDocumentOwner(ddo)

Returns the DID identifier of a document owner, or first entry in the authentication array of a DDO. The difference between this function and util.getAFSOwnerIdentity is that this function does not do any resolving.

  • ddo - Document to retrieve owner from
const owner = util.getDocumentOwner(ddo)

util.hash(str, [encoding])

blake2b hashes a string and returns the hashed string. An optional encoding can be provided, which defaults to hex encoding.

  • str - String to hash
  • encoding - optional encoding of the string
const result = util.hash('Hello')

util.hashDID(did, [encoding])

blake2b hashes a DID with an optional encoding, which defaults to hex. The difference between this and hash is that this function takes care of extracting the identifer portion of the DID prior to hashing.

  • did - DID to hash
  • encoding - optional encoding of the DID
const hash = util.hashDID('did:ara:14078363f2d9aa0d269827261544e598d8bf11c66f88e49d05e85bd3d181ec8e')

util.getIdentifier(did)

Returns the identifier portion of a DID.

  • did - DID to parse
const identifier = util.getIdentifier('did:ara:14078363f2d9aa0d269827261544e598d8bf11c66f88e49d05e85bd3d181ec8e') // 14078363f2d9aa0d269827261544e598d8bf11c66f88e49d05e85bd3d181ec8e

util.transform.toBuffer(input, [encoding])

Converts a string to a buffer.

  • input - string to convert
  • encoding - Encoding of string for conversion
const buf = util.web3.toBuffer('hi')
// <Buffer 68 69>

util.transform.toHexString(input, [opts])

Converts the input to a hex string. Can optionally prepend 0x for compatability with EVM.

  • input - String, Number, or Buffer to be converted
  • opts
    • ethify - Should the result be prepended by a 0x
    • encoding - The type of encoding of the input
const str = util.transform.toHexString('ef61059258414a65bf2d94a4fd3b503b5fee8b48', { encoding: 'hex', ethify: true })
// 0xef61059258414a65bf2d94a4fd3b503b5fee8b48

async util.web3.account.load(opts)

Loads the Ethereum account associated with an Ara identity, returning the loaded account object.

  • opts
    • did - DID to load account from
    • password - Identity's password
const did = 'did:ara:14078363f2d9aa0d269827261544e598d8bf11c66f88e49d05e85bd3d181ec8e'
const password = 'myPass'
const loadedAccount = await util.web3.account.load({ did, password })

async util.web3.call(opts)

Makes a function call to a deployed Ethereum contract.

  • opts
    • abi - ABI of the compiled Solidity contract to call
    • address - Ethereum address where contract has been deployed
    • functionName - Name of the function on the contract to call

Returns the result of the call.

const { abi } = require('./build/contracts/MyContract.json')
const contractAddress = '0xef61059258414a65bf2d94a4fd3b503b5fee8b48'
const result = await call({ abi, address: contractAddress, functionName: 'myContractFunction' })

util.web3.isAddress(address)

Validates whether a hex string is a valid Ethereum address.

  • address - string to validate
let isAddress = util.web3.isAddress('0xef61059258414a65bf2d94a4fd3b503b5fee8b48') // true
isAddress = util.web3.isAddress('Hello') // false

util.web3.sha3(params, [abiEncode = true])

SHA3 hashes given parameters. By default, ABI encodes parameters before hashing.

  • params - Parameters of any type or object containing parameters
  • abiEncode - Whether to ABI encode parameters prior to hashing. Defaults to true.
const result = util.web3.sha3({ param1: 1, param2: 2 })

util.web3.getContext([provider])

Creates and returns an Ara context object containing a Web3 instance.

  • provider - optional Boolean flag indicating whether a new Web3 provider should be created. Defaults to true
const ctxProvider = util.web3.getContext()
await ctxProvider.ready() // wait for provider to be ready
let { web3 } = ctxProvider
ctxProvider.close() // always close context if provider was created

const ctxNoProvider = util.web3.getContext(false);
({ web3 } = ctxNoProvider) // no need to wait for provider or close context

async util.web3.contract.deploy(opts)

Deploys a contract to the network of the current Web3 provider. This returns an instance of the deployed Contract as well as the gasLimit that was used for deploying this contract.

  • opts
    • abi - ABI of the compiled Solidity contract to deploy
    • bytecode - Bytecode of compiled contract
    • account - Ethereum account to deploy from
const { abi, bytecode } = require('./build/contracts/MyContract.json')
const account = await util.web3.account.load({ did, password })
const { contractAddress, gasLimit } = await deploy({ account, abi, bytecode })

async util.web3.contract.estimateGas(tx, opts)

Estimates the gas cost of a transaction.

const transaction = await util.web3.tx.create({
  account,
  to: '0xef61059258414a65bf2d94a4fd3b503b5fee8b48',
  data: {
    abi,
    functionName: 'setNumbers',
    values: [1, 2, 3]
  }
})
const estimate = util.web3.contract.estimateGas(transaction, opts)

util.web3.contract.get(abi, address)

Gets a contract instance based on its ABI and deployed address

  • abi - ABI of compiled Solidity contract
  • address - Deployed address of the contract

Returns object

  • contract - The contract instance
  • ctx - The Ara context object
const address = '0xef61059258414a65bf2d94a4fd3b503b5fee8b48'
const { contract, ctx } = util.web3.contract.get(abi, address)
ctx.close()

async util.web3.tx.create(opts, [signTx])

Creates an EthereumTx object that can be published to the current network. Signs the transaction with the account's privateKey by default.

  • opts
    • account - the account that will be initiating the transaction
    • to - the address of the contract of the transaction
    • data - function data to encode as part of the transaction
      • abi - contract ABI
      • functionName - name of function that's being called
      • values - function argument values as an array
    • gasPrice - optional Gas price to use for this transaction
    • gasLimit - optional Gas limit to use for this transaction
  • signTx - should this transaction be signed

Returns object:

  • tx - The transaction object created
  • ctx - The Ara context object
const account = await util.web3.account.load({ did, password })
const { tx: signedTx, ctx: ctx1 } = await util.web3.tx.create({ account, to: '0xef61059258414a65bf2d94a4fd3b503b5fee8b48' })
ctx1.close()

const { tx: unsignedTx, ctx: ctx2 } = await util.web3.tx.create({ account, to: '0xef61059258414a65bf2d94a4fd3b503b5fee8b48' }, false)
ctx2.close()

const contractAddress = '0xef61059258414a65bf2d94a4fd3b503b5fee8b48'
const { tx: anotherTx, ctx3 } = await util.web3.tx.create({
  account,
  to: contractAddress,
  data: {
    abi,
    functionName: 'setPrice',
    values: [100]
  },
  gasLimit: 100000
})
ctx3.close()

async util.web3.tx.sendSignedTransaction(tx[, { onhash, onreceipt, onconfirmation, onerror, onmined }])

Sends a signed transaction to the current network.

  • tx - The signed EthereumTx object to publish to the network
  • onhash - Optional callback fired right after the transaction is sent and a transaction hash string is available
  • onreceipt - Optional callback fired when the transaction receipt Object is available
  • onconfirmation - Optional callback fired for every confirmation up to the 12th confirmation. Receives the confirmation number as the first and the receipt Object as the second argument. Fired from confirmation 0 on, which is the block where its mined.
  • onerror - Optional callback fired if an error occurs during sending. If an out of gas error, the second parameter is the receipt.
  • onmined - Optional callback fired when receipt Object is available

Returns the transaction receipt object.

const account = await util.web3.account.load({ did, password })
const { tx: signedTx, ctx } = await util.web3.tx.create({ account, to: '0xef61059258414a65bf2d94a4fd3b503b5fee8b48' })
const receipt = await util.web3.tx.sendSignedTransaction(signedTx)
ctx.close()

util.web3.tx.estimateCost(tx, [denomination])

Estimates the cost of a transaction. The returned value can be a particular denomination, defaults to ether. You can find valid denomination values here.

  • tx - EthereumTx object of the transaction
  • denomination - Unit to return the cost in
const costInEth = util.web3.tx.estimateCost(tx)
const costInFinney = util.web3.tx.estimateCost(tx, 'finney')

util.web3.tx.sign(tx, privateKey)

Signs a transaction object with an account's privateKey.

  • tx - EthereumTx object of the transaction
  • privateKey - The Ethereum account's privateKey signing the transaction
const { tx: unsignedTx, ctx } = await util.web3.tx.create({ account, to: '0xef61059258414a65bf2d94a4fd3b503b5fee8b48' }, false)
const { privateKey } = account
const signedTx = util.web3.tx.sign(unsignedTx, privateKey)
ctx.close()

util.web3.tx.getTransactionReceipt(hash)

Returns the transaction receipt object for a mined transaction. Returns null for pending transactions.

  • hash - The transaction hash of a mined transaction
  const receipt = await util.web3.tx.getTransactionReceipt(hash)

util.web3.abi.encodeFunctionCall(abi, functionName, values)

Encodes a function call to its ABI signature, required for sending signed transactions that require a function on a deployed contract.

  • abi - ABI of the compiled Solidity contract
  • functionName - name of the function from the ABI to encode
  • values - array of arguments for the function to encode

Returns the encoded function call as a String.

const { abi } = require('./build/contracts/MyContract.json')
const encoded = util.web3.abi.encodeFunctionCall(abi, 'myFunctionName', ['arg1', 'arg2'])

util.web3.abi.encodeParameter(type, parameter)

Encodes a function parameter to its ABI signature.

Returns the encoded parameter as a String.

const encoded = util.web3.abi.encodeParameter('bytes', '0xFF')

util.web3.abi.encodeParameters(typesArray, parameters)

Encodes multiple function parameters to their ABI signatures.

  • typesArray - Array of types to encode (see Solidity types)
  • parameters - Array of parameter values to encode

Returns the encoded parameters as a String.

const encoded = util.web3.abi.encodeParameter(['bytes', 'string'], ['0xFF', 'Hello'])

Contributing

See Also

License

LGPL-3.0