Skip to content

Commit

Permalink
refactor notify raw
Browse files Browse the repository at this point in the history
  • Loading branch information
lastmjs committed Jan 16, 2024
1 parent d671918 commit 74480bd
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 57 deletions.
2 changes: 1 addition & 1 deletion examples/notify_raw/src/canister2/index.did
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
service: () -> {
receiveNotification: () -> ();
getNotified: () -> (bool) query;
receiveNotification: () -> ();
}
14 changes: 8 additions & 6 deletions src/compiler/rust/canister/src/ic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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::<notify_raw::NativeFunction>("")
.into(),
);

ic.set(
"performanceCounter",
Expand Down
96 changes: 50 additions & 46 deletions src/compiler/rust/canister/src/ic/notify_raw.rs
Original file line number Diff line number Diff line change
@@ -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<JSValueRef<'a>, anyhow::Error> {
let canister_id_bytes: Vec<u8> = 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<u8> = args
.get(2)
.expect("notify_raw args_raw argument is undefined")
.to_js_value()?
.try_into()?;
let payment_candid_bytes: Vec<u8> = 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);
}
}
}
}
5 changes: 2 additions & 3 deletions src/lib/ic/notify_raw.ts
Original file line number Diff line number Diff line change
@@ -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';

Expand All @@ -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
);
}
2 changes: 1 addition & 1 deletion src/lib/ic/types/azle_ic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export type AzleIc = {
canisterIdBytes: ArrayBufferLike,
method: string,
argsRawBuffer: ArrayBufferLike,
paymentCandidBytes: ArrayBufferLike
paymentString: string
) => void;
performanceCounter: (counterType: string) => bigint;
rejectCode: () => number;
Expand Down

0 comments on commit 74480bd

Please sign in to comment.