From 74480bd9d254aa7e67568279829d37f46b8b99c9 Mon Sep 17 00:00:00 2001 From: Jordan Last Date: Tue, 16 Jan 2024 17:25:34 -0600 Subject: [PATCH] refactor notify raw --- examples/notify_raw/src/canister2/index.did | 2 +- src/compiler/rust/canister/src/ic/mod.rs | 14 +-- .../rust/canister/src/ic/notify_raw.rs | 96 ++++++++++--------- src/lib/ic/notify_raw.ts | 5 +- src/lib/ic/types/azle_ic.ts | 2 +- 5 files changed, 62 insertions(+), 57 deletions(-) diff --git a/examples/notify_raw/src/canister2/index.did b/examples/notify_raw/src/canister2/index.did index 685ff4c122..7529697cb3 100644 --- a/examples/notify_raw/src/canister2/index.did +++ b/examples/notify_raw/src/canister2/index.did @@ -1,4 +1,4 @@ service: () -> { - receiveNotification: () -> (); getNotified: () -> (bool) query; + receiveNotification: () -> (); } diff --git a/src/compiler/rust/canister/src/ic/mod.rs b/src/compiler/rust/canister/src/ic/mod.rs index 7882bd6307..c8330f05ea 100644 --- a/src/compiler/rust/canister/src/ic/mod.rs +++ b/src/compiler/rust/canister/src/ic/mod.rs @@ -21,7 +21,7 @@ mod is_controller; // mod msg_cycles_available128; // mod msg_cycles_refunded; // mod msg_cycles_refunded128; -// mod notify_raw; +mod notify_raw; mod performance_counter; mod print; mod reject; @@ -214,11 +214,13 @@ pub fn register(context: &mut wasmedge_quickjs::Context) { // .unwrap(), // ) // .unwrap(); - // ic.set_property( - // "notifyRaw", - // context.wrap_callback2(notify_raw::native_function).unwrap(), - // ) - // .unwrap(); + + ic.set( + "notifyRaw", + context + .new_function::("") + .into(), + ); ic.set( "performanceCounter", diff --git a/src/compiler/rust/canister/src/ic/notify_raw.rs b/src/compiler/rust/canister/src/ic/notify_raw.rs index 9e26f57492..00d10c5081 100644 --- a/src/compiler/rust/canister/src/ic/notify_raw.rs +++ b/src/compiler/rust/canister/src/ic/notify_raw.rs @@ -1,49 +1,53 @@ -use std::convert::TryInto; - -// TODO basically copied from call_raw128 -use quickjs_wasm_rs::{CallbackArg, JSContextRef, JSValueRef}; - -pub fn native_function<'a>( - context: &'a JSContextRef, - _this: &CallbackArg, - args: &[CallbackArg], -) -> Result, anyhow::Error> { - let canister_id_bytes: Vec = args - .get(0) - .expect("notify_raw canister_id_bytes is undefined") - .to_js_value()? - .try_into()?; - let canister_id = candid::Principal::from_slice(&canister_id_bytes); - let method: String = args - .get(1) - .expect("notify_raw method argument is undefined") - .to_js_value()? - .try_into()?; - let args_raw: Vec = args - .get(2) - .expect("notify_raw args_raw argument is undefined") - .to_js_value()? - .try_into()?; - let payment_candid_bytes: Vec = args - .get(3) - .expect("notify_raw payment_candid_bytes argument is undefined") - .to_js_value()? - .try_into()?; - let payment: u128 = candid::decode_one(&payment_candid_bytes)?; - - let notify_result = ic_cdk::api::call::notify_raw(canister_id, &method, &args_raw, payment); - - match notify_result { - Ok(_) => context.undefined_value(), - Err(err) => { - // TODO it might be nice to convert the rejection code to a string as well if possible - // TODO to give the user an actual error message (like the enum variants converted to string) - let err_string = format!( - "Rejection code {rejection_code}", - rejection_code = (err as i32).to_string() - ); - - Err(anyhow::anyhow!(err_string)) +use wasmedge_quickjs::{Context, JsFn, JsValue}; + +pub struct NativeFunction; +impl JsFn for NativeFunction { + fn call(context: &mut Context, this_val: JsValue, argv: &[JsValue]) -> JsValue { + let canister_id_bytes = if let JsValue::ArrayBuffer(js_array_buffer) = argv.get(0).unwrap() + { + js_array_buffer.to_vec() + } else { + panic!("conversion from JsValue to JsArrayBuffer failed") + }; + let canister_id = candid::Principal::from_slice(&canister_id_bytes); + + let method = if let JsValue::String(js_string) = argv.get(1).unwrap() { + js_string.to_string() + } else { + panic!("conversion from JsValue to JsString failed") + }; + + let args_raw = if let JsValue::ArrayBuffer(js_array_buffer) = argv.get(2).unwrap() { + js_array_buffer.to_vec() + } else { + panic!("conversion from JsValue to JsArrayBuffer failed") + }; + + let payment_string = if let JsValue::String(js_string) = argv.get(3).unwrap() { + js_string.to_string() + } else { + panic!("conversion from JsValue to JsString failed") + }; + let payment: u128 = payment_string.parse().unwrap(); + + let notify_result = ic_cdk::api::call::notify_raw(canister_id, &method, &args_raw, payment); + + match notify_result { + Ok(_) => JsValue::UnDefined, + Err(err) => { + // TODO obviously fix this once we figure out wasmedge_quickjs errors + + // TODO it might be nice to convert the rejection code to a string as well if possible + // TODO to give the user an actual error message (like the enum variants converted to string) + let err_string = format!( + "Rejection code {rejection_code}", + rejection_code = (err as i32).to_string() + ); + + // Err(anyhow::anyhow!(err_string)) + + panic!(err_string); + } } } } diff --git a/src/lib/ic/notify_raw.ts b/src/lib/ic/notify_raw.ts index 87cba4f21d..34adc49e84 100644 --- a/src/lib/ic/notify_raw.ts +++ b/src/lib/ic/notify_raw.ts @@ -1,7 +1,6 @@ import { Void } from '../candid/types/primitive/void'; import { nat } from '../candid/types/primitive/nats/nat'; import { blob } from '../candid/types/constructed/blob'; -import { encode } from '../candid/serde/encode'; import { Principal } from '../candid/types/reference/principal'; import { text } from '../candid/types/primitive/text'; @@ -25,12 +24,12 @@ export function notifyRaw( const canisterIdBytes = canisterId.toUint8Array().buffer; const argsRawBuffer = argsRaw.buffer; - const paymentCandidBytes = encode(nat, payment).buffer; + const paymentString = payment.toString(); return globalThis._azleIc.notifyRaw( canisterIdBytes, method, argsRawBuffer, - paymentCandidBytes + paymentString ); } diff --git a/src/lib/ic/types/azle_ic.ts b/src/lib/ic/types/azle_ic.ts index dc7a5660fc..f9a7a0886f 100644 --- a/src/lib/ic/types/azle_ic.ts +++ b/src/lib/ic/types/azle_ic.ts @@ -42,7 +42,7 @@ export type AzleIc = { canisterIdBytes: ArrayBufferLike, method: string, argsRawBuffer: ArrayBufferLike, - paymentCandidBytes: ArrayBufferLike + paymentString: string ) => void; performanceCounter: (counterType: string) => bigint; rejectCode: () => number;