Migrating from 1.x SDK
To use the latest version of the SDK:ESM-only build
The SDK is now ESM-only.require('@rhinestone/sdk') no longer works — use ESM import syntax. Internal subpath imports were also removed; use the curated entry points (./actions/*, ./errors, ./utils, ./smart-sessions, ./jwt-server).
sendTransaction removed
The account.sendTransaction(transaction) shortcut is gone. Use the explicit prepareTransaction → signTransaction → submitTransaction flow:
sendUserOperation for ERC-4337 flows is unchanged.
Session permissions are ABI-driven
Session.actions is gone. Build sessions with toSession({ chain, owners, permissions }) instead — an ABI-driven definition the SDK resolves into a low-level Session. Each permission is an { abi, address, functions } entry; function selectors and param calldata offsets are derived from the ABI, and param value types are checked against ABI input types:
SessionDefinition; Session is the resolved output of toSession.
Session policies are declarative
In 1.x, eachaction carried a raw policies array that you assembled by hand. Those arrays are gone — policies are now expressed through fields on the permission’s function config, and toSession compiles them into the right on-chain policies:
params: { x: { anyOf: [a, b] } }— allowlist a parameter against several values (compiles to an arg-policy OR chain). A single{ condition, value }stays a cheaper universal-action.maxUses— cap how many times the function may be called.validUntil/validAfter— restrict the function to a time window (Date).valueLimit— cap cumulative ETH value (payable functions only; rejected at compile time otherwise).spendingLimit: { token, amount }— cap cumulative ERC-20 spend (only ontransfer/transferFrom/approve/increaseAllowance-shaped functions).
policies array on a permission now throws instead of being silently dropped. See Policies for the full set.
Session policy addresses
The smart session policies were redeployed, andtoSession now bakes the new addresses into the session digest by default. If an account already enabled sessions against the previous deployments, trying to use the existing session with the new policies results in an onchain revert due to the digest mismatch.
Pin the affected policies back to the addresses the account was enabled against via SessionDefinition.policyAddresses:
| Policy | Key | V1 address | V2 address (default) |
|---|---|---|---|
| Sudo | sudo | 0x0000003111cD8e92337C100F22B7A9dbf8DEE301 | 0x0000000000FEEc8D74e3143fBaBbca515358d869 |
| Call | universalAction | 0x0000006DDA6c463511C4e9B05CFc34C1247fCF1F | 0x0000000000714Cf48FcF88A0bFBa70d313415032 |
| Arg policy | argPolicy | — (new in V2) | 0x0000000000167edE64D8751daACDdC0312565a73 |
| Spending limit | spendingLimits | 0x00000088D48cF102A8Cdb0137A9b173f957c6343 | 0x000000000033212E272655D8a22402Db819477A6 |
| Timeframe | timeFrame | 0x8177451511dE0577b911C254E9551D981C26dc72 | 0x0000000000D30f611fA3bf652ac6879428586930 |
| Usage limit | usageLimit | 0x1F34eF8311345A3A4a4566aF321b313052F51493 | 0x00000000001d4479FA2A947026204d0283ceDe4B |
| Value limit | valueLimit | 0x730DA93267E7E513e932301B47F2ac7D062abC83 | 0x000000000021dC45451291BCDfc9f0B46d6f0278 |
Quote selection
prepareTransaction now returns quotes: { best, all } instead of a single quote. Existing prepare → sign → submit code keeps working — signTransaction defaults to quotes.best:
intentId from prepared.quotes.all:
getTransactionMessages(prepared, { intentId }) accepts the same selection so external signers see the route signTransaction will sign.
Settlement layer filter
settlementLayers is no longer a bare array. It’s a discriminated union with include / exclude so you can blacklist a single layer without listing all the others:
splitIntents. See Settlement Layers for usage patterns.
submitTransaction options bag
submitTransaction now takes an options object instead of positional arguments:
waitForExecution no longer accepts preconfirmations
The acceptsPreconfirmations parameter is removed. waitForExecution always waits for FILLED / COMPLETED and never treats PRECONFIRMED as terminal:
verifyExecutions removed from session signers
SingleSessionSignerSet, PerChainSessionSignerSet, and ChainSessionConfig no longer accept verifyExecutions. The SDK now derives it from the session shape — sessions with permissions use emissary execution validation, claim-only sessions use the EIP-1271 path — so the flag is redundant. Drop it from your signer set:
Passport account removed
account.type: 'passport' is no longer accepted. The PassportAccount type and the passport member of AccountType / AccountProviderConfig are removed.
Intent status by ID
getIntentStatus now takes a string instead of a bigint. If you persist intent IDs across runs, switch the storage type to string.
Portfolio shape
PortfolioToken no longer carries a token-level decimals or aggregate balances. decimals now lives on each per-chain chains[] entry alongside address and amount, since the same logical token can have different decimals across chains (e.g., USDC is 6 on Ethereum, 18 on BSC). Read the per-chain entry directly when rendering balances.
Permit2 claim policy renames
If you constructedPermit2ClaimPolicy values directly, the type tag and field names changed to be chain-aware:
Token registry helpers removed
getSupportedTokens, getTokenAddress, getTokenDecimals, and getAllSupportedChainsAndTokens are removed. Fetch the equivalent data from the orchestrator’s /chains endpoint:
deployAccountsForOwners removed
Create a backend deployer account, take a view-only reference to each user account, and submit a sponsored intent that calls deploy(userAccount). Pass multiple deploy(...) calls in one intent to batch deployments.
checkERC20AllowanceDirect removed
Read allowances directly with viem’s readContract:
ENS validator owner set
ENSValidatorConfig couples each owner with its expiry instead of using parallel arrays. Omit expiration for an owner that never expires:
Removed and relocated helpers
createRhinestoneAccountis removed. Usenew RhinestoneSDK({ apiKey }).createAccount(config).- Account recovery. The
@rhinestone/sdk/actions/recoverysubpackage (enable,recoverEcdsaOwnership,recoverPasskeyOwnership), therecoveryfield on the account config, and the guardian signer set are removed. account.deploy()session param. The unusedsessionoption onaccount.deploy()is removed (it was a no-op).- Compact-bound surface. The
@rhinestone/sdk/actions/compactsubpackage, thelockFundstransaction option, andAccount.emissaryConfigare removed alongside the orchestrator’s compact-based deposit/withdrawal flow. - Permit2 signing helpers.
signPermit2Batch,signPermit2Sequential, and the relatedMultiChainPermit2Config/MultiChainPermit2Result/BatchPermit2Resulttypes are removed. Signing now uses orchestrator-provided EIP-712 typed data internally. getPermit2Addressis removed. Permit2 lives at0x000000000022D473030F116dDEE9F6B43aC78BA3on every supported chain — hardcode the constant.walletClientToAccountandwrapParaAccountmoved from the package root to@rhinestone/sdk/utils.
Migrating from 1.x Alpha SDK
New entry point
RhinestoneSDK is now the main entry point to the SDK functionality.
To migrate, change the account creation code:
Transaction utilities (actions)
Action utilities related to using modules and resource locking (e.g.,installModule, addOwner, recoverEcdsaOwnership) were moved to separate subpackages:
rhinestoneAccount, address, chain, and provider params anymore when using actions:
All actions
All actions
/actions:installModuleto install a moduleuninstallModuleto uninstall a module
/actions/compact(resource locking with TheCompact):depositEtherto deposit ETH into TheCompactenableEtherWithdrawalto enable permissionless ETH withdrawal (starts reset period)disableEtherWithdrawalto cancel permissionless ETH withdrawalwithdrawEtherto withdraw ETH after the reset periodapproveErc20to approve an ERC-20 token for depositdepositErc20to deposit ERC-20 into TheCompactenableErc20Withdrawalto enable permissionless ERC-20 withdrawal (starts reset period)disableErc20Withdrawalto cancel permissionless ERC-20 withdrawalwithdrawErc20to withdraw ERC-20 after the reset period
/actions/ecdsa(ECDSA validator):enableto enable the validatordisableto disable the validatoraddOwnerto add an ownerremoveOwnerto remove an ownerchangeThresholdto change the signature threshold
/actions/mfa(multi-factor authorization):enableto enable the validatordisableto disable the validatorsetSubValidatorto add a sub-validator to the MFA setremoveSubValidatorto remove a sub-validator from the MFA setchangeThresholdto change the MFA signature threshold
/actions/passkeys(passkey validator):enableto enable the validatordisableto disable the validatoraddOwnerto add an ownerremoveOwnerto remove an ownerchangeThresholdto change the signature threshold
/actions/recovery(social recovery):enableto enable the validatorrecoverEcdsaOwnershipto recover ownership to a new ECDSA ownerrecoverPasskeyOwnershipto recover ownership to a new passkey owner
Errors
Error classes were moved to a separate subpackage:Using ERC-4337 flow
All transactions executed withsendTransaction and prepareTransaction now use Rhinestone intents.
Using the ERC-4337 user operations (for example, when using a social recovery) now requires a separate flow.
This change lets us improve type-safety and DX around using intents.
To keep using user operations for specific flows, change your code from:
Migrating from 0.x SDK
To use the latest version of the SDK, install it with thealpha tag:
deployerAccount parameter has been removed, as all deployments are now handled via the Orchestrator.
Also, sourceChains now accepts a list of chains instead of a single chain.
Due to the module address changes, you’d need to redeploy and refund the accounts.
Migrating from Orchestrator SDK
This guide provides a detailed breakdown of the changes between the Orchestrator SDK and the new SDK. If you’re looking for a fresh start, see our Quickstart.Installation
Previously:Account Creation
Choosing an account implementation
Before, you’d need to construct a smart account client withpermissionless:
The
account object is multi-chain; you don’t need to create separate instances for each chain.Choosing a validator
Before, you’d specify the validator config in your smart account setup:owners when creating the account:
Setting up Omni Account modules
Before, you’d need to provide the module configurations for the Omni Account manually:Under the hood, the SDK installs a single executor module that handles chain abstraction operations.
Initializing the Orchestrator Client
Before, you’d initialize an Orchestrator API client:Funding
As before, you can send the tokens or ETH directly to the account to fund it.Deploying
Before, you’d deploy the smart account using an ERC-4337 bundler:deploy method:
Fetching the Order Path
Before, you define the intent and usegetOrderPath to get the path.
prepareTransaction:
Signing the Intent
Before, you’d craft the packed signature and pass that to the bundle structure:signTransaction method:
Sending the Intent
Before, you’d use thepostSignedOrderBundle to submit the intent to the orchestrator:
submitTransaction method:
Getting the Intent Status
Before, you’d poll thegetBundleStatus method to get bundle status updates:
waitForExecution method: