# Shaka API

One immutable contract on Ethereum. No API key, no account, no approval — call it from your app or from your own contract.

Page: https://shaka.deal/api · Contract: https://etherscan.io/address/0x8f105b54494095373eD2573dBaFA7e546e2EbF99#code

---

## Contract

| | |
|---|---|
| Contract | `ShakaDeal` |
| Address | `0x8f105b54494095373eD2573dBaFA7e546e2EbF99` |
| Network | Ethereum mainnet |
| Asset | ETH (native) |
| Source | <a href="https://etherscan.io/address/0x8f105b54494095373eD2573dBaFA7e546e2EbF99#code" target="_blank" rel="noopener nofollow">Verified on Etherscan</a> |

The contract is immutable: its code can't be changed. No API key, no account, no approval — call it from a frontend, a backend or another contract.

## Quickstart

You need a wallet with enough ETH for the deal, the fee and gas, and ethers.js v6 or viem.

### 1. Connect

```javascript
import { ethers } from 'ethers';
// ABI: copy it from https://shaka.deal/api#abi or Etherscan
import SHAKA_ABI from './shaka-abi.json';

const SHAKA_ADDRESS = '0x8f105b54494095373eD2573dBaFA7e546e2EbF99'; // Ethereum mainnet

const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
const shaka = new ethers.Contract(SHAKA_ADDRESS, SHAKA_ABI, signer);
```

### 2. Create a deal

```javascript
const recipients = ['0xRecipientA...', '0xRecipientB...'];
const amounts = [
  ethers.parseEther('3'),   // recipient A, in ETH
  ethers.parseEther('1.2'), // recipient B, in ETH
];
// Receives 1% of the deal, paid by Shaka (ethers.ZeroAddress if none)
const referrer = '0xYourWallet...';
const dealReference = 'Invoice 2026-118';
// true = every recipient signs their share before the deal can be paid
const verificationRequired = false;

const tx = await shaka.createDeal(
  recipients, amounts, referrer, dealReference, verificationRequired
);
const receipt = await tx.wait();
const log = receipt.logs.find((l) => l.address.toLowerCase() === SHAKA_ADDRESS.toLowerCase());
const { dealId } = shaka.interface.parseLog(log).args; // from DealCreated
```

### 3. Pay it

```javascript
const grandTotal = await shaka.quote(dealId); // recipient amounts + 2% fee, in wei
// signatures: [] unless the deal requires verification
const payTx = await shaka.pay(dealId, [], { value: grandTotal });
await payTx.wait();
```

Every recipient is paid in that transaction.

## Fee

`quote(dealId)` returns the exact amount to send: the recipient amounts plus a 2% fee. Recipients always receive 100% of their amount. When a `referrer` is set, Shaka pays it 1% of the deal under its referral program. See <a href="/fee">Fee</a> for the pricing page.

## Signed shares

Create the deal with `verificationRequired = true` and it can't be paid until every recipient has approved their share.

1. Each recipient signs the digest returned by `approvalDigest(dealId, recipient, amount)`.
2. Pass the signatures to `pay(dealId, signatures)`, one per recipient.
3. If a signer doesn't match the recipient, or an amount doesn't match their share, `pay()` reverts.

Without verification, the deal is payable immediately and `signatures` is an empty array.

## Functions

| Function | What it does |
|---|---|
| `createDeal(recipients, amounts, referrer, dealReference, verificationRequired)` | Creates a deal and returns its `bytes32` ID. `amounts` are in wei, one per recipient. `dealReference` is free-form user input: escape it before rendering. |
| `quote(dealId)` | Returns the exact `grandTotal` in wei to send to `pay()`. Reverts if the deal is paid or cancelled. |
| `pay(dealId, signatures)` | Pays the deal in ETH. `msg.value` must equal `quote(dealId)`. If any transfer fails, the whole payment reverts. |
| `approvalDigest(dealId, recipient, amount)` | Returns the digest a recipient signs to approve their share. |
| `cancel(dealId)` | Creator only. Cancels an unpaid deal; it can never be paid afterwards. |
| `getDeal(dealId)` | Returns `recipients`, `amounts`, `creator`, `referrer`, `paid`, `cancelled`, `verificationRequired`, `dealReference`. |
| `deals(dealId)` | Returns the scalar fields only (no recipients or amounts). Use `getDeal()` when you need them. |

## Events

| Event | Fields |
|---|---|
| `DealCreated` | `dealId`, `creator`, `referrer`, `total`, `grandTotal`, `verificationRequired` |
| `DealPaid` | `dealId`, `payer`, `referrerAmount`, `shakaAmount`, `grandTotal` |
| `DealCancelled` | `dealId`, `creator` |

```javascript
shaka.on('DealPaid', (dealId, payer, referrerAmount, shakaAmount, grandTotal) => {
  console.log(dealId, ethers.formatEther(grandTotal));
});
```

## Errors

| Error | When |
|---|---|
| `TransferFailed(slot, recipient, amount)` | A recipient or the referrer can't receive ETH. The whole payment reverts. |
| `ReentrancyGuardReentrantCall()` | A reentrant call is detected during `pay()`. |

## Good to know

- **Wrong amount.** `msg.value` must match `quote(dealId)` exactly, or the payment reverts. Call `quote()` right before paying.
- **Wrong wallet.** If one recipient can't receive the payment, nothing moves. A deal can't be edited: cancel it and create a new one.
- **Cancel vs. pay.** If `cancel()` lands before a pending `pay()`, the payment reverts and the payer is never charged.
- **Recipients.** Up to 20 per deal — the contract enforces it. Each extra recipient adds gas; most deals have 2 to 5.
- **No holding.** The contract never holds funds. If you need a condition before paying, keep that logic on your side and call `pay()` when it resolves.

## viem

```typescript
import { createPublicClient, http } from 'viem';
import { mainnet } from 'viem/chains';

const client = createPublicClient({ chain: mainnet, transport: http() });

const grandTotal = await client.readContract({
  address: SHAKA_ADDRESS,
  abi: SHAKA_ABI,
  functionName: 'quote',
  args: [dealId],
});
```

## AI agents

Any MCP-compatible assistant can prepare deals and payment links through `mcp.shaka.deal`. See <a href="/agents">AI agents</a>.

## ABI

```json
[
  {
    "inputs": [],
    "name": "ReentrancyGuardReentrantCall",
    "type": "error"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "slot",
        "type": "bytes32"
      },
      {
        "internalType": "address",
        "name": "recipient",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "TransferFailed",
    "type": "error"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "creator",
        "type": "address"
      }
    ],
    "name": "DealCancelled",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "creator",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "referrer",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "total",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "grandTotal",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "bool",
        "name": "verificationRequired",
        "type": "bool"
      }
    ],
    "name": "DealCreated",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "payer",
        "type": "address"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "referrerAmount",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "shakaAmount",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "grandTotal",
        "type": "uint256"
      }
    ],
    "name": "DealPaid",
    "type": "event"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      },
      {
        "internalType": "address",
        "name": "recipient",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "amount",
        "type": "uint256"
      }
    ],
    "name": "approvalDigest",
    "outputs": [
      {
        "internalType": "bytes32",
        "name": "",
        "type": "bytes32"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      }
    ],
    "name": "cancel",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address[]",
        "name": "recipients",
        "type": "address[]"
      },
      {
        "internalType": "uint256[]",
        "name": "amounts",
        "type": "uint256[]"
      },
      {
        "internalType": "address",
        "name": "referrer",
        "type": "address"
      },
      {
        "internalType": "string",
        "name": "dealReference",
        "type": "string"
      },
      {
        "internalType": "bool",
        "name": "verificationRequired",
        "type": "bool"
      }
    ],
    "name": "createDeal",
    "outputs": [
      {
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      }
    ],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "",
        "type": "bytes32"
      }
    ],
    "name": "deals",
    "outputs": [
      {
        "internalType": "address",
        "name": "creator",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "referrer",
        "type": "address"
      },
      {
        "internalType": "uint256",
        "name": "total",
        "type": "uint256"
      },
      {
        "internalType": "bool",
        "name": "paid",
        "type": "bool"
      },
      {
        "internalType": "bool",
        "name": "cancelled",
        "type": "bool"
      },
      {
        "internalType": "bool",
        "name": "verificationRequired",
        "type": "bool"
      },
      {
        "internalType": "string",
        "name": "dealReference",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      }
    ],
    "name": "getDeal",
    "outputs": [
      {
        "internalType": "address[]",
        "name": "recipients",
        "type": "address[]"
      },
      {
        "internalType": "uint256[]",
        "name": "amounts",
        "type": "uint256[]"
      },
      {
        "internalType": "address",
        "name": "creator",
        "type": "address"
      },
      {
        "internalType": "address",
        "name": "referrer",
        "type": "address"
      },
      {
        "internalType": "bool",
        "name": "paid",
        "type": "bool"
      },
      {
        "internalType": "bool",
        "name": "cancelled",
        "type": "bool"
      },
      {
        "internalType": "bool",
        "name": "verificationRequired",
        "type": "bool"
      },
      {
        "internalType": "string",
        "name": "dealReference",
        "type": "string"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      },
      {
        "internalType": "bytes[]",
        "name": "signatures",
        "type": "bytes[]"
      }
    ],
    "name": "pay",
    "outputs": [],
    "stateMutability": "payable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "bytes32",
        "name": "dealId",
        "type": "bytes32"
      }
    ],
    "name": "quote",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "grandTotal",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "stateMutability": "payable",
    "type": "receive"
  }
]
```
