@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
JavaScript
;
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