fix(cct-sdk): Update and refactor solana lifecycle and tests - #321
fix(cct-sdk): Update and refactor solana lifecycle and tests#321mervin-link wants to merge 82 commits into
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
…eat/DAPP-10812-get-supported-tokens
…eat/DAPP-10812-get-supported-tokens
|
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.
§A — validateOptionalPublicKey + test refactor. Centralizes 8 duplicated if (params.x) validatePublicKey(...) guards into one validateOptionalPublicKey, swapping truthiness (if (x)) for !== undefined. The only new runtime divergence is the empty string: old code silently rewrote a caller's ''/null authority into "use payer" (masking a bug); new code rejects it. ''/null were never valid base58 pubkeys → pure hardening, no program-accepted input newly refused. Aligns to an existing in-file standard (resolvePoolProgram, validateInteger already use !== undefined); validate.ts isn't re-exported, so no CLI↔SDK boundary moves. The deploy-token.ts freezeAuthority?: string | null keeping its explicit !== null guard is correct — null is its documented "disable freezing" sentinel.
§B — parse/prepare lifecycle. SolanaOperation<P,Tx,Parsed=SolanaGenerateParams<P>> gains parse(params): Parsed (no-mutation normalize/default/convert), prepare() = validate()+parse(), and buildUnsigned consumes typed Parsed. The Parsed default makes the 9 non-adopters textually identical to before; adopters (accept-admin, and now configure/remove-allowlist) get typed PublicKeys with one fewer re-parse. Contained (base not re-exported), cross-family Operation<> untouched.
Live devnet proofs (carry forward — the add68cb delta is validation/doc/test only, no instruction/account change):
- §A
createLookupTableon devnet, wallet2SGSoyjD…C3V3: (a)authorityexplicit → tx5Xcj2tj…Hwjvp; (b)authorityomitted (→payer) → tx8NCoUz8…utRt9; both ALTs read backauthority = 2SGSoyjD…C3V3. (c) negativeauthority: ''→ rejected pre-flightCCTParamsInvalidError. - §B real
acceptAdminLANDED through the newpreparepath — tx5gLXmjt…5ZUzJu, on-chain ix data6af010ad89d5a3f6, accounts{config, token_admin_registry, mint, authority}byte-identical to the generated instruction; TAR read-backadministrator = 2SGSoyjD…C3V3,pendingAdministrator = 1111…1111. Generate-pathauthorityexplicit vs omitted → identical instruction (no-mutation confirmed). Grounded toccip-router/src/token_context.rs:179-196(authority=Signerwithaddress = pending_administrator @ Unauthorized).
Verified at add68cb: npm run check exit 0 (lint+typecheck+generate), 27/27 targeted tests pass (validate + deploy-token-pool + operation), including the new null/''-rejected and op-level authority:''-throws cases.
Resolved since the last pass (e27c959 → add68cb): §A TSDoc (validateOptionalPublicKey now documents "only undefined is absent; null/'' rejected" + @throws), §A coverage (null-throws + valid-passes + op-level authority:''), §A quoted error message, §B class/parse TSDoc (validate=cross-field / override parse when Parsed differs), and the B4 append-to-lookup-table regression fix. Thanks for these.
Not blockers / correct-by-design: the truthiness→!== undefined shift is pure hardening (''/null never valid pubkeys); freezeAuthority's null sentinel correctly keeps its explicit guard; parse() no-mutation is on-chain-proven byte-identical; the EVM side having no optional-address validator is a pre-existing gap, not this branch's responsibility. The B4 append-to-lookup-table.ts:94 fix (?. restored) is correct.
| * validation, defaults, or conversion; it must be overridden whenever `Parsed` differs from | ||
| * `SolanaGenerateParams<P>`. | ||
| */ | ||
| export abstract class SolanaOperation< |
There was a problem hiding this comment.
[§B nit — base no-op validate] Parse-only ops must still write an empty validate() {} stub. Consider a default no-op validate on the base so those ops can omit the boilerplate (removes the empty stub in configure/remove/accept-style ops).
There was a problem hiding this comment.
I considered this, but it would require override across every existing validator under noImplicitOverride. I’ll add a default no-op validation on the base once every op uses prepare.
What
ccip-sdkpackage and remove the dev buildpreparelifecycle:prepare (validate → parse) → build unsigned tx → submitacceptAdminto parse validated public-key strings into PublicKeysvalidateOptionalPublicKeyand replace truthy optional-key validation checksgenerate,validation, andexecuteWhy