Skip to content

wallets: accept base58/base64 Solana serializedTransaction + re-export web3.js types#1978

Draft
alfonso-paella wants to merge 1 commit into
mainfrom
devin/1784140593-solana-tx-encoding-web3js-types
Draft

wallets: accept base58/base64 Solana serializedTransaction + re-export web3.js types#1978
alfonso-paella wants to merge 1 commit into
mainfrom
devin/1784140593-solana-tx-encoding-web3js-types

Conversation

@alfonso-paella

Copy link
Copy Markdown
Contributor

Description

Two Solana DX fixes from a customer integrating Solana smart wallets + Jupiter.

1. serializedTransaction encoding trap. The Crossmint API's params.transaction expects base58SolanaWallet.sendTransaction bs58-encodes when you pass a VersionedTransaction object, but when you pass serializedTransaction: string it forwarded the value untouched, so base58 was silently required and undocumented. Jupiter returns base64, so those strings failed. (The README even wrongly documented <base64-encoded-transaction>.)

We now auto-detect and normalize. A new util deserializes to validate, so detection is unambiguous:

normalizeSolanaSerializedTransaction(serialized): string
  // try base58 → VersionedTransaction.deserialize(bs58.decode(s))  → return s unchanged (backward compatible)
  // else base64 → VersionedTransaction.deserialize(Buffer.from(s,"base64")) → return bs58.encode(bytes)
  // else throw "Value must be a base58- or base64-encoded Solana transaction"

base58 is tried first, so existing base58 callers are unaffected. JSDoc on SolanaTransactionInput.serializedTransaction / sendTransaction and the README now state both encodings are accepted.

2. @solana/web3.js type clash. @solana/web3.js was pinned exactly (1.98.1) in dependencies while also declared as a peer (^1.98.1). The exact pin makes package managers install a duplicate nested copy for consumers on a different 1.98.x, so their app's VersionedTransaction is not assignable to the SDK's. Least-disruptive, non-breaking fix:

  • Relax the dependencies range to ^1.98.1 (matches the peer range) so it dedupes to the consumer's copy.
  • Re-export the relevant types from the SDK entrypoint: VersionedTransaction, SolanaTransaction, SolanaKeypair, SolanaPublicKey (aliased to avoid clashing with the SDK's own Transaction).

Breaking-change note: the fully robust single-copy guarantee would be to make @solana/web3.js peer-only (drop it from dependencies). That is a breaking change — the SDK imports web3.js at runtime in several signer files, so consumers not already installing it would break — so it was intentionally avoided in favor of the caret relax + re-export.

Test plan

  • New unit tests for normalizeSolanaSerializedTransaction: base58 returned unchanged, base64 converted to the expected base58, invalid input throws.
  • Updated SolanaWallet tests: base58 pass-through + a base64 input asserting the API receives the base58 encoding. Test helper createMockSolanaSerializedTransaction now builds a real deserializable VersionedTransaction.
  • pnpm --filter @crossmint/wallets-sdk... build, pnpm --filter @crossmint/wallets-sdk test:vitest (652 passed), and pnpm lint all pass locally.

Package updates

  • @crossmint/wallets-sdkminor. Changeset added (.changeset/solana-transaction-encoding.md).

Link to Devin session: https://crossmint.devinenterprise.com/sessions/ef97ae75e32647d8a1aae862ed5f86b8
Requested by: @alfonso-paella

Co-Authored-By: Alfonso <alfonso@paella.dev>
@alfonso-paella alfonso-paella self-assigned this Jul 15, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor
Original prompt from Alfonso

# SDK DX: base58/base64 transaction encoding trap + bundled @solana/web3.js type clash

Repo: Crossmint/crossmint-sdk (has an environment blueprint; pnpm build, pnpm lint, wallets-sdk build+test as in the blueprint. Changesets required for packages/ changes: pnpm change:add).

#``# Context (from a customer report — you do NOT have access to the parent session)
A customer integrating Solana smart wallets + Jupiter reported two SDK DX issues:

> 1. The REST reference documents base58 for params.transaction, but the SDK's serializedTransaction input is undocumented and silently expects base58 too, while Jupiter returns base64. A sentence in the SDK docs (or accepting both encodings) would remove the trap.
> 2. The SDK bundles its own copy of ``@solana/web3.js, so the app's `VersionedTransaction` type is not assignable to the SDK's. Passing a string works, but a peer dependency or re-exported types would fix the type clash.

#``# Your task

  1. Encoding: Find where the wallets SDK accepts serializedTransaction for Solana. Confirm it expects base58. Choose the smaller, safer improvement: (a) accept both base58 and base64 (auto-detect) OR (b) document the base58 requirement clearly in the SDK reference/JSDoc. Prefer accepting both if it can be done unambiguously and safely; otherwise document. Implement it with tests.
  2. web3.js type clash: Investigate how ``@solana/web3.js is declared (dependency vs peerDependency) in the wallets SDK package(s). Evaluate making it a peer dependency and/or re-exporting the relevant transaction types so app-side `VersionedTransaction` is assignable. Implement the least-disruptive fix. Be careful about breaking changes — if making it a peer dep is a breaking change, note it and consider re-exporting types as the non-breaking option.
  3. Add a changeset, run pnpm lint and wallets-sdk build+test.

#``# Deliverable
A draft PR (or two, if the two concerns are cleanly separable) against Crossmint/crossmint-sdk. Describe th... (96 chars truncated...)

@changeset-bot

changeset-bot Bot commented Jul 15, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 3993ce5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 9 packages
Name Type
@crossmint/wallets-sdk Minor
@crossmint/wallets-quickstart-devkit Patch
@crossmint/wallets-playground-react Patch
@crossmint/client-sdk-react-base Patch
@crossmint/client-sdk-react-native-ui Patch
@crossmint/client-sdk-react-ui Patch
@crossmint/wallets-playground-expo Patch
@crossmint/auth-ssr-nextjs-demo Patch
@crossmint/client-sdk-nextjs-starter Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@devin-ai-integration

Copy link
Copy Markdown
Contributor

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR that start with 'DevinAI' or '@devin'.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant