Migrating SDK from v1.5 to v2.0
This guide helps you migrate your code from v1.x to v2.0.0-alpha of the Intuition TypeScript packages. This is a major version update with significant breaking changes due to the underlying contract migration from EthMultiVault to MultiVault.
Contract Migration Overviewβ
The core smart contract has been upgraded from EthMultiVault to MultiVault, introducing significant architectural changes that impact all TypeScript libraries built on top.
Key Contract Changesβ
1. ID System Migrationβ
- EthMultiVault: Uses
uint256for atom/triple IDs - MultiVault: Uses
bytes32for term IDs (atoms and triples are now "terms")
2. Terminology Changesβ
- EthMultiVault: Atoms and Triples as separate entities
- MultiVault: Unified "Terms" concept (atoms and triples are both terms)
- EthMultiVault: Vault IDs
- MultiVault: Term IDs with Curve IDs for bonding curves
3. Bonding Curve Integrationβ
- EthMultiVault: Limited bonding curve support
- MultiVault: Full bonding curve integration with curve IDs for all operations
Breaking Changes Overviewβ
Package Version Updatesβ
| Package | Previous Version | New Version |
|---|---|---|
@0xintuition/protocol | 1.0.0-alpha.1 | 2.0.0 |
@0xintuition/sdk | 1.0.0-alpha.3 | 2.0.0 |
@0xintuition/graphql | 1.0.0-alpha.3 | 2.0.0 |
@0xintuition/cli | 0.0.2 | 2.0.0 |
1. Contract Migration Impactβ
Contract Function Mappingβ
The migration from EthMultiVault to MultiVault requires updating all contract interactions. Here's the complete function mapping:
Core Creation Functionsβ
Atom Creationβ
// EthMultiVault
function createAtom(bytes atomUri) payable returns (uint256)
function batchCreateAtom(bytes[] atomUris) payable returns (uint256[])
// MultiVault
function createAtoms(bytes[] data, uint256[] assets) payable returns (bytes32[])
Triple Creationβ
// EthMultiVault
function createTriple(uint256 subjectId, uint256 predicateId, uint256 objectId) payable returns (uint256)
function batchCreateTriple(uint256[] subjectIds, uint256[] predicateIds, uint256[] objectIds) payable returns (uint256[])
// MultiVault
function createTriples(bytes32[] subjectIds, bytes32[] predicateIds, bytes32[] objectIds, uint256[] assets) payable returns (bytes32[])
Deposit Functionsβ
EthMultiVaultβ
function depositAtom(address receiver, uint256 id) payable returns (uint256)
function depositTriple(address receiver, uint256 id) payable returns (uint256)
function batchDeposit(address receiver, uint256[] termIds, uint256[] amounts) payable returns (uint256[])
MultiVaultβ
function deposit(address receiver, bytes32 termId, uint256 curveId, uint256 minShares) payable returns (uint256)
function depositBatch(address receiver, bytes32[] termIds, uint256[] curveIds, uint256[] assets, uint256[] minShares) payable returns (uint256[])
Redeem Functionsβ
EthMultiVaultβ
function redeemAtom(uint256 shares, address receiver, uint256 id) returns (uint256)
function redeemTriple(uint256 shares, address receiver, uint256 id) returns (uint256)
function batchRedeem(uint256 percentage, address receiver, uint256[] ids) returns (uint256[])
MultiVaultβ
function redeem(address receiver, bytes32 termId, uint256 curveId, uint256 shares, uint256 minAssets) returns (uint256)
function redeemBatch(address receiver, bytes32[] termIds, uint256[] curveIds, uint256[] shares, uint256[] minAssets) returns (uint256[])
Contract Address Changes: EthMultiVault β MultiVaultβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
import { EthMultiVaultAbi } from '@0xintuition/protocol'
import { getEthMultiVaultAddress } from '@0xintuition/sdk'
const address = getEthMultiVaultAddress(chainId)
After:
import { intuitionTestnet, MultiVaultAbi } from '@0xintuition/protocol'
import { getMultiVaultAddressFromChainId } from '@0xintuition/sdk'
const address = getMultiVaultAddressFromChainId(intuitionTestnet.id)
Contract Event Changesβ
EthMultiVault Eventsβ
event AtomCreated(address indexed creator, address indexed atomWallet, bytes atomData, uint256 vaultId)
event TripleCreated(address indexed creator, uint256 subjectId, uint256 predicateId, uint256 objectId, uint256 vaultId)
MultiVault Eventsβ
event AtomCreated(address indexed creator, bytes32 indexed termId, bytes atomData, address atomWallet)
event TripleCreated(address indexed creator, bytes32 indexed termId, bytes32 subjectId, bytes32 predicateId, bytes32 objectId)
Data Structure Migrationβ
ID Handling Updateβ
Before:
This Before block intentionally preserves the removed v1 numeric-ID shape for historical comparison and is illustrative rather than copy-paste code for the current package.
const atomId: bigint = 123n
const tripleId: bigint = 456n
After:
import type { Hex } from 'viem'
const atomId: Hex =
'0x906527aae4af914b1ac01ff9adfdda5dafde3b5e21f84045e0660b0a15c07769'
const tripleId: Hex =
'0xc4e64dbc3d69293d28259653d9b15d2ab3f6aa1aa0b1a489e5250974cd089730'
Query Functionsβ
// EthMultiVault
function atoms(uint256 atomId) view returns (bytes)
function getTripleAtoms(uint256 id) view returns (uint256, uint256, uint256)
// MultiVault
function atom(bytes32 atomId) view returns (bytes)
function getAtom(bytes32 atomId) view returns (bytes)
function triple(bytes32 tripleId) view returns (bytes32, bytes32, bytes32)
function getTriple(bytes32 tripleId) view returns (bytes32, bytes32, bytes32)
Share and Asset Conversionsβ
// EthMultiVault
function convertToShares(uint256 assets, uint256 id) view returns (uint256)
function convertToAssets(uint256 shares, uint256 id) view returns (uint256)
// MultiVault
function convertToShares(bytes32 termId, uint256 curveId, uint256 assets) view returns (uint256)
function convertToAssets(bytes32 termId, uint256 curveId, uint256 shares) view returns (uint256)
New MultiVault Featuresβ
1. Utilization Trackingβ
import {
multiVaultGetTotalUtilizationForEpoch,
multiVaultGetUserUtilizationForEpoch,
type ReadConfig,
} from '@0xintuition/protocol'
import type { Address } from 'viem'
async function getEpochUtilization(
config: ReadConfig,
userAddress: Address,
epoch: bigint,
) {
const userUtilization = await multiVaultGetUserUtilizationForEpoch(config, {
args: [userAddress, epoch],
})
const totalUtilization = await multiVaultGetTotalUtilizationForEpoch(config, {
args: [epoch],
})
return { userUtilization, totalUtilization }
}
2. Epoch Systemβ
import {
multiVaultCurrentEpoch,
multiVaultGetUserLastActiveEpoch,
type ReadConfig,
} from '@0xintuition/protocol'
import type { Address } from 'viem'
async function getEpochState(config: ReadConfig, userAddress: Address) {
const currentEpoch = await multiVaultCurrentEpoch(config)
const lastActiveEpoch = await multiVaultGetUserLastActiveEpoch(config, {
args: [userAddress],
})
return { currentEpoch, lastActiveEpoch }
}
3. Enhanced Fee Managementβ
import { MultiVaultAbi, type WriteConfig } from '@0xintuition/protocol'
import type { Address, Hex } from 'viem'
async function readAndClaimFees(
config: WriteConfig,
atomWallet: Address,
termId: Hex,
epoch: bigint,
) {
const accumulatedFees = await config.publicClient.readContract({
address: config.address,
abi: MultiVaultAbi,
functionName: 'accumulatedAtomWalletDepositFees',
args: [atomWallet],
})
const protocolFees = await config.publicClient.readContract({
address: config.address,
abi: MultiVaultAbi,
functionName: 'accumulatedProtocolFees',
args: [epoch],
})
const { request } = await config.publicClient.simulateContract({
account: config.walletClient.account,
address: config.address,
abi: MultiVaultAbi,
functionName: 'claimAtomWalletDepositFees',
args: [termId],
})
const transactionHash = await config.walletClient.writeContract(request)
return { accumulatedFees, protocolFees, transactionHash }
}
4. Improved Preview Functionsβ
import {
multiVaultPreviewAtomCreate,
multiVaultPreviewDeposit,
type WriteConfig,
} from '@0xintuition/protocol'
import type { Hex } from 'viem'
async function previewVaultOperations(
config: WriteConfig,
termId: Hex,
curveId: bigint,
assets: bigint,
) {
const [depositShares, depositAssetsAfterFees] =
await multiVaultPreviewDeposit(config, {
args: [termId, curveId, assets],
})
const [atomShares, atomAssetsAfterFixedFees, atomAssetsAfterFees] =
await multiVaultPreviewAtomCreate(config, {
args: [termId, assets],
})
return {
depositShares,
depositAssetsAfterFees,
atomShares,
atomAssetsAfterFixedFees,
atomAssetsAfterFees,
}
}
2. TypeScript Library Changesβ
Protocol Package (@0xintuition/protocol)β
Atom Creation: Singular β Pluralβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
import {
createAtom,
createAtomCalculateBaseCost,
createAtomEncode,
} from '@0xintuition/protocol'
// Single atom creation
await createAtom(config, { args: [atomUri], value })
// Encoding
const encodedData = createAtomEncode(atomUri)
// Cost calculation
const cost = await createAtomCalculateBaseCost(config)
After:
The payable multiVaultCreateAtoms wrapper is pending the post-publish SDK resync, so this deposit-value-coupled migration example is excluded from copy-paste typechecking until that package shape is available.
import {
multiVaultCreateAtoms,
multiVaultCreateAtomsEncode,
multiVaultGetAtomCost,
type WriteConfig,
} from '@0xintuition/protocol'
import { toHex } from 'viem'
async function createAtoms(config: WriteConfig, atomUris: string[]) {
const atomCost = await multiVaultGetAtomCost(config)
const atomData = atomUris.map((uri) => toHex(uri))
const assets = atomData.map(() => atomCost)
const value = assets.reduce((total, amount) => total + amount, 0n)
const transactionHash = await multiVaultCreateAtoms(config, {
args: [atomData, assets],
value,
})
const encodedData = multiVaultCreateAtomsEncode(atomData, assets)
return { transactionHash, encodedData, atomCost }
}
Triple Creation: Singular β Pluralβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
import {
createTriple,
createTripleCalculateBaseCost,
createTripleEncode,
} from '@0xintuition/protocol'
await createTriple(config, {
args: [subjectId, predicateId, objectId],
value,
})
const encodedData = createTripleEncode(subjectId, predicateId, objectId)
const cost = await createTripleCalculateBaseCost(config)
After:
The payable multiVaultCreateTriples wrapper is pending the post-publish SDK resync, so this deposit-value-coupled migration example is excluded from copy-paste typechecking until that package shape is available.
import {
multiVaultCreateTriples,
multiVaultCreateTriplesEncode,
multiVaultGetTripleCost,
type WriteConfig,
} from '@0xintuition/protocol'
import type { Hex } from 'viem'
async function createTriples(
config: WriteConfig,
subjectIds: Hex[],
predicateIds: Hex[],
objectIds: Hex[],
) {
if (
subjectIds.length !== predicateIds.length ||
subjectIds.length !== objectIds.length
) {
throw new Error('Subject, predicate, and object arrays must have equal length')
}
const tripleCost = await multiVaultGetTripleCost(config)
const assets = subjectIds.map(() => tripleCost)
const value = assets.reduce((total, amount) => total + amount, 0n)
const transactionHash = await multiVaultCreateTriples(config, {
args: [subjectIds, predicateIds, objectIds, assets],
value,
})
const encodedData = multiVaultCreateTriplesEncode(
subjectIds,
predicateIds,
objectIds,
assets,
)
return { transactionHash, encodedData, tripleCost }
}
Deposit and Redeem Simplificationβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
import {
depositAtom,
depositAtomEncode,
depositTriple,
depositTripleEncode,
redeemAtom,
redeemAtomEncode,
redeemTriple,
redeemTripleEncode,
} from '@0xintuition/protocol'
// Separate functions for atoms and triples
await depositAtom(config, { args: [receiver, atomId], value })
await depositTriple(config, { args: [receiver, tripleId], value })
await redeemAtom(config, { args: [shares, receiver, atomId] })
await redeemTriple(config, { args: [shares, receiver, tripleId] })
After:
The payable deposit wrapper is pending the post-publish SDK resync, so this deposit-value-coupled migration example is excluded from copy-paste typechecking until that package shape is available.
import type { Address, Hex } from 'viem'
// Prepare the current MultiVault inputs without calling the pending SDK wrapper.
function prepareVaultCalls(
receiver: Address,
termId: Hex,
curveId: bigint,
assets: bigint,
minShares: bigint,
shares: bigint,
minAssets: bigint,
) {
const depositCall = {
args: [receiver, termId, curveId, minShares],
value: assets,
} as const
const redeemArgs = [
receiver,
termId,
curveId,
shares,
minAssets,
] as const
return { depositCall, redeemArgs }
}
Batch Operations Renamedβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
import {
batchCreateAtom,
batchCreateTriple,
batchDepositCurve,
batchRedeemCurve,
} from '@0xintuition/protocol'
After:
import {
multiVaultCreateAtoms, // Replaces batchCreateAtom
multiVaultCreateTriples, // Replaces batchCreateTriple
multiVaultDepositBatch, // Replaces batchDepositCurve
multiVaultRedeemBatch, // Replaces batchRedeemCurve
} from '@0xintuition/protocol'
Multicall Function Nameβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
import { multiCallIntuitionConfigs } from '@0xintuition/protocol'
const config = await multiCallIntuitionConfigs({ address, publicClient })
After:
import {
multiVaultMultiCallIntuitionConfigs,
type ReadConfig,
} from '@0xintuition/protocol'
async function getMultiVaultConfig(config: ReadConfig) {
return multiVaultMultiCallIntuitionConfigs(config)
}
Removed EthMultiVault APIβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
import { EthMultiVault } from '@0xintuition/protocol'
const ethMultiVault = new EthMultiVault({ publicClient, walletClient })
const result = await ethMultiVault.createAtom('hello')
After:
The payable multiVaultCreateAtoms wrapper is pending the post-publish SDK resync, so this deposit-value-coupled migration example is excluded from copy-paste typechecking until that package shape is available.
import {
getMultiVaultAddressFromChainId,
intuitionTestnet,
multiVaultCreateAtoms,
multiVaultGetAtomCost,
type WriteConfig,
} from '@0xintuition/protocol'
import { toHex } from 'viem'
async function createHelloAtom(
clients: Omit<WriteConfig, 'address'>,
) {
const config: WriteConfig = {
...clients,
address: getMultiVaultAddressFromChainId(intuitionTestnet.id),
}
const atomCost = await multiVaultGetAtomCost(config)
return multiVaultCreateAtoms(config, {
args: [[toHex('hello')], [atomCost]],
value: atomCost,
})
}
Bonding Curve Integrationβ
The new MultiVault contract requires curve IDs for all operations:
import {
multiVaultGetBondingCurveConfig,
type ReadConfig,
} from '@0xintuition/protocol'
async function getDefaultCurveId(config: ReadConfig) {
const { defaultCurveId } = await multiVaultGetBondingCurveConfig(config)
return defaultCurveId
}
Pass that curve ID to deposit and redeem operations. The payable deposit wrapper is pending the post-publish SDK resync, so this value-forwarding example is excluded from copy-paste typechecking until that package shape is available.
import {
multiVaultDeposit,
multiVaultGetBondingCurveConfig,
type WriteConfig,
} from '@0xintuition/protocol'
import type { Address, Hex } from 'viem'
async function depositWithDefaultCurve(
config: WriteConfig,
receiver: Address,
termId: Hex,
assets: bigint,
minShares: bigint,
) {
const { defaultCurveId } = await multiVaultGetBondingCurveConfig(config)
return multiVaultDeposit(config, {
args: [receiver, termId, defaultCurveId, minShares],
value: assets,
})
}
Migration Stepsβ
Step 1: Update Function Callsβ
Creating Atomsβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
const atomId = await ethMultiVault.createAtom(atomData, { value: fee })
After:
The payable multiVaultCreateAtoms wrapper is pending the post-publish SDK resync, so this deposit-value-coupled migration example is excluded from copy-paste typechecking until that package shape is available.
import {
multiVaultCreateAtoms,
type WriteConfig,
} from '@0xintuition/protocol'
import type { Hex } from 'viem'
async function createMigratedAtom(
config: WriteConfig,
atomData: Hex,
assets: bigint,
) {
return multiVaultCreateAtoms(config, {
args: [[atomData], [assets]],
value: assets,
})
}
Depositingβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
const shares = await ethMultiVault.depositAtom(receiver, atomId, {
value: assets,
})
After:
The payable deposit wrapper is pending the post-publish SDK resync, so this value-forwarding migration example is excluded from copy-paste typechecking until that package shape is available.
import { multiVaultDeposit, type WriteConfig } from '@0xintuition/protocol'
import type { Address, Hex } from 'viem'
async function depositIntoMigratedVault(
config: WriteConfig,
receiver: Address,
termId: Hex,
curveId: bigint,
assets: bigint,
minShares: bigint,
) {
return multiVaultDeposit(config, {
args: [receiver, termId, curveId, minShares],
value: assets,
})
}
Redeemingβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
const assets = await ethMultiVault.redeemAtom(shares, receiver, atomId)
After:
import { multiVaultRedeem, type WriteConfig } from '@0xintuition/protocol'
import type { Address, Hex } from 'viem'
async function redeemFromMigratedVault(
config: WriteConfig,
receiver: Address,
termId: Hex,
curveId: bigint,
shares: bigint,
minAssets: bigint,
) {
return multiVaultRedeem(config, {
args: [receiver, termId, curveId, shares, minAssets],
})
}
3. SDK Package Changes (@0xintuition/sdk)β
SDK read helpers use the mainnet GraphQL API by default. Configure the endpoint once before the migrated read examples; use API_URL_DEV for Intuition Testnet or API_URL_PROD for Mainnet:
import { configureSdk } from '@0xintuition/sdk'
import { API_URL_DEV } from '@0xintuition/graphql'
configureSdk({ apiUrl: API_URL_DEV })
SDK atom creation helpers dynamically fetch and forward the required atom base cost. Any optional amount is an additional TRUST/tTRUST deposit (signal), not the base cost itself.
API Function Renamingβ
Before:
This Before block intentionally preserves the removed v1 API for historical comparison and is illustrative rather than copy-paste code for the current package.
import { getAtom, getTriple } from '@0xintuition/sdk'
const atomData = await getAtom('124862')
const tripleData = await getTriple('54670')
After:
import {
configureSdk,
getAtomDetails,
getTripleDetails,
} from '@0xintuition/sdk'
import { API_URL_DEV } from '@0xintuition/graphql'
configureSdk({ apiUrl: API_URL_DEV })
const atomData = await getAtomDetails(
'0x906527aae4af914b1ac01ff9adfdda5dafde3b5e21f84045e0660b0a15c07769',
)
const tripleData = await getTripleDetails(
'0xc4e64dbc3d69293d28259653d9b15d2ab3f6aa1aa0b1a489e5250974cd089730',
)
Triple Creation Parameter Changesβ
Before:
This Before block preserves the pre-v3 call shape of createTripleStatement for historical comparison. The helper still exists and is payable, so this deposit-value-coupled example is excluded from copy-paste typechecking pending the post-publish SDK resync.
import { createTripleStatement } from '@0xintuition/sdk'
const triple = await createTripleStatement(config, {
args: [subjectVaultId, predicateVaultId, objectVaultId],
depositAmount: 1000000000000000000n, // Optional
})
After:
The payable createTripleStatement example is pending the post-publish SDK resync, so this deposit-value-coupled migration example is excluded from copy-paste typechecking until that package shape is available.
import {
createTripleStatement,
type WriteConfig,
} from '@0xintuition/sdk'
import type { Hex } from 'viem'
async function createMigratedTriple(
config: WriteConfig,
subjectId: Hex,
predicateId: Hex,
objectId: Hex,
) {
const assets = 1000000000000000000n
return createTripleStatement(config, {
args: [[subjectId], [predicateId], [objectId], [assets]],
value: assets,
})
}
4. Configuration Changesβ
EthMultiVault Configβ
struct GeneralConfig {
address admin;
address protocolMultisig;
uint256 feeDenominator;
uint256 minDeposit;
uint256 minShare;
uint256 atomUriMaxLength;
uint256 decimalPrecision;
uint256 minDelay;
}
MultiVault Configβ
struct GeneralConfig {
address admin;
address protocolMultisig;
uint256 feeDenominator;
address trustBonding; // New
uint256 minDeposit;
uint256 minShare;
uint256 atomDataMaxLength; // Renamed
uint256 decimalPrecision;
// minDelay removed
}
5. Removed Functionsβ
The following functions have been removed and replaced:
Protocol Packageβ
createAtomβcreateAtomscreateTripleβcreateTriplesbatchCreateAtomβcreateAtomsbatchCreateTripleβcreateTriplesdepositAtom/depositTripleβdepositredeemAtom/redeemTripleβredeemcreateAtomCalculateBaseCostβgetAtomCostcreateTripleCalculateBaseCostβgetTripleCost- All curve-specific functions β
depositBatch/redeemBatch atoms-by-hash.tsfile completely removed
SDK Packageβ
createThingβcreateAtomFromThingcreateEthereumAccountβcreateAtomFromEthereumAccountgetEthMultiVaultAddressβgetMultiVaultAddressFromChainIdgetAtomβgetAtomDetailsgetTripleβgetTripleDetails
6. Breaking Changes Summaryβ
- All IDs changed from
uint256tobytes32 - Curve ID parameter required for most operations
- Batch functions have different signatures
- Event structures updated
- Some functions renamed or merged
- New slippage protection with
minShares/minAssetsparameters
7. Best Practicesβ
- Always use the default curve ID unless you have specific bonding curve requirements
- Implement proper slippage protection with min/max parameters
- Handle the new epoch system for utilization tracking
- Update your event listeners to match new event structures
- Use preview functions to estimate outcomes before transactions
π Summaryβ
This major version update consolidates and simplifies the API while adding new functionality. The main changes are:
- Contract Migration:
EthMultiVaultβMultiVaultwith architectural improvements - ID System: Changed from
uint256tobytes32for all term identifiers - Bonding Curves: Full integration requiring curve IDs for all operations
- Singular β Plural: Functions now support batch operations by default
- Unified APIs: Simplified deposit/redeem functions for all vault types
- Enhanced Features: New utilization tracking, epoch system, and preview functions
- Event Updates: Improved event parsing with new event structures
Take your time with the migration and test thoroughly. The new API is more powerful and consistent, providing a better developer experience.