@broxus/js-core
Version:
MobX-based JavaScript Core library
674 lines (511 loc) • 17.9 kB
Markdown
# Broxus JavaScript Core library
This library provides a comprehensive set of MobX-based models, and utilities for building JavaScript applications
that interact with TVM-based blockchains. It offers reactive state management for smart contracts, tokens,
DEX operations, and more.
## Installation
Install the package as development dependency
```shell
npm install @broxus/js-core
```
```shell
yarn add @broxus/js-core
```
```shell
pnpm add @broxus/js-core
```
```shell
bun add @broxus/js-core
```
## Core
### `AbstractStore`
Base abstract class for creating reactive stores and services with built-in state and data management.
#### Interface
```typescript
abstract class AbstractStore<
T extends ObjectLiteral = ObjectLiteral,
U extends ObjectLiteral = ObjectLiteral
> {
protected _data: T
protected _state: U
setData<K extends keyof T>(dataOrFn: Pick<T, K> | ((prevData: Readonly<T>) => Pick<T, K>)): this
setData<K extends keyof T>(key: K, value: T[K]): this
setState<K extends keyof U>(stateOrFn: Pick<U, K> | ((prevState: Readonly<U>) => Pick<U, K>)): this
setState<K extends keyof U>(key: K, value?: U[K]): this
toJSON(): T
toJSON(both: true): [T, U]
}
```
#### Example
```typescript
import { AbstractStore } from '@broxus/js-core'
import { makeObservable, observable } from 'mobx'
interface UserData {
balance: string
name: string
}
interface UserState {
error?: string
isLoading: boolean
}
class UserStore extends AbstractStore<UserData, UserState> {
constructor() {
super({
initialData: { name: '', balance: '0' },
initialState: { isLoading: false }
})
makeObservable(this)
}
async loadUser(address: string): Promise<void> {
this.setState('isLoading', true)
try {
// Load user data
this.setData({ balance: '1000', name: 'User' })
}
catch (e: any) {
this.setState('error', e.message)
}
finally {
this.setState('isLoading', false)
}
}
}
```
### `SmartContractModel`
Abstract class for creating reactive smart contract wrappers with automatic state synchronization and blockchain event watching.
#### Interface
```typescript
abstract class SmartContractModel<
T extends SmartContractModelData | ObjectLiteral = SmartContractModelData,
U extends SmartContractModelState | ObjectLiteral = SmartContractModelState,
> extends AbstractStore<SmartContractModelData & T, SmartContractModelState & U> {
readonly address: Address
readonly computedStorageData?: {
accountStatus: 'uninit' | 'frozen' | 'active' | 'nonexist'
deleteDueLimit: string
freezeDueLimit: string
storageFee: string
storageFeeDebt?: string
}
readonly contractState?: FullContractState
readonly isDeployed?: boolean
readonly isSyncing?: boolean
readonly syncedAt?: number
syncContractState(options?: { force?: boolean, ttl?: number }): Promise<FullContractState | undefined>
watch?(callback?: (data: T, state: U) => void): Promise<Subscriber>
unwatch?(): Promise<void>
}
```
#### Example
```typescript
import { SmartContractModel } from '@broxus/js-core'
import { ProviderRpcClient } from 'everscale-inpage-provider'
interface CustomContractData {
owner: Address
value: string
}
class CustomContract extends SmartContractModel<CustomContractData> {
constructor(connection: ProviderRpcClient, address: Address) {
super(connection, address)
}
async sync() {
await this.syncContractState({ force: true })
if (!this.isDeployed) {
throw new Error('Contract not deployed')
}
// Fetch and set contract data
this.setData({
owner: /* ... */,
value: /* ... */
})
}
}
```
### `Endpoint`
Class for creating type-safe HTTP API endpoints with automatic URL generation and request handling.
#### Interface
```typescript
class Endpoint<TParams = undefined, TRequestBody = undefined, TResponse = any> {
constructor(path: string, basePath?: string)
url(params?: TParams): string
request(routeParams?: TParams, requestInit?: RequestInit, bodyData?: TRequestBody): Promise<Response>
fetch<UResponse = TResponse>(routeParams?: TParams, requestInit?: RequestInit, bodyData?: TRequestBody): Promise<UResponse>
post<UResponse = TResponse>(routeParams?: TParams, requestInit?: RequestInit, bodyData?: TRequestBody): Promise<UResponse>
put<UResponse = TResponse>(routeParams?: TParams, requestInit?: RequestInit, bodyData?: TRequestBody): Promise<UResponse>
delete<UResponse = TResponse>(routeParams?: TParams, requestInit?: RequestInit, bodyData?: TRequestBody): Promise<UResponse>
}
```
#### Example
```typescript
import { Endpoint } from '@broxus/js-core'
interface TokenInfo {
symbol: string
decimals: number
}
// Create endpoint with route parameters
const tokenEndpoint = new Endpoint<{ address: string }, undefined, TokenInfo>(
'/tokens/:address',
'https://api.example.com'
)
// Use the endpoint
const tokenInfo = await tokenEndpoint.fetch({ address: '0:abc...' })
console.log(tokenInfo.symbol) // 'USDT'
```
## Network Configuration
### `MasterChainConfig`
Model for accessing **masterchain** network configuration parameters including gas prices, limits, and message forwarding fees.
#### Features
- Gas prices and limits for masterchain
- Message forwarding prices
- Storage fee parameters
- Real-time configuration updates watching
#### Interface
```typescript
class MasterChainConfig extends SmartContractModel<MasterChainConfigData> {
readonly gasPrice: string
readonly gasLimit: string
readonly gasCredit: string
readonly blockGasLimit: string
readonly freezeDueLimit: string
readonly deleteDueLimit: string
readonly flatGasLimit: string
readonly flatGasPrice: string
readonly specialGasLimit: string
// Message forwarding prices
readonly lumpPrice: string
readonly bitPrice: string
readonly cellPrice: string
readonly ihrPriceFactor: string
readonly firstFrac: string
readonly nextFrac: string
}
```
#### Example
```typescript
import { MasterChainConfig } from '@broxus/js-core'
const masterConfig = await MasterChainConfig.create(
connection,
'-1:5555555555555555555555555555555555555555555555555555555555555555',
{ sync: true }
)
console.log(masterConfig.gasPrice) // '1000000'
console.log(masterConfig.gasLimit) // '1000000'
console.log(masterConfig.bitPrice) // '1'
console.log(masterConfig.cellPrice) // '500'
// Watch for configuration updates
await masterConfig.watch((data, state) => {
console.log('Gas price updated:', data.gasPrice)
})
```
### `ShardChainConfig`
Model for accessing **shardchain** (workchain) network configuration parameters including gas prices, limits, and message forwarding fees.
#### Features
- Gas prices and limits for workchain
- Message forwarding prices
- Storage fee parameters
- Real-time configuration updates watching
#### Interface
```typescript
class ShardChainConfig extends SmartContractModel<ShardChainConfigData> {
readonly gasPrice: string
readonly gasLimit: string
readonly gasCredit: string
readonly blockGasLimit: string
readonly freezeDueLimit: string
readonly deleteDueLimit: string
readonly flatGasLimit: string
readonly flatGasPrice: string
readonly specialGasLimit: string
// Message forwarding prices
readonly lumpPrice: string
readonly bitPrice: string
readonly cellPrice: string
readonly ihrPriceFactor: string
readonly firstFrac: string
readonly nextFrac: string
}
```
#### Example
```typescript
import { ShardChainConfig } from '@broxus/js-core'
const shardConfig = await ShardChainConfig.create(
connection,
'-1:5555555555555555555555555555555555555555555555555555555555555555',
{ sync: true }
)
console.log(shardConfig.gasPrice) // '1000000'
console.log(shardConfig.gasLimit) // '10000000'
// Use gas price for transaction calculations
const gasFee = BigInt(shardConfig.gasPrice) * BigInt(estimatedGas)
```
## Models
### `TvmToken`
Model for TVM-based token (TIP-3 standard) with reactive state management and blockchain synchronization.
#### Features
- Automatic token details synchronization (symbol, decimals, totalSupply, etc.)
- Real-time blockchain state watching
- Token wallet management
- Balance queries
#### Interface
```typescript
class TvmToken<T extends TvmTokenData | ObjectLiteral = TvmTokenData>
extends SmartContractModel<T & TvmTokenData> {
static Utils: TvmTokenUtils
static Wallet: typeof TvmTokenWallet
readonly symbol: string
readonly decimals: number
readonly name: string
readonly totalSupply?: string
readonly rootOwnerAddress?: Address
readonly verified?: boolean
wallet(ownerAddress: Address | string): Promise<TvmTokenWallet>
walletOf(ownerAddress: Address | string): Promise<Address>
balance(ownerAddress: Address | string): Promise<string | undefined>
}
```
#### Example
```typescript
import { TvmToken } from '@broxus/js-core'
const token = await TvmToken.create(
connection,
{
address: '0:a49cd4e158a9a15555e624759e2e4e766d22600b7800d891e46f9291f044a93d',
symbol: 'WEVER',
decimals: 9,
name: 'Wrapped EVER'
},
{ sync: true, watch: true }
)
console.log(token.symbol) // 'WEVER'
console.log(token.totalSupply) // '1000000000000000'
// Get user wallet
const userWallet = await token.wallet('0:user_address...')
console.log(userWallet.balance) // '100000000'
```
### `TvmTokenWallet`
Model for TVM token wallet with transfer and balance management capabilities.
#### Features
- Balance synchronization
- Token transfers
- Burn operations
- Wallet destruction
#### Interface
```typescript
class TvmTokenWallet extends SmartContractModel<TvmTokenWalletData> {
static Utils: TvmTokenWalletUtils
readonly balance?: string
readonly ownerAddress?: Address
readonly tokenAddress?: Address
transfer(params: TransferParams, args?: SendInternalParams): Promise<DelayedMessageExecution>
transferToWallet(params: TransferToWalletParams, args?: SendInternalParams): Promise<DelayedMessageExecution>
burn(params: BurnParams, args?: SendInternalParams): Promise<DelayedMessageExecution>
destroy(params: DestroyParams, args?: SendInternalParams): Promise<DelayedMessageExecution>
}
```
#### Example
```typescript
import { TvmTokenWallet } from '@broxus/js-core'
const wallet = await TvmTokenWallet.create(
connection,
{ address: '0:wallet_address...' },
{ sync: true },
provider
)
// Transfer tokens
await wallet.transfer({
amount: '1000000000',
recipient: '0:recipient_address...',
remainingGasTo: '0:sender_address...'
})
```
### `Dex`
Model for DEX root contract with pair/pool deployment and account management.
#### Features
- DEX account deployment
- Pair creation (constant product AMM)
- Stable pool creation
- Expected address calculation
#### Interface
```typescript
class Dex extends SmartContractModel<DexData> {
static Utils: DexUtils
readonly manager: Address
readonly owner: Address
readonly vault: Address
deployAccount(params: DexDeployAccountParams, args?: SendInternalParams): Promise<Transaction | undefined>
deployPair(params: DexDeployPairParams, args?: SendInternalParams): Promise<Transaction | undefined>
deployStablePool(params: DexDeployPoolParams, args?: SendInternalParams): Promise<Transaction | undefined>
getExpectedAccountAddress(params: { ownerAddress: Address | string }): Promise<Address>
getExpectedPairAddress(params: { leftRootAddress: Address | string, rightRootAddress: Address | string }): Promise<Address>
getExpectedPoolAddress(params: { roots: (Address | string)[] }): Promise<Address>
}
```
#### Example
```typescript
import { Dex } from '@broxus/js-core'
const dex = await Dex.create(
connection,
'0:dex_root_address...',
{ sync: true }
)
// Deploy user DEX account
await dex.deployAccount({
ownerAddress: '0:user_address...',
sendGasTo: '0:user_address...',
onTransactionSuccess: ({ input }) => {
console.log('Account deployed:', input.dexAccountAddress)
}
})
```
### `DexAccount`
Model for user's DEX account with liquidity management capabilities.
#### Features
- Token deposits and withdrawals
- Liquidity provision
- Pool management
- Balance tracking
#### Interface
```typescript
class DexAccount extends SmartContractModel<DexAccountData> {
static Utils: DexAccountUtils
readonly balances?: Map<string, string>
readonly ownerAddress: Address
readonly wallets?: Map<string, Address>
depositToken(params: DepositTokenParams, args?: SendInternalParams): Promise<Transaction | undefined>
withdrawToken(params: WithdrawTokenParams, args?: SendInternalParams): Promise<Transaction | undefined>
depositLiquidity(params: DepositLiquidityParams, args?: SendInternalParams): Promise<Transaction | undefined>
addPool(params: AddPoolParams, args?: SendInternalParams): Promise<Transaction | undefined>
}
```
#### Example
```typescript
import { DexAccount } from '@broxus/js-core'
const account = await DexAccount.create(
connection,
{ dex, ownerAddress: '0:user_address...' },
{ sync: true }
)
// Deposit tokens to account
await account.depositToken({
amount: '1000000000',
tokenAddress: '0:token_address...',
senderAddress: '0:user_address...',
recipientTokenWallet: '0:dex_account_wallet...',
remainingGasTo: '0:user_address...'
})
```
### `DexGasValues`
Model for querying DEX operation gas values and fees.
#### Interface
```typescript
class DexGasValues extends SmartContractModel {
static Utils: DexGasValuesUtils
getDeployAccountGas(): Promise<string>
getDepositToAccountGas(): Promise<string>
getAccountWithdrawGas(params: { deployWalletValue?: string }): Promise<string>
getAccountDepositGas(params: { autoChange: boolean }): Promise<string>
getAddPoolGas(params: { N: number }): Promise<string>
getDeployPoolGas(params: { N: number }): Promise<string>
}
```
### `DexPair`
Model for constant product AMM pair with liquidity operations.
#### Features
- Pair details synchronization
- Balance tracking
- Liquidity withdrawal
- Fee parameters
#### Interface
```typescript
class DexPair extends SmartContractModel<DexPairData> {
static Utils: DexPairUtils
readonly leftToken: TokenInfo
readonly rightToken: TokenInfo
readonly lpToken: TokenInfo
readonly balances?: Map<string, string>
readonly feeParams: DexPairFeeParams
readonly isActive?: boolean
syncBalances(options?: { force?: boolean }): Promise<Map<string, string>>
withdrawLiquidity(params: WithdrawParams, args?: SendInternalParams): Promise<Transaction | undefined>
}
```
#### Example
```typescript
import { DexPair } from '@broxus/js-core'
const pair = await DexPair.create(
connection,
{
dex,
leftRootAddress: '0:token1_address...',
rightRootAddress: '0:token2_address...'
},
{ sync: true }
)
console.log(pair.leftToken.symbol) // 'USDT'
console.log(pair.rightToken.symbol) // 'WEVER'
console.log(pair.balances) // Map { '0:token1...' => '1000000', ... }
```
### `DexStablePair`
Model for StableSwap pair (2 tokens) with reduced slippage for similar assets.
Similar to `DexPair` but optimized for stable pairs (e.g., USDT-USDC).
### `DexStablePool`
Model for StableSwap pool supporting multiple tokens (N-token pool).
#### Features
- Multi-token pool management
- Virtual price calculation
- Amplification coefficient
- Low slippage swaps for correlated assets
#### Interface
```typescript
class DexStablePool extends SmartContractModel<DexStablePoolData> {
static Utils: DexStablePoolUtils
readonly tokens: TokenInfo[]
readonly lpToken: TokenInfo
readonly balances?: Map<string, string>
readonly virtualPrice?: string
readonly feeParams: DexStablePoolFeeParams
withdrawLiquidity(params: WithdrawParams, args?: SendInternalParams): Promise<Transaction | undefined>
}
```
#### Example
```typescript
import { DexStablePool } from '@broxus/js-core'
const pool = await DexStablePool.create(
connection,
{
dex,
roots: [
'0:usdt_address...',
'0:usdc_address...',
'0:dai_address...'
]
},
{ sync: true }
)
console.log(pool.tokens.length) // 3
console.log(pool.virtualPrice) // '1.002134...'
```
## Other Models
The library also includes the following models:
- **Gauge** - Liquidity mining gauge contract
- **GaugeAccount** - User's gauge account for rewards
- **VoteEscrow** - Vote-escrowed token locking
- **VoteEscrowAccount** - User's vote escrow account
- **VoteEscrowDaoRoot** - DAO governance root
- **VoteEscrowProposal** - Governance proposal
- **TvmTokenFactory** - Token factory contract
- **VaultTokenWallet** - Vault token wallet
- **WrappedCurrencyVault** - Native currency wrapping vault
## Utilities
Each model comes with a static `Utils` class providing low-level ABI interaction methods:
```typescript
// Token utilities
TvmToken.Utils.getDetails(connection, address, state)
TvmToken.Utils.walletOf(connection, { ownerAddress, tokenAddress })
TvmToken.Utils.balance(connection, { walletAddress })
// DEX utilities
Dex.Utils.getExpectedPairAddress(connection, dexAddress, params, state)
DexPair.Utils.getBalances(connection, pairAddress, state)
DexPair.Utils.expectedExchange(connection, pairAddress, amount, state)
```
## License
MIT