diff --git a/tools/didc-js/wasm-package/src/core.rs b/tools/didc-js/wasm-package/src/core.rs index 14d98194..80738f24 100644 --- a/tools/didc-js/wasm-package/src/core.rs +++ b/tools/didc-js/wasm-package/src/core.rs @@ -93,7 +93,12 @@ pub fn decode(args: DecodeArgs) -> Result { } })?; - IDLArgs::from_bytes_with_types(&args_bytes, &idl.env, &method.rets).map_err(|e| { + let method_types = match args.use_service_method_return_type { + None | Some(true) => &method.rets, + Some(false) => &method.args, + }; + + IDLArgs::from_bytes_with_types(&args_bytes, &idl.env, method_types).map_err(|e| { LibraryError::IdlArgsFromBytesFailed { reason: format!("Could not decode args from bytes {}", e), } diff --git a/tools/didc-js/wasm-package/src/types.rs b/tools/didc-js/wasm-package/src/types.rs index 3e5edf72..acc50573 100644 --- a/tools/didc-js/wasm-package/src/types.rs +++ b/tools/didc-js/wasm-package/src/types.rs @@ -40,6 +40,10 @@ export interface DecodeArgs { * A method to pick from the service. If not provided, the entire idl is used. */ serviceMethod?: string; + /** + * Wether to use the service method return type to decode the value. Default is true if serviceMethod is provided. + */ + useServiceMethodReturnType?: boolean; /** * The format of the input value. Default is 'hex'. */ @@ -95,6 +99,7 @@ pub struct DecodeArgs { pub input_format: EncodeFormat, pub input: String, pub service_method: Option, + pub use_service_method_return_type: Option, } #[derive(Debug, Serialize, Deserialize, Eq, PartialEq)] @@ -209,6 +214,13 @@ impl TryFrom for DecodeArgs { })? .as_string(); + let use_service_method_return_type = + js_sys::Reflect::get(&obj, &JsValue::from_str("useServiceMethodReturnType")) + .map_err(|_| LibraryError::MappingError { + reason: "Could not get 'useServiceMethodReturnType' from JsValue".to_string(), + })? + .as_bool(); + let target_form = js_sys::Reflect::get(&obj, &JsValue::from_str("targetFormat")) .map_err(|_| LibraryError::MappingError { reason: "Could not get 'targetFormat' from JsValue".to_string(), @@ -237,6 +249,7 @@ impl TryFrom for DecodeArgs { input_format, input, service_method, + use_service_method_return_type, }) } } diff --git a/tools/didc-js/wasm-package/src/validation.rs b/tools/didc-js/wasm-package/src/validation.rs index 30956401..0847e717 100644 --- a/tools/didc-js/wasm-package/src/validation.rs +++ b/tools/didc-js/wasm-package/src/validation.rs @@ -74,6 +74,7 @@ mod tests { input_format: EncodeFormat::Hex, input: "test".to_string(), service_method: None, + use_service_method_return_type: None, }; assert!(args.validate().is_ok()); diff --git a/tools/didc-js/wasm-tests/src/decode.test.ts b/tools/didc-js/wasm-tests/src/decode.test.ts index fe790515..2072315b 100644 --- a/tools/didc-js/wasm-tests/src/decode.test.ts +++ b/tools/didc-js/wasm-tests/src/decode.test.ts @@ -2,7 +2,7 @@ import { decode } from "@dfinity/didc"; import { IDL } from "./test.utils"; describe("decode", () => { - it("decoding returns the correct candid decoded value from hex", () => { + it("decoding returns the method return type decoded value from hex", () => { expect( decode({ idl: IDL, @@ -13,4 +13,28 @@ describe("decode", () => { }) ).toBe("(90 : nat64)"); }); + + it("decoding returns the method arg type decoded value from hex", () => { + expect( + decode({ + idl: IDL, + input: "4449444c016c01c98dea8b0a7801006400000000000000", + serviceMethod: "store_number", + inputFormat: "hex", + targetFormat: "candid", + useServiceMethodReturnType: false, + }) + ).toBe("(record { number = 100 : nat64 })"); + }); + + it("decoding without the service method can still return the decoded value", () => { + expect( + decode({ + idl: IDL, + input: "4449444c016c01c98dea8b0a7801006400000000000000", + inputFormat: "hex", + targetFormat: "candid", + }) + ).toBe("(record { 2_709_161_673 = 100 : nat64 })"); + }); });