Sui Scallop SDK (Dart)
A fully featured Dart toolkit for interacting with the Scallop lending protocol on the Sui network. It wraps Scallop's on-chain Move contracts, off-chain indexer APIs, price oracles, and transaction builders so you can build lending apps, portfolio dashboards, and automation in pure Dart.
Features
- Unified
Scallopclient that exposes builders, queries, utilities, and constants behind a single initialization step. - Read market state from on-chain RPC and the Scallop indexer, with automatic fallback to on-chain reads when the indexer is unavailable.
- Transaction builders for the core lending flows (obligation management, supply, borrow, repay, stake/unstake, claim, loyalty programs, xOracle updates, etc.).
- Utilities for Scallop metadata (addresses, whitelists, decimals), coin selection/merging, and price feeds from Pyth, Switchboard, and the Scallop price service.
- Portfolio helpers that aggregate user positions, TVL, borrow limits, rewards, and staking data.
- Built on
sui_kit, so you can plug in any signer, key-derivation path, or full-node rotation strategy SuiKit supports.
Installation
dart pub add sui_scallop_sdk
Or add it to your pubspec.yaml:
dependencies:
sui_scallop_sdk: ^1.0.4
Then run dart pub get (or flutter pub get).
Platform support: this package uses gRPC (
dart:io) and supports the native platforms (Android, iOS, Linux, macOS, and Windows). Web/WASM is not supported.
Quick Start
The SDK is composed of a few building blocks, all reachable from a single Scallop instance:
Scallop: the entry point. Construct it, callawait init()once, then read the sub-models from its getters.scallop.constants: the canonical package/object IDs, coin metadata, and whitelists.scallop.indexer: Scallop's REST indexer for cached market data.scallop.utils: helpers (coin parsing, price feeds, coin selection).scallop.query: read APIs across market, spool, loyalty, veSCA, and oracle contracts.scallop.builder: enhances Sui transaction blocks with Scallop-specific Move calls.scallop.client: high-level methods that build, sign, and submit transactions.
Bootstrap the client
import 'dart:io';
import 'package:sui_kit/sui_kit.dart';
import 'package:sui_scallop_sdk/sui_scallop_sdk.dart';
Future<Scallop> createScallop() async {
final scallop = Scallop(
networkType: NetworkType.mainnet,
// A secret key is only needed to sign transactions; omit it for read-only use.
secretKey: Platform.environment['PRIVATE_KEY'],
// Optional overrides: addressId, indexerApiUrl, pythEndpoints, tokensPerSecond, ...
);
// Fetches addresses/metadata and wires up the query/builder/client stack.
// Must be awaited before accessing any of the getters below.
await scallop.init();
return scallop;
}
Querying market data
final scallop = await createScallop();
final query = scallop.query;
// Fetch pools (indexer first, fallback to RPC if needed).
final market = await query.getMarketPools(['sui', 'wusdc']);
final suiPool = market.pools['sui'];
print('SUI supply APY: ${suiPool?.supplyApy}');
// Inspect user balances and obligations.
final balances = await query.getCoinAmounts(['sui', 'wusdc']);
final obligations = await query.getObligations();
// Portfolio helper with staking and incentive data.
final lendings = await query.getLendings(poolCoinNames: ['sui', 'wusdc']);
// Protocol-wide totals.
final tvl = await query.getTvl();
Most query methods accept an indexer: true flag. When set, the SDK tries the REST API first and silently falls back to direct on-chain reads if the request fails.
Submitting transactions
final scallop = await createScallop();
final client = scallop.client;
// Deposit 1 SUI (amounts are in the coin's smallest unit; 1 SUI = 1e9 MIST).
final response = await client.deposit('sui', BigInt.from(1000000000));
print('Tx digest: ${response.txResponse?.digest}');
// Build an unsigned borrow transaction for sponsorship or custom signing.
final obligations = await client.getObligations();
final obligation = obligations.first;
final borrow = await client.borrow(
'wusdc',
BigInt.from(5000000),
obligationId: obligation.id,
obligationKey: obligation.keyId,
sign: false,
);
final txBlock = borrow.txBlock; // hand off to your own signing flow
ScallopClient covers the common flows (openObligation, deposit, depositAndStake, withdraw, borrow, repay, flashLoan, stake, unstake, claim, mintSCoin, burnSCoin, etc.). Each method supports sign: false so you can compose, sponsor, or inspect transactions before submitting. For lower-level control, use scallop.builder and work with the Move helpers it exposes.
Utility helpers
final scallop = await createScallop();
final utils = scallop.utils;
final coinType = utils.parseCoinType('wusdc');
final sCoinName = utils.parseMarketCoinName('sui'); // -> 'ssui'
final prices = await utils.getCoinPrices();
final selection = await utils.selectCoins(
BigInt.from(5000000000),
coinType: coinType,
ownerAddress: utils.walletAddress,
);
Configuration
Scallop's constructor accepts these optional parameters:
networkType: target Sui network (defaults to mainnet). Switch full nodes at runtime viascallop.utils.scallopSuiKit.switchFullNodes([...]).secretKey/walletAddress: the signer used for transactions and owner-scoped queries.addressId: the Scallop address record to load (override to test against forks or specific deployments).indexerApiUrl/baseUrl/defaultHeaders/timeout: point the REST indexer / HTTP client at custom endpoints.pythEndpoints/pythTimeoutMs/usePythPullModel/sponsoredFeeds: configure Pyth price-feed resolution. Builders for xOracle and Switchboard updates live underlib/src/builders/oracles.tokensPerSecond: throttle RPC calls via the built-in rate limiter.
Testing & Examples
A runnable example lives in example/sui_scallop_sdk_example.dart:
dart run example/sui_scallop_sdk_example.dart
The repository also includes integration tests that exercise the query and builder surfaces. They expect a .env file with PRIVATE_KEY=<hex_or_bech32_key>:
dart test
Troubleshooting
- Ensure your wallet has the required coins before submitting transactions. The SDK surfaces the underlying Sui RPC errors when a balance is insufficient.
- The SDK targets Sui mainnet. Override
addressIdorindexerApiUrlonly if you point at a custom mainnet deployment or a self-hosted indexer. - Large portfolio queries aggregate many RPC requests; raise your test
Timeoutor lowertokensPerSecondif you regularly hit rate limits.
Contributing
Issues and pull requests are welcome. Please run dart format ., dart analyze, and the test suite before submitting changes.
License
Licensed under the Apache 2.0 license.