API & Integration

Build on
Shaka.

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

Contract 0x8f105b54494095373eD2573dBaFA7e546e2EbF99
What you can build

Any deal flow.
Any split.

01
Commission splits

Set every wallet and every amount before the deal closes. One payment, and everyone is paid in the same transaction.

createDeal(recipients, amounts, referrer, dealReference, verificationRequired)
02
Your brand, your payment flow

Your clients pay in your interface, on your domain. The contract settles in the background. White label

pay(dealId, signatures)
03
Payouts on your condition

A milestone, an approval, an oracle: keep the condition on your side and call the contract the moment it resolves.

// condition met: pay(dealId, signatures)

Contract

Contract ShakaDeal
Address 0x8f105b54494095373eD2573dBaFA7e546e2EbF99
Network Ethereum mainnet
Asset ETH (native)
Source Verified on Etherscan

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

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

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

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 Fee 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
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

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 AI agents.

ABI

The full contract interface, 13 entries — the same as the verified contract on Etherscan.

Show the full ABI
[
  {
    "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"
  }
]

Your next deal.
Closed.

Set up the deal in two minutes. Every party signs their share, your client pays once, and everyone is paid the same day — with a receipt for each.