feat(sdk): add approve/revoke delegation for light-token ATAs#2351
feat(sdk): add approve/revoke delegation for light-token ATAs#2351
Conversation
|
Important Review skippedReview was skipped due to path filters ⛔ Files ignored due to path filters (14)
CodeRabbit blocks several paths by default. You can override this behavior by explicitly including those paths in the path filters. For example, including ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
📝 Coding Plan
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
84166d7 to
13ab9fe
Compare
| export async function transferDelegatedInterface( | ||
| rpc: Rpc, | ||
| payer: Signer, | ||
| source: PublicKey, | ||
| mint: PublicKey, | ||
| recipient: PublicKey, | ||
| delegate: Signer, | ||
| owner: PublicKey, | ||
| amount: number | bigint | BN, | ||
| confirmOptions?: ConfirmOptions, | ||
| ) { | ||
| const mintInfo = await getMintInterface(rpc, mint); | ||
| return _transferDelegatedInterface( | ||
| rpc, | ||
| payer, | ||
| source, | ||
| mint, | ||
| recipient, | ||
| delegate, | ||
| owner, | ||
| amount, | ||
| confirmOptions, | ||
| mintInfo.programId, | ||
| ); |
There was a problem hiding this comment.
🔴 Unified path transferDelegatedInterface and createTransferDelegatedInterfaceInstructions don't force wrap = true
Every other unified transfer function explicitly forces wrap = true to auto-wrap SPL/T22 balances into the canonical light-token ATA. However, transferDelegatedInterface (unified/index.ts:655-678) and createTransferDelegatedInterfaceInstructions (unified/index.ts:686-708) delegate directly to their standard-path counterparts without injecting wrap: true. The standard _transferDelegatedInterface (transfer-delegated-interface.ts:53) calls transferInterface without passing wrap, so it defaults to false. Similarly, _createTransferDelegatedInterfaceInstructions (transfer-delegated-interface.ts:97) passes { owner, programId } without wrap.
This means delegated transfers via the /unified import won't wrap SPL/T22 balances before transferring, breaking the unified path's core contract. If a delegate is approved for an amount that requires wrapping SPL/T22 tokens, the transfer fails with "Insufficient balance" instead of wrapping and succeeding.
Comparison with correctly-wrapped unified functions
Unified transferInterface (line 249-262) correctly passes wrap: true:
return _transferInterface(
rpc, payer, source, mint, recipient, owner, amount,
undefined,
confirmOptions, options,
true, // wrap=true for unified
decimals,
);
But unified transferDelegatedInterface (line 667) does NOT:
return _transferDelegatedInterface(
rpc, payer, source, mint, recipient, delegate, owner, amount,
confirmOptions, mintInfo.programId,
);
Was this helpful? React with 👍 or 👎 to provide feedback.
… ATAs Add TypeScript SDK functions to call the on-chain CTokenApprove (discriminator 4) and CTokenRevoke (discriminator 5) instruction handlers for light-token associated token accounts. New files: - instructions/approve-revoke.ts: sync instruction builders matching Rust SDK layout - actions/approve-interface.ts: async actions with cold loading + tx sending - tests/e2e/approve-revoke-light-token.test.ts: unit + E2E tests Also adds getLightTokenDelegate helper and extends FrozenOperation type.
Avoid unnecessary getMintInterface RPC call when caller provides decimals.
Add transferDelegatedInterface action and unified wrapper, completing the approve → transfer → revoke delegation flow for light-token ATAs.
Update transferDelegatedInterface and createTransferDelegatedInterfaceInstructions to accept a recipient wallet address instead of an explicit destination token account, matching the transferInterface convention from PR #2354. ATA derivation and idempotent creation now happen internally for all programId variants (light-token, SPL, Token-2022).
13ab9fe to
81d9662
Compare
| * @param programId Token program ID (default: LIGHT_TOKEN_PROGRAM_ID) | ||
| * @returns Transaction signature | ||
| */ | ||
| export async function transferDelegatedInterface( |
There was a problem hiding this comment.
remove wrapper - the tests and clients just call transferInterface / createTransferInterfaceInstructions / createTransferToAccountInterfaceInstructions - passing the delegate as the owner/signer.
and those functions should handle it just fine @tilo-14
| * @param programId Token program ID (default: LIGHT_TOKEN_PROGRAM_ID) | ||
| * @returns Instruction batches | ||
| */ | ||
| export async function createRevokeInterfaceInstructions( |
There was a problem hiding this comment.
createXInterfaceInstructions should be extracted into their own files in the instructions dir
| decimals, | ||
| ); | ||
|
|
||
| const revokeIx = createLightTokenRevokeInstruction( |
There was a problem hiding this comment.
seems we currently don't use xInterface as a true superset of spl.
IE
if the source is a hot spl account, approve and revoke should internally dispatch to provided token program's native instruction if wrap=false. the token-programId is passed by client, and defaults to light-token
if wrap=true, (this is if importing via /unified, or if manually passed by client via an optional param, which also seems to be missing), they should internally dispatch to 1) wrap spl to light 2) approve/revoke on the light token account
Summary
createLightTokenApproveInstruction(discriminator 4) andcreateLightTokenRevokeInstruction(discriminator 5) instruction builders matching Rust SDK account layoutapproveInterface/revokeInterfaceasync actions with cold loading + tx sending, following thetransferInterfacepatterngetLightTokenDelegatetest helper and extendFrozenOperationtype with'approve' | 'revoke'src/index.tsandsrc/v3/unified/index.tsTest plan
LIGHT_PROTOCOL_VERSION=V2 pnpm run buildpasses (all 5 bundles)LIGHT_PROTOCOL_VERSION=V2 npx vitest run tests/e2e/approve-revoke-light-token.test.ts