diff --git a/packages/renderers-js/src/fragments/accountFetchHelpers.ts b/packages/renderers-js/src/fragments/accountFetchHelpers.ts index 4cbe789ec..1d1ce4bab 100644 --- a/packages/renderers-js/src/fragments/accountFetchHelpers.ts +++ b/packages/renderers-js/src/fragments/accountFetchHelpers.ts @@ -1,4 +1,5 @@ import { AccountNode } from '@codama/nodes'; +import { getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { TypeManifest } from '../TypeManifest'; @@ -6,11 +7,12 @@ import { Fragment, fragment, fragmentFromTemplate } from './common'; export function getAccountFetchHelpersFragment( scope: Pick & { - accountNode: AccountNode; + accountPath: NodePath; typeManifest: TypeManifest; }, ): Fragment { - const { accountNode, typeManifest, nameApi, customAccountData } = scope; + const { accountPath, typeManifest, nameApi, customAccountData } = scope; + const accountNode = getLastNodeFromPath(accountPath); const hasCustomData = customAccountData.has(accountNode.name); const accountTypeFragment = hasCustomData ? typeManifest.strictType.clone() diff --git a/packages/renderers-js/src/fragments/accountPdaHelpers.ts b/packages/renderers-js/src/fragments/accountPdaHelpers.ts index 67f17b057..a9618c394 100644 --- a/packages/renderers-js/src/fragments/accountPdaHelpers.ts +++ b/packages/renderers-js/src/fragments/accountPdaHelpers.ts @@ -1,5 +1,5 @@ import { AccountNode, isNodeFilter } from '@codama/nodes'; -import { NodeStack } from '@codama/visitors-core'; +import { findProgramNodeFromPath, getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import type { TypeManifest } from '../TypeManifest'; @@ -7,13 +7,14 @@ import { Fragment, fragment, fragmentFromTemplate } from './common'; export function getAccountPdaHelpersFragment( scope: Pick & { - accountNode: AccountNode; - accountStack: NodeStack; + accountPath: NodePath; typeManifest: TypeManifest; }, ): Fragment { - const { accountNode, accountStack, nameApi, linkables, customAccountData, typeManifest } = scope; - const pdaNode = accountNode.pda ? linkables.get([...accountStack.getPath(), accountNode.pda]) : undefined; + const { accountPath, nameApi, linkables, customAccountData, typeManifest } = scope; + const accountNode = getLastNodeFromPath(accountPath); + const programNode = findProgramNodeFromPath(accountPath)!; + const pdaNode = accountNode.pda ? linkables.get([...accountPath, accountNode.pda]) : undefined; if (!pdaNode) { return fragment(''); } @@ -39,7 +40,7 @@ export function getAccountPdaHelpersFragment( findPdaFunction, hasVariableSeeds, pdaSeedsType, - program: accountStack.getProgram(), + program: programNode, }) .mergeImportsWith(accountTypeFragment) .addImports(importFrom, hasVariableSeeds ? [pdaSeedsType, findPdaFunction] : [findPdaFunction]) diff --git a/packages/renderers-js/src/fragments/accountSizeHelpers.ts b/packages/renderers-js/src/fragments/accountSizeHelpers.ts index b26d13560..1c20fce5d 100644 --- a/packages/renderers-js/src/fragments/accountSizeHelpers.ts +++ b/packages/renderers-js/src/fragments/accountSizeHelpers.ts @@ -1,12 +1,14 @@ import { AccountNode } from '@codama/nodes'; +import { getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { Fragment, fragment, fragmentFromTemplate } from './common'; export function getAccountSizeHelpersFragment( - scope: Pick & { accountNode: AccountNode }, + scope: Pick & { accountPath: NodePath }, ): Fragment { - const { accountNode, nameApi } = scope; + const { accountPath, nameApi } = scope; + const accountNode = getLastNodeFromPath(accountPath); if (accountNode.size == null) { return fragment(''); } diff --git a/packages/renderers-js/src/fragments/accountType.ts b/packages/renderers-js/src/fragments/accountType.ts index eac5dcd53..6db8f95aa 100644 --- a/packages/renderers-js/src/fragments/accountType.ts +++ b/packages/renderers-js/src/fragments/accountType.ts @@ -1,4 +1,5 @@ import { AccountNode } from '@codama/nodes'; +import { getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { TypeManifest } from '../TypeManifest'; @@ -7,11 +8,12 @@ import { getTypeWithCodecFragment } from './typeWithCodec'; export function getAccountTypeFragment( scope: Pick & { - accountNode: AccountNode; + accountPath: NodePath; typeManifest: TypeManifest; }, ): Fragment { - const { accountNode, typeManifest, nameApi, customAccountData } = scope; + const { accountPath, typeManifest, nameApi, customAccountData } = scope; + const accountNode = getLastNodeFromPath(accountPath); if (customAccountData.has(accountNode.name)) { return fragment(''); diff --git a/packages/renderers-js/src/fragments/instructionAccountTypeParam.ts b/packages/renderers-js/src/fragments/instructionAccountTypeParam.ts index a9abea487..7a25bb8e2 100644 --- a/packages/renderers-js/src/fragments/instructionAccountTypeParam.ts +++ b/packages/renderers-js/src/fragments/instructionAccountTypeParam.ts @@ -1,5 +1,11 @@ -import { InstructionAccountNode, InstructionInputValueNode, InstructionNode, pascalCase } from '@codama/nodes'; -import { LinkableDictionary, NodeStack } from '@codama/visitors-core'; +import { InstructionAccountNode, InstructionInputValueNode, pascalCase } from '@codama/nodes'; +import { + findInstructionNodeFromPath, + findProgramNodeFromPath, + getLastNodeFromPath, + LinkableDictionary, + NodePath, +} from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { ImportMap } from '../ImportMap'; @@ -8,12 +14,13 @@ import { Fragment, fragment } from './common'; export function getInstructionAccountTypeParamFragment( scope: Pick & { allowAccountMeta: boolean; - instructionAccountNode: InstructionAccountNode; - instructionNode: InstructionNode; - instructionStack: NodeStack; + instructionAccountPath: NodePath; }, ): Fragment { - const { instructionNode, instructionAccountNode, instructionStack, allowAccountMeta, linkables } = scope; + const { instructionAccountPath, allowAccountMeta, linkables } = scope; + const instructionAccountNode = getLastNodeFromPath(instructionAccountPath); + const instructionNode = findInstructionNodeFromPath(instructionAccountPath)!; + const programNode = findProgramNodeFromPath(instructionAccountPath)!; const typeParam = `TAccount${pascalCase(instructionAccountNode.name)}`; const accountMeta = allowAccountMeta ? ' | IAccountMeta' : ''; const imports = new ImportMap(); @@ -25,11 +32,7 @@ export function getInstructionAccountTypeParamFragment( return fragment(`${typeParam} extends string${accountMeta} | undefined = undefined`, imports); } - const defaultAddress = getDefaultAddress( - instructionAccountNode.defaultValue, - instructionStack.getProgram()!.publicKey, - linkables, - ); + const defaultAddress = getDefaultAddress(instructionAccountNode.defaultValue, programNode.publicKey, linkables); return fragment(`${typeParam} extends string${accountMeta} = ${defaultAddress}`, imports); } diff --git a/packages/renderers-js/src/fragments/instructionByteDelta.ts b/packages/renderers-js/src/fragments/instructionByteDelta.ts index 3c3c7fc82..6ba13a064 100644 --- a/packages/renderers-js/src/fragments/instructionByteDelta.ts +++ b/packages/renderers-js/src/fragments/instructionByteDelta.ts @@ -1,15 +1,16 @@ import { assertIsNode, camelCase, InstructionByteDeltaNode, InstructionNode, isNode } from '@codama/nodes'; +import { getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { Fragment, fragment, mergeFragments } from './common'; export function getInstructionByteDeltaFragment( scope: Pick & { - instructionNode: InstructionNode; + instructionPath: NodePath; useAsync: boolean; }, ): Fragment { - const { byteDeltas } = scope.instructionNode; + const { byteDeltas } = getLastNodeFromPath(scope.instructionPath); const fragments = (byteDeltas ?? []).flatMap(r => getByteDeltaFragment(r, scope)); if (fragments.length === 0) return fragment(''); return mergeFragments( diff --git a/packages/renderers-js/src/fragments/instructionData.ts b/packages/renderers-js/src/fragments/instructionData.ts index 02840e4f4..57859356a 100644 --- a/packages/renderers-js/src/fragments/instructionData.ts +++ b/packages/renderers-js/src/fragments/instructionData.ts @@ -1,4 +1,5 @@ import { InstructionNode } from '@codama/nodes'; +import { getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { TypeManifest } from '../TypeManifest'; @@ -8,10 +9,11 @@ import { getTypeWithCodecFragment } from './typeWithCodec'; export function getInstructionDataFragment( scope: Pick & { dataArgsManifest: TypeManifest; - instructionNode: InstructionNode; + instructionPath: NodePath; }, ): Fragment { - const { instructionNode, dataArgsManifest, nameApi, customInstructionData } = scope; + const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); if (instructionNode.arguments.length === 0 || customInstructionData.has(instructionNode.name)) { return fragment(''); } diff --git a/packages/renderers-js/src/fragments/instructionExtraArgs.ts b/packages/renderers-js/src/fragments/instructionExtraArgs.ts index fe626d12c..4057daf59 100644 --- a/packages/renderers-js/src/fragments/instructionExtraArgs.ts +++ b/packages/renderers-js/src/fragments/instructionExtraArgs.ts @@ -1,4 +1,5 @@ import { InstructionNode } from '@codama/nodes'; +import { getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import { GlobalFragmentScope } from '../getRenderMapVisitor'; import { TypeManifest } from '../TypeManifest'; @@ -7,10 +8,11 @@ import { Fragment, fragment, fragmentFromTemplate } from './common'; export function getInstructionExtraArgsFragment( scope: Pick & { extraArgsManifest: TypeManifest; - instructionNode: InstructionNode; + instructionPath: NodePath; }, ): Fragment { - const { instructionNode, extraArgsManifest, nameApi } = scope; + const { instructionPath, extraArgsManifest, nameApi } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); if ((instructionNode.extraArguments ?? []).length === 0) { return fragment(''); } diff --git a/packages/renderers-js/src/fragments/instructionFunction.ts b/packages/renderers-js/src/fragments/instructionFunction.ts index d99afdbe2..2a8f977a8 100644 --- a/packages/renderers-js/src/fragments/instructionFunction.ts +++ b/packages/renderers-js/src/fragments/instructionFunction.ts @@ -1,5 +1,10 @@ import { camelCase, InstructionArgumentNode, InstructionNode, isNode, isNodeFilter, pascalCase } from '@codama/nodes'; -import { NodeStack, ResolvedInstructionInput } from '@codama/visitors-core'; +import { + findProgramNodeFromPath, + getLastNodeFromPath, + NodePath, + ResolvedInstructionInput, +} from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { NameApi } from '../nameTransformers'; @@ -18,8 +23,7 @@ export function getInstructionFunctionFragment( > & { dataArgsManifest: TypeManifest; extraArgsManifest: TypeManifest; - instructionNode: InstructionNode; - instructionStack: NodeStack; + instructionPath: NodePath; renamedArgs: Map; resolvedInputs: ResolvedInstructionInput[]; useAsync: boolean; @@ -27,8 +31,7 @@ export function getInstructionFunctionFragment( ): Fragment { const { useAsync, - instructionNode, - instructionStack, + instructionPath, resolvedInputs, renamedArgs, dataArgsManifest, @@ -36,6 +39,8 @@ export function getInstructionFunctionFragment( nameApi, customInstructionData, } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); + const programNode = findProgramNodeFromPath(instructionPath)!; if (useAsync && !hasAsyncFunction(instructionNode, resolvedInputs, asyncResolvers)) { return fragment(''); } @@ -66,7 +71,7 @@ export function getInstructionFunctionFragment( const hasAnyArgs = hasDataArgs || hasExtraArgs || hasRemainingAccountArgs; const hasInput = hasAccounts || hasAnyArgs; const instructionDataName = nameApi.instructionDataType(instructionNode.name); - const programAddressConstant = nameApi.programAddressConstant(instructionStack.getProgram()!.name); + const programAddressConstant = nameApi.programAddressConstant(programNode.name); const encoderFunction = customData ? dataArgsManifest.encoder.render : `${nameApi.encoderFunction(instructionDataName)}()`; @@ -165,8 +170,9 @@ function getTypeParams(instructionNode: InstructionNode, programAddressConstant: .addImports('generatedPrograms', [programAddressConstant]); } -function getInstructionType(scope: { instructionNode: InstructionNode; nameApi: NameApi }): Fragment { - const { instructionNode, nameApi } = scope; +function getInstructionType(scope: { instructionPath: NodePath; nameApi: NameApi }): Fragment { + const { instructionPath, nameApi } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); const instructionTypeName = nameApi.instructionType(instructionNode.name); const programAddressFragment = fragment('TProgramAddress'); const accountTypeParamsFragments = instructionNode.accounts.map(account => { @@ -192,8 +198,13 @@ function getInstructionType(scope: { instructionNode: InstructionNode; nameApi: ).mapRender(r => `${instructionTypeName}<${r}>`); } -function getInputTypeCall(scope: { instructionNode: InstructionNode; nameApi: NameApi; useAsync: boolean }): Fragment { - const { instructionNode, useAsync, nameApi } = scope; +function getInputTypeCall(scope: { + instructionPath: NodePath; + nameApi: NameApi; + useAsync: boolean; +}): Fragment { + const { instructionPath, useAsync, nameApi } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); const inputTypeName = useAsync ? nameApi.instructionAsyncInputType(instructionNode.name) : nameApi.instructionSyncInputType(instructionNode.name); diff --git a/packages/renderers-js/src/fragments/instructionInputResolved.ts b/packages/renderers-js/src/fragments/instructionInputResolved.ts index ca27b7f5a..e5501b469 100644 --- a/packages/renderers-js/src/fragments/instructionInputResolved.ts +++ b/packages/renderers-js/src/fragments/instructionInputResolved.ts @@ -1,5 +1,5 @@ import { camelCase, InstructionNode, isNode } from '@codama/nodes'; -import { ResolvedInstructionInput } from '@codama/visitors-core'; +import { getLastNodeFromPath, NodePath, ResolvedInstructionInput } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { Fragment, fragment, mergeFragments } from './common'; @@ -7,16 +7,17 @@ import { getInstructionInputDefaultFragment } from './instructionInputDefault'; export function getInstructionInputResolvedFragment( scope: Pick & { - instructionNode: InstructionNode; + instructionPath: NodePath; resolvedInputs: ResolvedInstructionInput[]; useAsync: boolean; }, ): Fragment { + const instructionNode = getLastNodeFromPath(scope.instructionPath); const resolvedInputFragments = scope.resolvedInputs.flatMap((input: ResolvedInstructionInput): Fragment[] => { const inputFragment = getInstructionInputDefaultFragment({ ...scope, input, - optionalAccountStrategy: scope.instructionNode.optionalAccountStrategy, + optionalAccountStrategy: instructionNode.optionalAccountStrategy, }); if (!inputFragment.render) return []; const camelName = camelCase(input.name); diff --git a/packages/renderers-js/src/fragments/instructionInputType.ts b/packages/renderers-js/src/fragments/instructionInputType.ts index 25b5a9553..6e8fdaa7b 100644 --- a/packages/renderers-js/src/fragments/instructionInputType.ts +++ b/packages/renderers-js/src/fragments/instructionInputType.ts @@ -7,6 +7,8 @@ import { pascalCase, } from '@codama/nodes'; import { + getLastNodeFromPath, + NodePath, ResolvedInstructionAccount, ResolvedInstructionArgument, ResolvedInstructionInput, @@ -20,13 +22,14 @@ import { Fragment, fragment, fragmentFromTemplate, mergeFragments } from './comm export function getInstructionInputTypeFragment( scope: Pick & { dataArgsManifest: TypeManifest; - instructionNode: InstructionNode; + instructionPath: NodePath; renamedArgs: Map; resolvedInputs: ResolvedInstructionInput[]; useAsync: boolean; }, ): Fragment { - const { instructionNode, useAsync, nameApi } = scope; + const { instructionPath, useAsync, nameApi } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); const instructionInputType = useAsync ? nameApi.instructionAsyncInputType(instructionNode.name) @@ -57,12 +60,13 @@ export function getInstructionInputTypeFragment( function getAccountsFragment( scope: Pick & { - instructionNode: InstructionNode; + instructionPath: NodePath; resolvedInputs: ResolvedInstructionInput[]; useAsync: boolean; }, ): Fragment { - const { instructionNode, resolvedInputs, useAsync, asyncResolvers } = scope; + const { instructionPath, resolvedInputs, useAsync, asyncResolvers } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); const fragments = instructionNode.accounts.map(account => { const resolvedAccount = resolvedInputs.find( @@ -113,12 +117,13 @@ function getAccountTypeFragment(account: Pick & { dataArgsManifest: TypeManifest; - instructionNode: InstructionNode; + instructionPath: NodePath; renamedArgs: Map; resolvedInputs: ResolvedInstructionInput[]; }, ): [Fragment, Fragment] { - const { instructionNode, nameApi } = scope; + const { instructionPath, nameApi } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); const customData = scope.customInstructionData.get(instructionNode.name); if (customData) { @@ -143,12 +148,13 @@ function getDataArgumentsFragments( function getExtraArgumentsFragment( scope: Pick & { - instructionNode: InstructionNode; + instructionPath: NodePath; renamedArgs: Map; resolvedInputs: ResolvedInstructionInput[]; }, ): Fragment { - const { instructionNode, nameApi } = scope; + const { instructionPath, nameApi } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); const instructionExtraName = nameApi.instructionExtraType(instructionNode.name); const extraArgsType = nameApi.dataArgsType(instructionExtraName); diff --git a/packages/renderers-js/src/fragments/instructionParseFunction.ts b/packages/renderers-js/src/fragments/instructionParseFunction.ts index ffdccf2f8..8a2a68641 100644 --- a/packages/renderers-js/src/fragments/instructionParseFunction.ts +++ b/packages/renderers-js/src/fragments/instructionParseFunction.ts @@ -1,5 +1,5 @@ import { InstructionNode } from '@codama/nodes'; -import { NodeStack } from '@codama/visitors-core'; +import { findProgramNodeFromPath, getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { TypeManifest } from '../TypeManifest'; @@ -8,11 +8,12 @@ import { Fragment, fragment, fragmentFromTemplate } from './common'; export function getInstructionParseFunctionFragment( scope: Pick & { dataArgsManifest: TypeManifest; - instructionNode: InstructionNode; - instructionStack: NodeStack; + instructionPath: NodePath; }, ): Fragment { - const { instructionNode, instructionStack, dataArgsManifest, nameApi, customInstructionData } = scope; + const { instructionPath, dataArgsManifest, nameApi, customInstructionData } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); + const programNode = findProgramNodeFromPath(instructionPath)!; const customData = customInstructionData.get(instructionNode.name); const hasAccounts = instructionNode.accounts.length > 0; const hasOptionalAccounts = instructionNode.accounts.some(account => account.isOptional); @@ -23,7 +24,7 @@ export function getInstructionParseFunctionFragment( const hasData = !!customData || instructionNode.arguments.length > 0; const instructionDataName = nameApi.instructionDataType(instructionNode.name); - const programAddressConstant = nameApi.programAddressConstant(instructionStack.getProgram()!.name); + const programAddressConstant = nameApi.programAddressConstant(programNode.name); const dataTypeFragment = fragment( customData ? dataArgsManifest.strictType.render : nameApi.dataType(instructionDataName), ); diff --git a/packages/renderers-js/src/fragments/instructionRemainingAccounts.ts b/packages/renderers-js/src/fragments/instructionRemainingAccounts.ts index 312a0e847..cb47f7f79 100644 --- a/packages/renderers-js/src/fragments/instructionRemainingAccounts.ts +++ b/packages/renderers-js/src/fragments/instructionRemainingAccounts.ts @@ -6,17 +6,18 @@ import { InstructionRemainingAccountsNode, isNode, } from '@codama/nodes'; +import { getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { Fragment, fragment, mergeFragments } from './common'; export function getInstructionRemainingAccountsFragment( scope: Pick & { - instructionNode: InstructionNode; + instructionPath: NodePath; useAsync: boolean; }, ): Fragment { - const { remainingAccounts } = scope.instructionNode; + const { remainingAccounts } = getLastNodeFromPath(scope.instructionPath); const fragments = (remainingAccounts ?? []).flatMap(r => getRemainingAccountsFragment(r, scope)); if (fragments.length === 0) return fragment(''); return mergeFragments( @@ -30,7 +31,7 @@ export function getInstructionRemainingAccountsFragment( function getRemainingAccountsFragment( remainingAccounts: InstructionRemainingAccountsNode, scope: Pick & { - instructionNode: InstructionNode; + instructionPath: NodePath; useAsync: boolean; }, ): Fragment[] { @@ -50,9 +51,9 @@ function getRemainingAccountsFragment( function getArgumentValueNodeFragment( remainingAccounts: InstructionRemainingAccountsNode, - scope: { instructionNode: InstructionNode }, + scope: { instructionPath: NodePath }, ): Fragment { - const { instructionNode } = scope; + const instructionNode = getLastNodeFromPath(scope.instructionPath); assertIsNode(remainingAccounts.value, 'argumentValueNode'); const argumentName = camelCase(remainingAccounts.value.name); const isOptional = remainingAccounts.isOptional ?? false; diff --git a/packages/renderers-js/src/fragments/instructionType.ts b/packages/renderers-js/src/fragments/instructionType.ts index c991a9453..70f629db4 100644 --- a/packages/renderers-js/src/fragments/instructionType.ts +++ b/packages/renderers-js/src/fragments/instructionType.ts @@ -1,5 +1,5 @@ import { InstructionNode, pascalCase } from '@codama/nodes'; -import { NodeStack } from '@codama/visitors-core'; +import { findProgramNodeFromPath, getLastNodeFromPath, NodePath } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { Fragment, fragmentFromTemplate, mergeFragments } from './common'; @@ -8,12 +8,12 @@ import { getInstructionAccountTypeParamFragment } from './instructionAccountType export function getInstructionTypeFragment( scope: Pick & { - instructionNode: InstructionNode; - instructionStack: NodeStack; + instructionPath: NodePath; }, ): Fragment { - const { instructionNode, instructionStack, nameApi, customInstructionData } = scope; - const programNode = instructionStack.getProgram()!; + const { instructionPath, nameApi, customInstructionData } = scope; + const instructionNode = getLastNodeFromPath(instructionPath); + const programNode = findProgramNodeFromPath(instructionPath)!; const hasAccounts = instructionNode.accounts.length > 0; const customData = customInstructionData.get(instructionNode.name); const hasData = !!customData || instructionNode.arguments.length > 0; @@ -25,7 +25,7 @@ export function getInstructionTypeFragment( getInstructionAccountTypeParamFragment({ ...scope, allowAccountMeta: true, - instructionAccountNode: account, + instructionAccountPath: [...instructionPath, account], }), ), renders => renders.join(', '), diff --git a/packages/renderers-js/src/fragments/pdaFunction.ts b/packages/renderers-js/src/fragments/pdaFunction.ts index 66cc12d09..41323dd57 100644 --- a/packages/renderers-js/src/fragments/pdaFunction.ts +++ b/packages/renderers-js/src/fragments/pdaFunction.ts @@ -1,5 +1,5 @@ import { isNode, isNodeFilter, PdaNode } from '@codama/nodes'; -import { NodeStack, visit } from '@codama/visitors-core'; +import { findProgramNodeFromPath, getLastNodeFromPath, NodePath, visit } from '@codama/visitors-core'; import type { GlobalFragmentScope } from '../getRenderMapVisitor'; import { ImportMap } from '../ImportMap'; @@ -7,11 +7,12 @@ import { Fragment, fragmentFromTemplate } from './common'; export function getPdaFunctionFragment( scope: Pick & { - pdaNode: PdaNode; - pdaStack: NodeStack; + pdaPath: NodePath; }, ): Fragment { - const { pdaNode, pdaStack, typeManifestVisitor, nameApi } = scope; + const { pdaPath, typeManifestVisitor, nameApi } = scope; + const pdaNode = getLastNodeFromPath(pdaPath); + const programNode = findProgramNodeFromPath(pdaPath)!; // Seeds. const imports = new ImportMap(); @@ -37,7 +38,7 @@ export function getPdaFunctionFragment( findPdaFunction: nameApi.pdaFindFunction(pdaNode.name), hasVariableSeeds, pdaSeedsType: nameApi.pdaSeedsType(pdaNode.name), - programAddress: pdaNode.programId ?? pdaStack.getProgram()!.publicKey, + programAddress: pdaNode.programId ?? programNode.publicKey, seeds, }) .mergeImportsWith(imports) diff --git a/packages/renderers-js/src/getRenderMapVisitor.ts b/packages/renderers-js/src/getRenderMapVisitor.ts index 4c92631cd..a6ea57fc1 100644 --- a/packages/renderers-js/src/getRenderMapVisitor.ts +++ b/packages/renderers-js/src/getRenderMapVisitor.ts @@ -147,8 +147,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { const scope = { ...globalScope, - accountNode: node, - accountStack: stack.clone(), + accountPath: stack.getPath('accountNode'), typeManifest: visit(node, typeManifestVisitor), }; @@ -237,8 +236,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { strict: nameApi.dataType(instructionExtraName), }), ), - instructionNode: node, - instructionStack: stack, + instructionPath: stack.getPath('instructionNode'), renamedArgs: getRenamedArgsMap(node), resolvedInputs: visit(node, resolvedInstructionInputVisitor), }; @@ -295,7 +293,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions = {}) { throw new Error('Account must be visited inside a program.'); } - const scope = { ...globalScope, pdaNode: node, pdaStack: stack }; + const scope = { ...globalScope, pdaPath: stack.getPath('pdaNode') }; const pdaFunctionFragment = getPdaFunctionFragment(scope); const imports = new ImportMap().mergeWith(pdaFunctionFragment);