Getting Started
Integrate Morpher Trading in your Project
This guide provides instructions and examples for integrating the MorpherTradeSDK
into your application. We’ll cover the setup process using both a React/Wagmi-based approach (as seen in this project) and a generic viem
setup.
Installation
First, add the SDK to your project dependencies.
npm install morpher-trading-sdk
You will also need a library to interact with the Ethereum blockchain, such as viem
or wagmi
.
npm install viem wagmi
Core Concepts
1. Initialization
The first step is to create an instance of the SDK. This instance should be created once and made available throughout your application. A common pattern is to use a state management library or a React Context.
import { MorpherTradeSDK } from 'morpher-trading-sdk';
// The API endpoint is available in your project's environment variables.
const morpherTradeSDK = new MorpherTradeSDK(import.meta.env.VITE_MORPHER_API_ENDPOINT);
2. Wallet Interaction
To execute transactions (like opening or closing positions), the SDK requires access to the user’s wallet. This is achieved by passing account
, walletClient
, and publicClient
objects from a library like viem
or wagmi
to the SDK’s transaction methods.
account
: The user’s connected wallet account object, containing the address.publicClient
: A client for reading data from the blockchain (e.g., balances, contract state).walletClient
: A client for writing data to the blockchain (i.e., sending transactions and signing messages).
3. Fetching Data vs. Executing Trades
The SDK methods can be categorized into two groups:
- Read-only methods: Fetching market lists, portfolio data, positions, etc. These generally only require an
eth_address
. Some, likegetCurrencyList
, also need apublicClient
to fetch on-chain balances. - Write methods:
executeTrade
andcancelOrder
. These require theaccount
,walletClient
, andpublicClient
to sign and send transactions.
Example 1: React with Wagmi & Zustand
This project uses Zustand for state management and Wagmi for wallet interactions. This is a robust way to structure a trading application.
Step 1: Initialize SDK in a Zustand Store
The SDK instance is created once and exposed through a Zustand store. This makes it easily accessible from any component.
File: src/store/market.ts
import { create } from 'zustand'
import { MorpherTradeSDK } from "morpher-trading-sdk"
const morpherTradeSDK = new MorpherTradeSDK(import.meta.env.VITE_MORPHER_API_ENDPOINT);
interface MarketState {
morpherTradeSDK: MorpherTradeSDK;
// ... other state properties
}
export const useMarketStore = create<MarketState>((set) => ({
morpherTradeSDK: morpherTradeSDK,
// ... other state initializers
}));
Step 2: Connect Wallet and Fetch Data
Components use Wagmi’s hooks (useAccount
, usePublicClient
, useWalletClient
) to get the necessary wallet details. Once the user is connected, you can fetch their data.
File: src/components/trade/ClosePosition.tsx
import { useAccount, usePublicClient } from "wagmi";
import { useMarketStore } from "@/store/market";
import { usePortfolioStore } from "@/store/portfolio";
function MyComponent() {
const { address } = useAccount();
const publicClient = usePublicClient();
const { morpherTradeSDK } = useMarketStore();
const { setCurrencyList } = usePortfolioStore();
useEffect(() => {
const fetchCurrencyList = async () => {
if (address && publicClient && morpherTradeSDK.ready) {
const tokenAddresses = [
{ symbol: 'MPH', address: morpherTradeSDK.tokenAddress as `0x${string}` },
{ symbol: 'USDC', address: morpherTradeSDK.usdcAddress as `0x${string}` }
];
const fetchedCurrencyList = await morpherTradeSDK.getCurrencyList({
address,
publicClient,
tokenAddresses
});
setCurrencyList(fetchedCurrencyList);
}
};
fetchCurrencyList();
}, [address, publicClient, morpherTradeSDK.ready]);
// ...
}
Step 3: Execute a Trade
To execute a trade, retrieve the account
and walletClient
from Wagmi and pass them to executeTrade
.
File: src/components/trade/ClosePosition.tsx
import { useAccount, usePublicClient, useWalletClient } from "wagmi";
import { useMarketStore } from "@/store/market";
import { usePortfolioStore } from "@/store/portfolio";
function ClosePosition() {
const { morpherTradeSDK } = useMarketStore();
const { selectedPosition, closePercentage } = usePortfolioStore();
const { data: walletClient } = useWalletClient();
const publicClient = usePublicClient();
const [tradeExecuting, setTradeExecuting] = useState(false);
const executeCloseTrade = () => {
if (!walletClient || !publicClient || !selectedPosition) return;
setTradeExecuting(true);
morpherTradeSDK.closePosition({
account: walletClient.account,
walletClient,
publicClient,
market_id: selectedPosition.market_id,
closePercentage: closePercentage,
callback: (result) => {
console.log('Trade result:', result);
setTradeExecuting(false);
}
});
};
// ...
}
Example 2: Generic Viem Project
If you’re not using React or a framework with hooks, you can use viem
directly.
Step 1: Setup Viem Clients
First, create your publicClient
and walletClient
.
import { createPublicClient, createWalletClient, custom, http } from 'viem'
import { mainnet } from 'viem/chains'
import { MorpherTradeSDK } from 'morpher-trading-sdk';
// Initialize SDK
const sdk = new MorpherTradeSDK('https://api.morpher.com/v2');
// Create a public client
const publicClient = createPublicClient({
chain: mainnet,
transport: http()
});
// Create a wallet client from a browser wallet (e.g., MetaMask)
const walletClient = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum)
});
Step 2: Fetch Account and Execute a Trade
Request the user’s account and then use the clients to perform actions.
async function main() {
// Get user account
const [address] = await walletClient.requestAddresses();
const account = { address, type: 'json-rpc' };
// Fetch user's open positions
try {
const positions = await sdk.getPositions({ eth_address: address });
console.log('Open Positions:', positions);
if (positions.length > 0) {
const firstPosition = positions[0];
// Example: Close 50% of the first position
console.log(`Closing 50% of position ${firstPosition.id}...`);
sdk.closePosition({
account,
walletClient,
publicClient,
market_id: firstPosition.market_id,
closePercentage: 50,
callback: (result) => {
if (result.result === 'success') {
console.log('Successfully closed position!', result.txHash);
} else {
console.error('Failed to close position:', result.err);
}
}
});
}
} catch (error) {
console.error('An error occurred:', error);
}
}
// You would typically call main() after a user action, like clicking a button.
// main();
This generic approach can be adapted to any frontend framework (Vue, Svelte, etc.) or even a vanilla JavaScript project.