You are reading content from Scuttlebutt
@aljoscha %Z0HqWQ6alxZdN3BvadBrvSyMYL+WKOokZZdaK6QZpOY=.sha256

@Piet

Some stuff on the js bindings for the rust legacy message implementation:

extern crate ssb_legacy_msg_data;
extern crate ssb_legacy_msg;
extern crate ssb_multiformats;

fn foo() {
    // Parsing a legacy value into a dynamically typed enum:
    let _ = ssb_legacy_msg_data::json::from_slice::<ssb_legacy_msg_data::value::Value>(bytes)?;

    // Parsing a legacy value into a dynamically typed enum, validating that it can serve as the
    // content of a message:
    let _ = ssb_legacy_msg_data::json::from_slice::<ssb_legacy_msg_data::value::ContentValue>(bytes)?;

    // The same can be done for parsing into js objects, by implementing the serde::Deserialize
    // trait for js objects. All n-api errors can be propagated via the `Error::custom` function,
    // so no need for debug asserts.
    //
    // Js API:
    // - decodeLegacyJson(buf) -> JsValue (throws on error)
    //   - ssb_legacy_msg_data::json::from_slice::<napi::JsValue>()
    // - decodeLegacyJsonContent(buf) -> JsValue (throws on error)
    //   - ssb_legacy_msg_data::json::from_slice::<napi::JsContentValue>()

    // Serializing anything that implements `serde::Serialize` into the signing encoding.
    let _ = ssb_legacy_msg_data::json::to_vec(val, false)?; // can also do `to_string`
    // Serializing anything that implements `serde::Serialize` into the transport encoding.
    let _ = ssb_legacy_msg_data::json::to_vec(val, true)?; // can also do `to_string`

    // These can error if data is invalid (e.g. a float is an infinity), the js API should throw
    // accordingly.
    // To enable this, implement `serde::Serialize` for the js value type.
    // All n-api errors can be propagate via `"Error::custom"` again.
    //
    // Js API:
    // - encodeJsonSigning(js_value) -> JsBuffer (throws on error)
    // - encodeJsonTransport(js_value) -> JsBuffer (throws on error)

    // Note that nothing enforces deduplication or correct serialization order of object entries.
    // You can simply use n-api's default iteration order and hope that it matches that of
    // JSON.stringify (precisely defined [here](https://spec.scuttlebutt.nz/datamodel.html#signing-encoding-objects)).

    // When the cbor stuff is done, all of the above can also be done for cbor (by literally
    // substituting "cbor" for "json")

    // Parsing a legacy message (as opposed to free-form data):
    let _ = ssb_legacy_msg::json::from_legacy::<ContentValue>(bytes)

    // The js binding can internally do `ssb_legacy_msg::json::from_legacy::<JsContentValue>(bytes)`,
    // then create another js object, initializing its members from the `Message<JsContentValue>`.
    // (if this was unclear, feel free to ask. Well, that actually applies to everything here)
    //
    // Js API:
    // decodeMessageJson(buf) -> JsValue (throws on error)

    // Encoding a legacy message into the signing encoding:
    let _ = ssb_legacy_msg::json::to_legacy_vec(&msg, false)?;
    // Encoding a legacy message into the transport encoding:
    let _ = ssb_legacy_msg::json::to_legacy_vec(&msg, true)?;

    // Js encoding can simply reuse js `encodeJsonSigning` and `encodeJsonTransport`, since js ssb
    // stores messages as regular objects.

    // Verification: All public functions in `ssb_legacy_msg::verify` can be exposed in js as well,
    // using js buffers and numbers as appropriate. Multiformats need to be converted to their
    // legacy encodings, and then put into js strings (which are utf-16 rather than rust's utf-8),
    // so there might be another converion in there.
}
Join Scuttlebutt now