Skip to content

feat(cct-sdk): Add configure allowlist solana op - #323

Merged
mervin-link merged 87 commits into
cct-sdkfrom
feat/DAPP-10805-configure-allowlist
Aug 6, 2026
Merged

feat(cct-sdk): Add configure allowlist solana op#323
mervin-link merged 87 commits into
cct-sdkfrom
feat/DAPP-10805-configure-allowlist

Conversation

@mervin-link

@mervin-link mervin-link commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

What

  • DAPP-10805
  • Add Solana CCT token-pool configureAllowlist unsigned and signed operations
  • Support canonical pool types and compatible custom pool program addresses

Why

  • Allow pool owners to add allowlist entries and enable or disable allowlist enforcement after pool initialization

@mervin-link
mervin-link requested a review from apedrob August 4, 2026 12:46
@mervin-link
mervin-link requested review from a team, PabloMansanet and aelmanaa as code owners August 4, 2026 12:46
@vercel

vercel Bot commented Aug 4, 2026

Copy link
Copy Markdown

You must have Developer access to commit code to Chainlink Labs on Vercel. If you contact an administrator and receive Developer access, commit again to see your changes.

Learn more: https://vercel.com/docs/accounts/team-members-and-roles/access-roles#team-level-roles

Comment thread ccip-sdk/src/cct/solana/token-pool/operations/configure-allowlist.ts Outdated
Comment thread ccip-sdk/src/cct/solana/token-admin-registry/operations/append-to-lookup-table.ts Outdated
Comment thread ccip-sdk/src/cct/solana/index.ts

@aelmanaa aelmanaa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed a03421d across type-safety, architecture, and DX — grounded against the chainlink-ccip Solana pool programs and proven end-to-end on devnet (the op configures the allowlist and the allowlist actually gates sends). The op is functionally correct; requesting changes on DX/naming/docs/scope before it ships on the CCT surface.

Proof the op writes correct state (append semantics + duplicate revert), live devnet:

  • add A → tx, add B → tx, add C → tx → read-back allow_list = [A, B, C] in insertion order = append, not replace.
  • re-add existing A → reverts AllowlistKeyAlreadyExisted (err 6010) — grounded at burnmint-token-pool/src/lib.rs:376-380 (add: Vec<Pubkey>, push, require!(!list.contains…)).

Proof the allowlist ENFORCES sends (2×2 sender matrix, live devnet): two fresh pools (op is append-only → one per case), allowlist written by this op, then the exact gated instruction lock_or_burn_tokens simulated against live pool state:

pool original_sender in list? result
P1 allow_list=[WALLET] (configure tx) WALLET PASS — burn executes, pool returns LockOrBurnOutV1
P1 OTHER BLOCKEDInvalidSender 6006
P2 allow_list=[OTHER] (configure tx) OTHER PASS
P2 WALLET BLOCKEDInvalidSender 6006

Same pool, flip only original_sender → flips PASS ↔ block, isolating the allowlist as the sole variable. Block is the grounded gate base-token-pool/src/common.rs:659: require!(!allow_list_enabled || allow_list.contains(&original_sender), InvalidSender) → verbatim AnchorError … common.rs:659. Error Code: InvalidSender. Error Number: 6006. Error Message: Sender not allowed (0x1776). Pool states: P1 · P2.

The 5 blockers in the inline comments are all independent of enforcement working — and proving it does enforce actually sharpens B1/B2 (a wrong address genuinely blocks senders, and there's no SDK way to remove it).

@mervin-link

Copy link
Copy Markdown
Collaborator Author

Reviewed a03421d across type-safety, architecture, and DX — grounded against the chainlink-ccip Solana pool programs and proven end-to-end on devnet (the op configures the allowlist and the allowlist actually gates sends). The op is functionally correct; requesting changes on DX/naming/docs/scope before it ships on the CCT surface.

Proof the op writes correct state (append semantics + duplicate revert), live devnet:

  • add A → tx, add B → tx, add C → tx → read-back allow_list = [A, B, C] in insertion order = append, not replace.
  • re-add existing A → reverts AllowlistKeyAlreadyExisted (err 6010) — grounded at burnmint-token-pool/src/lib.rs:376-380 (add: Vec<Pubkey>, push, require!(!list.contains…)).

Proof the allowlist ENFORCES sends (2×2 sender matrix, live devnet): two fresh pools (op is append-only → one per case), allowlist written by this op, then the exact gated instruction lock_or_burn_tokens simulated against live pool state:

pool original_sender in list? result
P1 allow_list=[WALLET] (configure tx) WALLET ✅ PASS — burn executes, pool returns LockOrBurnOutV1
P1 OTHER ❌ BLOCKEDInvalidSender 6006
P2 allow_list=[OTHER] (configure tx) OTHER ✅ PASS
P2 WALLET ❌ BLOCKEDInvalidSender 6006
Same pool, flip only original_sender → flips PASS ↔ block, isolating the allowlist as the sole variable. Block is the grounded gate base-token-pool/src/common.rs:659: require!(!allow_list_enabled || allow_list.contains(&original_sender), InvalidSender) → verbatim AnchorError … common.rs:659. Error Code: InvalidSender. Error Number: 6006. Error Message: Sender not allowed (0x1776). Pool states: P1 · P2.

The 5 blockers in the inline comments are all independent of enforcement working — and proving it does enforce actually sharpens B1/B2 (a wrong address genuinely blocks senders, and there's no SDK way to remove it).

I’ve addressed the inline feedback: renamed the append input to add, reject duplicate input, documented toggle behavior, added reciprocal docs links, and expanded execute coverage.

@mervin-link
mervin-link requested a review from aelmanaa August 5, 2026 15:28

@aelmanaa aelmanaa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed 930a731 across type-safety, architecture, and DX — grounded against the chainlink-ccip Solana pool programs and proven end-to-end on devnet (the op writes the allowlist and the allowlist actually gates sends). The first pass (a03421d) requested changes on 5 DX/naming/docs/test items; b5083b0 "fix: address comments" resolves all five. Approving.

All 5 blockers resolved (verified):

  • B1 ✅ param allowlistadd (matches the IDL add: Vec<Pubkey> + mirrors the future remove); doc now "Addresses to append … Must not contain duplicates"; new client-side dedup parses each add[i] then Set-checks, rejecting within-array duplicates before the on-chain AllowlistKeyAlreadyExisted revert.
  • B2 ✅ facade @remarks Removing addresses is not yet supported by the SDK. on both methods (and now superseded — the companion removeFromAllowList has since landed as DAPP-10806).
  • B3 ✅ facade docs "Every call overwrites enforcement; pass add: [] to toggle it without appending"; execute @example shows the pure-toggle pattern (add: [], enabled: false).
  • B4append-to-lookup-table.ts:94?. restored (!params.additionalAddresses?.length) with a narrow eslint-disable-next-line @typescript-eslint/no-unnecessary-condition (this fix rode in via the fix/refactor-solana-operation base).
  • B5 ✅ tests: multi-address + append with an enabled: false decoded-assert (catches a swapped-args bug), empty-list toggle, non-array reject, duplicate reject, and an execute success path; the @see copy-paste nit is fixed (generate↔execute cross-link).

DRY ✓ faithful accept-admin parse/prepare clone, shared validators reused, accountsStrict matches the IDL. Cross-family: interface reused polymorphically — same SolanaOperation lifecycle; EVM has no allowlist SDK op yet (its pool exposes applyAllowListUpdates, a future EVM op is owed). Per-version validity: grounded against burnmint/cctp/lockrelease pool programs — configure_allow_list(add, enabled) identical across all three. npm run check green.

Proof it writes correct state (append semantics + dedup), live devnet @ 930a731 — fresh burn-mint pool mint UmhE5TR…PpFdY: renamed add API lands and appends (ground-truth read allowList=[X, Y] insertion order) — add X, append Y; toggle-only add:[] enabled:false → ground-truth listEnabled=false tx; new dedup guard add:[Z,Z]rejected pre-RPC CCTParamsInvalidError param=add "must not contain duplicate addresses".

Proof it ENFORCES sends (2×2 sender matrix, live devnet — still valid; the on-chain instruction is byte-identical to a03421d, only the TS param name + a pre-RPC guard changed): two fresh pools (P1 91y9tsa… · P2 2Jhfsf…), allowlist written by this op, then lock_or_burn_tokens simulated against live state:

pool original_sender in list? result
P1 allow_list=[WALLET] WALLET PASS — burn executes
P1 OTHER BLOCKEDInvalidSender 6006
P2 allow_list=[OTHER] OTHER PASS
P2 WALLET BLOCKEDInvalidSender 6006

Flipping only original_sender flips PASS↔block — isolating the allowlist as the sole variable. Block is the grounded gate base-token-pool/src/common.rs:659 require!(!allow_list_enabled || allow_list.contains(&original_sender), InvalidSender) (0x1776).

Minor note (not blocking): deployTokenPool still names its initial-set param allowlist while the append op is now add — defensible (set vs append), flagging for a conscious call.

Base automatically changed from fix/refactor-solana-operation to cct-sdk August 6, 2026 10:46
@mervin-link
mervin-link merged commit 1af73ba into cct-sdk Aug 6, 2026
2 of 4 checks passed
@mervin-link
mervin-link deleted the feat/DAPP-10805-configure-allowlist branch August 6, 2026 11:46
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.

3 participants