Skip to content

Commit

Permalink
Fix transaction serialize/deserialize bugs in ghost wallet. (#40)
Browse files Browse the repository at this point in the history
Contribute what we have fixed in https://github.com/brave/wallet-standard-brave
back to the reference wallet implementation. Most codes are actually from
wallet-adapter.
- Always deserialize transactions using VersionedTransaction.deserialize()
- In #signTransaction, specify requireAllSignatures and verifySignatures
  to false when serializing legacy transactions signed by wallet, because
  transactions could be partial signed.
  • Loading branch information
yrliou authored Dec 15, 2023
1 parent 2a1d55c commit c68c266
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
7 changes: 7 additions & 0 deletions packages/wallets/ghost/src/solana.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// This is copied from @solana/wallet-standard-chains

import type { IdentifierString } from '@wallet-standard/base';
import type { Transaction, VersionedTransaction } from '@solana/web3.js';

/** Solana Mainnet (beta) cluster, e.g. https://api.mainnet-beta.solana.com */
export const SOLANA_MAINNET_CHAIN = 'solana:mainnet';
Expand Down Expand Up @@ -31,3 +32,9 @@ export type SolanaChain = (typeof SOLANA_CHAINS)[number];
export function isSolanaChain(chain: IdentifierString): chain is SolanaChain {
return SOLANA_CHAINS.includes(chain as SolanaChain);
}

export function isVersionedTransaction(
transaction: Transaction | VersionedTransaction
): transaction is VersionedTransaction {
return 'version' in transaction;
}
28 changes: 24 additions & 4 deletions packages/wallets/ghost/src/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import bs58 from 'bs58';
import { GhostWalletAccount } from './account.js';
import { icon } from './icon.js';
import type { SolanaChain } from './solana.js';
import { isSolanaChain, SOLANA_CHAINS } from './solana.js';
import { isSolanaChain, isVersionedTransaction, SOLANA_CHAINS } from './solana.js';
import { bytesEqual } from './util.js';
import type { Ghost } from './window.js';

Expand Down Expand Up @@ -236,7 +236,16 @@ export class GhostWallet implements Wallet {

const signedTransaction = await this.#ghost.signTransaction(VersionedTransaction.deserialize(transaction));

outputs.push({ signedTransaction: signedTransaction.serialize() });
const serializedTransaction = isVersionedTransaction(signedTransaction)
? signedTransaction.serialize()
: new Uint8Array(
(signedTransaction as Transaction).serialize({
requireAllSignatures: false,
verifySignatures: false,
})
);

outputs.push({ signedTransaction: serializedTransaction });
} else if (inputs.length > 1) {
let chain: SolanaChain | undefined = undefined;
for (const input of inputs) {
Expand All @@ -251,12 +260,23 @@ export class GhostWallet implements Wallet {
}
}

const transactions = inputs.map(({ transaction }) => Transaction.from(transaction));
const transactions = inputs.map(({ transaction }) => VersionedTransaction.deserialize(transaction));

const signedTransactions = await this.#ghost.signAllTransactions(transactions);

outputs.push(
...signedTransactions.map((signedTransaction) => ({ signedTransaction: signedTransaction.serialize() }))
...signedTransactions.map((signedTransaction) => {
const serializedTransaction = isVersionedTransaction(signedTransaction)
? signedTransaction.serialize()
: new Uint8Array(
(signedTransaction as Transaction).serialize({
requireAllSignatures: false,
verifySignatures: false,
})
);

return { signedTransaction: serializedTransaction };
})
);
}

Expand Down

0 comments on commit c68c266

Please sign in to comment.