Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
Expand Down
158 changes: 158 additions & 0 deletions tooling/dev-environments/multibaas/contracts.mdx
Original file line number Diff line number Diff line change
@@ -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://<deployment-id>.multibaas.com/api/v0
```

<Note>
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.
</Note>

### 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.
57 changes: 57 additions & 0 deletions tooling/dev-environments/multibaas/overview.mdx
Original file line number Diff line number Diff line change
@@ -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

<Note>
The network cannot be changed after a deployment is created. Create separate deployments for mainnet and testnet environments.
</Note>

Your deployment will be available at `https://<deployment-id>.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)
166 changes: 166 additions & 0 deletions tooling/dev-environments/multibaas/webhooks.mdx
Original file line number Diff line number Diff line change
@@ -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://<deployment-id>.multibaas.com/api/v0/webhooks" \
-H "Authorization: Bearer <api-key>" \
-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<Response> {
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://<deployment-id>.multibaas.com
MULTIBAAS_API_KEY=<your-api-key>
MULTIBAAS_WEBHOOK_SECRET=<your-webhook-secret>
```