Rhinestone supports both locked and unlocked funds. Using unlocked funds is the default flow and does not require any setup. In this case, the funds are “locked” just-in-time (the JIT flow). The claim transactions on source chain(s) are processed first, then the fill transaction is executed on the target chain. The JIT flow is generally slower. For a better performance, you can use resource-locked funds using the Fill-First flow instead. The user would first deposit (lock) the funds into The Compact contract. When executing an intent, the relayer would first handle the fill transaction on the destination chain, then use locked funds as a payment on the source chain(s). The Fill-First flow is significantly faster. Learn more about the JIT flow and Resource Locking in our conceptual guide.

Using Resource Locks

Deposits

To use resource locking, the user needs to top up their locked balance. There are two ways to lock: sweep user assets automatically or deposit manually.

Auto Top-Up

If enabled as part of the intent, The Compact will be automatically topped up the first time the user does an intent. The intent will use the JIT flow to sweep all supported tokens into The Compact. After that, all intents will come through the Fill-First flow (until the locked balance is depleted). To automatically lock the user funds:
const transactionResult = await rhinestoneAccount.sendTransaction({
  sourceChains: [base],
  targetChain: arbitrum,
  calls: [
    // …
  ],
  tokenRequests: [
    // …
  ],
  lockFunds: true,
})
This will lock the user assets into The Compact.

Manual Deposit

You can also deposit assets manually:
const usdcAddress = getTokenAddress('USDC', sourceChain.id);
const transactionResult = await rhinestoneAccount.sendTransaction({
  chain: sourceChain,
  calls: [
    depositEther(address, etherAmount),
    approveErc20(usdcAddress, usdcAmount),
    depositErc20(
      address,
      usdcAddress,
      usdcAmount,
    ),
  ],
})
This will lock both ETH and USDC on the source chain.

Unlocking The Funds

Users can unlock their funds if needed. There are two ways to unlock: using permissionless and instant withdrawals.

Permissionless Withdrawals

Permissionless withdrawals are two-step: you first need to enable the withdrawal, then wait for an unlock (reset) period, and do the actual withdrawal. The current reset period used by Rhinestone is 7 days. To enable the withdrawal:
const usdcAddress = getTokenAddress('USDC', sourceChain.id);
const transactionResult = await rhinestoneAccount.sendTransaction({
  chain: sourceChain,
  calls: [
    enableErc20Withdrawal(usdcAddress)
  ],
})
To withdraw the assets:
const usdcAddress = getTokenAddress('USDC', sourceChain.id);
const transactionResult = await rhinestoneAccount.sendTransaction({
  chain: sourceChain,
  calls: [
    withdrawErc20(address, usdcAddress, usdcAmount)
  ],
})

Instant Withdrawals

You can also withdraw instantly by requesting a signature from Rhinestone Orchestrator service.
We’re currently working on supporting this. Reach out if you need this.