Agenda
現象
Solana Anchorで作ったProgramをReactから呼び出そうとすると、以下のエラー。
@coral-xyz_anchor.js?v=4eaec7da:6889 Uncaught Error: Provider local is not available on browser.
at AnchorProvider.local (@coral-xyz_anchor.js?v=4eaec7da:6889:13)
at getProvider (@coral-xyz_anchor.js?v=4eaec7da:7068:27)
at new _Program (@coral-xyz_anchor.js?v=4eaec7da:11179:18)
at getAnchorProgram (anchor.ts:8:19)
at pages.tsx:12:17
ソース
import * as anchor from ‘@coral-xyz/anchor’;
import idl from “./kumo_no_ito.json”;
export const getAnchorProgram = (): any => {
if (!import.meta.env.VITE_PROGRAM_ID) throw new Error(‘Undefined PROGRAM_ID’);
const programId = new anchor.web3.PublicKey(import.meta.env.VITE_PROGRAM_ID);
const program = new anchor.Program(idl as anchor.Idl, programId);
return program;
}
原因
Anchorがデフォルトだと環境がlocalhostを参照していて、localhost参照だとReactみたいなフロントエンドは動かせない(バックエンドのNodeだったら動く)。
以下で環境設定を取得でき、裏では ANCHOR_PROVIDER_URL の値を取得している。
anchor.AnchorProvider.env()
対応
Anchor側だったらAnchor.tomlで対応できるが、Reactだとそれがないため、anchor.Programにconnectionをセットし、そこでdevnetを指定する。
ソース
// Solana
import { Connection, clusterApiUrl } from '@solana/web3.js';
// Anchor
import * as anchor from '@coral-xyz/anchor';
import idl from "./kumo_no_ito.json";
export const getAnchorProgram = (): any => {
if (!import.meta.env.VITE_PROGRAM_ID) throw new Error('Undefined PROGRAM_ID');
const programId = new anchor.web3.PublicKey(import.meta.env.VITE_PROGRAM_ID);
const connection = new Connection(clusterApiUrl('devnet'), 'confirmed');
const program = new anchor.Program(idl as anchor.Idl, programId, { connection });
return program;
}
参照
- Proper way to integrate Solana's Wallet Adapter with Anchor and further questions
- Anchor: Change Localnet to Devnet
もしかしたら、@solana/wallet-adapter-react の useConnection(), useAnchorWallet() でも、対応できるかもしれない(確認できていないため、間違っている可能性あり)。