Skip to content

Commit

Permalink
feat(swapping): first work version
Browse files Browse the repository at this point in the history
Supported:

- Healthcheck.
- Swapping.
- Revert.
- Tx.
- Chains.
- Routes.
- Bridging.
  • Loading branch information
phnaharris committed Dec 16, 2023
1 parent f457731 commit fcb4c1b
Show file tree
Hide file tree
Showing 36 changed files with 1,691 additions and 22 deletions.
21 changes: 21 additions & 0 deletions .github/codecov.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# ref: https://docs.codecov.com/docs/codecovyml-reference
coverage:
# Hold ourselves to a high bar
range: 85..100
round: down
precision: 1
status:
# ref: https://docs.codecov.com/docs/commit-status
project:
default:
# Avoid false negatives
threshold: 1%

# Test files aren't important for coverage
ignore:
- "tests"

# Make comments less noisy
comment:
layout: "files"
require_changes: true
12 changes: 12 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
on:
push:
branches: [main]
name: main
jobs:
codecov:
runs-on: ubuntu-latest
steps:
- name: Upload coverage reports to Codecov
uses: codecov/codecov-action@v3
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
19 changes: 15 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,31 @@ name = "symbiosis-api"
version = "0.1.0"
edition = "2021"
authors = ["phnaharris <phnanh.harris@gmail.com>"]
license = "GPL-3.0-or-later"
description = "A high-level binding for Symbiosis API, written in Rust."
repository = "https://github.com/phnaharris/symbiosis-api-rs.git"
keywords = ["symbiosis", "api", "swap", "bridge", "web3"]
categories = ["api-bindings", "development-tools"]
readme = "README.md"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
anyhow = "1.0.75"
ethers-core = { git = "https://github.com/gakonst/ethers-rs", features = [
"legacy",
] }
async-trait = "0.1.74"
bytes = "1.5.0"
chrono = { version = "0.4.31", features = ["serde"] }
derive_builder = "0.12.0"
ethers-core = { version = "2.0.11", features = ["legacy"] }
http = "0.2.9"
reqwest = { version = "0.11.22", features = ["json"] }
serde = "1.0.189"
serde_json = "1.0.107"
smart-default = "0.7.1"
serde_urlencoded = "0.7.1"
serde_with = "3.4.0"
tokio = { version = "1.33.0", features = ["macros", "rt-multi-thread"] }
tracing = "0.1.40"
url = "2.5.0"

[dev-dependencies]
tracing-subscriber = { version = "0.3.17", features = ["json", "env-filter"] }
73 changes: 67 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,71 @@
# Symbiosis API Binding Written in Rust (currently support api-v2)
# symbiosis-api

You can find the Swagger of Symbiosis API at
[this URL](https://api-v2.symbiosis.finance/crosschain/docs/).
[![Crates.io](https://img.shields.io/crates/v/symbiosis-api.svg)](https://crates.io/crates/symbiosis-api)
[![Documentation](https://docs.rs/symbiosis-api/badge.svg)](https://docs.rs/symbiosis-api/)
[![Codecov](https://codecov.io/github/phnaharris/symbiosis-api/coverage.svg?branch=main)](https://codecov.io/gh/phnaharris/symbiosis-api)
[![Build Status](https://github.com/phnaharris/symbiosis-api-rs/actions/workflows/main.yml/badge.svg)](https://github.com/phnaharris/symbiosis-api-rs/actions/workflows/main.yml)

# Installation
A high-level binding for Symbiosis API, written in Rust.

```bash
cargo add symbiosis-api
Symbiosis API allows you to integrate the functionalities of the Symbiosis Protocol into your
application, platform or protocol.

By integrating the Symbiosis API, you can quickly and effectively enable decentralized
cross-chain swaps and cross-chain liquidity management for your users.

This crate uses the [reqwest] crate for a convenient, higher-level HTTP Client, for request and
response, to and from Symbiosis, and [serde] for serialize and deserialize from and to
appropriate data format.

## Examples

Let's start out swapping from ETH on Ethereum to MNT on Mantle network.

```rust
use ethers_core::types::Chain;
use ethers_core::utils::parse_ether;
use symbiosis_api::cores::query::Query;
use symbiosis_api::{
api::swapping,
api::swapping::SwapResponse,
symbiosis::Symbiosis,
types::token::{Token, TokenAmount},
};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create the client.
let client = Symbiosis::new("");

// Create a simple endpoint.
let eth = Token::builder().build()?;
let mnt = Token::builder().chain_id(Chain::Mantle).build()?;
let token_amount_in = TokenAmount::builder()
.token(eth)
.amount(parse_ether(1)?)
.build()?;
let endpoint = swapping::SwappingExactIn::builder()
.token_amount_in(token_amount_in)
.token_out(mnt)
.from(
"0xe99E80EE4792395b2F639eE0661150D2b6B1996d"
.parse()
.unwrap(),
)
.to("0xe99E80EE4792395b2F639eE0661150D2b6B1996d"
.parse()
.unwrap())
.build()?;

// Call the endpoint. The return type decides how to represent the value.
let swapping: SwapResponse = endpoint.query(&client).await?;

println!("{:?}", swapping);

anyhow::Ok(())
}
```

For more examples, take a look at the `examples/` directory.

This crate design based on https://plume.benboeckel.net/~/JustAnotherBlog/designing-rust-bindings-for-rest-ap-is
8 changes: 8 additions & 0 deletions README.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# {{crate}}

[![Crates.io](https://img.shields.io/crates/v/symbiosis-api.svg)](https://crates.io/crates/symbiosis-api)
[![Documentation](https://docs.rs/symbiosis-api/badge.svg)](https://docs.rs/symbiosis-api/)
[![Codecov](https://codecov.io/github/phnaharris/symbiosis-api/coverage.svg?branch=main)](https://codecov.io/gh/phnaharris/symbiosis-api)
[![Build Status](https://github.com/phnaharris/symbiosis-api-rs/actions/workflows/main.yml/badge.svg)](https://github.com/phnaharris/symbiosis-api-rs/actions/workflows/main.yml)

{{readme}}
43 changes: 43 additions & 0 deletions examples/bridging_exact_in.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use ethers_core::types::Chain;
use ethers_core::utils::parse_ether;
use symbiosis_api::api::bridging::{self, BridgeResponse};
use symbiosis_api::cores::query::Query;
use symbiosis_api::{
symbiosis::Symbiosis,
types::token::{Token, TokenAmount},
};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create the client.
let client = Symbiosis::new("");

// Create a simple endpoint.
let usdc_eth = Token::builder()
.address("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48".into())
.decimals(6)
.build()?;
let token_amount_in = TokenAmount::builder()
.token(usdc_eth)
.amount(parse_ether(1)?)
.build()?;
let endpoint = bridging::BridgingExactIn::builder()
.token_amount_in(token_amount_in)
.chain_id_out(Chain::Boba)
.from(
"0xe99E80EE4792395b2F639eE0661150D2b6B1996d"
.parse()
.unwrap(),
)
.to("0xe99E80EE4792395b2F639eE0661150D2b6B1996d"
.parse()
.unwrap())
.build()?;

// Call the endpoint. The return type decides how to represent the value.
let bridging: BridgeResponse = endpoint.query(&client).await?;

println!("{:?}", bridging);

anyhow::Ok(())
}
21 changes: 21 additions & 0 deletions examples/chain.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use symbiosis_api::{
api::chain::{self, SymbiosisChain},
cores::query::Query,
symbiosis::Symbiosis,
};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create the client.
let client = Symbiosis::new("");

// Create a simple endpoint.
let endpoint = chain::GetSupportedChains;

// Call the endpoint. The return type decides how to represent the value.
let chains: Vec<SymbiosisChain> = endpoint.query(&client).await?;

println!("{:?}", chains);

anyhow::Ok(())
}
18 changes: 18 additions & 0 deletions examples/healthcheck.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use symbiosis_api::cores::query::Query;
use symbiosis_api::{api::healthcheck, symbiosis::Symbiosis};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create the client.
let client = Symbiosis::new("");

// Create a simple endpoint.
let endpoint = healthcheck::HealthCheck;

// Call the endpoint. The return type decides how to represent the value.
let healthcheck: Result<String, anyhow::Error> = endpoint.query(&client).await;

println!("{:?}", healthcheck);

anyhow::Ok(())
}
21 changes: 21 additions & 0 deletions examples/revert.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use symbiosis_api::api::revert::{Revert, RevertResponse};
use symbiosis_api::cores::query::Query;
use symbiosis_api::symbiosis::Symbiosis;

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create the client.
let client = Symbiosis::new("");

// Create a simple endpoint.
let endpoint = Revert::builder()
.transaction_hash(Default::default())
.build()?;

// Call the endpoint. The return type decides how to represent the value.
let revert: RevertResponse = endpoint.query(&client).await?;

println!("{:?}", revert);

anyhow::Ok(())
}
21 changes: 21 additions & 0 deletions examples/routes.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
use symbiosis_api::{
api::routes::{self, AvailableRoutesResponse},
cores::query::Query,
symbiosis::Symbiosis,
};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create the client.
let client = Symbiosis::new("");

// Create a simple endpoint.
let endpoint = routes::GetAvailableRoutes;

// Call the endpoint. The return type decides how to represent the value.
let routes: Vec<AvailableRoutesResponse> = endpoint.query(&client).await?;

println!("{:?}", routes);

anyhow::Ok(())
}
25 changes: 25 additions & 0 deletions examples/stucked.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use symbiosis_api::api::revert::{Stucked, StuckedResponse};
use symbiosis_api::cores::query::Query;
use symbiosis_api::symbiosis::Symbiosis;

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create the client.
let client = Symbiosis::new("");

// Create a simple endpoint.
let endpoint = Stucked::builder()
.address(
"0xe99E80EE4792395b2F639eE0661150D2b6B1996d"
.parse()
.unwrap(),
)
.build()?;

// Call the endpoint. The return type decides how to represent the value.
let stucked: Vec<StuckedResponse> = endpoint.query(&client).await?;

println!("{:?}", stucked);

anyhow::Ok(())
}
42 changes: 42 additions & 0 deletions examples/swapping_exact_in.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use ethers_core::types::Chain;
use ethers_core::utils::parse_ether;
use symbiosis_api::cores::query::Query;
use symbiosis_api::{
api::swapping,
api::swapping::SwapResponse,
symbiosis::Symbiosis,
types::token::{Token, TokenAmount},
};

#[tokio::main]
async fn main() -> Result<(), anyhow::Error> {
// Create the client.
let client = Symbiosis::new("");

// Create a simple endpoint.
let eth = Token::builder().build()?;
let mnt = Token::builder().chain_id(Chain::Mantle).build()?;
let token_amount_in = TokenAmount::builder()
.token(eth)
.amount(parse_ether(1)?)
.build()?;
let endpoint = swapping::SwappingExactIn::builder()
.token_amount_in(token_amount_in)
.token_out(mnt)
.from(
"0xe99E80EE4792395b2F639eE0661150D2b6B1996d"
.parse()
.unwrap(),
)
.to("0xe99E80EE4792395b2F639eE0661150D2b6B1996d"
.parse()
.unwrap())
.build()?;

// Call the endpoint. The return type decides how to represent the value.
let swapping: SwapResponse = endpoint.query(&client).await?;

println!("{:?}", swapping);

anyhow::Ok(())
}
Loading

0 comments on commit fcb4c1b

Please sign in to comment.