Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions src/fragments/instructionFunction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ export function getInstructionFunctionFragment(
const instructionNode = getLastNodeFromPath(instructionPath);
const programNode = findProgramNodeFromPath(instructionPath)!;

const rootNode = instructionPath.find(node => node.kind === 'rootNode');
let rootProgramClassName: string;
if (rootNode) {
rootProgramClassName = `${nameApi.programType(rootNode.program.name)}.programId`;
} else {
rootProgramClassName = `'${programNode.publicKey}'`;
}

const functionName = nameApi.instructionFunction(instructionNode.name);
const instructionDataName = nameApi.instructionDataType(instructionNode.name);

Expand Down Expand Up @@ -107,7 +115,7 @@ export function getInstructionFunctionFragment(

pdaResolutions.push(
` final resolved${accountName.charAt(0).toUpperCase() + accountName.slice(1)} = ${accountName} ?? ` +
`await Ed25519HDPublicKey.findProgramAddress(\n seeds: [${seeds.join(', ')}],\n programId: programId ?? Ed25519HDPublicKey.fromBase58('${programNode.publicKey ?? 'PROGRAM_ID_HERE'}'),\n );`,
`await Ed25519HDPublicKey.findProgramAddress(\n seeds: [${seeds.join(', ')}],\n programId: programId ?? Ed25519HDPublicKey.fromBase58(${rootProgramClassName}),\n );`,
);
}
} else if (builtinAddress) {
Expand Down Expand Up @@ -195,7 +203,7 @@ export function getInstructionFunctionFragment(

const functionBody = `${pdaResolutionCode}${accountMetas}${dataSerializationCode}
return Instruction(
programId: programId ?? Ed25519HDPublicKey.fromBase58('${programNode.publicKey ?? 'PROGRAM_ID_HERE'}'),
programId: programId ?? Ed25519HDPublicKey.fromBase58(${rootProgramClassName}),
accounts: accounts,
data: instructionData,
);`;
Expand All @@ -210,6 +218,9 @@ ${functionBody}
}`;

const imports = new Set(['package:solana/solana.dart']);
if (rootNode) {
imports.add(`../programs/${rootNode.program.name}.dart`);
}

return createFragment(content, Array.from(imports));
}
20 changes: 16 additions & 4 deletions src/utils/pda.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isNode, PdaNode, PdaSeedValueNode, StandaloneValueNode } from '@codama/nodes';
import { CamelCaseString, isNode, PdaNode, PdaSeedValueNode, StandaloneValueNode } from '@codama/nodes';

import { Fragment } from './fragment';
import { RenderScope } from './options';
Expand Down Expand Up @@ -56,6 +56,7 @@ export function createInlinePdaFile(
pdaSeedValues: PdaSeedValueNode[] | undefined,
nameApi: RenderScope['nameApi'],
programPublicKey: string | undefined,
programName: string | undefined,
asPage: <TFragment extends Fragment | undefined>(
fragment: TFragment,
pageOptions?: { libraryName?: string },
Expand All @@ -65,6 +66,11 @@ export function createInlinePdaFile(
const seeds = generatePdaSeeds(pdaNode, pdaSeedValues, nameApi);

const parameters: string[] = [];
let programClassName: string = '';
if (programName) {
programClassName = nameApi.programType(programName as CamelCaseString);
}


pdaNode.seeds.forEach(seed => {
if (isNode(seed, 'variablePdaSeedNode')) {
Expand All @@ -78,9 +84,12 @@ export function createInlinePdaFile(
});

const parameterList = parameters.length > 0 ? parameters.join(', ') : '';
const programIdValue = programPublicKey
? `Ed25519HDPublicKey.fromBase58('${programPublicKey}')`
: 'PROGRAM_ID_HERE';
const programIdValue =
programClassName && programClassName !== ''
? `Ed25519HDPublicKey.fromBase58(${programClassName}.programId)`
: programPublicKey
? `Ed25519HDPublicKey.fromBase58('${programPublicKey}')`
: 'PROGRAM_ID_HERE';

const content = `/// Returns the PDA address for ${accountName}
Future<Ed25519HDPublicKey> ${functionName}(${parameterList}) async {
Expand All @@ -91,6 +100,9 @@ Future<Ed25519HDPublicKey> ${functionName}(${parameterList}) async {
}`;

const imports = new Set(['package:solana/solana.dart', 'dart:typed_data']);
if (programClassName) {
imports.add(`../programs/${programName}.dart`);
}

const fragment: Fragment = {
content,
Expand Down
4 changes: 3 additions & 1 deletion src/visitors/getRenderMapVisitor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ export function getRenderMapVisitor(options: GetRenderMapOptions) {
}

const pdaName = camelCase(account.name);
const programNode = findProgramNodeFromPath(stack.getPath('instructionNode'));

// Avoid duplicate PDA files for the same account name
if (!pdaRenderMaps.has(pdaName)) {
Expand All @@ -115,7 +116,8 @@ export function getRenderMapVisitor(options: GetRenderMapOptions) {
account.defaultValue.pda,
account.defaultValue.seeds,
renderScope.nameApi,
findProgramNodeFromPath(stack.getPath('instructionNode'))?.publicKey,
programNode?.publicKey,
programNode?.name,
asPage,
);
if (pdaFile) {
Expand Down