xdb-digitalbits-base
Version:
Low level digitalbits support library
136 lines (119 loc) • 5.64 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.decodeAddressToMuxedAccount = decodeAddressToMuxedAccount;
exports.encodeMuxedAccountToAddress = encodeMuxedAccountToAddress;
exports.encodeMuxedAccount = encodeMuxedAccount;
var _isString = require('lodash/isString');
var _isString2 = _interopRequireDefault(_isString);
var _digitalbitsXdr_generated = require('../generated/digitalbits-xdr_generated');
var _digitalbitsXdr_generated2 = _interopRequireDefault(_digitalbitsXdr_generated);
var _strkey = require('../strkey');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Converts a DigitalBits address (in G... or M... form) to an XDR MuxedAccount
* structure, forcing the ed25519 representation by default.
*
* This optionally (that is, opt-in only) supports proper muxed accounts, where
* an M... address will resolve to both its underlying G... address and an ID.
* Note that this behaviour will eventually be the default.
*
* @function
*
* @param {string} address G... or M... address to encode into XDR
* @param {bool} [supportMuxing] allows decoding of the muxed
* representation of the address, extracting the underlying ID from the M...
* address
*
* @returns {xdr.MuxedAccount} a muxed account object for this address string
*
* @note If you pass a G... address and DO specify supportMuxing=true, then
* this will return an xdr.MuxedAccount with an ID of zero.
* @warning If you pass an M... address and do NOT specify supportMuxing=true,
* then this function will throw an error.
*/
function decodeAddressToMuxedAccount(address, supportMuxing) {
if (supportMuxing) {
if (_strkey.StrKey.isValidMed25519PublicKey(address)) {
return _decodeAddressFullyToMuxedAccount(address);
}
if (_strkey.StrKey.isValidEd25519PublicKey(address)) {
return encodeMuxedAccount(address, '0');
}
}
return _digitalbitsXdr_generated2.default.MuxedAccount.keyTypeEd25519(_strkey.StrKey.decodeEd25519PublicKey(address));
}
/**
* Converts an xdr.MuxedAccount to its string representation.
*
* By default, this returns its "G..." string representation (i.e. forcing the
* ed25519 representation), but can return the "M..." representation via opt-in.
*
* @function
*
* @param {xdr.MuxedAccount} muxedAccount account to stringify
* @param {bool} [supportMuxing] converts the object into its full,
* proper M... address, encoding both the underlying G... address and the
* Muxing ID
*
* @returns {string} stringified G... (corresponding to the underlying pubkey)
* or M... address (corresponding to both the key and the muxed ID)
*/
function encodeMuxedAccountToAddress(muxedAccount, supportMuxing) {
if (muxedAccount.switch().value === _digitalbitsXdr_generated2.default.CryptoKeyType.keyTypeMuxedEd25519().value) {
if (supportMuxing) {
return _encodeMuxedAccountFullyToAddress(muxedAccount);
}
muxedAccount = muxedAccount.med25519();
}
return _strkey.StrKey.encodeEd25519PublicKey(muxedAccount.ed25519());
}
/**
* Transform a DigitalBits address (G...) and an ID into its XDR representation.
*
* @param {string} address - a DigitalBits G... address
* @param {string} id - a Uint64 ID represented as a string
* @return {xdr.MuxedAccount} - XDR representation of the above muxed account
*/
function encodeMuxedAccount(address, id) {
if (!_strkey.StrKey.isValidEd25519PublicKey(address)) {
throw new Error('address should be a DigitalBits account ID (G...)');
}
if (!(0, _isString2.default)(id)) {
throw new Error('id should be a string representing a number (uint64)');
}
return _digitalbitsXdr_generated2.default.MuxedAccount.keyTypeMuxedEd25519(new _digitalbitsXdr_generated2.default.MuxedAccountMed25519({
id: _digitalbitsXdr_generated2.default.Uint64.fromString(id),
ed25519: _strkey.StrKey.decodeEd25519PublicKey(address)
}));
}
// Decodes an "M..." account ID into its MuxedAccount object representation.
function _decodeAddressFullyToMuxedAccount(address) {
var rawBytes = _strkey.StrKey.decodeMed25519PublicKey(address);
// Decoding M... addresses cannot be done through a simple
// MuxedAccountMed25519.fromXDR() call, because the definition is:
//
// constructor(attributes: { id: Uint64; ed25519: Buffer });
//
// Note the ID is the first attribute. However, the ID comes *last* in the
// stringified (base32-encoded) address itself (it's the last 8-byte suffix).
// The `fromXDR()` method interprets bytes in order, so we need to parse out
// the raw binary into its requisite parts, i.e. use the MuxedAccountMed25519
// constructor directly.
//
// Refer to https://github.com/xdbfoundation/go/blob/master/xdr/muxed_account.go#L26
// for the Golang implementation of the M... parsing.
return _digitalbitsXdr_generated2.default.MuxedAccount.keyTypeMuxedEd25519(new _digitalbitsXdr_generated2.default.MuxedAccountMed25519({
id: _digitalbitsXdr_generated2.default.Uint64.fromXDR(rawBytes.slice(-8)),
ed25519: rawBytes.slice(0, -8)
}));
}
// Converts an xdr.MuxedAccount into its *true* "M..." string representation.
function _encodeMuxedAccountFullyToAddress(muxedAccount) {
if (muxedAccount.switch() === _digitalbitsXdr_generated2.default.CryptoKeyType.keyTypeEd25519()) {
return encodeMuxedAccountToAddress(muxedAccount);
}
var muxed = muxedAccount.med25519();
return _strkey.StrKey.encodeMed25519PublicKey(Buffer.concat([muxed.ed25519(), muxed.id().toXDR('raw')]));
}