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.

134 lines 6.68 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.CryptoSyncCoin = void 0; const bc_ur_registry_1 = require("@keystonehq/bc-ur-registry"); const RegistryType_1 = require("./RegistryType"); const CryptoDetailedAccount_1 = require("./CryptoDetailedAccount"); const bc_ur_registry_crypto_coin_identity_1 = require("@ngraveio/bc-ur-registry-crypto-coin-identity"); const { RegistryTypes, decodeToDataItem } = bc_ur_registry_1.extend; var Keys; (function (Keys) { Keys[Keys["coin_id"] = 1] = "coin_id"; Keys[Keys["accounts"] = 2] = "accounts"; Keys[Keys["masterFingerprint"] = 3] = "masterFingerprint"; })(Keys || (Keys = {})); class CryptoSyncCoin extends bc_ur_registry_1.RegistryItem { constructor(coin_id, accounts, master_fingerprint) { super(); this.getRegistryType = () => RegistryType_1.ExtendedRegistryTypes.CRYPTO_SYNC_COIN; this.getCoinId = () => this.coin_id; this.getAccounts = () => this.accounts; this.getCryptoAccount = () => (this.accounts instanceof bc_ur_registry_1.CryptoAccount ? this.accounts : undefined); this.getCryptoMultiAccounts = () => (this.accounts instanceof bc_ur_registry_1.CryptoMultiAccounts ? this.accounts : undefined); this.getDetailedAccounts = () => (this.accounts instanceof Array ? this.accounts : undefined); this.getMasterFingerprint = () => this.masterFingerprint; this.toDataItem = () => { const map = {}; map[Keys.coin_id] = this.coin_id.toDataItem(); map[Keys.coin_id].setTag(this.coin_id.getRegistryType().getTag()); // Convert accounts base on type, first check if array if (Array.isArray(this.accounts)) { // This meants its CryptoDetailedAccount[] map[Keys.accounts] = this.accounts.map((account) => { const dataItem = account.toDataItem(); dataItem.setTag(account.getRegistryType().getTag()); return dataItem; }); } else { // This means its CryptoAccount | CryptoMultiAccounts const dataItem = this.accounts.toDataItem(); dataItem.setTag(this.accounts.getRegistryType().getTag()); map[Keys.accounts] = dataItem; } // If master_fingerprint is set add it to map if (this.masterFingerprint) { map[Keys.masterFingerprint] = this.masterFingerprint.readUInt32BE(0); } return new bc_ur_registry_1.DataItem(map); }; // Be sure that coinId is correct type if (!(coin_id instanceof bc_ur_registry_crypto_coin_identity_1.CryptoCoinIdentity)) { throw new Error('CoinId is not type of CryptoCoinIdentity'); } // TODO: add checks for edwards coins thats paths must be all hardened // Be sure that accounts is correct type CryptoSyncCoin.checkInputs(accounts, master_fingerprint); this.coin_id = coin_id; this.accounts = accounts; this.masterFingerprint = master_fingerprint; } } exports.CryptoSyncCoin = CryptoSyncCoin; CryptoSyncCoin.checkInputs = (accounts, masterFingerprint) => { // if its detailed_accounts array, run CryptoDetailedAccount.checkAccount for each of them if (Array.isArray(accounts)) { accounts.forEach((account) => { // check if account is type of detailed account // if not throw error if (!(account instanceof CryptoDetailedAccount_1.CryptoDetailedAccount)) { throw new Error('Account is not type of CryptoDetailedAccount'); } // run checkAccount for each of the detailed account CryptoDetailedAccount_1.CryptoDetailedAccount.checkAccount(account.getAccount()); }); } else if (accounts instanceof bc_ur_registry_1.CryptoAccount) { // Be sure that masterfingerprint is same as the one in CryptoAccount if (masterFingerprint?.toString('hex') !== accounts.getMasterFingerprint().toString('hex')) { throw new Error('Master fingerprint is not the same as the one in CryptoAccount'); } // We will run checks on each of the CryptoOutput in CryptoAccount accounts.getOutputDescriptors().forEach((output) => { CryptoDetailedAccount_1.CryptoDetailedAccount.checkAccount(output); }); } else if (accounts instanceof bc_ur_registry_1.CryptoMultiAccounts) { // Be sure that masterfingerprint is same as the one in CryptoMultiAccounts if (masterFingerprint?.toString('hex') !== accounts.getMasterFingerprint().toString('hex')) { throw new Error('Master fingerprint is not the same as the one in CryptoMultiAccounts'); } // We will run checks on each of the CryptoAccount in CryptoMultiAccounts accounts.getKeys().forEach((hdKey) => { CryptoDetailedAccount_1.CryptoDetailedAccount.checkAccount(hdKey); }); } }; CryptoSyncCoin.fromDataItem = (dataItem) => { const map = dataItem.getData(); const coin_id = bc_ur_registry_crypto_coin_identity_1.CryptoCoinIdentity.fromDataItem(map[Keys.coin_id]); let masterFingerprint = undefined; const _masterFingerprint = map[Keys.masterFingerprint]; if (_masterFingerprint) { masterFingerprint = Buffer.alloc(4); masterFingerprint.writeUInt32BE(_masterFingerprint, 0); } // Check if accounts is an array const accounts = map[Keys.accounts]; let accountsParsed; if (Array.isArray(accounts)) { // This means its CryptoDetailedAccount[] accountsParsed = accounts.map((account) => { return CryptoDetailedAccount_1.CryptoDetailedAccount.fromDataItem(account); }); } else { // This means its CryptoAccount | CryptoMultiAccounts const accountTag = accounts.getTag(); if (accountTag === RegistryTypes.CRYPTO_ACCOUNT.getTag()) { accountsParsed = bc_ur_registry_1.CryptoAccount.fromDataItem(accounts); } else if (accountTag === RegistryTypes.CRYPTO_MULTI_ACCOUNTS.getTag()) { accountsParsed = bc_ur_registry_1.CryptoMultiAccounts.fromDataItem(accounts); } else { throw new Error('Invalid account type'); } } return new CryptoSyncCoin(coin_id, accountsParsed, masterFingerprint); }; CryptoSyncCoin.fromCBOR = (_cborPayload) => { const dataItem = decodeToDataItem(_cborPayload); return CryptoSyncCoin.fromDataItem(dataItem); }; //# sourceMappingURL=CryptoSyncCoin.js.map