Conversation
Server-side (nodejs) and client-side (react) Privy wallet examples for light-token transfers, wrap, unwrap, load, and balances. Restructured privy/ layout: - nodejs/: server wallet signing via @privy-io/node - react/: embedded wallet signing via @privy-io/react-auth - scripts/: setup helpers (mint creation, SPL interface registration) Transfer creates destination associated token account idempotently before transferring.
React hooks (useTransfer, useUnwrap) now call high-level SDK functions (createTransferInterfaceInstructions, createUnwrapInstructions) instead of manually assembling instructions. Shared signAndSendBatches helper handles multi-tx flows from batched instruction arrays. Balance hooks (react + nodejs) refactored to per-mint accumulator pattern that queries all mints in one pass instead of single-mint. TokenBalance now exposes hot/cold/spl/t22/unified breakdown. Other changes: - useWrap: imports from /unified subpath, uses idempotent ATA create - unwrap (nodejs + react): auto-detect token program from mint owner - mint-light-token script: --spl flag for SPL token program mints - mint-spl script: auto-detect token program from mint account - Remove standalone load.ts (load is handled by transfer/unwrap SDK)
Remove hidden wrap-then-transfer flow from Send button. Add explicit Unify button for wrapping SPL/T22 into unified balance. Send only enabled when unified balance > 0.
| "mint:spl-and-wrap": "tsx src/mint-spl-and-wrap.ts", | ||
| "mint:spl-and-wrap:spl": "tsx src/mint-spl-and-wrap.ts --spl", |
There was a problem hiding this comment.
🔴 Setup scripts reference non-existent file mint-light-token.ts
The privy/scripts/package.json scripts mint:light-token and mint:light-token:spl reference tsx src/mint-light-token.ts, but this file does not exist. The actual file created in this PR is privy/scripts/src/mint-spl-and-wrap.ts, which implements the intended functionality (create mint, mint tokens, wrap, and transfer). Running npm run mint:light-token will fail immediately with a file-not-found error.
Root Cause
The file was likely renamed from mint-light-token.ts to mint-spl-and-wrap.ts during development, but the package.json script references were not updated to match.
The scripts at privy/scripts/package.json:7-8 point to:
"mint:light-token": "tsx src/mint-light-token.ts",
"mint:light-token:spl": "tsx src/mint-light-token.ts --spl",But only privy/scripts/src/mint-spl-and-wrap.ts exists. The README and quick-start guides for both the Node.js and React examples instruct users to run npm run mint:light-token as the first setup step, so this breaks the entire onboarding flow.
Impact: Both npm run mint:light-token and npm run mint:light-token:spl are completely broken. Users cannot create test mints, which is the prerequisite for all other operations.
| "mint:spl-and-wrap": "tsx src/mint-spl-and-wrap.ts", | |
| "mint:spl-and-wrap:spl": "tsx src/mint-spl-and-wrap.ts --spl", | |
| "mint:light-token": "tsx src/mint-spl-and-wrap.ts", | |
| "mint:light-token:spl": "tsx src/mint-spl-and-wrap.ts --spl", |
Was this helpful? React with 👍 or 👎 to provide feedback.
| return rpc.sendRawTransaction(signedTxBuffer, { | ||
| skipPreflight: false, | ||
| preflightCommitment: 'confirmed', | ||
| }); |
There was a problem hiding this comment.
🟡 useWrap missing confirmTransaction — returns signature for potentially unconfirmed transaction
The useWrap hook sends the signed transaction via sendRawTransaction and immediately returns the resulting signature without calling confirmTransaction. This is inconsistent with every other signing path in the codebase.
Root cause and impact
Compare useWrap.ts:87-90 which returns the sendRawTransaction promise directly:
const signedTxBuffer = Buffer.from(signedTx.signedTransaction);
return rpc.sendRawTransaction(signedTxBuffer, {
skipPreflight: false,
preflightCommitment: 'confirmed',
});…with the shared signAndSendBatches.ts:35-39 used by useTransfer and useUnwrap:
const sig = await rpc.sendRawTransaction(signedTxBuffer, { ... });
await rpc.confirmTransaction(sig, 'confirmed');…and the Node.js equivalent at privy/nodejs/src/wrap.ts:75-79:
await connection.confirmTransaction(signature, 'confirmed');Impact: When useWrap returns, the transaction may still be pending or may ultimately fail on-chain. Any caller (like handleTransferSuccess in privy/react/src/App.tsx:52-56) that immediately refreshes balances via fetchBalances will read stale data because the wrap hasn't been confirmed yet. The UI would show "Success" with unchanged balances.
| return rpc.sendRawTransaction(signedTxBuffer, { | |
| skipPreflight: false, | |
| preflightCommitment: 'confirmed', | |
| }); | |
| const signedTxBuffer = Buffer.from(signedTx.signedTransaction); | |
| const signature = await rpc.sendRawTransaction(signedTxBuffer, { | |
| skipPreflight: false, | |
| preflightCommitment: 'confirmed', | |
| }); | |
| await rpc.confirmTransaction(signature, 'confirmed'); | |
| return signature; |
Was this helpful? React with 👍 or 👎 to provide feedback.
Summary
privy/nodejs/): Server-side Privy wallet signing for transfer, wrap, unwrap, load, balances, and transaction history — all targeting devnetprivy/react/): Browser-based embedded wallet with hooks for light-token operations (transfer, wrap, unwrap, balances, history) + unit testsprivy/scripts/): Mint creation, SPL minting, and SPL interface registration using local keypairDetails
@lightprotocol/compressed-token/unifiedsubpath for SDK actionsTest plan