UNPKG

@radixdlt/application

Version:

A JavaScript client library for interacting with the Radix Distributed Ledger.

524 lines 29.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Radix = void 0; const tslib_1 = require("tslib"); const account_1 = require("@radixdlt/account"); const networking_1 = require("@radixdlt/networking"); const api_1 = require("./api"); const operators_1 = require("rxjs/operators"); const rxjs_1 = require("rxjs"); const crypto_1 = require("@radixdlt/crypto"); const errors_1 = require("./errors"); const util_1 = require("@radixdlt/util"); const dto_1 = require("./dto"); const actions_1 = require("./actions"); const wallet_1 = require("./wallet"); const _1 = require("."); const utils_1 = require("./api/utils"); const txTypeFromActions = (input) => { const { activeAddress } = input; const myAddress = activeAddress.toString(); const fromUnique = (0, dto_1.flatMapAddressesOf)(Object.assign(Object.assign({}, input), { includeTo: false })).map(a => a.toString()); const toUnique = (0, dto_1.flatMapAddressesOf)(Object.assign(Object.assign({}, input), { includeFrom: false })).map(a => a.toString()); const toMe = toUnique.includes(myAddress); const fromMe = fromUnique.includes(myAddress); if (toMe && fromMe) { return dto_1.TransactionType.FROM_ME_TO_ME; } else if (toMe) { return dto_1.TransactionType.INCOMING; } else if (fromMe) { return dto_1.TransactionType.OUTGOING; } else { return dto_1.TransactionType.UNRELATED; } }; const decorateSimpleExecutedTransactionWithType = (simpleExecutedTX, activeAddress) => (Object.assign(Object.assign({}, simpleExecutedTX), { transactionType: txTypeFromActions({ actions: simpleExecutedTX.actions, activeAddress, }) })); const shouldConfirmTransactionAutomatically = (confirmationScheme) => confirmationScheme === 'skip'; const create = () => { const subs = new rxjs_1.Subscription(); const radixLog = util_1.log; // TODO configure child loggers const nodeSubject = new rxjs_1.ReplaySubject(); const coreAPISubject = new rxjs_1.ReplaySubject(); const walletSubject = new rxjs_1.ReplaySubject(); const errorNotificationSubject = new rxjs_1.Subject(); const deriveNextLocalHDAccountSubject = new rxjs_1.Subject(); const addAccountByPrivateKeySubject = new rxjs_1.Subject(); const switchAccountSubject = new rxjs_1.Subject(); const tokenBalanceFetchSubject = new rxjs_1.Subject(); const stakingFetchSubject = new rxjs_1.Subject(); const wallet$ = walletSubject.asObservable(); const networkSubject = new rxjs_1.ReplaySubject(); const nativeTokenSubject = new rxjs_1.ReplaySubject(); let walletSubscription; const coreAPIViaNode$ = nodeSubject .asObservable() .pipe((0, operators_1.map)((n) => (0, api_1.radixCoreAPI)(n, (0, api_1.nodeAPI)(n.url)))); const coreAPI$ = (0, rxjs_1.merge)(coreAPIViaNode$, coreAPISubject.asObservable()).pipe((0, operators_1.shareReplay)(1)); // Forwards calls to RadixCoreAPI, return type is a function: `(input?: I) => Observable<O>` const fwdAPICall = (pickFn, errorFn) => (...input) => coreAPI$.pipe((0, operators_1.mergeMap)(a => pickFn(a)(...input)), (0, operators_1.take)(1), // Important! (0, operators_1.catchError)((error) => { throw errorFn((0, util_1.isArray)(error) ? error[0] : error); })); const api = { networkId: fwdAPICall(a => a.networkId, m => (0, errors_1.networkIdErr)(m)), tokenBalancesForAddress: fwdAPICall(a => a.tokenBalancesForAddress, m => (0, errors_1.tokenBalancesErr)(m)), transactionHistory: fwdAPICall(a => a.transactionHistory, m => (0, errors_1.transactionHistoryErr)(m)), recentTransactions: fwdAPICall(a => a.recentTransactions, m => (0, errors_1.recentTransactionsErr)(m)), nativeToken: fwdAPICall(a => a.nativeToken, m => (0, errors_1.nativeTokenErr)(m)), tokenInfo: fwdAPICall(a => a.tokenInfo, m => (0, _1.tokenInfoErr)(m)), stakesForAddress: fwdAPICall(a => a.stakesForAddress, m => (0, errors_1.stakesForAddressErr)(m)), unstakesForAddress: fwdAPICall(a => a.unstakesForAddress, m => (0, errors_1.unstakesForAddressErr)(m)), validators: fwdAPICall(a => a.validators, m => (0, errors_1.validatorsErr)(m)), lookupValidator: fwdAPICall(a => a.lookupValidator, m => (0, errors_1.lookupValidatorErr)(m)), getTransaction: fwdAPICall(a => a.transactionStatus, m => (0, errors_1.lookupTxErr)(m)), buildTransaction: fwdAPICall(a => a.buildTransaction, m => (0, errors_1.buildTxFromIntentErr)(m)), finalizeTransaction: fwdAPICall(a => a.finalizeTransaction, m => (0, errors_1.finalizeTxErr)(m)), submitSignedTransaction: fwdAPICall(a => a.submitSignedTransaction, m => (0, errors_1.submitSignedTxErr)(m)), }; const activeAddress = wallet$.pipe((0, operators_1.mergeMap)(a => a.observeActiveAccount()), (0, operators_1.map)(a => a.address), (0, operators_1.shareReplay)(1)); const revealMnemonic = () => wallet$.pipe((0, operators_1.map)((wallet) => wallet.revealMnemonic())); const activeAddressToAPIObservableWithTrigger = (trigger, pickFn, errorFn) => (0, rxjs_1.merge)(trigger.pipe((0, operators_1.withLatestFrom)(activeAddress), (0, operators_1.map)(result => result[1])), activeAddress).pipe((0, operators_1.withLatestFrom)(coreAPI$), (0, operators_1.switchMap)(([address, api]) => pickFn(api)(address).pipe((0, operators_1.catchError)(error => { console.error(error); errorNotificationSubject.next(errorFn(error)); return rxjs_1.EMPTY; }))), (0, operators_1.shareReplay)(1)); const tokenBalances = activeAddressToAPIObservableWithTrigger(tokenBalanceFetchSubject, a => a.tokenBalancesForAddress, errors_1.tokenBalancesErr); /* const decorateSimpleTokenBalanceWithTokenInfo = ( simpleTokenBalance: SimpleTokenBalance, ): Observable<TokenBalance> => api.tokenInfo(simpleTokenBalance.tokenIdentifier).pipe( map( (tokenInfo: Token): TokenBalance => ({ amount: simpleTokenBalance.amount, token: tokenInfo, }), ), ) */ const stakingPositions = activeAddressToAPIObservableWithTrigger(stakingFetchSubject, a => a.stakesForAddress, errors_1.stakesForAddressErr); const unstakingPositions = activeAddressToAPIObservableWithTrigger(stakingFetchSubject, a => a.unstakesForAddress, errors_1.unstakesForAddressErr); const transactionHistory = (input) => activeAddress.pipe((0, operators_1.take)(1), (0, operators_1.switchMap)(activeAddress => api .transactionHistory(Object.assign(Object.assign({}, input), { address: activeAddress })) .pipe((0, operators_1.map)((simpleTxHistory) => (Object.assign(Object.assign({}, simpleTxHistory), { transactions: simpleTxHistory.transactions.map((simpleExecutedTX) => decorateSimpleExecutedTransactionWithType(simpleExecutedTX, activeAddress)) })))))); const node$ = (0, rxjs_1.merge)(nodeSubject.asObservable(), coreAPISubject.asObservable().pipe((0, operators_1.map)(api => api.node))); const activeAccount = wallet$.pipe((0, operators_1.mergeMap)(wallet => wallet.observeActiveAccount()), (0, operators_1.shareReplay)(1), (0, operators_1.distinctUntilChanged)((prev, cur) => prev.equals(cur))); const accounts = wallet$.pipe((0, operators_1.mergeMap)(wallet => wallet.observeAccounts()), (0, operators_1.shareReplay)(1)); const __makeTransactionFromIntent = (transactionIntent$, options) => { var _a; const txLog = radixLog; // TODO configure child loggers const txSubs = new rxjs_1.Subscription(); txLog.debug(`Start of transaction flow, inside constructor of 'TransactionTracking'.`); const signUnsignedTx = (unsignedTx) => { txLog.debug('Starting signing transaction (async).'); return (0, rxjs_1.combineLatest)(transactionIntent$, activeAccount.pipe((0, operators_1.take)(1))).pipe((0, operators_1.mergeMap)(([transactionIntent, account,]) => { const nonXRDHRPsOfRRIsInTx = transactionIntent.actions .filter(a => a.type === actions_1.ActionType.TOKEN_TRANSFER) .map(a => a) .filter(t => t.rri.name !== 'xrd') .map(t => t.rri.name); const uniquenonXRDHRPsOfRRIsInTx = [ ...new Set(nonXRDHRPsOfRRIsInTx), ]; if (uniquenonXRDHRPsOfRRIsInTx.length > 1) { const errMsg = `Error cannot sign transction with multiple non-XRD RRIs. Unsupported by Ledger app.`; util_1.log.error(errMsg); return (0, rxjs_1.throwError)(new Error(errMsg)); } const nonXRDHrp = uniquenonXRDHRPsOfRRIsInTx.length === 1 ? uniquenonXRDHRPsOfRRIsInTx[0] : undefined; return account .sign(unsignedTx.transaction, nonXRDHrp) .pipe((0, operators_1.map)((signature) => { const publicKeyOfSigner = account.publicKey; txLog.debug(`Finished signing transaction`); return { transaction: unsignedTx.transaction, signature, publicKeyOfSigner, }; })); })); }; const pendingTXSubject = new rxjs_1.Subject(); const askUserToConfirmSubject = new rxjs_1.ReplaySubject(); const userDidConfirmTransactionSubject = new rxjs_1.ReplaySubject(); if (shouldConfirmTransactionAutomatically(options.userConfirmation)) { txLog.debug('Transaction has been setup to be automatically confirmed, requiring no final confirmation input from user.'); txSubs.add(askUserToConfirmSubject.subscribe(() => { txLog.debug(`askUserToConfirmSubject got 'next', calling 'next' on 'userDidConfirmTransactionSubject'`); userDidConfirmTransactionSubject.next(0); })); } else { txLog.debug(`Transaction has been setup so that it requires a manual final confirmation from user before being finalized.`); const twoWayConfirmationSubject = options.userConfirmation; txSubs.add(askUserToConfirmSubject.subscribe(ux => { txLog.info(`Forwarding signedUnconfirmedTX and 'userDidConfirmTransactionSubject' to subject 'twoWayConfirmationSubject' now (inside subscribe to 'askUserToConfirmSubject')`); const confirmation = { txToConfirm: ux, confirm: () => userDidConfirmTransactionSubject.next(0), }; twoWayConfirmationSubject.next(confirmation); })); } const trackingSubject = new rxjs_1.ReplaySubject(); const track = (event) => { trackingSubject.next(event); }; const completionSubject = new rxjs_1.Subject(); const trackError = (input) => { const errorEvent = { eventUpdateType: input.inStep, error: input.error, }; txLog.debug(`Forwarding error to 'errorSubject'`); track(errorEvent); completionSubject.error(errorEvent.error); }; const builtTransaction$ = transactionIntent$.pipe((0, operators_1.withLatestFrom)(activeAddress), (0, operators_1.switchMap)(([intent, address]) => { txLog.debug('Transaction intent created => requesting 🛰 API to build it now.'); track({ transactionState: intent, eventUpdateType: dto_1.TransactionTrackingEventType.INITIATED, }); return api.buildTransaction(intent, address); }), (0, operators_1.catchError)((e) => { txLog.error(`API failed to build transaction`); trackError({ error: e, inStep: dto_1.TransactionTrackingEventType.BUILT_FROM_INTENT, }); return rxjs_1.EMPTY; }), (0, operators_1.tap)(builtTx => { txLog.debug('TX built by API => asking for confirmation to sign...'); track({ transactionState: builtTx, eventUpdateType: dto_1.TransactionTrackingEventType.BUILT_FROM_INTENT, }); askUserToConfirmSubject.next(builtTx); }), (0, operators_1.tap)(builtTx => { track({ transactionState: builtTx, eventUpdateType: dto_1.TransactionTrackingEventType.ASKED_FOR_CONFIRMATION, }); })); const signedTransaction$ = (0, rxjs_1.combineLatest)([ builtTransaction$, userDidConfirmTransactionSubject, ]).pipe((0, operators_1.map)(([signedTx, _]) => signedTx), (0, operators_1.tap)(unsignedTx => { track({ transactionState: unsignedTx, eventUpdateType: dto_1.TransactionTrackingEventType.CONFIRMED, }); }), (0, operators_1.mergeMap)(unsignedTx => signUnsignedTx(unsignedTx)), (0, operators_1.shareReplay)(1), (0, operators_1.catchError)((e) => { txLog.error(`API failed to sign transaction, error: ${JSON.stringify(e, null, 4)}`); trackError({ error: e, inStep: dto_1.TransactionTrackingEventType.SIGNED, }); return rxjs_1.EMPTY; })); const finalizedTx$ = signedTransaction$.pipe((0, operators_1.mergeMap)((signedTx) => { txLog.debug(`Finished signing tx => submitting it to 🛰 API.`); track({ transactionState: signedTx, eventUpdateType: dto_1.TransactionTrackingEventType.SIGNED, }); return networkSubject.pipe((0, operators_1.mergeMap)(network => api.finalizeTransaction(network, signedTx))); }), (0, operators_1.catchError)((e) => { txLog.error(`API failed to submit transaction, error: ${JSON.stringify(e, null, 4)}`); trackError({ error: e, inStep: dto_1.TransactionTrackingEventType.FINALIZED, }); return rxjs_1.EMPTY; }), (0, operators_1.tap)(finalizedTx => { track({ transactionState: finalizedTx, eventUpdateType: dto_1.TransactionTrackingEventType.FINALIZED, }); })); txSubs.add(finalizedTx$ .pipe((0, operators_1.mergeMap)((finalizedTx) => networkSubject.pipe((0, operators_1.mergeMap)(network => api.submitSignedTransaction(network, { blob: finalizedTx.blob, txID: finalizedTx.txID, })))), (0, operators_1.catchError)((e) => { txLog.error(`API failed to submit transaction, error: ${JSON.stringify(e, null, 4)}`); trackError({ error: e, inStep: dto_1.TransactionTrackingEventType.SUBMITTED, }); return rxjs_1.EMPTY; }), (0, operators_1.tap)({ next: (pendingTx) => { txLog.debug(`Submitted transaction with txID='${pendingTx.txID.toString()}', it is now pending.`); track({ transactionState: pendingTx, eventUpdateType: dto_1.TransactionTrackingEventType.SUBMITTED, }); pendingTXSubject.next(pendingTx); }, error: (submitTXError) => { // TODO would be great to have access to txID here, hopefully API includes it in error msg? txLog.error(`Submission of signed transaction to API failed with error: ${submitTXError.message}`); pendingTXSubject.error(submitTXError); }, })) .subscribe()); const pollTxStatusTrigger = ((_a = options.pollTXStatusTrigger) !== null && _a !== void 0 ? _a : (0, rxjs_1.interval)(1000)).pipe((0, operators_1.share)()); const transactionStatus$ = (0, rxjs_1.combineLatest)([ pollTxStatusTrigger, pendingTXSubject, ]).pipe((0, operators_1.mergeMap)(([_, pendingTx]) => { txLog.debug(`Asking API for status of transaction with txID: ${pendingTx.txID.toString()}`); return networkSubject.pipe((0, operators_1.mergeMap)(network => api.getTransaction(pendingTx.txID, network).pipe((0, operators_1.retryWhen)((0, utils_1.retryOnErrorCode)({ maxRetryAttempts: 3, errorCodes: [404], }))))); }), (0, operators_1.distinctUntilChanged)((prev, cur) => prev.status === cur.status), (0, operators_1.share)()); const transactionCompletedWithStatusConfirmed$ = transactionStatus$.pipe((0, operators_1.skipWhile)(({ status }) => status !== dto_1.TransactionStatus.CONFIRMED), (0, operators_1.take)(1)); const transactionCompletedWithStatusFailed$ = transactionStatus$.pipe((0, operators_1.skipWhile)(({ status }) => status !== dto_1.TransactionStatus.FAILED), (0, operators_1.take)(1)); txSubs.add(transactionStatus$.subscribe({ next: statusOfTransaction => { const { status, txID } = statusOfTransaction; txLog.debug(`Status ${status.toString()} of transaction with txID='${txID.toString()}'`); track({ transactionState: statusOfTransaction, eventUpdateType: dto_1.TransactionTrackingEventType.UPDATE_OF_STATUS_OF_PENDING_TX, }); }, error: (transactionStatusError) => { // TODO hmm how to get txID here? txLog.error(`Failed to get status of transaction`, transactionStatusError); }, })); txSubs.add(transactionCompletedWithStatusConfirmed$.subscribe({ next: statusOfTransaction => { const { txID } = statusOfTransaction; txLog.info(`Transaction with txID='${txID.toString()}' has completed succesfully.`); track({ transactionState: statusOfTransaction, eventUpdateType: dto_1.TransactionTrackingEventType.COMPLETED, }); completionSubject.next(txID); completionSubject.complete(); txSubs.unsubscribe(); }, })); txSubs.add(transactionCompletedWithStatusFailed$.subscribe(status => { const errMsg = `API status of tx with id=${status.txID.toString()} returned 'FAILED'`; txLog.error(errMsg); trackError({ error: new Error(errMsg), inStep: dto_1.TransactionTrackingEventType.UPDATE_OF_STATUS_OF_PENDING_TX, }); txSubs.unsubscribe(); })); return { completion: completionSubject.asObservable(), events: trackingSubject.asObservable(), }; }; const __makeTransactionFromBuilder = (transactionIntentBuilderT, makeTXOptions, builderOptions) => { radixLog.debug(`make transaction from builder`); const intent$ = transactionIntentBuilderT.build(builderOptions !== null && builderOptions !== void 0 ? builderOptions : { skipEncryptionOfMessageIfAny: { spendingSender: activeAddress.pipe((0, operators_1.take)(1)), // IMPORTANT ! }, }); return __makeTransactionFromIntent(intent$, makeTXOptions); }; const transferTokens = (input) => { radixLog.debug(`transferTokens`); const builder = dto_1.TransactionIntentBuilder.create().transferTokens(input.transferInput); let encryptMsgIfAny = false; if (input.message) { builder.message(input.message); encryptMsgIfAny = input.message.encrypt; } return __makeTransactionFromBuilder(builder, Object.assign({}, input), encryptMsgIfAny ? { encryptMessageIfAnyWithAccount: activeAccount.pipe((0, operators_1.take)(1)), } : undefined); }; const stakeTokens = (input) => (0, tslib_1.__awaiter)(void 0, void 0, void 0, function* () { radixLog.debug('stake'); const nativeToken = yield (0, rxjs_1.firstValueFrom)(nativeTokenSubject); return __makeTransactionFromBuilder(dto_1.TransactionIntentBuilder.create().stakeTokens(Object.assign(Object.assign({}, input.stakeInput), { tokenIdentifier: nativeToken.rri })), Object.assign({}, input)); }); const unstakeTokens = (input) => (0, tslib_1.__awaiter)(void 0, void 0, void 0, function* () { radixLog.debug('unstake'); const nativeToken = yield (0, rxjs_1.firstValueFrom)(nativeTokenSubject); return __makeTransactionFromBuilder(dto_1.TransactionIntentBuilder.create().unstakeTokens(Object.assign(Object.assign({}, input.unstakeInput), { tokenIdentifier: nativeToken.rri })), Object.assign({}, input)); }); const decryptTransaction = (input) => { radixLog.debug(`Trying to decrypt transaction with txID=${input.txID.toString()}`); if (!input.message) { const noMsg = `TX contains no message, nothing to decrypt (txID=${input.txID.toString()}).`; radixLog.info(noMsg); return (0, rxjs_1.throwError)(() => new Error(noMsg)); } const messageBuffer = Buffer.from(input.message, 'hex'); const encryptedMessageResult = crypto_1.Message.fromBuffer(messageBuffer); if (!encryptedMessageResult.isOk()) { const errMessage = `Failed to parse message as 'EncryptedMessage' type, underlying error: '${(0, util_1.msgFromError)(encryptedMessageResult.error)}'. Might not have been encrypted? Try decode string as UTF-8 string.`; util_1.log.warn(errMessage); return (0, rxjs_1.throwError)(new Error(errMessage)); } const encryptedMessage = encryptedMessageResult.value; if (encryptedMessage.kind !== 'ENCRYPTED') return (0, rxjs_1.of)(encryptedMessage.plaintext); return activeAccount.pipe((0, operators_1.take)(1), (0, operators_1.mergeMap)((account) => { const myPublicKey = account.publicKey; util_1.log.debug(`Trying to decrypt message with activeSigningKey with pubKey=${myPublicKey.toString()}`); const publicKeyOfOtherPartyResult = (0, dto_1.singleRecipientFromActions)(myPublicKey, input.actions); if (!publicKeyOfOtherPartyResult.isOk()) { return (0, rxjs_1.throwError)(new Error((0, util_1.msgFromError)(publicKeyOfOtherPartyResult.error))); } util_1.log.debug(`Trying to decrypt message with publicKeyOfOtherPartyResult=${publicKeyOfOtherPartyResult.toString()}`); return account.decrypt({ encryptedMessage, publicKeyOfOtherParty: publicKeyOfOtherPartyResult.value, }); }), (0, operators_1.take)(1)); }; const restoreLocalHDAccountsToIndex = (index) => wallet$.pipe((0, operators_1.mergeMap)(wallet => wallet.restoreLocalHDAccountsToIndex(index))); subs.add(deriveNextLocalHDAccountSubject .pipe((0, operators_1.withLatestFrom)(wallet$), (0, operators_1.mergeMap)(([derivation, wallet]) => wallet.deriveNextLocalHDAccount(derivation))) .subscribe()); subs.add(addAccountByPrivateKeySubject .pipe((0, operators_1.withLatestFrom)(wallet$), (0, operators_1.mergeMap)(([privateKeyInput, wallet]) => wallet.addAccountFromPrivateKey(privateKeyInput))) .subscribe()); subs.add(switchAccountSubject .pipe((0, operators_1.withLatestFrom)(wallet$), (0, operators_1.tap)(([switchTo, wallet]) => wallet.switchAccount(switchTo))) .subscribe()); let headerSub; const methods = { // we forward the full `RadixAPI`, but we also provide some convenience methods based on active account/address. ledger: Object.assign({}, api), __wallet: wallet$, __node: node$, __reset: () => subs.unsubscribe(), // Primarily useful for testing __withNodeConnection: (node$) => { subs.add(node$.subscribe(n => { radixLog.debug(`Using node ${n.url.toString()}`); nodeSubject.next(n); }, (error) => { errorNotificationSubject.next((0, errors_1.nodeError)(error)); })); return methods; }, __withAPI: (radixCoreAPI$) => { subs.add(radixCoreAPI$.subscribe(a => coreAPISubject.next(a))); return methods; }, __withWallet: (wallet) => { walletSubject.next(wallet); return methods; }, __withKeychain: (signingKeychain) => { (0, rxjs_1.firstValueFrom)(networkSubject).then(network => { const wallet = wallet_1.Wallet.create({ signingKeychain, network, }); methods.__withWallet(wallet); }); return methods; }, connect: (url) => (0, tslib_1.__awaiter)(void 0, void 0, void 0, function* () { methods.__withNodeConnection((0, rxjs_1.of)({ url: new URL(url) })); const networkId = yield (0, rxjs_1.firstValueFrom)(api.networkId()); const nativeToken = yield (0, rxjs_1.firstValueFrom)(api.nativeToken(networkId)); networkSubject.next(networkId); nativeTokenSubject.next(nativeToken); }), login: (password, loadKeystore) => { walletSubscription === null || walletSubscription === void 0 ? void 0 : walletSubscription.unsubscribe(); void account_1.SigningKeychain.byLoadingAndDecryptingKeystore({ password, load: loadKeystore, }).then(signingKeychainResult => { signingKeychainResult.match((signingKeychain) => { walletSubscription = networkSubject.subscribe(network => { const wallet = wallet_1.Wallet.create({ signingKeychain, network, }); methods.__withWallet(wallet); }); }, error => { errorNotificationSubject.next((0, errors_1.walletError)(error)); }); }); return methods; }, errors: errorNotificationSubject.asObservable(), deriveNextAccount: (input) => { const derivation = input !== null && input !== void 0 ? input : {}; deriveNextLocalHDAccountSubject.next(derivation); return methods; }, deriveHWAccount: (input) => wallet$.pipe((0, operators_1.mergeMap)(wallet => wallet.deriveHWAccount(input))), displayAddressForActiveHWAccountOnHWDeviceForVerification: () => wallet$.pipe((0, operators_1.mergeMap)(wallet => wallet.displayAddressForActiveHWAccountOnHWDeviceForVerification())), addAccountFromPrivateKey: (input) => { addAccountByPrivateKeySubject.next(input); return methods; }, switchAccount: (input) => { switchAccountSubject.next(input); return methods; }, restoreLocalHDAccountsToIndex, decryptTransaction: decryptTransaction, logLevel: (level) => { util_1.log.setLevel(level); return methods; }, transactionStatus: (txID, trigger) => trigger.pipe((0, operators_1.withLatestFrom)(networkSubject), (0, operators_1.mergeMap)(([_, network]) => api.getTransaction(txID, network)), (0, operators_1.distinctUntilChanged)((prev, cur) => prev.status === cur.status), (0, operators_1.filter)(({ txID }) => txID.equals(txID)), (0, operators_1.tap)(({ status }) => radixLog.info(`Got transaction status ${status.toString()} for txID: ${txID.toString()}`))), withTokenBalanceFetchTrigger: (trigger) => { subs.add(trigger.subscribe(tokenBalanceFetchSubject)); return methods; }, withStakingFetchTrigger: (trigger) => { subs.add(trigger.subscribe(stakingFetchSubject)); return methods; }, // Wallet APIs revealMnemonic, activeAddress, activeAccount, accounts, // Active AccountAddress/Account APIs tokenBalances, stakingPositions, unstakingPositions, lookupTransaction: (txID) => networkSubject.pipe((0, operators_1.mergeMap)(network => api.getTransaction(txID, network).pipe((0, operators_1.withLatestFrom)(activeAddress), (0, operators_1.map)(([simpleTx, aa]) => decorateSimpleExecutedTransactionWithType(simpleTx, aa))))), transactionHistory, transferTokens, stakeTokens, unstakeTokens, getTransaction: (txID) => networkSubject.pipe((0, operators_1.mergeMap)(network => api.getTransaction(txID, network))), validators: () => networkSubject.pipe((0, operators_1.mergeMap)(network => api.validators(network))), setHeaders: (headers) => { headerSub.unsubscribe(); headerSub = coreAPI$.subscribe(api => api.setHeaders(headers)); }, targetApiVersion: networking_1.apiVersion, }; return methods; }; exports.Radix = { create, }; //# sourceMappingURL=radix.js.map