Agent integration: depositing into SweetHouse
This guide is for developers building autonomous agents — Talus/Nexus agents, trading bots, treasury managers — that want to allocate capital to the Suigar house programmatically.
Nothing here needs permission from Suigar. The deposit and redeem entry points are public Move functions on a shared object, callable by any address or any Move package on Sui mainnet.
Building on Talus/Nexus? Start at Using the Nexus tools — Suigar is registered in the mainnet tool registry. Everyone else can go straight to Calling it.
What you are buying
SweetHouse is the bankroll that takes the other side of every bet on Suigar. Players wager against the house, so the pool collects the house edge over time and absorbs the losses when players win.
Depositing mints hTokens (StakedCoin<CoinType>), a receipt whose price moves with the pool. Redeeming burns them at the current price.
Returns are gambling P&L, not lending interest. Expected value is positive because the house edge is positive, but variance is real and a short window can be negative. Size accordingly, and do not model this as a fixed-yield venue.
Addresses
Sui mainnet:
| Core package | 0xcbb0929f21450013ebe5e86e7139f2409da2e3ed212c51126a7e6448b795a43f |
| SweetHouse (shared object) | 0xa1549d73230118716bc08865b8d62454f360ddaf40eee2158e458e52125d4ef1 |
| SUI | 0x2::sui::SUI — 9 decimals |
| USDC | 0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC — 6 decimals |
Resolve these at runtime rather than hardcoding them. Package ids change when a package is upgraded. The Suigar MCP server exposes the current set:
npx -y @suigar/mcp # then call read_config with network: "mainnet"
All amounts below are in base units — 1 USDC is 1000000.
Using the Nexus tools (Talus)
Suigar is registered in the Nexus mainnet tool registry. Drag these onto a canvas in Talus Vision, or reference them by FQN in a DAG. All three are read-or-propose: none of them sign, and none hold a key.
| FQN | What it does |
|---|---|
win.suigar.house.pool-stats@1 | Live bankroll telemetry for one coin |
win.suigar.house.deposit-intent@1 | Prepares a deposit for signing |
win.suigar.house.redeem-intent@1 | Prepares a withdrawal for signing |
pool-stats
Input { "coin": "USDC" }. Returns total liquidity, trailing APY, hToken price, deposit fee, remaining capacity and whether deposits are open.
{"ok": {
"coin": "USDC",
"total_liquidity": "36583327149",
"public_pool_apy_percent": 84.99,
"htoken_price": 1.6608,
"public_pool_deposit_fee_percent": 0,
"public_pool_remaining_capacity": "0",
"deposit_available": false,
"as_of_ms": 1788181866458
}}
public_pool_apy_percent and htoken_price are null when there is not enough price history to compute them honestly.
deposit-intent and redeem-intent
Input for a deposit: { "coin": "USDC", "amount": "10000000", "owner_address": "0x…" }.
They validate against live pool state — a closed pool or an amount over remaining capacity comes back as err rather than a proposal the chain would reject — then return the exact Move call to sign:
{"ok": {
"move_target": "0xcbb0929f…::sweethouse::deposit_public_pool_and_mint_staked_coins",
"type_arguments": ["0xdba34672…::usdc::USDC"],
"sweethouse_object_id": "0xa1549d73…",
"amount": "10000000",
"fee_amount": "0",
"net_deposit_amount": "10000000",
"estimated_htokens": "6021211",
"recipient": "0x…",
"summary": "Deposit 10000000 base units of USDC into the Suigar house…",
"as_of_ms": 1788181866458
}}
Show summary to whoever approves the transaction — they are approving it on the strength of that line.
Who signs
Nothing in Nexus signs on a user's behalf once a workflow is running: from that point every transaction is signed by the Leader, which has no authority over your coins. So these tools propose, and whoever owns the funds signs.
They return an intent — target, type arguments, amounts — rather than serialised transaction bytes. Bytes would pin specific coin objects by id and version, so a proposal approved twenty minutes later would already be stale if that coin had been spent, merged or split. Assemble and sign fresh at signing time; the transaction block example shows the shape, and Two patterns for autonomous agents covers the alternative of depositing in the same transaction that launches the workflow.
A workflow that uses them
pool-stats(USDC)→ ifdeposit_availableand the APY beats your alternative →deposit-intent→ emit the proposal for your owner to sign.
Branch on the err variant to handle a closed or full pool. Both intent tools return err with kind set to err_input, err_upstream or err_internal, so a DAG can route on the cause.
Errors you will actually see
The USDC pool is not currently accepting deposits— the public pool is at its cap. Correct and expected while capacity is full.Amount exceeds remaining capacity of N base units— deposit less, or wait for room.
Calling it
From a transaction block (recommended)
You do not need any Move code or dependency. Build a PTB and call the package directly.
import { Transaction } from '@mysten/sui/transactions';
const CORE = '0xcbb0929f21450013ebe5e86e7139f2409da2e3ed212c51126a7e6448b795a43f';
const SWEET_HOUSE = '0xa1549d73230118716bc08865b8d62454f360ddaf40eee2158e458e52125d4ef1';
const USDC = '0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC';
const tx = new Transaction();
// Split the amount you want to deposit off a USDC coin you own.
// For SUI you can split from tx.gas instead.
const [deposit] = tx.splitCoins(tx.object(myUsdcCoinId), [10_000_000]); // 10 USDC
const hTokens = tx.moveCall({
target: `${CORE}::sweethouse::deposit_public_pool_and_mint_staked_coins`,
typeArguments: [USDC],
arguments: [tx.object(SWEET_HOUSE), deposit],
});
// The call RETURNS a coin. You must consume it or the transaction fails.
tx.transferObjects([hTokens], myAddress);
From your own Move package
If your agent holds its treasury inside a contract, call it directly:
use suigar::sweethouse;
use suigar::house::StakedCoin;
public fun allocate_to_house<CoinType>(
house: &mut sweethouse::SweetHouse,
funds: Coin<CoinType>,
ctx: &mut TxContext,
): Coin<StakedCoin<CoinType>> {
sweethouse::deposit_public_pool_and_mint_staked_coins<CoinType>(house, funds, ctx)
}
This requires the suigar package as a Move dependency, and its source is not currently published. If you need the Move path, contact us — otherwise use the transaction-block route above, which needs nothing from us and is what most integrations should use.
Exiting
Exiting is two steps, and in the normal case you only perform the first.
1. Request the redemption. Hand back your hTokens:
tx.moveCall({
target: `${CORE}::sweethouse::redeem_request`,
typeArguments: [USDC],
arguments: [
tx.object(SWEET_HOUSE),
tx.object(myHTokenCoinId),
tx.object('0x6'), // the Clock
],
});
This emits RedeemRequestCreatedEvent with a request id.
2. Wait. Suigar settles open requests automatically, in practice within hours. The payout is transferred to the address that made the request, so nothing further is required of you.
Fallback. If a request has not been settled 7 days after it was made, you can claim it yourself:
tx.moveCall({
target: `${CORE}::sweethouse::claim_own_redeem_request_after_delay`,
typeArguments: [USDC],
arguments: [tx.object(SWEET_HOUSE), tx.pure.id(requestId), tx.object('0x6')],
});
The claim must be signed by the same address that created the request. If your agent rotates keys, keep the requesting key available until the request settles.
Two patterns for autonomous agents
Worth understanding before you design a workflow: a running workflow cannot sign for you. In Nexus, your own wallet signs when you publish, when you fund, and when you launch. From the moment a workflow starts, every transaction is signed by the Leader — and the Leader has no authority over your coins. So a deposit has to happen at a moment you sign.
That leaves two shapes, and they differ in who decides the amount.
Decide up front, deposit at launch
A Sui transaction is a list of commands, so the transaction that starts your workflow can deposit first:
- Split the amount off one of your coins.
- Call
deposit_public_pool_and_mint_staked_coinsand transfer the hTokens to yourself. - Start the workflow, in the same transaction.
One signature, funds moved, workflow running. Use the Nexus SDK or CLI for the third command; the first two are exactly as shown above.
The limitation: the amount is fixed before the agent has thought about anything.
Let the agent decide, then sign
Have the workflow end by proposing a deposit rather than making one. The final step emits the call to make and the numbers behind it; your app or wallet picks that up and asks you to approve.
The agent gets to reason over live conditions — capacity, fee, current price — and you keep the keys. Nothing custodial anywhere.
One design note if you build this: emit the intent, not pre-built transaction bytes. Serialised bytes pin specific coin objects by id and version, so a proposal you approve twenty minutes later is already broken if that coin was spent, merged or split in the meantime. Emit the target, type arguments, amounts and object ids, and assemble the transaction fresh at signing time.
Reading live state
Before depositing, check that the pool is open and how much room is left.
- On chain — read the SweetHouse object and inspect
public_pool.max_capacityagainst the pool's total value. - Public API —
GET https://api.suigar.com/stats/pool-apysreturns the trailing APY per pool, andGET https://api.suigar.com/stats/pool-price-history?coinType=...returns the hToken price series.
Before you ship
- A deposit fee is charged off the top. It is stored on chain as
public_deposit_fee, out of 100,000, so1000means 1%. Subtract it when computing a net expected return. - Deposits are capped. The contract asserts
deposit + current pool total <= max_capacity, measured against the pool's total value. A deposit that would exceed the cap aborts. - A cap of
0means the pool is closed, not uncapped. Check before assuming a pool accepts deposits. - The deposit call returns a coin. Transfer it somewhere in the same transaction or the transaction will not build.
- Redeeming needs the Clock at
0x6. - Package ids move on upgrade. Resolve them at runtime.
- Whitelist pools have no deposit path. Public pool only.
Questions
For the Move dependency, higher deposit caps, or anything not covered here: contact@suigar.com.