diff --git a/.vitepress/config.ts b/.vitepress/config.ts index d8dcf64b8..fd2a6cf99 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -756,7 +756,33 @@ function sidebarHome() { { text: "⛽ Gas Tank API", link: "/gas-tank/gas-tank-api", - items: [], + collapsed: true, + items: [ + { + text: "🔹 Introduction", + link: "/gas-tank/gas-tank-api", + }, + { + text: "🔹 Authentication", + link: "/gas-tank/gas-tank-api#authentication", + }, + { + text: "🔹 Messages", + link: "/gas-tank/gas-tank-api#messages", + }, + { + text: "🔹 Chains / Tokens / Status", + link: "/gas-tank/gas-tank-api#chains-token-status", + }, + { + text: "🔹 Balances & Gas top-up: Deposit, Withdraw, Send Gas", + link: "/gas-tank/gas-tank-api#balance-transactions-deposit-withdraw-send-gas", + }, + { + text: "🔹 Other services", + link: "/gas-tank/gas-tank-api#other-services", + }, + ], }, { text: "🛠️ Partners APIs", diff --git a/assets-services/assets-and-prices-api.md b/assets-services/assets-and-prices-api.md index cefef09a0..41c7b0889 100644 --- a/assets-services/assets-and-prices-api.md +++ b/assets-services/assets-and-prices-api.md @@ -170,7 +170,7 @@ getSupportedChains(); Get Assets Crypto Currencies provides information about cryptocurrencies on various blockchains, including Ethereum, Binance Smart Chain, and Solana. The API returns data such as the cryptocurrency's name, symbol, icon, type, external data, scaling factor, chain, market cap, and price. -[Query GraphQL directly here](https://gql-router.dev.xdefi.services/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAMKEAOKEJMeeyUAlggM4AUAJOQIYDmC6UhCRIEUFI2EBBPLxYBCADREOAM0YAbFPkFkClarXpIoBAGKbteZR26qrABTyMoAogBFu2gCqNENuytBTx8-BABKImAAHSQiIm4WFgQUFijY%2BPioCioaOgZmdh5%2BQS4%2BBGV1LR0VKqtlQPwnFzdbeybnVwb2vFLGvEiYuMz44oQQ7nThkayIGFQMmfiNP0YURaWIVVVk9enMgF8NzLGppdHygEkkVQgz8-iAC0SAOQQADxQHcuOl5DA8iwIHhfodQfEEGB%2BGkhg94kgIGAEPc4URGGBwTMkNxEJiRiwCHAAEYQDR4zIuYTk%2BIofQIalED5WbEaCYMuDcPAAaxSJG45AZLCg3BWSF4Zm44mBDKgz0YSAZ5E6yNhqMyOLmC32DyO2pmup1oINYOGuoOIEUIAAbpzGNwiRpWBgQKroiAxm7BKr4m71HgWOsMEQAKyKY5u-qeohIGAaMmmsPDX2WfBR71EN2y7jylhRmNxxMjN3o3NB-MaQuZN0E4mk0uCcuLA6ViM9ZquPOxiuLVtWTtx2Lmy3kCAB1QrXiPFAAeXI%2BC8kiQAGVsoxKM6QAcgA) +[Query GraphQL directly here](https://gql-router.xdefi.services/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAMKEAOKEJMeeyUAlggM4AUAJOQIYDmC6UhCRIEUFI2EBBPLxYBCADREOAM0YAbFPkFkClarXpIoBAGKbteZR26qrABTyMoAogBFu2gCqNENuytBTx8-BABKImAAHSQiIm4WFgQUFijY%2BPioCioaOgZmdh5%2BQS4%2BBGV1LR0VKqtlQPwnFzdbeybnVwb2vFLGvEiYuMz44oQQ7nThkayIGFQMmfiNP0YURaWIVVVk9enMgF8NzLGppdHygEkkVQgz8-iAC0SAOQQADxQHcuOl5DA8iwIHhfodQfEEGB%2BGkhg94kgIGAEPc4URGGBwTMkNxEJiRiwCHAAEYQDR4zIuYTk%2BIofQIalED5WbEaCYMuDcPAAaxSJG45AZLCg3BWSF4Zm44mBDKgz0YSAZ5E6yNhqMyOLmC32DyO2pmup1oINYOGuoOIEUIAAbpzGNwiRpWBgQKroiAxm7BKr4m71HgWOsMEQAKyKY5u-qeohIGAaMmmsPDX2WfBR71EN2y7jylhRmNxxMjN3o3NB-MaQuZN0E4mk0uCcuLA6ViM9ZquPOxiuLVtWTtx2Lmy3kCAB1QrXiPFAAeXI%2BC8kiQAGVsoxKM6QAcgA) ::: code-group @@ -349,7 +349,7 @@ getCryptoAssets(); Get Assets Fiat Currencies provides information about fiat currencies on various blockchains, including Ethereum, Binance Smart Chain, and Solana. The API returns data such as the fiat currency's name, symbol, scaling factor, character, and price. -[Query GraphQL directly here](https://gql-router.dev.xdefi.services/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAGICWAhigMIx57JRkIDOAFACQAOFA5guiLUISJAigoyIgIJ5eLAIQAaIhwBmZADYp8g8lVr1GBctvwqOFNTryCAIlQQAVMogtWbABTxkoAog46LogAlETAADpIREQULCwIKCzhUTExGgZ0DEhMrGw8-ILcfAgqGma2quU2Kh66qnV4tdb43r7%2Bli14bX5hkdFpMQUIgRQpA4MxUBAwqKmTMZquZCjzCxBqagmrE2kAvmtpw%2BMLQyUAkkhqECenMchghiwQeIcLABZxAHIIAB4onhKb32wPuYH4yX6dxiSAgYAQt2hRDIYFBkyQFEQaMGLAIcAARhBNNi0iwoBQlkheCQKBIXiSpp88LSbAyiFwfH5EUjYnAZnNdncDoLJsKhcCxSCBsK9iAlCAAG4UHwUfGaVgYEBQogREDDXWCbUxXUaPAsVYYIgAViUh11jQNRCQME0xOltoGJq0rMtRp1IBRLEdztd8z2HuNIAdlpDmgj-saPQQwZdbtl8q4EHNaiWvHeKAA8lx8FQpEgAMpQHxcNCYEB7IA) +[Query GraphQL directly here](https://gql-router.xdefi.services/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABAGICWAhigMIx57JRkIDOAFACQAOFA5guiLUISJAigoyIgIJ5eLAIQAaIhwBmZADYp8g8lVr1GBctvwqOFNTryCAIlQQAVMogtWbABTxkoAog46LogAlETAADpIREQULCwIKCzhUTExGgZ0DEhMrGw8-ILcfAgqGma2quU2Kh66qnV4tdb43r7%2Bli14bX5hkdFpMQUIgRQpA4MxUBAwqKmTMZquZCjzCxBqagmrE2kAvmtpw%2BMLQyUAkkhqECenMchghiwQeIcLABZxAHIIAB4onhKb32wPuYH4yX6dxiSAgYAQt2hRDIYFBkyQFEQaMGLAIcAARhBNNi0iwoBQlkheCQKBIXiSpp88LSbAyiFwfH5EUjYnAZnNdncDoLJsKhcCxSCBsK9iAlCAAG4UHwUfGaVgYEBQogREDDXWCbUxXUaPAsVYYIgAViUh11jQNRCQME0xOltoGJq0rMtRp1IBRLEdztd8z2HuNIAdlpDmgj-saPQQwZdbtl8q4EHNaiWvHeKAA8lx8FQpEgAMpQHxcNCYEB7IA) ::: code-group @@ -605,7 +605,7 @@ getLosersTokens(); Get LP Tokens is fully the same structure as Get Assets Tokens but it’s like "Low Priority" tokens. The API returns data such as the LP token's symbol, scaling factor, address, chain, fees, defi protocols and external data. -[Query GraphQL directly here](https://gql-router.dev.xdefi.services/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABADIAKAKhANbIDOAFACQAOAhgOYLpEDCESJAigoAlgICCeDnQCEAGiJMAZqIA2KfDyq0kAMXWa8ipm2VGeAETaaKoxCbNGyeUVG5Frt%2BwgCURYAAdJCIiNjo6BBQ6AODQ0LUWHXoGdi4eVk4ERVUNLSVco0UnfNNzfGLyvBc3DzLnV3d-IJD40LSELzZY1rbQqAgYVDi%2BhPtRFBHRiGVlSMne%2BIBfKfiOntH2rIBJJGUIDc3Q5DBeGDw6CDxV0YALcIA5BAAPFDIsm%2BXP47AuGJajqEkBAwAhDoCiANUHg2CJ-t9NqIwAjRnQCHAAEYQNQovp0KBsNSiJAcPSwlBXXFtNhgMB4BARKnxKD3YlM0LKBBggEQvoAN0JuHZRBWiwhoNULggFIGanBvP6rKQwtCbgEKqISDYiGFooVet5LyMWrUXSZSPNUKZWp1Ys2cDYeFoKF4bBYTJYjW5wu1g2GdtGBohaMx2KZKAILAQuKDfVjoVjBtFSxA8hAAtcbAxagZGBAPMCIA6hZ4PNChdUF0mGCIAFZ5KtCyVrjWkDA1DjWksG60K4Z8CX5YWQ1i1HRB22Oz22oWkePW%2B21NP4oWWWxifOeJOl42QDS6QzN5rFyNuyMm1UJ4vlxeGrUrx3gim0ywIHQUMoiRxbigAPJRmExAEABlKBXBYNBMBAJYgA) +[Query GraphQL directly here](https://gql-router.xdefi.services/graphql?explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4QEcYIE4CeABADIAKAKhANbIDOAFACQAOAhgOYLpEDCESJAigoAlgICCeDnQCEAGiJMAZqIA2KfDyq0kAMXWa8ipm2VGeAETaaKoxCbNGyeUVG5Frt%2BwgCURYAAdJCIiNjo6BBQ6AODQ0LUWHXoGdi4eVk4ERVUNLSVco0UnfNNzfGLyvBc3DzLnV3d-IJD40LSELzZY1rbQqAgYVDi%2BhPtRFBHRiGVlSMne%2BIBfKfiOntH2rIBJJGUIDc3Q5DBeGDw6CDxV0YALcIA5BAAPFDIsm%2BXP47AuGJajqEkBAwAhDoCiANUHg2CJ-t9NqIwAjRnQCHAAEYQNQovp0KBsNSiJAcPSwlBXXFtNhgMB4BARKnxKD3YlM0LKBBggEQvoAN0JuHZRBWiwhoNULggFIGanBvP6rKQwtCbgEKqISDYiGFooVet5LyMWrUXSZSPNUKZWp1Ys2cDYeFoKF4bBYTJYjW5wu1g2GdtGBohaMx2KZKAILAQuKDfVjoVjBtFSxA8hAAtcbAxagZGBAPMCIA6hZ4PNChdUF0mGCIAFZ5KtCyVrjWkDA1DjWksG60K4Z8CX5YWQ1i1HRB22Oz22oWkePW%2B21NP4oWWWxifOeJOl42QDS6QzN5rFyNuyMm1UJ4vlxeGrUrx3gim0ywIHQUMoiRxbigAPJRmExAEABlKBXBYNBMBAJYgA) ::: code-group diff --git a/components/staking/CreateCosmosDelegateTx.jsx b/components/staking/CreateCosmosDelegateTx.jsx index 0dda8fca0..7c23d2996 100644 --- a/components/staking/CreateCosmosDelegateTx.jsx +++ b/components/staking/CreateCosmosDelegateTx.jsx @@ -4,7 +4,7 @@ import PlayIcon from "../PlayIcon"; import { cosmosSupportedAssets as assetSupported } from "../common"; const CreateCosmosDelegateTx = () => { - const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; + const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const validators = ["Meria", "StakeLab", "Custom"]; const [loading, setLoading] = useState(false); diff --git a/components/staking/CreateErc20ApproveTx.jsx b/components/staking/CreateErc20ApproveTx.jsx index 04d711419..4c4ee99bf 100644 --- a/components/staking/CreateErc20ApproveTx.jsx +++ b/components/staking/CreateErc20ApproveTx.jsx @@ -4,7 +4,7 @@ import PlayIcon from "../PlayIcon"; import { otherSupportedAssets as assetSupported } from "../common"; const CreateErc20ApproveTx = () => { - const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; + const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const [loading, setLoading] = useState(false); const [response, setResponse] = useState({}); const [assetSelected, setAssetSelected] = useState(undefined); diff --git a/components/staking/CreateLidoStakeTx.jsx b/components/staking/CreateLidoStakeTx.jsx index 4e238b170..09a23a235 100644 --- a/components/staking/CreateLidoStakeTx.jsx +++ b/components/staking/CreateLidoStakeTx.jsx @@ -4,7 +4,7 @@ import PlayIcon from "../PlayIcon"; import { otherSupportedAssets as assetSupported } from "../common"; const CreateLidoStakeTx = () => { - const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; + const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const [loading, setLoading] = useState(false); const [response, setResponse] = useState({}); const [assetSelected, setAssetSelected] = useState(undefined); diff --git a/components/staking/CreateStrideLiquidStakingTx.jsx b/components/staking/CreateStrideLiquidStakingTx.jsx index 9b1866da1..b4027d270 100644 --- a/components/staking/CreateStrideLiquidStakingTx.jsx +++ b/components/staking/CreateStrideLiquidStakingTx.jsx @@ -4,7 +4,7 @@ import PlayIcon from "../PlayIcon"; import { cosmosSupportedAssets as assetSupported } from "../common"; const CreateStrideLiquidStakingTx = () => { - const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; + const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const [loading, setLoading] = useState(false); const [response, setResponse] = useState({}); const [assetSelected, setAssetSelected] = useState(undefined); diff --git a/components/staking/GetCosmosDelegations.jsx b/components/staking/GetCosmosDelegations.jsx index a6cb3d1c4..23f5b4052 100644 --- a/components/staking/GetCosmosDelegations.jsx +++ b/components/staking/GetCosmosDelegations.jsx @@ -4,7 +4,7 @@ import PlayIcon from "../PlayIcon"; import { cosmosSupportedAssets as assetSupported } from "../common"; const GetCosmosDelegations = () => { - const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; + const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const [loading, setLoading] = useState(false); const [response, setResponse] = useState({}); const [assetSelected, setAssetSelected] = useState(undefined); diff --git a/components/staking/GetLidoStakedBalance.jsx b/components/staking/GetLidoStakedBalance.jsx index 58a11540c..734c40c5a 100644 --- a/components/staking/GetLidoStakedBalance.jsx +++ b/components/staking/GetLidoStakedBalance.jsx @@ -4,7 +4,7 @@ import PlayIcon from "../PlayIcon"; import { otherSupportedAssets as assetSupported } from "../common"; const GetLidoStakedBalance = () => { - const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; + const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const [loading, setLoading] = useState(false); const [response, setResponse] = useState({}); const [assetSelected, setAssetSelected] = useState(undefined); diff --git a/components/staking/GetStrideStakedAssetBalance.jsx b/components/staking/GetStrideStakedAssetBalance.jsx index 200fb2709..512b70e2c 100644 --- a/components/staking/GetStrideStakedAssetBalance.jsx +++ b/components/staking/GetStrideStakedAssetBalance.jsx @@ -4,7 +4,7 @@ import PlayIcon from "../PlayIcon"; import { cosmosSupportedAssets as assetSupported } from "../common"; const GetStrideStakedAssetBalance = () => { - const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; + const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const [loading, setLoading] = useState(false); const [response, setResponse] = useState({}); const [assetSelected, setAssetSelected] = useState(undefined); diff --git a/developers/blocknative-xdefi-integration.md b/developers/blocknative-xdefi-integration.md index d54b61882..476ee6ac0 100644 --- a/developers/blocknative-xdefi-integration.md +++ b/developers/blocknative-xdefi-integration.md @@ -1,28 +1,310 @@ # BlockNative XDEFI Integration -First, your app need to install the core Onboard library, the injected wallets module and optionally ethers js to support browser extension and mobile wallets: +In this tutorial we're going to build dApp which supports multiple wallets using the [Web3-Onboard](https://onboard.blocknative.com) library. + +![image](images/blocknative/blocknative_connect_modal.jpg) + +### Get started + +Create new react app + +```bash +npx create-react-app my-blocknative-app --template typescript +``` + +> It's always good idea to start explore something new with fresh and pristine codebase to make sure that exploration subject does not interferes with your existing codebase. + +I +Install web3-onboard core and react packages. ```bash -yarn add @web3-onboard/core @web3-onboard/injected-wallets ethers +yarn add @web3-onboard/core @web3-onboard/react +``` + +> We'll be using `@web3-onboard/react` which provides some fancy react hooks on top of core package, + +Install wallet providers + +```bash +yarn add @web3-onboard/xdefi @web3-onboard/injected-wallets @web3-onboard/walletconnect +``` + +> We'll be using `@web3-onboard/xdefi` package and packages for fallback wallets: `@web3-onboard/walletconnect` and `@web3-onboard/injected-wallets` + +### Setting up Web3Onboard provider + +First, we need to configure our Web3Onboard. +Let's make Web3Onboard configuration function and complete it step by step + +```javascript +import { init } from "@web3-onboard/react"; + +export function configureWeb3Onboard() { + const web3Onboard = init({ + wallets: [], + chains: [], + theme: "dark", + appMetadata: { + name: "My App", + description: "My App with Web3Onboard", + recommendedInjectedWallets: [{ name: "XDEFI", url: "https://xdefi.io" }], + }, + }); + + return web3Onboard; +} +``` + +Now we have our configuration function, but it does not do much yet. +Let's provide some wallets + +```javascript +import { init } from "@web3-onboard/react"; +import xdefiWalletModule from "@web3-onboard/xdefi"; // [!code ++] +import walletConnectModule from "@web3-onboard/walletconnect"; // [!code ++] +import injectedModule from "@web3-onboard/injected-wallets"; // [!code ++] + +export function configureWeb3Onboard() { + + const wallets = + const web3Onboard = init({ + wallets:[ + xdefiWalletModule(), // [!code ++] + walletConnectModule({ projectId: "YOUR_PROJECT_ID" }), // [!code ++] + injectedModule(), // [!code ++] + ]; + chains: [], + theme: "dark", + appMetadata: { + name: "My App", + description: "My App with Web3Onboard", + recommendedInjectedWallets: [{ name: "XDEFI", url: "https://xdefi.io" }], + }, + }); + + return web3Onboard; +} +``` + +and add supported chains + +```javascript +export function configureWeb3Onboard(chains = defaultChainsList) { + const wallets = [ + xdefiWalletModule(), + walletConnectModule({ projectId: "YOUR_PROJECT_ID" }), + injectedModule(), + ]; + const web3Onboard = init({ + wallets, + chains: export function configureWeb3Onboard() { + const web3Onboard = init({ + wallets: [ + xdefiWalletModule(), + walletConnectModule({ projectId: "YOUR_PROJECT_ID" }), + injectedModule(), + ], + chains: [// [!code ++] + {// [!code ++] + id: "0x1", // [!code ++] + token: "ETH", // [!code ++] + label: "Ethereum", // [!code ++] + rpcUrl: "https://ethereum-rpc.publicnode.com",// [!code ++] + },// [!code ++] + {// [!code ++] + id: "0x2105", // [!code ++] + token: "ETH", // [!code ++] + label: "Base",// [!code ++] + rpcUrl: "https://mainnet.base.org", // [!code ++] + },// [!code ++] + {// [!code ++] + id: "0x89",// [!code ++] + token: "MATIC",// [!code ++] + label: "Polygon",// [!code ++] + rpcUrl: "https://matic-mainnet.chainstacklabs.com",// [!code ++] + },// [!code ++] + ],// [!code ++] + theme: "dark", + appMetadata: { + name: "My App", + description: "My App with Web3Onboard", + recommendedInjectedWallets: [{ name: "XDEFI", url: "https://xdefi.io" }], + }, + }); + + return web3Onboard; +}, + theme: "dark", + appMetadata: { + name: "My App", + description: "My App with Web3Onboard", + recommendedInjectedWallets: [{ name: "XDEFI", url: "https://xdefi.io" }], + }, + }); + + return web3Onboard; +} +``` + +Now, we're ready to set up Web3OnboardProvider. Open your React app enty file and wrap your app with Web3OnboardProvider like on sample below + +```javascript +import React from "react"; +import ReactDOM from "react-dom/client"; +import "./index.css"; +import App from "./App"; +import { Web3OnboardProvider } from "@web3-onboard/react"; +import { configureWeb3Onboard } from "./configureWeb3Onboard"; + +const root = ReactDOM.createRoot( + document.getElementById("root") as HTMLElement +); + +root.render( + + + + + +); ``` -Then initialize in your app: +At this point we're done with Web3OnboardProvider setup and finally can start implement our app! + +### Connect and disconnect wallet buttons + +At this step we will try to achieve following result: + +1. Show connect wallet button if there is no connected wallet yet + ![image](images/blocknative/web3-onboard-connect-wallet-btn.jpg) + > Our fancy "connect wallet" button +2. Show Web3Onboard connect wallet modal on "connect wallet" button press + ![image](images/blocknative/blocknative_connect_modal.jpg) + + > Web3Onboard connect wallet modal + +3. Show disconnect button once we have some wallet connected + ![image](images/blocknative/web3onboard-disconnect.jpg) + > Connected wallet state + +Let's proceed with implementation. Here it is: + +```tsx +import { useConnectWallet } from "@web3-onboard/react"; +import "./App.css"; +import { useCallback } from "react"; + +function App() { + const [{ wallet, connecting }, connectWallet, disconnectWallet] = + useConnectWallet(); + + const disconnect = useCallback(async () => { + if (wallet) { + await disconnectWallet({ label: wallet.label }); + } + }, [wallet, disconnectWallet]); + const walletConnected = Boolean(wallet); -```js -import Onboard from "@web3-onboard/core"; -import xdefiWalletModule from "@web3-onboard/xdefi"; + return ( +
+
+
+ + {walletConnected ? ( + + ) : null} +
+
+
+ ); +} +export default App; +``` -// initialize the module with options -const xdefiWalletSdk = xdefiWalletModule(); +Once wallet connected, you must see Blocknative conrol center at the bottom right corner +![image](images/blocknative/web3onboard-control-center.jpg) +If you don't need it, you can disable it on Web3Onboard configuration step. -const onboard = Onboard({ - // ... other Onboard options - wallets: [ - xdefiWalletSdk(), - //... other wallets - ], +```javascript +const web3Onboard = init({ + accountCenter: { + mobile: { + enabled: false, + }, + desktop: { + enabled: false, + }, + }, + ...restOfTheConfig, }); +``` + +For more detailed information on Account center please visit Web3Onboard docs [for core library](https://onboard.blocknative.com/docs/modules/core#accountcenter) and [for React](https://onboard.blocknative.com/docs/modules/react#useaccountcenter) + +### Show connected chain, address and balance -const connectedWallets = await onboard.connectWallet(); -console.log(connectedWallets); +`useConnectWallet` hook exposes a wallet object of type `WalletState` which represents connected wallet state. + +Here are some typings which are briefly describe what info we can get from `WalletState` just by taking a quick look + +```typescript +interface WalletState { + label: string; + icon: string; + provider: EIP1193Provider; + accounts: Account[]; + chains: ConnectedChain[]; + instance?: unknown; +} +type Account = { + address: Address; + ens: Ens | null; + uns: Uns | null; + balance: Balances | null; + secondaryTokens?: SecondaryTokenBalances[] | null; +}; +type Balances = Record | null; +type ConnectedChain = { + id: Chain["id"]; + namespace: Chain["namespace"]; +}; ``` + +> Some types omited for brevity. Refer to Web3Onboarding documentation for full info. + +Taking a brief look shows that we can get all we need: connected chain, account address and current balance. Let's show that info! + +```tsx +{ + walletConnected ? ( +
+
Network Chain ID: {wallet?.chains?.[0].id}
+
Account Address: {wallet?.accounts?.[0].address}
+
+
Balance:
+ + {Object.keys(wallet?.accounts?.[0].balance || {}).map((tokenSymbol) => ( +
+ {wallet?.accounts?.[0].balance?.[tokenSymbol]} {tokenSymbol} +
+ ))} +
+
+ ) : null; +} +``` + +And here is the result +![image](images/blocknative/web3onboard-account-information.jpg) + +> Our UI already looks nice. But it will be your homework to make it look gorgeous + +### Additional resources + +- [Web3Onboard docs](https://onboard.blocknative.com/docs/overview/introduction) diff --git a/developers/cosmoskit-xdefi-integration.md b/developers/cosmoskit-xdefi-integration.md index 07a3eced4..7b972a1fb 100644 --- a/developers/cosmoskit-xdefi-integration.md +++ b/developers/cosmoskit-xdefi-integration.md @@ -1,6 +1,14 @@ # CosmosKit XDEFI Integration -First, your app need to install 2 packages for the XDEFI: +### Get started + +Best way to get started with CosmosKit is to scaffold new app from terminal with [create-cosmos-app](https://github.com/cosmology-tech/create-cosmos-app) + +```bash +yarn create cosmos-app +``` + +Next, you will need to install 2 packages for the XDEFI: - `@cosmos-kit/xdefi` - `@cosmos-kit/xdefi-extension` @@ -25,7 +33,7 @@ import { wallets as xdefi } from "@cosmos-kit/xdefi"; ### add to your provider -```js +```javascript function MyCosmosApp({ Component, pageProps }: AppProps) { return ( Reminder: always use `walletConnectWallet` and `injectedWallet` to support WalletConnect based wallets and other browser wallets that inject their provider into window + +You can then pass your curated list of wallets to RainbowKit `getDefaultConfig`. ```javascript -import { connectorsForWallets } from '@rainbow-me/rainbowkit'; -import { createConfig } from 'wagmi'; +import { getDefaultConfig } from "@rainbow-me/rainbowkit"; -const connectors = connectorsForWallets(/* ... */); +const wallets = [ + { + groupName: "Recommended", + wallets: [xdefiWallet], + }, + { + groupName: "Other", + wallets: [walletConnectWallet, injectedWallet], + }, +]; -const config = createConfig({ - connectors, - {/* Wagmi config */} +const config = getDefaultConfig({ + wallets, + /* Rest of the config*/ }); const queryClient = new QueryClient(); @@ -45,65 +66,149 @@ const queryClient = new QueryClient(); const App = () => ( - - {/* Your App */} - + {/* Your App */} ); ``` -### Examples +> RainbowKit `getDefaultConfig` is a wrapper around Wagmi's `createConfig` which does some job for you like creating connectors for your wallets and creating transport for chains passed to config -Here are examples: Show XDEFI Wallet along with generic fallback wallets. +### Full example ```javascript -import { connectorsForWallets } from "@rainbow-me/rainbowkit"; +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { WagmiProvider } from 'wagmi'; import { - xdefiWallet, - // other wallets -} from "@rainbow-me/rainbowkit/wallets"; - -const connectors = connectorsForWallets( - [ - { - groupName: "Suggested", - wallets: [ - xdefiWallet, - // other wallets - ], - }, + arbitrum, + base, + mainnet, + optimism, + polygon, + zora, +} from 'wagmi/chains'; +import { getDefaultConfig, RainbowKitProvider } from '@rainbow-me/rainbowkit'; + +const config = getDefaultConfig({ + appName: 'RainbowKit App', + projectId: 'YOUR_PROJECT_ID',// Required for WalletConnect based wallets + chains: [ + mainnet, + polygon, + optimism, + arbitrum, + base, + zora, ], - { appName: "RainbowKit App", projectId: "YOUR_PROJECT_ID" }, -); -``` + ssr: true, // We scaffolded Nextjs app, so, need to enable SSR for it +}); -> Reminder: The order of the wallets array defines the order in which wallets will be displayed in the UI. +const client = new QueryClient(); + +function MyApp({ Component, pageProps }: AppProps) { + return ( + + + + + + + + ); +} +``` -You also can use the `groupName` key to name different wallet groups. This is useful if you want to communicate to your users which wallets you recommend, as well as other possible wallets. +### The Wagmi's `createConfig` -Recommend XDEFI Wallet along with other wallets in a separate group +If RainbowKit `getDefaultConfig` does not work for you for some reason, you can use Wagmi's `createConfig` directly. See example below for reference ```javascript -import { connectorsForWallets } from "@rainbow-me/rainbowkit"; +import type { AppProps } from "next/app"; + +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { WagmiProvider, createConfig, http } from "wagmi"; +import { arbitrum, base, mainnet, optimism, polygon, zora } from "wagmi/chains"; +import { + connectorsForWallets, + RainbowKitProvider, +} from "@rainbow-me/rainbowkit"; import { xdefiWallet, - // other wallets + walletConnectWallet, + injectedWallet, + //other wallets } from "@rainbow-me/rainbowkit/wallets"; +import { createClient } from "viem"; const connectors = connectorsForWallets( + // you have to provide CreateConnectorFn[] list for your wallets + // when using Wagmi's createConfig [ { groupName: "Recommended", wallets: [xdefiWallet], }, { - groupName: "Others", - wallets: [ - // other wallets - ], + groupName: "Other", + wallets: [walletConnectWallet, injectedWallet], }, ], - { appName: "RainbowKit App", projectId: "YOUR_PROJECT_ID" }, + { + // Notice that our appName and projectId for WalletConnect now moved + // from config's top level to connectorsForWallets parameter + appName: "My Rainbowkit App", + projectId: "YOUR_PROJECT_ID", + } ); + +const config = createConfig({ + connectors, + chains: [mainnet, polygon, optimism, arbitrum, base, zora], + client({ chain }) { + // you have to provide client factory when using Wagmi's createConfig + return createClient({ chain, transport: http() }); + }, + ssr: true, // we scaffolded Nextjs app +}); + +const client = new QueryClient(); + +function MyApp({ Component, pageProps }: AppProps) { + return ( + + + + + + + + ); +} ``` + +### RainbowKit theming + +Once we have set up our wallets list, it's time to pick a proper theme. +RainbowKit has prebuilt light, dark and midnight themes. We'll be using prebuilt dark theme in this guide. For further theme customizations please refer to [RainbowKit theming docs](https://www.rainbowkit.com/docs/theming). + +```javascript +import { + darkTheme, // [!code ++] +} from "@rainbow-me/rainbowkit"; + ... + // [!code ++] + + + ... +``` + +### We're Done! Time to explore results + +![Expected result](images/rainbowkit/rainbowkit_integration_result.jpg) + +> Please note: If you have wallet already installed, it will be listed in "Installed" instead of "Recommended". Installed group appears automatically + +### Additional resources + +- [RainbowKit docs](https://www.rainbowkit.com/docs/) +- [Wagmi createConfig docs](https://wagmi.sh/react/api/createConfig) diff --git a/developers/solana-adapter-xdefi-integration.md b/developers/solana-adapter-xdefi-integration.md index fc7db273e..d0c76c858 100644 --- a/developers/solana-adapter-xdefi-integration.md +++ b/developers/solana-adapter-xdefi-integration.md @@ -1,52 +1,53 @@ # Solana Adapter XDEFI Integration -# Extension Wallet Solana Integration +### Get started -[[toc]] +Best way to start with solana dApps is to use [create-solana-dapp](https://github.com/solana-developers/create-solana-dapp/tree/main/packages/create-solana-dapp) -## Using Solana Adapter +```bash +npx create-solana-dapp@latest +``` -### Solana Adapter not installed +create-solana-dapp supports `React` and `NextJs` version. We'll use `NextJs` version. +![image](images/solana/solana-xdefi-integration-nextjs-template.jpg) -Install the latest wallets package: +### XDEFIWalletAdapter vs Wallet Standard -```bash -npm install @solana/wallet-adapter-xdefi@latest -``` +XDEFI wallet implements [Wallet Standard](https://github.com/wallet-standard/wallet-standard) and does not require any specific adapter to get started with Solana and XDEFI Wallet. -Once installed, you can add XDEFI Wallet by making adding this part of code: +> You can read more about Wallet Standard [here](https://docs.phantom.app/developer-powertools/wallet-standard). -```js -import { XDEFIWalletAdapter } from `@solana/wallet-adapter-xdefi`; -import { /* ... other adapters ... */ } from `@solana/wallet-adapter-wallets`; +However, XDEFIWalletAdapter provide XDEFI Wallet installation info when XDEFI Wallet is not installed. Which might be useful in many cases. +So, in case you want maintain supported wallets list, you'll need to use Adapters for parlicular wallets or maintain your own wallet connect modal with supported wallets list. -const wallets = useMemo( - () => [ - new XDEFIWalletAdapter(), - // ... other adapters ... - ], - [] -); +Here how looks when you have no adapter provided to `WalletProvider` and no wallet installed +![image](images/solana/solana-no-wallets-available.jpg) - -``` +> which might be ok for experienced users but pretty confusing for newcomers. -### Solana Adapter already installed +And here how it looks when user have some wallet installed which implements Wallet Standard +![image](images/solana/solana-detected-wallet-standard.jpg) -Install the latest wallets package: +### Using Solana Adapter + +Solana provides wallet adapters in two flavors: individual packages for each wallet or single tree-shakeable package which contains all wallet adapters available. We'll use later one. you can see all available adapters [here](https://github.com/anza-xyz/wallet-adapter/blob/master/PACKAGES.md#wallets) ```bash npm install @solana/wallet-adapter-wallets@latest ``` -Once installed, you can add XDEFI Wallet by making 2 changes: +Once installed, you can add XDEFI Wallet by making adding this part of code: -```js +```tsx import { XDEFIWalletAdapter, // [!code ++] /* ... other adapters ... */ } from `@solana/wallet-adapter-wallets`; +const onError = useCallback((error: WalletError) => { + console.error(error); +}, []); + const wallets = useMemo( () => [ new XDEFIWalletAdapter(), // [!code ++] @@ -55,11 +56,44 @@ const wallets = useMemo( [] ); - + +``` + +> `web/components/solana/solana-provider.tsx` + +Default behaviour of the `onError` callback is just log error. But what we need from it - is to redirect user to wallet home/installation page when user clicked on not installed wallet inside "Connect Wallet" modal +![image](images/solana//solana-wallet-not-installed.jpg) + +> it will just log and error and do nothing when you will try to connect not installed wallet + +Let's fix this: + +```tsx +import { + Adapter, + WalletError, + WalletNotReadyError, // [!code ++] + WalletReadyState, // [!code ++] +} from '@solana/wallet-adapter-base'; + +const onError = useCallback((error: WalletError, walletAdapter?: Adapter) => { + if (// [!code ++] + error instanceof WalletNotRea // [!code ++]dyError && + walletAdapter?.readyState === WalletReadyState.NotDetected // [!code ++] + ) {// [!code ++] + window.open(walletAdapter?.url, "_blank"); // [!code ++] + return; // [!code ++] + } // [!code ++] + console.error(error); +}, []); + ``` -## Using XDEFI Provider +> Now, when user will try to connect XDEFI Wallet while it is not installed, user will be taken to XDEFI Wallet home page in a new window. -## Using XDEFI SDK +### Additional Resources -TBD +- [create-solana-dapp](https://github.com/solana-developers/create-solana-dapp) +- [Solana Wallet Adapter](https://github.com/anza-xyz/wallet-adapter) +- [Solana Wallet Adapter Samples](https://github.com/anza-xyz/wallet-adapter/tree/master/packages/starter) +- [Wallet Standard](https://github.com/wallet-standard/wallet-standard) diff --git a/gas-tank/authentication-services.md b/gas-tank/authentication-services.md new file mode 100644 index 000000000..8b5a65f52 --- /dev/null +++ b/gas-tank/authentication-services.md @@ -0,0 +1,133 @@ +## Authentication + +### Multiple Addresses Login + +This endpoint facilitates the generation of JWT tokens for multiple wallet addresses in a single request. The request payload should consist of an array of objects, each containing an address and its corresponding signature. Upon successful validation of the signatures, the server will generate JWT tokens for the provided addresses. + +To get signatures, you can use `personal_sign` method from web3.js or ethers.js. Below is an example of how to get a signature using web3.js: + +::: code-group + +```javascript [Request] +const web3 = new Web3(window.ethereum); +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +const address1 = "0x1234567890123456789012345678901234567890"; +const address2 = "0x0987654321098765432109876543210987654321"; + +const messageToSign = await ( + await fetch(`${GAS_TANK_ENDPOINT}/v2/auth/message`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify([address1, address2]), + }) +).json(); + +const message = messageToSign.message; + + +const signature1 = await web3.eth.personal.sign(message, address1); +const signature2 = await web3.eth.personal.sign(message, address2); + +await fetch(`${GAS_TANK_ENDPOINT}/v2/auth/login`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify([ + { + address: address1, // Address of the user // [!code highlight] + signature: signature1, // Signature // [!code highlight] + }, + { + address: address2, // [!code highlight] + signature: signature2, // [!code highlight] + }, + ... + ]), +}) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) +``` + +```json [Response] +{ + "access": "jwt.access.token", + "refresh": "jwt.refresh.token" +} +``` + +::: + +You can also add new wallets to an existing JWT token. Request will be secured by JWT header. Clients need to submit an array of objects containing the address and signature for each new wallet. The server will validate the signatures and, if successful, update the existing JWT token to include the new wallets and generate new JWT. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/v2/auth/update`, { + method: "POST", + headers: { + "Content-Type": "application/json", + "Authorization": `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + body: JSON.stringify([ + { + address: newAddress, // [!code highlight] + signature: newSignature, // [!code highlight] + }, + ... + ]), +}) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) +``` + +```json [Response] +{ + "access": "jwt.access.token", + "refresh": "jwt.refresh.token" +} +``` + +::: + +### Refresh JWT Token + +Clients can use this endpoint to obtain a new JWT token without re-authenticating, providing a refresh token. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/v2/auth/refresh`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + body: JSON.stringify({ + refresh: refreshToken, // Refresh token // [!code highlight] + }), +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "access": "jwt.access.token", + "refresh": "jwt.refresh.token" +} +``` + +::: diff --git a/gas-tank/balance-services.md b/gas-tank/balance-services.md new file mode 100644 index 000000000..a4c424326 --- /dev/null +++ b/gas-tank/balance-services.md @@ -0,0 +1,553 @@ +## Balance & Transactions - Deposit, Withdraw, Send Gas + +### Get all balance entries for user + +This endpoint returns a list of all balance entries per address by using JWT + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/balances`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "additionalProp1": [ + { + "id": "string", + "address": "string", + "tokenAddress": "string", + "balance": 0, + "chain": "string" + } + ], + "additionalProp2": [ + { + "id": "string", + "address": "string", + "tokenAddress": "string", + "balance": 0, + "chain": "string" + } + ], + ... +} +``` + +::: + +### Get balances by address + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/balances/${address}`, { // Address to retrieve balances // [!code highlight] + method: "GET", + headers: { + "Content-Type": "application/json" + "Authorization": `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, +}) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) +``` + +```json [Response] +[ + { + "id": "string", + "address": "string", + "tokenAddress": "string", + "balance": 0, + "chain": "string" + }, + ... +] +``` + +::: + +### Get total balances using JWT + +This endpoint returns a list of total balances for the specified JWT. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/balances/totals`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +[ + { + "address": "string", + "symbol": "string", + "value": "string", + "decimals": 0 + }, + ... +] +``` + +::: + +### Deposit balance + +This endpoint allows users to deposit balance to the Gas Tank platform. + +To deposit the balance, you need to sign the message with the private key of the address you want to deposit the balance for. `v`, `r`, `s` are the signature fields of the message signed by the address owner and `message` is generated in [Construct Deposit Message](#construct-deposit-message). + +You can sign a string of data using [ethers.js](https://docs.ethers.org/v5), below is an example of [how to sign a message using ethers.js](https://docs.ethers.org/v5/getting-started/#getting-started--signing) and deposit the balance. + +::: code-group + +```javascript [Request] +import { ethers } from "ethers"; + +const web3 = new Web3(window.ethereum); +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; +const address = "0x1234567890123456789012345678901234567890"; // Address to deposit balance // [!code highlight] +const message = message; // Message is generated in Construct Deposit Message +const privateKey = "0x1234"; // Private key of the address // [!code highlight] +const wallet = new ethers.Wallet(privateKey); +const signature = await wallet.signMessage(message); +const { v, r, s } = ethers.utils.splitSignature(signature); + +await fetch(`${GAS_TANK_ENDPOINT}/balances/increase`, { + method: "POST", + headers: { + "Content-Type": "application/json" + "Authorization": `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + body: JSON.stringify({ + address: address, // [!code highlight] + tokenAddress: "string", // Token contract address for deposit // [!code highlight] + chain: "string", // The blockchain network [!code highlight] + owner: "string", // The owner's address (can match the 'address' field) [!code highlight] + spender: "string", // Gas Tank's internal address [!code highlight] + value: "string", // Amount of deposited token [!code highlight] + deadline: 0, // Date for checking the validity of the signature [!code highlight] + v: v, // [!code highlight] + r: r, // [!code highlight] + s: s // [!code highlight] + }), +}) + .then((response) => { + // Balance deposit successfully + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +::: + +### Withdraw balance + +This endpoint allows users to withdraw their balance from the Gas Tank platform. + +To withdraw the balance, you need to sign the message with the private key of the address you want to withdraw the balance from. The `signature` field is the signature of the message signed by the address owner and `message` is generated in [Aonstruct Withdraw Message](#construct-withdraw-message). + +Same as the [Deposit balance](#deposit-balance), you can sign a string of data using [ethers.js](https://docs.ethers.org/v5/getting-started/), below is an example of [how to sign a message using ethers.js](https://docs.ethers.org/v5/getting-started/#getting-started--signing) and withdraw the balance. + +::: code-group + +```javascript [Request] +import { ethers } from "ethers"; + +const web3 = new Web3(window.ethereum); +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; +const address = "0x1234567890123456789012345678901234567890"; // Address to withdraw balance // [!code highlight] +const message = message; // Message is generated in Construct Withdraw Message +const privateKey = "0x1234"; // Private key of the address // [!code highlight] +const wallet = new ethers.Wallet(privateKey); +const signature = await wallet.signMessage(message); + +await fetch(`${GAS_TANK_ENDPOINT}/balances/withdraw`, { + method: "POST", + headers: { + "Content-Type": "application/json" + "Authorization": `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + body: JSON.stringify({ + address: address, // [!code highlight] + tokenAddress: "string", // Token contract address for withdraw [!code highlight] + amount: "string", // Amount of withdraw token [!code highlight] + chain: "string", // The blockchain network [!code highlight] + recipient: "string", // The recipient's wallet address [!code highlight] + message: message, // [!code highlight] + signature: signature // [!code highlight] + }), +}) + .then((response) => { + // Balance withdrawn successfully + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +::: + +### Internal transfer + +This endpoint allows users to create an internal transfer task on the Gas Tank platform. The internal transfer task is used to transfer balance from one address to another address on the Gas Tank platform. The `signature` field is the signature of the message signed by the address owner and `message` is generated in [Construct Internal Transfer Message](#construct-internal-transfer-message). + +::: code-group + +```javascript [Request] +import { ethers } from "ethers"; + +const web3 = new Web3(window.ethereum); +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; +const address = "0x1234567890123456789012345678901234567890"; // Address to transfer balance // [!code highlight] +const message = message; // Message is generated in Construct Internal Transfer Message +const privateKey = "0x1234"; // Private key of the address // [!code highlight] +const wallet = new ethers.Wallet(privateKey); +const signature = await wallet.signMessage(message); + +await fetch(`${GAS_TANK_ENDPOINT}/balances/transfer`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + body: JSON.stringify({ + address: address, // [!code highlight] + tokenAddress: "string", // Token contract address for transfer [!code highlight] + amount: "string", // Amount of transfer [!code highlight] + chain: "string", // The blockchain network [!code highlight] + recipient: "string", // The recipient's wallet address [!code highlight] + message: message, // [!code highlight] + signature: signature, // [!code highlight] + }), +}) + .then((response) => { + // Internal transfer task created successfully + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +::: + +### Get a quote for consuming balance + +This endpoint allows users to generate a quote for consuming their balance on the Gas Tank platform. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/balances/consume/quote`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + body: JSON.stringify({ + address: "string", // Your wallet address // [!code highlight] + minDestinationAmount: "string", // Minimum amount of the token to consume // [!code highlight] + destinationChain: "string", // The blockchain network // [!code highlight] + }), +}) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +```json [Response] +{ + "expectedOutput": "string", + "fee": "string", + "spentAssets": [ + { + "tokenAddress": "string", + "amount": "string", + "chain": "string" + } + ] +} +``` +::: + +### Consume balance + +This endpoint allows users to consume their balance on the Gas Tank platform. + +To consume the balance, you need to sign the message with the private key of the address you want to consume the balance from. The `signature` field is the signature of the message signed by the address owner and `message` is generated in [Construct Consume Message](#construct-consume-message). + +Same as the [Deposit balance](#deposit-balance)/[Withdraw balance](#withdraw-balance), you can sign a string of data using [ethers.js](https://docs.ethers.org/v5/getting-started/), below is an example of [how to sign a message using ethers.js](https://docs.ethers.org/v5/getting-started/#getting-started--signing) and consume the balance. + +::: code-group + +```javascript [Request] +import { ethers } from "ethers"; + +const web3 = new Web3(window.ethereum); +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; +const address = "0x1234567890123456789012345678901234567890"; // Address to consume balance // [!code highlight] +const message = message; // Message is generated in Construct Consume Message +const privateKey = "0x1234"; // Private key of the address // [!code highlight] +const wallet = new ethers.Wallet(privateKey); +const signature = await wallet.signMessage(message); + +await fetch(`${GAS_TANK_ENDPOINT}/balances/consume`, { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + body: JSON.stringify({ + address: address, // [!code highlight] + minDestinationAmount: "string", // Minimum amount of the token to consume // [!code highlight] + destinationAddress: "string", // The recipient's wallet address // [!code highlight] + destinationChain: "string", // The blockchain network // [!code highlight] + message: message, // [!code highlight] + signature: signature, // [!code highlight] + }), +}) + .then((response) => { + // Balance consumed successfully + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +::: + +### Get user balance queue update + +This endpoint allows users to get the balance queue update for any job ongoing (e.g., deposit, withdrawal, transfer, consume). + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/transactions`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, +}) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +```json [Response] +{ + "additionalProp1": [ + { + "id": "string", + "type": "string", + "address": "string", + "tokenAddress": "string", + "amount": "string", + "chain": "string", + "destinationChain": "string", + "destinationAddress": "string", + "permitObject": {}, + "processed": true, + "processedMetadata": {}, + "pendingTransactions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "chain": "ethereum", + "transactionHash": "0x6b175474e89094c44da98b954eedeac495271d0f", + "blockNumber": 123456, + "balanceUpdateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "confirmed": false, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } + ], + "createdAt": "2024-04-11T04:13:07.102Z", + "updatedAt": "2024-04-11T04:13:07.102Z" + } + ], + ... +} +``` + +::: + +### Get balance queue update by ID + +This endpoint allows users to get the balance queue update for a specific ID (e.g., deposit, withdrawal, transfer, consume). + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/transactions/${id}`, { + method: "GET", + headers: { + "Content-Type": "application", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, +}) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +```json [Response] +{ + "id": "string", + "type": "string", + "address": "string", + "tokenAddress": "string", + "amount": "string", + "chain": "string", + "destinationChain": "string", + "destinationAddress": "string", + "permitObject": {}, + "processed": true, + "processedMetadata": {}, + "pendingTransactions": [ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "chain": "ethereum", + "transactionHash": "0x6b175474e89094c44da98b954eedeac495271d0f", + "blockNumber": 123456, + "balanceUpdateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "confirmed": false, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + } + ], + "createdAt": "2024-04-11T04:17:30.107Z", + "updatedAt": "2024-04-11T04:17:30.107Z" +} +``` + +::: + +### Get pending transactions by address + +This endpoint allows users to get pending transactions for a specific address. Results returned a list of pending transactions. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch( + `${GAS_TANK_ENDPOINT}/transactions/pending/${address}`, // Address to retrieve pending transaction // [!code highlight] + { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + }, +) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +```json [Response] +[ + { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "chain": "ethereum", + "transactionHash": "0x6b175474e89094c44da98b954eedeac495271d0f", + "blockNumber": 123456, + "balanceUpdateId": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "confirmed": false, + "createdAt": "2023-01-01T00:00:00Z", + "updatedAt": "2023-01-01T00:00:00Z" + }, + ... +] +``` + +::: + +### Get fee for a given amount + +This endpoint allows users to get the fee for a given amount in a specific chain. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch( + `${GAS_TANK_ENDPOINT}/fees/${chain}`, // Chain to get fee // [!code highlight] + { + method: "POST", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, + }, +) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +```json [Response] +{ + "high": "string", + "medium": "string", + "low": "string" +} +``` + +::: diff --git a/gas-tank/chains-services.md b/gas-tank/chains-services.md new file mode 100644 index 000000000..c993f2e1f --- /dev/null +++ b/gas-tank/chains-services.md @@ -0,0 +1,169 @@ +## Chains / Token / Status + +### Get all Tokens + +This endpoint allows users to retrieve information about all tokens available on the Gas Tank platform. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/chains/tokens`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "additionalProp1": { + "name": "string", + "key": "string", + "chainId": "string", + "native": { + "symbol": "string", + "decimals": 0, + "address": "string", + "actions": [ + "string" + ] + }, + "tokens": [ + { + "name": "string", + "symbol": "string", + "decimals": 0, + "address": "string", + "actions": [ + "string" + ] + } + ] + }, + "additionalProp2": { + "name": "string", + "key": "string", + "chainId": "string", + "native": { + "symbol": "string", + "decimals": 0, + "address": "string", + "actions": [ + "string" + ] + }, + "tokens": [ + { + "name": "string", + "symbol": "string", + "decimals": 0, + "address": "string", + "actions": [ + "string" + ] + } + ] + }, + ... +} +``` + +::: + +### Get dispatchers information + +This endpoint provides information about the dispatchers on the Gas Tank platform. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/chains/dispatchers-info`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "additionalProp1": { + "chain": "string", + "address": "string", + "balance": "string", + "status": "string", + "threshold": "string" + }, + "additionalProp2": { + "chain": "string", + "address": "string", + "balance": "string", + "status": "string", + "threshold": "string" + }, + ... +} +``` + +::: + +### Get chains Operational status + +This endpoint provides information about the status of all supported chains on the Gas Tank platform. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/chains/status`, { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${jwtToken}`, // JWT token // [!code highlight] + }, +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "operational": true, + "chains": [ + { + "chain": "string", + "operational": true, + "actions": { + "increase": true, + "withdraw": true, + "consume": true + }, + "extras": { + "address": "string", + "balance": "string", + "threshold": "string", + "status": "string" + }, + "comment": "string" + }, + ... + ] +} +``` + +::: diff --git a/gas-tank/gas-tank-api.md b/gas-tank/gas-tank-api.md index 5464b97f8..65ac786c3 100644 --- a/gas-tank/gas-tank-api.md +++ b/gas-tank/gas-tank-api.md @@ -1,3 +1,23 @@ -# Gas Tank API +--- +next: + text: "🔹 Campaigns Service API" + link: "/campaigns/campaigns-service-api" +--- -Coming soon... +# Gas Tank API Documentation + +The Gas Tank is a versatile platform that empowers users to manage gas tank balances seamlessly across different blockchain networks. This project facilitates actions such as depositing, withdrawing, internal transferring, and consuming gas tank balances, allowing users to efficiently utilize their resources on EVM, Cosmos-like, and UTXO chains. With support for multiple blockchain environments, The Gas Tank offers users a unified solution for gas utilization across diverse networks. Check the [Gas Tank API Swagger](https://gas-tank.xdefi.services/docs/) for more information. + +The base URL for all Gas Tank API is: https://gas-tank.xdefi.services + +Below are the available services provided by the Gas Tank API. You need to have a valid JWT token to access the services. You can get the JWT token by using the _[Multiple Address Login](#multiple-address-login)_ endpoint. + + + + + + + + + + diff --git a/gas-tank/messages-service.md b/gas-tank/messages-service.md new file mode 100644 index 000000000..a1bd5806f --- /dev/null +++ b/gas-tank/messages-service.md @@ -0,0 +1,142 @@ +## Messages + +### Construct Deposit Message + +This endpoint will generate `messages` parameter for [Deposit balances](#deposit-balance). + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/msg/increase`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + owner: "0xOwnerWalletAddress", // The wallet address of the owner // [!code highlight] + tokenAddress: "0xTokenContractAddress", // The contract address of the token // [!code highlight] + amount: "1", // Amount of the token to deposit // [!code highlight] + chain: "ethereum", // The blockchain network, e.g., 'ethereum' // [!code highlight] + }), +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "type": "string", + "message": "string" +} +``` + +::: + +### Construct Withdraw Message + +This endpoint will generate `messages` parameter for [Withdraw balances](#withdraw-balance). + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/msg/withdraw`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + address: "0xYourWalletAddress", // Your wallet address // [!code highlight] + tokenAddress: "0xTokenContractAddress", // The contract address of the token // [!code highlight] + amount: "1", // Amount of the token to withdraw // [!code highlight] + chain: "ethereum", // The blockchain network, e.g., 'ethereum' // [!code highlight] + recipient: "0xRecipientWalletAddress", // The recipient's wallet address // [!code highlight] + }), +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "type": "string", + "message": "string" +} +``` + +::: + +### Construct Internal Transfer Message + +This endpoint will generate `messages` parameter for [Internal Transfer balances](#internal-transfer). + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/msg/internal-transfer`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + address: "0xYourWalletAddress", // Your wallet address // [!code highlight] + tokenAddress: "0xTokenContractAddress", // The contract address of the token // [!code highlight] + amount: "1", // Amount of the token to transfer // [!code highlight] + chain: "ethereum", // The blockchain network, e.g., 'ethereum' // [!code highlight] + recipient: "0xRecipientWalletAddress", // The recipient's wallet address // [!code highlight] + }), +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "type": "string", + "message": "string" +} +``` + +::: + +### Construct Consume Message + +This endpoint will generate `messages` parameter for [Consume balances](#consume-balance). + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/msg/consume`, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + address: "0xYourWalletAddress", // Your wallet address // [!code highlight] + minDestinationAmount: "1", // Minimum amount of the token to consume // [!code highlight] + destinationChain: "ethereum", // The blockchain network, e.g., 'ethereum' // [!code highlight] + }), +}).then((response) => { + console.log(response); + // Handle & do something with the response +}); +``` + +```json [Response] +{ + "type": "string", + "message": "string" +} +``` + +::: diff --git a/gas-tank/other-services.md b/gas-tank/other-services.md new file mode 100644 index 000000000..327fd0078 --- /dev/null +++ b/gas-tank/other-services.md @@ -0,0 +1,110 @@ +## Other services + +This section provides information about the other services provided by the Gas Tank API. APIs in this section not require JWT token for authentication. + +### Get information about the Gas Tank + +This endpoint provides information about the conversion rates between different tokens and fees for deposit, withdrawal and consume actions. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/balances/info`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, +}) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +```json [Response] +{ + "conversionRates": { + "xdefi": { + "eth": 0.00003406230336183101, + "bnb": 0.00020052618581142264, + "usdc": 0.13496037812654052, + "usdt": 0.1349557894736842, + ... + }, + "eth": { + "xdefi": 29357.967644682656, + "usdt": 3763.926315789474, + ... + }, + ... // Other pairs + }, + "spenderAddresses": [ + "0x0E87C393120410d1edd00Ae5b616419795c5B57D" + ], + "fees": { + "deposit": { + "fees": { + "high": "357840000000000", + "medium": "357420000000000", + "low": "357210000000000" + } + }, + "withdraw": { + "fees": { + "high": "357840000000000", + "medium": "357420000000000", + "low": "357210000000000" + } + }, + "consume": { + "fees": { + "high": "357840000000000", + "medium": "357420000000000", + "low": "357210000000000" + } + } + } +} +``` + +::: + +### Check the status of the application + +This endpoint provides information about the status of the Gas Tank application and its dependencies. + +::: code-group + +```javascript [Request] +const GAS_TANK_ENDPOINT = "https://gas-tank.xdefi.services"; + +await fetch(`${GAS_TANK_ENDPOINT}/healthcheck`, { + method: "GET", + headers: { + "Content-Type": "application/json", + }, +}) + .then((response) => { + console.log(response); + // Handle & do something with the response + }) + .catch((error) => { + // Catch & handle the error + }); +``` + +```json [Response] +{ + "status": "OK", + "database": "Connected", + "mnemonic": "Set", + "nats": "Connected" +} +``` + +::: diff --git a/staking/staking-api.md b/staking/staking-api.md index 1c9074a2c..5cf4c0b04 100644 --- a/staking/staking-api.md +++ b/staking/staking-api.md @@ -6,7 +6,7 @@ Staking is a process that involves holding funds in a cryptocurrency wallet to s XDEFI offers a staking API that enables developers to engage with the staking features across multiple blockchain networks. This API is crafted for simplicity and ease of use, emphasizing a high degree of abstraction from the complexities of the underlying blockchains. -The base URL for all API endpoints is: https://gql-router.dev.xdefi.services/graphql +The base URL for all API endpoints is: https://gql-router.xdefi.services/graphql Below are the services provided by the staking API. @@ -28,7 +28,7 @@ You can use the `getStrideStakedAssetBalance` query to get the balance of a stak ::: code-group ```javascript [GetStrideStakedAssetBalance] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query GetStrideStakedAssetBalance($strideAddress: String!, $asset: SupportedAssets!) { staking { getStrideStakedAssetBalance(asset: $asset, strideAddress: $strideAddress) { @@ -80,7 +80,7 @@ You can use the `createStrideLiquidStakingTx` mutation to create a staking trans ::: code-group ```javascript [CreateStrideLiquidStakingTx] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query CreateStrideLiquidStakingTx($input: StrideStakingInput!) { staking { createStrideLiquidStakingTx(input: $input) @@ -134,7 +134,7 @@ You can use the `getCosmosDelegations` query to get the delegations of a Cosmos ::: code-group ```javascript [GetCosmosDelegations] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query getCosmosDelegations($asset: SupportedAssets!, $address: String!) { staking { getCosmosDelegations(address: $address, asset: $asset) { @@ -189,7 +189,7 @@ You can use the `createCosmosDelegateTx` mutation to create a native staking tra ::: code-group ```javascript [Meria/StakeLab Validator] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query CreateCosmosDelegateTx($delegationInput: CosmosDelegationInput!, $validatorAddress: String, $provider: Providers) { staking { createCosmosDelegateTx( @@ -230,7 +230,7 @@ await fetch(GRAPHQL_ENDPOINT, { ``` ```javascript [Custom validator’s address] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query CreateCosmosDelegateTx($delegationInput: CosmosDelegationInput!, $validatorAddress: String, $provider: Providers) { staking { createCosmosDelegateTx( @@ -293,7 +293,7 @@ You can use the `getLidoStakedAssetBalance` query to get the balance of a staked ::: code-group ```javascript [GetLidoStakedBalance] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query GetLidoStakedBalance($asset: SupportedAssets!, $address: String!) { staking { getLidoStakedBalance(address: $address, asset: $asset) { @@ -343,7 +343,7 @@ You can use the `createLidoStakeTx` query to create a staking transaction on LID ::: code-group ```javascript [CreateLidoStakeTx] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query CreateLidoStakeTx($input: LidoStakingInput!) { staking { createLidoStakeTx(input: $input) { @@ -397,7 +397,7 @@ You can use the `lidoCheckErc20Allowance` query to check the allowance for staki ::: code-group ```javascript [LidoCheckErc20Allowance] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query LidoCheckErc20Allowance($ownerAddress: String!, $asset: SupportedAssets!) { staking { lidoCheckErc20Allowance(input: {ownerAddress: $ownerAddress, asset: $asset}) @@ -443,7 +443,7 @@ You can use the `createErc20ApproveTx` query to create an approval transaction t ::: code-group ```javascript [CreateErc20ApproveTx] -const GRAPHQL_ENDPOINT = "https://gql-router.dev.xdefi.services/graphql"; +const GRAPHQL_ENDPOINT = "https://gql-router.xdefi.services/graphql"; const query = `query createErc20ApproveTx($input: Erc20ApproveInput!) { staking { createErc20ApproveTx(input: $input) {