Skip to content

Commit

Permalink
started on examples
Browse files Browse the repository at this point in the history
  • Loading branch information
wilsoncusack committed Feb 5, 2024
1 parent ed8bdb7 commit b0bbeb4
Show file tree
Hide file tree
Showing 5 changed files with 162 additions and 40 deletions.
80 changes: 40 additions & 40 deletions src/Encoder.sol
Original file line number Diff line number Diff line change
Expand Up @@ -62,22 +62,29 @@ library MessageDataCodec {

function encode(MessageData memory instance) internal pure returns (bytes memory) {
// Omit encoding fields if default value
bytes memory type__Key = uint64(instance.type_) != 0 ? ProtobufLib.encode_key(1, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory type_ = uint64(instance.type_) != 0 ? ProtobufLib.encode_int32(int32(uint32(instance.type_))) : new bytes(0);
bytes memory fid__Key = uint64(instance.fid) != 0 ? ProtobufLib.encode_key(2, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory type__Key =
uint64(instance.type_) != 0 ? ProtobufLib.encode_key(1, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory type_ =
uint64(instance.type_) != 0 ? ProtobufLib.encode_int32(int32(uint32(instance.type_))) : new bytes(0);
bytes memory fid__Key =
uint64(instance.fid) != 0 ? ProtobufLib.encode_key(2, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory fid = uint64(instance.fid) != 0 ? ProtobufLib.encode_uint64(instance.fid) : new bytes(0);
bytes memory timestamp__Key = uint64(instance.timestamp) != 0 ? ProtobufLib.encode_key(3, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory timestamp = uint64(instance.timestamp) != 0 ? ProtobufLib.encode_uint32(instance.timestamp) : new bytes(0);
bytes memory network__Key = uint64(instance.network) != 0 ? ProtobufLib.encode_key(4, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory network = uint64(instance.network) != 0 ? ProtobufLib.encode_int32(int32(uint32(instance.network))) : new bytes(0);
bytes memory timestamp__Key = uint64(instance.timestamp) != 0
? ProtobufLib.encode_key(3, uint64(ProtobufLib.WireType.Varint))
: new bytes(0);
bytes memory timestamp =
uint64(instance.timestamp) != 0 ? ProtobufLib.encode_uint32(instance.timestamp) : new bytes(0);
bytes memory network__Key = uint64(instance.network) != 0
? ProtobufLib.encode_key(4, uint64(ProtobufLib.WireType.Varint))
: new bytes(0);
bytes memory network =
uint64(instance.network) != 0 ? ProtobufLib.encode_int32(int32(uint32(instance.network))) : new bytes(0);

// Encode frame_action_body
FrameActionBodyCodec.FrameActionBody__Encoded__Nested memory frame_action_body = FrameActionBodyCodec.encodeNested(16, instance.frame_action_body);
bytes memory frame_action_body__Encoded = abi.encodePacked(
frame_action_body.key,
frame_action_body.length,
frame_action_body.nestedInstance
);
FrameActionBodyCodec.FrameActionBody__Encoded__Nested memory frame_action_body =
FrameActionBodyCodec.encodeNested(16, instance.frame_action_body);
bytes memory frame_action_body__Encoded =
abi.encodePacked(frame_action_body.key, frame_action_body.length, frame_action_body.nestedInstance);

// Use abi.encodePacked for efficient concatenation
return abi.encodePacked(
Expand Down Expand Up @@ -131,19 +138,17 @@ library CastIdCodec {
}

function encode(CastId memory instance) internal pure returns (bytes memory) {
bytes memory fid__Key = uint64(instance.fid) != 0 ? ProtobufLib.encode_key(1, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory fid__Key =
uint64(instance.fid) != 0 ? ProtobufLib.encode_key(1, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory fid = uint64(instance.fid) != 0 ? ProtobufLib.encode_uint64(instance.fid) : new bytes(0);
bytes memory hash__Key = instance.hash.length > 0 ? ProtobufLib.encode_key(2, uint64(ProtobufLib.WireType.LengthDelimited)) : new bytes(0);
bytes memory hash__Length = instance.hash.length > 0 ? ProtobufLib.encode_uint64(uint64(instance.hash.length)) : new bytes(0);
bytes memory hash__Key = instance.hash.length > 0
? ProtobufLib.encode_key(2, uint64(ProtobufLib.WireType.LengthDelimited))
: new bytes(0);
bytes memory hash__Length =
instance.hash.length > 0 ? ProtobufLib.encode_uint64(uint64(instance.hash.length)) : new bytes(0);
bytes memory hash = instance.hash.length > 0 ? bytes(instance.hash) : new bytes(0);

return abi.encodePacked(
fid__Key,
fid,
hash__Key,
hash__Length,
hash
);
return abi.encodePacked(fid__Key, fid, hash__Key, hash__Length, hash);
}

// Encode a nested CastId, wrapped in key and length if non-default
Expand Down Expand Up @@ -187,26 +192,21 @@ library FrameActionBodyCodec {
}

function encode(FrameActionBody memory instance) internal pure returns (bytes memory) {
bytes memory url__Key = instance.url.length > 0 ? ProtobufLib.encode_key(1, uint64(ProtobufLib.WireType.LengthDelimited)) : new bytes(0);
bytes memory url__Length = instance.url.length > 0 ? ProtobufLib.encode_uint64(uint64(instance.url.length)) : new bytes(0);
bytes memory url__Key = instance.url.length > 0
? ProtobufLib.encode_key(1, uint64(ProtobufLib.WireType.LengthDelimited))
: new bytes(0);
bytes memory url__Length =
instance.url.length > 0 ? ProtobufLib.encode_uint64(uint64(instance.url.length)) : new bytes(0);
bytes memory url = instance.url.length > 0 ? bytes(instance.url) : new bytes(0);
bytes memory button_index__Key = uint64(instance.button_index) != 0 ? ProtobufLib.encode_key(2, uint64(ProtobufLib.WireType.Varint)) : new bytes(0);
bytes memory button_index = uint64(instance.button_index) != 0 ? ProtobufLib.encode_uint32(instance.button_index) : new bytes(0);
bytes memory button_index__Key = uint64(instance.button_index) != 0
? ProtobufLib.encode_key(2, uint64(ProtobufLib.WireType.Varint))
: new bytes(0);
bytes memory button_index =
uint64(instance.button_index) != 0 ? ProtobufLib.encode_uint32(instance.button_index) : new bytes(0);
CastIdCodec.CastId__Encoded__Nested memory cast_id = CastIdCodec.encodeNested(3, instance.cast_id);
bytes memory cast_id__Encoded = abi.encodePacked(
cast_id.key,
cast_id.length,
cast_id.nestedInstance
);
bytes memory cast_id__Encoded = abi.encodePacked(cast_id.key, cast_id.length, cast_id.nestedInstance);

return abi.encodePacked(
url__Key,
url__Length,
url,
button_index__Key,
button_index,
cast_id__Encoded
);
return abi.encodePacked(url__Key, url__Length, url, button_index__Key, button_index, cast_id__Encoded);
}

// Encode a nested FrameActionBody, wrapped in key and length if non-default
Expand Down
48 changes: 48 additions & 0 deletions src/examples/ERC4337/Account.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import {MessageData} from "../../FrameVerifier.sol";
// import Strings

import {UserOperation} from "./UserOperation.sol";
import {SharedVerifier} from "../SharedVerifier.sol";

contract Account {
bytes32 public publicKey;
string public baseUrl;
SharedVerifier public sharedVerifier;
uint256 public lastFrameTimstamp;

struct FrameUserOpSignature {
bytes32 signature_r;
bytes32 signature_s;
MessageData messageData;
}

function validateUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 missingAccountFunds)
external
returns (uint256 validationData)
{
FrameUserOpSignature memory frameStruct = abi.decode(userOp.signature, (FrameUserOpSignature));
string memory expectedUrl = string.concat(baseUrl, Strings.toString(block.chainId), ":", userOp.callData);
frameStruct.messageData.frame_action_body.url = expectedUrl;

if (
SharedVerifier.verifyMessageData(
SharedVerifier.VerifyRequest(
publicKey, frameStruct.signature_r, frameStruct.signature_s, frameStruct.messageData
)
)
) {
if (frameStruct.messageData.frame_action_body.timestamp < lastFrameTimstamp) {
return 1;
}
lastFrameTimstamp = frameStruct.messageData.frame_action_body.timestamp;
return 0;
}

return 1;

// pay missing account funds
}
}
24 changes: 24 additions & 0 deletions src/examples/ERC4337/Paymaster.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import {UserOperation} from "./UserOperation.sol";
import {SharedVerifier} from "../SharedVerifier.sol";

contract Paymaster {
mapping(bytes32 => uint256) public castBalance;
mapping(uint256 => uint256) public fidBalance;

function validatePaymasterUserOp(UserOperation calldata userOp, bytes32 userOpHash, uint256 maxCost)
external
returns (bytes memory context, uint256 validationData)
{}

function postOp(PostOpMode mode, bytes calldata context, uint256 actualGasCost) external {}

enum PostOpMode {
opSucceeded, // user op succeeded
opReverted, // user op reverted. still has to pay for gas.
postOpReverted // user op succeeded, but caused postOp to revert

}
}
16 changes: 16 additions & 0 deletions src/examples/ERC4337/UserOperation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

struct UserOperation {
address sender;
uint256 nonce;
bytes initCode;
bytes callData;
uint256 callGasLimit;
uint256 verificationGasLimit;
uint256 preVerificationGas;
uint256 maxFeePerGas;
uint256 maxPriorityFeePerGas;
bytes paymasterAndData;
bytes signature;
}
34 changes: 34 additions & 0 deletions src/examples/SharedVerifier.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;

import {MessageData, FrameVerifier} from "../FrameVerifier.sol";

// To attempt to save gas verifying Frames in multiple contracts
// we can use a shared verifier that saves the result
contract SharedVerifier {
mapping(bytes32 => bool) public isValid;

struct VerifyRequest {
bytes32 public_key;
bytes32 signature_r;
bytes32 signature_s;
MessageData messageData;
}

function verifyMessageData(VerifyRequest memory request) external returns (bool) {
bytes32 hash = keccak256(abi.encode(request.messageData));
if (isValid[hash]) {
return true;
}

bool valid = FrameVerifier.verifyMessageData(
request.public_key, request.signature_r, request.signature_s, request.messageData
);

if (valid) {
isValid[hash] = true;
}

return valid;
}
}

0 comments on commit b0bbeb4

Please sign in to comment.