PlacePosition.tsx

Go to src/components/PlacePosition.tsx where we will be building our next component to handle placing positions.

Importing Dependencies:

  1. Import the required dependencies

import { useConnection, useWallet } from '@solana/wallet-adapter-react';
import { PublicKey } from '@solana/web3.js';
import { FC, useCallback, useEffect } from 'react';
import { notify } from "../utils/notifications";
import { ParimutuelWeb3, PositionSideEnum, WalletSigner } from '@hxronetwork/parimutuelsdk';
import { PariConfig } from './Config';

Setting up our component

  1. Create a functional component PlacePosition which will take in 3 props pariPubkey, side, and amount

const PlacePosition: FC<{pariPubkey: string, side: PositionSideEnum, amount: string}> = (props) => {
  // ...
}
  1. In the component, use the useConnection and useWallet hooks to retrieve the connection and public key. Also, initialize a parimutuelWeb3 instance with the required config and connection

const { connection } = useConnection();
const { publicKey, signTransaction } = useWallet();
const wallet = useWallet()

const { config } = PariConfig;
const parimutuelWeb3 = new ParimutuelWeb3(config, connection);
  1. Get the pariPubkey, side, and amount props passed to the component

const {pariPubkey, side, amount} = props
  1. Use the useEffect hook to run a piece of code whenever the pariPubkey value changes

useEffect(() => {
}, [pariPubkey]);
  1. Create a onClick event handler using the useCallback hook. This event handler will be called when the button is clicked, and it will make a call to the parimutuelWeb3.placePosition method to place a position.

The required parameters are: - wallet - PublicKey(pariPubkey) - parseFloat(amount) * (10 ** 9 / 1) - side - Date.now()

If the transaction is successful, a success notification will be displayed, otherwise, an error notification will be displayed.
const onClick = useCallback(async (amount: string, pariPubkey: string) => {
        if (!publicKey) {
          notify({ type: 'error', message: 'Wallet not connected!' });
          console.error('Send Transaction: Wallet not connected!');
          return;
        }
        let transactionId = '';
        try {
      
          transactionId = await parimutuelWeb3.placePosition(
            wallet as WalletSigner,
            new PublicKey(pariPubkey),
            parseFloat(amount) * (10 ** 9 / 1),
            side,
            Date.now()
          );
      
          if (transactionId) {
            console.log(`Transaction: ${transactionId}`);
            notify({ type: 'success', message: `Placed ${side === PositionSideEnum.LONG ? 'LONG' : 'SHORT'} Position`, txid: transactionId });
          }
        } catch (error) {
          notify({ type: 'error', message: 'Transaction failed!', description: error.message, txid: transactionId });
          console.error(`Transaction failed! ${error.message}`, transactionId);
          return;
        }
      }, [publicKey, notify, connection, signTransaction]);
  1. Use side to determine the color gradient of the button. If the side is equal to PositionSideEnum.LONG, the button will have a gradient from purple to teal. If the side is equal to PositionSideEnum.SHORT, the button will have a gradient from pink to yellow.

const bgGradientClass =
    side === PositionSideEnum.LONG
      ? 'bg-gradient-to-r from-indigo-500 to-teal-500 hover:from-teal-500 hover:to-indigo-500'
      : 'bg-gradient-to-r from-pink-500 to-yellow-500 hover:from-yellow-500 hover:to-pink-500';

Returning our component

Return the following to set up the PlacePosition button:

return (
        <div>
            <button
                className={`group w-60 m-2 btn disabled:animate-none bg-gradient-to-r ${bgGradientClass} ...`}
                onClick={() => onClick(amount, pariPubkey)} disabled={amount === '0'}
            >
                <div className="hidden group-disabled:block ">
                    Enter Amount...
                </div>
                <span className="block group-disabled:hidden" > 
                   {amount} USDC {side === PositionSideEnum.LONG? 'LONG' : 'SHORT'}
                </span>
            </button>
        </div>
    );
};

The PlacePosition button checks whether the user input an amount, and will block the user from placing a position if they have not

Now, let us test it!

  1. Head over to src/components/PlacePostionBox.tsx

  2. Import PlacePosition from our component

import PlacePosition from './PlacePosition'
  1. Place two instances of PlacePosition under the <input/> element, one for placing Long positions and the other one for Shorts, and pass in amount as the amount prop, pubkey as the pariKey prop, and a PositionSideEnum for each side for the side prop


<div style={{ marginLeft: '-15px', marginTop: '10px' }}>
		<PlacePosition amount={amount} pariPubkey={pubkey} side={PositionSideEnum.LONG}/>
		<PlacePosition amount={amount} pariPubkey={pubkey} side={PositionSideEnum.SHORT} />
</div>

The output should look similar to this:

Now, users can set position amounts and place positions for whichever side they choose, for the time interval that they selected, in the BTC-USD Devnet Parimutuel Market

Using it on Devnet

To use the app on devnet you will need Hxro issued devnet USDC token

How to:

  1. Connect your wallet

  2. Click the airdrop button on the right of the connect button

  3. Click on USDC and you will get airdropped Hxro Devnet USDC that you can use to play with on your app!

Token Adress: DXSVQJqJbNTTcGqCkfHnQYXwG5GhZsfg2Ka9tNkK3ohr

Up Next

V2 of this Parimutuel UI Project Walkthrough with more functionalities from the Parimutuel TS SDK

Last updated