{"id":24995405,"url":"https://github.com/compolabs/spark-rs","last_synced_at":"2025-04-12T04:11:01.259Z","repository":{"id":164927854,"uuid":"640335488","full_name":"compolabs/spark-rs","owner":"compolabs","description":null,"archived":false,"fork":false,"pushed_at":"2024-05-25T11:56:29.000Z","size":216,"stargazers_count":5,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-25T23:41:45.345Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/compolabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-05-13T18:38:20.000Z","updated_at":"2024-05-25T11:56:30.000Z","dependencies_parsed_at":"2025-02-04T15:38:40.306Z","dependency_job_id":"fc629ac8-d11b-486d-8f91-7f0413379a56","html_url":"https://github.com/compolabs/spark-rs","commit_stats":null,"previous_names":["compolabs/spark-rs"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/compolabs%2Fspark-rs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/compolabs%2Fspark-rs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/compolabs%2Fspark-rs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/compolabs%2Fspark-rs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/compolabs","download_url":"https://codeload.github.com/compolabs/spark-rs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248514221,"owners_count":21116903,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-04T15:37:44.482Z","updated_at":"2025-04-12T04:11:01.235Z","avatar_url":"https://github.com/compolabs.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Spark Rust SDK\n\nThis repository contains the implementation of a predicate-based order book on the Fuel network, along with tests and Spark Rust SDK code.\n\n## Components\n### Predicate + Proxy\nThis system utilizes a predicate to represent an order that can be filled by anyone. To create an order, the maker sends a coin to the predicate root, which can be unlocked by any transaction that fulfills the order's conditions. These conditions, such as transferring a specific amount of an asset to a receiver, are encoded into the predicate bytecode, making them specific to that particular order.\n\nThe order owner can execute the order by spending the predicate coin in a transaction that satisfies the order's conditions. The owner has flexibility in how they use the predicate coin, as long as the transaction output meets the order's conditions and is the first output in the set.\n\nTo cancel an order, the maker can spend the predicate coin in a transaction that includes a single coin input signed by the receiver. The transaction consists of two inputs: the signed coin and the predicate coin.\n\nAlice provides information about the price and tokens in this predicate. Additionally, Alice can send additional money to the same predicate root to increase the change amount.\n\n### Spark Rust SDK\n\nDesigned for seamless integration with CLOB Spark using the Rust programming language, the Spark Rust SDK offers the following functionality:\n\n----------\n#### Getting Predicate Instance\nTo create a predicate, you need to provide the following configurables:\n```rust\nconfigurable {\n    ASSET0: b256 = ZERO_B256, // Asset that provides the maker (Alice)\n    ASSET1: b256 = ZERO_B256, // Asset that provides the taker (Bob)\n    MAKER: b256 = ZERO_B256, // Order owner\n    PRICE: u64 = 0, // asset1_amount / asset0_amount\n    ASSET0_DECIMALS: u8 = 1,\n    ASSET1_DECIMALS: u8 = 1,\n    PRICE_DECIMALS: u8 = 9, // optional\n    MIN_FULFILL_AMOUNT0: u64 = 1, // optional\n}\n```\nExample:\n```rust\nlet usdc_decimals = 6;\nlet uni_decimals = 9;\nlet amount0 = 1000_000_000_u64; // 1000 USDC\nlet amount1 = 300_000_000_000_u64; // 200 UNI\nlet price_decimals = 9;\n\nlet exp = (price_decimals + usdc_decimals - uni_decimals).into();\nlet price = amount1 * 10u64.pow(exp) / amount0;\nprintln!(\"Order price: {:?} UNI/USDC\", price);\n\nlet configurables = BuyPredicateConfigurables::new()\n    .set_ASSET0(Bits256::from_hex_str(\u0026usdc_asset_id.to_string()).unwrap())\n    .set_ASSET1(Bits256::from_hex_str(\u0026uni_asset_id.to_string()).unwrap())\n    .set_ASSET0_DECIMALS(usdc_decimals)\n    .set_ASSET1_DECIMALS(uni_decimals)\n    .set_MAKER(Bits256::from_hex_str(\u0026alice.address().hash().to_string()).unwrap())\n    .set_PRICE(price)\n    .set_PRICE_DECIMALS(price_decimals)\n    .set_MIN_FULFILL_AMOUNT0(0);\n\nlet predicate: Predicate = Predicate::load_from(PREDICATE_BIN_PATH)\n    .unwrap()\n    .with_configurables(configurables);\n```\n----------\n#### Order Creation\n```rust\nasync fn create_order(\n    wallet: \u0026WalletUnlocked, // Order owner\n    proxy_address: \u0026str, // Proxy contract address as a string\n\n\n    params: ProxySendFundsToPredicateParams, \n    amount: u64, // amount0\n) -\u003e Result\u003cFuelCallResponse\u003c()\u003e, fuels::prelude::Error\u003e;\n```\nExample:\n```rust\nlet params = ProxySendFundsToPredicateParams {\n    predicate_root: predicate.address().into(),\n    asset_0: usdc.contract_id().into(),\n    asset_1: uni.contract_id().into(),\n    maker: alice.address().into(),\n    min_fulfill_amount_0: 1,\n    price,\n    asset_0_decimals: 6,\n    asset_1_decimals: 9,\n    price_decimals: 9,\n};\n\ncreate_order(\u0026alice, PROXY_ADDRESS, params, amount0)\n    .await\n    .unwrap();\n```\n----------\n#### Order Cancellation\n```rust\npub async fn cancel_order(\n    wallet: \u0026WalletUnlocked, // Order owner\n    predicate: \u0026Predicate, // Predicate instance\n    asset0: AssetId,\n    amount0: u64,\n) -\u003e Result\u003cFuelCallResponse\u003c()\u003e, fuels::prelude::Error\u003e;\n```\nExample:\n```rust\ncancel_order(\u0026alice, \u0026predicate, usdc_asset_id, usdc_mint_amount)\n    .await\n    .unwrap();\n```\n----------\n#### Order Fulfillment\n```rust\nasync fn fulfill_order(\n    wallet: \u0026WalletUnlocked, // Taker\n    predicate: \u0026Predicate, // Predicate instance\n    owner_address: \u0026Bech32Address, \n    asset0: AssetId,\n    amount0: u64,\n    asset1: AssetId,\n    amount1: u64,\n) -\u003e Result\u003cFuelCallResponse\u003c()\u003e, fuels::prelude::Error\u003e;\n```\nExample:\n```rust\nfulfill_order(\n    \u0026bob,\n    \u0026predicate,\n    alice.address(),\n    usdc_asset_id,\n    usdc_mint_amount, // amount0\n    uni_asset_id,\n    uni_mint_amount, // amount0\n)\n.await\n.unwrap();\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcompolabs%2Fspark-rs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcompolabs%2Fspark-rs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcompolabs%2Fspark-rs/lists"}