diff options
Diffstat (limited to 'packages/taler-wallet-core/src/wallet.ts')
-rw-r--r-- | packages/taler-wallet-core/src/wallet.ts | 273 |
1 files changed, 143 insertions, 130 deletions
diff --git a/packages/taler-wallet-core/src/wallet.ts b/packages/taler-wallet-core/src/wallet.ts index f21ba6ec1..236b27575 100644 --- a/packages/taler-wallet-core/src/wallet.ts +++ b/packages/taler-wallet-core/src/wallet.ts @@ -285,6 +285,7 @@ export interface WalletExecutionContext { readonly http: HttpRequestLibrary; readonly db: DbAccess<typeof WalletStoresV1>; readonly oc: ObservabilityContext; + readonly taskScheduler: TaskScheduler; } export const EXCHANGE_COINS_LOCK = "exchange-coins-lock"; @@ -299,16 +300,16 @@ type CancelFn = () => void; * auditors into the database, unless these defaults have * already been applied. */ -async function fillDefaults(ws: InternalWalletState): Promise<void> { +async function fillDefaults(wex: WalletExecutionContext): Promise<void> { const notifications: WalletNotification[] = []; - await ws.db.runReadWriteTx(["config", "exchanges"], async (tx) => { + await wex.db.runReadWriteTx(["config", "exchanges"], async (tx) => { const appliedRec = await tx.config.get("currencyDefaultsApplied"); let alreadyApplied = appliedRec ? !!appliedRec.value : false; if (alreadyApplied) { logger.trace("defaults already applied"); return; } - for (const exch of ws.config.builtin.exchanges) { + for (const exch of wex.ws.config.builtin.exchanges) { const resp = await addPresetExchangeEntry( tx, exch.exchangeBaseUrl, @@ -324,18 +325,18 @@ async function fillDefaults(ws: InternalWalletState): Promise<void> { }); }); for (const notif of notifications) { - ws.notify(notif); + wex.ws.notify(notif); } } export async function getDenomInfo( - ws: InternalWalletState, + wex: WalletExecutionContext, tx: WalletDbReadOnlyTransaction<["denominations"]>, exchangeBaseUrl: string, denomPubHash: string, ): Promise<DenominationInfo | undefined> { const key = `${exchangeBaseUrl}:${denomPubHash}`; - const cached = ws.denomCache[key]; + const cached = wex.ws.denomCache[key]; if (cached) { return cached; } @@ -351,11 +352,11 @@ export async function getDenomInfo( * previous withdrawals. */ async function listKnownBankAccounts( - ws: InternalWalletState, + wex: WalletExecutionContext, currency?: string, ): Promise<KnownBankAccounts> { const accounts: KnownBankAccountsInfo[] = []; - await ws.db.runReadOnlyTx(["bankAccounts"], async (tx) => { + await wex.db.runReadOnlyTx(["bankAccounts"], async (tx) => { const knownAccounts = await tx.bankAccounts.iter().toArray(); for (const r of knownAccounts) { if (currency && currency !== r.currency) { @@ -378,12 +379,12 @@ async function listKnownBankAccounts( /** */ async function addKnownBankAccounts( - ws: InternalWalletState, + wex: WalletExecutionContext, payto: string, alias: string, currency: string, ): Promise<void> { - await ws.db.runReadWriteTx(["bankAccounts"], async (tx) => { + await wex.db.runReadWriteTx(["bankAccounts"], async (tx) => { tx.bankAccounts.put({ uri: payto, alias: alias, @@ -397,10 +398,10 @@ async function addKnownBankAccounts( /** */ async function forgetKnownBankAccounts( - ws: InternalWalletState, + wex: WalletExecutionContext, payto: string, ): Promise<void> { - await ws.db.runReadWriteTx(["bankAccounts"], async (tx) => { + await wex.db.runReadWriteTx(["bankAccounts"], async (tx) => { const account = await tx.bankAccounts.get(payto); if (!account) { throw Error(`account not found: ${payto}`); @@ -411,11 +412,11 @@ async function forgetKnownBankAccounts( } async function setCoinSuspended( - ws: InternalWalletState, + wex: WalletExecutionContext, coinPub: string, suspended: boolean, ): Promise<void> { - await ws.db.runReadWriteTx(["coins", "coinAvailability"], async (tx) => { + await wex.db.runReadWriteTx(["coins", "coinAvailability"], async (tx) => { const c = await tx.coins.get(coinPub); if (!c) { logger.warn(`coin ${coinPub} not found, won't suspend`); @@ -453,10 +454,10 @@ async function setCoinSuspended( /** * Dump the public information of coins we have in an easy-to-process format. */ -async function dumpCoins(ws: InternalWalletState): Promise<CoinDumpJson> { +async function dumpCoins(wex: WalletExecutionContext): Promise<CoinDumpJson> { const coinsJson: CoinDumpJson = { coins: [] }; logger.info("dumping coins"); - await ws.db.runReadOnlyTx(["coins", "denominations"], async (tx) => { + await wex.db.runReadOnlyTx(["coins", "denominations"], async (tx) => { const coins = await tx.coins.iter().toArray(); for (const c of coins) { const denom = await tx.denominations.get([ @@ -477,7 +478,7 @@ async function dumpCoins(ws: InternalWalletState): Promise<CoinDumpJson> { withdrawalReservePub = cs.reservePub; } const denomInfo = await getDenomInfo( - ws, + wex, tx, c.exchangeBaseUrl, c.denomPubHash, @@ -530,10 +531,10 @@ async function getClientFromWalletState( } async function createStoredBackup( - ws: InternalWalletState, + wex: WalletExecutionContext, ): Promise<CreateStoredBackupResponse> { - const backup = await exportDb(ws.idb); - const backupsDb = await openStoredBackupsDatabase(ws.idb); + const backup = await exportDb(wex.ws.idb); + const backupsDb = await openStoredBackupsDatabase(wex.ws.idb); const name = `backup-${new Date().getTime()}`; await backupsDb.runAllStoresReadWriteTx(async (tx) => { await tx.backupMeta.add({ @@ -547,12 +548,12 @@ async function createStoredBackup( } async function listStoredBackups( - ws: InternalWalletState, + wex: WalletExecutionContext, ): Promise<StoredBackupList> { const storedBackups: StoredBackupList = { storedBackups: [], }; - const backupsDb = await openStoredBackupsDatabase(ws.idb); + const backupsDb = await openStoredBackupsDatabase(wex.ws.idb); await backupsDb.runAllStoresReadWriteTx(async (tx) => { await tx.backupMeta.iter().forEach((x) => { storedBackups.storedBackups.push({ @@ -564,10 +565,10 @@ async function listStoredBackups( } async function deleteStoredBackup( - ws: InternalWalletState, + wex: WalletExecutionContext, req: DeleteStoredBackupRequest, ): Promise<void> { - const backupsDb = await openStoredBackupsDatabase(ws.idb); + const backupsDb = await openStoredBackupsDatabase(wex.ws.idb); await backupsDb.runAllStoresReadWriteTx(async (tx) => { await tx.backupData.delete(req.name); await tx.backupMeta.delete(req.name); @@ -575,12 +576,12 @@ async function deleteStoredBackup( } async function recoverStoredBackup( - ws: InternalWalletState, + wex: WalletExecutionContext, req: RecoverStoredBackupRequest, ): Promise<void> { logger.info(`Recovering stored backup ${req.name}`); const { name } = req; - const backupsDb = await openStoredBackupsDatabase(ws.idb); + const backupsDb = await openStoredBackupsDatabase(wex.ws.idb); const bd = await backupsDb.runAllStoresReadWriteTx(async (tx) => { const backupMeta = tx.backupMeta.get(name); if (!backupMeta) { @@ -593,12 +594,12 @@ async function recoverStoredBackup( return backupData; }); logger.info(`backup found, now importing`); - await importDb(ws.db.idbHandle(), bd); + await importDb(wex.db.idbHandle(), bd); logger.info(`import done`); } async function handlePrepareWithdrawExchange( - ws: InternalWalletState, + wex: WalletExecutionContext, req: PrepareWithdrawExchangeRequest, ): Promise<PrepareWithdrawExchangeResponse> { const parsedUri = parseTalerUri(req.talerUri); @@ -606,7 +607,7 @@ async function handlePrepareWithdrawExchange( throw Error("expected a taler://withdraw-exchange URI"); } const exchangeBaseUrl = parsedUri.exchangeBaseUrl; - const exchange = await fetchFreshExchange(ws, exchangeBaseUrl); + const exchange = await fetchFreshExchange(wex, exchangeBaseUrl); if (exchange.masterPub != parsedUri.exchangePub) { throw Error("mismatch of exchange master public key (URI vs actual)"); } @@ -638,11 +639,11 @@ export interface PendingOperationsResponse { * Implementation of the "wallet-core" API. */ async function dispatchRequestInternal<Op extends WalletApiOperation>( - ws: InternalWalletState, + wex: WalletExecutionContext, operation: WalletApiOperation, payload: unknown, ): Promise<WalletCoreResponseType<typeof operation>> { - if (!ws.initCalled && operation !== WalletApiOperation.InitWallet) { + if (!wex.ws.initCalled && operation !== WalletApiOperation.InitWallet) { throw Error( `wallet must be initialized before running operation ${operation}`, ); @@ -651,17 +652,17 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( // definitions we already have? switch (operation) { case WalletApiOperation.CreateStoredBackup: - return createStoredBackup(ws); + return createStoredBackup(wex); case WalletApiOperation.DeleteStoredBackup: { const req = codecForDeleteStoredBackupRequest().decode(payload); - await deleteStoredBackup(ws, req); + await deleteStoredBackup(wex, req); return {}; } case WalletApiOperation.ListStoredBackups: - return listStoredBackups(ws); + return listStoredBackups(wex); case WalletApiOperation.RecoverStoredBackup: { const req = codecForRecoverStoredBackupRequest().decode(payload); - await recoverStoredBackup(ws, req); + await recoverStoredBackup(wex, req); return {}; } case WalletApiOperation.InitWallet: { @@ -669,7 +670,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( // Write to the DB to make sure that we're failing early in // case the DB is not writeable. try { - await ws.db.runReadWriteTx(["config"], async (tx) => { + await wex.db.runReadWriteTx(["config"], async (tx) => { tx.config.put({ key: ConfigRecordKey.LastInitInfo, value: timestampProtocolToDb(TalerProtocolTimestamp.now()), @@ -681,41 +682,41 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( innerError: getErrorDetailFromException(e), }); } - ws.initCalled = true; - if (ws.config.testing.skipDefaults) { + wex.ws.initCalled = true; + if (wex.ws.config.testing.skipDefaults) { logger.trace("skipping defaults"); } else { logger.trace("filling defaults"); - await fillDefaults(ws); + await fillDefaults(wex); } const resp: InitResponse = { - versionInfo: getVersion(ws), + versionInfo: getVersion(wex), }; return resp; } case WalletApiOperation.WithdrawTestkudos: { - await withdrawTestBalance(ws, { + await withdrawTestBalance(wex, { amount: "TESTKUDOS:10" as AmountString, corebankApiBaseUrl: "https://bank.test.taler.net/", exchangeBaseUrl: "https://exchange.test.taler.net/", }); return { - versionInfo: getVersion(ws), + versionInfo: getVersion(wex), }; } case WalletApiOperation.WithdrawTestBalance: { const req = codecForWithdrawTestBalance().decode(payload); - await withdrawTestBalance(ws, req); + await withdrawTestBalance(wex, req); return {}; } case WalletApiOperation.RunIntegrationTest: { const req = codecForIntegrationTestArgs().decode(payload); - await runIntegrationTest(ws, req); + await runIntegrationTest(wex, req); return {}; } case WalletApiOperation.RunIntegrationTestV2: { const req = codecForIntegrationTestV2Args().decode(payload); - await runIntegrationTest2(ws, req); + await runIntegrationTest2(wex, req); return {}; } case WalletApiOperation.ValidateIban: { @@ -728,45 +729,45 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.TestPay: { const req = codecForTestPayArgs().decode(payload); - return await testPay(ws, req); + return await testPay(wex, req); } case WalletApiOperation.GetTransactions: { const req = codecForTransactionsRequest().decode(payload); - return await getTransactions(ws, req); + return await getTransactions(wex, req); } case WalletApiOperation.GetTransactionById: { const req = codecForTransactionByIdRequest().decode(payload); - return await getTransactionById(ws, req); + return await getTransactionById(wex, req); } case WalletApiOperation.GetWithdrawalTransactionByUri: { const req = codecForGetWithdrawalDetailsForUri().decode(payload); - return await getWithdrawalTransactionByUri(ws, req); + return await getWithdrawalTransactionByUri(wex, req); } case WalletApiOperation.AddExchange: { const req = codecForAddExchangeRequest().decode(payload); - await fetchFreshExchange(ws, req.exchangeBaseUrl, { + await fetchFreshExchange(wex, req.exchangeBaseUrl, { expectedMasterPub: req.masterPub, }); return {}; } case WalletApiOperation.UpdateExchangeEntry: { const req = codecForUpdateExchangeEntryRequest().decode(payload); - await fetchFreshExchange(ws, req.exchangeBaseUrl, { + await fetchFreshExchange(wex, req.exchangeBaseUrl, { forceUpdate: !!req.force, }); return {}; } case WalletApiOperation.ListExchanges: { - return await listExchanges(ws); + return await listExchanges(wex); } case WalletApiOperation.GetExchangeEntryByUrl: { const req = codecForGetExchangeEntryByUrlRequest().decode(payload); - return lookupExchangeByUri(ws, req); + return lookupExchangeByUri(wex, req); } case WalletApiOperation.ListExchangesForScopedCurrency: { const req = codecForListExchangesForScopedCurrencyRequest().decode(payload); - const exchangesResp = await listExchanges(ws); + const exchangesResp = await listExchanges(wex); const result: ExchangesShortListResponse = { exchanges: [], }; @@ -783,32 +784,32 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.GetExchangeDetailedInfo: { const req = codecForAddExchangeRequest().decode(payload); - return await getExchangeDetailedInfo(ws, req.exchangeBaseUrl); + return await getExchangeDetailedInfo(wex, req.exchangeBaseUrl); } case WalletApiOperation.ListKnownBankAccounts: { const req = codecForListKnownBankAccounts().decode(payload); - return await listKnownBankAccounts(ws, req.currency); + return await listKnownBankAccounts(wex, req.currency); } case WalletApiOperation.AddKnownBankAccounts: { const req = codecForAddKnownBankAccounts().decode(payload); - await addKnownBankAccounts(ws, req.payto, req.alias, req.currency); + await addKnownBankAccounts(wex, req.payto, req.alias, req.currency); return {}; } case WalletApiOperation.ForgetKnownBankAccounts: { const req = codecForForgetKnownBankAccounts().decode(payload); - await forgetKnownBankAccounts(ws, req.payto); + await forgetKnownBankAccounts(wex, req.payto); return {}; } case WalletApiOperation.GetWithdrawalDetailsForUri: { const req = codecForGetWithdrawalDetailsForUri().decode(payload); - return await getWithdrawalDetailsForUri(ws, req.talerWithdrawUri, { + return await getWithdrawalDetailsForUri(wex, req.talerWithdrawUri, { notifyChangeFromPendingTimeoutMs: req.notifyChangeFromPendingTimeoutMs, restrictAge: req.restrictAge, }); } case WalletApiOperation.AcceptManualWithdrawal: { const req = codecForAcceptManualWithdrawalRequet().decode(payload); - const res = await createManualWithdrawal(ws, { + const res = await createManualWithdrawal(wex, { amount: Amounts.parseOrThrow(req.amount), exchangeBaseUrl: req.exchangeBaseUrl, restrictAge: req.restrictAge, @@ -819,7 +820,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( const req = codecForGetWithdrawalDetailsForAmountRequest().decode(payload); const wi = await getExchangeWithdrawalInfo( - ws, + wex, req.exchangeBaseUrl, Amounts.parseOrThrow(req.amount), req.restrictAge, @@ -843,23 +844,23 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( return resp; } case WalletApiOperation.GetBalances: { - return await getBalances(ws); + return await getBalances(wex); } case WalletApiOperation.GetBalanceDetail: { const req = codecForGetBalanceDetailRequest().decode(payload); - return await getBalanceDetail(ws, req); + return await getBalanceDetail(wex, req); } case WalletApiOperation.GetUserAttentionRequests: { const req = codecForUserAttentionsRequest().decode(payload); - return await getUserAttentions(ws, req); + return await getUserAttentions(wex, req); } case WalletApiOperation.MarkAttentionRequestAsRead: { const req = codecForUserAttentionByIdRequest().decode(payload); - return await markAttentionRequestAsRead(ws, req); + return await markAttentionRequestAsRead(wex, req); } case WalletApiOperation.GetUserAttentionUnreadCount: { const req = codecForUserAttentionsRequest().decode(payload); - return await getUserAttentionsUnreadCount(ws, req); + return await getUserAttentionsUnreadCount(wex, req); } case WalletApiOperation.GetPendingOperations: { // FIXME: Eventually remove the handler after deprecation period. @@ -869,7 +870,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.SetExchangeTosAccepted: { const req = codecForAcceptExchangeTosRequest().decode(payload); - await acceptExchangeTermsOfService(ws, req.exchangeBaseUrl); + await acceptExchangeTermsOfService(wex, req.exchangeBaseUrl); return {}; } case WalletApiOperation.SetExchangeTosForgotten: { @@ -880,7 +881,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( case WalletApiOperation.AcceptBankIntegratedWithdrawal: { const req = codecForAcceptBankIntegratedWithdrawalRequest().decode(payload); - return await acceptWithdrawalFromUri(ws, { + return await acceptWithdrawalFromUri(wex, { selectedExchange: req.exchangeBaseUrl, talerWithdrawUri: req.talerWithdrawUri, forcedDenomSel: req.forcedDenomSel, @@ -890,7 +891,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( case WalletApiOperation.GetExchangeTos: { const req = codecForGetExchangeTosRequest().decode(payload); return getExchangeTos( - ws, + wex, req.exchangeBaseUrl, req.acceptedFormat, req.acceptLanguage, @@ -898,7 +899,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.GetContractTermsDetails: { const req = codecForGetContractTermsDetails().decode(payload); - return getContractTermsDetails(ws, req.proposalId); + return getContractTermsDetails(wex, req.proposalId); } case WalletApiOperation.RetryPendingNow: { logger.error("retryPendingNow currently not implemented"); @@ -906,19 +907,19 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.SharePayment: { const req = codecForSharePaymentRequest().decode(payload); - return await sharePayment(ws, req.merchantBaseUrl, req.orderId); + return await sharePayment(wex, req.merchantBaseUrl, req.orderId); } case WalletApiOperation.PrepareWithdrawExchange: { const req = codecForPrepareWithdrawExchangeRequest().decode(payload); - return handlePrepareWithdrawExchange(ws, req); + return handlePrepareWithdrawExchange(wex, req); } case WalletApiOperation.PreparePayForUri: { const req = codecForPreparePayRequest().decode(payload); - return await preparePayForUri(ws, req.talerPayUri); + return await preparePayForUri(wex, req.talerPayUri); } case WalletApiOperation.PreparePayForTemplate: { const req = codecForPreparePayTemplateRequest().decode(payload); - return preparePayForTemplate(ws, req); + return preparePayForTemplate(wex, req); } case WalletApiOperation.ConfirmPay: { const req = codecForConfirmPayRequest().decode(payload); @@ -934,45 +935,45 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } else { throw Error("transactionId or (deprecated) proposalId required"); } - return await confirmPay(ws, transactionId, req.sessionId); + return await confirmPay(wex, transactionId, req.sessionId); } case WalletApiOperation.AbortTransaction: { const req = codecForAbortTransaction().decode(payload); - await abortTransaction(ws, req.transactionId); + await abortTransaction(wex, req.transactionId); return {}; } case WalletApiOperation.SuspendTransaction: { const req = codecForSuspendTransaction().decode(payload); - await suspendTransaction(ws, req.transactionId); + await suspendTransaction(wex, req.transactionId); return {}; } case WalletApiOperation.FailTransaction: { const req = codecForFailTransactionRequest().decode(payload); - await failTransaction(ws, req.transactionId); + await failTransaction(wex, req.transactionId); return {}; } case WalletApiOperation.ResumeTransaction: { const req = codecForResumeTransaction().decode(payload); - await resumeTransaction(ws, req.transactionId); + await resumeTransaction(wex, req.transactionId); return {}; } case WalletApiOperation.DumpCoins: { - return await dumpCoins(ws); + return await dumpCoins(wex); } case WalletApiOperation.SetCoinSuspended: { const req = codecForSetCoinSuspendedRequest().decode(payload); - await setCoinSuspended(ws, req.coinPub, req.suspended); + await setCoinSuspended(wex, req.coinPub, req.suspended); return {}; } case WalletApiOperation.TestingGetSampleTransactions: return { transactions: sampleWalletCoreTransactions }; case WalletApiOperation.ForceRefresh: { const req = codecForForceRefreshRequest().decode(payload); - return await forceRefresh(ws, req); + return await forceRefresh(wex, req); } case WalletApiOperation.StartRefundQueryForUri: { const req = codecForPrepareRefundRequest().decode(payload); - return await startRefundQueryForUri(ws, req.talerRefundUri); + return await startRefundQueryForUri(wex, req.talerRefundUri); } case WalletApiOperation.StartRefundQuery: { const req = codecForStartRefundQueryRequest().decode(payload); @@ -983,30 +984,30 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( if (txIdParsed.tag !== TransactionType.Payment) { throw Error("expected payment transaction ID"); } - await startQueryRefund(ws, txIdParsed.proposalId); + await startQueryRefund(wex, txIdParsed.proposalId); return {}; } case WalletApiOperation.AddBackupProvider: { const req = codecForAddBackupProviderRequest().decode(payload); - return await addBackupProvider(ws, req); + return await addBackupProvider(wex, req); } case WalletApiOperation.RunBackupCycle: { const req = codecForRunBackupCycle().decode(payload); - await runBackupCycle(ws, req); + await runBackupCycle(wex, req); return {}; } case WalletApiOperation.RemoveBackupProvider: { const req = codecForRemoveBackupProvider().decode(payload); - await removeBackupProvider(ws, req); + await removeBackupProvider(wex, req); return {}; } case WalletApiOperation.ExportBackupRecovery: { - const resp = await getBackupRecovery(ws); + const resp = await getBackupRecovery(wex); return resp; } case WalletApiOperation.TestingWaitTransactionState: { const req = payload as TestingWaitTransactionRequest; - await waitTransactionState(ws, req.transactionId, req.txState); + await waitTransactionState(wex, req.transactionId, req.txState); return {}; } case WalletApiOperation.GetCurrencySpecification: { @@ -1055,7 +1056,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.ImportBackupRecovery: { const req = codecForAny().decode(payload); - await loadBackupRecovery(ws, req); + await loadBackupRecovery(wex, req); return {}; } // case WalletApiOperation.GetPlanForOperation: { @@ -1064,31 +1065,31 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( // } case WalletApiOperation.ConvertDepositAmount: { const req = codecForConvertAmountRequest.decode(payload); - return await convertDepositAmount(ws, req); + return await convertDepositAmount(wex, req); } case WalletApiOperation.GetMaxDepositAmount: { const req = codecForGetAmountRequest.decode(payload); - return await getMaxDepositAmount(ws, req); + return await getMaxDepositAmount(wex, req); } case WalletApiOperation.ConvertPeerPushAmount: { const req = codecForConvertAmountRequest.decode(payload); - return await convertPeerPushAmount(ws, req); + return await convertPeerPushAmount(wex, req); } case WalletApiOperation.GetMaxPeerPushAmount: { const req = codecForGetAmountRequest.decode(payload); - return await getMaxPeerPushAmount(ws, req); + return await getMaxPeerPushAmount(wex, req); } case WalletApiOperation.ConvertWithdrawalAmount: { const req = codecForConvertAmountRequest.decode(payload); - return await convertWithdrawalAmount(ws, req); + return await convertWithdrawalAmount(wex, req); } case WalletApiOperation.GetBackupInfo: { - const resp = await getBackupInfo(ws); + const resp = await getBackupInfo(wex); return resp; } case WalletApiOperation.PrepareDeposit: { const req = codecForPrepareDepositRequest().decode(payload); - return await prepareDepositGroup(ws, req); + return await prepareDepositGroup(wex, req); } case WalletApiOperation.GenerateDepositGroupTxId: return { @@ -1096,42 +1097,42 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( }; case WalletApiOperation.CreateDepositGroup: { const req = codecForCreateDepositGroupRequest().decode(payload); - return await createDepositGroup(ws, req); + return await createDepositGroup(wex, req); } case WalletApiOperation.DeleteTransaction: { const req = codecForDeleteTransactionRequest().decode(payload); - await deleteTransaction(ws, req.transactionId); + await deleteTransaction(wex, req.transactionId); return {}; } case WalletApiOperation.RetryTransaction: { const req = codecForRetryTransactionRequest().decode(payload); - await retryTransaction(ws, req.transactionId); + await retryTransaction(wex, req.transactionId); return {}; } case WalletApiOperation.SetWalletDeviceId: { const req = codecForSetWalletDeviceIdRequest().decode(payload); - await setWalletDeviceId(ws, req.walletDeviceId); + await setWalletDeviceId(wex, req.walletDeviceId); return {}; } case WalletApiOperation.TestCrypto: { - return await ws.cryptoApi.hashString({ str: "hello world" }); + return await wex.cryptoApi.hashString({ str: "hello world" }); } case WalletApiOperation.ClearDb: - await clearDatabase(ws.db.idbHandle()); + await clearDatabase(wex.db.idbHandle()); return {}; case WalletApiOperation.Recycle: { throw Error("not implemented"); return {}; } case WalletApiOperation.ExportDb: { - const dbDump = await exportDb(ws.idb); + const dbDump = await exportDb(wex.ws.idb); return dbDump; } case WalletApiOperation.ListGlobalCurrencyExchanges: { const resp: ListGlobalCurrencyExchangesResponse = { exchanges: [], }; - await ws.db.runReadOnlyTx(["globalCurrencyExchanges"], async (tx) => { + await wex.db.runReadOnlyTx(["globalCurrencyExchanges"], async (tx) => { const gceList = await tx.globalCurrencyExchanges.iter().toArray(); for (const gce of gceList) { resp.exchanges.push({ @@ -1147,7 +1148,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( const resp: ListGlobalCurrencyAuditorsResponse = { auditors: [], }; - await ws.db.runReadOnlyTx(["globalCurrencyAuditors"], async (tx) => { + await wex.db.runReadOnlyTx(["globalCurrencyAuditors"], async (tx) => { const gcaList = await tx.globalCurrencyAuditors.iter().toArray(); for (const gca of gcaList) { resp.auditors.push({ @@ -1161,7 +1162,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.AddGlobalCurrencyExchange: { const req = codecForAddGlobalCurrencyExchangeRequest().decode(payload); - await ws.db.runReadWriteTx(["globalCurrencyExchanges"], async (tx) => { + await wex.db.runReadWriteTx(["globalCurrencyExchanges"], async (tx) => { const key = [req.currency, req.exchangeBaseUrl, req.exchangeMasterPub]; const existingRec = await tx.globalCurrencyExchanges.indexes.byCurrencyAndUrlAndPub.get( @@ -1180,7 +1181,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.RemoveGlobalCurrencyExchange: { const req = codecForRemoveGlobalCurrencyExchangeRequest().decode(payload); - await ws.db.runReadWriteTx(["globalCurrencyExchanges"], async (tx) => { + await wex.db.runReadWriteTx(["globalCurrencyExchanges"], async (tx) => { const key = [req.currency, req.exchangeBaseUrl, req.exchangeMasterPub]; const existingRec = await tx.globalCurrencyExchanges.indexes.byCurrencyAndUrlAndPub.get( @@ -1196,7 +1197,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.AddGlobalCurrencyAuditor: { const req = codecForAddGlobalCurrencyAuditorRequest().decode(payload); - await ws.db.runReadWriteTx(["globalCurrencyAuditors"], async (tx) => { + await wex.db.runReadWriteTx(["globalCurrencyAuditors"], async (tx) => { const key = [req.currency, req.auditorBaseUrl, req.auditorPub]; const existingRec = await tx.globalCurrencyAuditors.indexes.byCurrencyAndUrlAndPub.get( @@ -1215,7 +1216,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.RemoveGlobalCurrencyAuditor: { const req = codecForRemoveGlobalCurrencyAuditorRequest().decode(payload); - await ws.db.runReadWriteTx(["globalCurrencyAuditors"], async (tx) => { + await wex.db.runReadWriteTx(["globalCurrencyAuditors"], async (tx) => { const key = [req.currency, req.auditorBaseUrl, req.auditorPub]; const existingRec = await tx.globalCurrencyAuditors.indexes.byCurrencyAndUrlAndPub.get( @@ -1231,67 +1232,67 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( } case WalletApiOperation.ImportDb: { const req = codecForImportDbRequest().decode(payload); - await importDb(ws.db.idbHandle(), req.dump); + await importDb(wex.db.idbHandle(), req.dump); return []; } case WalletApiOperation.CheckPeerPushDebit: { const req = codecForCheckPeerPushDebitRequest().decode(payload); - return await checkPeerPushDebit(ws, req); + return await checkPeerPushDebit(wex, req); } case WalletApiOperation.InitiatePeerPushDebit: { const req = codecForInitiatePeerPushDebitRequest().decode(payload); - return await initiatePeerPushDebit(ws, req); + return await initiatePeerPushDebit(wex, req); } case WalletApiOperation.PreparePeerPushCredit: { const req = codecForPreparePeerPushCreditRequest().decode(payload); - return await preparePeerPushCredit(ws, req); + return await preparePeerPushCredit(wex, req); } case WalletApiOperation.ConfirmPeerPushCredit: { const req = codecForConfirmPeerPushPaymentRequest().decode(payload); - return await confirmPeerPushCredit(ws, req); + return await confirmPeerPushCredit(wex, req); } case WalletApiOperation.CheckPeerPullCredit: { const req = codecForPreparePeerPullPaymentRequest().decode(payload); - return await checkPeerPullPaymentInitiation(ws, req); + return await checkPeerPullPaymentInitiation(wex, req); } case WalletApiOperation.InitiatePeerPullCredit: { const req = codecForInitiatePeerPullPaymentRequest().decode(payload); - return await initiatePeerPullPayment(ws, req); + return await initiatePeerPullPayment(wex, req); } case WalletApiOperation.PreparePeerPullDebit: { const req = codecForCheckPeerPullPaymentRequest().decode(payload); - return await preparePeerPullDebit(ws, req); + return await preparePeerPullDebit(wex, req); } case WalletApiOperation.ConfirmPeerPullDebit: { const req = codecForAcceptPeerPullPaymentRequest().decode(payload); - return await confirmPeerPullDebit(ws, req); + return await confirmPeerPullDebit(wex, req); } case WalletApiOperation.ApplyDevExperiment: { const req = codecForApplyDevExperiment().decode(payload); - await applyDevExperiment(ws, req.devExperimentUri); + await applyDevExperiment(wex, req.devExperimentUri); return {}; } case WalletApiOperation.GetVersion: { - return getVersion(ws); + return getVersion(wex); } case WalletApiOperation.TestingWaitTransactionsFinal: - return await waitUntilAllTransactionsFinal(ws); + return await waitUntilAllTransactionsFinal(wex); case WalletApiOperation.TestingWaitRefreshesFinal: - return await waitUntilRefreshesDone(ws); + return await waitUntilRefreshesDone(wex); case WalletApiOperation.TestingSetTimetravel: { const req = codecForTestingSetTimetravelRequest().decode(payload); setDangerousTimetravel(req.offsetMs); - ws.taskScheduler.reload(); + wex.taskScheduler.reload(); return {}; } case WalletApiOperation.DeleteExchange: { const req = codecForDeleteExchangeRequest().decode(payload); - await deleteExchange(ws, req); + await deleteExchange(wex, req); return {}; } case WalletApiOperation.GetExchangeResources: { const req = codecForGetExchangeResourcesRequest().decode(payload); - return await getExchangeResources(ws, req.exchangeBaseUrl); + return await getExchangeResources(wex, req.exchangeBaseUrl); } case WalletApiOperation.TestingInfiniteTransactionLoop: { const myDelayMs = (payload as any).delayMs ?? 5; @@ -1301,7 +1302,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( const url = "https://exchange.demo.taler.net/reserves/01PMMB9PJN0QBWAFBXV6R0KNJJMAKXCV4D6FDG0GJFDJQXGYP32G?timeout_ms=30000"; logger.info(`fetching ${url}`); - const res = await ws.http.fetch(url); + const res = await wex.http.fetch(url); logger.info(`fetch result ${res.status}`); } }; @@ -1312,7 +1313,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( let loopCount = 0; while (true) { logger.info(`looping test write tx, iteration ${loopCount}`); - await ws.db.runReadWriteTx(["config"], async (tx) => { + await wex.db.runReadWriteTx(["config"], async (tx) => { await tx.config.put({ key: ConfigRecordKey.TestLoopTx, value: loopCount, @@ -1338,7 +1339,7 @@ async function dispatchRequestInternal<Op extends WalletApiOperation>( ); } -export function getVersion(ws: InternalWalletState): WalletCoreVersion { +export function getVersion(wex: WalletExecutionContext): WalletCoreVersion { const result: WalletCoreVersion = { implementationSemver: walletCoreBuildInfo.implementationSemver, implementationGitHash: walletCoreBuildInfo.implementationGitHash, @@ -1364,9 +1365,21 @@ async function handleCoreApiRequest( id: string, payload: unknown, ): Promise<CoreApiResponse> { + const wex: WalletExecutionContext = { + ws, + cancellationToken: CancellationToken.CONTINUE, + cryptoApi: ws.cryptoApi, + db: ws.db, + http: ws.http, + taskScheduler: ws.taskScheduler, + oc: { + observe(event) {}, + }, + }; + try { await ws.ensureWalletDbOpen(); - const result = await dispatchRequestInternal(ws, operation as any, payload); + const result = await dispatchRequestInternal(wex, operation as any, payload); return { type: "response", operation, |