{"id":36437822,"url":"https://github.com/dacadeorg/sui-move-deepbook","last_synced_at":"2026-01-18T13:00:31.093Z","repository":{"id":207587311,"uuid":"719343550","full_name":"dacadeorg/sui-move-deepbook","owner":"dacadeorg","description":null,"archived":false,"fork":false,"pushed_at":"2024-03-29T14:16:23.000Z","size":14,"stargazers_count":6,"open_issues_count":1,"forks_count":22,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-12-30T14:26:38.841Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Move","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/dacadeorg.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}},"created_at":"2023-11-16T00:59:21.000Z","updated_at":"2024-11-23T09:43:06.000Z","dependencies_parsed_at":"2023-11-16T16:05:48.241Z","dependency_job_id":"1484becd-9dab-40f8-b848-cc3ce194b4e0","html_url":"https://github.com/dacadeorg/sui-move-deepbook","commit_stats":null,"previous_names":["dacadeorg/sui-move-deepbook"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/dacadeorg/sui-move-deepbook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dacadeorg%2Fsui-move-deepbook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dacadeorg%2Fsui-move-deepbook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dacadeorg%2Fsui-move-deepbook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dacadeorg%2Fsui-move-deepbook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dacadeorg","download_url":"https://codeload.github.com/dacadeorg/sui-move-deepbook/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dacadeorg%2Fsui-move-deepbook/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28536686,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T10:13:46.436Z","status":"ssl_error","status_checked_at":"2026-01-18T10:13:11.045Z","response_time":98,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":"2026-01-11T20:00:22.343Z","updated_at":"2026-01-18T13:00:31.080Z","avatar_url":"https://github.com/dacadeorg.png","language":"Move","funding_links":[],"categories":["**8\\. Conclusion**"],"sub_categories":["**7.4 Security, Audits, and Formal Verification**"],"readme":"## Disclaimer: Use of Unaudited Code for Educational Purposes Only\nThis code is provided strictly for educational purposes and has not undergone any formal security audit. \nIt may contain errors, vulnerabilities, or other issues that could pose risks to the integrity of your system or data.\n\nBy using this code, you acknowledge and agree that:\n- No Warranty: The code is provided \"as is\" without any warranty of any kind, either express or implied. The entire risk as to the quality and performance of the code is with you.\n- Educational Use Only: This code is intended solely for educational and learning purposes. It is not intended for use in any mission-critical or production systems.\n- No Liability: In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the use or performance of this code.\n- Security Risks: The code may not have been tested for security vulnerabilities. It is your responsibility to conduct a thorough security review before using this code in any sensitive or production environment.\n- No Support: The authors of this code may not provide any support, assistance, or updates. You are using the code at your own risk and discretion.\n\nBefore using this code, it is recommended to consult with a qualified professional and perform a comprehensive security assessment. By proceeding to use this code, you agree to assume all associated risks and responsibilities.\n\n## Setup\n\n### Prerequisites\nBefore we proceed, we should install a couple of things. Also, if you are using a Windows machine, it's recommended to use WSL2.\n\nOn Ubuntu/Debian/WSL2(Ubuntu):\n```\nsudo apt update\nsudo apt install curl git-all cmake gcc libssl-dev pkg-config libclang-dev libpq-dev build-essential -y\n```\nOn MacOs:\n```\nbrew install curl cmake git libpq\n```\nIf you don't have `brew` installed, run this:\n```\n/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)\"\n```\n\nNext, we need rust and cargo:\n```\ncurl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh\n```\nif you get an error like this:\n```\nerror: could not amend shell profile: '/home/codespace/.config/fish/conf.d/rustup.fish': could not write rcfile file: '/home/codespace/.config/fish/conf.d/rustup.fish': No such file or directory (os error 2)\n```\nrun these commands and re-run the rustup script:\n```\nmkdir -p /home/codespace/.config/fish/conf.d\ntouch /home/codespace/.config/fish/conf.d/rustup.fish\n```\n\n### Install Sui\nIf you are using Github codespaces, it's recommended to use pre-built binaries rather than building them from source.\n\nTo download pre-built binaries, you should run `download-sui-binaries.sh` in the terminal. \nThis scripts takes three parameters (in this particular order) - `version`, `environment` and `os`:\n- sui version, for example `1.15.0`. You can lookup a more up-to-date version available here [SUI Github releases](https://github.com/MystenLabs/sui/releases).\n- `environment` - that's the environment that you are targeting, in our case it's `testnet`. Other available options are: `devnet` and `mainnet`.\n- `os` - name of the os. If you are using Github codespaces, put `ubuntu-x86_64`. Other available options are: `macos-arm64`, `macos-x86_64`, `ubuntu-x86_64`, `windows-x86_64` (not for WSL).\n\nTo donwload SUI binaries for codespace, run this command:\n```\n./download-sui-binaries.sh \"v1.21.1\" \"testnet\" \"ubuntu-x86_64\"\n```\nand restart your terminal window.\n\nIf you prefer to build the binaries from source, run this command in your terminal:\n```\ncargo install --locked --git https://github.com/MystenLabs/sui.git --branch testnet sui\n```\n\n### Install dev tools (not required, might take a while when installin in codespaces)\n```\ncargo install --git https://github.com/move-language/move move-analyzer --branch sui-move --features \"address32\"\n\n```\n\n### Run a local network\nTo run a local network with a pre-built binary (recommended way), run this command:\n```\nRUST_LOG=\"off,sui_node=info\" sui-test-validator\n```\n\nOptionally, you can run it from sources.\n```\ngit clone --branch testnet https://github.com/MystenLabs/sui.git\n\ncd sui\n\nRUST_LOG=\"off,sui_node=info\" cargo run --bin sui-test-validator\n```\n\n### Install SUI Wallet (optionally)\n```\nhttps://chrome.google.com/webstore/detail/sui-wallet/opcgpfmipidbgpenhmajoajpbobppdil?hl=en-GB\n```\n\n### Configure connectivity to a local node\nOnce the local node is running (using `sui-test-validator`), you should the url of a local node - `http://127.0.0.1:9000` (or similar).\nAlso, another url in the output is the url of a local faucet - `http://127.0.0.1:9123`.\n\nNext, we need to configure a local node. To initiate the configuration process, run this command in the terminal:\n```\nsui client active-address\n```\nThe prompt should tell you that there is no configuration found:\n```\nConfig file [\"/home/codespace/.sui/sui_config/client.yaml\"] doesn't exist, do you want to connect to a Sui Full node server [y/N]?\n```\nType `y` and in the following prompts provide a full node url `http://127.0.0.1:9000` and a name for the config, for example, `localnet`.\n\nOn the last prompt you will be asked which key scheme to use, just pick the first one (`0` for `ed25519`).\n\nAfter this, you should see the ouput with the wallet address and a mnemonic phrase to recover this wallet. You can save so later you can import this wallet into SUI Wallet.\n\nAdditionally, you can create more addresses and to do so, follow the next section - `Create addresses`.\n\n### Testnet configuration\n\nFor the sake of this tutorial, let's add a testnet node:\n```\nsui client new-env --rpc https://fullnode.testnet.sui.io:443 --alias testnet\n```\nand switch to `testnet`:\n```\nsui client switch --env testnet\n```\n\n### Create addresses\nFor this tutorial we need two separate addresses. To create an address run this command in the terminal:\n```\nsui client new-address ed25519\n```\nwhere:\n- `ed25519` is the key scheme (other available options are: `ed25519`, `secp256k1`, `secp256r1`)\n\nAnd the output should be similar to this:\n```\n╭─────────────────────────────────────────────────────────────────────────────────────────────────╮\n│ Created new keypair and saved it to keystore.                                                   │\n├────────────────┬────────────────────────────────────────────────────────────────────────────────┤\n│ address        │ 0x05db1e318f1e4bc19eb3f2fa407b3ebe1e7c3cd8147665aacf2595201f731519             │\n│ keyScheme      │ ed25519                                                                        │\n│ recoveryPhrase │ lava perfect chef million beef mean drama guide achieve garden umbrella second │\n╰────────────────┴────────────────────────────────────────────────────────────────────────────────╯\n```\nUse `recoveryPhrase` words to import the address to the wallet app.\n\n\n### Get localnet SUI tokens\n```\ncurl --location --request POST 'http://127.0.0.1:9123/gas' --header 'Content-Type: application/json' \\\n--data-raw '{\n    \"FixedAmountRequest\": {\n        \"recipient\": \"\u003cADDRESS\u003e\"\n    }\n}'\n```\n`\u003cADDRESS\u003e` - replace this by the output of this command that returns the active address:\n```\nsui client active-address\n```\n\nYou can switch to another address by running this command:\n```\nsui client switch --address \u003cADDRESS\u003e\n```\nabd run the HTTP request to mint some SUI tokens to this account as well.\n\nAlso, you can top up the balance via the wallet app. To do that, you need to import an account to the wallet.\n\n### Get testnet SUI tokens\nAfter you switched to `testnet`, run this command to get 1 testnet SUI:\n```\nsui client faucet\n```\nit will use the the current active address and the current active network.\n\n## Build and publish a smart contract\n\n### Build package\nTo build tha package, you should run this command:\n```\nsui move build\n```\n\nIf the package is built successfully, the next step is to publish the package:\n### Publish package\n```\nsui client publish --gas-budget 100000000 --json\n```\nHere we do not specify the path to the package dir so it will use the current dir - `.`\n\nAfter the contract is published we need to extract some object ids from the output. Here is the list of env variable that we source in the current shell and their values:\n- `PACKAGE_ID` - the id of the published package. The json path to it is `.objectChanges[].packageId`\n- `ORIGINAL_UPGRADE_CAP_ID` - the upgrade cap id that we might need if we find ourselves in the situation when we need to upgrade the contract. Path: `.objectChanges[].objectId` where `.objectChanges[].objectType` is  `0x2::package::UpgradeCap`\n- `SUI_FEE_COIN_ID` the id of the SUI coin that we are going to use to pay the fee for the pool creation. Take any from the output of this command: `sui client gas --json`\n- `ACCOUNT_ID1` - currently active address, assign the output of this command: `sui client active-address`. Repeat the same for the secondary account and assign the output to `ACCOUNT_ID1`\n- `CLOCK_OBJECT_ID` - the id of the `Clock` object, default to `0x6`\n- `BASE_COIN_TYPE` - the type of the SUI coin, default to `0x2::sui::SUI`\n- `QUOTE_COIN_TYPE` - the type of the quote coin that we deployed for the sake of this tutorial. The coin is `WBTC` in the `wbtc` module in the `$PACKAGE_ID` package. So the value will look like this: `\u003cPACKAGE_ID\u003e::wbtc::WBTC`\n- `WBTC_TREASURY_CAP_ID` it's the treasury cap id that is needed for token mint operations. In the publish output you should look for the object with `objectType` `0x2::coin::TreasuryCap\u003c$PACKAGE_ID::wbtc::WBTC\u003e` (replace `$PACKAGE_ID` with the actual package id) and this object also has `objectId` - that's the value that we are looking for.\n\n## Interact with the contract\n\n### Create pool\n\nNow we create a pool:\n```\nsui client call --package $PACKAGE_ID  --module book --function new_pool --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --args $SUI_FEE_COIN_ID --gas-budget 10000000000 --json\n```\nAfter the pool is created, check the output and locate the object with the type `0xdee9::clob_v2::Pool\u003c$BASE_COIN_TYPE, $QUOTE_COIN_TYPE\u003e` (`$BASE_COIN_TYPE`, `$QUOTE_COIN_TYPE` - replace with the actual values) and assign the value from the `objectId` property to `$POOL_ID`.\n\nIn this case, the pool is created with the default values for `REFERENCE_TAKER_FEE_RATE` and `REFERENCE_MAKER_REBATE_RATE` where the former one is `2_500_000` (0.25%) and the latter one is `1_500_000` (0.15%).\n\nIn case you'd like to customize these values, you should use `create_customized_pool`:\n```\npublic fun create_customized_pool\u003cBaseAsset, QuoteAsset\u003e(\n        tick_size: u64,\n        lot_size: u64,\n        taker_fee_rate: u64,\n        maker_rebate_rate: u64,\n        creation_fee: Coin\u003cSUI\u003e,\n        ctx: \u0026mut TxContext,\n    )\n```\n\n### Create custodian account\nFor limit orders we need to have custodian accounts (more details [here](https://docs.sui-deepbook.com/deepbook-sdk/trade-and-swap#2.1.2-create-custodian-account)):\n```\nsui client call --package $PACKAGE_ID  --module book --function new_custodian_account  --gas-budget 10000000000\n```\nIn the publish output you should look for the object with `objectType` `0xdee9::custodian_v2::AccountCap` and assign the value `objectId` to the env variable `ACCOUNT1_CAP`.\nRepeat the same for the secondary account that we created previously (use `sui client switch --address \u003cADDRESS\u003e`) and the output assign to ACCOUNT2_CAP.\n\n### Mint WBTC token\nNow we need to mint WBTC tokens. Switch to the address that you've used to publish the contract and run this command to mint tokens:\n```\nsui client call --function mint --module wbtc --package $PACKAGE_ID  --args $WBTC_TREASURY_CAP_ID \"10000000000\" $ACCOUNT_ID1 --gas-budget 10000000 --json\n```\nRe-run the same command but change `ACCOUNT_ID1` to `ACCOUNT_ID2`.\nCheck the output and look for an object with `objectType` that has a value like this `String(\"0x2::coin::Coin\u003c$PACKAGE_ID::wbtc::WBTC\u003e\")` and get the value of `objectId` and assign it ot `ACCOUNT1_WBTC_OBJECT_ID`.\n\n### Make deposits\nNow we need to make deposits (both base and quote) to `ACCOUNT1_CAP_ID` (for limit orders).\nFirst, prepare the `BASE_COIN_ID` variable by assigning the output of `sui client gas` (any of the values) and the run this command:\n```\nsui client call --package $PACKAGE_ID  --module book --function make_base_deposit  --args $POOL_ID $BASE_COIN_ID $ACCOUNT1_CAP_ID --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n```\n\nNow deposit the quote coin:\n```\nsui client call --package $PACKAGE_ID  --module book --function make_quote_deposit  --args $POOL_ID $ACCOUNT1_WBTC_OBJECT_ID $ACCOUNT1_CAP_ID --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n```\nThe arguments strictly match the signature of the function that is called.\n\n### Place limit orders\nLet's place multiple limit orders:\n```\n sui client call --package $PACKAGE_ID  --module book --function place_limit_order  --args \"$POOL_ID\" 42 5000000000 200 0 true 1888824053000 0 $CLOCK_OBJECT_ID \"$ACCOUNT1_CAP\" --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n \n sui client call --package $PACKAGE_ID  --module book --function place_limit_order  --args \"$POOL_ID\" 42 5000000000 300 0 true 1888824053000 0 $CLOCK_OBJECT_ID \"$ACCOUNT1_CAP\" --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n \n sui client call --package $PACKAGE_ID  --module book --function place_limit_order  --args \"$POOL_ID\" 42 2000000000 1000 0 true 1888824053000 0 $CLOCK_OBJECT_ID \"$ACCOUNT1_CAP\" --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n \n sui client call --package $PACKAGE_ID  --module book --function place_limit_order  --args \"$POOL_ID\" 42 20000000000 1000 0 false 1888824053000 0 $CLOCK_OBJECT_ID \"$ACCOUNT1_CAP\" --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n```\nwhere:\n- `1888824053000` is a timestamp somewhere in the future, to avoid order expiration for the sake of simplicity\n- `42` is an id of the order, can be any number.\n\nNotice that these commands are mostly the same except for the arguments for `priect`, `quantity` and `is_bid`.\n\n`is_bid` indicated whether you want to sell or buy assets. More details here: [2.1.4 Place Limit Order](https://docs.sui-deepbook.com/deepbook-sdk/trade-and-swap).\n\n### Place market order\nNow we need to place a market order to buy/sell assets. We are going to do this using our secondary account.\n\nFirst, switch to the secondary account:\n```\nsui client switch --address \u003cADDRESS\u003e\n```\n\nNow place the order:\n```\nsui client call --package $PACKAGE_ID  --module book --function place_base_market_order  --args $POOL_ID $ACCOUNT2_CAP $SUI_COIN_ID 942 \"false\" $CLOCK_OBJECT_ID --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n```\nwhere:\n- `942` is an id of the order, can be any number\n\nCheck the output of this command and find the `balanceChanges` array where the balance changes will be listed, you should see the exchanged assets. Also, you can double-check this in the wallet app.\nThe amount of tokens won't be precisly the number you expect because there is a deepbook fee, more details [here](https://docs.sui-deepbook.com/deepbook-fee-structure).\n\nMore info about the market orders can be found [here](https://docs.sui-deepbook.com/deepbook-sdk/trade-and-swap#2.2-place-market-order).\n\n### Swap order\nNow let's try to run a swap order. \nRe-run the commands the place limit orders (using the first account) and the switch back to the secondary account, and run the swap order:\n\n```\nsui client call --package $PACKAGE_ID  --module book --function swap_exact_base_for_quote  --args \"$POOL_ID\" 42 $ACCOUNT2_CAP 1500 $BASE_COIN_ID $CLOCK_OBJECT_ID --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n```\nwhere:\n- `BASE_COIN_ID` is the id of the SUI coin, get the value from `sui client gas --json`\n- `42` is an id of the order, can be any number\n\nCheck the output of this command and find the `balanceChanges` array where the balance changes will be listed, you should see the exchanged assets. Also, you can double-check this in the wallet app.\n\n### Withdrap from the account cap\n\nAfter you deposited either base or quote assets you can withdraw them back to your main address:\n\n#### withdraw base\n```\nsui client call --package $PACKAGE_ID  --module book --function withdraw_base --args \"$POOL_ID\" 100 $ACCOUNT2_CAP --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n```\n\n#### withdraw quote\n```\nsui client call --package $PACKAGE_ID  --module book --function withdraw_quote --args \"$POOL_ID\" 100 $ACCOUNT2_CAP --type-args $BASE_COIN_TYPE $QUOTE_COIN_TYPE --gas-budget 10000000000 --json\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdacadeorg%2Fsui-move-deepbook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdacadeorg%2Fsui-move-deepbook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdacadeorg%2Fsui-move-deepbook/lists"}