diff --git a/docs.json b/docs.json index f003dbdb0..6f28c4dde 100644 --- a/docs.json +++ b/docs.json @@ -276,6 +276,14 @@ "tooling/dev-environments/thirdweb/one-click-deploy" ] }, + { + "group": "Using MultiBaas", + "pages": [ + "tooling/dev-environments/multibaas/overview", + "tooling/dev-environments/multibaas/contracts", + "tooling/dev-environments/multibaas/webhooks" + ] + }, "tooling/dev-environments/remix", "tooling/dev-environments/hardhat" ] diff --git a/tooling/dev-environments/multibaas/contracts.mdx b/tooling/dev-environments/multibaas/contracts.mdx new file mode 100644 index 000000000..f494e3d2b --- /dev/null +++ b/tooling/dev-environments/multibaas/contracts.mdx @@ -0,0 +1,158 @@ +--- +title: Smart Contracts +description: Deploy, link, and call smart contracts on Celo using the MultiBaas REST API and SDK. +--- + +MultiBaas manages contracts in two layers: + +- **[Library](https://docs.curvegrid.com/multibaas/manage-contracts#smart-contract-library)** — contract definitions (ABI and bytecode) +- **[On-chain](https://docs.curvegrid.com/multibaas/manage-contracts#on-chain-smart-contracts)** — deployed instances linked to a blockchain address + +## Adding a Contract to the Library + +You can add a contract to the library in four ways: + +1. **Direct ABI upload** — paste an ABI JSON directly +2. **Solidity source upload** — MultiBaas compiles it for you +3. **Address lookup** — MultiBaas fetches the ABI from Blockscout or Etherscan by contract address +4. **Framework plugin** — automated via the [Hardhat](#hardhat) or [Forge](#foundry-/-forge) plugin during deployment (see below) + +## Deploying or Linking a Contract + +### Deploy a new contract + +1. Go to **Contracts → On-chain → + → Deploy Contract** +2. Select a contract from the library +3. Fill in constructor parameters +4. Optionally enable **Sync Events** and set a starting block for event indexing +5. Submit — if using a Cloud Wallet, MultiBaas signs and submits the transaction automatically + +### Link an existing contract + +1. Go to **Contracts → On-chain → + → Link Contract** +2. Enter the contract address (MultiBaas can auto-fetch the ABI from a block explorer) +3. Select the contract definition from the library +4. Optionally enable **Sync Events** + +## Calling Contract Methods + +Once a contract is linked, MultiBaas exposes all its functions via the [REST API](https://docs.curvegrid.com/multibaas/api/multibaas-api). Toggle on Developer Mode in the contract functions UI to see sample payload, curl, TypeScript, or golang code. The base URL for all API calls is: + +``` +https://.multibaas.com/api/v0 +``` + + +The API path uses `/chains/ethereum/` as a fixed prefix regardless of the actual EVM network. This is a MultiBaas convention — it works correctly for Celo. + + +### Using the TypeScript SDK + +Install the [TypeScript SDK](https://www.npmjs.com/package/@curvegrid/multibaas-sdk): + +```bash +npm install @curvegrid/multibaas-sdk +``` + +Configure the client: + +```typescript +import * as MultiBaas from '@curvegrid/multibaas-sdk'; + +const config = new MultiBaas.Configuration({ + basePath: `${process.env.MULTIBAAS_DEPLOYMENT_URL}/api/v0`, + accessToken: process.env.MULTIBAAS_API_KEY, +}); + +const contractsApi = new MultiBaas.ContractsApi(config); +``` + +**Read a contract function:** + +```typescript +const response = await contractsApi.callContractFunction( + 'my-contract-alias', // address alias configured in MultiBaas + 'MyContract', // contract label in the library + 'balanceOf', // method name + { + args: ['0xRecipientAddress'], + signAndSubmit: false, + }, +); + +console.log(response.data.result.output); +``` + +**Write to a contract using a Cloud Wallet:** + +```typescript +const response = await contractsApi.callContractFunction( + 'my-contract-alias', + 'MyContract', + 'transfer', + { + args: ['0xRecipientAddress', '1000000000000000000'], + from: process.env.CLOUD_WALLET_ADDRESS, + signAndSubmit: true, + }, +); + +console.log(response.data.result.tx.hash); +``` + +Setting `signAndSubmit: true` with a configured Cloud Wallet address instructs MultiBaas to sign and broadcast the transaction on your behalf. + +**Write to a contract with an external wallet (viem):** + +```typescript +import { createWalletClient, custom } from 'viem'; +import { celo } from 'viem/chains'; + +const walletClient = createWalletClient({ + chain: celo, + transport: custom(window.ethereum), +}); + +// Get the unsigned transaction from MultiBaas +const response = await contractsApi.callContractFunction( + 'my-contract-alias', + 'MyContract', + 'transfer', + { + args: ['0xRecipientAddress', '1000000000000000000'], + signAndSubmit: false, + }, +); + +const tx = response.data.result.tx; + +// Sign and submit with the user's connected wallet +await walletClient.sendTransaction({ + to: tx.to, + data: tx.data, + value: BigInt(tx.value ?? 0), + account: userAddress, +}); +``` + +## Framework Plugins + +### Hardhat + +The `hardhat-multibaas-plugin` automatically uploads and links contracts in your MultiBaas deployment as part of your Hardhat deploy scripts. + +```bash +npm install --save-dev hardhat hardhat-multibaas-plugin @nomicfoundation/hardhat-ignition +``` + +See the [plugin repository](https://github.com/curvegrid/hardhat-multibaas-plugin) for setup instructions. + +### Foundry / Forge + +The `forge-multibaas` plugin provides the same integration for Foundry-based projects. + +```bash +forge install curvegrid/forge-multibaas +``` + +See the [plugin repository](https://github.com/curvegrid/forge-multibaas) for setup instructions. diff --git a/tooling/dev-environments/multibaas/overview.mdx b/tooling/dev-environments/multibaas/overview.mdx new file mode 100644 index 000000000..37aaa900d --- /dev/null +++ b/tooling/dev-environments/multibaas/overview.mdx @@ -0,0 +1,57 @@ +--- +title: MultiBaas by Curvegrid +sidebarTitle: Overview +description: Blockchain middleware for building dApps on Celo with a REST API, smart contract management, and real-time event webhooks. +--- + +[MultiBaas](https://www.curvegrid.com/blockchain-platform) by [Curvegrid](https://www.curvegrid.com) is a blockchain middleware platform that wraps your smart contracts in a REST API and advanced feature toolkit. It handles contract management, transaction signing, event indexing, and webhook delivery so you can focus on building your application without managing low-level blockchain infrastructure. + +## Key Features + +- **[REST API](https://docs.curvegrid.com/multibaas/api/multibaas-api)** — interact with any linked smart contract over HTTPS using standard HTTP clients or the TypeScript/Go SDK +- **[Contract Management](https://docs.curvegrid.com/multibaas/manage-contracts)** — deploy, link, and manage contracts via the dashboard or API; import ABIs from Blockscout or Etherscan by address +- **[Event Webhooks](https://docs.curvegrid.com/multibaas/webhooks)** — receive real-time HTTP callbacks whenever a contract event is emitted on-chain +- **[Cloud Wallets](https://docs.curvegrid.com/multibaas/cloud-wallets)** — server-side signing via Azure Key Vault (AWS KMS and Google Cloud KMS available on request) +- **[Transaction Manager](https://docs.curvegrid.com/multibaas/txm)** — monitors Cloud Wallet transactions and auto-resubmits stuck transactions +- **[Event Indexing](https://docs.curvegrid.com/multibaas/event-indexing)** — built-in indexer with a query and aggregation API for historical event data +- **[Framework Plugins](https://docs.curvegrid.com/multibaas/plugins)** — Hardhat and Foundry Forge plugins to automate contract uploads during deployment + +## Getting Started + +### 1. Create a Deployment + +1. Sign up at [console.curvegrid.com](https://console.curvegrid.com) using Google, GitHub, Microsoft, or email +2. Click **New Deployment** +3. Enter a label, description, and select **Celo** (Mainnet or Sepolia) as the network + + +The network cannot be changed after a deployment is created. Create separate deployments for mainnet and testnet environments. + + +Your deployment will be available at `https://.multibaas.com`. + +### 2. Generate an API Key + +In your deployment, go to **Admin → API Keys → New Key**. + +MultiBaas has multiple key types with different permission levels. The most frequently used are Administrator and DApp User: + +| Key Type | Use Case | +|---|---| +| **Administrator** | Server-side code only, full deployment control | +| **DApp User** | Safe to use in frontend apps, read-only and unsigned transaction composition | + +Never expose an Administrator key in client-side code. + +### 3. Configure CORS (Frontend Apps) + +If you are building a frontend application, add your origin at **Admin → CORS**. + +## Resources + +- [MultiBaas Documentation](https://docs.curvegrid.com/multibaas/) +- [Curvegrid Console](https://console.curvegrid.com) +- [TypeScript SDK (`@curvegrid/multibaas-sdk`)](https://www.npmjs.com/package/@curvegrid/multibaas-sdk) +- [Go SDK](https://github.com/curvegrid/multibaas-sdk-go) +- [Sample App](https://github.com/curvegrid/multibaas-sample-app) +- [Curvegrid Discord](https://discord.gg/ud9U7nP) diff --git a/tooling/dev-environments/multibaas/webhooks.mdx b/tooling/dev-environments/multibaas/webhooks.mdx new file mode 100644 index 000000000..a3e0d11e4 --- /dev/null +++ b/tooling/dev-environments/multibaas/webhooks.mdx @@ -0,0 +1,166 @@ +--- +title: Event Webhooks +description: Receive real-time HTTP callbacks for on-chain contract events using MultiBaas webhooks. +--- + +MultiBaas webhooks deliver real-time HTTP POST callbacks to your server whenever a configured on-chain event fires. This lets you react to contract activity without polling the blockchain. + +## Supported Event Types + +| Type | Trigger | +|---|---| +| `event.emitted` | A contract event is emitted on-chain (requires **Sync Events** enabled on the contract) | +| `transaction.included` | A Cloud Wallet transaction is mined in a block | + +## Creating a Webhook + +### In the Dashboard + +1. Go to **Blockchain → Webhooks → +** +2. Enter a label and your publicly accessible HTTPS endpoint URL +3. Save + +### Via API + +```bash +curl -X POST \ + "https://.multibaas.com/api/v0/webhooks" \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "label": "my-webhook", + "url": "https://your-app.example.com/api/webhooks/multibaas" + }' +``` + +## Webhook Payload + +Each request delivers a JSON array of one or more events: + +```typescript +type MultiBaasEvent = { + id: string; + event: 'event.emitted' | 'transaction.included'; + data: { + triggeredAt: string; + event: { + name: string; + signature: string; + inputs: { + name: string; + value: string; + hashed: boolean; + type: string; + }[]; + rawFields: string; + contract: { + address: string; + addressLabel: string; + name: string; + label: string; + }; + indexInLog: number; + }; + }; +}; +``` + +## Verifying Signatures + +Every webhook request includes two headers: + +- **`X-MultiBaas-Signature`** — HMAC-SHA256 of the raw request body concatenated with the timestamp +- **`X-MultiBaas-Timestamp`** — Unix timestamp as a string + +Always verify the signature before processing an event to confirm the request originated from MultiBaas. + +```typescript +import { createHmac } from 'node:crypto'; + +function verifyWebhookSignature( + payload: string, + signature: string | null, + timestamp: string | null, +): boolean { + if (!payload || !signature || !timestamp) return false; + + const hmac = createHmac('sha256', process.env.MULTIBAAS_WEBHOOK_SECRET!); + hmac.update(Buffer.from(payload)); + hmac.update(timestamp); + const expected = hmac.digest().toString('hex'); + + return signature === expected; +} +``` + +The webhook secret is shown once when you create the webhook in the MultiBaas dashboard. + +## Example: Next.js Webhook Handler + +The following is based on how [Celo Mondo](https://mondo.celo.org/) uses MultiBaas webhooks to process Celo governance events in real time. + +```typescript +// app/api/webhooks/multibaas/route.ts +import { NextRequest } from 'next/server'; +import { createHmac } from 'node:crypto'; + +type MultiBaasEvent = { + id: string; + event: 'event.emitted'; + data: { + triggeredAt: string; + event: { + name: string; + signature: string; + inputs: { name: string; value: string; hashed: boolean; type: string }[]; + rawFields: string; + contract: { + address: string; + addressLabel: string; + name: string; + label: string; + }; + indexInLog: number; + }; + }; +}; + +export async function POST(request: NextRequest): Promise { + const rawBody = await request.text(); + const signature = request.headers.get('X-MultiBaas-Signature'); + const timestamp = request.headers.get('X-MultiBaas-Timestamp'); + + if (!rawBody || !signature || !timestamp) { + return new Response(null, { status: 403 }); + } + + // Verify the signature before processing + const hmac = createHmac('sha256', process.env.MULTIBAAS_WEBHOOK_SECRET!); + hmac.update(Buffer.from(rawBody)); + hmac.update(timestamp); + const expected = hmac.digest().toString('hex'); + + if (signature !== expected) { + return new Response(null, { status: 403 }); + } + + const events: MultiBaasEvent[] = JSON.parse(rawBody); + + for (const { data: { event } } of events) { + console.log(`Received ${event.name} from ${event.contract.address}`); + // Handle each event... + } + + return new Response(null, { status: 200 }); +} +``` + +For a full production example — including governance proposal processing, multisig approval handling, progressive historical backfill, and database integration — see the [Celo Mondo webhook handler](https://github.com/celo-org/celo-mondo/tree/main/src/app/api/webhooks/multibaas). + +## Environment Variables + +```bash +MULTIBAAS_DEPLOYMENT_URL=https://.multibaas.com +MULTIBAAS_API_KEY= +MULTIBAAS_WEBHOOK_SECRET= +```