feat(cct-sdk): Add accept admin solana op - #317
Conversation
…10498-deploy-token
…10498-deploy-token
…10498-deploy-token
…-create-token-account
…10498-deploy-token
…-create-token-account
…-10498-deploy-token
…-create-token-account
…-create-token-account
…-create-token-account
|
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 from an isolated build:
- deployToken
3NSLt4D1…c77KW→deployTokenPool → createLookupTable → registerToken(owner)2EaqH4xV…rCrs(registry: administrator = zero default, pending = wallet) → acceptAdmin2Uendc85…bQiX→ setPool succeeds2UqWZfap…VS3U— the exact call that revertedUnauthorized (7000)in the register-token review before this op existed. - Wire-exact: the landed instruction data is exactly
6af010ad89d5a3f6= sha256(global:accept_admin_role_token_admin_registry)[0..8], no args; program logInstruction: AcceptAdminRoleTokenAdminRegistry; accounts (config RO, registry writable, mint RO, authority signer+writable) match the canonicalAcceptAdminRoleTokenAdminRegistrycontext (token_context.rs:179-196) and whatccip-solana-bs58-generator'saccept-admin-rolebuilds. Read the registry PDA back two independent ways (SDK decode + raw borsh-offset decode): administrator == wallet, pending zeroed — the handler's exact promotion semantics (token_admin_registry.rs:115-132). - Both accept paths proven: accept-after-register (admin = zeros) and accept-after-transfer (admin non-zero, via a self-
proposeAdminthen a second accept, txoEExtfeJ…Vb8n) — the preflight gates onpending == authorityonly, exactly like the chain (never stricter, never looser), and the registry'slookup_tablesurvives the accept untouched, as the handler promises. - Isolation semantics are right and typed, client-side before any tx: unregistered mint →
CCIPTokenNotConfiguredError; no pending / wrong wallet →CCTParamsInvalidError. Notably better than our bs58 generator, which has no preflight at all for this op. - Naming: 👍.
acceptAdminis the one op of the trio that already matches the agreed cross-family scheme (registerAdmin/transferAdmin/acceptAdmin) — nothing to rename here.
Two asks before merge, both raised inline with suggestions: A1 (the "no pending admin" test rejects via the wrong branch — proven with a sentinel-message experiment at this head) and A3 (one message for two different rejection states; the idempotent-retry case reads wrong — hit it live). On stacking: since #313 will rename proposeAdmin → transferAdmin on the base branch, and this PR's added lines never reference the propose op, the rename only shuffles adjacent import/barrel lines — landing order #313-rename → #317 keeps both merges trivial. 5/5 new tests pass at the merged form on my machine.
aelmanaa
left a comment
There was a problem hiding this comment.
Re-reviewed at 0429741 (was 0a53a3c). 6 of 7 prior comments are fixed — thank you. One trivial blocker remains: the "no pending admin" test assertion substring doesn't match the message text, so accept-admin.test.ts fails 1/5.
Fixed at 0429741:
- A3 (conflated message) ✅ — two distinct messages at
accept-admin.ts:69-82, both live-proven on devnet - Address docstring ✅ — trimmed to "Router or OffRamp"
- Test typing ✅ —
Partial<GenerateAcceptAdminParams> - Discriminator + account-metas assert ✅ —
6af010ad89d5a3f6+ full key flags - Execute-path
reasonassert ✅ —includes('requires authority to be the executing wallet') - Journey docs ✅ —
@remarks/@seeto registerAdmin/transferAdmin/setPool on both facade methods
Remaining (inline): the A1 stub fix is structurally correct (now reaches the !pendingAdministrator branch), but the assertion checks reason.includes('no pending administrator') while the message reads "no administrator is pending for this token…" — word order is swapped, substring doesn't match, test is RED. One-word fix: align the assertion to 'no administrator is pending' or 'nothing to accept'.
What
acceptAdminandgenerateUnsignedAcceptAdminTokenAdminRegistry operationsacceptAdminRoleTokenAdminRegistryWhy