diff --git a/app/globals.css b/app/globals.css index 131bb56db..917073190 100644 --- a/app/globals.css +++ b/app/globals.css @@ -89,4 +89,36 @@ width: 100%; object-fit: cover; } - \ No newline at end of file + + +/* make the SVG follow surrounding text color */ +.svg-inherit { color: inherit; } + +/* always recolor fills; don't add a stroke unless it already exists */ +.svg-inherit * { fill: currentColor; } +.svg-inherit [fill="none"] { fill: none; } +.svg-inherit [stroke]:not([stroke="none"]) { stroke: currentColor; } + +/* 24×24 container, centers any aspect-ratio icon */ +.icon-24 { + width: 24; + height: 24; + display: inline-flex; + align-items: center; + justify-content: center; + line-height: 0; +} + +/* scale the SVG so the larger dimension becomes 24px */ +.icon-24 > svg { + max-width: 50%; + max-height: 100%; + width: auto; + height: auto; +} + + +/* color inheritance (from earlier) */ +.svg-inherit { color: inherit; } +.svg-inherit [fill]:not([fill="none"]) { fill: currentColor; } +.svg-inherit [stroke]:not([stroke="none"]) { stroke: currentColor; } \ No newline at end of file diff --git a/app/layout.tsx b/app/layout.tsx index 56e0811ae..c916b3a39 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -74,7 +74,7 @@ export default async function RootLayout({ pageMap={await getPageMap()} docsRepositoryBase="https://github.com/availproject/docs/tree/main" editLink="Edit this page on GitHub" - sidebar={{ defaultMenuCollapseLevel: 2, autoCollapse: true, toggleButton: true }} + sidebar={{ defaultMenuCollapseLevel: 1, autoCollapse: true, toggleButton: true }} footer={footer} search={ -**SET UP THE SDK BEFORE YOU START:** - -You can find the SDK setup instructions in the [Overview](/api-reference/avail-nexus-sdk/overview) page. - - -Use the `bridge()` function to bridge tokens between chains across all supported networks. - -## Parameters - -```typescript showLineNumbers filename="Typescript" -/** - * Parameters for bridging tokens. - */ -export interface BridgeParams { - token: SUPPORTED_TOKENS; - amount: number | string; - chainId: SUPPORTED_CHAINS_IDS; - gas?: bigint; -} -``` - -## Example - -```typescript showLineNumbers filename="Typescript" -import type { BridgeParams, BridgeResult, SimulationResult } from '@avail-project/nexus'; - -// Bridge tokens between chains -const result: BridgeResult = await sdk.bridge({ - token: 'USDC', - amount: 100, - chainId: 137, -} as BridgeParams); - -// Simulate bridge to preview costs -const simulation: SimulationResult = await sdk.simulateBridge({ - token: 'USDC', - amount: 100, - chainId: 137, -}); -``` - -## Return Value - -```typescript showLineNumbers filename="Typescript" -/** - * Result structure for bridge transactions. - */ -export interface BridgeResult { - success: boolean; - error?: string; - explorerUrl?: string; - transactionHash?: string; // Add transaction hash property -} -``` \ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-core/transfer/page.mdx b/app/nexus/avail-nexus-sdk/examples/nexus-core/transfer/page.mdx deleted file mode 100644 index 9d64dfc2c..000000000 --- a/app/nexus/avail-nexus-sdk/examples/nexus-core/transfer/page.mdx +++ /dev/null @@ -1,76 +0,0 @@ ---- -title: "Transfer tokens using the Nexus SDK" ---- - -import { Callout, Steps, Tabs } from 'nextra/components' - -# `transfer()` - - -**SET UP THE SDK BEFORE YOU START:** - -You can find the SDK setup instructions in the [Overview](/api-reference/avail-nexus-sdk/overview) page. - - -Use the `transfer()` function to transfer tokens to a specific recipient across all supported chains. - -## Parameters - -`TransferParams` is an object that contains the following properties: - -```typescript showLineNumbers filename="Typescript" -/** - * Parameters for transferring tokens. - */ -export interface TransferParams { - token: SUPPORTED_TOKENS; - amount: number | string; - chainId: SUPPORTED_CHAINS_IDS; - recipient: `0x${string}`; -} -``` - -## Example - -```typescript showLineNumbers filename="Typescript" -import type { TransferParams, TransferResult } from '@avail-project/nexus'; - -// Smart transfer with automatic optimization -const result: TransferResult = await sdk.transfer({ - token: 'USDC', - amount: 100, - chainId: 42161, // Arbitrum - recipient: '0x...', -} as TransferParams); - -// The SDK automatically: -// 1. Checks if you have USDC + ETH for gas on Arbitrum -// 2. Uses direct EVM transfer if available (faster, cheaper) -// 3. Falls back to chain abstraction if local funds insufficient - -// Simulate transfer to preview costs and optimization path -const simulation: SimulationResult = await sdk.simulateTransfer({ - token: 'USDC', - amount: 100, - chainId: 42161, - recipient: '0x...', -}); - -// Check if direct transfer will be used -console.log('Fees:', simulation.intent.fees); -// For direct transfers: gasSupplied shows actual native token cost -// For CA transfers: includes additional CA routing fees -``` - -## Return Value - -```typescript showLineNumbers filename="Typescript" -/** - * Result structure for transfer transactions. - */ -export interface TransferResult { - success: boolean; - error?: string; - explorerUrl?: string; -} -``` \ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-core/_meta.ts b/app/nexus/avail-nexus-sdk/nexus-core/_meta.ts similarity index 85% rename from app/nexus/avail-nexus-sdk/examples/nexus-core/_meta.ts rename to app/nexus/avail-nexus-sdk/nexus-core/_meta.ts index d80e10e77..fcda62c02 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-core/_meta.ts +++ b/app/nexus/avail-nexus-sdk/nexus-core/_meta.ts @@ -1,7 +1,7 @@ export default { "fetch-unified-balances": "Unified Balance", "transfer": "Transfer", - "bridge-tokens": "Bridge", + "bridge": "Bridge", "bridge-and-execute": "Bridge & Execute", "api-reference": "API Reference" } \ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-core/api-reference/page.mdx b/app/nexus/avail-nexus-sdk/nexus-core/api-reference/page.mdx similarity index 73% rename from app/nexus/avail-nexus-sdk/examples/nexus-core/api-reference/page.mdx rename to app/nexus/avail-nexus-sdk/nexus-core/api-reference/page.mdx index d6b129bdf..9a55978b5 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-core/api-reference/page.mdx +++ b/app/nexus/avail-nexus-sdk/nexus-core/api-reference/page.mdx @@ -12,8 +12,8 @@ The Avail Nexus headlessSDK provides a comprehensive set of APIs for cross-chain ## Quick Start -```typescript showLineNumbers filename="Typescript" -import { NexusSDK } from '@avail-project/nexus'; +```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" +import { NexusSDK } from '@avail-project/nexus-core'; // Initialize SDK const sdk = new NexusSDK({ network: 'mainnet' }); @@ -23,24 +23,12 @@ await sdk.initialize(provider); // Your wallet provider const balances = await sdk.getUnifiedBalances(); console.log('All balances:', balances); -// Get swap-specific balances -const swapBalances = await sdk.getSwapBalances(); -console.log('Swap balances:', swapBalances); - -// Swap tokens (EXACT_IN - specify input amount) -const swapResult = await sdk.swap({ - fromAmount: parseUnits('100', 6), // 100 USDC - fromChainID: 137, // Polygon - fromTokenAddress: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', // USDC on Polygon - toChainID: 1, // Ethereum - toTokenAddress: '0xA0b86a33E6441E02ad58c70b70fa3c2b3c3e74C9', // ETH on Ethereum -}); - // Bridge tokens const bridgeResult = await sdk.bridge({ token: 'USDC', amount: 100, chainId: 137, // to Polygon + sourceChains: [10, 42161], // Only use USDC from `Optimism` and `Arbitrum` as source for bridge }); // Transfer tokens (automatically optimized) @@ -49,6 +37,7 @@ const transferResult = await sdk.transfer({ amount: 0.1, chainId: 1, // Uses direct transfer if ETH + gas available on Ethereum recipient: '0x742d35Cc6634C0532925a3b8D4C9db96c4b4Db45', + sourceChains: [8453], // Only use ETH from `Base` as source for bridge }); const executeResult = await sdk.execute({ @@ -119,32 +108,13 @@ const executeResult = await sdk.execute({ | USDC | USD Coin | 6 | All supported | | USDT | Tether USD | 6 | All supported | -
-How to fetch supported chains from the SDK? - -```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" -import { SUPPORTED_CHAINS } from @avail-project/nexus; - -// Mainnet Chain IDs -SUPPORTED_CHAINS.ETHEREUM; // 1 -SUPPORTED_CHAINS.OPTIMISM; // 10 -SUPPORTED_CHAINS.POLYGON; // 137 -SUPPORTED_CHAINS.ARBITRUM; // 42161 -SUPPORTED_CHAINS.AVALANCHE; // 43114 -SUPPORTED_CHAINS.BASE; // 8453 -SUPPORTED_CHAINS.LINEA; // 59144 -SUPPORTED_CHAINS.SCROLL; // 534351 -``` -
- - ## API Reference ### Initialization -```typescript showLineNumbers filename="Typescript" -import { NexusSDK } from '@avail-project/nexus'; -import type { NexusNetwork } from '@avail-project/nexus'; +```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" +import { NexusSDK } from '@avail-project/nexus-core'; +import type { NexusNetwork } from '@avail-project/nexus-core'; // Mainnet (default) const sdk = new NexusSDK(); @@ -158,8 +128,8 @@ await sdk.initialize(window.ethereum); // Returns: Promise ### Event Handling -```typescript showLineNumbers filename="Typescript" -import type { OnIntentHook, OnAllowanceHook, EventListener } from '@avail-project/nexus'; +```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" +import type { OnIntentHook, OnAllowanceHook, EventListener } from '@avail-project/nexus-core'; // Intent approval flows sdk.setOnIntentHook(({ intent, allow, deny, refresh }: Parameters[0]) => { @@ -199,8 +169,8 @@ sdk.onChainChanged((chainId) => console.log('Chain:', chainId)); #### Progress Events for All Operations -```typescript showLineNumbers filename="Typescript" -import { NEXUS_EVENTS, ProgressStep } from '@avail-project/nexus'; +```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" +import { NEXUS_EVENTS, ProgressStep } from '@avail-project/nexus-core'; // Bridge & Execute Progress const unsubscribeBridgeExecuteExpected = sdk.nexusEvents.on( @@ -274,24 +244,20 @@ All events include the same `typeID` structure and runtime `data` such as `trans ### Unified Balance(s) -```typescript showLineNumbers filename="Typescript" -import type { UserAsset, TokenBalance } from '@avail-project/nexus'; +```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" +import type { UserAsset, TokenBalance } from '@avail-project/nexus-core'; // Get all balances across chains const balances: UserAsset[] = await sdk.getUnifiedBalances(); // Get balance for specific token const usdcBalance: UserAsset | undefined = await sdk.getUnifiedBalance('USDC'); - -// Get swap balances -const swapBalances: SwapBalances = await sdk.getSwapBalances(); - ``` ### Bridge Operations -```typescript showLineNumbers filename="Typescript" -import type { BridgeParams, BridgeResult, SimulationResult } from '@avail-project/nexus'; +```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" +import type { BridgeParams, BridgeResult, SimulationResult } from '@avail-project/nexus-core'; // Bridge tokens between chains const result: BridgeResult = await sdk.bridge({ @@ -310,8 +276,8 @@ const simulation: SimulationResult = await sdk.simulateBridge({ ### Transfer Operations -```typescript showLineNumbers filename="Typescript" -import type { TransferParams, TransferResult } from '@avail-project/nexus'; +```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" +import type { TransferParams, TransferResult } from '@avail-project/nexus-core'; // Smart transfer with automatic optimization const result: TransferResult = await sdk.transfer({ @@ -342,7 +308,7 @@ console.log('Fees:', simulation.intent.fees); ### Execute Operations -```typescript showLineNumbers filename="Typescript" +```typescript showLineNumbers filename="Typescript" showLineNumbers filename="Typescript" import type { ExecuteParams, ExecuteResult, @@ -350,7 +316,7 @@ import type { BridgeAndExecuteParams, BridgeAndExecuteResult, BridgeAndExecuteSimulationResult, -} from '@avail-project/nexus'; +} from '@avail-project/nexus-core'; // Execute contract functions with dynamic parameter builder - Compound V3 Supply const result: ExecuteResult = await sdk.execute({ @@ -402,6 +368,7 @@ const bridgeAndExecuteResult: BridgeAndExecuteResult = await sdk.bridgeAndExecut token: 'USDC', amount: '100000000', // 100 USDC (6 decimals) toChainId: 1, // Ethereum + sourceChains: [8453], // Only use USDC from `Base` as source for bridge execute: { contractAddress: '0xa354F35829Ae975e850e23e9615b11Da1B3dC4DE', // Yearn USDC Vault contractAbi: [ @@ -449,137 +416,10 @@ console.log('Approval required:', simulation.metadata?.approvalRequired); console.log('Bridge receive amount:', simulation.metadata?.bridgeReceiveAmount); ``` -### Swap Operations +## Allowance Management ```typescript showLineNumbers filename="Typescript" -import type { SwapInput, SwapResult, SwapBalances } from '@avail-project/nexus'; - -// EXACT_IN Swap - Specify exact input amount, variable output -const exactInSwap: SwapResult = await sdk.swap({ - fromAmount: parseUnits('100', 6), // Exactly 100 USDC - fromChainID: 137, // Polygon - fromTokenAddress: '0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174', // USDC on Polygon - toChainID: 1, // Ethereum - toTokenAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH on Ethereum -}); - -// EXACT_OUT Swap - Specify exact output amount, variable input -const exactOutSwap: SwapResult = await sdk.swap({ - toAmount: parseUnits('1', 18), // Exactly 1 ETH output - toChainID: 1, // Ethereum - toTokenAddress: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', // WETH on Ethereum - // fromAmount, fromChainID, fromTokenAddress determined automatically -}, { - swapIntentHook: async (data: SwapIntentHook) => { - // use this to capture the intent allow, reject and refresh functions - const {intent, allow, reject, refresh} = data; - // Use it to handle user interaction - // - // setSwapIntent(intent); - // setAllowCallback(allow); - // setRejectCallback(reject); - // setRefreshCallback(refresh); - - // or directly approve or reject the intent - allow() - },); - -// Cross-chain swap with custom options -const crossChainSwap: SwapResult = await sdk.swap( - { - fromAmount: parseUnits('50', 6), // 50 USDC - fromChainID: 42161, // Arbitrum - fromTokenAddress: '0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8', // USDC on Arbitrum - toChainID: 10, // Optimism - toTokenAddress: '0x4200000000000000000000000000000000000006', // WETH on Optimism - }, - { - swapIntentHook: async (data: SwapIntentHook) => { - // use this to capture the intent allow, reject and refresh functions - const {intent, allow, reject, refresh} = data; - // Use it to handle user interaction or display transaction details - - // setSwapIntent(intent); - // setAllowCallback(allow); - // setRejectCallback(reject); - // setRefreshCallback(refresh); - - // or directly approve or reject the intent - // calling allow processes the txn - allow() - }, - } -); - -// Handle swap results -if (exactInSwap.success) { - console.log('✅ Swap successful!'); - console.log('Source transaction:', exactInSwap.sourceExplorerUrl); - console.log('Destination transaction:', exactInSwap.destinationExplorerUrl); -} else { - console.error('❌ Swap failed:', exactInSwap.error); -} - -// Get swap-specific balances for better UX -const swapBalances: SwapBalances = await sdk.getSwapBalances(); -console.log('Available for swapping:', swapBalances); -``` - - -**Note:** - -- **Source chains/tokens** are restricted to what `getSwapSupportedChainsAndTokens()` returns -- **Destination chains/tokens** can be any supported chain and token address -- `DESTINATION_SWAP_TOKENS` provides popular destination options but is not exhaustive - - -
-`Swap` Types - -**EXACT_IN Swaps:** -- You specify exactly how much you want to spend (`fromAmount`) -- Output amount varies based on market conditions and fees -- Use case: "I want to swap all my 100 USDC" - -**EXACT_OUT Swaps:** -- You specify exactly how much you want to receive (`toAmount`) -- Input amount varies based on market conditions and fees -- Use case: "I need exactly 1 ETH for a specific purpose" -
- -#### Swap Progress Events - -```typescript showLineNumbers filename="Typescript" -import { NEXUS_EVENTS } from '@avail-project/nexus'; - -// Listen for swap progress updates -const unsubscribeSwapSteps = sdk.nexusEvents.on( - NEXUS_EVENTS.SWAP_STEPS, - (step) => { - console.log('Swap step:', step.type); - - if (step.type === 'SOURCE_SWAP_HASH' && step.explorerURL) { - console.log('Source transaction:', step.explorerURL); - } - - if (step.type === 'DESTINATION_SWAP_HASH' && step.explorerURL) { - console.log('Destination transaction:', step.explorerURL); - } - - if (step.type === 'SWAP_COMPLETE' && step.completed) { - console.log('✅ Swap completed successfully!'); - } - }, -); - -// Cleanup -unsubscribeSwapSteps(); -``` - -### Allowance Management - -```typescript showLineNumbers filename="Typescript" -import type { AllowanceResponse } from '@avail-project/nexus'; +import type { AllowanceResponse } from '@avail-project/nexus-core'; // Check allowances const allowances: AllowanceResponse[] = await sdk.getAllowance(137, ['USDC', 'USDT']); @@ -591,21 +431,21 @@ await sdk.setAllowance(137, ['USDC'], 1000000n); await sdk.revokeAllowance(137, ['USDC']); ``` -### Intent Management +## Intent Management ```typescript showLineNumbers filename="Typescript" -import type { RequestForFunds } from '@avail-project/nexus'; +import type { RequestForFunds } from '@avail-project/nexus-core'; // Get user's transaction intents const intents: RequestForFunds[] = await sdk.getMyIntents(1); ``` -### Utilities +## Utilities All utility functions are available under `sdk.utils`: ```typescript showLineNumbers filename="Typescript" -import type { ChainMetadata, TokenMetadata, SUPPORTED_TOKENS } from '@avail-project/nexus'; +import type { ChainMetadata, TokenMetadata, SUPPORTED_TOKENS } from '@avail-project/nexus-core'; // Address utilities const isValid: boolean = sdk.utils.isValidAddress('0x...'); @@ -634,17 +474,17 @@ const isSupportedToken: boolean = sdk.utils.isSupportedToken('USDC'); const chains: Array<{ id: number; name: string; logo: string }> = sdk.utils.getSupportedChains(); // Swap discovery utilities -const swapOptions: SwapSupportedChainsResult = sdk.utils.getSwapSupportedChainsAndTokens(); +const swapOptions: SupportedChainsResult = sdk.utils.getSwapSupportedChainsAndTokens(); // Chain ID conversion const hexChainId: string = sdk.utils.chainIdToHex(137); const decimalChainId: number = sdk.utils.hexToChainId('0x89'); ``` -### Provider Methods +## Provider Methods ```typescript showLineNumbers filename="Typescript" -import type { EthereumProvider, RequestArguments } from '@avail-project/nexus'; +import type { EthereumProvider, RequestArguments } from '@avail-project/nexus-core'; // Get chain abstracted provider const provider: EthereumProvider = sdk.getEVMProviderWithCA(); @@ -661,10 +501,11 @@ await sdk.deinit(); ### Usage Examples -#### Basic Bridge with Result Handling + +### Basic Bridge with Result Handling ```typescript showLineNumbers filename="Typescript" -import { NexusSDK, type BridgeResult } from '@avail-project/nexus'; +import { NexusSDK, type BridgeResult } from '@avail-project/nexus-core'; const sdk = new NexusSDK(); await sdk.initialize(window.ethereum); @@ -689,10 +530,10 @@ try { } ``` -#### Execute with Receipt Confirmation +### Execute with Receipt Confirmation ```typescript showLineNumbers filename="Typescript" -import type { ExecuteResult } from '@avail-project/nexus'; +import type { ExecuteResult } from '@avail-project/nexus-core'; // MakerDAO DSR (Dai Savings Rate) Deposit const result: ExecuteResult = await sdk.execute({ @@ -737,10 +578,10 @@ console.log('Gas used:', result.gasUsed); console.log('Confirmations:', result.confirmations); ``` -#### Complete Portfolio Management +### Complete Portfolio Management ```typescript showLineNumbers filename="Typescript" -import type { UserAsset, ChainMetadata } from '@avail-project/nexus'; +import type { UserAsset, ChainMetadata } from '@avail-project/nexus-core'; // Get complete balance overview const balances: UserAsset[] = await sdk.getUnifiedBalances(); @@ -759,10 +600,10 @@ for (const asset of balances) { } ``` -### Error Handling +## Error Handling ```typescript showLineNumbers filename="Typescript" -import type { BridgeResult } from '@avail-project/nexus'; +import type { BridgeResult } from '@avail-project/nexus-core'; try { const result: BridgeResult = await sdk.bridge({ token: 'USDC', amount: 100, chainId: 137 }); @@ -786,7 +627,7 @@ try { ``` ```typescript showLineNumbers filename="Typescript" -import type { ExecuteSimulation, ExecuteResult } from '@avail-project/nexus'; +import type { ExecuteSimulation, ExecuteResult } from '@avail-project/nexus-core'; // Simulate before executing const simulation: ExecuteSimulation = await sdk.simulateExecute(params); @@ -818,7 +659,7 @@ import type { SwapInput, SwapResult, SwapBalances, - SwapSupportedChainsResult, + SupportedChainsResult, DESTINATION_SWAP_TOKENS, UserAsset, TokenBalance, @@ -831,5 +672,5 @@ import type { RequestArguments, EventListener, NexusNetwork, -} from '@avail-project/nexus'; +} from '@avail-project/nexus-core'; ``` \ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-core/bridge-and-execute/page.mdx b/app/nexus/avail-nexus-sdk/nexus-core/bridge-and-execute/page.mdx similarity index 84% rename from app/nexus/avail-nexus-sdk/examples/nexus-core/bridge-and-execute/page.mdx rename to app/nexus/avail-nexus-sdk/nexus-core/bridge-and-execute/page.mdx index 2dbfa92f9..2546b2a68 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-core/bridge-and-execute/page.mdx +++ b/app/nexus/avail-nexus-sdk/nexus-core/bridge-and-execute/page.mdx @@ -9,9 +9,19 @@ import { Callout, Steps, Tabs } from 'nextra/components' **SET UP THE SDK BEFORE YOU START:** -You can find the SDK setup instructions in the [Overview](/api-reference/avail-nexus-sdk/overview) page. +1. You can find the SDK setup instructions in the [Quickstart](/nexus/nexus-quickstart) page. +2. We also [created a tutorial](/nexus/nexus-examples/nexus-initialization-basic) to make it easier to understand how devs need to initialize the Nexus SDK in their project. +Use the `bridgeAndExecute()` function to bridge a token and execute a contract function on the recipient chain in a single flow. + +## Method signature + +```typescript showLineNumbers filename="Typescript" +async bridgeAndExecute(params: BridgeAndExecuteParams): Promise +async simulateBridgeAndExecute(params: BridgeAndExecuteParams): Promise +``` + ## Parameters ```typescript showLineNumbers filename="Typescript" @@ -20,6 +30,7 @@ export interface BridgeAndExecuteParams { token: SUPPORTED_TOKENS; amount: number | string; recipient?: `0x${string}`; + sourceChains?: number[]; execute?: Omit; enableTransactionPolling?: boolean; transactionTimeout?: number; @@ -32,7 +43,7 @@ export interface BridgeAndExecuteParams { } ``` -# Example +## Example ```typescript showLineNumbers filename="Typescript" import type { @@ -42,7 +53,7 @@ import type { BridgeAndExecuteParams, BridgeAndExecuteResult, BridgeAndExecuteSimulationResult, -} from '@avail-project/nexus'; +} from '@avail-project/nexus-core'; // Execute contract functions with dynamic parameter builder - Compound V3 Supply const result: ExecuteResult = await sdk.execute({ @@ -94,6 +105,7 @@ const bridgeAndExecuteResult: BridgeAndExecuteResult = await sdk.bridgeAndExecut token: 'USDC', amount: '100000000', // 100 USDC (6 decimals) toChainId: 1, // Ethereum + sourceChains: [8453], // Only use USDC from `Base` as source for bridge execute: { contractAddress: '0xa354F35829Ae975e850e23e9615b11Da1B3dC4DE', // Yearn USDC Vault contractAbi: [ @@ -143,6 +155,8 @@ console.log('Bridge receive amount:', simulation.metadata?.bridgeReceiveAmount); ## Return Value +The return value is a `BridgeAndExecuteResult` object. + ```typescript showLineNumbers filename="Typescript" export interface BridgeAndExecuteResult { executeTransactionHash?: string; diff --git a/app/nexus/avail-nexus-sdk/nexus-core/bridge/page.mdx b/app/nexus/avail-nexus-sdk/nexus-core/bridge/page.mdx new file mode 100644 index 000000000..2859a515d --- /dev/null +++ b/app/nexus/avail-nexus-sdk/nexus-core/bridge/page.mdx @@ -0,0 +1,87 @@ +--- +title: "Bridge tokens using the Nexus SDK" +--- + +import { Callout, Steps, Tabs } from 'nextra/components' + +# `bridge()` + + +**SET UP THE SDK BEFORE YOU START:** + +1. You can find the SDK setup instructions in the [Quickstart](/nexus/nexus-quickstart) page. +2. We also [created a tutorial](/nexus/nexus-examples/nexus-initialization-basic) to make it easier to understand how devs need to initialize the Nexus SDK in their project. + + +Use the `bridge()` function to bridge a specific token from one (*or many*) chains to a single chain. + +## Method signature + +```typescript showLineNumbers filename="Typescript" +async bridge(params: BridgeParams): Promise +async simulateBridge(params: BridgeParams): Promise +``` + +## Parameters + +```typescript showLineNumbers filename="Typescript" +/** + * Parameters for bridging tokens. + */ +export interface BridgeParams { + token: SUPPORTED_TOKENS; + amount: number | string; + chainId: SUPPORTED_CHAINS_IDS; + gas?: bigint; + sourceChains?: number[]; +} +``` + + +1. `chainID` refers to the Chain ID of the recipient chain. +2. `sourceChains` is an optional param that takes an array of chainIDs. +Use this if you want only some of your funds to be used for bridging.. +Helpful if you want to maintain your holdings on some chains. + + +## Example + +```typescript showLineNumbers filename="Typescript" +import type { BridgeParams, BridgeResult, SimulationResult } from '@avail-project/nexus-core'; + +// Bridge tokens between chains +const result: BridgeResult = await sdk.bridge({ + token: 'USDC', + amount: 100, + chainId: 137, + sourceChains: [84532, 80002], // Only use USDC from `Base Sepolia` and `Polygon Amoy` as sources for the bridge +} as BridgeParams); + +// Simulate bridge to preview costs +// Note that you can avoid using optional params +const simulation: SimulationResult = await sdk.simulateBridge({ + token: 'USDC', + amount: 100, + chainId: 137, +}); +``` + +## Return Value + +The return value is a `BridgeResult` object, which is a union type. + +```typescript showLineNumbers filename="Typescript" +/** + * Result structure for bridge transactions. + */ +export type BridgeResult = + | { + success: false; + error: string; + } + | { + success: true; + explorerUrl: string; + transactionHash?: string; + }; +``` \ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-core/fetch-unified-balances/page.mdx b/app/nexus/avail-nexus-sdk/nexus-core/fetch-unified-balances/page.mdx similarity index 64% rename from app/nexus/avail-nexus-sdk/examples/nexus-core/fetch-unified-balances/page.mdx rename to app/nexus/avail-nexus-sdk/nexus-core/fetch-unified-balances/page.mdx index 5e509036f..0b1e071a1 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-core/fetch-unified-balances/page.mdx +++ b/app/nexus/avail-nexus-sdk/nexus-core/fetch-unified-balances/page.mdx @@ -9,18 +9,27 @@ import { Callout, Steps, Tabs } from 'nextra/components' **SET UP THE SDK BEFORE YOU START:** -You can find the SDK setup instructions in the [Overview](/api-reference/avail-nexus-sdk/overview) page. +1. You can find the SDK setup instructions in the [Quickstart](/nexus/nexus-quickstart) page. +2. We also [created a tutorial](/nexus/nexus-examples/nexus-initialization-basic) to make it easier to understand how devs need to initialize the Nexus SDK in their project. -Use these functions to fetch consolidated token balances across all supported chains. -This shows users their total available liquidity without needing to check each chain individually. +Use these functions to fetch consolidated token balances across all supported chains in one call. **Note:** Check out the [API reference](/api-reference/avail-nexus-sdk/api-reference) for a full list of supported tokens and chains. +## Method signatures + +```typescript showLineNumbers filename="Typescript" +async getUnifiedBalances(): Promise +async getUnifiedBalance(symbol: string): Promise +``` + ## Parameters +- `symbol` (string, required for `getUnifiedBalance`): Token symbol, e.g. `'USDC' | 'USDT' | 'ETH'`. + ### `getUnifiedBalances()` Fetches the unified balance of all tokens across all chains for a user. @@ -64,23 +73,26 @@ class UserAsset { get balance(): string; // Getter for balance } -// The underlying data structure -interface UserAssetDatum { - symbol: string; // Token symbol (e.g., 'USDC', 'ETH') - balance: string; // Total balance across all chains - balanceInFiat: number; // USD value of the balance - decimals: number; // Token decimals - breakdown: { // Per-chain breakdown array - balance: string; // Balance on this specific chain - balanceInFiat: number; // USD value on this chain +// The underlying data structure for `UserAsset` +export type UserAssetDatum = { + abstracted?: boolean; + balance: string; + balanceInFiat: number; + breakdown: { + balance: string; + balanceInFiat: number; chain: { - id: number; // Chain ID - logo: string; // Chain logo URL - name: string; // Chain name + id: number; + logo: string; + name: string; }; - contractAddress: `0x${string}`; // Token contract address - decimals: number; // Token decimals on this chain - isNative?: boolean; // Whether this is native token (optional) + contractAddress: `0x${string}`; + decimals: number; + isNative?: boolean; + universe: Universe; }[]; -} + decimals: number; + icon?: string; + symbol: string; +}; ``` \ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/nexus-core/transfer/page.mdx b/app/nexus/avail-nexus-sdk/nexus-core/transfer/page.mdx new file mode 100644 index 000000000..63a95c84d --- /dev/null +++ b/app/nexus/avail-nexus-sdk/nexus-core/transfer/page.mdx @@ -0,0 +1,101 @@ +--- +title: "Transfer tokens using the Nexus SDK" +--- + +import { Callout, Steps, Tabs } from 'nextra/components' + +# `transfer()` + + +**SET UP THE SDK BEFORE YOU START:** + +You can find the SDK setup instructions in the [Overview](/nexus/avail-nexus-sdk/nexus-core/api-reference/) page. + + +Use the `transfer()` function to convert multiple tokens from multiple chains to a single token on a single chain. + +## Method signature + +```typescript showLineNumbers filename="Typescript" +async transfer(params: TransferParams): Promise +async simulateTransfer(params: TransferParams): Promise +``` + +## Parameters + +```typescript showLineNumbers filename="Typescript" +/** + * Parameters for transferring tokens. + */ +export interface TransferParams { + token: SUPPORTED_TOKENS; + amount: number | string; + chainId: SUPPORTED_CHAINS_IDS; + recipient: `0x${string}`; + sourceChains?: number[]; +} +``` + + +1. `chainID` refers to the Chain ID of the recipient chain. +2. `sourceChains` is an optional param that takes an array of chainIDs. +Use this if you want only some of your funds to be used for the transfer. +Helpful if you want to maintain your holdings on some chains. + + +## Example + +```typescript showLineNumbers filename="Typescript" +import type { TransferParams, TransferResult, SimulationResult } from '@avail-project/nexus-core'; + +// Smart transfer with automatic optimization +const result: TransferResult = await sdk.transfer({ + token: 'USDC', // Convert selected tokens to USDC + amount: 100, + chainId: 42161, // Transfer selected funds to Arbitrum + recipient: '0x...', + sourceChains: [84532, 80002], // Only use ETH from `Base Sepolia` and `Polygon Amoy` as sources for the transfer +} as TransferParams); + +// The SDK automatically: +// 1. Checks if you have USDC + ETH for gas on Arbitrum +// 2. Uses direct EVM transfer if available (faster, cheaper) +// 3. Falls back to chain abstraction if local funds insufficient + +// Simulate transfer to preview costs and optimization path +const simulation: SimulationResult = await sdk.simulateTransfer({ + token: 'USDC', + amount: 100, + chainId: 42161, + recipient: '0x...', + sourceChains: [84532, 80002], +}); + +// Check if direct transfer will be used +console.log('Fees:', simulation.intent.fees); +// For direct transfers: gasSupplied shows actual native token cost +// For CA transfers: includes additional CA routing fees +``` + +## Return Value + +The return value is a `TransferResult` object, which is a union type. + +```typescript showLineNumbers filename="Typescript" +/** + * Result structure for transfer transactions. + */ +export type TransferResult = + +// Upon success, returns the transaction hash and explorer url + | { + success: true; + transactionHash: string; + explorerUrl: string; + } + // Upon failure, returns the error message + | { + success: false; + error: string; + }; +``` \ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/_meta.ts b/app/nexus/avail-nexus-sdk/nexus-widgets/_meta.ts similarity index 80% rename from app/nexus/avail-nexus-sdk/examples/nexus-widgets/_meta.ts rename to app/nexus/avail-nexus-sdk/nexus-widgets/_meta.ts index b41189069..a47eb4bae 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/_meta.ts +++ b/app/nexus/avail-nexus-sdk/nexus-widgets/_meta.ts @@ -1,6 +1,6 @@ export default { "transfer": "Transfer", - "bridge-tokens": "Bridge", + "bridge": "Bridge", "bridge-and-execute": "Bridge & Execute", "api-reference": "API Reference" } \ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/api-reference/page.mdx b/app/nexus/avail-nexus-sdk/nexus-widgets/api-reference/page.mdx similarity index 77% rename from app/nexus/avail-nexus-sdk/examples/nexus-widgets/api-reference/page.mdx rename to app/nexus/avail-nexus-sdk/nexus-widgets/api-reference/page.mdx index 38f95e398..4a12b9362 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/api-reference/page.mdx +++ b/app/nexus/avail-nexus-sdk/nexus-widgets/api-reference/page.mdx @@ -148,11 +148,9 @@ import { BridgeButton, TransferButton, BridgeAndExecuteButton, - SwapButton, TOKEN_CONTRACT_ADDRESSES, TOKEN_METADATA, SUPPORTED_CHAINS, - DESTINATION_SWAP_TOKENS, type SUPPORTED_TOKENS, type SUPPORTED_CHAIN_IDS } from '@avail-project/nexus-widgets'; @@ -213,23 +211,6 @@ import { parseUnits } from 'viem'; )} - -/* Swap | EXACT_IN ------------------------------------------------------------- */ - - {({ onClick, isLoading }) => ( - - )} - ``` ## Component APIs @@ -366,104 +347,6 @@ Nexus then: 2. Sets ERC-20 allowance if required 3. Executes `contractAddress.functionName(functionParams, { value })` -### `SwapButton` - -Cross-chain token swapping with support for both EXACT_IN and EXACT_OUT modes. - -```tsx showLineNumbers filename="TSX" -interface SwapButtonProps { - title?: string; // Will appear once initialization is completed - prefill?: Omit; // fromChainID, toChainID, fromTokenAddress, toTokenAddress, fromAmount - className?: string; - children(props: { onClick(): void; isLoading: boolean }): React.ReactNode; -} - -interface SwapInputData { - fromChainID?: number; - toChainID?: number; - fromTokenAddress?: string; - toTokenAddress?: string; - fromAmount?: string | number; - toAmount?: string | number; -} -``` - -**EXACT_IN Swap Example:** - -```tsx showLineNumbers filename="TSX" -// Swap exactly 100 USDC from Polygon to LDO on Arbitrum - - {({ onClick, isLoading }) => ( - - )} - -``` - -## Swap Utilities - -### Discovering Available Swap Options - -```tsx showLineNumbers filename="TSX" -import { useNexus, DESTINATION_SWAP_TOKENS } from '@avail-project/nexus-widgets'; - -function SwapOptionsExample() { - const { sdk, isSdkInitialized } = useNexus(); - const [swapOptions, setSwapOptions] = useState(null); - - useEffect(() => { - if (isSdkInitialized) { - // Get supported source chains and tokens for swaps - const supportedOptions = sdk.utils.getSwapSupportedChainsAndTokens(); - setSwapOptions(supportedOptions); - } - }, [sdk, isSdkInitialized]); - - return ( -
- {/* Source chains and tokens */} - {swapOptions?.map(chain => ( -
-

{chain.name} (Chain ID: {chain.id})

- {chain.tokens.map(token => ( -
- {token.symbol}: {token.tokenAddress} -
- ))} -
- ))} - - {/* Popular destination options */} -

Popular Destinations:

- {Array.from(DESTINATION_SWAP_TOKENS.entries()).map(([chainId, tokens]) => ( -
-

Chain {chainId}

- {tokens.map(token => ( -
- {token.symbol} - {token.name} -
- ))} -
- ))} -
- ); -} -``` - -**Key Points:** -- **Source restrictions**: Source chains/tokens are limited to what `getSwapSupportedChainsAndTokens()` returns -- **Destination flexibility**: Destination can be any supported chain and token address -- **DESTINATION_SWAP_TOKENS**: Provides popular destination options for UI building, but is not exhaustive - ## Prefill Behavior | Widget | Supported keys | Locked in UI | @@ -471,61 +354,9 @@ function SwapOptionsExample() { | `BridgeButton` | `chainId`, `token`, `amount` | ✅ | | `TransferButton` | `chainId`, `token`, `amount`, `recipient` | ✅ | | `BridgeAndExecuteButton` | `toChainId`, `token`, `amount` | ✅ | -| `SwapButton` | `fromChainID`, `toChainID`, `fromTokenAddress`, `toTokenAddress`, `fromAmount`, `toAmount` | ✅ | Values passed in `prefill` appear as **read-only** fields, enforcing your desired flow. -## Widget Examples - -### Cross-Chain Swapping - -```tsx showLineNumbers filename="TSX" -// Multi-step cross-chain swap with destination selection - - {({ onClick, isLoading }) => ( -
-

Cross-Chain Swap

-

Swap tokens across any supported chains

- -
- )} -
- -// Fixed-route swap for arbitrage or specific pairs - - {({ onClick, isLoading }) => ( -
-

Arbitrage Opportunity

-

Better WETH rates on Optimism

- -
- )} -
-``` - ### DeFi Protocol Integration ```tsx showLineNumbers filename="TSX" diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/bridge-and-execute/page.mdx b/app/nexus/avail-nexus-sdk/nexus-widgets/bridge-and-execute/page.mdx similarity index 83% rename from app/nexus/avail-nexus-sdk/examples/nexus-widgets/bridge-and-execute/page.mdx rename to app/nexus/avail-nexus-sdk/nexus-widgets/bridge-and-execute/page.mdx index 0bce00aba..c797c909e 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/bridge-and-execute/page.mdx +++ b/app/nexus/avail-nexus-sdk/nexus-widgets/bridge-and-execute/page.mdx @@ -9,7 +9,8 @@ import { Callout, Tabs } from 'nextra/components' **SET UP THE SDK BEFORE YOU START:** -You can find the SDK setup instructions in the [Overview](/api-reference/avail-nexus-sdk/overview) page. +1. You can find the SDK setup instructions in the [Quickstart](/nexus/nexus-quickstart) page. +2. We also [created a tutorial](/nexus/nexus-examples/nexus-initialization-basic) to make it easier to understand how devs need to initialize the Nexus SDK in their project. Use the `BridgeAndExecuteButton` component to provide a pre-built interface that handles bridging tokens to a destination chain and then executing a smart contract function on that chain in a single flow. @@ -20,25 +21,17 @@ Useful for flows like *“bridge 500 USDC to Base and stake it in a lending pool ## Props ```typescript showLineNumbers filename="Typescript" -type DynamicParamBuilder = ( - token: SUPPORTED_TOKENS, - amount: string, - chainId: SUPPORTED_CHAINS_IDS, - userAddress: `0x${string}`, -) => { - functionParams: readonly unknown[]; - value?: string; // wei; defaults to "0" -}; - -interface BridgeAndExecuteButtonProps { - title?: string; // Will appear once intialization is completed - contractAddress: `0x${string}`; // REQUIRED - contractAbi: Abi; // REQUIRED - functionName: string; // REQUIRED - buildFunctionParams: DynamicParamBuilder; // REQUIRED - prefill?: { toChainId?: number; token?: SUPPORTED_TOKENS; amount?: string }; - className?: string; - children(props: { onClick(): void; isLoading: boolean; disabled: boolean }): React.ReactNode; +export interface BridgeAndExecuteButtonProps extends BaseComponentProps { + contractAddress: `0x${string}`; + contractAbi: Abi; + functionName: string; + buildFunctionParams: DynamicParamBuilder; + prefill?: { + toChainId?: SUPPORTED_CHAINS_IDS; + token?: SUPPORTED_TOKENS; + amount?: string; + }; + children: (props: { onClick: () => void; isLoading: boolean; disabled: boolean }) => ReactNode; } ``` diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/bridge-tokens/page.mdx b/app/nexus/avail-nexus-sdk/nexus-widgets/bridge/page.mdx similarity index 59% rename from app/nexus/avail-nexus-sdk/examples/nexus-widgets/bridge-tokens/page.mdx rename to app/nexus/avail-nexus-sdk/nexus-widgets/bridge/page.mdx index e6622304b..39a9c52ac 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/bridge-tokens/page.mdx +++ b/app/nexus/avail-nexus-sdk/nexus-widgets/bridge/page.mdx @@ -9,37 +9,24 @@ import { Callout, Tabs } from 'nextra/components' **SET UP THE SDK BEFORE YOU START:** -You can find the SDK setup instructions in the [Overview](/api-reference/avail-nexus-sdk/overview) page. +1. You can find the SDK setup instructions in the [Quickstart](/nexus/nexus-quickstart) page. +2. We also [created a tutorial](/nexus/nexus-examples/nexus-initialization-basic) to make it easier to understand how devs need to initialize the Nexus SDK in their project. -Use the `BridgeButton` component to provide a pre-built bridge interface that handles token bridging between supported chains. -The widget automatically manages the bridge flow, UI modals, and transaction state. - - -**Note:**
+Use the `BridgeButton` component to provide a pre-built bridge interface that handles token bridging between supported chains. -1. We made a small demo website that implements the `BridgeButton` widget. -Check it out here: [nexus-ui-components-demo.vercel.app](https://nexus-ui-components-demo.vercel.app/) - -2. If you just want to see an example that uses the `BridgeButton` widget, -refer to the repo here: [nexus-ui-components-demo](https://github.com/availproject/nexus-ui-components-demo/blob/main/src/components/nexus.tsx#L20) -
+The widget automatically manages the bridge flow, UI modals, and transaction state. ## Props ```typescript showLineNumbers filename="Typescript" -interface BridgeButtonProps { - title?: string; // Will appear once intialization is completed - prefill?: Partial; // chainId, token, amount - className?: string; - children(props: { onClick(): void; isLoading: boolean }): React.ReactNode; -} +import type { BridgeParams } from '@avail-project/nexus-core'; -interface BridgeConfig { - token?: SUPPORTED_TOKENS; - amount?: number | string; - chainId?: SUPPORTED_CHAINS_IDS; - gas?: bigint; +interface BridgeButtonProps { + title?: string; // Appears in the modal header once initialization completes + prefill?: Partial; // chainId, token, amount (locked in the UI) + className?: string; // Applied to the wrapper div around your trigger content + children(props: { onClick(): void; isLoading: boolean }): React.ReactNode; // render prop trigger } ``` @@ -78,16 +65,16 @@ import { NexusProvider, BridgeButton } from '@avail-project/nexus-widgets'; function App() { return ( - {({ onClick, isLoading }) => ( )} diff --git a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/transfer/page.mdx b/app/nexus/avail-nexus-sdk/nexus-widgets/transfer/page.mdx similarity index 63% rename from app/nexus/avail-nexus-sdk/examples/nexus-widgets/transfer/page.mdx rename to app/nexus/avail-nexus-sdk/nexus-widgets/transfer/page.mdx index a356fadcb..2e0d36604 100644 --- a/app/nexus/avail-nexus-sdk/examples/nexus-widgets/transfer/page.mdx +++ b/app/nexus/avail-nexus-sdk/nexus-widgets/transfer/page.mdx @@ -9,20 +9,24 @@ import { Callout, Tabs } from 'nextra/components' **SET UP THE SDK BEFORE YOU START:** -You can find the SDK setup instructions in the [Overview](/api-reference/avail-nexus-sdk/overview) page. +1. You can find the SDK setup instructions in the [Quickstart](/nexus/nexus-quickstart) page. +2. We also [created a tutorial](/nexus/nexus-examples/nexus-initialization-basic) to make it easier to understand how devs need to initialize the Nexus SDK in their project. -Use the `TransferButton` component to provide a pre-built transfer interface that handles token transfers to any wallet address on any supported chain. +Use the `TransferButton` component for a pre-built interface that handles token transfers to any wallet address on any supported chain. + The widget automatically manages the transfer flow, UI modals, and transaction state. ## Props ```typescript showLineNumbers filename="Typescript" +import type { TransferParams } from '@avail-project/nexus-core'; + interface TransferButtonProps { - title?: string; // Will appear once intialization is completed - prefill?: Partial; // chainId, token, amount, recipient - className?: string; - children(props: { onClick(): void; isLoading: boolean }): React.ReactNode; + title?: string; // Appears in the modal header once initialization completes + prefill?: Partial; // Params required by the `.transfer()` function + className?: string; // Applied to the wrapper div around your trigger content + children(props: { onClick(): void; isLoading: boolean }): React.ReactNode; // render prop trigger } ``` @@ -61,12 +65,12 @@ import { NexusProvider, TransferButton } from '@avail-project/nexus-widgets'; function App() { return ( - {({ onClick, isLoading }) => ( diff --git a/app/nexus/avail-nexus-sdk/page.mdx b/app/nexus/avail-nexus-sdk/page.mdx index b52e1a1c6..c47322c10 100644 --- a/app/nexus/avail-nexus-sdk/page.mdx +++ b/app/nexus/avail-nexus-sdk/page.mdx @@ -4,82 +4,55 @@ title: Avail Nexus SDK Reference asIndexPage: true --- -import { Callout, Steps, Tabs } from 'nextra/components'; +import { Callout, Steps, Tabs, Cards } from 'nextra/components' +import { FileIcon, LinkIcon, GithubIcon24 } from '@components/icons' -# Avail Nexus +# Avail Nexus SDK Reference -A powerful TypeScript SDK for cross-chain operations, token bridging, and unified balance management across multiple EVM chains. +This section contains dedicated pages for the main functions exposed by the Avail Nexus SDK as part of \ +`nexus-core` and `nexus-widgets`. -## Get Started +## Nexus Core -The Nexus SDK is split into two main packages: +### Links + + } href="https://github.com/availproject/nexus-sdk/tree/main/packages/core" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://www.npmjs.com/package/@avail-project/nexus-core?activeTab=code" target="_blank" rel="noopener noreferrer" arrow /> + -1. [**@avail-project/nexus**](https://github.com/availproject/nexus-sdk/tree/main/packages/core): Headless SDK for cross-chain operations - - No React dependencies required - - Direct Chain Abstraction integration +### Docs -### Install: + + } href="/nexus/avail-nexus-sdk/nexus-core/fetch-unified-balances" /> + } href="/nexus/avail-nexus-sdk/nexus-core/bridge" /> + } href="/nexus/avail-nexus-sdk/nexus-core/transfer" /> + } href="/nexus/avail-nexus-sdk/nexus-core/bridge-and-execute" /> + } href="/nexus/avail-nexus-sdk/nexus-core/api-reference" /> + - +## Nexus Widgets - -```bash filename="Terminal" -npm install @avail-project/nexus -``` - +### Links - -```bash filename="Terminal" -yarn add @avail-project/nexus -``` - + + } href="https://github.com/availproject/nexus-sdk/tree/main/packages/widgets" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://www.npmjs.com/package/@avail-project/nexus-widgets?activeTab=code" target="_blank" rel="noopener noreferrer" arrow /> + - -```bash filename="Terminal" -pnpm add @avail-project/nexus -``` - +### Docs - + + } href="/nexus/avail-nexus-sdk/nexus-widgets/transfer" /> + } href="/nexus/avail-nexus-sdk/nexus-widgets/bridge" /> + } href="/nexus/avail-nexus-sdk/nexus-widgets/bridge-and-execute" /> + } href="/nexus/avail-nexus-sdk/nexus-widgets/api-reference" /> + - +## Common Utils and Constants -1. The headless SDK still requires an injected wallet provider (e.g. MetaMask, WalletConnect, etc.) -2. It is designed for client-side browser environments and **cannot be used** in any server-side environments. - +In these files you can find a suite of helper function exposed by the SDK, as well as some constants and addresses that are used throughout the SDK. -2. [**@avail-project/nexus-widgets**](https://github.com/availproject/nexus-sdk/tree/main/packages/widgets): Convenient React components for plug-n-play - - Ready-to-use React components for seamless integration - - Drop-in bridge, transfer, bridge-and-execute and execute components - -### Install: - - - - -```bash filename="Terminal" -npm install @avail-project/nexus-widgets -``` - - - -```bash filename="Terminal" -yarn add @avail-project/nexus-widgets -``` - - - -```bash filename="Terminal" -pnpm add @avail-project/nexus-widgets -``` - - - - - - -**YOU WILL NEED A REACT-BASED FRONTEND**
- -1. Any React-based dev environment works, including React frameworks like Next.js, Remix, Gatsby, or build tools like Vite, Create React App, and Webpack. -2. You also need the following peer dependencies: `react` , `react-dom`, `viem`. -
\ No newline at end of file + + } href="https://github.com/availproject/nexus-sdk/blob/main/packages/commons/utils/index.ts" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://github.com/availproject/nexus-sdk/blob/main/packages/commons/constants/index.ts" target="_blank" rel="noopener noreferrer" arrow /> + \ No newline at end of file diff --git a/app/nexus/nexus-cheatsheet/page.mdx b/app/nexus/nexus-cheatsheet/page.mdx new file mode 100644 index 000000000..31b2d2fdd --- /dev/null +++ b/app/nexus/nexus-cheatsheet/page.mdx @@ -0,0 +1,76 @@ +--- +image: "/img/docs-link-preview.png" +title: Nexus cheat sheet +description: "A single page to find all external links and resources to help you get started with Avail Nexus" +--- + +import { Callout, Steps, Tabs, Cards } from 'nextra/components'; +import { FileIcon, FilesIcon, LinkIcon, GithubIcon24 } from '@components/icons' + + +# Nexus cheat sheet + +We created this page to make it easier for devs to navigate between all the links and resources related to Avail Nexus. +Feel free to suggest any additions you think are missing. + +## Nexus SDK + +The most convenient way to interact with the decentralized solver network powering Avail Nexus is through the Nexus SDK. + +Link to the Nexus SDK Github repo: + + +} arrow /> + + +The overall Nexus SDK is split into two main packages: + +### Nexus-core + +The headless version , for fine-grained control over the Nexus SDK. + + + } href="https://github.com/availproject/nexus-sdk/tree/main/packages/core" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://www.npmjs.com/package/@avail-project/nexus-core?activeTab=code" target="_blank" rel="noopener noreferrer" arrow /> + + +We also built a demo app with `nexus-core` to provide more reference code: + + + } href="https://avail-nexus-demo-five.vercel.app/" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://github.com/availproject/avail-nexus-demo" target="_blank" rel="noopener noreferrer" arrow /> + + +### Nexus-widgets + +Comes with built-in UI components to make it easier to integrate the Nexus SDK into your React app. + + + } href="https://github.com/availproject/nexus-sdk/tree/main/packages/widgets" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://www.npmjs.com/package/@avail-project/nexus-widgets?activeTab=code" target="_blank" rel="noopener noreferrer" arrow /> + + +We also built a demo app with `nexus-widgets` to provide more reference code: + + + } href="https://nexus-demo.availproject.org/" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://github.com/availproject/nexus-ui-components-demo" target="_blank" rel="noopener noreferrer" arrow /> + + +### Common Utils and Constants + +In these files you can find a suite of helper function exposed by the SDK, as well as some constants and addresses that are used throughout the SDK. + + + } href="https://github.com/availproject/nexus-sdk/blob/main/packages/commons/utils/index.ts" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://github.com/availproject/nexus-sdk/blob/main/packages/commons/constants/index.ts" target="_blank" rel="noopener noreferrer" arrow /> + + +## Nexus SDK templates + +Clone these repos to quickly get started with the Nexus SDK using `Next JS` or `Vite`. + + + } href="https://github.com/availproject/nexus-nextjs-template" target="_blank" rel="noopener noreferrer" arrow /> + } href="https://github.com/availproject/nexus-vite-template" target="_blank" rel="noopener noreferrer" arrow /> + \ No newline at end of file diff --git a/app/nexus/nexus-examples/_meta.ts b/app/nexus/nexus-examples/_meta.ts new file mode 100644 index 000000000..451812215 --- /dev/null +++ b/app/nexus/nexus-examples/_meta.ts @@ -0,0 +1,6 @@ +export default { + "nexus-initialization-basic": "Barebones initialization inside Next JS", + "nexus-initialization-rainbowkit": "Initialize the Nexus SDK using RainbowKit", + // "nexus-porto-extension": "Add Porto Wallet to Your Nexus SDK Project", + // "nexus-bridge": "Bridge tokens using the Nexus SDK", +} diff --git a/app/nexus/nexus-examples/nexus-initialization-basic/page.mdx b/app/nexus/nexus-examples/nexus-initialization-basic/page.mdx new file mode 100644 index 000000000..adc5fd3b5 --- /dev/null +++ b/app/nexus/nexus-examples/nexus-initialization-basic/page.mdx @@ -0,0 +1,350 @@ +--- +title: "Get Started with the Nexus SDK using Next JS" +description: "This tutorial will help you get started with the Nexus SDK using Next JS" +keywords: + - docs + - Avail Nexus + - Next JS + - Vite + - Nexus SDK initialization + - Unified balances + - Fetch Balances using the Nexus SDK +--- + +import { Callout, Steps, Tabs } from 'nextra/components'; + +# Get Started with the Nexus SDK using Next JS + + +**WANT TO SKIP THE TUTORIAL?**
+We created two template repos for devs to easily get started with the Nexus SDK using Next JS and Vite. +We recommend going through the tutorial first, but to each their own: + +1. [availproject/nexus-nextjs-template](https://github.com/availproject/nexus-nextjs-template) +2. [availproject/nexus-vite-template](https://github.com/availproject/nexus-vite-template) +
+ +## Prerequisites + + +The following tutorial uses `pnpm` as the package manager, adjust the commands +if you're using a different one. + + +1. Make sure [Node.js](https://nodejs.org/en) is installed on your system. We recommend +version `20.x.x` or higher. + +2. Set up a package manager of your choice. We use [pnpm](https://pnpm.io/) for this tutorial, +but alternatives like [npm](https://www.npmjs.com/) and [yarn](https://yarnpkg.com/) work just fine. + +3. Make sure you have an [EIP-1193](https://eips.ethereum.org/EIPS/eip-1193) compatible wallet provider (for example, MetaMask) installed in your browser to follow along with the tutorial. + +## Objectives + +By the end of this tutorial you will have: + +1. Understood how to initialize the Nexus SDK inside a frontend environment. +2. Implemented said initialization using Next JS. +3. Fetched unified balances using the Nexus SDK. + + +**WHAT IS A 'UNIFIED BALANCE'?**
+You can refer to this [page in our docs](/nexus/concepts/unified-balance) for more details. +
+ +## What Does 'Initialization' Mean Here? + +- The Nexus SDK allows you to seamlessly transfer tokens across-chains using the `.transfer()` +and `.bridge()` functions *(We'll go through them in the following tutorials)*. You can also fetch unified balances using the `.getUnifiedBalances()` function. + +- To do any of that though, the SDK needs access to a wallet. You can do this on the frontend +by using an injected wallet provider that follows the [`EIP-1193`](https://eips.ethereum.org/EIPS/eip-1193) standard. + +- And to do that, you need to call the `.initialize()` function of the SDK while passing +the wallet provider to it. + +- The flows to do this differ between the headless and the widgets SDK. +We will go over both of them in this tutorial. + + +The `.initialize()` function must be called **AFTER** a wallet has been connected. +Otherwise, the SDK will throw an error. + + +## Initialize the Nexus SDK using Next JS (A minimal example using nexus-core) + +### Objective + +In this section we will create a minimal Next JS page with 4 buttons: + +1. The first button will be used to connect a wallet to the app. +2. The second button will be used to initialize the SDK using `nexus-core`. +3. The third button will be used to fetch the unified balances using the Nexus SDK. +4. The fourth button will de-initialize the SDK using the `deinit()` function. + +### Set up a basic Next JS project + +1. Navigate into a directory of your choice and create a new Next JS project at it's root: + +```bash filename="Terminal" +pnpm create next-app@latest . --ts --eslint --app --src-dir +``` + +2. Install the `nexus-core` package: + +```bash filename="Terminal" +pnpm add @avail-project/nexus-core +``` + +3. Update the `src/app/page.tsx` file to the following: + +```tsx filename="src/app/page.tsx" showLineNumbers +export default function Home() { + return
Hello Nexus!
; +} +``` + +4. Run a dev server using: + +```bash filename="Terminal" +pnpm dev +``` + +You should now have a bare bones Next JS project running in your browser. \ +Let us now get down to business!!! + +### Set up an instance of the Nexus SDK + +We will set up a single instance of the Nexus SDK and use it across the app. +This will help keep the code clean and make it easier to understand the flow of the app. + +1. Create a file at `src/lib/nexus.ts` and add the following code: + +```tsx filename="src/lib/nexus.ts" showLineNumbers +import { NexusSDK } from '@avail-project/nexus-core'; + +export const sdk = new NexusSDK({ network: 'testnet'}); +``` + +This initializes the Nexus SDK with the `testnet` chains. +If this param is not provided, the SDK will default to `mainnet`. + + +You can check out a complete list of the supported networks [here](/nexus/avail-nexus-sdk/examples/nexus-core/api-reference#supported-chains). + + +2. Now fill the page with the following helper functions: + +```tsx showLineNumbers filename="src/lib/nexus.ts" + +// Thin wrapper that calls sdk.isInitialized() from the SDK +export function isInitialized() { + return sdk.isInitialized(); +} + +export async function initializeWithProvider(provider: any) { + if (!provider) throw new Error('No EIP-1193 provider (e.g., MetaMask) found'); + + //If the SDK is already initialized, return + if (sdk.isInitialized()) return; + + //If the SDK is not initialized, initialize it with the provider passed as a parameter + await sdk.initialize(provider); +} + +export async function deinit() { + + //If the SDK is not initialized, return + if (!sdk.isInitialized()) return; + + //If the SDK is initialized, de-initialize it + await sdk.deinit(); +} + +export async function getUnifiedBalances() { + + //Get the unified balances from the SDK + return await sdk.getUnifiedBalances(); +} +``` + +Let's quickly go over the role of each function: + +1. `isInitialized()`: This thin wrapper calls `sdk.isInitialized()` from the Nexus SDK to query and return the initialization status of the SDK. +2. `initializeWithProvider(provider: any)`: This function checks if the SDK is already initialized and if not, it initializes it with the provider passed as a parameter. + +This function must be called **AFTER** a wallet has been connected. +Otherwise, the SDK will throw an error. + +3. `deinit()`: This function checks if the SDK is initialized and if so, it de-initializes it. +4. `getUnifiedBalances()`: This function calls `sdk.getUnifiedBalances()` from the Nexus SDK to fetch the unified balance of the user. + +### Set up the buttons + +Create four new files in the `src/components` directory: + + + +#### connect-button.tsx + +This component will be used to connect a `EIP-1193` compatible wallet to the app. + +```tsx filename="src/components/connect-button.tsx" showLineNumbers +'use client'; + +export default function ConnectButton({ className }: { className?: string }) { + const onClick = async () => { + const eth = (window as any)?.ethereum; + if (!eth) return alert('Install an EIP-1193 wallet (e.g., MetaMask)'); + await eth.request?.({ method: 'eth_requestAccounts' }); + alert('Wallet already connected'); + }; + return ; +} +``` + +#### init-button.tsx + +This component will be used to initialize the SDK using `nexus-core`. + +This tutorial only covers the **default injected provider** (`window.ethereum`). If you are planning to use other wallets that utilize **Wagmi such as RainbowKit, Privy etc.**, check out our other articles that cover how to get a Web3 Provider from that wallet to initialize the SDK. + +- [RainbowKit](http://docs.availproject.org/nexus/nexus-examples/nexus-rainbowkit-extension) + + + +```tsx filename="src/components/init-button.tsx" showLineNumbers +'use client'; + +import { initializeWithProvider, isInitialized } from '../lib/nexus'; + +export default function InitButton({ + className, + onReady, +}: { className?: string; onReady?: () => void }) { + const onClick = async () => { + const eth = (window as any)?.ethereum; + try { + // We're calling our wrapper function from the lib/nexus.ts file here. + // Essentially calls "sdk.initialize(provider)" - SDK method. + await initializeWithProvider(eth); + onReady?.(); + alert('Nexus initialized'); + } catch (e: any) { + alert(e?.message ?? 'Init failed'); + } + }; + return ; +} +``` + +#### fetch-unified-balance-button.tsx + +This component will be used to fetch the unified balances using the Nexus SDK. + +```tsx filename="src/components/fetch-unified-balance-button.tsx" showLineNumbers +'use client'; + +import { getUnifiedBalances, isInitialized } from '../lib/nexus'; + +export default function FetchUnifiedBalanceButton({ + className, + onResult, +}: { className?: string; onResult?: (r: any) => void }) { + const onClick = async () => { + if (!isInitialized()) return alert('Initialize first'); + const res = await getUnifiedBalances(); + onResult?.(res); + console.log(res); + }; + return ; +} +``` + +#### de-init-button.tsx + +This component will be used to de-initialize the SDK using the `deinit()` function. + +```tsx filename="src/components/de-init-button.tsx" showLineNumbers +'use client'; + +import { deinit, isInitialized } from '../lib/nexus'; + +export default function DeinitButton({ + className, + onDone, +}: { className?: string; onDone?: () => void }) { + const onClick = async () => { + await deinit(); + onDone?.(); + alert('Nexus de-initialized'); + }; + return ; +} +``` + + + +### Set up the Landing Page + +Update the `src/app/page.tsx` file to the following: + +```tsx filename="src/app/page.tsx" showLineNumbers +'use client'; + +import { useState } from 'react'; +import ConnectButton from '@/components/connect-button'; +import InitButton from '@/components/init-button'; +import FetchUnifiedBalanceButton from '@/components/fetch-unified-balance-button'; +import DeinitButton from '@/components/de-init-button'; +import { isInitialized } from '@/lib/nexus'; + +export default function Page() { + const [initialized, setInitialized] = useState(isInitialized()); + const [balances, setBalances] = useState(null); + + const btn = + 'px-4 py-2 rounded-md bg-blue-600 text-white hover:bg-blue-700 ' + + 'disabled:opacity-50 disabled:cursor-not-allowed'; + + return ( +
+
+ + setInitialized(true)} /> + setBalances(r)} /> + { setInitialized(false); setBalances(null); }} /> + +
+ Nexus SDK Initialization Status: {initialized ? 'Initialized' : 'Not initialized'} +
+ + {balances && ( +
{JSON.stringify(balances, null, 2)}
+ )} +
+
+ ); +} +``` + +`sdk.getUnifiedBalances()` returns a JSON object with the balances of the user on each of the supported chains. +We're rendering it out on the screen raw to keep the tutorial simple, but you can always format it as you please. + + +**What's Happening Here?** + +1. We use the `useState` hook to manage the initialization status and balances of the SDK. +2. Some basic CSS is applied to the buttons to arrange them in a column. +3. Some buttons are conditionally toggled based on the initialization status of the SDK. +4. All in all, clicking through the buttons will allow you to initialize the SDK, fetch balances for a user, and de-initialize the SDK. + + +## Think About What You Just Did Here! + +In just a few lines of code, you leveraged the power of the Nexus SDK to fetch a list of tokens that the user holds across several different chains. +You can now move around those tokens as you please, the possibilities are endless! + +You might want to bridge one of the tokens across chains, or maybe you want to swap all existing tokens of your user spread across different chains into `ETH` on `Arbitrum`. + +Once you have a wallet connected and the SDK initialized, you can do all of this and more! \ No newline at end of file diff --git a/app/nexus/nexus-examples/nexus-initialization-rainbowkit/page.mdx b/app/nexus/nexus-examples/nexus-initialization-rainbowkit/page.mdx new file mode 100644 index 000000000..ef4ea2a2f --- /dev/null +++ b/app/nexus/nexus-examples/nexus-initialization-rainbowkit/page.mdx @@ -0,0 +1,341 @@ +--- +title: "Add RainbowKit to Your Nexus SDK Project" +description: "Learn how to enhance your existing Nexus SDK project with RainbowKit for better wallet connection experience" +keywords: + - docs + - Avail Nexus + - Next JS + - RainbowKit + - Nexus SDK enhancement + - Wallet connection +--- + +import { Callout, Steps, Tabs } from 'nextra/components'; + +# Add RainbowKit to Your Nexus SDK Project + + +**PREREQUISITE**
+This tutorial assumes you have already completed the [basic Nexus SDK tutorial](/nexus/nexus-examples/nexus-initialization-basic). +If you haven't, please go through that first to set up your base project. +
+ +## What You'll Learn + +By the end of this tutorial you will have: + +1. Enhanced your existing Nexus SDK project with RainbowKit +2. Improved the wallet connection experience with better UI +3. Added support for multiple wallet providers +4. Maintained all existing Nexus SDK functionality + +--- + +Check out the [RainbowKit docs](https://rainbowkit.com/docs/introduction) for latest information on how to use and customize it. + + +## Install RainbowKit Dependencies + +Navigate to the root of your project that you created in the [basic Nexus SDK tutorial](/nexus/nexus-examples/nexus-initialization-basic#initialize-the-nexus-sdk-using-next-js-a-minimal-example-using-nexus-core). + +Add the required packages to your existing project: + +```bash filename="Terminal" showLineNumbers +pnpm add @rainbow-me/rainbowkit wagmi viem @tanstack/react-query +``` + +## Configure RainbowKit + +### 1. Create Wagmi Configuration + +Create a new file at `src/lib/wagmi.ts`: + +```tsx filename="src/lib/wagmi.ts" showLineNumbers +import { getDefaultConfig } from '@rainbow-me/rainbowkit'; +import { mainnet, arbitrum, polygon, optimism, base, avalanche } from 'wagmi/chains'; + +export const config = getDefaultConfig({ + appName: 'Nexus SDK with RainbowKit', + projectId: 'YOUR_PROJECT_ID', // Get this from https://cloud.walletconnect.com/ + chains: [mainnet, arbitrum, polygon, optimism, base, avalanche], + ssr: true, // If your dApp uses server side rendering (SSR) +}); +``` + + +You need to get a Project ID from [WalletConnect Cloud](https://cloud.walletconnect.com/) for RainbowKit to work properly. This is free and only takes a few minutes to set up. + + +### 2. Create Providers Component + +Create a new file at `src/components/providers.tsx`: + +```tsx filename="src/components/providers.tsx" showLineNumbers +'use client'; + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { WagmiProvider } from 'wagmi'; +import { RainbowKitProvider } from '@rainbow-me/rainbowkit'; +import { config } from '@/lib/wagmi'; +import '@rainbow-me/rainbowkit/styles.css'; + +const queryClient = new QueryClient(); + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + + + + {children} + + + + ); +} +``` + +### 3. Update Layout + +Update your `src/app/layout.tsx` to wrap your app with the providers: + +```tsx filename="src/app/layout.tsx" showLineNumbers +import { Providers } from '@/components/providers'; +import './globals.css'; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + {children} + + + + ); +} +``` + +## Update Your Components + +### 1. Replace Connect Button + +Update your `src/components/connect-button.tsx` to use RainbowKit: + +```tsx filename="src/components/connect-button.tsx" showLineNumbers +'use client'; + +import { ConnectButton } from '@rainbow-me/rainbowkit'; + +export default function ConnectWalletButton({ className }: { className?: string }) { + return ( + + {({ + account, + chain, + openAccountModal, + openChainModal, + openConnectModal, + authenticationStatus, + mounted, + }) => { + const ready = mounted && authenticationStatus !== 'loading'; + const connected = + ready && + account && + chain && + (!authenticationStatus || + authenticationStatus === 'authenticated'); + + return ( +
+ {(() => { + if (!connected) { + return ( + + ); + } + + if (chain.unsupported) { + return ( + + ); + } + + return ( +
+ + + +
+ ); + })()} +
+ ); + }} +
+ ); +} +``` + +### 2. Update Init Button + +Update your `src/components/init-button.tsx` to use Wagmi's connector: + +```tsx filename="src/components/init-button.tsx" showLineNumbers +'use client'; + +import { useAccount } from 'wagmi'; +import { initializeWithProvider, isInitialized } from '../lib/nexus'; + +export default function InitButton({ + className, + onReady, +}: { className?: string; onReady?: () => void }) { + const { connector } = useAccount(); + + const onClick = async () => { + try { + // Get the provider from the connected wallet + const provider = await connector?.getProvider(); + if (!provider) throw new Error('No provider found'); + + // We're calling our wrapper function from the lib/nexus.ts file here. + await initializeWithProvider(provider); + onReady?.(); + alert('Nexus initialized'); + } catch (e: any) { + alert(e?.message ?? 'Init failed'); + } + }; + return ; +} +``` +The lines of interest for us is majorly what's here below: +```ts +const provider = await connector?.getProvider(); + if (!provider) throw new Error('No provider found'); + // We're calling our wrapper function from the lib/nexus.ts file here. + await initializeWithProvider(provider); +``` +- Since RainbowKit uses `wagmi`, you can easily get the EIP-1193 Provider of your connected wallet with `useAccount` +- Here, we import `useAccount` hook from `wagmi`, and get the `connector` property from which we can call `getProvider()` which returns the EIP-1193 Provider for the connected wallet. This makes it very easy for any RainbowKit connected wallet to initialize the Nexus SDK and unlock crosschain features. +- Once we have the `provider`, we can pass it into our helper function to initialize Nexus. + +### 3. Update Main Page + +Update your `src/app/page.tsx` to show wallet connection status: + +```tsx filename="src/app/page.tsx" showLineNumbers +'use client'; + +import { useState } from 'react'; +import { useAccount } from 'wagmi'; +import ConnectWalletButton from '@/components/connect-button'; +import InitButton from '@/components/init-button'; +import FetchUnifiedBalanceButton from '@/components/fetch-unified-balance-button'; +import DeinitButton from '@/components/de-init-button'; +import { isInitialized } from '@/lib/nexus'; + +export default function Page() { + const { isConnected } = useAccount(); + const [initialized, setInitialized] = useState(isInitialized()); + const [balances, setBalances] = useState(null); + + const btn = + 'px-4 py-2 rounded-md bg-blue-600 text-white hover:bg-blue-700 ' + + 'disabled:opacity-50 disabled:cursor-not-allowed'; + + return ( +
+
+ + setInitialized(true)} /> + setBalances(r)} /> + { setInitialized(false); setBalances(null); }} /> + +
+ Wallet Status: {isConnected ? 'Connected' : 'Not connected'} +
+
+ Nexus SDK Initialization Status: {initialized ? 'Initialized' : 'Not initialized'} +
+ + {balances && ( +
{JSON.stringify(balances, null, 2)}
+ )} +
+
+ ); +} +``` + +## What Changed? + +The only changes from your basic tutorial are: + +1. **Added RainbowKit packages** - 4 new dependencies +2. **Created Wagmi config** - Chain and app configuration +3. **Added providers** - RainbowKit and Wagmi providers +4. **Updated connect button** - Now uses RainbowKit's ConnectButton +5. **Updated init button** - Uses Wagmi's connector instead of window.ethereum +6. **Added wallet status** - Shows connection status + +**Everything else stays exactly the same!** Your Nexus SDK setup, balance fetching, and de-initialization all work identically. + +## Next Steps + +Your Nexus SDK project now has a much better wallet connection experience while maintaining all the same functionality. You can continue building with the same Nexus SDK methods you learned in the basic tutorial! + + +**Want to learn more?**
+Check out the [RainbowKit documentation](https://www.rainbowkit.com/docs) for more customization options and advanced features. +
diff --git a/app/nexus/nexus-examples/page.mdx b/app/nexus/nexus-examples/page.mdx new file mode 100644 index 000000000..b0586fe24 --- /dev/null +++ b/app/nexus/nexus-examples/page.mdx @@ -0,0 +1,22 @@ +--- +title: "Nexus SDK Examples" +description: "Examples of how to use the Nexus SDK" +keywords: + - docs + - Avail Nexus + - Examples + - Nexus SDK +asIndexPage: true +--- +import { Cards } from 'nextra/components'; +import { FileIcon } from '@components/icons'; + +# More examples with Nexus SDK + +We will expand this section with different examples of how to use the Nexus SDK. +Keep tuned! + + + } href="/nexus/nexus-examples/nexus-initialization-basic" /> + } href="/nexus/nexus-examples/nexus-initialization-rainbowkit" /> + \ No newline at end of file diff --git a/app/nexus/nexus-overview/page.mdx b/app/nexus/nexus-overview/page.mdx new file mode 100644 index 000000000..b170c3373 --- /dev/null +++ b/app/nexus/nexus-overview/page.mdx @@ -0,0 +1,84 @@ +--- +image: "/img/docs-link-preview.png" +title: Nexus SDK Overview +--- + +import { Callout, Steps, Tabs } from 'nextra/components'; + +# Nexus SDK Overview + +A powerful TypeScript SDK for cross-chain operations, token bridging, and unified balance management across multiple EVM chains. + +## Get Started + +The Nexus SDK is split into two main packages: + +1. [**@avail-project/nexus-core**](https://github.com/availproject/nexus-sdk/tree/main/packages/core): Headless SDK for cross-chain operations + - No React dependencies required + - Direct Chain Abstraction integration + +### Install: + + + + +```bash filename="Terminal" +npm install @avail-project/nexus-core +``` + + + +```bash filename="Terminal" +yarn add @avail-project/nexus-core +``` + + + +```bash filename="Terminal" +pnpm add @avail-project/nexus-core +``` + + + + + + +1. The headless SDK still requires an injected wallet provider (e.g. MetaMask, WalletConnect, etc.) +2. It is designed for client-side browser environments and **cannot be used** in any server-side environments. + + +2. [**@avail-project/nexus-widgets**](https://github.com/availproject/nexus-sdk/tree/main/packages/widgets): Convenient React components for a plug-n-play experience. + - Ready-to-use React components for seamless integration + - Drop-in bridge, transfer, bridge-and-execute and execute components + +### Install: + + + + +```bash filename="Terminal" +npm install @avail-project/nexus-widgets +``` + + + +```bash filename="Terminal" +yarn add @avail-project/nexus-widgets +``` + + + +```bash filename="Terminal" +pnpm add @avail-project/nexus-widgets +``` + + + + + + +**YOU WILL NEED A REACT-BASED FRONTEND**
+ +1. Any React-based dev environment works, including React frameworks like Next.js, Remix, Gatsby, or build tools like Vite, Create React App, and Webpack. +2. You also need the following peer dependencies: `react` , `react-dom`, `viem`. +
\ No newline at end of file diff --git a/app/nexus/avail-nexus-sdk/overview/page.mdx b/app/nexus/nexus-quickstart/page.mdx similarity index 82% rename from app/nexus/avail-nexus-sdk/overview/page.mdx rename to app/nexus/nexus-quickstart/page.mdx index a79f9d26c..f942388c1 100644 --- a/app/nexus/avail-nexus-sdk/overview/page.mdx +++ b/app/nexus/nexus-quickstart/page.mdx @@ -6,7 +6,7 @@ import { Callout, Steps, Tabs } from 'nextra/components'; # Get Started -This page will help you get started with `nexus` as well as `nexus-widgets`. +This page will help you get started with `nexus-core` as well as `nexus-widgets`. {/* We built a React demo app that uses the Avail Nexus SDK UI components to implement a unified Web3 experience. @@ -16,13 +16,13 @@ This page will help you get started with `nexus` as well as `nexus-widgets`. */} -## Nexus (headless) +## Nexus Core -We also made a demo app for the headless package to make it easier for devs to get on-boarded with the Avail Nexus SDK. -You can visit the Nexus (headless) demo app here: [avail-headless-nexus-demo.avail.so](https://avail-headless-nexus-demo.avail.so/) +We also made a demo app for the headless package to make it easier for devs to get on-boarded with the Avail Nexus SDK: -- [Github](https://github.com/availproject/avail-nexus-demo) +- [avail-headless-nexus-demo.avail.so](https://avail-headless-nexus-demo.avail.so/) +- [Github repo for the demo app](https://github.com/availproject/avail-nexus-demo) Getting started with the headless Nexus SDK is simple. @@ -33,8 +33,16 @@ Getting started with the headless Nexus SDK is simple. The Nexus SDK requires an injected wallet provider (e.g. RainbowKit, ConnectKit, etc.) + +To be clear, even a basic injected provider using the `window.ethereum` object will work, but we recommend using a dedicated wallet provider. + + ### Initialize the SDK + +A more complete example of getting started with `nexus-core` can be found [in this page of our docs](/nexus/nexus-examples/nexus-initialization-basic). + + Choose the network type you want to use and initialize the SDK with the wallet provider. ```typescript showLineNumbers filename="Typescript" @@ -56,10 +64,10 @@ await sdk.initialize(window.ethereum); // Returns: Promise ## Nexus-Widgets (React) -We also made a demo app for the widgets package to make it easier for devs to get on-boarded with the Avail Nexus SDK. -You can visit the Nexus (widgets) demo app here: [nexus-ui-components-demo.avail.so](https://nexus-ui-components-demo.avail.so/) +We also made a demo app for the widgets package to make it easier for devs to get on-boarded with the Avail Nexus SDK: -- [Github](https://github.com/availproject/nexus-ui-components-demo) +- [nexus-ui-components-demo.avail.so](https://nexus-ui-components-demo.avail.so/) +- [Github repo for the demo app](https://github.com/availproject/nexus-ui-components-demo) The `nexus-widgets` package is a set of React components that make it easier to integrate the Nexus SDK into your React app. diff --git a/components/icons/avail-svg-black-on-white.svg b/components/icons/avail-svg-black-on-white.svg new file mode 100644 index 000000000..dcfaf852f --- /dev/null +++ b/components/icons/avail-svg-black-on-white.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/components/icons/avail-svg-white-on-black.svg b/components/icons/avail-svg-white-on-black.svg new file mode 100644 index 000000000..45594e3be --- /dev/null +++ b/components/icons/avail-svg-white-on-black.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/components/icons/avail-svg.svg b/components/icons/avail-svg.svg new file mode 100644 index 000000000..badbd2166 --- /dev/null +++ b/components/icons/avail-svg.svg @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/components/icons/github-24.svg b/components/icons/github-24.svg new file mode 100644 index 000000000..830f00462 --- /dev/null +++ b/components/icons/github-24.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/components/icons/index.ts b/components/icons/index.ts index 2324bcb7a..c25e33149 100644 --- a/components/icons/index.ts +++ b/components/icons/index.ts @@ -27,3 +27,7 @@ export { default as TerminalIcon } from './terminal.svg' export { default as DiagramIcon } from './diagram.svg' export { default as FolderTreeIcon } from './folder-tree.svg' export { default as IdCardIcon } from './id-card.svg' +export { default as GithubIcon24 } from './github-24.svg' +export { default as AvailSvgWhiteOnBlack } from './avail-svg-white-on-black.svg' +export { default as AvailSvgBlackOnWhite } from './avail-svg-black-on-white.svg' +export { default as AvailSvg } from './avail-svg.svg' \ No newline at end of file diff --git a/middleware.ts b/middleware.ts index 1be12be2f..e927792d9 100644 --- a/middleware.ts +++ b/middleware.ts @@ -1286,7 +1286,55 @@ export function middleware(request: NextRequest) { { source: "/nexus/avail-nexus-sdk/api-reference", destination: `${origin}/nexus/avail-nexus-sdk/examples/nexus-core/api-reference`, - } + }, + + // Nexus redirects due to the decision taken to not go with the Tutorials top-level + + { + source: "/nexus/avail-nexus-sdk/overview", + destination: `${origin}/nexus/nexus-overview`, + }, + // { + // source: "/nexus/avail-nexus-sdk/overview", + // destination: `${origin}/nexus/nexus-quickstart`, + // }, + + { + source: "/nexus/avail-nexus-sdk/examples/nexus-core/fetch-unified-balances", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-core/fetch-unified-balances`, + }, + { + source: "/nexus/avail-nexus-sdk/examples/nexus-core/transfer", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-core/transfer`, + }, + { + source: "/nexus/avail-nexus-sdk/examples/nexus-core/bridge-tokens", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-core/bridge`, + }, + { + source: "/nexus/avail-nexus-sdk/examples/nexus-core/bridge-and-execute", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-core/bridge-and-execute`, + }, + { + source: "/nexus/avail-nexus-sdk/examples/nexus-core/api-reference", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-core/api-reference`, + }, + { + source: "/nexus/avail-nexus-sdk/examples/nexus-widgets/transfer", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-widgets/transfer`, + }, + { + source: "/nexus/avail-nexus-sdk/examples/nexus-widgets/bridge-tokens", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-widgets/bridge`, + }, + { + source: "/nexus/avail-nexus-sdk/examples/nexus-widgets/bridge-and-execute", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-widgets/bridge-and-execute`, + }, + { + source: "/nexus/avail-nexus-sdk/examples/nexus-widgets/api-reference", + destination: `${origin}/nexus/avail-nexus-sdk/nexus-widgets/api-reference`, + }, ]; diff --git a/public/reserveDocs/nexus-porto-extension/page.mdx b/public/reserveDocs/nexus-porto-extension/page.mdx new file mode 100644 index 000000000..d4eccf3b9 --- /dev/null +++ b/public/reserveDocs/nexus-porto-extension/page.mdx @@ -0,0 +1,291 @@ +--- +title: "Add Porto Wallet to Your Nexus SDK Project" +description: "Learn how to enhance your existing Nexus SDK project with Porto Wallet for secure wallet connection" +keywords: + - docs + - Avail Nexus + - Next JS + - Porto Wallet + - Nexus SDK enhancement + - Wallet connection +--- + +import { Callout, Steps, Tabs } from 'nextra/components'; + +# Add Porto Wallet to Your Nexus SDK Project + + +**PREREQUISITE**
+This tutorial assumes you have already completed the [basic Nexus SDK tutorial](/nexus/nexus-examples/nexus-initialization-basic). +If you haven't, please go through that first to set up your base project. +
+ +## What You'll Learn + +By the end of this tutorial you will have: + +1. Enhanced your existing Nexus SDK project with Porto Wallet +2. Added secure wallet connection with iframe-based authentication +3. Integrated Porto with Wagmi for better wallet management +4. Maintained all existing Nexus SDK functionality + +--- + +Check out the [Porto docs](https://rainbowkit.com/docs/introduction) for latest information on how to use and customize it. + + +## Install Porto Wallet Dependencies + +Add the required packages to your existing project: + +```bash filename="Terminal" +pnpm add porto wagmi viem @tanstack/react-query +``` + +## Configure Porto Wallet + +### 1. Create Wagmi Configuration + +Create a new file at `src/lib/wagmi.ts`: + +```tsx filename="src/lib/wagmi.ts" +import { http, createConfig, createStorage } from 'wagmi'; +import { mainnet, arbitrum, polygon, optimism, base, avalanche } from 'wagmi/chains'; +import { porto } from 'wagmi/connectors'; + +// Create a safe storage that works in both server and client environments +const safeStorage = typeof window !== 'undefined' ? localStorage : { + getItem: () => null, + setItem: () => {}, + removeItem: () => {}, +}; + +export const config = createConfig({ + chains: [mainnet, arbitrum, polygon, optimism, base, avalanche], + connectors: [porto()], + storage: createStorage({ storage: safeStorage }), + transports: { + [mainnet.id]: http(), + [arbitrum.id]: http(), + [polygon.id]: http(), + [optimism.id]: http(), + [base.id]: http(), + [avalanche.id]: http(), + }, +}); +``` + +### 2. Create Providers Component + +Create a new file at `src/components/providers.tsx`: + +```tsx filename="src/components/providers.tsx" +'use client'; + +import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; +import { WagmiProvider } from 'wagmi'; +import { config } from '@/lib/wagmi'; + +const queryClient = new QueryClient(); + +export function Providers({ children }: { children: React.ReactNode }) { + return ( + + + {children} + + + ); +} +``` + +### 3. Update Layout + +Update your `src/app/layout.tsx` to wrap your app with the providers: + +```tsx filename="src/app/layout.tsx" +import { Providers } from '@/components/providers'; +import './globals.css'; + +export default function RootLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( + + + + {children} + + + + ); +} +``` + +## Update Your Components + +### 1. Replace Connect Button + +Update your `src/components/connect-button.tsx` to use Porto Wallet: + +```tsx filename="src/components/connect-button.tsx" +'use client'; + +import { useConnect, useConnectors, useAccount } from 'wagmi'; + +export default function ConnectWalletButton({ className }: { className?: string }) { + const connect = useConnect(); + const connectors = useConnectors(); + const { isConnected, address } = useAccount(); + + const handleConnect = () => { + const portoConnector = connectors.find((connector: any) => connector.name === 'Porto'); + if (portoConnector) { + connect.connect({ connector: portoConnector }); + } + }; + + if (isConnected) { + return ( +
+ + Connected: {address?.slice(0, 6)}...{address?.slice(-4)} + +
+ ); + } + + return ( + + ); +} +``` + +### 2. Update Init Button + +Update your `src/components/init-button.tsx` to use Wagmi's connector: + +```tsx filename="src/components/init-button.tsx" +'use client'; + +import { useAccount } from 'wagmi'; +import { initializeWithProvider, isInitialized } from '../lib/nexus'; + +export default function InitButton({ + className, + onReady, +}: { className?: string; onReady?: () => void }) { + const { connector } = useAccount(); + + const onClick = async () => { + try { + // Get the provider from the connected wallet + const provider = await connector?.getProvider(); + if (!provider) throw new Error('No provider found'); + + // We're calling our wrapper function from the lib/nexus.ts file here. + await initializeWithProvider(provider); + onReady?.(); + alert('Nexus initialized'); + } catch (e: any) { + alert(e?.message ?? 'Init failed'); + } + }; + return ; +} +``` + +### 3. Update Main Page + +Update your `src/app/page.tsx` to show wallet connection status: + +```tsx filename="src/app/page.tsx" +'use client'; + +import { useState } from 'react'; +import { useAccount } from 'wagmi'; +import ConnectWalletButton from '@/components/connect-button'; +import InitButton from '@/components/init-button'; +import FetchUnifiedBalanceButton from '@/components/fetch-unified-balance-button'; +import DeinitButton from '@/components/de-init-button'; +import { isInitialized } from '@/lib/nexus'; + +export default function Page() { + const { isConnected } = useAccount(); + const [initialized, setInitialized] = useState(isInitialized()); + const [balances, setBalances] = useState(null); + + const btn = + 'px-4 py-2 rounded-md bg-blue-600 text-white hover:bg-blue-700 ' + + 'disabled:opacity-50 disabled:cursor-not-allowed'; + + return ( +
+
+ + setInitialized(true)} /> + setBalances(r)} /> + { setInitialized(false); setBalances(null); }} /> + +
+ Wallet Status: {isConnected ? 'Connected' : 'Not connected'} +
+
+ Nexus SDK Initialization Status: {initialized ? 'Initialized' : 'Not initialized'} +
+ + {balances && ( +
{JSON.stringify(balances, null, 2)}
+ )} +
+
+ ); +} +``` + +## Development Setup + + +**HTTPS Required**
+Porto Wallet requires a secure origin (HTTPS) to function correctly. In development, you can enable HTTPS in Next.js by using the `--experimental-https` flag: + +```bash +pnpm dev --experimental-https +``` + +Make sure your development environment supports HTTPS to avoid issues with Porto's iframe integration. +
+ +## What Changed? + +The only changes from your basic tutorial are: + +1. **Added Porto Wallet packages** - 4 new dependencies +2. **Created Wagmi config** - Chain and connector configuration +3. **Added providers** - Wagmi and React Query providers +4. **Updated connect button** - Now uses Porto Wallet connector +5. **Updated init button** - Uses Wagmi's connector instead of window.ethereum +6. **Added wallet status** - Shows connection status + +**Everything else stays exactly the same!** Your Nexus SDK setup, balance fetching, and de-initialization all work identically. + +## Benefits You Now Have + +- **Secure Authentication**: Iframe-based wallet connection for enhanced security +- **No Extensions Required**: Works without browser wallet extensions +- **Cross-Platform**: Works on desktop and mobile devices +- **Wagmi Integration**: Seamless integration with popular React wallet libraries +- **Better UX**: Professional wallet connection experience + +## Next Steps + +Your Nexus SDK project now has a secure wallet connection experience while maintaining all the same functionality. You can continue building with the same Nexus SDK methods you learned in the basic tutorial! + + +**Want to learn more?**
+Check out the [Porto Wallet documentation](https://porto.sh/sdk) for more customization options and advanced features. +
diff --git a/static/introductionData.ts b/static/introductionData.ts index 05ceacf71..61337552c 100644 --- a/static/introductionData.ts +++ b/static/introductionData.ts @@ -9,9 +9,12 @@ export const IntroData = [ { topic: "Read more", links: [{ link: "/nexus/introduction-to-nexus", placeholder: "Introduction to Avail Nexus"}, - { link: "/nexus/concepts/unified-balance", placeholder: "What is a Unified Balance?"}, + { link: "/nexus/concepts/unified-balance", placeholder: "What is a Unified Balance?"}, + { link: "/nexus/nexus-overview", placeholder: "Nexus SDK overview"}, + { link: "/nexus/nexus-quickstart", placeholder: "Quickstart"}, {link: "/nexus/avail-nexus-sdk/api-reference#supported-chains", placeholder: "Supported Chains & Tokens"}, {link: "/nexus/avail-nexus-sdk", placeholder: "Avail Nexus SDK Reference"}, + {link: "/nexus/nexus-cheatsheet", placeholder: "Nexus cheat sheet"}, ], textcolor: "FE8B6C" }