Skip to content

Commit 30569c6

Browse files
authored
Merge pull request #1092 from tkhq/foundry-example
initial foundry example
2 parents a1fa36b + f784571 commit 30569c6

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

76 files changed

+29305
-0
lines changed

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,8 @@ turnkey.json
135135

136136
# turborepo
137137
.turbo
138+
139+
# Foundry
140+
out/
141+
cache/
142+
broadcast/

examples/foundry/.env.example

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
TURNKEY_API_PRIVATE_KEY="<Turnkey API Private Key>"
2+
TURNKEY_ORGANIZATION_ID="<Turnkey organization ID>"
3+
TURNKEY_ADDRESS="<Turnkey Wallet Account Address, Private Key Address, or Private Key ID>"
4+
FOUNDRY_DISABLE_NIGHTLY_WARNING="true" # required until production release

examples/foundry/README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
# Example: `foundry`
2+
3+
This example shows how to set up and broadcast a smart contract from a Turnkey wallet using Foundry & Forge.
4+
5+
## Getting started
6+
7+
### 0 / Foundry versioning
8+
9+
Make sure you have [Foundry](https://getfoundry.sh/introduction/installation) installed locally.
10+
Until >v1.4.4 release, it is also necessary to use a Nightly build for the Turnkey flag to be enabled.
11+
12+
```bash
13+
$ curl -L https://foundry.paradigm.xyz | bash
14+
$ foundryup --install nightly
15+
```
16+
17+
### 1/ Cloning the example
18+
19+
```bash
20+
$ git clone https://github.com/tkhq/sdk
21+
$ cd sdk/examples/foundry/
22+
```
23+
24+
### 2/ Setting up Turnkey
25+
26+
The first step is to set up your Turnkey organization and account. By following the [Quickstart](https://docs.turnkey.com/getting-started/quickstart) guide, you should have:
27+
28+
- A public/private API key pair for Turnkey
29+
- An organization ID
30+
- A Turnkey wallet account (address), private key address, or a private key ID
31+
32+
Once you've gathered these values, add them to a new `.env` file. Notice that your private key should be securely managed and **_never_** be committed to git.
33+
34+
```bash
35+
$ cp .env.example .env
36+
```
37+
38+
Now open `.env` and add the missing environment variables:
39+
40+
- `TURNKEY_API_PRIVATE_KEY`
41+
- `TURNKEY_ORGANIZATION_ID`
42+
- `TURNKEY_ADDRESS` -- a Turnkey wallet account address, private key address, or private key ID
43+
44+
For convenience we have hardcoded several popular chains and RPCs in `foundry.toml`, but you're welcome to change for different values.
45+
46+
### 3/ Running the sample deploy script
47+
48+
The following command will compile and broadcast Foundry's demo `Counter.sol` contract to the Sepolia network.
49+
You will need some SepoliaETH in your Turnkey wallet address.
50+
51+
```bash
52+
$ forge script script/Counter.s.sol --rpc-url sepolia --turnkey --broadcast
53+
```
54+
55+
Visit the relevant chain explorer to view your transaction; you have successfully signed and deployed your first contract with Turnkey!
56+
57+
See the following for a sample output:
58+
59+
```
60+
[⠊] Compiling...
61+
No files changed, compilation skipped
62+
Script ran successfully.
63+
64+
## Setting up 1 EVM.
65+
66+
==========================
67+
68+
Chain 11155111
69+
70+
Estimated gas price: 0.001037667 gwei
71+
72+
Estimated total gas used for script: 203856
73+
74+
Estimated amount required: 0.000000211534643952 ETH
75+
76+
==========================
77+
78+
##### sepolia
79+
✅ [Success] Hash: 0xf492f7059d91ec1b91537a82b55289d1091e2a498db2881bd04d19b26ad29e0d
80+
Contract Address: 0x2352D015613705F2c365dEead916d45BAaf547d4
81+
Block: 9624270
82+
Paid: 0.000000162718420767 ETH (156813 gas * 0.001037659 gwei)
83+
84+
✅ Sequence #1 on sepolia | Total Paid: 0.000000162718420767 ETH (156813 gas * avg 0.001037659 gwei)
85+
86+
87+
==========================
88+
```

examples/foundry/foundry.lock

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
{
2+
"lib/forge-std": {
3+
"tag": {
4+
"name": "v1.11.0",
5+
"rev": "8e40513d678f392f398620b3ef2b418648b33e89"
6+
}
7+
}
8+
}

examples/foundry/foundry.toml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[profile.default]
2+
src = "src"
3+
out = "out"
4+
libs = ["lib"]
5+
6+
# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
7+
8+
[rpc_endpoints]
9+
base = "https://mainnet.base.org"
10+
baseSepolia = "https://sepolia.base.org"
11+
ethereum = "https://ethereum.publicnode.com"
12+
sepolia = "https://ethereum-sepolia-rpc.publicnode.com"
13+
polygon = "https://polygon-rpc.com"
14+
polygonAmoy = "https://rpc-amoy.polygon.technology"
15+
monadTestnet = "https://testnet-rpc.monad.xyz/"
16+
celo = "https://forno.celo.org"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
src/Vm.sol linguist-generated
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
* @danipopes @klkvr @mattsse @grandizzy @yash-atreya @zerosnacks @onbjerg @0xrusowsky
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
version: 2
2+
updates:
3+
- package-ecosystem: "github-actions"
4+
directory: "/"
5+
schedule:
6+
interval: "weekly"
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
name: CI
2+
3+
permissions: {}
4+
5+
on:
6+
workflow_dispatch:
7+
pull_request:
8+
push:
9+
branches:
10+
- master
11+
12+
jobs:
13+
build:
14+
name: build +${{ matrix.toolchain }} ${{ matrix.flags }}
15+
runs-on: ubuntu-latest
16+
timeout-minutes: 10
17+
permissions:
18+
contents: read
19+
strategy:
20+
fail-fast: false
21+
matrix:
22+
toolchain: [stable, nightly]
23+
flags:
24+
- ""
25+
- --via-ir
26+
- --use solc:0.8.17 --via-ir
27+
- --use solc:0.8.17
28+
- --use solc:0.8.0
29+
- --use solc:0.7.6
30+
- --use solc:0.7.0
31+
- --use solc:0.6.2
32+
- --use solc:0.6.12
33+
steps:
34+
- uses: actions/checkout@v5
35+
with:
36+
persist-credentials: false
37+
- uses: foundry-rs/foundry-toolchain@v1
38+
- run: forge --version
39+
- run: |
40+
case "${{ matrix.flags }}" in
41+
*"solc:0.8.0"* | *"solc:0.7"* | *"solc:0.6"*)
42+
forge build --skip test --skip Config --skip StdConfig --skip LibVariable --deny-warnings ${{ matrix.flags }}
43+
;;
44+
*)
45+
forge build --skip test --deny-warnings ${{ matrix.flags }}
46+
;;
47+
esac
48+
# via-ir compilation time checks.
49+
- if: contains(matrix.flags, '--via-ir')
50+
run: forge build --skip test --deny-warnings ${{ matrix.flags }} --contracts 'test/compilation/*'
51+
52+
test:
53+
runs-on: ubuntu-latest
54+
timeout-minutes: 10
55+
permissions:
56+
contents: read
57+
strategy:
58+
fail-fast: false
59+
matrix:
60+
toolchain: [stable, nightly]
61+
steps:
62+
- uses: actions/checkout@v5
63+
with:
64+
persist-credentials: false
65+
- uses: foundry-rs/foundry-toolchain@v1
66+
with:
67+
version: ${{ matrix.toolchain }}
68+
- run: forge --version
69+
- run: |
70+
if [ "${{ matrix.toolchain }}" = "stable" ]; then
71+
forge test -vvv --no-match-path "test/Config.t.sol"
72+
else
73+
forge test -vvv
74+
fi
75+
76+
fmt:
77+
runs-on: ubuntu-latest
78+
timeout-minutes: 10
79+
permissions:
80+
contents: read
81+
steps:
82+
- uses: actions/checkout@v5
83+
with:
84+
persist-credentials: false
85+
- uses: foundry-rs/foundry-toolchain@v1
86+
- run: forge --version
87+
- run: forge fmt --check
88+
89+
typos:
90+
runs-on: ubuntu-latest
91+
timeout-minutes: 10
92+
permissions:
93+
contents: read
94+
steps:
95+
- uses: actions/checkout@v5
96+
with:
97+
persist-credentials: false
98+
- uses: crate-ci/typos@7436548694def3314aacd93ed06c721b1f91ea04 # v1
99+
100+
codeql:
101+
name: Analyze (${{ matrix.language }})
102+
runs-on: ubuntu-latest
103+
permissions:
104+
security-events: write
105+
actions: read
106+
contents: read
107+
strategy:
108+
fail-fast: false
109+
matrix:
110+
include:
111+
- language: actions
112+
build-mode: none
113+
steps:
114+
- name: Checkout repository
115+
uses: actions/checkout@v5
116+
with:
117+
persist-credentials: false
118+
- name: Initialize CodeQL
119+
uses: github/codeql-action/init@v3
120+
with:
121+
languages: ${{ matrix.language }}
122+
build-mode: ${{ matrix.build-mode }}
123+
- name: Perform CodeQL Analysis
124+
uses: github/codeql-action/analyze@v3
125+
with:
126+
category: "/language:${{matrix.language}}"
127+
128+
ci-success:
129+
runs-on: ubuntu-latest
130+
if: always()
131+
needs:
132+
- build
133+
- test
134+
- fmt
135+
- typos
136+
- codeql
137+
timeout-minutes: 10
138+
steps:
139+
- name: Decide whether the needed jobs succeeded or failed
140+
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1
141+
with:
142+
jobs: ${{ toJSON(needs) }}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: Sync Release Branch
2+
3+
permissions: {}
4+
5+
on:
6+
release:
7+
types:
8+
- created
9+
10+
jobs:
11+
sync-release-branch:
12+
runs-on: ubuntu-latest
13+
permissions:
14+
contents: write
15+
if: startsWith(github.event.release.tag_name, 'v1')
16+
steps:
17+
- name: Check out the repo
18+
uses: actions/checkout@v5
19+
with:
20+
persist-credentials: true
21+
fetch-depth: 0
22+
ref: v1
23+
24+
# The email is derived from the bots user id,
25+
# found here: https://api.github.com/users/github-actions%5Bbot%5D
26+
- name: Configure Git
27+
run: |
28+
git config user.name github-actions[bot]
29+
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
30+
31+
- name: Sync Release Branch
32+
run: |
33+
git fetch --tags
34+
git checkout v1
35+
git reset --hard ${GITHUB_REF}
36+
git push --force

0 commit comments

Comments
 (0)