{"id":13572736,"url":"https://github.com/scallop-io/sui-kit","last_synced_at":"2026-01-18T04:39:46.750Z","repository":{"id":157806152,"uuid":"621609510","full_name":"scallop-io/sui-kit","owner":"scallop-io","description":"Toolkit for interacting with SUI network in typescript","archived":false,"fork":false,"pushed_at":"2025-10-24T16:50:32.000Z","size":954,"stargazers_count":188,"open_issues_count":4,"forks_count":37,"subscribers_count":16,"default_branch":"main","last_synced_at":"2025-11-23T14:00:00.509Z","etag":null,"topics":["sui","typescript"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scallop-io.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-03-31T02:34:53.000Z","updated_at":"2025-10-28T12:12:47.000Z","dependencies_parsed_at":null,"dependency_job_id":"956c310f-8591-4bb1-a012-c1a6a5e10346","html_url":"https://github.com/scallop-io/sui-kit","commit_stats":null,"previous_names":[],"tags_count":43,"template":false,"template_full_name":null,"purl":"pkg:github/scallop-io/sui-kit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scallop-io%2Fsui-kit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scallop-io%2Fsui-kit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scallop-io%2Fsui-kit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scallop-io%2Fsui-kit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scallop-io","download_url":"https://codeload.github.com/scallop-io/sui-kit/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scallop-io%2Fsui-kit/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28529917,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-18T00:39:45.795Z","status":"online","status_checked_at":"2026-01-18T02:00:07.578Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["sui","typescript"],"created_at":"2024-08-01T15:00:18.639Z","updated_at":"2026-01-18T04:39:46.741Z","avatar_url":"https://github.com/scallop-io.png","language":"TypeScript","funding_links":[],"categories":["SDKs","Client SDKs \u0026 Libraries"],"sub_categories":["Sui SDKs","Client SDKs"],"readme":"# Toolkit for interacting with SUI network\n\n## Features\n\n- [x] Transfer SUI, Custom Coin and objects.\n- [x] Move call\n- [x] Programmable transaction\n- [x] Query on-chain data\n- [x] HD wallet multi-accounts\n\n## Pre-requisites\n\n```bash\nnpm install @scallop-io/sui-kit\n```\n\n## How to use\n\n### Init SuiKit\n\n```typescript\nimport { SuiKit } from '@scallop-io/sui-kit';\n\n// The following types of secret key are supported:\n// 1. base64 key from SUI cli keystore file\n// 2. 32 bytes hex key\n// 3. 64 bytes legacy hex key\nconst secretKey = '\u003cSecret key\u003e';\nconst suiKit1 = new SuiKit({ secretKey });\n\n// 12 or 24 words mnemonics\nconst mnemonics = '\u003cMnemonics\u003e';\nconst suiKit2 = new SuiKit({ mnemonics });\n\n// It will create a HD wallet with a random mnemonics\nconst suiKit3 = new SuiKit();\n\n// Override options\nconst suiKit = new SuiKit({\n  mnemonics: '\u003cMnemonics\u003e',\n  // 'testnet' | 'mainnet' | 'devnet', default is 'devnet'\n  networkType: 'testnet',\n  // the fullnode url, default is the preconfig fullnode url for the given network type\n  // It will rotate the fullnode when the current fullnode is not available\n  fullnodeUrls: '[\u003cSUI fullnode1\u003e, \u003cSUI fullnode2\u003e]',\n  // the faucet url, default is the preconfig faucet url for the given network type\n  faucetUrl: '\u003cSUI faucet url\u003e',\n});\n```\n\n### Transfer\n\nYou can use SuiKit to transfer SUI, custom coins, and any objects.\n\n```typescript\nconst recipient1 = '0x123'; // repace with real address\nconst recipient2 = '0x456'; // repace with real address\n\n// transfer SUI to single recipient\nawait suiKit.transferSui(recipient1, 1000);\n// transfer SUI to multiple recipients\nawait suiKit.transferSuiToMany([recipient1, recipient2], [1000, 2000]);\n\nconst coinType = '\u003cpkgId\u003e::custom_coin::CUSTOM_COIN';\n// Transfer custom coin to single recipient\nawait suiKit.transferCoin(recipient1, 1000, coinType);\n// Transfer custom coin to multiple recipients\nawait suiKit.transferCoinToMany(\n  [recipient1, recipient2],\n  [1000, 2000],\n  coinType\n);\n\n// Transfer objects\nconst objectIds = ['\u003cobjId1\u003e', '\u003cobjId2\u003e'];\nawait suiKit.transferObjects(objectIds, recipient1);\n```\n\n### Stake SUI\n\nYou can use SuiKit to stake SUI.\n\n```typescript\n/**\n * This is an example of using SuiKit to stake SUI\n */\nconst stakeAmount = 1000;\nconst validatorAddress = '0x123'; // replace with real address\nsuiKit.stakeSui(stakeAmount, validatorAddress).then(() =\u003e {\n  console.log('Stake SUI success');\n});\n```\n\n### Move call\n\nYou can use SuiKit to call move functions.\n\n```typescript\nconst res = await suiKit.moveCall({\n  target: '0x2::coin::join',\n  arguments: [coin0, coin1],\n  typeArguments: [coinType],\n});\nconsole.log(res);\n```\n\nHow to pass arguments?\nSuppose you have a move function like this:\n\n```move\npublic entry fun test_args(\n  addrs: vector\u003caddress\u003e,\n  name: vector\u003cu8\u003e,\n  numbers: vector\u003cu64\u003e,\n  bools: vector\u003cbool\u003e,\n  coins: vector\u003cCoin\u003cSUI\u003e\u003e,\n  ctx: \u0026mut TxContext,\n) {\n  // ...\n}\n```\n\nYou can pass the arguments like this:\n\n```typescript\nconst addr1 =\n  '0x656b875c9c072a465048fc10643470a39ba331727719df46c004973fcfb53c95';\nconst addr2 =\n  '0x10651e50cdbb4944a8fd77665d5af27f8abde6eb76a12b97444809ae4ddb1aad';\nconst coin1 =\n  '0xd4a01b597b87986b04b65e04049499b445c0ee901fe8ba310b1cf29feaa86876';\nconst coin2 =\n  '0x4d4a01b597b87986b04b65e04049499b445c0ee901fe8ba310b1cf29feaa8687';\nsuiKit.moveCall({\n  target: `${pkgId}::module::test_args`,\n  arguments: [\n    // pass vector\u003caddress\u003e, need to specify the vecType as 'address'\n    { value: [addr1, addr2], vecType: 'address' },\n    // pass vector\u003cu8\u003e, need to specify the vecType as 'u8'\n    { value: [10, 20], vecType: 'u8' },\n    // pass vector\u003cu64\u003e, default vecType for number array is 'u64', so no need to specify\n    [34324, 234234],\n    // pass vector\u003cbool\u003e, default vecType for boolean array is 'bool', so no need to specify\n    [true, false],\n    // pass vector\u003cCoin\u003cSUI\u003e\u003e, no need to specify the vecType for object array\n    [coin1, coin2],\n  ],\n});\n```\n\nAll the supported types are:\n\n- address\n- u8\n- u16\n- u32\n- u64\n- u128\n- u256\n- bool\n- object\n\n### Programmable transaction\n\nWith programmable transaction, you can send a transaction with multiple actions.\nThe following is an example using flashloan to make arbitrage.\n(check [here](./examples/sample_move/custom_coin/sources/dex.move) for the corresponding Move contract code)\n\n```typescript\nimport { SuiKit, SuiTxBlock } from '@scallop-io/sui-kit';\nimport * as process from 'process';\nimport * as dotenv from 'dotenv';\ndotenv.config();\n\nconst treasuryA =\n  '0xe5042357d2c2bb928f37e4d12eac594e6d02327d565e801eaf9aca4c7340c28c';\nconst treasuryB =\n  '0xdd2f53171b8c886fad20e0bfecf1d4eede9d6c75762f169a9f3c3022e5ce7293';\nconst dexPool =\n  '0x8a13859a8d930f3238ddd31180a5f0914e5b8dbaa31e18387066b61a563fedf9';\n\nconst pkgId =\n  '0x3c316b6af0586343ce8e6b4be890305a1f83b7e196366f6435b22b6e3fc8e3d9';\n\n(async () =\u003e {\n  const mnemonics = process.env.MNEMONICS;\n  const suiKit = new SuiKit({ mnemonics });\n  const sender = suiKit.currentAddress;\n\n  const tx = new SuiTxBlock();\n  // 1. Make a flash loan for coinB\n  const [coinB, loan] = tx.moveCall(`${pkgId}::custom_coin_b::flash_loan`, [\n    treasuryB,\n    10 ** 9,\n  ]);\n  // 2. Swap from coinB to coinA, ratio is 1:1\n  const coinA = tx.moveCall(`${pkgId}::dex::swap_a`, [dexPool, coinB]);\n  // 3. Swap from coinA back to coinB, ratio is 1:2\n  const coinB2 = tx.moveCall(`${pkgId}::dex::swap_b`, [dexPool, coinA]);\n  // 4. Repay flash loan\n  const [paybackCoinB] = tx.splitCoins(coinB2, [10 ** 9]);\n  tx.moveCall(`${pkgId}::custom_coin_b::payback_loan`, [\n    treasuryB,\n    paybackCoinB,\n    loan,\n  ]);\n  // 4. Transfer profits to sender\n  tx.transferObjects([coinB2], sender);\n\n  // 5. Execute transaction\n  const res = await suiKit.signAndSendTxn(tx);\n  console.log(res);\n})();\n```\n\n### Multi-accounts\n\nSuiKit follows bip32 \u0026 bip39 standard, so you can use it to manage multiple accounts.\nWhen init SuiKit, you can pass in your mnemonics to create a wallet with multiple accounts.\n\n```typescript\n/**\n * This is an example of using SuiKit to manage multiple accounts.\n */\nimport { SuiKit } from '@scallop-io/sui-kit';\n\nasync function checkAccounts(suiKit: SuiKit) {\n  const displayAccounts = async (suiKit: SuiKit, accountIndex: number) =\u003e {\n    const coinType = '0x2::sui::SUI';\n    const addr = suiKit.getAddress({ accountIndex });\n    const balance = (await suiKit.getBalance(coinType, { accountIndex }))\n      .totalBalance;\n    console.log(`Account ${accountIndex}: ${addr} has ${balance} SUI`);\n  };\n  // log the first 10 accounts\n  const numAccounts = 10;\n  for (let i = 0; i \u003c numAccounts; i++) {\n    await displayAccounts(suiKit, i);\n  }\n}\n\nasync function internalTransferSui(\n  suiKit: SuiKit,\n  fromAccountIndex: number,\n  toAccountIndex: number,\n  amount: number\n) {\n  const toAddr = suiKit.getAddress({ accountIndex: toAccountIndex });\n  console.log(\n    `Transfer ${amount} SUI from account ${fromAccountIndex} to account ${toAccountIndex}`\n  );\n  return await suiKit.transferSui(toAddr, amount, {\n    accountIndex: fromAccountIndex,\n  });\n}\n\nconst mnemonics = process.env.MNEMONICS;\nconst suiKit = new SuiKit({ mnemonics });\ncheckAccounts(suiKit).then(() =\u003e {});\n// transfer 1000 SUI from account 0 to account 1\ninternalTransferSui(suiKit, 0, 1, 1000).then(() =\u003e {});\n```\n\n### Publish \u0026 upgrade Move package\n\nWe have a standalone npm package to help you publish and upgrade Move package based on sui-kit.\n\nPlease refer to the repository: [sui-package-kit](https://docs.sui.io/devnet/build/install)\n\n[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/scallop-io/sui-kit)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscallop-io%2Fsui-kit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscallop-io%2Fsui-kit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscallop-io%2Fsui-kit/lists"}