use message envelope as documented

This commit is contained in:
Florian Dold 2020-07-31 22:46:23 +05:30
parent 3db00d9d73
commit b37c98346d
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
3 changed files with 49 additions and 40 deletions

View File

@ -40,7 +40,10 @@ import {
handleCoreApiRequest,
CoreApiResponseSuccess,
CoreApiResponse,
CoreApiEnvelope,
} from "../walletCoreApiHandler";
import { makeErrorDetails } from "../operations/errors";
import { TalerErrorCode } from "../TalerErrorCode";
// @ts-ignore: special built-in module
//import akono = require("akono");
@ -132,9 +135,18 @@ export class AndroidHttpLib implements HttpRequestLibrary {
}
}
function sendAkonoMessage(m: string): void {
function sendAkonoMessage(ev: CoreApiEnvelope): void {
// @ts-ignore
globalThis.__akono_sendMessage(m);
const sendMessage = globalThis.__akono_sendMessage;
if (typeof sendMessage !== "function") {
const errMsg =
"FATAL: cannot install android wallet listener: akono functions missing";
console.error(errMsg);
throw new Error(errMsg);
}
const m = JSON.stringify(ev);
// @ts-ignore
sendMessage(m);
}
class AndroidWalletMessageHandler {
@ -154,7 +166,6 @@ class AndroidWalletMessageHandler {
const wrapResponse = (result: unknown): CoreApiResponseSuccess => {
return {
type: "response",
isError: false,
id,
operation,
result,
@ -164,9 +175,7 @@ class AndroidWalletMessageHandler {
case "init": {
this.walletArgs = {
notifyHandler: async (notification: WalletNotification) => {
sendAkonoMessage(
JSON.stringify({ type: "notification", payload: notification }),
);
sendAkonoMessage({ type: "notification", payload: notification });
},
persistentStoragePath: args.persistentStoragePath,
httpLib: this.httpLib,
@ -232,14 +241,6 @@ class AndroidWalletMessageHandler {
}
export function installAndroidWalletListener(): void {
// @ts-ignore
const sendMessage: (m: string) => void = globalThis.__akono_sendMessage;
if (typeof sendMessage !== "function") {
const errMsg =
"FATAL: cannot install android wallet listener: akono functions missing";
console.error(errMsg);
throw new Error(errMsg);
}
const handler = new AndroidWalletMessageHandler();
const onMessage = async (msgStr: any): Promise<void> => {
if (typeof msgStr !== "string") {
@ -262,16 +263,19 @@ export function installAndroidWalletListener(): void {
console.log(
`android listener: sending success response for ${operation} (${id})`,
);
sendMessage(JSON.stringify(respMsg));
sendAkonoMessage(respMsg);
} catch (e) {
const respMsg = {
type: "response",
const respMsg: CoreApiResponse = {
type: "error",
id,
operation,
isError: true,
result: { message: e.toString() },
error: makeErrorDetails(
TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
"unexpected exception",
{},
),
};
sendMessage(JSON.stringify(respMsg));
sendAkonoMessage(respMsg);
return;
}
};

View File

@ -30,6 +30,7 @@ import {
makeCodecOptional,
} from "./util/codec";
import { Amounts } from "./util/amounts";
import { OperationErrorDetails } from "./types/walletTypes";
interface AddExchangeRequest {
exchangeBaseUrl: string;
@ -156,10 +157,11 @@ async function dispatchRequestInternal(
wallet: Wallet,
operation: string,
payload: unknown,
): Promise<unknown> {
): Promise<Record<string, any>> {
switch (operation) {
case "withdrawTestkudos":
return await withdrawTestBalance(wallet);
await withdrawTestBalance(wallet);
return {};
case "getTransactions": {
const req = codecForTransactionsRequest().decode(payload);
return await wallet.getTransactions(req);
@ -201,10 +203,11 @@ async function dispatchRequestInternal(
}
case "setExchangeTosAccepted": {
const req = codecForAcceptExchangeTosRequest().decode(payload);
return await wallet.acceptExchangeTermsOfService(
await wallet.acceptExchangeTermsOfService(
req.exchangeBaseUrl,
req.etag,
);
return {};
}
case "applyRefund": {
const req = codecForApplyRefundRequest().decode(payload);
@ -225,7 +228,8 @@ async function dispatchRequestInternal(
}
case "abortProposal": {
const req = codecForAbortProposalRequest().decode(payload);
return await wallet.refuseProposal(req.proposalId);
await wallet.refuseProposal(req.proposalId);
return {};
}
case "retryPendingNow": {
await wallet.runPending(true);
@ -253,10 +257,18 @@ export type CoreApiResponse =
| CoreApiResponseSuccess
| CoreApiResponseError;
export type CoreApiEnvelope =
| CoreApiResponse
| CoreApiNotification;
export interface CoreApiNotification {
type: "notification";
payload: unknown;
}
export interface CoreApiResponseSuccess {
// To distinguish the message from notifications
type: "response";
isError: false,
operation: string,
id: string;
result: unknown;
@ -264,11 +276,10 @@ export interface CoreApiResponseSuccess {
export interface CoreApiResponseError {
// To distinguish the message from notifications
type: "response";
isError: true,
type: "error";
operation: string,
id: string;
error: unknown;
error: OperationErrorDetails;
}
/**
@ -283,11 +294,10 @@ export async function handleCoreApiRequest(
try {
const result = await dispatchRequestInternal(w, operation, payload);
return {
isError: false,
type: "response",
operation,
id,
result,
type: "response",
};
} catch (e) {
if (
@ -295,15 +305,14 @@ export async function handleCoreApiRequest(
e instanceof OperationFailedAndReportedError
) {
return {
isError: true,
type: "error",
operation,
id,
error: e.operationError,
type: "response",
};
} else {
return {
isError: true,
type: "error",
operation,
id,
error: makeErrorDetails(
@ -311,7 +320,6 @@ export async function handleCoreApiRequest(
`unexpected exception: ${e}`,
{},
),
type: "response",
};
}
}

View File

@ -21,12 +21,9 @@ class Wallet:
print(r)
assert r.returncode == 0
json_r = json.loads(r.stdout)
if json_r["isError"]:
print(r)
assert not json_r["isError"]
if "result" not in json_r:
# TODO should there not always be a "result"?
return None
if json_r["type"] != "response" or "result" not in json_r:
print(json_r)
assert json_r["type"] == "response"
return json_r["result"]
def testing_withdraw(self, amount, exchange_url, bank_url):