@ngraveio/bc-ur-multi-layer-sync
Version:
Provides BC-UR types for syncing multiple coins and accounts from cold wallets to watch only wallets.
152 lines • 7.03 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.CryptoDetailedAccount = void 0;
const bc_ur_registry_1 = require("@keystonehq/bc-ur-registry");
const RegistryType_1 = require("./RegistryType");
const bc_ur_registry_hex_string_1 = require("@ngraveio/bc-ur-registry-hex-string");
const { RegistryTypes, decodeToDataItem } = bc_ur_registry_1.extend;
var Keys;
(function (Keys) {
Keys[Keys["account"] = 1] = "account";
Keys[Keys["tokenIds"] = 2] = "tokenIds";
})(Keys || (Keys = {}));
class CryptoDetailedAccount extends bc_ur_registry_1.RegistryItem {
constructor(account, tokenIds) {
super();
this.getRegistryType = () => RegistryType_1.ExtendedRegistryTypes.CRYPTO_DETAILED_ACCOUNT;
this.getAccount = () => this.account;
this.getCryptoHDKey = () => { return this.account instanceof bc_ur_registry_1.CryptoHDKey ? this.account : undefined; };
this.getCryptoOutput = () => { return this.account instanceof bc_ur_registry_1.CryptoOutput ? this.account : undefined; };
this.getTokenIds = () => {
if (!this.tokenIds)
return undefined;
// Always return string representation of the token ids
return this.tokenIds.map((tokenId) => {
if (tokenId instanceof bc_ur_registry_hex_string_1.HexString) {
// Shall we really add 0x to start?
return '0x' + tokenId.getData();
}
return tokenId;
});
};
this.toDataItem = () => {
const map = {};
// Set account based on its type CryptoHDkey or CryptoOutput
let dataItemAccount;
// Convert to data item
dataItemAccount = this.account.toDataItem();
const accountTag = this.account.getRegistryType().getTag();
// There is a bug in crypto output, it doesnt have top level datatem
// Add one layer of data item if its crypto output and contains tag
if (accountTag == RegistryTypes.CRYPTO_OUTPUT.getTag() && dataItemAccount.getTag()) {
dataItemAccount = new bc_ur_registry_1.DataItem(dataItemAccount);
}
// Now set the tag
dataItemAccount.setTag(this.account.getRegistryType().getTag());
map[Keys.account] = dataItemAccount;
// Return TokenIds based on their type
if (this.tokenIds) {
map[Keys.tokenIds] = this.tokenIds.map((tokenId) => {
if (tokenId instanceof bc_ur_registry_hex_string_1.HexString)
return tokenId.toDataItem();
return tokenId;
});
}
return new bc_ur_registry_1.DataItem(map);
};
// Validate inputs
CryptoDetailedAccount.checkAccount(account);
this.account = account;
// Token Ids are just hex string for erc20 token like 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
// For ESDT and SPL types its going to be encoded as string
// We will try to parse the string into bytes with removing 0x part,
// if we cannot we will encode it as utf8 string
if (Array.isArray(tokenIds)) {
this.tokenIds = tokenIds.map((tokenId) => {
// If its an instance of hexString already just return it
if (tokenId instanceof bc_ur_registry_hex_string_1.HexString)
return tokenId;
// If its buffer or a string try to parse as HexString
try {
return new bc_ur_registry_hex_string_1.HexString(tokenId);
}
catch (error) {
// TODO: check the error if its not hex
return tokenId;
}
});
}
}
static checkAccount(account) {
if (!(account instanceof bc_ur_registry_1.CryptoHDKey) && !(account instanceof bc_ur_registry_1.CryptoOutput)) {
throw new Error('account must be instance of CryptoHDKey or CryptoOutput');
}
// only accept cryptoOutput if it has CryptoHDKey type instead of CryptoECKey
if (account instanceof bc_ur_registry_1.CryptoOutput) {
// Check if it has hdkey
if (!(account.getHDKey() instanceof bc_ur_registry_1.CryptoHDKey)) {
throw new Error('account must be instance of CryptoHDKey or CryptoOutput cointaining CryptoHDKey');
}
// Check if HDkey has origin and a valid path
CryptoDetailedAccount.checkHdKey(account.getHDKey());
}
else {
// Check if HDkey has origin and a valid path
CryptoDetailedAccount.checkHdKey(account);
}
}
static checkHdKey(hdKey) {
// Check if hdkey has origin and a valid path
if (!hdKey.getOrigin() || !hdKey.getOrigin().getPath()) {
throw new Error("HdKey must have origin and path information eg: m/44'/60'/0'/0/0");
}
}
}
exports.CryptoDetailedAccount = CryptoDetailedAccount;
CryptoDetailedAccount.fromDataItem = (dataItem) => {
const map = dataItem.getData();
let account;
let tokenIds = undefined;
const accountDataItem = map[Keys.account];
const accountTag = accountDataItem.getTag();
// Cast to correct type based on tag
if (accountTag == RegistryTypes.CRYPTO_HDKEY.getTag()) {
account = bc_ur_registry_1.CryptoHDKey.fromDataItem(accountDataItem);
}
else if (accountTag == RegistryTypes.CRYPTO_OUTPUT.getTag()) {
// Because of the bug, we need to remove the top level data item
// First we will try as it should be, then with bug fix
try {
account = bc_ur_registry_1.CryptoOutput.fromDataItem(accountDataItem);
}
catch (error) {
account = bc_ur_registry_1.CryptoOutput.fromDataItem(accountDataItem.getData());
}
}
else {
throw new Error(`Invalid tag for account: ${accountTag}`);
}
// If token-ids are provided
if (map[Keys.tokenIds]) {
// Now check the type of token-ids
const tokenIdsRead = map[Keys.tokenIds];
// Parse every element in the array
tokenIds = tokenIdsRead.map((tokenId) => {
// Check if string
if (typeof tokenId == 'string')
return tokenId;
// Check if hex string
else if (tokenId instanceof bc_ur_registry_1.DataItem) {
return bc_ur_registry_hex_string_1.HexString.fromDataItem(tokenId);
}
else
throw new Error(`Invalid type for token-id: ${typeof tokenId}`);
});
}
return new CryptoDetailedAccount(account, tokenIds);
};
CryptoDetailedAccount.fromCBOR = (_cborPayload) => {
const dataItem = decodeToDataItem(_cborPayload);
return CryptoDetailedAccount.fromDataItem(dataItem);
};
//# sourceMappingURL=CryptoDetailedAccount.js.map