feat(cct-sdk): Add transfer admin solana op - #313
Conversation
|
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 |
There was a problem hiding this comment.
I ran this op live on Solana devnet:
- Executed
proposeAdminend-to-end: tx5sQaftoHuU3cWekpZUri6kqhZVuYsLBYZZTKLjyTFfgpmQYqwxXffSmJ9VRaT9he2xGjWjATY2YYgbpbtDpgCH8m. Read the registry PDA back two independent ways (SDK decode + rawgetAccountInfoborsh-offset decode):pending_administrator== the proposednewAdmin,administratorunchanged. Accounts and data match the canonicalModifyTokenAdminRegistrycontext byte-for-byte. - The client preflight mirrors the on-chain constraint (
authority == administrator @ Unauthorized,token_context.rs:132) exactly — neither stricter nor looser — and both negative paths reject client-side with typed errors before any transaction (wrong-state authority; authority ≠ executing wallet). Nice. - Type discipline, error taxonomy, layer boundaries, and the facade/barrel pattern all match the sibling ops; 4/4 new tests pass at head.
Two things I'd ask for before merge, both raised inline: the rename to transferAdminRole (the chain's own program log for this op's transaction is Instruction: TransferAdminRoleTokenAdminRegistry; "propose" is the registration verb everywhere else in CCIP — including our own bs58 generator), and the journey docs hook-up once DAPP-10605's accept op exists. On that second point, an operational note: to test this op at all I had to perform the accept instruction outside the SDK — after registerToken the registry's administrator is the zero default, so proposeAdmin/transferAdminRole has nothing it can act on until the accept op lands. The two PRs are really one journey; landing 10604 → 10605 in order (10605 rebased onto this head) and cross-linking their docs would close the register-token review's F1 completely.
(Not this PR's diff, but noting for the stack: register-token.test.ts:8 on the base branch has an import-x/order warning — errors.ts import above the ../../../../ group; a lint:fix on whichever branch lands first clears it.)
aelmanaa
left a comment
There was a problem hiding this comment.
✅ Approve — the rename landed correctly and completely; all prior blockers and nits resolved.
Re-reviewed at 4771aef (was dd03030). Every finding from the prior pass is fixed:
- P1 (rename) ✅ —
transferAdminend-to-end: classTransferAdmin, facadegenerateUnsignedTransferAdmin/transferAdmin, op filetransfer-admin.ts, tests. No residualproposeAdminidentifier in SDK code. Still wraps the unchangedtransferAdminRoleTokenAdminRegistryinstruction. Fresh devnet run under the new name is wire-identical (same discriminatorb262cbb5cb6b6a0e, same on-chain logInstruction: TransferAdminRoleTokenAdminRegistry). - Comments 2–7 ✅ — journey docs wired (
@remarks/@seetoacceptAdmin+ register↔accept↔setPool), test typing (Partial<GenerateTransferAdminParams>), discriminator + account-metas asserts, execute-pathreasonassert, address docstring trimmed, state-blind message branched (pending-registration case). - Import-order lint ✅ —
errors.tsnow inside the internal group; eslint clean.
Live re-verification (devnet, 2026-07-29): fresh mint → registerAdmin (owner) → raw accept → transferAdmin executed — on-chain pending_administrator == newAdmin, administrator unchanged, read back via SDK + raw borsh decode. Wire byte-identical to the pre-rename dd03030 run.
One non-blocking nit: the {@link acceptAdmin} / {@link generateUnsignedAcceptAdmin} links are forward references — the accept op ships on DAPP-10605 (PR #317), so they resolve only once #313 → #317 land in the agreed order.
CI note: npm ci fails on the lockfile sync issue (@emnapi/core@1.11.2 missing) — same repo-wide infra issue as #310/#317, not from this PR's code. Local npm run check is green with a clean install (prettier + eslint + tsc + 5/5 + 9/9 tests).
What
transferAdminandgenerateUnsignedTransferAdminTokenAdminRegistry operationstransferAdminRoleTokenAdminRegistryWhy