use message envelope as documented
This commit is contained in:
parent
3db00d9d73
commit
b37c98346d
@ -40,7 +40,10 @@ import {
|
|||||||
handleCoreApiRequest,
|
handleCoreApiRequest,
|
||||||
CoreApiResponseSuccess,
|
CoreApiResponseSuccess,
|
||||||
CoreApiResponse,
|
CoreApiResponse,
|
||||||
|
CoreApiEnvelope,
|
||||||
} from "../walletCoreApiHandler";
|
} from "../walletCoreApiHandler";
|
||||||
|
import { makeErrorDetails } from "../operations/errors";
|
||||||
|
import { TalerErrorCode } from "../TalerErrorCode";
|
||||||
|
|
||||||
// @ts-ignore: special built-in module
|
// @ts-ignore: special built-in module
|
||||||
//import akono = require("akono");
|
//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
|
// @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 {
|
class AndroidWalletMessageHandler {
|
||||||
@ -154,7 +166,6 @@ class AndroidWalletMessageHandler {
|
|||||||
const wrapResponse = (result: unknown): CoreApiResponseSuccess => {
|
const wrapResponse = (result: unknown): CoreApiResponseSuccess => {
|
||||||
return {
|
return {
|
||||||
type: "response",
|
type: "response",
|
||||||
isError: false,
|
|
||||||
id,
|
id,
|
||||||
operation,
|
operation,
|
||||||
result,
|
result,
|
||||||
@ -164,9 +175,7 @@ class AndroidWalletMessageHandler {
|
|||||||
case "init": {
|
case "init": {
|
||||||
this.walletArgs = {
|
this.walletArgs = {
|
||||||
notifyHandler: async (notification: WalletNotification) => {
|
notifyHandler: async (notification: WalletNotification) => {
|
||||||
sendAkonoMessage(
|
sendAkonoMessage({ type: "notification", payload: notification });
|
||||||
JSON.stringify({ type: "notification", payload: notification }),
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
persistentStoragePath: args.persistentStoragePath,
|
persistentStoragePath: args.persistentStoragePath,
|
||||||
httpLib: this.httpLib,
|
httpLib: this.httpLib,
|
||||||
@ -232,14 +241,6 @@ class AndroidWalletMessageHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function installAndroidWalletListener(): void {
|
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 handler = new AndroidWalletMessageHandler();
|
||||||
const onMessage = async (msgStr: any): Promise<void> => {
|
const onMessage = async (msgStr: any): Promise<void> => {
|
||||||
if (typeof msgStr !== "string") {
|
if (typeof msgStr !== "string") {
|
||||||
@ -262,16 +263,19 @@ export function installAndroidWalletListener(): void {
|
|||||||
console.log(
|
console.log(
|
||||||
`android listener: sending success response for ${operation} (${id})`,
|
`android listener: sending success response for ${operation} (${id})`,
|
||||||
);
|
);
|
||||||
sendMessage(JSON.stringify(respMsg));
|
sendAkonoMessage(respMsg);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
const respMsg = {
|
const respMsg: CoreApiResponse = {
|
||||||
type: "response",
|
type: "error",
|
||||||
id,
|
id,
|
||||||
operation,
|
operation,
|
||||||
isError: true,
|
error: makeErrorDetails(
|
||||||
result: { message: e.toString() },
|
TalerErrorCode.WALLET_UNEXPECTED_EXCEPTION,
|
||||||
|
"unexpected exception",
|
||||||
|
{},
|
||||||
|
),
|
||||||
};
|
};
|
||||||
sendMessage(JSON.stringify(respMsg));
|
sendAkonoMessage(respMsg);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -30,6 +30,7 @@ import {
|
|||||||
makeCodecOptional,
|
makeCodecOptional,
|
||||||
} from "./util/codec";
|
} from "./util/codec";
|
||||||
import { Amounts } from "./util/amounts";
|
import { Amounts } from "./util/amounts";
|
||||||
|
import { OperationErrorDetails } from "./types/walletTypes";
|
||||||
|
|
||||||
interface AddExchangeRequest {
|
interface AddExchangeRequest {
|
||||||
exchangeBaseUrl: string;
|
exchangeBaseUrl: string;
|
||||||
@ -156,10 +157,11 @@ async function dispatchRequestInternal(
|
|||||||
wallet: Wallet,
|
wallet: Wallet,
|
||||||
operation: string,
|
operation: string,
|
||||||
payload: unknown,
|
payload: unknown,
|
||||||
): Promise<unknown> {
|
): Promise<Record<string, any>> {
|
||||||
switch (operation) {
|
switch (operation) {
|
||||||
case "withdrawTestkudos":
|
case "withdrawTestkudos":
|
||||||
return await withdrawTestBalance(wallet);
|
await withdrawTestBalance(wallet);
|
||||||
|
return {};
|
||||||
case "getTransactions": {
|
case "getTransactions": {
|
||||||
const req = codecForTransactionsRequest().decode(payload);
|
const req = codecForTransactionsRequest().decode(payload);
|
||||||
return await wallet.getTransactions(req);
|
return await wallet.getTransactions(req);
|
||||||
@ -201,10 +203,11 @@ async function dispatchRequestInternal(
|
|||||||
}
|
}
|
||||||
case "setExchangeTosAccepted": {
|
case "setExchangeTosAccepted": {
|
||||||
const req = codecForAcceptExchangeTosRequest().decode(payload);
|
const req = codecForAcceptExchangeTosRequest().decode(payload);
|
||||||
return await wallet.acceptExchangeTermsOfService(
|
await wallet.acceptExchangeTermsOfService(
|
||||||
req.exchangeBaseUrl,
|
req.exchangeBaseUrl,
|
||||||
req.etag,
|
req.etag,
|
||||||
);
|
);
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
case "applyRefund": {
|
case "applyRefund": {
|
||||||
const req = codecForApplyRefundRequest().decode(payload);
|
const req = codecForApplyRefundRequest().decode(payload);
|
||||||
@ -225,7 +228,8 @@ async function dispatchRequestInternal(
|
|||||||
}
|
}
|
||||||
case "abortProposal": {
|
case "abortProposal": {
|
||||||
const req = codecForAbortProposalRequest().decode(payload);
|
const req = codecForAbortProposalRequest().decode(payload);
|
||||||
return await wallet.refuseProposal(req.proposalId);
|
await wallet.refuseProposal(req.proposalId);
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
case "retryPendingNow": {
|
case "retryPendingNow": {
|
||||||
await wallet.runPending(true);
|
await wallet.runPending(true);
|
||||||
@ -253,10 +257,18 @@ export type CoreApiResponse =
|
|||||||
| CoreApiResponseSuccess
|
| CoreApiResponseSuccess
|
||||||
| CoreApiResponseError;
|
| CoreApiResponseError;
|
||||||
|
|
||||||
|
export type CoreApiEnvelope =
|
||||||
|
| CoreApiResponse
|
||||||
|
| CoreApiNotification;
|
||||||
|
|
||||||
|
export interface CoreApiNotification {
|
||||||
|
type: "notification";
|
||||||
|
payload: unknown;
|
||||||
|
}
|
||||||
|
|
||||||
export interface CoreApiResponseSuccess {
|
export interface CoreApiResponseSuccess {
|
||||||
// To distinguish the message from notifications
|
// To distinguish the message from notifications
|
||||||
type: "response";
|
type: "response";
|
||||||
isError: false,
|
|
||||||
operation: string,
|
operation: string,
|
||||||
id: string;
|
id: string;
|
||||||
result: unknown;
|
result: unknown;
|
||||||
@ -264,11 +276,10 @@ export interface CoreApiResponseSuccess {
|
|||||||
|
|
||||||
export interface CoreApiResponseError {
|
export interface CoreApiResponseError {
|
||||||
// To distinguish the message from notifications
|
// To distinguish the message from notifications
|
||||||
type: "response";
|
type: "error";
|
||||||
isError: true,
|
|
||||||
operation: string,
|
operation: string,
|
||||||
id: string;
|
id: string;
|
||||||
error: unknown;
|
error: OperationErrorDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -283,11 +294,10 @@ export async function handleCoreApiRequest(
|
|||||||
try {
|
try {
|
||||||
const result = await dispatchRequestInternal(w, operation, payload);
|
const result = await dispatchRequestInternal(w, operation, payload);
|
||||||
return {
|
return {
|
||||||
isError: false,
|
type: "response",
|
||||||
operation,
|
operation,
|
||||||
id,
|
id,
|
||||||
result,
|
result,
|
||||||
type: "response",
|
|
||||||
};
|
};
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (
|
if (
|
||||||
@ -295,15 +305,14 @@ export async function handleCoreApiRequest(
|
|||||||
e instanceof OperationFailedAndReportedError
|
e instanceof OperationFailedAndReportedError
|
||||||
) {
|
) {
|
||||||
return {
|
return {
|
||||||
isError: true,
|
type: "error",
|
||||||
operation,
|
operation,
|
||||||
id,
|
id,
|
||||||
error: e.operationError,
|
error: e.operationError,
|
||||||
type: "response",
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
return {
|
return {
|
||||||
isError: true,
|
type: "error",
|
||||||
operation,
|
operation,
|
||||||
id,
|
id,
|
||||||
error: makeErrorDetails(
|
error: makeErrorDetails(
|
||||||
@ -311,7 +320,6 @@ export async function handleCoreApiRequest(
|
|||||||
`unexpected exception: ${e}`,
|
`unexpected exception: ${e}`,
|
||||||
{},
|
{},
|
||||||
),
|
),
|
||||||
type: "response",
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,12 +21,9 @@ class Wallet:
|
|||||||
print(r)
|
print(r)
|
||||||
assert r.returncode == 0
|
assert r.returncode == 0
|
||||||
json_r = json.loads(r.stdout)
|
json_r = json.loads(r.stdout)
|
||||||
if json_r["isError"]:
|
if json_r["type"] != "response" or "result" not in json_r:
|
||||||
print(r)
|
print(json_r)
|
||||||
assert not json_r["isError"]
|
assert json_r["type"] == "response"
|
||||||
if "result" not in json_r:
|
|
||||||
# TODO should there not always be a "result"?
|
|
||||||
return None
|
|
||||||
return json_r["result"]
|
return json_r["result"]
|
||||||
|
|
||||||
def testing_withdraw(self, amount, exchange_url, bank_url):
|
def testing_withdraw(self, amount, exchange_url, bank_url):
|
||||||
|
Loading…
Reference in New Issue
Block a user