Skip to main content

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 package0xcbb0929f21450013ebe5e86e7139f2409da2e3ed212c51126a7e6448b795a43f
SweetHouse (shared object)0xa1549d73230118716bc08865b8d62454f360ddaf40eee2158e458e52125d4ef1
SUI0x2::sui::SUI — 9 decimals
USDC0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::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.

FQNWhat it does
win.suigar.house.pool-stats@1Live bankroll telemetry for one coin
win.suigar.house.deposit-intent@1Prepares a deposit for signing
win.suigar.house.redeem-intent@1Prepares 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) → if deposit_available and 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

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:

  1. Split the amount off one of your coins.
  2. Call deposit_public_pool_and_mint_staked_coins and transfer the hTokens to yourself.
  3. 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_capacity against the pool's total value.
  • Public APIGET https://api.suigar.com/stats/pool-apys returns the trailing APY per pool, and GET 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, so 1000 means 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 0 means 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.