Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify nodejs and wasm bindings p. 2 #1146

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 19 additions & 13 deletions bindings/nodejs/lib/bindings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ const callClientMethodAsync = (
handler: ClientMethodHandler,
): Promise<string> =>
new Promise((resolve, reject) => {
callClientMethod(method, handler, (error: Error, result: string) => {
callClientMethod(method, handler, (error: any, result: string) => {
if (error) {
reject(error);
} else {
Expand All @@ -51,7 +51,7 @@ const callSecretManagerMethodAsync = (
callSecretManagerMethod(
method,
handler,
(error: Error, result: string) => {
(error: any, result: string) => {
if (error) {
reject(error);
} else {
Expand All @@ -75,23 +75,29 @@ const listenWalletAsync = (
callback: (error: Error, event: Event) => void,
handler: WalletMethodHandler,
): Promise<void> => {
listenWallet(
eventTypes,
function (err: any, data: string) {
const parsed = JSON.parse(data);
callback(err, new Event(parsed.accountIndex, parsed.event));
},
handler,
);
return Promise.resolve();
return new Promise((resolve) => {
listenWallet(
eventTypes,
function (err: any, data: string) {
const parsed = JSON.parse(data);
callback(
// Send back raw error instead of parsing
err,
new Event(parsed.accountIndex, parsed.event),
);
},
handler,
);
resolve();
});
};

const callWalletMethodAsync = (
method: string,
handler: WalletMethodHandler,
): Promise<string> =>
new Promise((resolve, reject) => {
callWalletMethod(method, handler, (error: Error, result: string) => {
callWalletMethod(method, handler, (error: any, result: string) => {
if (error) {
reject(error);
} else {
Expand All @@ -110,8 +116,8 @@ export {
callSecretManagerMethodAsync,
callUtilsMethod,
callWalletMethodAsync,
destroyWallet,
listenWalletAsync,
destroyWallet,
getClientFromWallet,
getSecretManagerFromWallet,
listenMqtt,
Expand Down
48 changes: 28 additions & 20 deletions bindings/nodejs/lib/client/client-method-handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { errorHandle } from '..';
import {
callClientMethodAsync,
createClient,
Expand All @@ -19,16 +20,24 @@ export class ClientMethodHandler {
* @param options client options or a client method handler.
*/
constructor(options: IClientOptions | ClientMethodHandler) {
// The rust client object is not extensible
if (Object.isExtensible(options)) {
this.methodHandler = createClient(JSON.stringify(options));
} else {
this.methodHandler = options as ClientMethodHandler;
try {
// The rust client object is not extensible
if (Object.isExtensible(options)) {
this.methodHandler = createClient(JSON.stringify(options));
} else {
this.methodHandler = options as ClientMethodHandler;
}
} catch (error: any) {
throw errorHandle(error);
}
}

async destroy() {
return destroyClient(this.methodHandler);
destroy(): void {
try {
destroyClient(this.methodHandler);
} catch (error: any) {
throw errorHandle(error);
}
}

/**
Expand All @@ -48,17 +57,8 @@ export class ClientMethodHandler {
}
}),
this.methodHandler,
).catch((error: Error) => {
try {
if (error.message !== undefined) {
error = Error(JSON.parse(error.message).payload);
} else {
error = Error(JSON.parse(error.toString()).payload);
}
} catch (e) {
console.error(e);
}
return Promise.reject(error);
).catch((error: any) => {
throw errorHandle(error);
});
}

Expand All @@ -68,10 +68,18 @@ export class ClientMethodHandler {
* @param topics The topics to listen to.
* @param callback The callback to be called when an MQTT event is received.
*/
async listen(
listen(
topics: string[],
callback: (error: Error, result: string) => void,
): Promise<void> {
return listenMqtt(topics, callback, this.methodHandler);
try {
return listenMqtt(topics, callback, this.methodHandler).catch(
(error: any) => {
throw errorHandle(error);
},
);
} catch (error: any) {
throw errorHandle(error);
}
}
}
4 changes: 2 additions & 2 deletions bindings/nodejs/lib/client/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,8 @@ export class Client {
this.methodHandler = new ClientMethodHandler(options);
}

async destroy() {
return this.methodHandler.destroy();
destroy() {
this.methodHandler.destroy();
}

/**
Expand Down
34 changes: 34 additions & 0 deletions bindings/nodejs/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,37 @@ export * from './types';
export * from './utils';
export * from './wallet';
export * from './logger';

// For future reference to see what we return from rust as a serialized string
export type Result = {
// "error" | "panic" or other binding method response name
type: string;
payload: {
// All method names from types/bridge/__name__.name
// Or all variants of rust sdk Error type
type: string;
// If "ok", json payload
payload?: string;
// If !"ok", error
error?: string;
};
};

function errorHandle(error: any): Error {
if (error instanceof TypeError) {
// neon or other bindings lib related error
throw error;
} else if (error instanceof Error) {
const err: Result = JSON.parse(error.message);
if (err.type == 'panic') {
return Error(err.payload.toString());
} else {
return Error(err.payload.error);
}
} else {
// Something bad happened! Make sure we dont double parse
return TypeError(error);
}
}

export { errorHandle };
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Copyright 2021-2023 IOTA Stiftung
// SPDX-License-Identifier: Apache-2.0

import { errorHandle } from '..';
import {
callSecretManagerMethodAsync,
createSecretManager,
Expand All @@ -19,11 +20,17 @@ export class SecretManagerMethodHandler {
* @param options A secret manager type or a secret manager method handler.
*/
constructor(options: SecretManagerType | SecretManagerMethodHandler) {
// The rust secret manager object is not extensible
if (Object.isExtensible(options)) {
this.methodHandler = createSecretManager(JSON.stringify(options));
} else {
this.methodHandler = options as SecretManagerMethodHandler;
try {
// The rust secret manager object is not extensible
if (Object.isExtensible(options)) {
this.methodHandler = createSecretManager(
JSON.stringify(options),
);
} else {
this.methodHandler = options as SecretManagerMethodHandler;
}
} catch (error: any) {
throw errorHandle(error);
}
}

Expand All @@ -35,9 +42,18 @@ export class SecretManagerMethodHandler {
*/
async callMethod(method: __SecretManagerMethods__): Promise<string> {
return callSecretManagerMethodAsync(
JSON.stringify(method),
// mapToObject is required to convert maps to array since they otherwise get serialized as `[{}]` even if not empty
JSON.stringify(method, function mapToObject(_key, value) {
if (value instanceof Map) {
return Object.fromEntries(value);
} else {
return value;
}
}),
this.methodHandler,
);
).catch((error: any) => {
throw errorHandle(error);
});
}
}

Expand Down
66 changes: 32 additions & 34 deletions bindings/nodejs/lib/wallet/wallet-method-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,11 @@ import type {
} from '../types/wallet';
import { Client } from '../client';
import { SecretManager } from '../secret_manager';
import { errorHandle } from '..';

// The WalletMethodHandler class interacts with methods with the rust bindings.
export class WalletMethodHandler {
// External rust object
methodHandler: any;

/**
Expand All @@ -35,7 +37,19 @@ export class WalletMethodHandler {
secretManager: options?.secretManager,
};

this.methodHandler = createWallet(JSON.stringify(walletOptions));
try {
this.methodHandler = createWallet(JSON.stringify(walletOptions));
} catch (error: any) {
throw errorHandle(error);
}
}

destroy(): void {
try {
destroyWallet(this.methodHandler);
} catch (error: any) {
throw errorHandle(error);
}
}

/**
Expand All @@ -55,17 +69,8 @@ export class WalletMethodHandler {
}
}),
this.methodHandler,
).catch((error: Error) => {
try {
if (error.message !== undefined) {
error = Error(JSON.parse(error.message).payload);
} else {
error = Error(JSON.parse(error.toString()).payload);
}
} catch (e) {
console.error(e);
}
return Promise.reject(error);
).catch((error: any) => {
throw errorHandle(error);
});
}

Expand Down Expand Up @@ -98,11 +103,13 @@ export class WalletMethodHandler {
eventTypes: WalletEventType[],
callback: (error: Error, event: Event) => void,
): Promise<void> {
return listenWalletAsync(eventTypes, callback, this.methodHandler);
}

async destroy(): Promise<void> {
return destroyWallet(this.methodHandler);
return listenWalletAsync(
eventTypes,
callback,
this.methodHandler,
).catch((error: any) => {
throw errorHandle(error);
});
}

/**
Expand All @@ -113,28 +120,19 @@ export class WalletMethodHandler {
const result = getClientFromWallet(this.methodHandler);
return new Client(result);
} catch (error: any) {
if (error.message !== undefined) {
throw Error(JSON.parse(error.message).payload);
} else {
throw Error(JSON.parse(error.toString()).payload);
}
throw errorHandle(error);
}
}

/**
* Get the secret manager associated with the wallet.
*/
async getSecretManager(): Promise<SecretManager> {
return new Promise((resolve, reject) => {
getSecretManagerFromWallet(this.methodHandler).then(
(result: any) => {
if (result.message !== undefined) {
reject(JSON.parse(result.message).payload);
} else {
resolve(new SecretManager(result));
}
},
);
});
getSecretManager(): SecretManager {
try {
let result = getSecretManagerFromWallet(this.methodHandler);
return new SecretManager(result);
} catch (error: any) {
throw errorHandle(error);
}
}
}
4 changes: 2 additions & 2 deletions bindings/nodejs/lib/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ export class Wallet {
/**
* Destroy the Wallet and drop its database connection.
*/
async destroy(): Promise<void> {
destroy(): void {
return this.methodHandler.destroy();
}

Expand Down Expand Up @@ -151,7 +151,7 @@ export class Wallet {
/**
* Get secret manager.
*/
async getSecretManager(): Promise<SecretManager> {
getSecretManager(): SecretManager {
return this.methodHandler.getSecretManager();
}

Expand Down
Loading