https://github.com/balancednetwork/balanced-intents-sdk
https://github.com/balancednetwork/balanced-intents-sdk
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/balancednetwork/balanced-intents-sdk
- Owner: balancednetwork
- License: mit
- Created: 2024-10-22T02:35:06.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-11-25T09:44:21.000Z (over 1 year ago)
- Last Synced: 2025-04-05T18:51:29.817Z (about 1 year ago)
- Language: TypeScript
- Size: 42 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Balanced Intent Solver SDK (Alpha)
Balanced Intent Solver SDK provides abstractions to assist you with interacting with the cross-chain Intent Smart Contracts and Solver.
**Note** SDK is currently in alpha testing stage and is subject to change!
## Installation
### NPM
Installing through npm:
`npm i --save @balanced/solver-sdk`
**NOTE** Package is not yet published to the npm registry!!!
### Local
Package can be locally installed by following this steps:
1. Clone this repository to your local machine.
2. `cd` into repository folder location.
3. Execute `npm install` command in your CLI to install dependencies.
4. Execute `npm run build` to build the package.
5. In your app repository `package.json` file, define dependency named `"@balanced/solver-sdk"` under `"dependencies"`.
Instead of version define absolute path to your SDK repository `"file:"` (e.g. `"file:/Users/dev/balanced-solver-sdk"`).
Full example: `"@balanced/solver-sdk": "file:/Users/dev/balanced-solver-sdk"`.
## Local Development
How to setup local development
1. Clone repository.
2. Make sure you have [Node.js](https://nodejs.org/en/download/package-manager) v18+ and corresponding npm installed on your system.
3. Execute `npm install` command in your CLI to install dependencies.
4. Make code changes.
1. Do not forget to export TS files in same folder `index.ts`.
2. Always import files using `.js` postfix.
5. Before commiting execute `npm run prepublishOnly` in order to verify build, format and exports.
## Load SDK Config
SDK includes predefined configurations of supported chains, tokens and other relevant information for the client to consume.
```typescript
import { ChainName, ChainConfig, chainConfig, Token, IntentService } from "@balanced/solver-sdk"
// all supported Intent chains
const supportedChains: ChainName[] = IntentService.getSupportedChains()
// retrieve arbitrum chain config
const arbChainConfig: EvmChainConfig = IntentService.getChainConfig("arb")
// example of how to construct token per chain map using supported chains array
const supportedTokensPerChain: Map = new Map(
supportedChains.map((chain) => {
return [chain, IntentService.getChainConfig(chain).supportedTokens]
}),
)
// example of how to construct chain name to chain config map
const chainConfigs: Map = new Map(
supportedChains.map((chain) => {
return [chain, IntentService.getChainConfig(chain)]
}),
)
```
## Request a Quote
Requesting a quote should require you to just consume user input amount and converting it to the appropriate token amount (scaled by token decimals).
All the required configurations (chain id [nid], token decimals and address) should be loaded as described in [Load SDK Config](#load-sdk-config).
```typescript
import { IntentService } from "@balanced/solver-sdk"
const quoteResult = await IntentService.getQuote({
token_src: "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
token_src_blockchain_id: "0xa4b1.arbitrum",
token_dst: "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI",
token_dst_blockchain_id: "sui",
src_amount: "100000000000000000",
})
/**
* Example response (quoteResult)
* {
* "ok": true,
* "value": {
* "output": {
* "expected_output":"1000000000000", // to be used in create intent order as toAmount
* "uuid":"e2795d2c-14a5-4d18-9be6-a257d7c9d274" // to be used in create intent order as quote_uuid
* }
* }
* }
*/
```
## Initialising Providers
SDK abstracts away the wallet and public RPC clients using `ChainProviderType` TS type which can be one of the following:
- `EvmProvider`: Provider used for EVM type chains (ETH, BSC, etc..). Implemented using [viem](https://viem.sh/docs/clients/wallet#json-rpc-accounts).
- `SuiProvider`: Provider used for SUI type chains (SUI). Implemented using [@mysten/sui](https://github.com/MystenLabs/sui) and [@mysten/wallet-standard](https://docs.sui.io/standards/wallet-standard).
Optionally, you can supply EVM providers (wallet and public clients) yourself (see `EvmInitializedConfig`).
SUI accepts only initialized Wallet, Account and Client.
Providers are used to request wallet actions (prompts wallet extension) and make RPC calls to the RPC nodes.
EVM Provider example:
```typescript
import { EvmProvider } from "@balanced/solver-sdk"
// NOTE: user address should be provided by application when user connects wallet
const evmProvider = new EvmProvider({
userAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a",
chain: "arb",
provider: (window as any).ethereum,
})
```
SUI Provider example (uses [SUI dApp Kit](https://sdk.mystenlabs.com/dapp-kit/):
```typescript
import { SuiProvider } from "@balanced/solver-sdk"
import { useCurrentWallet, useCurrentAccount } from "@mysten/dapp-kit"
const account = useCurrentAccount()
const { currentWallet, connectionStatus } = useCurrentWallet()
// check that wallet is connected and account is defined
if (connectionStatus === "connected" && account) {
const suiProvider = new SuiProvider({ wallet, account, client })
} else {
throw new Error("Wallet or Account undefined. Please connect wallet and select account.")
}
```
## Create Intent Order
Creating Intent Order requires creating provider for the chain that intent is going to be created on (`fromChain`).
Example for ARB -> SUI Intent Order:
```typescript
import { IntentService, EvmProvider, CreateIntentOrderPayload, IntentStatusCode } from "@balanced/solver-sdk"
// create EVM provider because "arb" is of ChainType "evm" (defined in ChainConfig type - see section Load SDK Config)
// NOTE: window can only be accessed client side (browser)
const evmProvider = new EvmProvider({
userAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a",
chain: "arb",
provider: (window as any).ethereum,
})
const intentOrderPayload: CreateIntentOrderPayload = {
quote_uuid: "a0dd7652-b360-4123-ab2d-78cfbcd20c6b",
fromAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a", // address we are sending funds from (fromChain)
toAddress: "0x81600ec58a2efd97f41380370cddf25b7a416d03ee081552becfa9710ea30878", // destination address where funds are transfered to (toChain)
fromChain: "arb", // ChainName
toChain: "sui", // ChainName
token: "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
amount: BigInt("100000000000000000"),
toToken: "0x0000000000000000000000000000000000000000000000000000000000000002::sui::SUI",
toAmount: BigInt("1000000000000"),
} as const
// checks if token transfer amount is approved (required for EVM, can be skipped for SUI as it defaults to true)
const isAllowanceValid = await IntentService.isAllowanceValid(intentOrderPayload, evmProvider)
if (isAllowanceValid.ok) {
if (!isAllowanceValid.value) {
// allowance invalid, prompt approval
const approvalResult = await IntentService.approve(
"0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
BigInt("100000000000000000"),
IntentService.getChainConfig("arb").intentContract,
evmProvider,
)
if (approvalResult.ok) {
const executionResult = await IntentService.executeIntentOrder(intentOrderPayload, evmProvider)
if (executionResult.ok) {
const intentStatus = await IntentService.getStatus({
task_id: executionResult.value.task_id,
})
if (intentStatus.ok) {
console.log(intentStatus)
/**
* Example status
* {
* "ok": true,
* "value": {
* "output": {
* "status":3, // use IntentStatusCode to map status code
* "tx_hash":"0xabcdefasdasdsafssadasdsadsadasdsadasdsadsa"
* }
* }
* }
*/
} else {
// handle error
}
} else {
// handle error
}
} else {
// handle error
}
} else {
// allowance is valid
const executionResult = await IntentService.executeIntentOrder(intentOrderPayload, evmProvider)
// ...rest of result check and status check logic as above
}
} else {
// handle error
}
```
## Cancel Intent Order
Active Intent Order can be cancelled using order ID obtained as explained in [Get Intent Order](#get-intent-order).
Example cancel order:
```typescript
import { IntentService, SwapOrder, EvmProvider } from "@balanced/solver-sdk"
const evmProvider = new EvmProvider({
userAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a",
chain: "arb",
provider: (window as any).ethereum
})
const intentOrder: Result = await IntentService.getOrder(
"0xabcdefasdasdsafssadasdsadsadasdsadasdsadsa",
IntentService.getChainConfig("arb").intentContract,
evmProvider,
)
if (intentOrder.ok) {
const cancelResult: Result = await IntentService.cancelIntentOrder(
intentOrder.value.id,
"arb",
evmProvider,
)
if (cancelResult.ok) {
const txHash = cancelResult.value
..
} else {
// handle error
}
} else {
// handle error
}
```
## Get Intent Order
After the Intent order is created (`executeIntentOrder`), the resulting `txHash` can be used to query created on-chain order data.
Intent order id is assigned as a part of tx execution, thus if you want to grab an actual order id to be potentially canceled in future
you should invoke `IntentService.getOrder(..)` function.
Example get order:
```typescript
import { IntentService, SwapOrder, EvmProvider } from "@balanced/solver-sdk"
const evmProvider = new EvmProvider({
userAddress: "0x601020c5797Cdd34f64476b9bf887a353150Cb9a",
chain: "arb",
provider: (window as any).ethereum,
})
const intentOrder: Result = await IntentService.getOrder(
"0xabcdefasdasdsafssadasdsadsadasdsadasdsadsa",
IntentService.getChainConfig("arb").intentContract,
evmProvider,
)
```
## Get Intent Status
After Intent Order is created, the resulting `task_id` can be used to query the status of the task.
Example status check:
```typescript
import { IntentService } from "@balanced/solver-sdk"
const intentStatus = await IntentService.getStatus({
task_id: "a0dd7652-b360-4123-ab2d-78cfbcd20c6b",
})
/**
* Example intentStatus response
* {
* "ok": true,
* "value": {
* "output": {
* "status":3, // use IntentStatusCode to map status code
* "tx_hash":"0xabcdefasdasdsafssadasdsadsadasdsadasdsadsa"
* }
* }
* }
*/
```