Skip to main content

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 rhinestone.createSession({ 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:
The hand-written shape is now SessionDefinition; Session is the resolved output of createSession.

Session creation resolves wrapped-native tokens

toSession no longer reads bundled chain data. Calling toSession(definition) without options omits the wrapped-native deposit() permission, so a session that later needs to wrap native tokens can fail. Use the project-scoped RhinestoneSDK.createSession method for the normal online flow. It resolves the chain’s wrapped-native token from the orchestrator and fails if the chain is unsupported or does not advertise one:
For a fully offline flow, keep using toSession and pass the wrapped-native token explicitly:
For normal online usage, prefer RhinestoneSDK.createSession so the SDK resolves the wrapped-native token for you.

Session policies are declarative

In 1.x, each action 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 createSession 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 on transfer / transferFrom / approve / increaseAllowance-shaped functions).
Passing a raw 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, and createSession 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:
The singletons that changed between V1 and V2 — pin the ones your account’s sessions were enabled against:

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:
To sign a non-default route, pass an 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:
The same shape applies to 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:

experimental_ prefix dropped from the smart session API

The smart session API is now stable, so the experimental_ prefix is gone. Drop it across your integration:

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.

Older account versions removed

The selectable account.version values are trimmed to the versions we actively support:
  • Nexus keeps 1.2.0 and 1.2.1 (default 1.2.1). Removed 1.0.2, rhinestone-1.0.0-beta, and rhinestone-1.0.0.
  • Kernel keeps 3.3 only. Removed 3.1 and 3.2.
If you pinned a removed version, omit version to use the default, or pin a supported one.

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.

Alchemy provider config removed

The SDK no longer builds Alchemy URLs from an API key. Supply the RPC URLs through the custom provider config, or omit provider to use viem’s default transport:

Permit2 claim policy renames

If you constructed Permit2ClaimPolicy values directly, the type tag and field names changed to be chain-aware:

Token registry helpers removed

The SDK no longer bundles the supported-chain and token registry. SupportedChain is now number, so code must not assume that the installed SDK contains an exhaustive union of chain IDs. getSupportedTokens, getTokenAddress, getTokenDecimals, getAllSupportedChainsAndTokens, getWethAddress, getTokenSymbol, and isTokenAddressSupported are removed. Fetch the supported chains, token metadata, and wrappedNativeToken from the orchestrator’s /chains endpoint:

Token inputs are addresses

SDK token inputs no longer accept symbols like 'USDC' — pass the token’s address for the relevant chain. This applies to calls[].to, tokenRequests[].address, sourceAssets (both the token-list and per-chain-map forms), and cross-chain permit legs (from / to).
Look up token addresses per chain from the orchestrator’s /chains endpoint (see Token registry helpers removed).

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

  • createRhinestoneAccount is removed. Use new RhinestoneSDK({ apiKey }).createAccount(config).
  • Account recovery. The @rhinestone/sdk/actions/recovery subpackage (enable, recoverEcdsaOwnership, recoverPasskeyOwnership), the recovery field on the account config, and the guardian signer set are removed.
  • account.deploy() session param. The unused session option on account.deploy() is removed (it was a no-op).
  • 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.

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:
to this:

Transaction utilities (actions)

Action utilities related to using modules and resource locking (e.g., installModule, addOwner, recoverEcdsaOwnership) were moved to separate subpackages:
Additionally, you don’t need to pass rhinestoneAccount, address, chain, and provider params anymore when using 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

Errors

Error classes were moved to a separate subpackage:

Using ERC-4337 flow

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:
and
to:
and:

Migrating from 0.x SDK

To use the latest version of the SDK, install it with the alpha tag:
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.

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:
Now:

Account Creation

Choosing an account implementation

Before, you’d need to construct a smart account client with permissionless:
Now:
The account object is multi-chain; you don’t need to create separate instances for each chain.
See Smart Account Providers for details on choosing the account implementation.

Choosing a validator

Before, you’d specify the validator config in your smart account setup:
Now, you can use owners when creating the account:
Learn more about using the ECDSA and passkey validators as the account owner. If you are using Smart Sessions, see the relevant guide.

Setting up Omni Account modules

Before, you’d need to provide the module configurations for the Omni Account manually:
Now, that is handled automatically for you.
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:
Now, you need to pass the API key directly to the account instance:

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:
Now, you can use the deploy method:

Fetching the Order Path

Before, you define the intent and use getOrderPath to get the path.
Now, you can call prepareTransaction:

Signing the Intent

Before, you’d craft the packed signature and pass that to the bundle structure:
Now, you can use the signTransaction method:

Sending the Intent

Before, you’d use the postSignedOrderBundle to submit the intent to the orchestrator:
Now, you can use the submitTransaction method:

Getting the Intent Status

Before, you’d poll the getBundleStatus method to get bundle status updates:
Now, you can use the waitForExecution method:

Using with Existing Accounts

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.