scallop_deepbook_kit 5.0.0
scallop_deepbook_kit: ^5.0.0 copied to clipboard
A Dart/Flutter toolkit for interacting with DeepBook V3 Margin Pools on the Sui blockchain.
Scallop DeepBook Kit (Dart) | Scallop DeepBook 工具包(Dart) #
A Dart/Flutter toolkit for interacting with DeepBook V3 Margin Pools on the Sui
blockchain, built on the sui_dart SDK.
一個在 Sui 區塊鏈上與 DeepBook V3 Margin Pools 互動的 Dart/Flutter 工具套件,
建構於 sui_dart SDK 之上。
Features | 功能特色 #
- DeepBook V3 Margin integration — supply, withdraw, referrals, balances.
- Pool analytics —
DeepBookMarginPoolreads pool parameters and computes borrow/supply APR, utilization, and kinks (viadevInspect, no signing needed). - On-chain discovery —
getOnChainMarginPools()enumerates margin pools from the on-chain dynamic-fields table. - Flutter-friendly — pure Dart, no native plugins; works on mobile & desktop (gRPC; see Platform note).
- Built on
sui_dart— your org's Sui SDK (Transaction v2 builder, gRPC, Ed25519, BCS).
Installation | 安裝 #
dart pub add scallop_deepbook_kit
# Flutter projects: flutter pub add scallop_deepbook_kit
Or add it to your pubspec.yaml directly:
dependencies:
scallop_deepbook_kit: ^4.0.0
Use an unreleased version (git / path)
dependencies:
scallop_deepbook_kit:
git:
url: https://github.com/scallop-io/scallop-deepbook-kit-dart.git
# or, for local development:
# scallop_deepbook_kit:
# path: ../scallop-deepbook-kit-dart
Then run dart pub get (or flutter pub get).
Quick Start | 快速開始 #
import 'package:scallop_deepbook_kit/scallop_deepbook_kit.dart';
Future<void> main() async {
// Initialize the toolkit. The private key may be a `suiprivkey…` bech32 string,
// a hex string (with or without 0x), or base64. Raw key material defaults to Ed25519.
final toolkit = DeepBookMarginToolkit(ToolkitConfig(
network: 'testnet', // 'testnet' | 'mainnet'
privateKey: '<YOUR_PRIVATE_KEY>',
// supplierCapId: '0x…', // optional: reuse an existing cap
// grpcHost: 'fullnode.mainnet.sui.io', // optional: custom gRPC host (no scheme)
));
// ... and `await toolkit.dispose();` when finished, to close the gRPC channel.
// Create the Supplier Cap if one does not already exist.
await toolkit.initialize();
// Create a supply referral (optional).
final referralId = await toolkit.createSupplyReferral('SUI');
// Supply 0.1 SUI to the margin pool.
await toolkit.supplyToMarginPool('SUI', 0.1, referralId: referralId);
// Read balances.
final balance = await toolkit.getBalance('SUI');
print('Supplied: ${balance.userSupplyAmount} SUI');
print('Wallet: ${balance.walletBalance} SUI');
// Withdraw all supplied SUI (omit the amount to withdraw everything).
await toolkit.withdrawFromMarginPool('SUI');
// Withdraw accumulated referral fees.
if (referralId != null) {
await toolkit.withdrawReferralFees('SUI', referralId);
}
}
Flutter tip: never hard-code a private key in your app. Load it from secure storage (e.g.
flutter_secure_storage) or your backend, and pass it toToolkitConfig.
Pool analytics (no signing) | 池參數與年化(免簽名) #
final pool = DeepBookMarginPool(network: 'mainnet');
// Single pool
final sui = await pool.getPoolParameters('SUI');
print('supply APR: ${sui.supplyApr}'); // normalized fraction, e.g. 0.045 = 4.5%
print('borrow APR@hi:${sui.borrowAprOnHighKink}');
print('utilization: ${sui.utilizationRate}');
// Batch (one devInspect + batched object reads)
final many = await pool.getPoolsParameters(['SUI', 'USDC', 'DEEP']);
for (final p in many) {
print('${p.type}: util=${p.utilizationRate}, supplyAPR=${p.supplyApr}');
}
You can also pass a custom DeepBookConfig (e.g. with a custom marginPools map) — see
example/margin_pool_demo.dart.
Wallet usage (build, then sign yourself) | 錢包用法(自行簽名) #
Two ways to transact, depending on who holds the key:
DeepBookMarginToolkit— you give it the private key; it builds, signs, and executes for you (great for a Flutter app with an embedded wallet in secure storage).DeepBookMarginPoolbuild* helpers — read with the pool, build an unsigned tx, then sign + execute with your own wallet/signer. The private-key toolkit is never required.
final pool = DeepBookMarginPool(network: 'mainnet');
final account = SuiAccount.fromPrivateKey(keyFromSecureStorage); // your wallet/signer
final address = account.getAddress();
// Discover the user's SupplierCap(s) (matches by type suffix — upgrade-safe).
final caps = await pool.getSupplierCapIds(address);
// Build an unsigned supply tx (mint a cap if the user has none). The supply coin
// is resolved from the amount automatically (SUI from gas, else from the wallet).
final tx = Transaction()..setSender(address);
final cap = caps.isEmpty ? pool.buildMintSupplierCap(tx) : tx.object(caps.first);
await pool.buildSupply(tx, 'SUI', cap, 0.1, owner: address);
if (caps.isEmpty) tx.transferObjects([cap], address);
// Sign + execute with your account (or hand `tx` to any wallet/signer).
final result = await signAndExecuteTransaction(pool.suiClient, account, tx);
Other builders: buildWithdraw(tx, coinKey, cap, {amount}) (returns the coin to
transfer/merge), buildMintSupplyReferral, buildWithdrawReferralFees. Need the coin
argument alone? use the exported coinWithBalance(client, tx, owner:, coinType:, amount:).
Full example: example/wallet_flow_demo.dart.
Discover margin pools on-chain | 鏈上探索保證金池 #
final pools = await getOnChainMarginPools(); // defaults to mainnet
pools.forEach((key, pool) => print('$key -> ${pool.address} (${pool.type})'));
API Reference | API 參考 #
DeepBookMarginToolkit #
| Method | Returns | Description |
|---|---|---|
DeepBookMarginToolkit(ToolkitConfig config) |
— | Construct from network + private key. |
initialize() |
Future<String> |
Create the Supplier Cap if needed; returns its id. |
createSupplierCap() |
Future<String?> |
Mint a new Supplier Cap. |
createSupplyReferral(coin) |
Future<String?> |
Mint a supply referral for coin. |
supplyToMarginPool(coin, amount, {referralId}) |
Future<bool> |
Supply amount (human units). |
withdrawFromMarginPool(coin, {amount}) |
Future<bool> |
Withdraw amount, or all if omitted. |
withdrawReferralFees(coin, referralId) |
Future<bool> |
Withdraw accrued referral fees. |
getBalance(coin) |
Future<MarginBalance> |
userSupplyAmount + walletBalance. |
getSupplierCapId() |
String? |
Current Supplier Cap id. |
getAddress() |
String |
Wallet address. |
ToolkitConfig: network, privateKey, supplierCapId?, grpcHost?,
supplierCapPackageId?, dbConfig?. Also dispose() to close the gRPC channel.
DeepBookMarginPool #
Reads: getPoolParameters(coinKey, {supplierCapId}) → MarginPoolParams;
getPoolsParameters(coinKeys, {supplierCapId}) → List<MarginPoolParams>;
getSupplierCapIds([owner]) → Future<List<String>> (the owner's SupplierCap ids).
Tx builders (unsigned; sign + execute yourself): buildMintSupplierCap(tx) → cap;
buildSupply(tx, coinKey, cap, amount, {owner, referralId}) (resolves the coin);
buildWithdraw(tx, coinKey, cap, {amount}) → coin; buildMintSupplyReferral(tx, coinKey);
buildWithdrawReferralFees(tx, coinKey, referralId). Public fields: marginPoolContract,
dbConfig, suiClient. dispose() closes the channel (only if it owns it).
Also exported #
MarginPoolContract, getOnChainMarginPools, DeepBookConfig,
Coin/Pool/MarginPool/DeepbookPackageIds/PythConfig, the testnet*/mainnet* constant
maps, FLOAT_SCALAR, marginPoolParamKeys, MarginBalance, and the wallet-flow helpers
signAndExecuteTransaction(client, account, tx), coinWithBalance(client, tx, owner:, coinType:, amount:),
and GrpcExecResult.
Supported networks & coins | 支援的網路與幣種 #
- Networks:
testnet,mainnet(or supply custompackageIdsviaDeepBookConfig). - Margin-pool coin keys: mainnet
SUI, USDC, DEEP, WAL, SUIUSDE, XBTC, USDSUI; testnetSUI, DBUSDC, DEEP, DBTC. All package ids, coin types, and pool addresses are the current DeepBook V3 values.
Implementation notes | 實作說明 #
Transactions are built over gRPC: a coin of a given balance is resolved with
splitCoins(gas) for SUI, or listCoins + merge + split otherwise; the clock is
tx.object(SUI_CLOCK_OBJECT_ID); Option<ID> referrals use tx.pure.option('id', …); write
txs are built server-side via simulateTransaction(doGasSelection: true) (the fullnode
resolves gas and returns canonical signable bytes — no JSON-RPC build); 1e9-scaled rate math
uses BigInt with double for display.
Note on
sui_dart's gRPC wrappers:sui_dart0.4.1's high-levelsimulateTransaction/executeTransactionbuild a readMask that omitscommand_outputsand the full effects, so they return no Move-call return values. This package therefore calls the raw generated services with a correctFieldMask(seesrc/utils/grpc_exec.dart). Writes are built server-side viasimulateTransaction(doGasSelection: true)(the fullnode resolves gas and returns canonical signable bytes) — no JSON-RPC client is used.
Platform | 平台 #
gRPC uses native HTTP/2 — works on Flutter mobile & desktop (iOS, Android, macOS, Windows,
Linux). Flutter Web is not supported by raw gRPC (it needs a grpc-web proxy). Call
toolkit.dispose() / pool.dispose() to release the gRPC channel when done.
Verification status | 驗證狀態 #
- ✅
dart analyze— clean (no issues). - ✅
dart test— offline unit tests pass (math, conversion, constants, config, key parsing, Move-call BCS encoding). - ✅ Live read paths over gRPC —
getPoolParameters/getPoolsParameters(mainnet + testnet APR/utilization) andgetOnChainMarginPoolscovered bytest/live_grpc_test.dart(run withRUN_LIVE_TESTS=1 dart test test/live_grpc_test.dart; skipped by default so the offline suite stays fast). All pass against real fullnodes. - ✅ Live write & wallet flows — the private-key flow (
initialize/supply/withdraw) and the wallet build-then-sign flow (getSupplierCapIds→buildSupply→ sign/execute → withdraw) verified on testnet (tool/write_flow_check.dart,tool/wallet_flow_check.dart).
License | 授權 #
MIT — see LICENSE.