WebAssembly Integration
Relevant source files
The following files were used as context for generating this wiki page:
The MBBank library integrates WebAssembly (WASM) to handle complex, client-side encryption logic required by the Military Commercial Joint Stock Bank (MBBank) API. Specifically, it executes a WASM binary (main.wasm) used by the bank's official web portal to encrypt sensitive JSON payloads, such as login credentials and transaction details.
This integration is achieved using the wasmtime library, which provides a high-performance runtime for WebAssembly. The library emulates a JavaScript/Go environment to satisfy the WASM module's requirements, allowing the Python SDK to generate compatible dataEnc strings for secure communication with MBBank's servers.
Sources: mbbank/wasm_helper/__init__.py:318-343, mbbank/aio/mbbank.py:134-143, mbbank/sync/mbbank.py:114-123
Architecture and Components
The WebAssembly integration is divided into a runtime emulator and a memory management layer. These components work together to provide a bridge between Python and the WASM binary.
Core Runtime Components
The system implements a bridge that mimics the Go WebAssembly runtime environment. This is necessary because the WASM binary is compiled from Go and expects specific JavaScript-like host functions to be available.
| Component | Purpose |
|---|---|
GO | Emulates the Go runtime environment, managing IDs, values, and function wrappers for the WASM store. |
GOJS | Maps WASM imports (prefixed with runtime. or syscall/js.) to Python methods. |
globalThis | Mocks the global environment, including window.document and location origins required by the WASM module. |
Memory | Provides a high-level wrapper for wasmtime.Memory to handle multi-byte data types and endianness. |
Sources: mbbank/wasm_helper/__init__.py:13-158, mbbank/wasm_helper/helper.py:6-149
Component Relationship
The following diagram illustrates the relationship between the WASM execution components and the library's base classes.
This diagram shows how the bridge environment is structured to support WASM execution.
Sources: mbbank/wasm_helper/__init__.py:31-160, mbbank/wasm_helper/helper.py:6-20, mbbank/base/mbbank.py:49-51
Encryption Data Flow
The primary use case for WebAssembly is the encryption of JSON payloads. The library follows a specific sequence to retrieve the WASM binary and execute the encryption function.
Execution Sequence
- WASM Retrieval: The library checks the
_wasm_cache. If empty, it downloadsmain.wasmfromhttps://online.mbbank.com.vn/assets/wasm/main.wasm. - Environment Setup: A
wasmtime.EngineandStoreare initialized. - Module Instantiation: The
GOclass maps the WASM imports to theGOJSbridge methods. - Encryption Call: The
wasm_encryptfunction is called, which invokes thebderfunction inside the WASM module.
This sequence represents the synchronous and asynchronous flow used to encrypt data before API requests.
Sources: mbbank/aio/mbbank.py:104-114, mbbank/sync/mbbank.py:84-93, mbbank/wasm_helper/__init__.py:318-343
Technical Implementation Details
Memory Abstraction
The Memory class in helper.py handles the complexities of reading and writing structured data to the WebAssembly linear memory. It supports various data formats (Int8, Uint32, Float64, etc.) and automatically handles memory growth via mem.grow when the required address exceeds the current page allocation.
# Example of address handling in Memory
def write(self, value, start_address):
need = start_address + len(value)
if self.mem.size(self.store_wasm) * self.wasm_page_size < need:
grow_page = int(need / self.wasm_page_size) + 1
self.mem.grow(self.store_wasm, int(grow_page))
return self.mem.write(self.store_wasm, value, start_address)
Sources: mbbank/wasm_helper/helper.py:15-30
JS Bridge Emulation
The GO and GOJS classes emulate the behavior of the JavaScript syscall/js package in Go.
- Value Storage:
GO.storeValuehandles the conversion of Python types (None, bool, str, dict, callable) into references that the WASM module can track. - System Calls:
GOJShandles runtime tasks likert_walltime(getting system time) andrt_getRandomData(generating entropy viaos.urandom). - Object Property Access:
sysjs_valueGetandsysjs_valueSetallow the WASM module to manipulate Python objects as if they were JavaScript objects.
Sources: mbbank/wasm_helper/__init__.py:80-140, mbbank/wasm_helper/__init__.py:186-250
Usage in API Methods
The wasm_encrypt function is critical for the login method and other secure requests that require the encrypt=True flag in the _req internal method.
| Method | Usage Description | File Reference |
|---|---|---|
login | Encrypts the payload containing userId, password (MD5), and captcha. | mbbank/aio/mbbank.py:141 |
_req | When encrypt is True, it wraps the entire json_data into a {"dataEnc": ...} payload. | mbbank/sync/mbbank.py:122 |
Sources: mbbank/aio/mbbank.py:134-158, mbbank/sync/mbbank.py:114-138
Summary
The WebAssembly integration serves as a specialized execution environment for the MBBank encryption module. By providing a custom Go-to-Python bridge and memory management layer, the library avoids the need for a full browser environment while maintaining full compatibility with the bank's security requirements.
Sources: mbbank/wasm_helper/__init__.py, mbbank/wasm_helper/helper.py