{"_rev":"2-af2fd905bee28f10e5b705e9a8e6326e","time":{"created":"2024-03-05T10:10:55.476Z","1.4.4":"2024-03-05T09:23:19.545Z","modified":"2024-03-05T10:10:56.328Z","1.0.0":"2024-03-05T10:10:55.800Z"},"_id":"@buckmint/buckmint-connector","name":"@buckmint/buckmint-connector","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@buckmint/buckmint-connector","version":"1.0.0","description":"A NodeJS Connector for the Buckmint API","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","private":false,"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/buckmint/buckmint-connector-node.git"},"homepage":"https://github.com/buckmint/buckmint-connector-node","author":{"name":"Buckmint"},"license":"MIT","scripts":{"build":"tsup ./src/index.ts --format cjs,esm --dts","start":"ts-node ./example/rest.ts","start:ws":"ts-node ./example/websocket.ts","test":"mocha test/test.ts -r ts-node/register -r dotenv/config --timeout 10000","lint":"eslint . --ext .ts","ci":"pnpm run lint && pnpm run build","release":"pnpm run lint && pnpm run build && changeset publish","prettier-format":"run-script-os","prettier-format:win32":"prettier --config .prettierrc \"./src/**/*.ts\" --write","prettier-format:darwin:linux":"prettier --config .prettierrc 'src/**/*.ts' --write","prettier-format:default":"prettier --config .prettierrc 'src/**/*.ts' --write","prettier-watch":"run-script-os","prettier-watch:win32":"onchange \"src/**/*.ts\" -- prettier --write {{changed}}","prettier-watch:darwin:linux":"onchange 'src/**/*.ts' -- prettier --write {{changed}}","prettier-watch:default":"onchange 'src/**/*.ts' -- prettier --write {{changed}}"},"husky":{"hooks":{"pre-commit":"npm run test && npm run prettier-format && npm run lint"}},"keywords":["buckmint","connector","finance","api","wrapper","typescript","nodejs"],"devDependencies":{"@changesets/cli":"^2.26.0","@swc/core":"^1.3.38","@types/chai":"^4.3.4","@types/elliptic":"^6.4.14","@types/mocha":"^10.0.1","@types/node":"^18.6.1","@types/ws":"^8.5.4","@typescript-eslint/eslint-plugin":"^5.31.0","@typescript-eslint/parser":"^5.31.0","axios-mock-adapter":"^1.21.4","chai":"^4.3.7","dotenv":"^16.0.3","eslint":"^8.20.0","eslint-config-prettier":"^8.5.0","eslint-plugin-jest":"^26.6.0","eslint-plugin-prettier":"^4.2.1","husky":"^8.0.1","mocha":"^10.2.0","nodemon":"^2.0.19","onchange":"^7.1.0","prettier":"^2.7.1","run-script-os":"^1.1.6","ts-node":"^10.9.1","tsup":"^6.6.3","typescript":"^4.7.4"},"dependencies":{"axios":"^1.3.4","bn.js":"^5.2.1","elliptic":"^6.5.4","enc-utils":"^3.0.0","ethers":"^5.5.3","hash.js":"^1.1.7","web3":"^1.8.2","ws":"^8.12.1"},"tsup":{"entry":["src/index.ts"],"splitting":false,"clean":true},"_id":"@buckmint/buckmint-connector@1.0.0","gitHead":"f7628e95926d932855eb0dea586101767d75e73b","bugs":{"url":"https://github.com/buckmint/buckmint-connector-node/issues"},"_nodeVersion":"18.19.0","_npmVersion":"10.2.3","dist":{"integrity":"sha512-tn8MFME7LGTuubf4nbCMLIiQBqDtwLf5EH77FjwO09A2t9N8sYNfMepr7uEnAgSS70RUTIQXLNnQoJMfaEqTcg==","shasum":"fb600af7fc082ddd65b2ece53bab0afc48755bfc","tarball":"https://registry.npmjs.org/@buckmint/buckmint-connector/-/buckmint-connector-1.0.0.tgz","fileCount":33,"unpackedSize":954098,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCXZQ+Es3MpR/C4jSmZHaMes5/WTEm7oGTl/PeqMJD7yQIgH8+f8qoK0e7mA0QJF9To+D0t0Pc93pLlnyamcySBNXM="}]},"_npmUser":{"name":"buckmint","email":"ram@buckmint.org"},"directories":{},"maintainers":[{"name":"buckmint","email":"ram@buckmint.org"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/buckmint-connector_1.0.0_1709633455551_0.6901943456909458"},"_hasShrinkwrap":false}},"maintainers":[{"name":"buckmint","email":"ram@buckmint.org"}],"description":"A NodeJS Connector for the Buckmint API","homepage":"https://github.com/buckmint/buckmint-connector-node","keywords":["buckmint","connector","finance","api","wrapper","typescript","nodejs"],"repository":{"type":"git","url":"git+https://github.com/buckmint/buckmint-connector-node.git"},"author":{"name":"Buckmint"},"bugs":{"url":"https://github.com/buckmint/buckmint-connector-node/issues"},"license":"MIT","readme":"<h1 align=\"center\">Buckmint Connector NodeJS</h1>\n\n## Features\n\n- Complete endpoints including REST and WebSockets\n- Methods return parsed JSON.\n- High level abstraction for ease of use.\n- Easy authentication\n- Automatically sets JWT token internally\n- Calls refresh endpoint when token expires.\n- Typescript Types✨\n\nBuckmint Connector includes utility/connector functions which can be used to interact with the Buckmint API. It uses axios internally to handle all requests. It includes interceptors for setting JWT and handling re-login on token expiry.\n\n## Installation\n\nFirst, go to [Buckmint's Website](https://www.buckmint.org/) and create an account with your wallet.\n\nInstall from npm\n\n```sh\nnpm i @buckmint/buckmint-connector\n```\n\n## Getting Started\n\nThe default base url for mainnet is https://exchange-api.buckmint.org and testnet is https://testnet-exchange-api.buckmint.org. You can choose between mainnet and testnet by providing it through the constructor. The default is mainnet. All REST apis, WebSockets are handled by Client, WsClient classes respectively. All operations must be handled in a try-catch block.\n\n### Workflow\n\nCheck out the [example files](./example) to see an example workflow.\n\nTo use library inside example files\n\n```sh\nnpm run start\nnpm run start:ws\n```\n\n### Rest Client\n\nImport the REST Client\n\n```ts\nimport { Client } from '@buckmint/buckmint-connector'\n```\n\nCreate a new instance.  \nChoose between mainnet or testnet\n\n```ts\nconst client = new Client()\n// or\nconst client = new Client('testnet') // default mainnet\n```\n\n### General Endpoints\n\n#### Test connectivity\n\n`GET /sapi/v1/health/`\n\n```ts\nclient.testConnection()\n```\n\n#### 24hr Price\n\n`GET /sapi/v1/market/tickers/`\n\n```ts\nclient.get24hPrice({ market: 'ethusdc' })\n```\n\n#### Kline/Candlestick Data\n\n`GET /sapi/v1/market/kline/`\n\n```ts\nclient.getCandlestick({\n  market: 'ethusdc',\n  period: 120,\n})\n```\n\n#### Order Book\n\n`GET /sapi/v1/market/orderbook/`\n\n```ts\nclient.getOrderBook({\n  market: 'ethusdc',\n})\n```\n\n#### Recent trades\n\n`GET /sapi/v1/market/trades/`\n\n```ts\nclient.getRecentTrades({\n  market: 'ethusdc',\n})\n```\n\n#### Login\n\nBoth `login` and `completeLogin` sets JWT as Authorization Token. Optionally, `setAccessToken` and `setRefreshToken` can be used to set tokens directly.\n\ngetNonce: `POST /sapi/v1/auth/nonce/`  \nlogin: `POST /sapi/v1/auth/login/`\n\n```ts\nimport { signMsg } from '@buckmint/buckmint-connector'\n\nconst nonce = await client.getNonce(ethAddress)\nconst signedMsg = signMsg(nonce.payload, ethPrivateKey)\nconst loginRes = await client.login(ethAddress, signedMsg.signature)\n\n// or\n\nconst loginRes = await client.completeLogin(ethAddress, ethPrivateKey) //calls above functions internally\n\n// or\n\nclient.setAccessToken(access) // same as client.setToken()\nclient.setRefreshToken(refresh)\n// these functions are called internally when you use login or completeLogin\n```\n\n#### Refresh Token\n\n`POST /sapi/v1/auth/token/refresh/`\n\nIf refresh token is set (manually or by using login functions), the refresh endpoint is called automatically when access token expires. Optionally, you can call `refreshTokens` manually by passing in refreshToken (passing it is optional, it'll work if has been set before).\n\n```ts\nconst res = await client.refreshTokens(refreshToken)\n```\n\n#### Logout\n\nSets tokens to null\n\n```ts\nclient.logOut()\n```\n\n#### Profile Information (Private 🔒)\n\n`GET /sapi/v1/user/profile/`\n\n```ts\nclient.getProfileInfo()\n```\n\n#### Balance details (Private 🔒)\n\n`GET /sapi/v1/user/balance/`\n\n```ts\nclient.getBalance()\n```\n\n#### Profit and Loss Details (Private 🔒)\n\n`GET /sapi/v1/user/pnl/`\n\n```ts\nclient.getProfitAndLoss()\n```\n\n#### Create order (Private 🔒)\n\nCreate Nonce Body\n\n```ts\nconst nonceBody: CreateOrderNonceBody = {\n  market: 'ethusdc',\n  ord_type: 'market',\n  price: 29580.51,\n  side: 'buy',\n  volume: 0.0001,\n}\n```\n\n> If you are affiliated with the Buckmint organization, please ensure that you add the organization_key and api_key to the request body in both the nonce and create endpoints. This field is entirely optional. To obtain these keys, please reach out to Buckmint at support@buckmint.org.\n>\n> ```ts\n> const nonceBody: CreateOrderNonceBody = {\n>   market: 'ethusdc',\n>   ord_type: 'market',\n>   price: 29580.51,\n>   side: 'buy',\n>   volume: 0.0001,\n>   organization_key: 'YOUR_ORGANIZATION_KEY', // This is an optional field. The organization’s key shared by Buckmint organization.\n>   api_key: 'YOUR_API_KEY', // This is an optional field. The organization’s API key shared by Buckmint organization.\n> }\n> ```\n\nCreate Order\n\ncreateOrderNonce: `POST /sapi/v1/orders/nonce/`\ncreateNewOrder: `POST /sapi/v1/orders/create/`\n\n```ts\nconst order = await client.createCompleteOrder(nonceBody, ethPrivateKey)\n//calls below functions internally, we recommend using createCompleteOrder for ease of use\n\n// or\nimport { signMsgHash } from '@buckmint/buckmint-connector'\n\nconst orderNonce = await client.createOrderNonce(nonceBody)\nconst signedBody = signMsgHash(orderNonce.payload, ethPrivateKey)\nconst order = await client.createNewOrder({\n  ...signedBody,\n  organization_key: '', // This is an optional field. The organization’s key shared by Buckmint organization.\n  api_key: '',\n}) // This is an optional field. The organization’s API key shared by Buckmint organization.\n\n// or\nimport {\n  createUserSignature,\n  getKeyPairFromSignature,\n  signOrderWithStarkKeys,\n} from '@buckmint/buckmint-connector'\n\nconst orderNonce = await client.createOrderNonce(nonceBody)\nconst userSignature = createUserSignature(ethPrivateKey, 'testnet') // or sign it yourself; default mainnet\nconst keyPair = getKeyPairFromSignature(userSignature.signature)\nconst signedBody = signOrderWithStarkKeys(keyPair, orderNonce.payload)\nconst order = await client.createNewOrder(signedBody)\n```\n\n#### Get Order (Private 🔒)\n\n`GET /sapi/v1/orders/{order_id}/`\n\n```ts\nclient.getOrder(orderId)\n```\n\n#### List orders (Private 🔒)\n\n`GET /sapi/v1/orders/`\n\n```ts\nclient.listOrders()\n```\n\n#### Cancel Order (Private 🔒)\n\n`POST /sapi/v1/orders/cancel/`\n\n```ts\nclient.cancelOrder(order_id)\n```\n\n#### List Trades (Private 🔒)\n\n`GET /sapi/v1/trades/`\n\n```ts\nclient.listTrades()\n```\n\n### WebSocket Client\n\nImport the WebSocket Client\n\n```ts\nimport { WsClient } from '@buckmint/buckmint-connector'\n```\n\nCreate a new instance\n\n```ts\nconst wsClient = new WsClient('public')\n// or\nconst wsClient = new WsClient('public', 'testnet') // default is 'mainnet'\n// or\nconst loginRes = await client.completeLogin(ethAddress, ethPrivateKey)\nconst wsClient = new WsClient('private', 'testnet', loginRes.token.access)\n// pass in jwt as 3rd argument for private connections\n```\n\n#### Connect\n\n```ts\nwsClient.connect()\n```\n\n#### Subscribe\n\n```ts\nconst streams = ['btcusdc.trades', 'btcusdc.ob-inc', 'btcusdc.kline-5m']\nwsClient.subscribe(streams)\n\n// or fpr private\n\nwsClient.subscribe(['trade', 'order'])\n```\n\n#### Unsubscribe\n\n```ts\nconst streams = ['btcusdc.trades', 'btcusdc.ob-inc', 'btcusdc.kline-5m']\nwsClient.unsubscribe(streams)\n\n// or fpr private\n\nwsClient.unsubscribe(['trade', 'order'])\n```\n\n#### Disconnect\n\n```ts\nwsClient.disconnect()\n```\n\n#### Usage\n\nWsClient includes a member called ws which is initialized with the [NodeJS WebSocket library](https://github.com/websockets/ws) (ws). You may use it to handle WebSocket operations.\n\n```ts\nwsClient.ws.on('message', (data) => {\n  console.log(data.toString())\n})\n```\n\n### Error Handling\n\nErrors thrown are of types `AuthenticationError | AxiosError`.\n\nExample\n\n```ts\nimport { isAuthenticationError } from '@buckmint/buckmint-connector'\ntry {\n  // async operations\n} catch (e) {\n  if (isAuthenticationError(e)) {\n    console.log(e)\n  } else {\n    console.log(e as AxiosError<Response<string>>)\n  }\n}\n```\n\n#### Create L2 Key Pair\n\nYou can create your own stark key pairs using the utility functions below\n\n```ts\nimport { generateKeyPairFromEthPrivateKey } from '@buckmint/buckmint-connector'\n\nconst keypair = generateKeyPairFromEthPrivateKey(ethPrivateKey, 'testnet') // default is mainnet\n\nconst stark_public_key = keypair.getPublic().getX().toString('hex')\nconst stark_private_key = keypair.getPrivate().toString('hex')\n```\n\n### Internal Transfer\n\nUsers will be able to seamlessly transfer assets from their CEXs or other chains with minimal fees.\n\nTo get started with the feature, follow these two steps:\n\n1. Reach out to Buckmint (support@buckmint.org) to get the organization key and API key.\n\n2. Generate the L2 key pair with your private key using the following example:\n\n```ts\nimport { generateKeyPairFromEthPrivateKey } from '@buckmint/buckmint-connector'\n\nconst keypair = generateKeyPairFromEthPrivateKey(ethPrivateKey, 'testnet')\n```\n\n### Available methods:\n\n#### To process the internal transfer, call the `initiateAndProcessInternalTransfers` method and pass the necessary arguments:\n\n```ts\nconst internalTransferResponse =\n  await client.initiateAndProcessInternalTransfers(\n    keypair, // The keypair generated in the above step.\n    organizationKey, // The organization’s key shared by Buckmint organization.\n    apiKey, // The organization’s API key shared by Buckmint organization.\n    'usdc', // The currency (e.g., USDC). Currently, we support USDC.\n    amount, // The amount (e.g., 10).\n    destination_address, // The receiver's eth address.\n    client_reference_id, // This is an optional field. If not specified, then it’s generated randomly. You can use this to uniquely identify a transfer at your end.\n  )\n```\n\n#### Retrieve a list of transfers initiated by the authenticated user:\n\n```javascript\nconst internalTransferList = await client.listInternalTransfers({\n  limit: 10, // This field is optional.\n  offset: 10, // This field is optional.\n})\n```\n\n#### Retrieve an internal transfer using its client reference id:\n\n```javascript\nconst internalTransferList = await client.getInternalTransferByClientId(\n  client_reference_id, // The client reference id you want to retrieve\n)\n```\n\n#### Check if a user exists by their destination address.\n\n```javascript\nconst checkUserRes = await client.checkInternalTransferUserExists(\n  buckmintOrganizationKey,\n  buckmintApiKey,\n  destination_address, // The destination address you want to check.\n)\n```\n\n### Deposit\n\n#### Ethereum Deposit\n\nThere are two ways to make a deposit on the Ethereum network:\n\n<!-- 1. Using ETH Private Key and RPC URL: This approach utilizes your ETH private key and an rpcUrl (e.g., from Infura or Alchemy).\n2. Custom Provider and Signer: This method involves creating your provider and signer using ethers.js or web3.js. You'll also need the stark_public_key. -->\n\n#### 1. Using ETH Private Key and RPC URL:\n\nIn this method, you will use an ETH private key and an RPC URL to execute a deposit. You'll also need to create an RPC URL using services like Infura, Alchemy, etc. Here's the code snippet for this method:\n\n```javascript\n  const res = await client.depositFromEthereumNetwork(\n    process.env.RPC_PROVIDER as string, // Use 'goerli' for the testnet and 'ethereum mainnet' for the mainnet.\n    privateKey, // Your ETH private key.\n    'testnet', // Network allowed values are 'testnet' or 'mainnet'.\n    'eth', // Enter the coin symbol.\n    0.00001, // Enter the amount you want to deposit.\n  );\n```\n\n#### 2. Using Custom Provider and Signer:\n\nThis method involves using a custom provider and signer, which can be created using the ethers.js library. The `stark_public_key` mentioned in the code should be obtained using the steps described in the [Create L2 Key Pair](#create-l2-key-pair) section. Here's the code snippet for this method:\n\n```javascript\n// Note: Please use ethers version 5.5.3.\nimport { Wallet, ethers } from 'ethers'\n\nconst provider = new ethers.providers.JsonRpcProvider(\n  process.env.RPC_PROVIDER, // Use 'goerli' for testnet and 'ethereum mainnet' for the mainnet.\n)\n\nconst signer = new Wallet(privateKey, provider)\n\nconst depositRes = await client.depositFromEthereumNetworkWithStarkKey(\n  signer, // The signer created above.\n  provider, // The provider created above.\n  `0x${stark_public_key}`, // The stark_public_key created above.\n  0.0000001, // Enter the amount you want to deposit.\n  'eth', // Enter the coin symbol.\n)\n```\n\n#### Polygon Deposit\n\nThere are two ways to make a deposit on the Polygon network:\n\n#### 1. Using ETH Private Key and RPC URL:\n\nIn this method, you will use an ETH private key and an RPC URL to execute a Polygon deposit. You'll also need to create an RPC URL using services like Infura, Alchemy, etc. Here's the code snippet for this method:\n\n```javascript\n  const depositRes = await client.depositFromPolygonNetwork(\n    process.env.RPC_PROVIDER as string, // Use 'Polygon Mumbai' for the testnet and 'Polygon mainnet' for the mainnet.\n    privateKey, // Your ETH private key.\n    'btc', // Enter the coin symbol.\n    0.00001, // Enter the amount you want to deposit.\n  );\n```\n\n#### 2. Using Custom Provider and Signer:\n\nThis method involves using a custom provider and signer, which can be created using the ethers.js library. Here's the code snippet for this method:\n\n```javascript\n// Note: Please use ethers version 5.5.3.\nimport { Wallet, ethers } from 'ethers'\n\nconst provider = new ethers.providers.JsonRpcProvider(\n  process.env.RPC_PROVIDER, // Use 'Polygon Mumbai' for the testnet and 'Polygon mainnet' for the mainnet.\n)\n\nconst signer = new Wallet(privateKey, provider)\n\nconst depositPolygonRes = await client.depositFromPolygonNetworkWithSigner(\n  signer, // The signer created above.\n  provider, // The provider created above.\n  'btc', // Enter the coin symbol.\n  0.00001, // Enter the amount you want to deposit.\n)\n```\n\n#### List Deposits\n\nTo get the deposit history, you can use the following code:\n\n```javascript\nconst depositsList = await client.listDeposits({\n  network: 'ETHEREUM', // Network for which you want to list the deposit history. Allowed networks are ETHEREUM & POLYGON\n  page: 2, // This is an optional field\n  limit: 1, // This is an optional field\n})\n```\n\n### Withdrawal\n\nGenerally, we have two modes of withdrawal: Normal Withdrawal and Fast Withdrawal. For withdrawal methods that require a signer and provider, please refer to the deposit method mentioned above.\n\n#### Normal Withdrawal\n\nWith Normal Withdrawal, your requested funds will be processed within a standard time frame (24 hours). This mode is suitable for users who are not in a rush to access their funds and are comfortable with the regular processing time.\n\n```javascript\n// Withdrawals\n\n// Normal withdrawal:\n// 1. Initiate your withdrawal request by calling the \"initiateNormalWithdrawal\" function.\nconst withdrawalRes = await client.initiateNormalWithdrawal(\n  keyPair, // The keyPair created above\n  0.0001, // Enter the amount you want to deposit\n  'usdc', // Enter the coin symbol\n)\n// 2. WAIT for up to 24 hours.\n// 3. Check whether the withdrawn balance is pending by calling the \"getPendingNormalWithdrawalAmountByCoin\" function with the required parameters.\nconst pendingBalance = await client.getPendingNormalWithdrawalAmountByCoin(\n  'eth', // Enter the coin symbol\n  ethAddress, // User public eth address\n  signer, // The signer created above\n)\n// 4. In the final step, if you find the balance is more than 0, you can use the \"completeNormalWithdrawal\" function to withdraw the cumulative amount to your ETH wallet.\nconst completeNWRes = await client.completeNormalWithdrawal(\n  'eth', // Enter the coin symbol\n  ethAddress, // User public eth address\n  signer, // The signer created above\n)\n\n//Get a list of withdrawals\nconst withdrawalsList = await client.listNormalWithdrawals({\n  page: 2, // This is an optional field\n})\n```\n\n#### Fast Withdrawal\n\nWith Fast Withdrawal, your funds will be processed in an expedited timeframe, often within a few minutes. This mode is ideal for users who require immediate access to their funds and are comfortable with paying a fee.\n\n```javascript\nconst fastWithdrawalRes = await client.fastWithdrawal(\n  keyPair, // The keyPair created above\n  0.0001, // Enter the amount you want to deposit\n  'usdc', // Enter the coin symbol\n  'ETHEREUM', // Allowed networks are POLYGON & ETHEREUM\n)\n\n//Get a list of fast withdrawals\nconst fastwithdrawalsList = await client.listFastWithdrawals({\n  page: 2, // This is an optional field\n})\n```\n\n#### Polygon withdrawal\n\nOn the Polygon network, we only support fast withdrawals.\n\n```javascript\nconst fastWithdrawalRes = await client.fastWithdrawal(\n  keyPair, // The keyPair created above\n  0.0001, // Enter the amount you want to deposit\n  'usdc', // Enter the coin symbol\n  'POLYGON', // Allowed networks are POLYGON & ETHEREUM\n)\n```\n","readmeFilename":"README.md"}