-
Notifications
You must be signed in to change notification settings - Fork 2
feat(wasm-solana): add transaction deserialization #100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Add WASM bindings for Solana transaction parsing and inspection: - Transaction.fromBase64() / fromBytes() for deserialization - Access to fee payer, recent blockhash, account keys - Instruction decoding with programId, accounts, and data - AccountMeta with isSigner/isWritable flags - Signature access by index (base58 or bytes) - Signable payload extraction for verification Uses official Solana crates exclusively: - solana-transaction for Transaction type and bincode serialization - solana-message is_signer()/is_maybe_writable() for account flags - solana-keypair Keypair::new_from_array() for 32-byte seed support Removed ed25519-dalek dependency (-44KB WASM, -36KB gzipped). Replaces @solana/web3.js Transaction.from() in BitGoJS. Ticket: BTC-2929
OttoAllmendinger
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's reduce the API surface a little bit (unless we really need compatibility)
if we really need these funcs for compatibility, a lot of them can be implemented in the TS layer and we can keep the rust/wasm layer smaller
| /** | ||
| * Serialize the transaction to base64 | ||
| * @returns The base64-encoded transaction | ||
| */ | ||
| toBase64(): string { | ||
| return this._wasm.to_base64(); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the JS world can take care of the base conversions from the Uint8Array
we risk having noisy fromBase64/fromHex/toBase64/toHex on a bunch of different types otherwise
also we have a lot of code that does needless round-tripping in the style of fromBase64(foo.toBase64))
base58 is a bit of an exception because there is no JS builtin
| /** | ||
| * Get all account keys as an array of base58 strings | ||
| * @returns Array of account public keys | ||
| */ | ||
| accountKeys(): string[] { | ||
| return Array.from(this._wasm.account_keys()) as string[]; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should probably use the key types we already have here
| /** | ||
| * Get a signature at the given index as a base58 string | ||
| * @param index - The signature index | ||
| * @returns The signature as a base58 string, or null if index is out of bounds |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why are signatures base58? maybe we can do Buffer here
| * @param index - The signature index | ||
| * @returns The signature bytes, or null if index is out of bounds | ||
| */ | ||
| signatureBytesAt(index: number): Uint8Array | null { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be signatureAt(index) and the other signatureBase58At(index) if we really need it
| /** | ||
| * Get an instruction at the given index | ||
| * @param index - The instruction index | ||
| * @returns The instruction, or null if index is out of bounds | ||
| */ | ||
| instructionAt(index: number): Instruction | null { | ||
| const instr = this._wasm.instruction_at(index); | ||
| return (instr as Instruction) ?? null; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we need this if we already have instructions?
| /** | ||
| * Deserialize a transaction from a base64-encoded string | ||
| * This is the format used by @solana/web3.js Transaction.serialize() | ||
| * @param base64 - The base64-encoded transaction | ||
| * @returns A Transaction instance | ||
| */ | ||
| static fromBase64(base64: string): Transaction { | ||
| const wasm = WasmTransaction.from_base64(base64); | ||
| return new Transaction(wasm); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
see base64 comment
| /** | ||
| * Get the number of instructions in the transaction | ||
| */ | ||
| get numInstructions(): number { | ||
| return this._wasm.num_instructions; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we already have instructions() to get the full array
Add WASM bindings for Solana transaction parsing and inspection:
Uses official Solana crates:
Replaces @solana/web3.js Transaction.from() in BitGoJS.
Ticket: BTC-2929