/bytecode), then adds the Notus-specific steps: resolve or register the smart wallet address, create a custom user operation from the bytecode list, sign userOperationHash, and call execute.
Resources
| Resource | Description |
|---|---|
| Deframe Docs | Strategy listing and bytecode generation |
| Register Smart Wallet | Notus POST /api/v1/wallets/register |
| Get Smart Wallet | Notus GET /api/v1/wallets/address |
| Create Custom User Operation | Notus POST /api/v1/crypto/custom-user-operation |
| Execute User Operation | Notus POST /api/v1/crypto/execute-user-op |
Prerequisites
Configure your backend or secure client with:- Deframe: base URL and
x-api-key(same as other integrations). - Notus:
X-Api-Keyheader on every Notus request, plus the factory address and salt your project uses so the counterfactual smart wallet is deterministic for each EOA.
https://api.notus.team/api/v1 as the API prefix (combine with the paths below).
Reference client
The snippets below usenotusPost, getSmartWalletFromNotus, createSmartWalletFromNotus, and signRawHash as shorthand. They are not part of Deframe — implement them in your app (for example with axios and viem WalletClient), following the same HTTP paths and headers as a typical Notus integration.
The structure below mirrors a small OOP-style client adapted from common Notus + viem setups (request builder, X-Api-Key, factory / salt, raw-hash signing for userOperationHash):
buildCustomUserOperation / sendUserOperation methods that call notusPost("/crypto/custom-user-operation", …) and notusPost("/crypto/execute-user-op", …) when you want a single place for all Notus traffic.
Integration pattern
1. Resolve the smart wallet (get or register)
The EOA is the address that will sign user operations. The smart wallet (account abstraction address) is derived from the EOA, factory, and salt. Recommended flow:- GET
/wallets/address?externallyOwnedAccount=...&factory=...&salt=...— Get Smart Wallet. - If the wallet is not registered yet (
registeredAtmissing or your product rules say so), POST/wallets/registerwith the sameexternallyOwnedAccount,factory, and optionalsalt— Register Smart Wallet.
wallet.accountAbstraction (or wallet.walletAddress when they match) as the walletAddress for Deframe bytecode requests and for Notus user operations.
Conceptually:
registeredAt and error payloads such as FACTORY_NOT_SUPPORTED).
2. Request strategy bytecodes from Deframe
| Parameter | Value |
|---|---|
| Method | GET |
| Path | /strategies/:strategy-id/bytecode |
| Query | action (required), wallet (required — use the Notus smart wallet address), amount (required, integer string in token decimals) |
| Headers | x-api-key: <Deframe API key> |
bytecode[] with to, data, value, and chainId per step. All steps in one Notus custom user operation must run in order on a single chainId; use the first item’s chainId when building the operation (if Deframe returns multiple chains, split into separate Notus flows).
3. Create a custom user operation on Notus
POST/crypto/custom-user-operation — Create Custom User Operation.
Map each Deframe bytecode to a Notus operation:
| Deframe | Notus body field |
|---|---|
to | operations[].address |
data | operations[].data |
value | operations[].value (hex string; use 0x0 when empty) |
chainId— number (e.g.137for Polygon; see Notus docs for supported networks).walletAddress— the smart wallet address from step 1.payGasFeeToken— ERC-20 contract address used to pay gas (required in the current API; pick the token Notus should debit for fees on that chain).
For a
lend action where the bytecode spends the entire balance of a
token, you usually cannot use that same token for payGasFeeToken: Notus
would try to pull fees from a balance already consumed by the lend flow, and
the user operation can revert. Prefer paying gas with the strategy
asset (or another token that still has leftover balance), not the
underlyingAsset when that is what you are fully deploying. For
withdraw, paying gas with the underlyingAsset is typically fine
because the flow increases that balance rather than draining it for the core
action.userOperation.userOperationHash (and related fields). If Notus returns a revert reason preview, fix balances, allowances, or ordering before executing.
4. Sign and execute the user operation
-
Sign the
userOperationHashwith the EOA that owns the smart wallet (raw message signature). With viem, sign the hash as raw bytes (not a human-readable EIP-191 message unless Notus specifies otherwise). Notus documents thatauthorizationmay be required on the first transaction for an EIP-7702 wallet: follow their note on viemsignAuthorization()vs serializing the signature for the execute endpoint — Execute User Operation. -
POST
/crypto/execute-user-opwith:userOperationHashsignatureauthorization— only when required for that wallet / first operation
Operational notes
- Single chain per custom user operation: Notus runs
operationsin order on onechainId. Multi-chain Deframe flows (metadata.isCrossChain) need a different orchestration than a single custom user operation. - Paymaster / gas token: Ensure
payGasFeeTokenand balances match Notus expectations for your project tier (errors such asUNAVAILABLE_COMPUTE_UNITSare documented on their side). - Smart wallet deployment: If the account is not yet deployed on the target chain, resolution or execution may fail until deployment rules for your factory are satisfied (see Notus factory compatibility and your dashboard settings).
Next steps
Privy Integration
Bytecode flow with embedded smart wallets
Dynamic Integration
Wallet auth and Deframe API usage
Deposit to Yield
End-user deposit guide
Fireblocks Integration
Custody integration