@longdotxyz/shared
v0.0.137
Published
Shared types and utilities for Long.xyz API
Downloads
1,975
Readme
@longdotxyz/shared
Shared TypeScript library for Long.xyz API containing GraphQL types, REST API contracts, and utilities.
Installation
npm install @longdotxyz/shared
# or
pnpm add @longdotxyz/sharedFeatures
- GraphQL Types & SDK: Auto-generated types and SDK client from GraphQL schema
- REST API Contracts: Type-safe API contracts built with ts-rest
- Type Utilities: Common types for blockchain addresses, pool keys, and more
- Utilities: Helper functions for native token handling
GraphQL Types and SDK
The library includes auto-generated GraphQL types and a ready-to-use SDK client.
Basic Setup
import { GraphQLClient } from "graphql-request";
import { getSdk } from "@longdotxyz/shared";
// Initialize GraphQL client
const client = new GraphQLClient("https://graphql.long.xyz");
// Create SDK instance
const sdk = getSdk(client);Example: Fetch Auction by Address
import { GetAuctionByAddressQuery, getSdk } from "@longdotxyz/shared";
// Query an auction
const { auction_pool } = await sdk.GetAuctionByAddress({
address: "0x123...",
});
// Type-safe access to auction data
if (auction_pool) {
console.log(auction_pool.auction_pool_address);
console.log(auction_pool.asset_address);
console.log(auction_pool.numeraire_address);
}Available GraphQL Types
import type { Asset, Asset_Bool_Exp, Asset_Order_By, AuctionPool, GraduationPool } from "@longdotxyz/shared";
// Use types for type-safe queries
const assetFilter: Asset_Bool_Exp = {
chain_id: { _eq: 1 },
asset_address: { _ilike: "0x%" },
};REST API Client (ts-rest)
The library provides type-safe REST API contracts using ts-rest.
Initialize API Client
import { initClient } from "@ts-rest/core";
import { rootContract } from "@longdotxyz/shared";
// Create typed API client
const apiClient = initClient(rootContract, {
baseUrl: "https://api.long.xyz/v1",
baseHeaders: {
"Content-Type": "application/json",
},
});Auction Endpoints
// Get dynamic auction details
const auctionResponse = await apiClient.auctions.getDynamicAuction({
params: {
address: "0x123...",
},
});
if (auctionResponse.status === 200) {
const { auction_pool_address, auction_base_token_symbol } = auctionResponse.body.result;
console.log(`Pool: ${auction_pool_address}, Symbol: ${auction_base_token_symbol}`);
}
// Create dynamic auction
const createResponse = await apiClient.auctions.createDynamicAuction({
body: {
chain_id: 8453, // Base
template_id: "template_123",
metadata: {
token_name: "My Token",
token_symbol: "MTK",
token_uri: "ipfs://...",
migration_duration: 86400,
migration_beneficiaries: [{ address: "0xabc...", amount: 10000 }],
user_address: "0xdef...",
},
},
});
if (createResponse.status === 200) {
const { governance_factory, pool_initializer, liquidity_migrator } = createResponse.body.result;
console.log("Auction created with factories:", { governance_factory, pool_initializer });
}Quote Endpoints (Uniswap V3/V4)
// V4 Exact Input Quote
const v4InputQuote = await apiClient.quotes.v4ExactInputSingle({
body: {
chain_id: 8453,
pool_key: {
currency0: "0x0000000000000000000000000000000000000000", // ETH
currency1: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
fee: 500,
tick_spacing: 10,
hooks: "0x0000000000000000000000000000000000000000",
},
zero_for_one: true,
exact_amount: "1000000000000000000", // 1 ETH
hook_data: "0x", // Optional hook data
},
});
if (v4InputQuote.status === 200) {
console.log(`Output amount: ${v4InputQuote.body.result.amount_out}`);
console.log(`Gas estimate: ${v4InputQuote.body.result.gas_estimate}`);
}
// V4 Exact Output Quote
const v4OutputQuote = await apiClient.quotes.v4ExactOutputSingle({
body: {
chain_id: 8453,
pool_key: {
currency0: "0x0000000000000000000000000000000000000000", // ETH
currency1: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", // USDC
fee: 500,
tick_spacing: 10,
hooks: "0x0000000000000000000000000000000000000000",
},
zero_for_one: true,
exact_amount: "1000000000", // 1000 USDC output
hook_data: "0x", // Optional hook data
},
});
if (v4OutputQuote.status === 200) {
console.log(`Input required: ${v4OutputQuote.body.result.amount_in}`);
console.log(`Gas estimate: ${v4OutputQuote.body.result.gas_estimate}`);
}
// V3 Exact Input Quote
const v3InputQuote = await apiClient.quotes.v3ExactInputSingle({
body: {
chain_id: 1,
token_in: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
token_out: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
amount_in: "1000000000000000000", // 1 WETH
fee: 500, // 0.05%
sqrt_price_limit_x96: "0", // Optional price limit
},
});
if (v3InputQuote.status === 200) {
console.log(`Output amount: ${v3InputQuote.body.result.amount_out}`);
console.log(`Price after: ${v3InputQuote.body.result.sqrt_price_x96_after}`);
console.log(`Ticks crossed: ${v3InputQuote.body.result.initialized_ticks_crossed}`);
console.log(`Gas estimate: ${v3InputQuote.body.result.gas_estimate}`);
}
// V3 Exact Output Quote
const v3OutputQuote = await apiClient.quotes.v3ExactOutputSingle({
body: {
chain_id: 1,
token_in: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", // WETH
token_out: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", // USDC
amount_out: "1000000000", // 1000 USDC
fee: 500, // 0.05%
},
});
if (v3OutputQuote.status === 200) {
console.log(`Input required: ${v3OutputQuote.body.result.amount_in}`);
console.log(`Price after: ${v3OutputQuote.body.result.sqrt_price_x96_after}`);
console.log(`Ticks crossed: ${v3OutputQuote.body.result.initialized_ticks_crossed}`);
console.log(`Gas estimate: ${v3OutputQuote.body.result.gas_estimate}`);
}Community Endpoints
// Fetch all communities
const communities = await apiClient.communities.fetchCommunities();
if (communities.status === 200) {
communities.body.result.forEach((community) => {
console.log(`${community.label}: ${community.description}`);
console.log(`Funding: ${community.funding_amount}`);
});
}
// Get specific community
const community = await apiClient.communities.getCommunity({
params: { id: 1 },
});IPFS Endpoints
// Upload an image to IPFS
const formData = new FormData();
formData.append("image", imageFile); // imageFile is a File object
const imageUpload = await apiClient.ipfs.uploadImage({
body: formData,
});
if (imageUpload.status === 200) {
const imageHash = imageUpload.body.result;
console.log(`Image IPFS hash: ${imageHash}`);
}
// Upload metadata to IPFS
const metadataUpload = await apiClient.ipfs.uploadMetadata({
body: {
name: "My Token",
description: "Token description",
image_hash: imageHash, // From previous upload
social_links: [
{ label: "Twitter", url: "https://twitter.com/mytoken" },
{ label: "Discord", url: "https://discord.gg/mytoken" },
],
vesting_recipients: [
{ address: "0xabc...", amount: 5000 },
{ address: "0xdef...", amount: 5000 },
],
fee_receiver: "0x123...",
},
});
if (metadataUpload.status === 200) {
const metadataHash = metadataUpload.body.result;
console.log(`Metadata IPFS hash: ${metadataHash}`);
}Pathfinding Endpoints
Get Swap Paths
import { apiClient } from "@longdotxyz/shared";
// Basic usage (Codex only)
const paths = await apiClient.pathfinding.fetchTokenPaths({
params: { tokenInAddress: "0xTokenAddress" },
});
// With Kyber fallback (when amount provided)
const pathsWithFallback = await apiClient.pathfinding.fetchTokenPaths({
params: { tokenInAddress: "0xTokenAddress" },
query: {
amount: "1000000000000000000", // 1 token in wei
tokenOut: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913", // Optional: USDC
},
});
if (pathsWithFallback.status === 200) {
const { paths, paths_count } = pathsWithFallback.body;
paths.forEach((path) => {
if (path.source === "kyber") {
// Kyber route includes executable calldata
console.log("Router:", path.router_address);
console.log("Calldata:", path.encoded_calldata);
console.log("Expected output:", path.amount_out);
} else {
// Codex route includes liquidity metrics
console.log("Liquidity:", path.total_liquidity_usd);
console.log("Volume:", path.total_volume_usd);
}
});
}Query Parameters:
amount(optional): Swap amount in wei. When provided, enables Kyber fallback if Codex returns no paths.tokenOut(optional): Target token address. If omitted, queries all exit tokens (WETH, USDC, ETH on Base).
Response Fields:
source: Either"codex"or"kyber"- indicates which service provided the routeencoded_calldata(Kyber only): Ready-to-execute swap calldatarouter_address(Kyber only): Kyber router contract addressamount_in(Kyber only): Input amount in weiamount_out(Kyber only): Expected output amount in weigas_estimate(Kyber only): Estimated gas for the swap
Type Utilities
Pool Key Type (Uniswap V4)
import { PoolKey } from "@longdotxyz/shared";
const poolKey: PoolKey = {
currency0: "0x0000000000000000000000000000000000000000",
currency1: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
fee: 500,
tick_spacing: 10,
hooks: "0x0000000000000000000000000000000000000000",
};Hex Address Validation
import { z } from "zod";
import { hex } from "@longdotxyz/shared";
// Validate and normalize hex addresses
const addressSchema = z.string().pipe(hex);
const validAddress = addressSchema.parse("0xabc..."); // Returns lowercase hexBigInt Coercion
import { coerceBigInt } from "@longdotxyz/shared";
const amount = coerceBigInt.parse("1000000000000000000"); // Returns bigint
const amount2 = coerceBigInt.parse(1000n); // Also accepts bigintNative Token Utilities
import { isNativeToken, isNativeTokenAddress } from "@longdotxyz/shared";
// Check if address is native token (ETH)
isNativeTokenAddress("0x0000000000000000000000000000000000000000"); // true
isNativeTokenAddress("0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE"); // true
// Check token object
isNativeToken({
address: "0x0000000000000000000000000000000000000000",
symbol: "ETH",
}); // trueDevelopment
Building the Library
# Generate GraphQL types
pnpm codegen
# Build TypeScript
pnpm build
# Run tests
pnpm test
# Format and lint
pnpm format
pnpm lintGraphQL Code Generation
The GraphQL types are generated from a schema using @graphql-codegen. Configuration is in codegen.ts.
pnpm codegenAPI Contract Structure
All API contracts are defined using ts-rest and exported from @longdotxyz/shared/contracts:
- Auctions:
/auctions/*- Dynamic auction creation and management - Quotes:
/quotes/*- Uniswap V3/V4 swap quotes - Communities:
/communities/*- Community data management - IPFS:
/ipfs/*- IPFS content creation
License
UNLICENSED