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).
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:
prepareTransaction now returns quotes: { best, all } instead of a single quote. Existing prepare → sign → submit code keeps working — signTransaction defaults to quotes.best:
const prepared = await rhinestoneAccount.prepareTransaction({ // …})const signed = await rhinestoneAccount.signTransaction(prepared)const result = await rhinestoneAccount.submitTransaction(signed)
To sign a non-default route, pass an intentId from prepared.quotes.all:
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:
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:
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.
getSupportedTokens, getTokenAddress, getTokenDecimals, and getAllSupportedChainsAndTokens are removed. Fetch the equivalent data from the orchestrator’s /chains endpoint:
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.
Compact-bound surface. The @rhinestone/sdk/actions/compact subpackage, the lockFunds transaction option, and Account.emissaryConfig are removed alongside the orchestrator’s compact-based deposit/withdrawal flow.
Permit2 signing helpers.signPermit2Batch, signPermit2Sequential, and the related MultiChainPermit2Config / MultiChainPermit2Result / BatchPermit2Result types are removed. Signing now uses orchestrator-provided EIP-712 typed data internally.
getPermit2Address is removed. Permit2 lives at 0x000000000022D473030F116dDEE9F6B43aC78BA3 on every supported chain — hardcode the constant.
walletClientToAccount and wrapParaAccount moved from the package root to @rhinestone/sdk/utils.
Action utilities related to using modules and resource locking (e.g., installModule, addOwner, recoverEcdsaOwnership) were moved to separate subpackages:
// Beforeimport { addPasskeyOwner } from '@rhinestone/sdk'// Afterimport { addOwner as addPasskeyOwner } from '@rhinestone/sdk/actions/passkeys'
Additionally, you don’t need to pass rhinestoneAccount, address, chain, and provider params anymore when using actions:
// Beforeawait rhinestoneAccount.sendTransaction({ calls: [ ...installModule({ rhinestoneAccount, module, }) ], // …})// Afterawait rhinestoneAccount.sendTransaction({ calls: [ // Note that you don't need to spread the actions anymore installModule(module) ], // …})
All actions
/actions:
installModule to install a module
uninstallModule to uninstall a module
/actions/compact (resource locking with TheCompact):
depositEther to deposit ETH into TheCompact
enableEtherWithdrawal to enable permissionless ETH withdrawal (starts reset period)
disableEtherWithdrawal to cancel permissionless ETH withdrawal
withdrawEther to withdraw ETH after the reset period
approveErc20 to approve an ERC-20 token for deposit
depositErc20 to deposit ERC-20 into TheCompact
enableErc20Withdrawal to enable permissionless ERC-20 withdrawal (starts reset period)
disableErc20Withdrawal to cancel permissionless ERC-20 withdrawal
withdrawErc20 to withdraw ERC-20 after the reset period
/actions/ecdsa (ECDSA validator):
enable to enable the validator
disable to disable the validator
addOwner to add an owner
removeOwner to remove an owner
changeThreshold to change the signature threshold
/actions/mfa (multi-factor authorization):
enable to enable the validator
disable to disable the validator
setSubValidator to add a sub-validator to the MFA set
removeSubValidator to remove a sub-validator from the MFA set
changeThreshold to change the MFA signature threshold
/actions/passkeys (passkey validator):
enable to enable the validator
disable to disable the validator
addOwner to add an owner
removeOwner to remove an owner
changeThreshold to change the signature threshold
/actions/recovery (social recovery):
enable to enable the validator
recoverEcdsaOwnership to recover ownership to a new ECDSA owner
recoverPasskeyOwnership to recover ownership to a new passkey owner
All transactions executed with sendTransaction 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:
const result = await rhinestoneAccount.sendTransaction( // …)
and
const data = await rhinestoneAccount.prepareTransaction({ // …})const signedData = await rhinestoneAccount.signTransaction(data)const result = await rhinestoneAccount.submitTransaction(signedData)
to:
const result = await rhinestoneAccount.sendUserOperation( // …)
and:
const data = await rhinestoneAccount.prepareUserOperation({ // …})const signedData = await rhinestoneAccount.signUserOperation(data)const result = await rhinestoneAccount.submitUserOperation(signedData)
To use the latest version of the SDK, install it with the alpha tag:
npm i @rhinestone/sdk@alpha
Note that the 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.
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.
For now, using the SDK with existing accounts is not possible. Users would need to create a new smart account.We’re working on making it possible to use the SDK with existing (deployed) smart accounts.Reach out if you need this.