Skip to content

Commit 89a7b12

Browse files
committed
Examples
1 parent 8260063 commit 89a7b12

3 files changed

Lines changed: 228 additions & 0 deletions

File tree

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"math/big"
6+
7+
"github.com/eipcodelab/eip7702-go/pkg/eip7702"
8+
"github.com/ethereum/go-ethereum/common"
9+
"github.com/ethereum/go-ethereum/crypto"
10+
)
11+
12+
func main() {
13+
// Demo key used in local dev tooling only.
14+
key, err := crypto.HexToECDSA("4f3edf983ac63f7f8b7d0c4f76f2a5a70fadb53fcbf65f45d6fd5d77f07683ab")
15+
if err != nil {
16+
panic(err)
17+
}
18+
19+
chainID := big.NewInt(1)
20+
delegate := common.HexToAddress("0x1111111111111111111111111111111111111111")
21+
nonce := uint64(0)
22+
23+
auth, err := eip7702.SignAuthorization(key, chainID, delegate, nonce)
24+
if err != nil {
25+
panic(err)
26+
}
27+
authority, err := eip7702.VerifyAuthorization(auth, chainID)
28+
if err != nil {
29+
panic(err)
30+
}
31+
digest, err := eip7702.AuthorizationDigest(chainID, delegate, nonce)
32+
if err != nil {
33+
panic(err)
34+
}
35+
36+
fmt.Println("== Basic EIP-7702 Authorization ==")
37+
fmt.Printf("Authority (signer): %s\n", authority.Hex())
38+
fmt.Printf("Delegate target: %s\n", delegate.Hex())
39+
fmt.Printf("Authorization digest: 0x%x\n", digest)
40+
fmt.Printf("Tuple: [chain_id=%s, address=%s, nonce=%d, y_parity=%d, r=0x%x, s=0x%x]\n",
41+
auth.ChainID.String(), auth.Address.Hex(), auth.Nonce, auth.YParity, auth.R, auth.S)
42+
43+
delegationCode := eip7702.DelegationCode(delegate)
44+
fmt.Printf("Code designation: 0x%x\n", delegationCode)
45+
}

examples/send-userop/main.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package main
2+
3+
import (
4+
"context"
5+
"fmt"
6+
"math/big"
7+
"os"
8+
9+
"github.com/eipcodelab/eip7702-go/pkg/batching"
10+
"github.com/eipcodelab/eip7702-go/pkg/userop"
11+
"github.com/ethereum/go-ethereum/common"
12+
)
13+
14+
const walletDelegateABI = `[
15+
{
16+
"type": "function",
17+
"name": "execute",
18+
"stateMutability": "nonpayable",
19+
"inputs": [
20+
{"name": "target", "type": "address"},
21+
{"name": "value", "type": "uint256"},
22+
{"name": "data", "type": "bytes"}
23+
],
24+
"outputs": []
25+
}
26+
]`
27+
28+
func main() {
29+
sender := common.HexToAddress("0x000000000000000000000000000000000000dEaD")
30+
entryPoint := common.HexToAddress("0x0000000071727De22E5E9d8BAf0edAc6f37da032") // v0.6 example
31+
if env := os.Getenv("ENTRYPOINT"); env != "" {
32+
entryPoint = common.HexToAddress(env)
33+
}
34+
35+
callData, err := batching.EncodeFunctionCall(
36+
walletDelegateABI,
37+
"execute",
38+
common.HexToAddress("0x1111111111111111111111111111111111111111"),
39+
big.NewInt(0),
40+
[]byte{},
41+
)
42+
if err != nil {
43+
panic(err)
44+
}
45+
46+
op := userop.UserOperation{
47+
Sender: sender,
48+
Nonce: userop.HexBig(big.NewInt(0)),
49+
InitCode: []byte{},
50+
CallData: callData,
51+
CallGasLimit: userop.HexUint64(200_000),
52+
VerificationGasLimit: userop.HexUint64(300_000),
53+
PreVerificationGas: userop.HexUint64(80_000),
54+
MaxFeePerGas: userop.HexBig(big.NewInt(35_000_000_000)),
55+
MaxPriorityFeePerGas: userop.HexBig(big.NewInt(2_000_000_000)),
56+
PaymasterAndData: []byte{},
57+
Signature: []byte{0xde, 0xad, 0xbe, 0xef}, // replace with actual signature
58+
}
59+
60+
payload, err := userop.BuildSendUserOperationRequest(op, entryPoint)
61+
if err != nil {
62+
panic(err)
63+
}
64+
65+
fmt.Println("== ERC-4337 UserOperation over EIP-7702 account ==")
66+
fmt.Println(string(payload))
67+
68+
endpoint := os.Getenv("BUNDLER_RPC_URL")
69+
if endpoint == "" {
70+
fmt.Println("Dry-run only. Set BUNDLER_RPC_URL to broadcast.")
71+
return
72+
}
73+
74+
client := userop.NewBundlerClient(endpoint)
75+
hash, err := client.SendUserOperation(context.Background(), op, entryPoint)
76+
if err != nil {
77+
panic(err)
78+
}
79+
fmt.Printf("Submitted userOp hash: %s\n", hash.Hex())
80+
}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"math/big"
6+
7+
"github.com/eipcodelab/eip7702-go/pkg/batching"
8+
"github.com/eipcodelab/eip7702-go/pkg/eip7702"
9+
"github.com/ethereum/go-ethereum/common"
10+
"github.com/ethereum/go-ethereum/crypto"
11+
)
12+
13+
const erc20ABI = `[
14+
{
15+
"type": "function",
16+
"name": "transfer",
17+
"stateMutability": "nonpayable",
18+
"inputs": [
19+
{"name": "to", "type": "address"},
20+
{"name": "value", "type": "uint256"}
21+
],
22+
"outputs": [{"name": "", "type": "bool"}]
23+
}
24+
]`
25+
26+
func main() {
27+
key, err := crypto.HexToECDSA("4f3edf983ac63f7f8b7d0c4f76f2a5a70fadb53fcbf65f45d6fd5d77f07683ab")
28+
if err != nil {
29+
panic(err)
30+
}
31+
authority := crypto.PubkeyToAddress(key.PublicKey)
32+
33+
chainID := big.NewInt(1)
34+
delegate := common.HexToAddress("0x1111111111111111111111111111111111111111")
35+
36+
transferA, err := batching.EncodeFunctionCall(
37+
erc20ABI,
38+
"transfer",
39+
common.HexToAddress("0x2000000000000000000000000000000000000002"),
40+
big.NewInt(1_000_000_000_000_000_000), // 1 token with 18 decimals
41+
)
42+
if err != nil {
43+
panic(err)
44+
}
45+
transferB, err := batching.EncodeFunctionCall(
46+
erc20ABI,
47+
"transfer",
48+
common.HexToAddress("0x3000000000000000000000000000000000000003"),
49+
big.NewInt(250_000_000_000_000_000),
50+
)
51+
if err != nil {
52+
panic(err)
53+
}
54+
55+
batchCalldata, err := batching.EncodeExecuteBatch([]batching.Call{
56+
{
57+
Target: common.HexToAddress("0xA0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"), // example ERC20
58+
Value: big.NewInt(0),
59+
Data: transferA,
60+
},
61+
{
62+
Target: common.HexToAddress("0xA0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"),
63+
Value: big.NewInt(0),
64+
Data: transferB,
65+
},
66+
})
67+
if err != nil {
68+
panic(err)
69+
}
70+
71+
auth, err := eip7702.SignAuthorization(key, chainID, delegate, 0)
72+
if err != nil {
73+
panic(err)
74+
}
75+
76+
setCodeTx := &eip7702.SetCodeTx{
77+
ChainID: chainID,
78+
Nonce: 0,
79+
MaxPriorityFeePerGas: big.NewInt(2_000_000_000),
80+
MaxFeePerGas: big.NewInt(40_000_000_000),
81+
GasLimit: 300_000,
82+
Destination: authority,
83+
Value: big.NewInt(0),
84+
Data: batchCalldata,
85+
AuthorizationList: []eip7702.Authorization{auth},
86+
// Outer tx signature is placeholder in this example.
87+
SignatureYParity: 0,
88+
SignatureR: big.NewInt(1),
89+
SignatureS: big.NewInt(1),
90+
}
91+
92+
raw, err := setCodeTx.EncodeTypedTransaction()
93+
if err != nil {
94+
panic(err)
95+
}
96+
97+
fmt.Println("== EIP-7702 Transaction Batching ==")
98+
fmt.Printf("Authority: %s\n", authority.Hex())
99+
fmt.Printf("Delegation target: %s\n", delegate.Hex())
100+
fmt.Printf("Batch calldata: 0x%x\n", batchCalldata)
101+
fmt.Printf("Typed tx (0x04...): 0x%x\n", raw)
102+
fmt.Println("Note: sign the outer set-code transaction before broadcasting.")
103+
}

0 commit comments

Comments
 (0)