Skip to content

Commit

Permalink
update examples (#44)
Browse files Browse the repository at this point in the history
* replace goerli w/ holesky in suave examples

* replace goerli w/ holesky in suave examples

* bun install

* chore: format

* update demos

* updating suave-std

* forge install: suave-std

* update suave-std

* update fn visibility in suave example to enable 'is Suapp'

* improve suave-web-demo readme

* fix comment

* fix suave example; make buildEthBlock work on all eth providers (requires suave-std upgrade)

* update suave-std (pin to commit da7ff46042139847cf32ba30afc1e24f4dc0bd86)

---------

Co-authored-by: zeroXbrock <[email protected]>
  • Loading branch information
zeroXbrock and zeroXbrock authored Jul 1, 2024
1 parent 9efacae commit be59d8d
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 25 deletions.
14 changes: 11 additions & 3 deletions examples/suave-web-demo/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,25 @@ Simple Vanilla JS web app that sends a mev-share bid to suave.

> This project requires a local suave-geth devnet to be running. See [instructions here](https://github.com/flashbots/suave-geth/tree/main?tab=readme-ov-file#starting-a-local-devnet) to spin one up.
Go to the [suave example](../suave/) and run `./deployContracts.sh`:
Start by building the library:

```sh
cd ../suave
# in project root (suave-viem/)
bun install
bun run build
```

Next, go to the [suave example](../suave/) and run `./deployContracts.sh`:

```sh
cd examples/suave
./deployContracts.sh
cd -
```

Next, install the project's dependencies.

```sh
cd ../suave-web-demo
bun install
```

Expand Down
2 changes: 1 addition & 1 deletion examples/suave-web-demo/src/suave.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function setupSendBidButton(
data: '0xf00ba7' as Hex,
}
const signedTx = await l1Wallet.signTransaction(sampleTx)
console.log('signed goerli tx', signedTx)
console.log('signed L1 tx', signedTx)

// create bid & send ccr
const decryptionCondition = 1n + (await l1Provider.getBlockNumber())
Expand Down
2 changes: 1 addition & 1 deletion examples/suave/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
PRIVATE_KEY=0x91ab9a7e53c220e6210460b65a7a3bb2ca181412a8a7b43ff336b3df1737ce12
KETTLE_ADDRESS=0xb5feafbdd752ad52afb7e1bd2e40432a485bbb7f
SUAVE_RPC_URL_HTTP=http://localhost:8545
GOERLI_RPC_URL_HTTP=https://ethereum-goerli.publicnode.com
L1_RPC_URL_HTTP=https://ethereum-holesky.publicnode.com
6 changes: 3 additions & 3 deletions examples/suave/bids.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ export class OFAOrder {
return encodeAbiParameters([
{
components: [
{ type: 'uint', name: 'blockNumber' },
{ type: 'uint', name: 'minTimestamp' },
{ type: 'uint', name: 'maxTimestamp' },
{ type: 'uint64', name: 'blockNumber' },
{ type: 'uint64', name: 'minTimestamp' },
{ type: 'uint64', name: 'maxTimestamp' },
{ type: 'bytes[]', name: 'txns' },
],
name: 'BundleObj',
Expand Down
9 changes: 5 additions & 4 deletions examples/suave/contracts/src/OFA.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
pragma solidity ^0.8.8;

import "suave-std/suavelib/Suave.sol";
import "suave-std/Suapp.sol";
import {Bundle} from "suave-std/protocols/Bundle.sol";
import "solady/src/utils/LibString.sol";

contract OFAPrivate {
contract OFAPrivate is Suapp {
// Struct to hold hint-related information for an order.
struct HintOrder {
Suave.DataId id;
Expand All @@ -19,11 +20,11 @@ contract OFAPrivate {
event Debug(string message, bytes data);

// Internal function to save order details and generate a hint.
function saveOrder(uint64 decryptionCondition) internal view returns (HintOrder memory) {
function saveOrder(uint64 decryptionCondition) internal returns (HintOrder memory) {
// Retrieve the bundle data from the confidential inputs
bytes memory bundleData = Suave.confidentialInputs();
Bundle.BundleObj memory bundle = abi.decode(bundleData, (Bundle.BundleObj));
bundleData = Bundle.encodeBundle(bundle).body;
bundleData = Bundle.encodeBundleParams(bundle);

// Simulate the bundle and extract its score.
uint64 egp = Suave.simulateBundle(bundleData);
Expand Down Expand Up @@ -109,7 +110,7 @@ contract OFAPrivate {
return abi.encodeWithSelector(this.emitMatchDataRecordAndHintCallback.selector, response);
}

function submitBundle(string memory builderUrl, bytes memory bundleData) internal view returns (bytes memory) {
function submitBundle(string memory builderUrl, bytes memory bundleData) internal returns (bytes memory) {
// encode the jsonrpc request in JSON format.
bytes memory body =
abi.encodePacked('{"jsonrpc":"2.0","method":"mev_sendBundle","params":[', bundleData, '],"id":1}');
Expand Down
38 changes: 25 additions & 13 deletions examples/suave/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { sleep } from 'bun'
import { http, Address, Hex, createPublicClient, formatEther, isHex } from 'viem'
import { goerli } from 'viem/chains'
import { holesky } from 'viem/chains'
import { TransactionRequestSuave } from 'viem/chains/suave/types'
import { OFAOrder } from './bids'
import { SuaveProvider, SuaveWallet, getSuaveProvider, getSuaveWallet, parseTransactionSuave } from 'viem/chains/utils'
Expand All @@ -19,15 +19,15 @@ if (!process.env.KETTLE_ADDRESS) {
if (!process.env.SUAVE_RPC_URL_HTTP) {
console.warn('SUAVE_RPC_URL_HTTP not set. Defaulting to localhost:8545')
}
if (!process.env.GOERLI_RPC_URL_HTTP) {
console.warn('GOERLI_RPC_URL_HTTP not set. Defaulting to localhost:8545')
if (!process.env.L1_RPC_URL_HTTP) {
console.warn('L1_RPC_URL_HTTP not set. Defaulting to localhost:8545')
}
const KETTLE_ADDRESS: Address = process.env.KETTLE_ADDRESS as Address
const PRIVATE_KEY: Hex = process.env.PRIVATE_KEY as Hex
const SUAVE_RPC_URL_HTTP: string =
process.env.SUAVE_RPC_URL_HTTP || 'http://localhost:8545'
const GOERLI_RPC_URL_HTTP: string =
process.env.GOERLI_RPC_URL_HTTP || 'http://localhost:8545'
const L1_RPC_URL_HTTP: string =
process.env.L1_RPC_URL_HTTP || 'http://localhost:8555'

if (!BidContractDeployment.address) {
console.error(
Expand All @@ -42,17 +42,17 @@ if (!isHex(BidContractDeployment.address)) {
const BID_CONTRACT_ADDRESS = BidContractDeployment.address as Hex

const suaveProvider: SuaveProvider<HttpTransport> = getSuaveProvider(http(SUAVE_RPC_URL_HTTP))
const goerliProvider = createPublicClient({
chain: goerli,
transport: http(GOERLI_RPC_URL_HTTP),
const l1Provider = createPublicClient({
chain: holesky,
transport: http(L1_RPC_URL_HTTP),
})
const adminWallet: SuaveWallet<HttpTransport> = getSuaveWallet({
transport: http(SUAVE_RPC_URL_HTTP),
privateKey: PRIVATE_KEY,
})
const wallet = getSuaveWallet({
transport: http(SUAVE_RPC_URL_HTTP),
privateKey: '0x01000070530220062104600650003002001814120800043ff33603df10300012',
privateKey: "0x6c45335a22461ccdb978b78ab61b238bad2fae4544fb55c14eb096c875ccfc52",
})
console.log('admin', adminWallet.account.address)
console.log('wallet', wallet.account.address)
Expand Down Expand Up @@ -90,10 +90,19 @@ const fundAccount = async (wallet: Address, amount: bigint) => {
}
return await adminWallet.sendTransaction(tx)
} else {
console.log(`wallet balance: ${formatEther(balance)} ETH`)
console.log(`SUAVE wallet balance: ${formatEther(balance)} ETH`)
}
}

async function checkL1Balance(minBalance?: bigint) {
const balance = await l1Provider.getBalance({ address: wallet.account.address })
const absoluteMin = minBalance || 1n
if (balance < absoluteMin) {
throw new Error(`L1 balance too low: ${formatEther(balance)} ETH (needed ${formatEther(absoluteMin)}).\nPlease fund this account: ${wallet.account.address}`)
}
console.log(`L1 balance: ${formatEther(balance)} ETH`)
}

/** MEV-Share implementation on SUAVE.
*
* To run this, you'll need to deploy the contract first.
Expand All @@ -107,18 +116,21 @@ async function testSuaveBids() {
)
fundRes && console.log('fundRes', fundRes)

// a tx that should be landed on goerli
// a tx that should be landed on L1
const testTx = {
to: '0x0000000000000000000000000000000000000000' as Address,
data: '0x686f776479' as Hex,
gas: 26000n,
gasPrice: 10000000000n,
chainId: 5,
chainId: 17000,
}
checkL1Balance(testTx.gas * testTx.gasPrice)
const signedTx = await wallet.signTransaction(testTx)

console.log("signed tx", signedTx)

// create bid & send ccr
const block = await goerliProvider.getBlockNumber()
const block = await l1Provider.getBlockNumber()
const bid = new OFAOrder(
block + 1n,
signedTx,
Expand Down

0 comments on commit be59d8d

Please sign in to comment.