UNPKG

@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
"use strict"; 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