From 0b17b557cd9f976e10fe0a012291ea120063c112 Mon Sep 17 00:00:00 2001 From: Michael Hayes Date: Fri, 17 Jan 2025 12:25:11 -0800 Subject: [PATCH] Add typesafe interface over wasm bindings --- packages/walrus-wasm/walrus_wasm.d.ts | 2 +- packages/walrus-wasm/walrus_wasm.js | 63 +++++++------ packages/walrus-wasm/walrus_wasm_bg.wasm | Bin 539710 -> 540001 bytes packages/walrus-wasm/walrus_wasm_bg.wasm.d.ts | 2 +- packages/walrus/src/utils/bcs.ts | 5 ++ packages/walrus/src/wasm.ts | 83 ++++++++++++++++++ 6 files changed, 121 insertions(+), 34 deletions(-) create mode 100644 packages/walrus/src/wasm.ts diff --git a/packages/walrus-wasm/walrus_wasm.d.ts b/packages/walrus-wasm/walrus_wasm.d.ts index 4a9bde7..d8a05e8 100644 --- a/packages/walrus-wasm/walrus_wasm.d.ts +++ b/packages/walrus-wasm/walrus_wasm.d.ts @@ -1,6 +1,5 @@ /* tslint:disable */ /* eslint-disable */ -export function from_signed_messages_and_indices(message_type: MessageType, signed_messages: any, signer_indices: Uint16Array): any; export function bls12381_min_pk_verify(signature: Uint8Array, public_key: Uint8Array, msg: Uint8Array): boolean; /** * Aggregate a list of signatures. @@ -12,6 +11,7 @@ export function bls12381_min_pk_aggregate(signatures: any): Uint8Array; */ export function bls12381_min_pk_verify_aggregate(public_keys: any, msg: Uint8Array, signature: Uint8Array): boolean; export function blake2b256(msg: Uint8Array): Uint8Array; +export function from_signed_messages_and_indices(message_type: MessageType, signed_messages: any, signer_indices: Uint16Array): any; /** * The message type for the [ProtocolMessageCertificate]. */ diff --git a/packages/walrus-wasm/walrus_wasm.js b/packages/walrus-wasm/walrus_wasm.js index b77e632..e070d2c 100644 --- a/packages/walrus-wasm/walrus_wasm.js +++ b/packages/walrus-wasm/walrus_wasm.js @@ -183,38 +183,6 @@ function passArray8ToWasm0(arg, malloc) { WASM_VECTOR_LEN = arg.length; return ptr; } - -let cachedUint16ArrayMemory0 = null; - -function getUint16ArrayMemory0() { - if (cachedUint16ArrayMemory0 === null || cachedUint16ArrayMemory0.byteLength === 0) { - cachedUint16ArrayMemory0 = new Uint16Array(wasm.memory.buffer); - } - return cachedUint16ArrayMemory0; -} - -function passArray16ToWasm0(arg, malloc) { - const ptr = malloc(arg.length * 2, 2) >>> 0; - getUint16ArrayMemory0().set(arg, ptr / 2); - WASM_VECTOR_LEN = arg.length; - return ptr; -} -/** - * @param {MessageType} message_type - * @param {any} signed_messages - * @param {Uint16Array} signer_indices - * @returns {any} - */ -module.exports.from_signed_messages_and_indices = function(message_type, signed_messages, signer_indices) { - const ptr0 = passArray16ToWasm0(signer_indices, wasm.__wbindgen_malloc); - const len0 = WASM_VECTOR_LEN; - const ret = wasm.from_signed_messages_and_indices(message_type, signed_messages, ptr0, len0); - if (ret[2]) { - throw takeFromExternrefTable0(ret[1]); - } - return takeFromExternrefTable0(ret[0]); -}; - /** * @param {Uint8Array} signature * @param {Uint8Array} public_key @@ -287,6 +255,37 @@ module.exports.blake2b256 = function(msg) { return v2; }; +let cachedUint16ArrayMemory0 = null; + +function getUint16ArrayMemory0() { + if (cachedUint16ArrayMemory0 === null || cachedUint16ArrayMemory0.byteLength === 0) { + cachedUint16ArrayMemory0 = new Uint16Array(wasm.memory.buffer); + } + return cachedUint16ArrayMemory0; +} + +function passArray16ToWasm0(arg, malloc) { + const ptr = malloc(arg.length * 2, 2) >>> 0; + getUint16ArrayMemory0().set(arg, ptr / 2); + WASM_VECTOR_LEN = arg.length; + return ptr; +} +/** + * @param {MessageType} message_type + * @param {any} signed_messages + * @param {Uint16Array} signer_indices + * @returns {any} + */ +module.exports.from_signed_messages_and_indices = function(message_type, signed_messages, signer_indices) { + const ptr0 = passArray16ToWasm0(signer_indices, wasm.__wbindgen_malloc); + const len0 = WASM_VECTOR_LEN; + const ret = wasm.from_signed_messages_and_indices(message_type, signed_messages, ptr0, len0); + if (ret[2]) { + throw takeFromExternrefTable0(ret[1]); + } + return takeFromExternrefTable0(ret[0]); +}; + /** * The message type for the [ProtocolMessageCertificate]. * @enum {0 | 1} diff --git a/packages/walrus-wasm/walrus_wasm_bg.wasm b/packages/walrus-wasm/walrus_wasm_bg.wasm index 7edee314ecfde03c9aa8078a0a1faba670b2ea8e..4dfc5731bf30534722b6808a00967cee862001c8 100644 GIT binary patch delta 34144 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 E2VZI?(f|Me delta 33980 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 z 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 Ser6W~|3ZA3T|$34`F{YZmjNCC diff --git a/packages/walrus-wasm/walrus_wasm_bg.wasm.d.ts b/packages/walrus-wasm/walrus_wasm_bg.wasm.d.ts index 69466f6..f0096bf 100644 --- a/packages/walrus-wasm/walrus_wasm_bg.wasm.d.ts +++ b/packages/walrus-wasm/walrus_wasm_bg.wasm.d.ts @@ -8,11 +8,11 @@ export const blobencoder_encode_with_metadata: (a: number, b: number, c: number) export const blobencoder_compute_metadata: (a: number, b: number, c: number) => [number, number, number]; export const blobencoder_decode_primary: (a: number, b: bigint, c: any) => [number, number, number]; export const blobencoder_decode_secondary: (a: number, b: bigint, c: any) => [number, number, number]; -export const from_signed_messages_and_indices: (a: number, b: any, c: number, d: number) => [number, number, number]; export const bls12381_min_pk_verify: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number]; export const bls12381_min_pk_aggregate: (a: any) => [number, number, number, number]; export const bls12381_min_pk_verify_aggregate: (a: any, b: number, c: number, d: number, e: number) => [number, number, number]; export const blake2b256: (a: number, b: number) => [number, number]; +export const from_signed_messages_and_indices: (a: number, b: any, c: number, d: number) => [number, number, number]; export const rustsecp256k1_v0_8_1_context_create: (a: number) => number; export const rustsecp256k1_v0_8_1_context_destroy: (a: number) => void; export const rustsecp256k1_v0_8_1_default_illegal_callback_fn: (a: number, b: number) => void; diff --git a/packages/walrus/src/utils/bcs.ts b/packages/walrus/src/utils/bcs.ts index 0b507c0..441f088 100644 --- a/packages/walrus/src/utils/bcs.ts +++ b/packages/walrus/src/utils/bcs.ts @@ -60,3 +60,8 @@ export const Sliver = bcs.enum('Sliver', { Primary: SliverData, Secondary: SliverData, }); + +export const SliverPair = bcs.struct('SliverPair', { + primary: SliverData, + secondary: SliverData, +}); diff --git a/packages/walrus/src/wasm.ts b/packages/walrus/src/wasm.ts new file mode 100644 index 0000000..b7ca216 --- /dev/null +++ b/packages/walrus/src/wasm.ts @@ -0,0 +1,83 @@ +// Copyright (c) Mysten Labs, Inc. +// SPDX-License-Identifier: Apache-2.0 + +import { BlobEncoder, from_signed_messages_and_indices, MessageType } from '@mysten/walrus-wasm'; + +import { blobIdFromBytes } from './utils/bcs.js'; +import type { BlobMetadataWithId, SliverPair } from './utils/bcs.js'; + +export interface EncodedBlob { + sliverPairs: (typeof SliverPair.$inferInput)[]; + metadata: typeof BlobMetadataWithId.$inferInput & { blob_id: string }; + rootHash: Uint8Array; +} + +export function encodeBlob(nShards: number, bytes: Uint8Array): EncodedBlob { + const encoder = new BlobEncoder(nShards); + + const [sliverPairs, metadata, rootHash] = encoder.encode_with_metadata(bytes); + + return { + sliverPairs, + metadata: { + ...metadata, + blob_id: blobIdFromBytes(new Uint8Array(metadata.blob_id)), + }, + rootHash: new Uint8Array(rootHash.Digest), + }; +} + +export interface CombinedSignature { + signers: number[]; + serializedMessage: Uint8Array; + signature: string; +} + +export interface Confirmation { + serializedMessage: string; + signature: string; +} + +export function combineSignatures( + confirmations: Confirmation[], + signerIndices: number[], +): CombinedSignature { + const combined = from_signed_messages_and_indices( + MessageType.Confirmation, + confirmations, + new Uint16Array(signerIndices), + ) as { + signers: number[]; + serialized_message: number[]; + signature: string; + }; + + return { + signers: signerIndices, + serializedMessage: new Uint8Array(combined.serialized_message), + signature: combined.signature, + }; +} + +export function decodePrimarySlivers( + nShards: number, + size: number | bigint, + sliverPairs: (typeof SliverPair.$inferInput)[], +): Uint8Array { + const encoder = new BlobEncoder(nShards); + const bytes = encoder.decode_primary(BigInt(size), sliverPairs); + return new Uint8Array(bytes); +} + +export function computeMetadata( + nShards: number, + bytes: Uint8Array, +): typeof BlobMetadataWithId.$inferInput & { blob_id: string } { + const encoder = new BlobEncoder(nShards); + const metadata = encoder.compute_metadata(bytes); + + return { + ...metadata, + blob_id: blobIdFromBytes(new Uint8Array(metadata.blob_id)), + }; +}