Skip to content

Commit 97970aa

Browse files
fix(docs): sentence newline
1 parent aab74ca commit 97970aa

3 files changed

Lines changed: 21 additions & 10 deletions

File tree

docs/smart-accounts/5-custom-instruction-comparison.mdx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ keywords:
1818

1919
Flare Smart Accounts expose two custom instruction memo opcodes that ultimately execute the same `PackedUserOperation` against a personal account:
2020

21-
- [**Custom Instruction**](/smart-accounts/custom-instruction) - opcode `0xFE`. The XRPL memo carries only `keccak256(userOp)` in fixed 42 bytes; an off-chain executor delivers the ABI-encoded custom instruction (`userOp`) via `executeDirectMintingWithData`.
22-
- [**Raw Custom Instruction**](/smart-accounts/raw-custom-instruction) - opcode `0xFF`. The XRPL memo contains the ABI-encoded `PackedUserOperation` in full.
21+
- [**Custom Instruction**](/smart-accounts/custom-instruction) - opcode `0xFE`.
22+
The XRPL memo carries only `keccak256(userOp)` in fixed 42 bytes; an off-chain executor delivers the ABI-encoded custom instruction (`userOp`) via `executeDirectMintingWithData`.
23+
- [**Raw Custom Instruction**](/smart-accounts/raw-custom-instruction) - opcode `0xFF`.
24+
The XRPL memo contains the ABI-encoded `PackedUserOperation` in full.
2325

2426
Both flows are validated on-chain against the same `(sender, nonce)` rules and emit the same [`UserOperationExecuted`](/smart-accounts/reference/IMasterAccountController#useroperationexecuted) event.
2527
The difference is purely in how the user-operation bytes travel to Flare, and which actor performs which step.
@@ -46,7 +48,8 @@ The 0xFE memo is a constant 42 bytes regardless of the user operation size, whic
4648

4749
**Use the custom instruction (`0xFE`) when**
4850

49-
- The user operation's ABI encoding exceeds the XRPL memo cap (long `bytes` arguments, large call batches, or deeply nested structs). Without it, you would either split the logical user operation into multiple XRPL payments (paying minting and executor fees on each) or deploy a Flare-side shim contract to compress the call - the custom instruction eliminates both.
51+
- The user operation's ABI encoding exceeds the XRPL memo cap (long `bytes` arguments, large call batches, or deeply nested structs).
52+
Without it, you would either split the logical user operation into multiple XRPL payments (paying minting and executor fees on each) or deploy a Flare-side shim contract to compress the call - the custom instruction eliminates both.
5053
- You want the call payload to remain off the public XRPL ledger.
5154
- You already operate an executor that observes XRPL payments and submits Flare transactions - the custom instruction lets that executor batch deliveries or rate-limit submissions without splitting user operations into multiple XRPL payments.
5255
- You need fee predictability: the XRPL memo is always 42 bytes, so the XRPL fee is constant regardless of how complex the user operation is.
@@ -81,7 +84,8 @@ The example helpers in [`flare-viem-starter`](https://github.com/flare-foundatio
8184

8285
A practical decision rule when integrating:
8386

84-
1. Default to the custom instruction (`0xFE`). It fits every call batch and keeps the call payload off the public XRPL ledger.
87+
1. Default to the custom instruction (`0xFE`).
88+
It fits every call batch and keeps the call payload off the public XRPL ledger.
8589
2. Reach for the raw custom instruction (`0xFF`) only when you do not want to operate or coordinate with an executor service, and you can guarantee `abi.encode(userOp)` stays well under ~900 bytes (leaving room for the 10-byte header and XRPL framing).
8690

8791
## Reference

docs/smart-accounts/guides/typescript-viem/02-custom-instruction.mdx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -148,9 +148,12 @@ The on-chain checks (XRPL signature, `proofOwner` binding, `keccak256(data)` com
148148

149149
Each entry in the user operation is a [`Call`](/smart-accounts/reference/IPersonalAccount#call) struct with three fields:
150150

151-
- `target` - the address of the Flare contract to invoke. The personal account dispatches the call with itself as `msg.sender`, so this is the contract that ultimately runs the call.
152-
- `value` - the amount of the native token (FLR on mainnet, C2FLR on Coston2) in wei to attach to the call. The sum of `value` across all calls is what the executor must attach as `msg.value` on `executeDirectMintingWithData` in Step 2; that value flows `AssetManagerFXRP -> MasterAccountController -> PersonalAccount.executeUserOp` and is split back across the inner calls.
153-
- `data` - the ABI-encoded calldata (4-byte function selector followed by ABI-encoded arguments) the personal account passes to `target`. Use Viem's [`encodeFunctionData`](https://viem.sh/docs/contract/encodeFunctionData) to build it from the contract ABI, function name, and arguments.
151+
- `target` - the address of the Flare contract to invoke.
152+
The personal account dispatches the call with itself as `msg.sender`, so this is the contract that ultimately runs the call.
153+
- `value` - the amount of the native token (FLR on mainnet, C2FLR on Coston2) in wei to attach to the call.
154+
The sum of `value` across all calls is what the executor must attach as `msg.value` on `executeDirectMintingWithData` in Step 2; that value flows `AssetManagerFXRP -> MasterAccountController -> PersonalAccount.executeUserOp` and is split back across the inner calls.
155+
- `data` - the ABI-encoded calldata (4-byte function selector followed by ABI-encoded arguments) the personal account passes to `target`.
156+
Use Viem's [`encodeFunctionData`](https://viem.sh/docs/contract/encodeFunctionData) to build it from the contract ABI, function name, and arguments.
154157

155158
```typescript
156159
export type Call = {
@@ -411,8 +414,11 @@ export async function executeDirectMintingWithData({
411414

412415
Two details are critical here:
413416

414-
- **`proofOwner`**: the FDC `XRPPayment` request binds the proof to the externally owned account that will eventually submit it. `AssetManagerFXRP` enforces this through `TransactionAttestation.verifyProofOwnership`. Pass the executor's address so the proof can only be used by that executor.
415-
- **`value`**: `msg.value` on `executeDirectMintingWithData` is forwarded `AssetManager -> MasterAccountController.handleMintedFAssets -> PersonalAccount.executeUserOp`. It must therefore equal the sum of `call.value` across the user operation - exactly the `totalCallValue` returned by Step 1.
417+
- **`proofOwner`**: the FDC `XRPPayment` request binds the proof to the externally owned account that will eventually submit it.
418+
`AssetManagerFXRP` enforces this through `TransactionAttestation.verifyProofOwnership`.
419+
Pass the executor's address so the proof can only be used by that executor.
420+
- **`value`**: `msg.value` on `executeDirectMintingWithData` is forwarded `AssetManager -> MasterAccountController.handleMintedFAssets -> PersonalAccount.executeUserOp`.
421+
It must therefore equal the sum of `call.value` across the user operation - exactly the `totalCallValue` returned by Step 1.
416422

417423
## Step 3: confirm execution from the receipt
418424

docs/smart-accounts/reference/IMasterAccountController.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,8 @@ Parameters:
273273
- `_underlyingTimestamp`: The XRPL transaction timestamp.
274274
- `_memoData`: The raw XRPL memo bytes carrying the [memo instruction](/smart-accounts/custom-instruction-comparison).
275275
- `_executor`: The executor address; must equal the personal account's pinned executor when one is set.
276-
- `_data`: Extra data not contained in the XRPL memo. For the `0xFE` custom instruction this is the ABI-encoded `PackedUserOperation`; for all other instruction IDs it is ignored.
276+
- `_data`: Extra data not contained in the XRPL memo.
277+
For the `0xFE` custom instruction this is the ABI-encoded `PackedUserOperation`; for all other instruction IDs it is ignored.
277278

278279
The `AssetManager` is the only address allowed to call this function — any other caller reverts with [`OnlyAssetManager`](#onlyassetmanager).
279280

0 commit comments

Comments
 (0)