<p align="left">
  <a href="https://nexlabs.io">  
    <img src="https://app.nexlabs.io/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fxlogo_s.ecf71c27.png&w=3840&q=75" alt=" Company Logo " width="50"/>
    <h1>Nexlabs.io</h1>
  </a>
</p>

# smart-contract-interaction

A powerful SDK for interacting with smart contracts, supporting multiple index symbols and environments like wallet extensions and mainnets.

## Installation

To install the package, run the following command:

```bash
npm i smart-contract-interaction
```

## Usage

### SDK Initialization

To begin, create a new instance of the NexIndex class with the index symbol and the current configuration object:

```javascript
import { NexIndex, Environment } from 'smart-contract-interaction';

// Define the configuration for connecting to the smart contract
const CurrentConfig = {
  env: Environment.WALLET_EXTENSION, // Choose the environment (e.g., WALLET_EXTENSION, LOCAL, MAINNET)
  rpc: {
    local: '<your_local_url>',      // Add your local RPC URL here
    mainnet: '<your_rpc_url>',      // Add your mainnet RPC URL here
    wallet: window.ethereum         // If using a wallet extension like MetaMask, pass the wallet object
  },
  wallet: {
    address: '<your_address>',      // Your wallet address here
    privateKey: '<your_private_key>' // Your wallet's private key for write operations
  }
};

// Instantiate the NexIndex class with the chosen index symbol
const index = new NexIndex('ANFI', CurrentConfig);
```

#### Allowed Index Symbols
 
You can interact with any of the following index symbols:

 - ANFI
 - CRYPTO5
 - MAG7
 - ARBEI

#### Allowed From Mint Symbols
 
You can interact with any of the following index symbols:

 - USDT
 - USDC ( for MAG7 only )
 
 #### Configuration Fields
 
 - **env**: Environment for smart contract interaction. Choose between:
 
   - LOCAL
   - MAINNET
   - WALLET_EXTENSION
 
 - **rpc**: RPC URLs for different environments.
 
 - **wallet**: Contains wallet details (wallet address and private key).

#### Methods
 
 Read Methods
 
 1. **getAddress()**
    - Returns the connected user's wallet address.
    - **Arguments**: None
 
    ```javascript
    const address = await index.getAddress();
    console.log(address);
    ```
 
 2. **getBalance()**
    - Returns the total balance of the selected index for the connected user.
    - **Arguments**: None
 
    ```javascript
    const balance = await index.getBalance();
    console.log(balance);
    ```
 
 3. **getAllowance()**
    - Returns the allowance of the selected index.
    - **Arguments**: None
 
    ```javascript
    const allowance = await index.getAllowance();
    console.log(allowance);
    ```
 
 4. **getTotalSupply()**
    - Returns the total supply of the selected index.
    - **Arguments**: None
 
    ```javascript
    const totalSupply = await index.getTotalSupply();
    console.log(totalSupply);
    ```
 
 #### Write Methods
 
 1. **approve(fromSymbol, amount)**
    - Approve the transfer of a specified amount of tokens from a given symbol.
    - **Arguments**:
      - `fromSymbol`: Symbol from which you want to approve the token.
      - `amount`: The amount of tokens to approve.
 
    ```javascript
    await index.approve('USDT', 100);
    ```
 
 2. **mint(fromSymbol, amount)**
    - Mint tokens for the specified index.
    - **Arguments**:
      - `fromSymbol`: Symbol from which you want to mint the token.
      - `amount`: The amount of tokens to mint.
 
    ```javascript
    await index.mint('USDT', 50);
    ```
 
 3. **burn(amount)**
    - Burn the specified amount of tokens.
    - **Arguments**:
      - `amount`: The amount of tokens to burn.
 
    ```javascript
    await index.burn(25);
    ```
 
 #### Example
 
 ```javascript
 // Import the necessary classes and environment enum
 import { NexIndex, Environment } from 'smart-contract-interaction';
 
 // Configuration for interacting with the smart contract
 const CurrentConfig = {
   env: Environment.MAINNET,
   rpc: {
     local: 'http://localhost:8545',
     mainnet: 'https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID',
     wallet: window.ethereum
   },
   wallet: {
     address: '0xYourWalletAddress',
     privateKey: '0xYourPrivateKey'
   }
 };
 
 // Initialize the NexIndex instance with a chosen index symbol
 const index = new NexIndex('MAG7', CurrentConfig);
 
 // Get the connected user's address
 const address = await index.getAddress();
 console.log(`User address: ${address}`);
 
 // Get the user's balance for the selected index
 const balance = await index.getBalance();
 console.log(`Balance: ${balance}`);
 
 // Approve a token transfer
 await index.approve('USDC', 100);
 
 // Mint new tokens
 await index.mint('USDC', 50);
 
 // Burn tokens
 await index.burn(20);
 ```
 
 ### Widget Implementation
 
 If the user wants to interact with our indices, they can do so via our provided widget.
 
 Usage
 
 To use the widget, integrate it into your front-end as shown below:
 
 ```javascript
 <Swap configs={configs} />
 ```
 
 The `configs` object contains the necessary configuration for the swap widget to function correctly. An example configuration is as follows:
 
 ```javascript
 const configs: SwapPropsObjectType = {
   connectionConfig: CurrentConfig,   // Pass the connection config object
   mode: 'dark',                      // Set the theme to either 'dark' or 'light'
   onCompletion: handleSwapCallback,   // Callback function triggered after swap
   swapFromCurrSymbol: 'USDT',         // OPTIONAL: Currency symbol to swap from (default: USDT)
   swapToCurrSymbol: 'CRYPTO5',        // OPTIONAL: Index symbol to swap to (default: ANFI)
 };
 ```
 
 ### SwapPropsObjectType Definition
 
 The widget requires a configuration object of type `SwapPropsObjectType`:
 
 ```typescript
 interface SwapPropsObjectType {
   connectionConfig: Config;                 // Configuration for connecting to the smart contract
   mode: modeType;                           // Choose between 'dark' or 'light' mode
   swapFromCurrSymbol?: allowedIndexSymbolProps | allowedMintSymbolProps  // Symbol for currency to swap from
   swapToCurrSymbol?: allowedIndexSymbolProps | allowedMintSymbolProps    // Symbol for index to swap to
   onCompletion: (data: SwapResult) => void; // Callback to handle swap completion
 }
 ```
 
 ### Types and Definitions
 
 **allowedMintSymbolProps**
 
 The allowed symbols for minting are:
 
 ```typescript
 type allowedMintSymbolProps = 'USDT' | 'USDC';
 ```
 
 **allowedIndexSymbolProps**
 
 The allowed index symbols for swapping are:
 
 ```typescript
 type allowedIndexSymbolProps = 'ANFI' | 'CRYPTO5' | 'MAG7' | 'ARBEI';
 ```
 
 **modeType**
 
 The widget can either be in dark or light mode:
 
 ```typescript
 type modeType = 'dark' | 'light';
 ```
 
 **SwapResult Interface**
 
 The `SwapResult` interface defines the structure of the callback data returned upon swap completion:
 
 ```typescript
 interface SwapResult {
   success: boolean;                  // Indicates if the swap was successful
   message: string;                   // Message describing the outcome of the swap
   error?: Error;                     // Optional error field if the swap fails
   receipt?: TransactionReceipt;      // Contains the transaction receipt in case of write functions
 }
 ```
 
 The `onCompletion` function will be invoked with the result of the swap, providing details such as whether the swap was successful, any errors, and the transaction receipt if available.
 
 ### Example Widget Integration
 
 Here's an example of how to integrate the swap widget into your project:
 
 ```javascript
 import { Swap, Config, SwapResult } from 'smart-contract-interaction';
 
 const CurrentConfig: Config = {
   env: Environment.WALLET_EXTENSION, // Wallet extension environment (e.g., MetaMask)
   rpc: {
     local: 'http://localhost:8545',
     mainnet: 'https://mainnet.infura.io/v3/YOUR_INFURA_PROJECT_ID',
     wallet: window.ethereum
   },
   wallet: {
     address: '0xYourWalletAddress',
     privateKey: '0xYourPrivateKey'
   }
 };
 
 const configs: SwapPropsObjectType = {
   connectionConfig: CurrentConfig,
   mode: 'dark',                      // Set mode to 'dark'
   swapFromCurrSymbol: 'USDT',         // Swap from USDT
   swapToCurrSymbol: 'CRYPTO5',        // Swap to CRYPTO5 index
   onCompletion: (data: SwapResult) => {
     if (data.success) {
       console.log('Swap successful:', data.receipt);
     } else {
       console.error('Swap failed:', data.error);
    }
   }
 };
 
 <Swap configs={configs} />
 ```
 
 The `onCompletion` callback will handle the result of the swap, providing either the transaction receipt for successful swaps or an error message if the swap fails.

### License
 
 This package is licensed under the MIT License.
