UNPKG

@aeternity/aepp-sdk

Version:
239 lines (214 loc) 6.33 kB
/* * ISC License (ISC) * Copyright (c) 2018 aeternity developers * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ /** * Aens module - routines to interact with the æternity naming system * * The high-level description of the naming system is * https://github.com/aeternity/protocol/blob/master/AENS.md in the protocol * repository. * @module @aeternity/aepp-sdk/es/ae/aens * @export Aens * @example import Aens from '@aeternity/aepp-sdk/es/ae/aens' */ import * as R from 'ramda' import { encodeBase58Check, salt } from '../utils/crypto' import { commitmentHash } from '../tx/builder/helpers' import Ae from './' /** * Transfer a domain to another account * @instance * @function * @alias module:@aeternity/aepp-sdk/es/ae/aens * @category async * @param {String} nameId * @param {String} account * @param {Object} [options={}] * @return {Promise<Object>} */ async function transfer (nameId, account, options = {}) { const opt = R.merge(this.Ae.defaults, options) const nameTransferTx = await this.nameTransferTx(R.merge(opt, { nameId, accountId: await this.address(), recipientId: account })) return this.send(nameTransferTx, opt) } /** * Revoke a domain * @instance * @function * @alias module:@aeternity/aepp-sdk/es/ae/aens * @category async * @param {String} nameId * @param {Object} [options={}] * @return {Promise<Object>} */ async function revoke (nameId, options = {}) { const opt = R.merge(this.Ae.defaults, options) const nameRevokeTx = await this.nameRevokeTx(R.merge(opt, { nameId, accountId: await this.address() })) return this.send(nameRevokeTx, opt) } /** * What kind of a hash is this? If it begins with 'ak_' it is an * account key, if with 'ok_' it's an oracle key. * * @param s - the hash. * returns the type, or throws an exception if type not found. */ function classify (s) { const keys = { ak: 'account_pubkey', ok: 'oracle_pubkey' } if (!s.match(/^[a-z]{2}_.+/)) { throw Error('Not a valid hash') } const klass = s.substr(0, 2) if (klass in keys) { return keys[klass] } else { throw Error(`Unknown class ${klass}`) } } /** * Update an aens entry * @instance * @function * @alias module:@aeternity/aepp-sdk/es/ae/aens * @param nameId domain hash * @param target new target * @param options * @return {Object} */ async function update (nameId, target, options = {}) { const opt = R.merge(this.Ae.defaults, options) const nameUpdateTx = await this.nameUpdateTx(R.merge(opt, { nameId: nameId, accountId: await this.address(), pointers: [R.fromPairs([['id', target], ['key', classify(target)]])] })) return this.send(nameUpdateTx, opt) } /** * Query the status of an AENS registration * @instance * @function * @alias module:@aeternity/aepp-sdk/es/ae/aens * @param {string} name * @return {Promise<Object>} */ async function query (name) { const o = await this.getName(name) const nameId = o.id return Object.freeze(Object.assign(o, { pointers: o.pointers || {}, update: async (target, options) => { return { ...(await this.aensUpdate(nameId, target, options)), ...(await this.aensQuery(name)) } }, transfer: async (account, options) => { return { ...(await this.aensTransfer(nameId, account, options)), ...(await this.aensQuery(name)) } }, revoke: async (options) => this.aensRevoke(nameId, options) })) } /** * Claim a previously preclaimed registration. This can only be done after the * preclaim step * @instance * @function * @alias module:@aeternity/aepp-sdk/es/ae/aens * @param {String} name * @param {String} salt * @param {Record} [options={}] * @return {Promise<Object>} the result of the claim */ async function claim (name, salt, options = {}) { const opt = R.merge(this.Ae.defaults, options) const claimTx = await this.nameClaimTx(R.merge(opt, { accountId: await this.address(), nameSalt: salt, name: `nm_${encodeBase58Check(Buffer.from(name))}` })) const result = await this.send(claimTx, opt) return { ...result, ...opt.waitMined && await this.aensQuery(name) } } /** * Preclaim a name. Sends a hash of the name and a random salt to the node * @instance * @function * @alias module:@aeternity/aepp-sdk/es/ae/aens * @param {string} name * @param {Record} [options={}] * @return {Promise<Object>} */ async function preclaim (name, options = {}) { const opt = R.merge(this.Ae.defaults, options) const _salt = salt() const height = await this.height() const hash = await commitmentHash(name, _salt) const preclaimTx = await this.namePreclaimTx(R.merge(opt, { accountId: await this.address(), commitmentId: hash })) const result = await this.send(preclaimTx, opt) return Object.freeze({ ...result, height, claim: options => this.aensClaim(name, _salt, (height + 1), options), salt: _salt, commitmentId: hash }) } /** * Aens Stamp * * Aens provides name-system related methods atop * {@link module:@aeternity/aepp-sdk/es/ae--Ae} clients. * @function * @alias module:@aeternity/aepp-sdk/es/ae/aens * @rtype Stamp * @param {Object} [options={}] - Initializer object * @return {Object} Aens instance */ const Aens = Ae.compose({ methods: { aensQuery: query, aensPreclaim: preclaim, aensClaim: claim, aensUpdate: update, aensTransfer: transfer, aensRevoke: revoke }, deepProps: { Ae: { defaults: { clientTtl: 1, nameTtl: 50000 // aec_governance:name_claim_max_expiration() => 50000 } } } }) export default Aens