diff --git a/CHANGELOG.md b/CHANGELOG.md index 4bd718b43d..c21bf728b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Add `#[interface(..)]` attribute for instruction discriminator overrides ([#2728](https://github.com/coral-xyz/anchor/pull/2728)). - ts: Add `.interface(..)` method for instruction discriminator overrides ([#2728](https://github.com/coral-xyz/anchor/pull/2728)). - cli: Check `anchor-lang` and CLI version compatibility ([#2753](https://github.com/coral-xyz/anchor/pull/2753)). +- ts: Add IdlSeed Type for IDL PDA seeds ([#2752](https://github.com/coral-xyz/anchor/pull/2752)). ### Fixes diff --git a/ts/packages/anchor/src/idl.ts b/ts/packages/anchor/src/idl.ts index dc88cd586e..4a6c71fb72 100644 --- a/ts/packages/anchor/src/idl.ts +++ b/ts/packages/anchor/src/idl.ts @@ -67,7 +67,26 @@ export type IdlPda = { programId?: IdlSeed; }; -export type IdlSeed = any; // TODO +export type IdlSeed = IdlSeedConst | IdlSeedArg | IdlSeedAccount; + +export type IdlSeedConst = { + kind: "const"; + type: IdlType; + value: any; +}; + +export type IdlSeedArg = { + kind: "arg"; + type: IdlType; + path: string; +}; + +export type IdlSeedAccount = { + kind: "account"; + type: IdlType; + account?: string; + path: string; +}; // A nested/recursive version of IdlAccount. export type IdlAccounts = { diff --git a/ts/packages/anchor/src/program/accounts-resolver.ts b/ts/packages/anchor/src/program/accounts-resolver.ts index 42b483e7d2..0bf4be87b1 100644 --- a/ts/packages/anchor/src/program/accounts-resolver.ts +++ b/ts/packages/anchor/src/program/accounts-resolver.ts @@ -15,6 +15,9 @@ import { IdlTypeDefTyStruct, IdlType, isIdlAccounts, + IdlSeedConst, + IdlSeedArg, + IdlSeedAccount, } from "../idl.js"; import * as utf8 from "../utils/bytes/utf8.js"; import { TOKEN_PROGRAM_ID, ASSOCIATED_PROGRAM_ID } from "../utils/token.js"; @@ -385,6 +388,7 @@ export class AccountsResolver { if (!accountDesc.pda?.programId) { return this._programId; } + switch (accountDesc.pda.programId.kind) { case "const": return new PublicKey( @@ -396,7 +400,7 @@ export class AccountsResolver { return await this.accountValue(accountDesc.pda.programId, path); default: throw new Error( - `Unexpected program seed kind: ${accountDesc.pda.programId.kind}` + `Unexpected program seed: ${accountDesc.pda.programId}` ); } } @@ -413,7 +417,7 @@ export class AccountsResolver { case "account": return await this.toBufferAccount(seedDesc, path); default: - throw new Error(`Unexpected seed kind: ${seedDesc.kind}`); + throw new Error(`Unexpected seed: ${seedDesc}`); } } @@ -438,14 +442,11 @@ export class AccountsResolver { return type as string; } - private toBufferConst(seedDesc: IdlSeed): Buffer { - return this.toBufferValue( - this.getType(seedDesc.type, (seedDesc.path || "").split(".").slice(1)), - seedDesc.value - ); + private toBufferConst(seedDesc: IdlSeedConst): Buffer { + return this.toBufferValue(this.getType(seedDesc.type), seedDesc.value); } - private async toBufferArg(seedDesc: IdlSeed): Promise { + private async toBufferArg(seedDesc: IdlSeedArg): Promise { const argValue = this.argValue(seedDesc); if (typeof argValue === "undefined") { return; @@ -456,7 +457,7 @@ export class AccountsResolver { ); } - private argValue(seedDesc: IdlSeed): any { + private argValue(seedDesc: IdlSeedArg): any { const split = seedDesc.path.split("."); const seedArgName = camelCase(split[0]); @@ -473,7 +474,7 @@ export class AccountsResolver { } private async toBufferAccount( - seedDesc: IdlSeed, + seedDesc: IdlSeedAccount, path: string[] = [] ): Promise { const accountValue = await this.accountValue(seedDesc, path); @@ -484,7 +485,7 @@ export class AccountsResolver { } private async accountValue( - seedDesc: IdlSeed, + seedDesc: IdlSeedAccount, path: string[] = [] ): Promise { const pathComponents = seedDesc.path.split(".");