IMPORTANT
Curvy SDK is currently in closed beta.
To receive support, please open a discussion at Curvy Community or GitHub Issues
Curvy SDK is a Typescript SDK that works in both server and browser environments and gives you the complete feature set of the Curvy protocol.
Curvy SDK can be installed with a Node package manager:
pnpm install @0xcurvy/curvy-sdk
The easiest way to get started is to run the provided curvy-os example app:
git clone https://github.com/0xCurvy/curvy-sdk.git
cd example/curvy-os
pnpm install
pnpm start
After opening the plain JS/HTML app in your browser, configure the API key you have received from the team, and
you will have the complete set of features in the Curvy SDK at your disposal through the primitive UI of curvy-os.
Before using the SDK, you must initialize the CurvySDK instance.
import { CurvySDK } from "@0xcurvy/curvy-sdk";
// Initialize with defaults (mainnet)
const sdk = await CurvySDK.init();Authentication with the Curvy Protocol relies on cryptographic signatures. You can log in an existing user or register a new one.
Registering a new Curvy ID providing the desired name alongside the signature data:
import { getAuthenticationSignatureParams } from "@0xcurvy/curvy-sdk";
import { useSignTypedData, useAccount } from "wagmi";
const { address } = useAccount();
const password = "optional-password";
const signatureParams = await getAuthenticationSignatureParams(
address,
password,
);
const { signTypedDataAsync } = useSignTypedData();
const signatureResult = await signTypedDataAsync(signatureParams);
const signatureData = {
signatureResult,
signatureParams,
signingAddress: address,
};
await sdk.register(
"my-awesome-id.curvy.name", // Curvy ID to register (it needs to end with .curvy.name domain)
signatureData,
);If you already have a user's signature, you can use the SDK's login method.
// Logging in on the Curvy Protocol network uses the same `signatureData` process as registration
await sdk.login(signatureData);The Curvy SDK handles asset balances across multiple networks. You can refresh balances on-demand, which updates the SDK's internal storage.
Call refreshBalances to scan for the latest balances across all active networks.
// Scan for balances
await sdk.refreshBalances();Once refreshed, you can query balances directly from the SDK.
// Fetch all balances for the active wallet
const balances = await sdk.getBalances();
// Pass false to force a refresh before returning, same as calling `sdk.refreshBalances()` prior to this
const freshBalances = await sdk.getBalances(false);
console.log(`Found ${balances.length} balance(s).`);
// Get aggregated totals per currency
const totals = await sdk.getTotals();The Curvy Protocol uses an Intent -> Estimate -> Execute model for interacting with assets. This abstracts away the complexity of stealth addresses, bridging, and shielding/unshielding.
An intent describes what the user wants to do. There are four intent types:
curvy-transfer— Send to a Curvy ID (.curvy.namehandle)curvy-swap— Swap currencies within the Curvy Protocolexternal-transfer— Transfer to an external wallet address on any of the supported chainssend-to-anyone— Generate a secure link that will allow you to send funds to anyone, prompting them to register or sign in
import type { TransferIntent } from "@0xcurvy/curvy-sdk";
// Fetch network and currency details from the SDK
const network = sdk.getNetwork("ethereum");
const currency = network.currencies.find((c) => c.symbol === "ETH");
const intent: TransferIntent = {
type: "curvy-transfer",
amount: 1000000000000000000n, // 1 ETH in wei
currency: currency,
network: network,
recipient: "vitalik.curvy.name", // Must be a Curvy ID ending in .curvy.name
};The SDK generates a local execution plan based on the user's current balances to fulfill the intent.
const estimation = await sdk.estimate(intent);
console.log("Gas fee:", estimation.gas);
console.log("Curvy fee:", estimation.curvyFee);
console.log("Effective amount:", estimation.effectiveAmount);Once estimated, execute the plan. The SDK handles generating zero-knowledge proofs and broadcasting transactions.
const executionResult = await sdk.execute(estimation.plan);
if (executionResult.success) {
console.log("Assets transferred successfully!");
} else {
console.error("Execution failed:", executionResult.error);
}