justhoot-sdk
v0.1.0
Published
Browser SDK for Relay swaps and bridges with Privy adapters and gasless execution.
Readme
justhoot-sdk
Browser SDK for swapping and bridging with Relay using your users’ wallets. Includes Privy adapters, EIP-7702 + Calibur execution on EVM, and sponsored Solana transactions.
Initial implementation; live transaction validation is not complete.
Install
npm install justhoot-sdkES module package with TypeScript declarations. Import Privy adapters from justhoot-sdk/privy.
Run the example
For contributors with access to the private repository, run from a source checkout:
bun install
cp example/.env.example example/.env
# Set VITE_PRIVY_APP_ID in example/.env.
bun run exampleOpen https://localhost:5173. See the example guide for Privy, HTTPS, and sponsor setup. Executing swaps uses mainnet and real funds.
Quick start with Privy
You need a selected origin wallet, RPC URLs, and a Relay-compatible backend proxy that injects your Relay API key. Never expose the Relay API key in the browser. Your app handles login, wallet creation, and deciding when to execute.
This example swaps Base USDC to Solana USDC; only the Base wallet signs.
import { createRelayClient } from 'justhoot-sdk';
import { createPrivyEvmAdapter } from 'justhoot-sdk/privy';
const sdk = createRelayClient({
wallets: {
evm: createPrivyEvmAdapter({
wallet: selectedPrivyEvmWallet,
signAuthorization, // From Privy's useSign7702Authorization().
}),
},
rpcUrls: {
8453: 'https://your-base-rpc',
792703809: 'https://your-solana-mainnet-rpc',
},
relay: {
baseUrl: 'https://your-relay-proxy',
headers: { Authorization: 'Bearer your-consumer-session-token' },
},
});
const quote = await sdk.getQuote({
origin: { chainId: 8453, token: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913' },
destination: { chainId: 792703809, token: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v' },
amount: '1000000', // 1 USDC in base units.
recipient: selectedPrivySolanaWallet.address,
slippageBps: 50, // 0.5%.
});
// Show the quote and fees before requesting signatures.
const execution = await sdk.execute({ quote });
localStorage.setItem('relay-tracking', JSON.stringify(execution.tracking));
const result = await sdk.waitForCompletion(execution.tracking);Other wallet providers can implement EvmWalletAdapter or SolanaWalletAdapter. Privy is not a runtime dependency of the SDK.
Integration essentials
- Supported routes: cross-chain EVM origins on Relay chains with Calibur, plus mainnet Solana origins including same-chain swaps. Same-chain EVM swaps and Solana routes requiring multiple transactions or additional signers are unsupported.
- Wallets: EVM wallets must support EIP-7702 authorization and EIP-712 signing. Solana wallets must support signing without broadcasting.
getDepositAddress({ chainId })returns the selected wallet’s address; your app monitors deposits. - Proxy: support browser CORS and Relay’s
GET /chains,GET /currencies/token/price,POST /quote/v2,POST /execute, andGET /intents/status/v3paths. Optional Fast Fill also needsPOST /fast-fill. Injectx-api-keyserver-side, including for execution. - Quotes: amounts are integer token base units. Quotes expire after at most two minutes and belong to the client that created them. Recreate the client and request a fresh quote when the wallet or authentication changes.
- Fees: EVM gas is fronted by Relay and charged through execution pricing. Solana origins require your own funded sponsor and reimburse it by default, as described below.
- Recovery:
executereturns after submission, not completion. Persist tracking fromonUpdateatsubmittingas well as the returned execution. If submission is uncertain, useRelaySdkError.trackingto observe it; never automatically retry a spend afterSUBMISSION_UNKNOWN.getStatusandwaitForCompletiononly observe; stopping a wait does not cancel a transaction.
Solana origins
Add a createPrivySolanaAdapter wallet and configure solanaSponsorship:
solanaSponsorship: {
feePayer: 'YOUR_SOLANA_SPONSOR_PUBLIC_KEY',
reimbursement: { multiplier: 1.5 }, // Default; set false to cover costs yourself.
signTransaction: async (request) => yourSponsorService(request),
},Your authenticated sponsor service must validate the full transaction and return signed bytes (Uint8Array) without changing the message or broadcasting it. See the example sponsor contract.
By default, reimbursement deducts 150% of estimated gas and eligible account-creation rent from the entered amount in the origin token. quote.input is the total budget, quote.swapInput is the remaining swap amount, and quote.fees includes reimbursement. The charge is fixed at quote time; the sponsor covers any difference from actual costs. Transfer-fee and transfer-hook tokens require reimbursement: false.
Reference
- API reference: configuration, application fees, routing options, Fast Fill, and tracking. Fast Fill requires a funded Relay app balance and can charge it if the origin deposit never lands.
- Exported types: authoritative option and result definitions.
- Example guide: runnable Privy integration and sponsor setup.
For local development, run bun run typecheck, bun run build, and bun run example:build.
License
MIT.
