Skip to content

docs: p-token #138 SyncNative breaking change migration guide - #154

Closed
tracy-codes wants to merge 1 commit into
mainfrom
tracy/ptoken-acct-fix
Closed

docs: p-token #138 SyncNative breaking change migration guide#154
tracy-codes wants to merge 1 commit into
mainfrom
tracy/ptoken-acct-fix

Conversation

@tracy-codes

Copy link
Copy Markdown
Contributor

Summary

This PR documents the p-token #138 breaking change that affects Swig transactions containing SyncNative instructions, and provides the exact resolution required for swig-ts (and Rust SDK clients) to remain compatible after p-token goes live on mainnet.

The Issue

During p-token mainnet readiness checks, the Solana Foundation identified Swig transactions (e.g., 275HQ...X9xgu) that would fail after p-token deployment.

Root cause: p-token PR #138 added account validation to the SPL Token SyncNative instruction processor. Previously, the processor iterated only the first account and silently ignored extras. After #138, if a second account exists, it must be the Rent Sysvar — otherwise the instruction errors.

The Swig TypeScript client (packages/lib/src/instructions/compactInstruction.ts) was found to append an extra account to the SyncNative instruction during compaction. Because this extra account is not the Rent Sysvar, those transactions will fail under p-token.

The on-chain Swig program is not at fault. The program faithfully executes compacted inner instructions via CPI. This is purely a client-side instruction construction issue.

How It's Fixed

This PR adds documentation and code comments to the swig-wallet repo. The actual runtime fix must be applied in swig-ts.

Changes in this PR

Impact on Clients Currently Using Swig

Who is affected?

  • All swig-ts clients that wrap SOL and rely on the built-in instruction compaction.
  • Any Rust SDK users that manually append extra accounts to SyncNative instructions.

What happens after p-token goes live?

Any Swig transaction containing a SyncNative instruction with an extra account (that is not the Rent Sysvar) will:

  1. Be rejected by the p-token program with an account validation error.
  2. Fail the entire Swig transaction, burning fees and breaking user flows.

Backwards compatibility

  • Pre-p-token: Extra accounts in SyncNative were silently ignored. These transactions worked.
  • Post-p-token: Extra accounts are validated. Invalid extra accounts cause failures.
  • Fix: Removing the extra account (keeping only the wSOL ATA) works on both pre-p-token and post-p-token environments.

Exact Changes Required for swig-ts

The TypeScript client must update packages/lib/src/instructions/compactInstruction.ts (and any other location constructing SyncNative) to prevent invalid extra accounts.

Recommended Fix (Option A)

Before compaction, detect SyncNative instructions and truncate their account list to only the wSOL ATA:

function sanitizeSyncNative(instruction: TransactionInstruction): TransactionInstruction {
  const isSyncNative =
    instruction.programId.equals(TOKEN_PROGRAM_ID) &&
    instruction.data.length === 1 &&
    instruction.data[0] === 17;

  if (!isSyncNative) return instruction;

  return new TransactionInstruction({
    programId: instruction.programId,
    keys: instruction.keys.slice(0, 1), // keep only wSOL ATA
    data: instruction.data,
  });
}

Alternative Fix (Option B)

If the Swig client architecture requires the extra account to remain for indexing consistency, ensure the second account is SYSVAR_RENT_PUBKEY:

import { SYSVAR_RENT_PUBKEY } from '@solana/web3.js';

// In compactInstruction.ts, when building SyncNative keys:
keys: [
  { pubkey: wsolAta, isSigner: false, isWritable: true },      // slot [0]
  { pubkey: SYSVAR_RENT_PUBKEY, isSigner: false, isWritable: false }, // slot [1] — MUST be Rent
],
data: Buffer.from([17]),

Rust SDK Considerations

The Rust compact_instructions function does not add extra accounts—it only deduplicates existing ones. Rust SDK users are unaffected unless they manually construct SyncNative with extra accounts.

If constructing SyncNative in Rust, follow the same rule: either include only the wSOL ATA, or ensure the second account is solana_program::sysvar::rent::ID.

Testing Recommendations

  1. Unit tests in swig-ts: Verify SyncNative instructions have exactly 1 account (or 2 where the second is Rent).
  2. Integration tests: Run end-to-end wSOL wrap/unwrap against a p-token-enabled validator (e.g., LiteSVM with p-token).
  3. Mainnet readiness audit: Review historical Swig SyncNative transactions for account counts.

Timeline

  • Immediate: Merge this PR to document the requirement.
  • Before p-token mainnet: Release a patched swig-ts version and notify all integrators to upgrade.
  • Ongoing: Monitor for any other SPL Token instructions affected by p-token validation changes.

Coordinated by: Solana Foundation (Edward Chan, Justin Blumenthal, Aaron)
Swig tracking: p-token mainnet readiness checks

…wig-ts fix

p-token PR #138 added account validation to the SPL Token SyncNative
instruction: if a second account exists, it must be the Rent Sysvar.
The Swig TypeScript client (swig-ts) was identified as appending an
extra account during instruction compaction, which will cause
transactions to fail after p-token goes live.

This commit adds:
- Module-level compatibility notes in compact_instructions.rs and lib.rs
- A comprehensive migration guide at docs/PTOKEN_SYNC_NATIVE_MIGRATION.md
  covering the issue, exact fix, pseudocode for swig-ts, and impact on
  existing clients.

No on-chain program changes are required; the fix is client-side.
tracy-codes added a commit to anagrambuild/swig-ts that referenced this pull request May 7, 2026
…bility

The p-token PR #138 added account validation to SPL Token SyncNative:
if a second account exists, it must be the Rent Sysvar. The Swig TS
client was appending an extra account during instruction compaction
(via handleUnbalanced after a SystemProgram transfer), causing those
transactions to fail after p-token goes live.

Changes:
- Add sanitizeSyncNative() that truncates SyncNative to exactly 1
  account (the wSOL ATA) before compaction
- Skip handleUnbalanced extra-account logic for SyncNative instructions
- Add unit tests verifying sanitization and transfer+SyncNative combos

This is a breaking change required for p-token mainnet readiness.

See: anagrambuild/swig-wallet#154
tracy-codes added a commit to anagrambuild/swig-ts that referenced this pull request May 7, 2026
…bility

The p-token PR #138 added account validation to SPL Token SyncNative:
if a second account exists, it must be the Rent Sysvar. The Swig TS
client was appending an extra account during instruction compaction
(via handleUnbalanced after a SystemProgram transfer), causing those
transactions to fail after p-token goes live.

Changes:
- Add sanitizeSyncNative() that truncates SyncNative to exactly 1
  account (the wSOL ATA) before compaction
- Skip handleUnbalanced extra-account logic for SyncNative instructions
- Add unit tests verifying sanitization and transfer+SyncNative combos

This is a breaking change required for p-token mainnet readiness.

See: anagrambuild/swig-wallet#154
@tracy-codes tracy-codes closed this May 7, 2026
tracy-codes added a commit to anagrambuild/swig-ts that referenced this pull request May 7, 2026
…bility

The p-token PR #138 added account validation to SPL Token SyncNative:
if a second account exists, it must be the Rent Sysvar. The Swig TS
client was appending an extra account during instruction compaction
(via handleUnbalanced after a SystemProgram transfer), causing those
transactions to fail after p-token goes live.

Changes:
- Add sanitizeSyncNative() that truncates SyncNative to exactly 1
  account (the wSOL ATA) before compaction
- Skip handleUnbalanced extra-account logic for SyncNative instructions
- Add unit tests verifying sanitization and transfer+SyncNative combos

This is a breaking change required for p-token mainnet readiness.

See: anagrambuild/swig-wallet#154
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