diff --git a/skills/bucket-sdk/SKILL.md b/skills/bucket-sdk/SKILL.md
new file mode 100644
index 0000000..3848c8e
--- /dev/null
+++ b/skills/bucket-sdk/SKILL.md
@@ -0,0 +1,421 @@
+---
+name: bucket-sdk
+description: Use when integrating with Bucket Protocol on Sui blockchain — building CDP transactions, PSM swaps, saving pool deposits/withdrawals, oracle price queries, flash mints, or querying vault and position data. Also use when the user wants to mint/repay USDB stablecoin, manage collateralized debt positions, swap stablecoins via PSM, or earn yield in Bucket saving pools. Trigger whenever someone needs to use @bucket-protocol/sdk as a dependency.
+---
+
+# Bucket Protocol SDK — Integration Guide
+
+`@bucket-protocol/sdk` is a TypeScript SDK for [Bucket Protocol](https://bucketprotocol.io), a CDP-based stablecoin protocol on Sui purpose-built for capital efficiency. Users deposit supported on-chain assets as collateral to borrow **USDB** (a decentralized, over-collateralized stablecoin pegged to $1 USD). The SDK lets you query on-chain state and build Programmable Transaction Blocks (PTBs) for CDPs, saving pools (sUSDB + BSR yield), PSM stablecoin swaps, flash mints, oracle price feeds, and one-click leverage.
+
+**Official docs**:
+
+## Installation
+
+```bash
+npm install @bucket-protocol/sdk @mysten/sui @mysten/bcs
+# or
+pnpm add @bucket-protocol/sdk @mysten/sui @mysten/bcs
+```
+
+Peer dependencies: `@mysten/sui >=2.0.0`, `@mysten/bcs >=2.0.0`.
+
+## Quick Start
+
+```typescript
+import { BucketClient, coinWithBalance } from '@bucket-protocol/sdk';
+import { Transaction } from '@mysten/sui/transactions';
+
+// 1. Initialize (fetches config from chain automatically)
+const client = await BucketClient.initialize({ network: 'mainnet' });
+
+// 2. Build a transaction
+const tx = new Transaction();
+const [, usdbCoin] = await client.buildManagePositionTransaction(tx, {
+ coinType: '0x2::sui::SUI',
+ depositCoinOrAmount: 1_000_000_000, // 1 SUI (9 decimals)
+ borrowAmount: 800_000, // 0.8 USDB (6 decimals)
+});
+tx.transferObjects([usdbCoin], myAddress);
+
+// 3. Sign and execute (with your own signer)
+await suiClient.signAndExecuteTransaction({ transaction: tx, signer });
+```
+
+## Initialization
+
+```typescript
+import { BucketClient } from '@bucket-protocol/sdk';
+// Custom RPC endpoint
+import { SuiGrpcClient } from '@mysten/sui/grpc';
+
+// Default — fetch all config from mainnet
+const client = await BucketClient.initialize({ network: 'mainnet' });
+
+const suiClient = new SuiGrpcClient({ network: 'mainnet', baseUrl: 'https://my-rpc.example.com' });
+const client = await BucketClient.initialize({ suiClient, network: 'mainnet' });
+
+// Override specific config (e.g. Pyth Hermes endpoint)
+const client = await BucketClient.initialize({
+ network: 'mainnet',
+ configOverrides: { PRICE_SERVICE_ENDPOINT: 'https://custom-hermes.example.com' },
+});
+```
+
+`initialize()` reads on-chain config objects to resolve all package IDs, vault/pool/aggregator shared object refs, and Pyth settings. Call `client.refreshConfig()` later to pick up protocol upgrades without re-creating the client.
+
+## Key Concepts
+
+### PTB Builders — Build, Don't Execute
+
+All write operations return PTB commands, not executed transactions. Methods prefixed `build*` take a `Transaction` object and append Move calls. You sign and execute separately. This lets you compose multiple SDK calls into a single atomic transaction.
+
+### `coinWithBalance` — Automatic Coin Merging
+
+Pass raw amounts instead of coin objects. The SDK auto-fetches user coins, merges them, and splits the needed amount at `tx.build()` time:
+
+```typescript
+import { coinWithBalance } from '@bucket-protocol/sdk';
+
+// These are equivalent:
+await client.buildPSMSwapInTransaction(tx, {
+ coinType: usdcType,
+ inputCoinOrAmount: 1_000_000, // pass number directly
+});
+await client.buildPSMSwapInTransaction(tx, {
+ coinType: usdcType,
+ inputCoinOrAmount: coinWithBalance({ type: usdcType, balance: 1_000_000 }), // explicit factory
+});
+```
+
+### Decimals
+
+| Token | Decimals | 1 unit in raw |
+| ----- | -------- | --------------- |
+| SUI | 9 | `1_000_000_000` |
+| USDB | 6 | `1_000_000` |
+| USDC | 6 | `1_000_000` |
+| BTC | 8 | `100_000_000` |
+
+Always pass amounts in raw (smallest unit). The SDK does not auto-scale.
+
+### Account vs EOA
+
+Bucket supports `Account` objects that hold positions on behalf of a wallet. Most builder methods accept an optional `accountObjectOrId` parameter:
+
+- **Omit** → operates on the wallet address directly (EOA mode)
+- **Pass Account object ID** → operates on that Account's positions
+
+## API Reference
+
+### Querying On-Chain Data
+
+All query methods are `async` and read-only — no transaction needed.
+
+```typescript
+// Protocol-level data
+const supply = await client.getUsdbSupply(); // bigint
+const prices = await client.getOraclePrices({ coinTypes: [SUI_TYPE_ARG] }); // Record
+const allPrices = await client.getAllOraclePrices(); // all supported coins
+
+// Vault data
+const vaults = await client.getAllVaultObjects(); // Record
+const collateralTypes = client.getAllCollateralTypes(); // string[]
+
+// Saving pool data
+const pools = await client.getAllSavingPoolObjects(); // Record
+
+// PSM pool data
+const psmPools = await client.getAllPsmPoolObjects(); // Record
+
+// Flash mint info
+const flash = await client.getFlashMintInfo(); // { feeRate, partner }
+
+// User-specific data
+const positions = await client.getUserPositions({ address }); // PositionInfo[]
+const savings = await client.getUserSavings({ address }); // SavingInfo[]
+const accounts = await client.getUserAccounts({ address }); // Account[]
+
+// Paginated position listing by collateral
+const { positions, nextCursor } = await client.getAllPositions({
+ coinType: SUI_TYPE_ARG,
+ pageSize: 50,
+ cursor: null,
+});
+
+// Reward queries
+const borrowRewards = await client.getAccountBorrowRewards({
+ address,
+ coinTypes: [SUI_TYPE_ARG],
+}); // Record>
+
+const savingRewards = await client.getAccountSavingPoolRewards({
+ address,
+ lpTypes: [susdbLpType],
+}); // Record>
+```
+
+### Building Transactions
+
+#### CDP — Manage Collateralized Debt Positions
+
+```typescript
+const tx = new Transaction();
+
+// Deposit collateral + borrow USDB
+const [collateralCoin, usdbCoin] = await client.buildManagePositionTransaction(tx, {
+ coinType: '0x2::sui::SUI',
+ depositCoinOrAmount: 2_000_000_000, // 2 SUI
+ borrowAmount: 1_000_000, // 1 USDB
+});
+tx.transferObjects([usdbCoin], myAddress);
+
+// Repay debt (partial or full)
+await client.buildManagePositionTransaction(tx, {
+ coinType: '0x2::sui::SUI',
+ repayCoinOrAmount: 500_000, // 0.5 USDB
+});
+
+// Withdraw collateral (requires sufficient CR)
+const [withdrawnCoin] = await client.buildManagePositionTransaction(tx, {
+ coinType: '0x2::sui::SUI',
+ withdrawAmount: 500_000_000, // 0.5 SUI
+});
+tx.transferObjects([withdrawnCoin], myAddress);
+
+// Close position entirely — repays all debt, returns all collateral
+const [allCollateral] = client.buildClosePositionTransaction(tx, {
+ address: myAddress,
+ coinType: '0x2::sui::SUI',
+});
+tx.transferObjects([allCollateral], myAddress);
+
+// Claim borrow incentive rewards
+const rewards = client.buildClaimBorrowRewardsTransaction(tx, {
+ coinType: '0x2::sui::SUI',
+});
+// rewards: Record
+Object.values(rewards).forEach((coin) => tx.transferObjects([coin], myAddress));
+```
+
+**Price is auto-fetched**: `buildManagePositionTransaction` calls `aggregatePrices` internally when `borrowAmount > 0` or `withdrawAmount > 0`. Deposit-only or repay-only operations skip the oracle call.
+
+#### Saving Pools — Two Layers of USDB Yield
+
+Bucket's saving system has **two layers**:
+
+- **Layer 1 — sUSDB (BSR)**: Stake USDB → receive sUSDB. Value appreciates via the Base Savings Rate (BSR) through an increasing exchange rate. `minted_sUSDB = staked_USDB / exchange_rate`.
+- **Layer 2 — sUSDB Savings Pool**: Deposit sUSDB → earn additional SUI rewards on top of BSR. Total APR = BSR + SUI rewards APR.
+
+No stake/unstake fee. No lockup.
+
+```typescript
+const tx = new Transaction();
+
+// Deposit USDB
+client.buildDepositToSavingPoolTransaction(tx, {
+ address: myAddress,
+ lpType: susdbLpType, // saving pool LP type
+ depositCoinOrAmount: 1_000_000, // 1 USDB
+});
+
+// Withdraw USDB
+const usdbCoin = client.buildWithdrawFromSavingPoolTransaction(tx, {
+ lpType: susdbLpType,
+ amount: 500_000,
+});
+tx.transferObjects([usdbCoin], myAddress);
+
+// Claim saving pool rewards
+const rewards = client.buildClaimSavingRewardsTransaction(tx, {
+ lpType: susdbLpType,
+});
+Object.values(rewards).forEach((coin) => tx.transferObjects([coin], myAddress));
+```
+
+#### PSM — Peg Stability Module Swaps
+
+```typescript
+const tx = new Transaction();
+
+// Swap USDC → USDB
+const usdbCoin = await client.buildPSMSwapInTransaction(tx, {
+ coinType: usdcType,
+ inputCoinOrAmount: 1_000_000, // 1 USDC
+});
+tx.transferObjects([usdbCoin], myAddress);
+
+// Swap USDB → USDC
+const usdcCoin = await client.buildPSMSwapOutTransaction(tx, {
+ coinType: usdcType,
+ usdbCoinOrAmount: 1_000_000, // 1 USDB
+});
+tx.transferObjects([usdcCoin], myAddress);
+```
+
+#### Flash Mint — Borrow USDB Within a Single Transaction
+
+```typescript
+const tx = new Transaction();
+
+// Mint USDB (must be burned in the same tx)
+const [usdbCoin, receipt] = client.flashMint(tx, { amount: 10_000_000 });
+
+// ... use usdbCoin for arbitrage, liquidation, etc. ...
+
+// Burn (repay) — must include the fee
+client.flashBurn(tx, { usdbCoin: remainingUsdb, flashMintReceipt: receipt });
+```
+
+### Composing Multiple Operations
+
+A key strength of PTBs is atomic composition. You can chain SDK calls in one transaction:
+
+```typescript
+const tx = new Transaction();
+
+// 1. Swap USDC to USDB
+const usdbCoin = await client.buildPSMSwapInTransaction(tx, {
+ coinType: usdcType,
+ inputCoinOrAmount: 1_000_000,
+});
+
+// 2. Deposit the USDB into a saving pool
+client.buildDepositToSavingPoolTransaction(tx, {
+ address: myAddress,
+ lpType: susdbLpType,
+ depositCoinOrAmount: usdbCoin, // pass TransactionResult directly
+});
+```
+
+#### Leverage via Flash Mint (One-Click Leverage Pattern)
+
+Bucket supports leveraged positions using flash mints. The one-click flow:
+
+1. Flash-mint USDB
+2. Swap flash-minted USDB → target collateral (via DEX)
+3. Deposit all collateral → borrow USDB
+4. Repay flash mint with borrowed USDB
+
+```typescript
+const tx = new Transaction();
+
+// 1. Flash mint USDB for the leverage amount
+const [flashUsdb, receipt] = client.flashMint(tx, { amount: leverageUsdbAmount });
+
+// 2. Swap USDB → SUI via external DEX aggregator (e.g. Cetus)
+// ... (DEX swap calls — not part of Bucket SDK) ...
+
+// 3. Deposit all SUI as collateral, borrow USDB to repay flash
+const [, borrowedUsdb] = await client.buildManagePositionTransaction(tx, {
+ coinType: '0x2::sui::SUI',
+ depositCoinOrAmount: totalSuiCoin,
+ borrowAmount: leverageUsdbAmount + flashFee,
+});
+
+// 4. Repay flash mint
+client.flashBurn(tx, { usdbCoin: borrowedUsdb, flashMintReceipt: receipt });
+```
+
+### Low-Level PTB Helpers
+
+For advanced use cases, the building blocks behind `build*` methods are also public:
+
+- **Price**: `aggregateBasicPrices(tx, { coinTypes })` (Pyth-only feeds), `aggregatePrices(tx, { coinTypes })` (all feeds incl. derivatives) → `TransactionResult[]`
+- **CDP internals**: `debtorRequest()` → `checkUpdatePositionRequest()` → `updatePosition()` → `checkUpdatePositionResponse()`
+- **Saving pool calls**: `savingPoolDeposit()`, `savingPoolWithdraw()`, `checkDepositResponse()`, `checkWithdrawResponse()`, `claimPoolIncentive()`
+- **PSM calls**: `psmSwapIn()`, `psmSwapOut()`
+- **Object refs**: `treasury(tx)`, `vault(tx, { coinType })`, `aggregator(tx, { coinType })`, `savingPoolObj(tx, { lpType })`, `psmPoolObj(tx, { coinType })`, `vaultRewarderRegistry(tx)`, `savingPoolGlobalConfig(tx)`, `flashGlobalConfig(tx)`
+- **Account helpers**: `accountAddress(tx, { address, accountObjectOrId })`, `newAccountRequest(tx, { address, accountObjectOrId })`, `newPriceCollector(tx, { coinType })`
+
+## Key Types
+
+```typescript
+// Vault info — returned by getAllVaultObjects()
+type VaultInfo = {
+ collateralType: string;
+ collateralDecimal: number;
+ collateralBalance: bigint;
+ usdbSupply: bigint;
+ maxUsdbSupply: bigint;
+ minCollateralRatio: number; // e.g. 1.1 = 110%
+ interestRate: number;
+ positionTableSize: number;
+ rewardRate: Record;
+};
+
+// User position — returned by getUserPositions()
+type PositionInfo = {
+ collateralType: string;
+ collateralAmount: bigint;
+ debtAmount: bigint;
+ debtor: string;
+ accountId?: string;
+ rewards?: Record;
+};
+
+// Saving pool info — returned by getAllSavingPoolObjects()
+type SavingPoolInfo = {
+ lpType: string;
+ lpSupply: bigint;
+ usdbBalance: bigint;
+ usdbDepositCap: bigint | null;
+ savingRate: number;
+ rewardRate: Record;
+};
+
+// PSM pool info — returned by getAllPsmPoolObjects()
+type PsmPoolInfo = {
+ coinType: string;
+ decimal: number;
+ balance: bigint;
+ usdbSupply: bigint;
+ feeRate: { swapIn: number; swapOut: number };
+ partnerFeeRate: Record;
+};
+
+// User saving — returned by getUserSavings()
+type SavingInfo = {
+ lpType: string;
+ address: string;
+ accountId?: string;
+ usdbBalance: bigint;
+ lpBalance: bigint;
+ rewards: Record;
+};
+
+// Flash mint info — returned by getFlashMintInfo()
+type FlashMintInfo = {
+ feeRate: number;
+ partner: Record;
+};
+```
+
+## Common Gotchas
+
+1. **async vs sync builders**: `buildManagePositionTransaction` and `buildPSMSwap*Transaction` are `async` (they fetch Pyth prices). `buildDepositToSavingPoolTransaction`, `buildWithdrawFromSavingPoolTransaction`, `buildClaimSavingRewardsTransaction`, `buildClosePositionTransaction`, and `buildClaimBorrowRewardsTransaction` are synchronous.
+
+2. **Zero coin auto-cleanup**: When `borrowAmount` is 0, the returned USDB coin is a zero coin that gets auto-destroyed. Same for collateral when `withdrawAmount` is 0. You don't need to handle this.
+
+3. **Dry-run / simulation**: Use `suiClient.simulateTransaction({ transaction: tx })` to test without signing. Set `tx.setSender(address)` first.
+
+4. **Config refresh**: If the protocol upgrades, call `client.refreshConfig()` to re-fetch on-chain config. Overrides from `initialize()` are preserved automatically.
+
+5. **No borrow fee**: The protocol has **no** one-time borrow fee (removed in the v2 upgrade). Only fixed per-asset interest rates apply. Interest accrues in real time and is added to debt continuously.
+
+6. **Mint caps**: Each vault has a max USDB supply (`VaultInfo.maxUsdbSupply`). Borrowing beyond this cap will fail on-chain.
+
+7. **Full liquidation**: When a position's CR drops below MCR, **all collateral is seized** (not partial). Liquidations are protocol-run. User loss ≈ `(MCR - 1) × Debt`. The SDK does not execute liquidations.
+
+8. **Repay with collateral**: The "repay with collateral" feature (selling collateral to repay debt) is a UI-level feature that routes through on-chain DEXes. The base SDK provides `buildManagePositionTransaction` with `repayCoinOrAmount` for repaying with USDB you already hold.
+
+9. **sUSDB exchange rate**: sUSDB appreciates vs USDB over time via BSR. When withdrawing, users receive more USDB per sUSDB than they deposited. The exchange rate only increases.
+
+## Bundled Resources
+
+This skill includes additional reference files. Consult them when you need detailed data:
+
+| Resource | Path | When to use |
+| ---------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
+| **Coin Types** | `references/coin-types.md` | Need the full `0x...` type string for a specific token (collateral, PSM, LP, reward) |
+| **Protocol Concepts** | `references/protocol-concepts.md` | Need to understand CDP mechanics, PSM vs CDP decision, saving pool yield, flash mints, Account vs EOA, or oracle pricing |
+| **Query State Script** | `scripts/query-state.ts` | Need to inspect live on-chain state (vault stats, prices, pool balances). Run with `npx tsx skills/bucket-sdk/scripts/query-state.ts` |
diff --git a/skills/bucket-sdk/references/coin-types.md b/skills/bucket-sdk/references/coin-types.md
new file mode 100644
index 0000000..4933279
--- /dev/null
+++ b/skills/bucket-sdk/references/coin-types.md
@@ -0,0 +1,100 @@
+# Bucket Protocol — Supported Coin Types (Mainnet)
+
+This file lists all coin types supported by Bucket Protocol on Sui mainnet. Use these exact strings when calling SDK methods like `buildManagePositionTransaction`, `buildPSMSwapInTransaction`, etc.
+
+> **Note**: Coin types may change as the protocol adds or removes support. Call `client.getAllCollateralTypes()`, `client.getAllOracleCoinTypes()`, or inspect `client.getConfig()` for the live list.
+
+## USDB (Bucket's Stablecoin)
+
+| Token | Coin Type | Decimals |
+| ----- | -------------------------------------------------------------------------------- | -------- |
+| USDB | `0xe14726c336e81b32328e92afc37345d159f5b550b09fa92bd43640cfdd0a0cfd::usdb::USDB` | 6 |
+
+Get it programmatically with `client.getUsdbCoinType()`.
+
+## Basic Collateral (Direct Pyth Price Feed)
+
+These tokens have a direct Pyth oracle price. They can be used as CDP collateral and are supported by `aggregateBasicPrices()`.
+
+| Token | Coin Type | Decimals | Notes |
+| ------ | ------------------------------------------------------------------------------------ | -------- | -------------------- |
+| SUI | `0x2::sui::SUI` | 9 | Native gas token |
+| BTC | `0xaafb102dd0902f5055cadecd687fb5b71ca82ef0e0285d90afde828ec58ca96b::btc::BTC` | 8 | |
+| ETH | `0xd0e89b2af5e4910726fbcd8b8dd37bb79b29e5f83f7491bca830e94f7f226d29::eth::ETH` | 8 | |
+| WAL | `0x356a26eb9e012a68958082340d4c4116e7f55615cf27affcff209cf0ae544f59::wal::WAL` | 9 | Walrus token |
+| USDC | `0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC` | 6 | |
+| USDT | `0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT` | 6 | |
+| haSUI | `0xbde4ba4c2e274a60ce15c1cfff9e5c42e41654ac8b6d906a57efa4bd3c29f47d::hasui::HASUI` | 9 | Haedal staked SUI |
+| CERT | `0x549e8b69270defbfafd4f94e17ec44cdbdd99820b33bda2278dea3b9a32d3f55::cert::CERT` | 9 | Volo staked SUI |
+| afSUI | `0xf325ce1300e8dac124071d3152c5c5ee6174914f8bc2161e88329cf579246efc::afsui::AFSUI` | 9 | Aftermath staked SUI |
+| SCA | `0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6::sca::SCA` | 9 | Scallop token |
+| BUCK | `0xce7ff77a83ea0cb6fd39bd8748e2ec89a3f41e8efdc3f4eb123e0ca37b184db2::buck::BUCK` | 9 | Bucket V1 stablecoin |
+| DEEP | `0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP` | 6 | DeepBook token |
+| XBTC | `0x876a4b7bce8aeaef60464c11f4026903e9afacab79b9b142686158aa86560b50::xbtc::XBTC` | 8 | |
+| WBTC | `0x0041f9f9344cac094454cd574e333c4fdb132d7bcc9379bcd4aab485b2a63942::wbtc::WBTC` | 8 | |
+| UP_USD | `0x5de877a152233bdd59c7269e2b710376ca271671e9dd11076b1ff261b2fd113c::up_usd::UP_USD` | 6 | Unihouse USD |
+| XAUM | `0x9d297676e7a4b771ab023291377b2adfaa4938fb9080b8d12430e4b108b836a9::xaum::XAUM` | 6 | Tokenized gold |
+
+## Derivative Collateral (Price from Underlying)
+
+These tokens derive their price from a basic token via an exchange rate (Scallop sCoin, Unihouse gCoin, or BFBTC). The SDK handles this automatically in `aggregatePrices()` — you don't need to treat them differently from basic collateral when using `build*` methods.
+
+### sCoin (Scallop Lending Receipts) — derivative_kind: `sCoin`
+
+| Token | Coin Type | Underlying |
+| ----- | ------------------------------------------------------------------------------------------------------ | ---------- |
+| sSUI | `0xaafc4f740de0dd0dde642a31148fb94517087052f19afb0f7bed1dc41a50c77b::scallop_sui::SCALLOP_SUI` | SUI |
+| sUSDC | `0x854950aa624b1df59fe64e630b2ba7c550642e9342267a33061d59fb31582da5::scallop_usdc::SCALLOP_USDC` | USDC |
+| sUSDT | `0xb1d7df34829d1513b73ba17cb7ad90c88d1e104bb65ab8f62f13e0cc103783d3::scallop_sb_usdt::SCALLOP_SB_USDT` | USDT |
+| sWAL | `0x622345b3f80ea5947567760eec7b9639d0582adcfd6ab9fccb85437aeda7c0d0::scallop_wal::SCALLOP_WAL` | WAL |
+| sDEEP | `0xeb7a05a3224837c5e5503575aed0be73c091d1ce5e43aa3c3e716e0ae614608f::scallop_deep::SCALLOP_DEEP` | DEEP |
+| sETH | `0xb14f82d8506d139eacef109688d1b71e7236bcce9b2c0ad526abcd6aa5be7de0::scallop_sb_eth::SCALLOP_SB_ETH` | ETH |
+| sSCA | `0x5ca17430c1d046fae9edeaa8fd76c7b4193a00d764a0ecfa9418d733ad27bc1e::scallop_sca::SCALLOP_SCA` | SCA |
+
+### gCoin (Unihouse Staked House Coins) — derivative_kind: `gCoin`
+
+| Token | Coin Type | Underlying |
+| ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------- |
+| gSUI | `0x2f2226a22ebeb7a0e63ea39551829b238589d981d1c6dd454f01fcc513035593::house::StakedHouseCoin<0x2::sui::SUI>` | SUI |
+| gUP_USD | `0x2f2226a22ebeb7a0e63ea39551829b238589d981d1c6dd454f01fcc513035593::house::StakedHouseCoin<0x5de877a152233bdd59c7269e2b710376ca271671e9dd11076b1ff261b2fd113c::up_usd::UP_USD>` | UP_USD |
+
+### BFBTC — derivative_kind: `BFBTC`
+
+| Token | Coin Type | Underlying |
+| ----- | ---------------------------------------------------------------------------------- | ---------- |
+| BFBTC | `0x7438e8caf5c345fbd3772517380bf0ca432f53892dee65ee0dda3eb127993cd9::bfbtc::BFBTC` | BTC |
+
+## PSM Pool Coins
+
+These coins can be swapped 1:1 with USDB via `buildPSMSwapInTransaction` / `buildPSMSwapOutTransaction`:
+
+| Token | Coin Type | Decimals |
+| ----- | -------------------------------------------------------------------------------- | -------- |
+| USDC | `0xdba34672e30cb065b1f93e3ab55318768fd6fef66c15942c9f7cb846e2f900e7::usdc::USDC` | 6 |
+| USDT | `0x375f70cf2ae4c00bf37117d0c85a2c71545e6ee05c4a5c7d282cd66a4504b068::usdt::USDT` | 6 |
+| BUCK | `0xce7ff77a83ea0cb6fd39bd8748e2ec89a3f41e8efdc3f4eb123e0ca37b184db2::buck::BUCK` | 9 |
+
+## Saving Pool LP Types
+
+Pass these as the `lpType` parameter to saving pool methods (`buildDepositToSavingPoolTransaction`, etc.):
+
+| Token | LP Type |
+| ----- | ---------------------------------------------------------------------------------- |
+| sUSDB | `0x38f61c75fa8407140294c84167dd57684580b55c3066883b48dedc344b1cde1e::susdb::SUSDB` |
+
+## Common Reward Types
+
+These appear as keys in borrow/saving reward records:
+
+| Token | Coin Type |
+| ----- | -------------------------------------------------------------------------------- |
+| SUI | `0x2::sui::SUI` |
+| SCA | `0x7016aae72cfc67f2fadf55769c0a7dd54291a583b63051a5ed71081cce836ac6::sca::SCA` |
+| DEEP | `0xdeeb7a4662eec9f2f3def03fb937a663dddaa2e215b8078a284d026b7946c270::deep::DEEP` |
+| XAUM | `0x9d297676e7a4b771ab023291377b2adfaa4938fb9080b8d12430e4b108b836a9::xaum::XAUM` |
+
+## Protocol Token
+
+| Token | Coin Type | Decimals | Notes |
+| ----- | ------------------------------------------------------------------------------ | -------- | ------------------------------------------ |
+| BUT | `0xbc858cb910b9914bee64fff0f9b38855355a040c49155a17b265d9086d256545::but::BUT` | 9 | Native protocol token; stakeable for deBUT |
diff --git a/skills/bucket-sdk/references/protocol-concepts.md b/skills/bucket-sdk/references/protocol-concepts.md
new file mode 100644
index 0000000..790b185
--- /dev/null
+++ b/skills/bucket-sdk/references/protocol-concepts.md
@@ -0,0 +1,342 @@
+# Bucket Protocol — Concepts & Decision Guide
+
+This document explains the core protocol concepts an agent needs to understand to make correct integration decisions.
+
+**Official docs**:
+
+## What is Bucket Protocol?
+
+Bucket Protocol is a **CDP-based stablecoin protocol on Sui, purpose-built for capital efficiency**. Users deposit supported on-chain assets as collateral to borrow **USDB**, a decentralized, over-collateralized stablecoin pegged to $1 USD.
+
+USDB serves two user needs:
+
+- **Volatile-asset holders** borrow USDB against collateral for long-term leverage or liquidity without selling core positions.
+- **Stablecoin allocators** hold USDB and deposit into the sUSDB Savings Pool for competitive, flexible yield.
+
+### Key Advantages
+
+- **Fixed per-asset interest rates** — funding costs known upfront, no variable rate anxiety
+- **High LTV** — per-asset CDP isolation enables more usable capital
+- **Explicit risk boundaries** — simple CR/MCR rule with live liquidation price; no Recovery Mode
+- **No one-time borrow fee** — only fixed interest rates apply
+- **Derivative collateral support** — LSTs, sCoins, gCoins can be used as collateral
+
+## CDP (Collateralized Debt Positions)
+
+### How It Works
+
+1. User deposits collateral (e.g. SUI, BTC, ETH) into a vault
+2. User borrows USDB against that collateral
+3. The position must maintain a **minimum collateral ratio** (MCR) — typically 110%
+4. Interest accrues on the debt over time
+5. User can repay debt and/or withdraw collateral at any time (within CR constraints)
+
+### Collateral Ratio (CR) & Liquidation Price
+
+```
+CR = (Collateral Price × Collateral Amount) / (initial Borrow Amount + Accrued Interest)
+```
+
+Each collateral has a fixed **Minimum Collateral Ratio (MCR)** (e.g. 110%). If CR < MCR, the position is liquidatable.
+
+```
+Liquidation Price = (MCR × Debt) / Collateral Amount
+```
+
+**Example**: 1,000 SUI at $5/SUI ($5,000 collateral), borrow 4,000 USDB, MCR = 110%
+
+- Entry CR = 5,000 / 4,000 = 125%
+- Liquidation Price = (1.10 × 4,000) / 1,000 = $4.40/SUI
+
+> After every action, the position must satisfy CR ≥ MCR.
+
+### When to Use Which CDP Method
+
+| Goal | Method | Needs Price? |
+| -------------------------- | ----------------------------------------------------------------------- | :----------: |
+| Deposit collateral only | `buildManagePositionTransaction({ depositCoinOrAmount })` | No |
+| Borrow USDB | `buildManagePositionTransaction({ borrowAmount })` | Yes (auto) |
+| Repay debt | `buildManagePositionTransaction({ repayCoinOrAmount })` | No |
+| Withdraw collateral | `buildManagePositionTransaction({ withdrawAmount })` | Yes (auto) |
+| Deposit + borrow in one tx | `buildManagePositionTransaction({ depositCoinOrAmount, borrowAmount })` | Yes (auto) |
+| Close entire position | `buildClosePositionTransaction()` | No |
+| Claim borrow incentives | `buildClaimBorrowRewardsTransaction()` | No |
+
+`buildManagePositionTransaction` is the all-in-one method. You can combine any of deposit/borrow/repay/withdraw in a single call. It handles zero-coin cleanup automatically.
+
+### Fees & Interest
+
+- **No one-time borrow fee** (removed in the v2 upgrade)
+- **Fixed borrow interest rate** per collateral type (visible in `VaultInfo.interestRate`)
+- Interest accrues in real time and is added to debt continuously
+- Rates are protocol-set and not user-adjustable
+
+### Mint Caps
+
+Each vault has a maximum USDB supply (`VaultInfo.maxUsdbSupply`). Borrowing beyond this cap will fail on-chain. Mint caps help manage market depth during liquidations and reduce slippage risk in extreme conditions.
+
+### Liquidation
+
+- **Trigger**: CR < MCR → position becomes liquidatable
+- **Scope**: **Full seizure** — ALL collateral in that CDP is taken
+- **Executor**: Liquidations are protocol-run (not by users)
+
+**How liquidation is executed on-chain:**
+
+1. Flash-mint USDB to immediately repay the CDP's outstanding debt
+2. Seize all collateral from the liquidated CDP
+3. Sell the seized collateral for USDB using on-chain venues
+4. Repay the flash-minted USDB from step 1
+
+**User loss**: At liquidation threshold, `User loss ≈ (MCR - 1) × Debt`. The user keeps the USDB previously borrowed.
+
+**Bad-debt backstop**: If collateral proceeds < debt, the protocol's Insurance Fund (funded from protocol revenue) covers the gap.
+
+**Avoiding liquidation**: Deposit more collateral or repay part of the debt to raise CR.
+
+> The SDK does **not** execute liquidations — it only builds position management transactions.
+
+## USDB Peg Mechanism
+
+USDB targets $1 USD via two mechanisms:
+
+### Peg Stability Module (PSM)
+
+The PSM enables trustless 1:1 conversions between USDB and supported stablecoins (USDC, USDT, BUCK), subject to a PSM fee.
+
+- **Swap In**: Stablecoin → USDB (e.g. deposit 1 USDC, receive ~1 USDB minus fee)
+- **Swap Out**: USDB → Stablecoin (e.g. deposit 1 USDB, receive ~1 USDC minus fee)
+
+Each PSM pool has `swapIn` and `swapOut` fee rates (visible in `PsmPoolInfo.feeRate`). Partner accounts may get lower fees via `partnerFeeRate`.
+
+### Price Stability & Arbitrage
+
+Let `price_usdb` = USDB market price on DEX, `fee_in` = PSM IN fee, `fee_out` = PSM OUT fee.
+
+**Upward depeg (USDB > $1)**: Acquire USDB via PSM IN at ~$1, sell on market at `price_usdb > 1`. Profitable when `price_usdb > 1 + fee_in + gas`.
+
+**Downward depeg (USDB < $1)**: Buy USDB on market at `price_usdb < 1`, exit via PSM OUT at ~$1. Profitable when `price_usdb < 1 - fee_out - gas`.
+
+**Flash-mint assisted arbitrage**: For capital efficiency, use flash mint to source/retire USDB within one transaction, pairing the opposite leg through PSM or market liquidity.
+
+### When to Use PSM vs CDP
+
+| Scenario | Use PSM | Use CDP |
+| ------------------------------- | :-----: | :-----: |
+| Quickly get USDB from USDC/USDT | ✓ | |
+| Convert USDB back to USDC/USDT | ✓ | |
+| Leverage crypto exposure | | ✓ |
+| Earn borrow incentive rewards | | ✓ |
+| Long-term USDB generation | | ✓ |
+| Arbitrage USDB peg on DEX | ✓ | |
+
+## Saving System — Two Layers of USDB Yield
+
+Bucket provides two layers of yield for USDB holders. Total APR = BSR + SUI rewards APR.
+
+### Layer 1: sUSDB and BSR (Base Savings Rate)
+
+- **BSR** is Bucket’s fixed savings rate for USDB. It accrues in real time by increasing the exchange rate between sUSDB and USDB.
+- **sUSDB** is the yield-bearing stablecoin you receive when you stake USDB. Yield does not change your sUSDB balance; instead, each unit of sUSDB represents more USDB over time.
+
+**Formulas**:
+
+```
+minted_sUSDB = staked_USDB / exchange_rate
+unstaked_USDB = sUSDB_balance × exchange_rate
+```
+
+- No stake or unstake fee. No lockup.
+- Balances and the exchange rate update in real time.
+
+### Layer 2: sUSDB Savings Pool
+
+- Deposit sUSDB into the sUSDB Savings Pool to earn **additional SUI rewards** on top of BSR.
+- Savings rewards accrue continuously and are claimable at any time.
+- Withdraw whenever — no fees, no lockup.
+
+### Key Parameters
+
+- `savingRate`: BSR yield rate (exchange rate growth)
+- `rewardRate`: Additional token incentive rates (per reward type, e.g. SUI)
+- `usdbDepositCap`: Maximum total USDB the pool accepts (null = no cap)
+- `lpSupply`: Total sUSDB LP tokens outstanding
+
+### SDK Methods
+
+| Goal | Method |
+| --------------------------------------------- | ------------------------------------------ |
+| Deposit USDB → get sUSDB → earn BSR + rewards | `buildDepositToSavingPoolTransaction()` |
+| Withdraw sUSDB → receive USDB | `buildWithdrawFromSavingPoolTransaction()` |
+| Claim SUI rewards from savings pool | `buildClaimSavingRewardsTransaction()` |
+
+## Flash Mint
+
+### How It Works
+
+Flash minting allows borrowing USDB **without collateral** within a single atomic transaction. The borrowed USDB must be repaid (plus fee) before the transaction completes, or the entire transaction reverts.
+
+### Use Cases
+
+- Arbitrage between USDB price on DEXes
+- Self-liquidation or position restructuring
+- Leveraged operations composed in a single PTB
+
+### Fee
+
+A small fee rate applies (visible in `FlashMintInfo.feeRate`). The repayment must cover principal + fee.
+
+```typescript
+const [usdbCoin, receipt] = client.flashMint(tx, { amount: 10_000_000 });
+// ... do things with usdbCoin (arbitrage, etc.) ...
+// Must return principal + fee:
+client.flashBurn(tx, { usdbCoin, flashMintReceipt: receipt });
+```
+
+## Leverage
+
+Bucket supports two ways to build a leveraged long on supported assets:
+
+### One-Click Leverage (SUI/LST, Wrapped BTC)
+
+Uses flash minting to automatically create a leveraged position in one transaction:
+
+1. User deposits initial capital (e.g. 100 USDC)
+2. Flash-mints USDB worth the leverage amount
+3. Swaps initial capital + flash-minted USDB for target collateral (via Cetus aggregator)
+4. Deposits all as collateral → borrows USDB
+5. Repays the flash-mint with borrowed USDB
+
+**Result**: Leveraged position established atomically. Costs shown: flash-loan fee + price impact.
+
+### Manual Looping (All Collaterals)
+
+For assets without one-click support:
+
+1. Deposit collateral → Borrow USDB
+2. Swap USDB → more collateral (via DEX)
+3. Deposit the new collateral
+4. Repeat until desired leverage
+
+### De-Leveraging
+
+To reduce leverage or raise CR:
+
+- **Repay with collateral**: sell portion of collateral into USDB to repay debt (atomically via DEX routing)
+- **Repay with USDB**: repay from USDB in wallet
+- After repayment, CR rises and liquidation price moves lower (safer)
+
+## Account System
+
+### EOA vs Account Objects
+
+Bucket supports two modes for holding positions:
+
+- **EOA (Externally Owned Account)**: Positions are tied directly to the wallet address. This is the default when `accountObjectOrId` is omitted.
+- **Account Object**: A Sui on-chain object (`Account`) that holds positions on behalf of the owner. Useful for managing multiple independent positions from one wallet, or for protocol-level integrations.
+
+### When to Use Account Objects
+
+- Most integrations should **omit** `accountObjectOrId` and operate in EOA mode
+- Use Account objects when: the user has existing Account-based positions (check with `getUserAccounts()`), or the integration needs separate position management
+
+### Checking for Existing Accounts
+
+```typescript
+const accounts = await client.getUserAccounts({ address: walletAddress });
+// accounts is an array of Account objects
+// If empty, the user only has EOA positions
+```
+
+## Oracle Price System
+
+### How Prices Work
+
+Bucket uses **Pyth Network** as its oracle. The SDK handles price feeds automatically:
+
+1. Fetches latest price data (VAA) from Pyth's Hermes REST API
+2. Builds on-chain Wormhole verification + Pyth update calls
+3. Passes the verified price to CDP/PSM operations
+
+### Basic vs Derivative Prices
+
+- **Basic**: Direct Pyth feed (SUI, BTC, ETH, USDC, etc.)
+- **Derivative**: Price derived from basic price × exchange rate
+ - **sCoin** (Scallop): sSUI price = SUI price × Scallop exchange rate
+ - **gCoin** (Unihouse): gSUI price = SUI price × Unihouse exchange rate
+ - **BFBTC**: BFBTC price = BTC price × BFBTC exchange rate
+
+`aggregatePrices()` handles both basic and derivative prices transparently. The `build*` methods that need prices (borrow, withdraw, PSM swap) call it internally.
+
+### Querying Prices Without a Transaction
+
+```typescript
+// Get live prices (simulates a PTB internally)
+const prices = await client.getOraclePrices({ coinTypes: ['0x2::sui::SUI'] });
+console.log(prices['0x2::sui::SUI']); // e.g. 3.45 (USD)
+
+// Get all supported prices
+const allPrices = await client.getAllOraclePrices();
+```
+
+## Composing Operations in a Transaction
+
+Sui's PTB model allows combining multiple operations atomically. Common patterns:
+
+### Pattern 1: PSM → Saving (get USDB then earn yield)
+
+```typescript
+const tx = new Transaction();
+const usdb = await client.buildPSMSwapInTransaction(tx, {
+ coinType: usdcType,
+ inputCoinOrAmount: 1_000_000,
+});
+client.buildDepositToSavingPoolTransaction(tx, {
+ address: myAddress,
+ lpType: susdbLpType,
+ depositCoinOrAmount: usdb,
+});
+```
+
+### Pattern 2: Borrow → PSM out (borrow USDB then convert to USDC)
+
+```typescript
+const tx = new Transaction();
+const [, usdb] = await client.buildManagePositionTransaction(tx, {
+ coinType: '0x2::sui::SUI',
+ depositCoinOrAmount: 2_000_000_000,
+ borrowAmount: 1_000_000,
+});
+const usdc = await client.buildPSMSwapOutTransaction(tx, {
+ coinType: usdcType,
+ usdbCoinOrAmount: usdb,
+});
+tx.transferObjects([usdc], myAddress);
+```
+
+### Pattern 3: Flash mint → Arbitrage → Repay
+
+```typescript
+const tx = new Transaction();
+const [usdb, receipt] = client.flashMint(tx, { amount: 10_000_000 });
+// ... use usdb for arbitrage on a DEX ...
+client.flashBurn(tx, { usdbCoin: usdbAfterArb, flashMintReceipt: receipt });
+```
+
+### Pattern 4: One-Click Leverage (Flash Mint → Swap → Deposit → Borrow → Repay)
+
+```typescript
+const tx = new Transaction();
+// 1. Flash mint USDB for leverage
+const [flashUsdb, receipt] = client.flashMint(tx, { amount: leverageAmount });
+// 2. Swap USDB → target collateral via DEX (not part of Bucket SDK)
+// ... DEX swap calls ...
+// 3. Deposit all collateral, borrow USDB to cover flash mint
+const [, borrowedUsdb] = await client.buildManagePositionTransaction(tx, {
+ coinType: '0x2::sui::SUI',
+ depositCoinOrAmount: totalCollateralCoin,
+ borrowAmount: leverageAmount + flashFee,
+});
+// 4. Repay flash mint
+client.flashBurn(tx, { usdbCoin: borrowedUsdb, flashMintReceipt: receipt });
+```
diff --git a/skills/bucket-sdk/scripts/query-state.ts b/skills/bucket-sdk/scripts/query-state.ts
new file mode 100644
index 0000000..c192d30
--- /dev/null
+++ b/skills/bucket-sdk/scripts/query-state.ts
@@ -0,0 +1,112 @@
+/**
+ * Diagnostic script: query Bucket Protocol on-chain state.
+ *
+ * Usage (from project root, or any project that has @bucket-protocol/sdk installed):
+ * npx tsx skills/bucket-sdk/scripts/query-state.ts
+ *
+ * Requires: @bucket-protocol/sdk, @mysten/sui
+ *
+ * Prints a summary of:
+ * - USDB total supply
+ * - Oracle prices for all supported collateral
+ * - Vault stats (TVL, collateral ratio, interest rate, max supply)
+ * - PSM pool balances and fee rates
+ * - Saving pool stats (rate, deposit cap, LP supply)
+ * - Flash mint info (fee rate)
+ */
+
+import { BucketClient } from '@bucket-protocol/sdk';
+
+function printLine(message = '') {
+ process.stdout.write(`${message}\n`);
+}
+
+function isDefined(value: T | null | undefined): value is T {
+ return value !== null && value !== undefined;
+}
+
+async function main() {
+ printLine('Initializing BucketClient (mainnet)...');
+ printLine();
+ const client = await BucketClient.initialize({ network: 'mainnet' });
+
+ // --- USDB Supply ---
+ const supply = await client.getUsdbSupply();
+ printLine(`USDB Total Supply: ${(Number(supply) / 1e6).toLocaleString()} USDB`);
+ printLine();
+
+ // --- Oracle Prices ---
+ printLine('=== Oracle Prices ===');
+ const prices = await client.getAllOraclePrices();
+ const sortedPrices = Object.entries(prices).sort(([, a], [, b]) => b - a);
+ for (const [coinType, price] of sortedPrices) {
+ const shortName = coinType.split('::').pop() ?? coinType;
+ printLine(` ${shortName.padEnd(20)} $${price}`);
+ }
+ printLine();
+
+ // --- Vaults ---
+ printLine('=== Vaults ===');
+ const vaults = await client.getAllVaultObjects();
+ for (const [coinType, vault] of Object.entries(vaults)) {
+ const shortName = coinType.split('::').pop() ?? coinType;
+ printLine(` [${shortName}]`);
+ printLine(` Min CR: ${vault.minCollateralRatio}`);
+ printLine(` Interest Rate: ${vault.interestRate}`);
+ printLine(
+ ` Max USDB: ${isDefined(vault.maxUsdbSupply) ? (Number(vault.maxUsdbSupply) / 1e6).toLocaleString() : 'unlimited'}`,
+ );
+ printLine(` USDB Minted: ${(Number(vault.usdbSupply) / 1e6).toLocaleString()}`);
+ printLine(` Collateral: ${vault.collateralBalance}`);
+ printLine(` Positions: ${vault.positionTableSize}`);
+ }
+ printLine();
+
+ // --- PSM Pools ---
+ printLine('=== PSM Pools ===');
+ const psmPools = await client.getAllPsmPoolObjects();
+ for (const [coinType, pool] of Object.entries(psmPools)) {
+ const shortName = coinType.split('::').pop() ?? coinType;
+ printLine(` [${shortName}]`);
+ printLine(` Balance: ${pool.balance}`);
+ printLine(` Swap-In Fee: ${pool.feeRate.swapIn}`);
+ printLine(` Swap-Out Fee:${pool.feeRate.swapOut}`);
+ }
+ printLine();
+
+ // --- Saving Pools ---
+ printLine('=== Saving Pools ===');
+ const savingPools = await client.getAllSavingPoolObjects();
+ for (const [lpType, pool] of Object.entries(savingPools)) {
+ const shortName = lpType.split('::').pop() ?? lpType;
+ printLine(` [${shortName}]`);
+ printLine(` Saving Rate: ${pool.savingRate}`);
+ printLine(` LP Supply: ${pool.lpSupply}`);
+ printLine(
+ ` Deposit Cap: ${isDefined(pool.usdbDepositCap) ? (Number(pool.usdbDepositCap) / 1e6).toLocaleString() : 'none'}`,
+ );
+ }
+ printLine();
+
+ // --- Flash Mint ---
+ printLine('=== Flash Mint ===');
+ const flashMint = await client.getFlashMintInfo();
+ printLine(` Fee Rate: ${flashMint.feeRate}`);
+ printLine();
+
+ // --- Supported Coin Types ---
+ printLine('=== Supported Collateral Types ===');
+ const collTypes = client.getAllCollateralTypes();
+ for (const ct of collTypes) {
+ const shortName = ct.split('::').pop() ?? ct;
+ printLine(` ${shortName}`);
+ }
+ printLine();
+
+ printLine('Done.');
+}
+
+main().catch((err) => {
+ console.error('Error:', err);
+ process.exit(1);
+});