Anchor v0.25.0で「Cannot read properties of undefined (reading 'methods')」エラー

現象

「% anchor init myAnchor」でanchorを作成後に、かんたんなcounterプログラムを実装して「% anchor test」を実行すると以下のエラーが発生。

実装内容は anchor tutorial basic-2 とほぼ同じ。
(上記だと記述内容が古いため、methodsを使用した書き換えで実装)

% anchor test

  myAnchor
    1) Creates a counter


  0 passing (8ms)
  1 failing

  1) myAnchor
       Creates a counter:
     TypeError: Cannot read properties of undefined (reading 'methods')
      at /Users/user/Desktop/temp/myAnchor/tests/myAnchor.ts:19:19
      at Generator.next (<anonymous>)
      at /Users/user/Desktop/temp/myAnchor/tests/myAnchor.ts:31:71
      at new Promise (<anonymous>)
      at __awaiter (tests/myAnchor.ts:27:12)
      at Context.<anonymous> (tests/myAnchor.ts:18:38)
      at processImmediate (node:internal/timers:464:21)
use anchor_lang::prelude::*;

declare_id!("Fg6PaFpoGXkYsidMpWTK6W2BeZ7FEfcYkg476zPFsLnS");

#[program]
pub mod my_anchor {
    use super::*;

    pub fn create(ctx: Context<Create>, authority: Pubkey) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.authority = authority;
        counter.count = 0;
        Ok(())
    }

    pub fn increment(ctx: Context<Increment>) -> Result<()> {
        let counter = &mut ctx.accounts.counter;
        counter.count += 1;
        Ok(())
    }
}

#[derive(Accounts)]
pub struct Create<'info> {
    #[account(init, payer = user, space = 8 + 40)]
    pub counter: Account<'info, Counter>,
    #[account(mut)]
    pub user: Signer<'info>,
    pub system_program: Program<'info, System>,
}

#[derive(Accounts)]
pub struct Increment<'info> {
    #[account(mut, has_one = authority)]
    pub counter: Account<'info, Counter>,
    pub authority: Signer<'info>,
}

#[account]
pub struct Counter {
    pub authority: Pubkey,
    pub count: u64,
}
import * as anchor from "@project-serum/anchor";
import { Program } from "@project-serum/anchor";
import { MyAnchor } from "../target/types/my_anchor";
import { assert } from 'chai';

describe("MyAnchor", () => {
  // anchor.setProvider(anchor.AnchorProvider.env());

  // Configure the client to use the local cluster.
  const provider = anchor.AnchorProvider.local();

  // Configure the client to use the local cluster.
  anchor.setProvider(provider);

  // Counter for the tests.
  const counter = anchor.web3.Keypair.generate();

  const program = anchor.workspace.Counter as Program<MyAnchor>;

  it("Creates a counter", async () => {
    await program.methods.create(
      provider.wallet.publicKey
    )
    .accounts({
      counter: counter.publicKey,
      user: provider.wallet.publicKey,
      systemProgram: anchor.web3.SystemProgram.programId,
    })
    .signers([counter])
    .rpc()

    let counterAccount = await program.account.counter.fetch(counter.publicKey);

    assert.ok(counterAccount.authority.equals(provider.wallet.publicKey));
    assert.ok(counterAccount.count.toNumber() === 0);
  });

  it("Updates a counter", async () => {
    await program.methods.increment()
      .accounts({
        counter: counter.publicKey,
        authority: provider.wallet.publicKey,
      })
      .rpc()

    const counterAccount = await program.account.counter.fetch(
      counter.publicKey
    );

    assert.ok(counterAccount.authority.equals(provider.wallet.publicKey));
    assert.ok(counterAccount.count.toNumber() == 1);
  });
});

原因

はっきりした原因はわからなかったが、おそらくPJ名(initで指定する名前)が悪さをしていると思われる。

「% anchor init myAnchor」

この、upperLowerCaseがダメっぽい(後述するが、小文字以外すべてダメだった)。

このPJ名は、Cargo.toml、lib.rs、idl(型定義ファイル)に記述されるのだが、program.methodsが、upperLowerCaseやアンダーバーを判別して読み込めていないのでは、という推測。

対応

全部小文字にして暫定的に解決。

「% anchor init myanchor」

大文字小文字、アンダーバー、ハイフンを試したがダメで、すべて小文字の場合しか解決されなかった。

備考

Anchorやnpm関連のファイル削除や1からの再作成など、試行錯誤したが解決できず、名前を変える以外に対応方法がなかった。
2022/7/19時点のバグ(?)と思われるため、そのうち直る可能性あり。
一応、GitHubのIssuesにも本現象 Error testing anchor project #1822 が起案されていた。

なお、「myanchor」を作成したあとに、「myAnchor」「my_anchor」「my-anchor」が作成できるか(大文字小文字、アンダーバー、ハイフンを区別しているのか)を試したところ、結果は区別していなかった。

% anchor init myanchor
〜〜〜作成される〜〜〜

% anchor init myAnchor
Error: File exists (os error 17)

% anchor init my_anchor
Error: Workspace already initialized

% anchor init my-anchor
Error: Workspace already initialized