Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 37 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ LP farming, leveraged yield farming, and more.
- **Token Swaps**: Integrated Cetus aggregator for optimal token routing
- **Type Safety**: Full TypeScript support with comprehensive type definitions
- **Options-Based API**: Consistent, easy-to-use interface across all methods
- **GraphQL-First Data Access**: SDK now initializes with network + optional GraphQL URL

## Installation

Expand All @@ -24,13 +25,14 @@ npm install @alphafi/alphafi-sdk

```typescript
import { AlphaFiSDK } from '@alphafi/alphafi-sdk';
import { SuiClient } from '@mysten/sui/client';

// Initialize the SDK
const suiClient = new SuiClient({ url: 'https://fullnode.mainnet.sui.io:443' });
const sdk = new AlphaFiSDK({
suiClient,
network: 'mainnet',
// Optional override (defaults by network):
// testnet -> https://graphql.testnet.sui.io/graphql
// mainnet -> https://graphql.mainnet.sui.io/graphql
graphqlUrl: process.env.SUI_GRAPHQL_URL,
});

const userAddress = 'your_sui_address_here';
Expand All @@ -54,8 +56,9 @@ const depositTx = await sdk.deposit({
amount: 1000000000n, // 1 SUI in base units
isAmountA: true, // For LP pools: which token this amount represents
});
// Sign & execute with your wallet / client
// await suiClient.signAndExecuteTransactionBlock({ transactionBlock: depositTx, signer });
// Sign & execute with your wallet / signer integration
// (example shown for shape only)
// await signerClient.signAndExecuteTransaction({ transaction: depositTx, signer });

// Build an unsigned withdraw transaction
const withdrawTx = await sdk.withdraw({
Expand Down Expand Up @@ -126,12 +129,37 @@ new AlphaFiSDK(config: AlphaFiSDKConfig)
#### Configuration Interface

```typescript
import type { Network } from '@alphafi/alphalend-sdk';

interface AlphaFiSDKConfig {
suiClient: SuiClient; // Sui blockchain client
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
network: Network; // Target network
graphqlUrl?: string; // Optional GraphQL endpoint override
apiBaseUrl?: string; // Optional AlphaFi API base URL override
}
```

#### Migration from Previous Initialization

If you were previously passing `suiClient` to `AlphaFiSDK`, migrate to `network` + optional
`graphqlUrl`:

```typescript
// Old
const sdk = new AlphaFiSDK({
suiClient,
network: 'mainnet',
});

// New
const sdk = new AlphaFiSDK({
network: 'mainnet',
graphqlUrl: process.env.SUI_GRAPHQL_URL, // optional
});
```

Under the hood, strategies now use a shared context-level AlphaLend client and resolve AlphaLend
constants from the active SDK network instead of hardcoded mainnet assumptions.

#### Core Methods

##### getPoolsData(strategiesType?: StrategyType[]): Promise\<Map\<string, PoolData>>
Expand Down Expand Up @@ -389,15 +417,11 @@ for (const [poolId, poolData] of allPools) {

```typescript
import { AlphaFiSDK } from '@alphafi/alphafi-sdk';
import { SuiClient } from '@mysten/sui/client';

const suiClient = new SuiClient({
url: process.env.SUI_RPC_URL || 'https://fullnode.mainnet.sui.io:443',
});

const sdk = new AlphaFiSDK({
suiClient,
network: (process.env.NETWORK as any) || 'mainnet',
graphqlUrl: process.env.SUI_GRAPHQL_URL, // optional
apiBaseUrl: process.env.ALPHAFI_API_URL, // optional
});

const userAddress = process.env.USER_ADDRESS;
Expand Down
16 changes: 8 additions & 8 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@
"author": "AlphaFi",
"license": "ISC",
"dependencies": {
"@alphafi/alphalend-sdk": "^1.1.28",
"@alphafi/stsui-sdk": "^0.0.23",
"@alphafi/alphalend-sdk": "^2.0.0",
"@alphafi/stsui-sdk": "^1.0.0",
"@apollo/client": "^4.0.11",
"@cetusprotocol/aggregator-sdk": "^1.4.2",
"@cetusprotocol/cetus-sui-clmm-sdk": "5.4.0",
Expand Down
6 changes: 5 additions & 1 deletion src/core/index.ts
Comment thread
harshaalphafi marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,11 @@ export class AlphaFiSDK {

constructor(config: AlphaFiSDKConfig) {
this.config = config;
this.strategyContext = new StrategyContext(config.network, config.suiClient, config.apiBaseUrl);
this.strategyContext = new StrategyContext(
config.network,
config.graphqlUrl,
config.apiBaseUrl,
);
this.protocol = new Protocol(this.strategyContext);
this.portfolio = new Portfolio(this.protocol, this.strategyContext);
}
Expand Down
9 changes: 4 additions & 5 deletions src/core/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@
* Core types and configuration interfaces for the AlphaFi SDK.
* These types define the structure for all SDK operations.
*/

import { SuiClient } from '@mysten/sui/client';
import { Transaction } from '@mysten/sui/transactions';
import { RouterDataV3 } from '@cetusprotocol/aggregator-sdk';
import { Network } from '@alphafi/alphalend-sdk';

/**
* Configuration required to initialize the AlphaFi SDK.
*/
export interface AlphaFiSDKConfig {
/** Sui blockchain client for network operations */
suiClient: SuiClient;
/** Target Sui network environment */
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
network: Network;
/** Optional Sui GraphQL endpoint override for network operations */
graphqlUrl?: string;
/** Base URL for the AlphaFi API (defaults to 'https://api.alphafi.xyz') */
apiBaseUrl?: string;
}
Expand Down
46 changes: 23 additions & 23 deletions src/models/blockchain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,36 +8,36 @@ import { graphql } from '@mysten/sui/graphql/schemas/latest';
import { Transaction } from '@mysten/sui/transactions';
import { toBase64 } from '@mysten/sui/utils';
import type { SimulationGasSummary, SimulationResult } from './types.js';
import { Network } from '@alphafi/alphalend-sdk';

export type BlockchainOptions = {
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
suiClient?: SuiClient;
gqlClient?: SuiGraphQLClient<any>;
network: Network;
txBuildClient?: SuiClient;
Comment thread
harshaalphafi marked this conversation as resolved.
graphqlUrl?: string;
};

export class Blockchain {
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet';
gqlClient: SuiGraphQLClient<any>;
suiClient: SuiClient;
network: Network;
graphqlUrl: string;
gqlClient: SuiGraphQLClient;
txBuildClient: SuiClient;

constructor(options: BlockchainOptions) {
this.network = options.network;
this.suiClient =
options.suiClient ||
new SuiClient({
url:
options.network === 'testnet'
? 'https://fullnode.testnet.sui.io/'
: 'https://fullnode.mainnet.sui.io/',
});
this.gqlClient =
options.gqlClient ||
new SuiGraphQLClient({
url:
options.network === 'testnet'
? 'https://graphql.testnet.sui.io/graphql'
: 'https://graphql.mainnet.sui.io/graphql',
});
this.graphqlUrl =
options.graphqlUrl ??
(options.network === 'testnet'
? 'https://graphql.testnet.sui.io/graphql'
: 'https://graphql.mainnet.sui.io/graphql');
this.txBuildClient = new SuiClient({
url:
options.network === 'testnet'
? 'https://fullnode.testnet.sui.io/'
: 'https://fullnode.mainnet.sui.io/',
});
this.gqlClient = new SuiGraphQLClient({
url: this.graphqlUrl,
});
}

async getCoinObject(tx: Transaction, coinType: string, address: string, amount?: bigint) {
Expand Down Expand Up @@ -126,7 +126,7 @@ export class Blockchain {
sender: string,
): Promise<SimulationResult | undefined> {
tx.setSenderIfNotSet(sender);
const txBytes = await tx.build({ client: this.suiClient });
const txBytes = await tx.build({ client: this.txBuildClient });
const txBase64 = toBase64(txBytes);

const query = graphql(`
Expand Down
16 changes: 6 additions & 10 deletions src/models/strategyContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@ import { Blockchain } from './blockchain.js';
import { CoinInfoProvider } from './coinInfoProvider.js';
import { PoolLabel, StrategyType } from '../strategies/strategy.js';
import { Decimal } from 'decimal.js';
import { AlphalendClient } from '@alphafi/alphalend-sdk';
import { AlphalendClient, Network } from '@alphafi/alphalend-sdk';
import { AlphaFiReceipt, AprData, CoinInfo, DistributorObject, SlushPositionCap } from './types.js';
import { normalizeStructTag } from '@mysten/sui/utils';
import { SuiClient } from '@mysten/sui/client/index.js';
import {
ALPHAFI_RECEIPT_TYPE,
CACHE_TTL,
Expand All @@ -28,6 +27,7 @@ export class StrategyContext {
readonly apiBaseUrl: string;
blockchain: Blockchain;
coinInfoProvider: CoinInfoProvider;
alphalendClient: AlphalendClient;

// Singleton caches for global data
private allPoolLabelsCache: SingletonCache<Map<string, PoolLabel>>; // For bulk fetches
Expand All @@ -44,14 +44,11 @@ export class StrategyContext {
private slushPositionsCache: Cache<string, Map<string, any[]>>;
private alphaFiPositionsCache: Cache<string, Map<string, any[]>>;

constructor(
network: 'mainnet' | 'testnet' | 'devnet' | 'localnet',
suiClient: SuiClient,
apiBaseUrl?: string,
) {
constructor(network: Network, graphqlUrl?: string, apiBaseUrl?: string) {
this.apiBaseUrl = apiBaseUrl ?? DEFAULT_API_BASE_URL;
this.blockchain = new Blockchain({ network, suiClient });
this.blockchain = new Blockchain({ network, graphqlUrl });
this.coinInfoProvider = new CoinInfoProvider();
this.alphalendClient = new AlphalendClient(network, graphqlUrl);

// Initialize singleton caches with appropriate TTLs
this.allPoolLabelsCache = new SingletonCache(CACHE_TTL.POOL_LABELS);
Expand Down Expand Up @@ -515,8 +512,7 @@ export class StrategyContext {

private async fetchAlphaLendTvl(): Promise<Map<string, Decimal>> {
const tvlMap = new Map<string, Decimal>();
const alphalendClient = new AlphalendClient('mainnet', this.blockchain.suiClient);
const markets = await alphalendClient.getAllMarkets({
const markets = await this.alphalendClient.getAllMarkets({
useCache: true,
cacheTTL: CACHE_TTL.ALPHALEND_MARKETS,
});
Expand Down
9 changes: 4 additions & 5 deletions src/strategies/alphaVault.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import {
POOLS,
VERSIONS,
} from '../utils/constants.js';
import { AlphalendClient, getConstants, getUserPositionCapId } from '@alphafi/alphalend-sdk';
import { getConstants, getUserPositionCapId } from '@alphafi/alphalend-sdk';

/**
* AlphaVault Strategy
Expand Down Expand Up @@ -917,7 +917,7 @@ export class AlphaVaultStrategy extends BaseStrategy<
}

async claimAirdrop(tx: Transaction, address: string, transferToWallet: boolean) {
const alphalendClient = new AlphalendClient('mainnet', this.context.blockchain.suiClient);
const alphalendClient = this.context.alphalendClient;
let airdropCoin;
const [suiCoin, alphaCoin] = await this.context.getCoinsBySymbols(['SUI', 'ALPHA']);
const airdropCoinMarketId = '1';
Expand Down Expand Up @@ -1010,10 +1010,9 @@ export class AlphaVaultStrategy extends BaseStrategy<

if (!transferToWallet) {
await alphalendClient.updatePrices(tx, ['0x2::sui::SUI']);
const alphalendConstants = getConstants('mainnet');
const alphalendConstants = getConstants(this.context.blockchain.network);
const userPositionCapId = await getUserPositionCapId(
this.context.blockchain.suiClient,
'mainnet',
this.context.alphalendClient.blockchain,
address,
);
if (!userPositionCapId) {
Expand Down
2 changes: 1 addition & 1 deletion src/strategies/lending.ts
Original file line number Diff line number Diff line change
Expand Up @@ -870,7 +870,7 @@ export class LendingStrategy extends BaseStrategy<

private async updateSingleTokenPrice(tx: Transaction, pythPriceInfo: string, feedId: string) {
const pythClient = new SuiPythClient(
this.context.blockchain.suiClient,
this.context.blockchain.txBuildClient,
PYTH_STATE_ID,
WORMHOLE_STATE_ID,
);
Expand Down
5 changes: 2 additions & 3 deletions src/strategies/looping.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import {
VERSIONS,
WORMHOLE_STATE_ID,
} from '../utils/constants.js';
import { AlphalendClient } from '@alphafi/alphalend-sdk';
import { stSuiExchangeRate, getConf as getStSuiConf } from '@alphafi/stsui-sdk';
import { SuiPriceServiceConnection, SuiPythClient } from '@pythnetwork/pyth-sui-js';

Expand Down Expand Up @@ -573,7 +572,7 @@ export class LoopingStrategy extends BaseStrategy<

private async updateSingleTokenPrice(tx: Transaction, pythPriceInfo: string, feedId: string) {
const pythClient = new SuiPythClient(
this.context.blockchain.suiClient,
this.context.blockchain.txBuildClient,
PYTH_STATE_ID,
WORMHOLE_STATE_ID,
);
Expand Down Expand Up @@ -873,7 +872,7 @@ export class LoopingStrategy extends BaseStrategy<
'ALPHA',
'BLUE',
]);
const alphalendClient = new AlphalendClient('mainnet', this.context.blockchain.suiClient);
const alphalendClient = this.context.alphalendClient;
await alphalendClient.updatePrices(tx, [stsuiCoin.coinType, suiCoin.coinType]);

tx.moveCall({
Expand Down
3 changes: 1 addition & 2 deletions src/strategies/lyf.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import {
SUI_SYSTEM_STATE,
VERSIONS,
} from '../utils/constants.js';
import { AlphalendClient } from '@alphafi/alphalend-sdk';
import { getConf as getStsuiConf } from '@alphafi/stsui-sdk';

/**
Expand Down Expand Up @@ -662,7 +661,7 @@ export class LyfStrategy extends BaseStrategy<

await this.collectAndSwapRewards(tx);

const alphalendClient = new AlphalendClient('mainnet', this.context.blockchain.suiClient);
const alphalendClient = this.context.alphalendClient;
await alphalendClient.updatePrices(tx, [
this.poolLabel.assetA.type,
this.poolLabel.assetB.type,
Expand Down
Loading
Loading