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.
- Each recipient signs the digest returned by
approvalDigest(dealId, recipient, amount). - Pass the signatures to
pay(dealId, signatures), one per recipient. - 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.valuemust matchquote(dealId)exactly, or the payment reverts. Callquote()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 pendingpay(), 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"
}
]