Skip to content

feat(dynamic-client): extract dynamic-address-resolution#996

Merged
lorisleiva merged 3 commits into
codama-idl:mainfrom
hoodieshq:feat/pr1-dynamic-address-resolution
May 18, 2026
Merged

feat(dynamic-client): extract dynamic-address-resolution#996
lorisleiva merged 3 commits into
codama-idl:mainfrom
hoodieshq:feat/pr1-dynamic-address-resolution

Conversation

@mikhd
Copy link
Copy Markdown
Contributor

@mikhd mikhd commented May 12, 2026

Description

This PR [1] extracts Account address resolution functionality from dynamic-client into dynamic-address-resolution package (including standalone PDA resolution). Package dynamic-client was cleaned and now uses dynamic-address-resolution.

Change

  • dynamic-address-resolution contains full functionality of Address resolution for the given Instruction's Account. Exports resolveStandalonePda, resolveInstructionAccountAddress and address helpers.
    • We only move files around with few re-namings and fixes of imports. util files and tests displayed as new are not new.
  • Added generics to exported functions, so they can consume generated types.
  • Cleaned dynamic-client.

Minor

  • Re-named isConvertibleAddress -> isAddressConvertible, createInputValueTransformer -> createCodecInputTransformer.
  • Duplicated three tiny cross-package helpers (formatValueType, safeStringify, getMaybeNodeKind - 20 lines of code) to avoid exposing them as public functions for now.
  • Moved tests files around to align with the new package folder structure.

Public API:

dynamic-address-resolution

// Resolvers
export { resolveInstructionAccountAddress, resolveStandalonePda } from './resolvers';

// Visitors
export { createCodecInputTransformer, createDefaultValueEncoderVisitor } from './visitors';

// Helpers
export { isPublicKeyLike, isAddressConvertible, toAddress } from './shared/address';
export { OPTIONAL_NODE_KINDS } from './shared/nodes';

// Types
export type { AccountsInput, ArgumentsInput, ResolverFn, ResolversInput, ResolverFnInput } from './shared/types';
export type { AddressInput, PublicKeyLike } from './shared/address';

dynamic-client

Unchanged

Notes

This is 1st out of 4 forthcoming dependent PRs. In the next we will do more in terms of spliting:

  1. Extract dynamic-instructions - it will contain functionality for building Solana kit Instruction and AccountMeta. Uses dynamic-address-resolution.

  2. Split type generations between dynamic-address-resolution, dynamic-instructions, dynamic-client packages.

  3. Refactor constant pda seeds resolution.

mikhd added 2 commits May 12, 2026 15:17
* feat: extract dynamic-address-resolution

* feat: add dynamic-address-resolution to dynamic-client

- Cleaned dynamic-client from dynamic-address-resolution files
- Hook dynamic-address-resolution, fix imports

* chore: re-build custom idls

* fix: cleanup

* feat: export DEFAULT_VALUE_ENCODER_SUPPORTED_NODE_KINDS from dynamic-address-resolution

* fix: types import

* fix: async describe

* fix: cleanup
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 12, 2026

🦋 Changeset detected

Latest commit: 5d6add5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@codama/dynamic-address-resolution Minor
@codama/dynamic-client Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

Copy link
Copy Markdown
Member

@lorisleiva lorisleiva left a comment

Choose a reason for hiding this comment

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

Thanks!

@lorisleiva lorisleiva merged commit dbfd246 into codama-idl:main May 18, 2026
4 checks passed
@lorisleiva
Copy link
Copy Markdown
Member

@trevor-cortex

Copy link
Copy Markdown

@trevor-cortex trevor-cortex left a comment

Choose a reason for hiding this comment

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

Summary

Extracts address resolution out of @codama/dynamic-client into a new @codama/dynamic-address-resolution package, with the dynamic-client code now consuming it. Most of the diff is renames (packages/dynamic-client/...packages/dynamic-address-resolution/...) with import path updates, a few function/type renames (isConvertibleAddressisAddressConvertible, createInputValueTransformercreateCodecInputTransformer, deriveStandalonePDAresolveStandalonePda), and the introduction of generics (TAccounts, TArgs, TResolvers) across the resolution pipeline so generated client types can flow through.

New public surface is curated in src/index.ts: resolveInstructionAccountAddress, resolveStandalonePda, two visitor factories, and a small set of address helpers. Package config mirrors the existing dynamic-* packages (tsup, multi-target exports, sideEffects: false, treeshakability test, workspace deps).

Overall the move is mechanical and clean. A few things worth a closer look below.

Things to watch

  1. deriveStandalonePDAresolveStandalonePda is a rename that isn't called out. The PR description only lists the isConvertibleAddress and createInputValueTransformer renames, but deriveStandalonePDA is also renamed. If @codama/dynamic-client previously re-exported deriveStandalonePDA from its public API, this is a breaking change there and the patch bump on dynamic-client in .changeset/neat-badgers-heal.md would be wrong (should be minor pre-1.0, or major if you've passed 1.0). Worth double-checking whether anything outside this repo was importing the old name.

  2. resolvePDAAddress dropped the = {} defaults for accountsInput/argumentsInput. Previously the function defaulted these to {}; now they propagate through as undefined from the new BaseResolutionContext typing. Most downstream lookups use ?.[name] so this is safe, but it's a behavioural change worth confirming is intentional — particularly anywhere the values are spread or iterated rather than indexed.

  3. Per-package memoized codecs. src/shared/codecs.ts keeps its own module-level cache, which is now distinct from any equivalent cache in dynamic-codecs / dynamic-client. Apps loading multiple of these packages will end up with one codec instance per package. Almost certainly fine, just noting it.

  4. src/index.ts exports DEFAULT_VALUE_ENCODER_SUPPORTED_NODE_KINDS in addition to the two visitor factories, but the PR description's "Public API" block omits it. Either trim the export or update the description — small thing but the README under "Types" doesn't list it either.

Notes for reviewers

  • The generic plumbing is consistent across all resolvers and visitors. The contravariance escape hatch in shared/types.ts (ResolverFnInput using ResolverFn<any, any>) is the right move and the comment explains why.
  • The auto-resolution truth table in resolve-instruction-account-address.ts is excellent — I traced each row against the canAutoResolve logic and it matches.
  • resolveAccountAddress now derives accountAddressInput from accountsInput?.[ixAccountNode.name] instead of receiving it as a parameter; behaviour is preserved because the only caller passing an external value (resolveAccountValueNodeAddress) was already looking up by the same name.
  • Lots of test files moved; new tests added for resolveInstructionAccountAddress, resolveConditional, codecs, types, and util. Good coverage on the new public function.

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