@radixdlt/application
Version:
A JavaScript client library for interacting with the Radix Distributed Ledger.
524 lines • 29.6 kB
JavaScript
;
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