MultiBaasでフロントエンドアプリを構築する
MultiBaasデプロイメントを作成したら、それを使用してフロントエンドアプリケーションを構築できます。通常、Solidityでスマートコントラクトを記述し、MultiBaasのWeb UIまたはHardhatやForgeプラグインを介してデプロイし、その後SDKのいずれか、またはMultiBaas APIを直接使用してブロックチェーンと対話します。
フロントエンドAPIキーのプロビジョニング
フロントエンドアプリ用のAPIキーは、MultiBaas Web UIを介してプロビジョニングできます。MultiBaas APIキーは、DApp Userグループにのみ属している場合に限り、フロントエンドアプリに直接埋め込むことができます。これらのAPIキーはMultiBaasに変更を加えることはできませんが、スマートコントラクト関数から読み取り、未署名のトランザクションを構成し、スマートコントラクトイベントデータと対話できます。
フロントエンドアプリ用のMultiBaas機能
MultiBaasは、フロントエンドアプリの構築に役立つ多数の機能を組み合わせています:
- スマートコントラクト関数との対話
- トランザクションを構成し、ユーザーに署名させ(以下を参照)、ブロックチェーンに送信
- スマートコントラクトイベントを効率的に読み取りおよび集約
CORS Origin
フロントエンドアプリがMultiBaaSへ直接APIコールを行うには、MultiBaasでCross-Origin Resource Sharing(CORS)設定を構成する必要があります。開発URL(例:http://localhost:3000)と公開デプロイメントURL(例:https://your-app-name-here.vercel.com)の両方を追加して、正しく動作するようにする必要があります。
許可されたオリジンを管理するには:
-
MultiBaasダッシュボードからCORS設定に移動します:
-
CORSページで許可されたオリジンのリストが表示されます。ここで、既存の許可されたオリジンを表示したり、新しいものを追加したりできます。
-
新しい許可されたオリジンを追加するには、**「Add Origin」をクリックし、提供された入力フィールドにオリジンURLを入力します。「Save」**をクリックして確認します。

または、MultiBaas REST APIを介してプログラムでCORS設定を管理することもできます。
ブラウザベースのweb3ウォレットによるトランザクション署名
MultiBaas上で直接Web UIを構築する場合、またはバックエンドからフロントエンドへMultiBaasを介して未署名のトランザクションを渡す場合、ブラウザベースのweb3ウォレット(例:MetaMask)にトランザクションに署名させ、ブロックチェーンに送信させることが一般的です。フロントエンドツールキットを使用してこれを行うには、いくつかの異なる方法があります。
MultiBaas APIによって返される未署名のトランザクションには、トランザクションをブロックに正常に含めるために必要なフィールドの完全なセットが含まれており、直接署名してブロックチェーンに送信できます。ただし、ブラウザベースのweb3ウォレットとのインターフェイスに使用されるweb3 JSウェブツールキットでは、MultiBaasから返されたものからトランザクションフィールドを若干再フォーマットする必要があります。これには、ガス関連フィールドとnonceフィールドを削除して、ブラウザベースのweb3ウォレットにこれらを再計算させ、トランザクションがブロックに正常に含まれる可能性を高めることも含まれます。
未署名トランザクションの例
フロントエンドコードのテストから始めたい場合、絶対的に最小限のトランザクションは、ある量のETHを別のアドレスに送信することです。以下のトランザクションにはガスやnonceフィールドが含まれておらず、web3ブラウザベースのウォレット(例:MetaMask)が通常これらを計算して追加し、ユーザーに確認と署名のためにトランザクションを渡すことに注意してください。
ゼロアドレスに一定量のETHを送信
const verySimpleTx = {
to: '0x0000000000000000000000000000000000000000',
value: '10000000000000000', // 0.0001 ETH
type: 2,
};
より実用的には、MultiBaas APIは未署名のトランザクションを計算できます。次の最小限の例では、MultiBaas TypeScript SDKを使用してスマートコントラクト関数を呼び出し、未署名のトランザクションを返します。
スマートコントラクト関数を呼び出してMultiBaas APIから未署名トランザクションを取得
const MultiBaas = require('@curvegrid/multibaas-sdk');
const { isAxiosError } = require('axios');
const config = new MultiBaas.Configuration({
basePath: 'http://<YOUR MULTIBAAS DEPLOYMENT ID>.multibaas.com/api/v0',
accessToken: '<YOUR API KEY HERE>',
});
const contractsApi = new MultiBaas.ContractsApi(config);
const deployedAddressOrAlias = '<your-deployed-or-linked-contract-alias>';
const contractLabel = '<your-contract-label>';
const contractMethod = '<your-contract-menthod>';
const payload = {
args: [],
from: '0x0000000000000000000000000000000000000000',
};
(async function () {
try {
const resp = await contractsApi.callContractFunction(
deployedAddressOrAlias,
contractLabel,
contractMethod,
payload,
);
console.log('Function call result:\n', resp.data.result);
} catch (e) {
if (isAxiosError(e)) {
console.log(
`MultiBaas error with status '${e.response.data.status}' and message: ${e.response.data.message}`,
);
} else {
console.log('An unexpected error occurred:', e);
}
}
})();
ethers.js
ethers.jsは、ブロックチェーンの対話を管理するためのJSツールキットです。MultiBaasからの未署名トランザクションは、ethers.js用に若干再フォーマットする必要があります。次のサンプルコードは、トランザクションデータ(txData)をMultiBaasが出力する形式で受け取り、返された未署名トランザクションをethers.js用に再フォーマットし、接続されたweb3ブラウザウォレットに送信して署名とブロックチェーンへの送信を行います。
ethers.jsを使用してフロントエンドアプリからweb3ブラウザベースのウォレット(例:MetaMask)に未署名トランザクションを渡すサンプルコード
// on page where ethers.js is installed (e.g. https://playground.ethers.org/)
// Function to format an unsigned transaction returned by the MultiBaas API
// to a format that is suitable for ethers.js and a web3 browser-based wallet,
// by removing nonce and gas fields so that the wallet can recompute them
function formatTransaction(txData) {
const formattedTx = JSON.parse(JSON.stringify(txData));
// convert fields that need to be converted
formattedTx.value = BigInt(formattedTx.value);
formattedTx.gasLimit = formattedTx.gas;
delete formattedTx.gas;
// let the wallet decide on the following parameters:
delete formattedTx.nonce;
delete formattedTx.gasPrice;
delete formattedTx.gasFeeCap;
delete formattedTx.gasTipCap;
delete formattedTx.from;
delete formattedTx.hash;
return formattedTx;
}
// Function to sign your transaction using MetaMask's eth_sendTransaction
async function signAndSendTransaction(txData) {
try {
if (typeof ethers === 'undefined') {
throw new Error('ethers.js is not loaded.');
}
if (!window.ethereum) {
throw new Error('No Web3 provider detected.');
}
// Connect to the provider
const provider = new ethers.BrowserProvider(window.ethereum);
console.log('Connected to provider');
// Request account access
const accounts = await provider.send('eth_requestAccounts', []);
const address = accounts[0];
console.log('Connected account:', address);
// Reformat transaction for ethers.js and web3 browser-based wallet
const formattedTx = formatTransaction(txData);
console.log('Transaction to sign:', formattedTx);
const signer = await provider.getSigner();
const tx = await signer.sendTransaction(formattedTx);
console.log('Transaction sent!');
console.log('Transaction hash:', tx.hash);
console.log('Full response:', tx);
return tx;
return {
signedData: { hash: dataHash, signature: signature },
formattedTx: formattedTx,
};
} catch (error) {
console.error('Error during transaction signing:', error);
throw error;
}
}
wagmiとviem
wagmiは、ブロックチェーンと対話するためのReact hooksのセットです。viemは対応するJSツールキットです。viemは、ethers.jsと同様の方法で単独で使用できます。
wagmi/viemを使用してフロントエンドアプリからweb3ブラウザベースのウォレット(例:MetaMask)に未署名トランザクションを渡すサンプルコード
const { createWalletClient, custom, http } = await import('https://esm.sh/viem');
console.log('viem imported successfully!');
async function getChainId() {
const chainIdHex = await window.ethereum.request({ method: 'eth_chainId' });
return parseInt(chainIdHex, 16);
}
// Get chain ID
const chainId = await getChainId();
console.log(`Connected to chain ID: ${chainId}`);
// Create a chain config based on chainId
const chain = {
id: chainId,
name: chainId === 1337 ? 'Local Development Chain' : `Chain ${chainId}`,
};
// Create a client with public and wallet actions
// This approach is recommended by the viem docs for test environments
const client = createWalletClient({
chain,
transport: custom(window.ethereum),
});
// Function to format an unsigned transaction returned by the MultiBaas API
// to a format that is suitable for wagmi/viem and a web3 browser-based wallet,
// by removing nonce and gas fields so that the wallet can recompute them
function formatTransaction(txData, address) {
const formattedTx = JSON.parse(JSON.stringify(txData));
// convert fields that need to be converted
formattedTx.value = BigInt(formattedTx.value);
formattedTx.gasLimit = formattedTx.gas;
delete formattedTx.gas;
// let the wallet decide on the following parameters:
delete formattedTx.nonce;
delete formattedTx.gasPrice;
delete formattedTx.gasFeeCap;
delete formattedTx.gasTipCap;
delete formattedTx.from;
delete formattedTx.hash;
formattedTx.account = address;
return formattedTx;
}
async function signAndSendTransaction(txData) {
try {
// Check if ethereum provider is available
if (!window.ethereum) {
throw new Error(
'No Web3 provider detected. Please install MetaMask or another Web3 wallet extension.',
);
}
// Request account access
const accounts = await client.requestAddresses();
const address = accounts[0];
console.log('Connected to wallet:', address);
// Reformat transaction for wagmi/viem and web3 browser-based wallet
const formattedTx = formatTransaction(txData, address);
console.log('Sending transaction:', formattedTx);
// Send the transaction
const hash = await client.sendTransaction(formattedTx);
console.log('Transaction sent successfully!');
console.log('Transaction hash:', hash);
return hash;
} catch (error) {
console.error('Transaction failed:', error);
throw error;
}
}
実用的なフロントエンドのユースケースでは、未署名のトランザクションをwagmiのsendTransactionAsyncのような関数に渡すだけです。詳細については、sample-appをご覧ください。