Skip to content

Commit b0ca170

Browse files
committed
init without binary
0 parents  commit b0ca170

27 files changed

Lines changed: 3954 additions & 0 deletions
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
name: Release On version tags
2+
3+
on:
4+
push:
5+
tags:
6+
- "v[0-9]+.[0-9]+.[0-9]*"
7+
8+
jobs:
9+
create_release:
10+
runs-on: ubuntu-latest
11+
permissions:
12+
contents: write
13+
steps:
14+
- uses: actions/checkout@v3
15+
- uses: ncipollo/release-action@v1
16+
17+
release:
18+
needs: create_release
19+
name: release ${{ matrix.target }}
20+
permissions: write-all
21+
runs-on: ubuntu-latest
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
include:
26+
- target: x86_64-pc-windows-gnu
27+
- target: x86_64-unknown-linux-musl
28+
- target: x86_64-apple-darwin
29+
steps:
30+
- uses: actions/checkout@master
31+
- name: Compile and release
32+
uses: rust-build/rust-build.action@v1.3.2
33+
env:
34+
SRC_DIR: forge-exec-ipc-client
35+
UPLOAD_MODE: none
36+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
37+
with:
38+
RUSTTARGET: ${{ matrix.target }}
39+
ARCHIVE_TYPES: ${{ matrix.archive }}
40+
TOOLCHAIN_VERSION: 1.64.0
41+
- name: tar
42+
working-directory: ./forge-exec-ipc-client
43+
run: |
44+
export PARENT_FOLDER=../output
45+
export FILE_NAME=forge-exec-ipc-client${{ matrix.target == 'x86_64-pc-windows-gnu' && '.exe' || '' }}
46+
export FOLDER_NAME=forge-exec-ipc-client_${{ github.ref_name }}_${{ matrix.target }}
47+
echo $FOLDER_NAME/$FILE_NAME
48+
mkdir -p archive_folder/$FOLDER_NAME
49+
cp $PARENT_FOLDER/$FILE_NAME archive_folder/$FOLDER_NAME/
50+
tar --directory=archive_folder -cf archive.tar.gz $FOLDER_NAME
51+
- name: upload
52+
working-directory: ./forge-exec-ipc-client
53+
run: |
54+
id=$(gh api -H "Accept: application/vnd.github+json" /repos/wighawag/forge-exec/releases/tags/${{ github.ref_name }} --jq .id)
55+
curl --fail-with-body -sS -X POST --data-binary @"archive.tar.gz" -H 'Content-Type: application/octet-stream' -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "https://uploads.github.com/repos/wighawag/forge-exec/releases/$id/assets?name=forge-exec-ipc-client_${{ github.ref_name }}_${{ matrix.target }}.tar.gz"
56+
env:
57+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58+
windows-msvc-release:
59+
needs: create_release
60+
name: release windows msvc
61+
permissions: write-all
62+
runs-on: windows-latest
63+
steps:
64+
- uses: actions/checkout@master
65+
- name: Build
66+
working-directory: ./forge-exec-ipc-client
67+
run: |
68+
cargo build --release
69+
- name: tar
70+
working-directory: ./forge-exec-ipc-client
71+
run: |
72+
mkdir archive_folder
73+
mkdir archive_folder/forge-exec-ipc-client_${{ github.ref_name }}_x86_64-pc-windows-msvc
74+
cp target/release/forge-exec-ipc-client.exe archive_folder/forge-exec-ipc-client_${{ github.ref_name }}_x86_64-pc-windows-msvc/
75+
tar --directory=archive_folder -cf archive.tar.gz forge-exec-ipc-client_${{ github.ref_name }}_x86_64-pc-windows-msvc
76+
- name: upload
77+
working-directory: ./forge-exec-ipc-client
78+
run: |
79+
$id = gh api -H "Accept: application/vnd.github+json" /repos/wighawag/forge-exec/releases/tags/${{ github.ref_name }} --jq .id
80+
curl --fail-with-body -sS -X POST --data-binary "@archive.tar.gz" -H 'Content-Type: application/octet-stream' -H 'Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}' "https://uploads.github.com/repos/wighawag/forge-exec/releases/$id/assets?name=forge-exec-ipc-client_${{ github.ref_name }}_x86_64-pc-windows-msvc.tar.gz"
81+
env:
82+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
83+
macos-arm-release:
84+
needs: create_release
85+
name: release mac os arm release
86+
permissions: write-all
87+
runs-on: macos-12
88+
steps:
89+
- uses: actions/checkout@master
90+
- name: check toolchain
91+
run: rustup default
92+
- name: Build
93+
working-directory: ./forge-exec-ipc-client
94+
run: |
95+
rustup toolchain install stable-aarch64-apple-darwin
96+
rustup target add aarch64-apple-darwin
97+
cargo build --release --target aarch64-apple-darwin
98+
- name: tar
99+
working-directory: ./forge-exec-ipc-client
100+
run: |
101+
export PARENT_FOLDER=target/aarch64-apple-darwin/release
102+
export FILE_NAME=forge-exec-ipc-client
103+
export FOLDER_NAME=forge-exec-ipc-client_${{ github.ref_name }}_aarch64-apple-darwin
104+
echo $FOLDER_NAME/$FILE_NAME
105+
mkdir -p archive_folder/$FOLDER_NAME
106+
cp $PARENT_FOLDER/$FILE_NAME archive_folder/$FOLDER_NAME/
107+
tar --directory=archive_folder -cf archive.tar.gz $FOLDER_NAME
108+
- name: upload
109+
working-directory: ./forge-exec-ipc-client
110+
run: |
111+
id=$(gh api -H "Accept: application/vnd.github+json" /repos/wighawag/forge-exec/releases/tags/${{ github.ref_name }} --jq .id)
112+
curl --fail-with-body -sS -X POST --data-binary @"archive.tar.gz" -H 'Content-Type: application/octet-stream' -H "Authorization: Bearer ${{ secrets.GITHUB_TOKEN }}" "https://uploads.github.com/repos/wighawag/forge-exec/releases/$id/assets?name=forge-exec-ipc-client_${{ github.ref_name }}_aarch64-apple-darwin.tar.gz"
113+
env:
114+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
115+
116+
npm_publish:
117+
name: publish to npm
118+
needs: [release, windows-msvc-release, macos-arm-release]
119+
runs-on: ubuntu-latest
120+
steps:
121+
- uses: actions/checkout@v3
122+
- uses: actions/setup-node@v3
123+
with:
124+
node-version: 18
125+
- name: download the binaries from the release
126+
run: |
127+
curl -L -O https://uploads.github.com/repos/wighawag/forge-exec/releases/$id/assets?name=forge-exec-ipc-client_${{ github.ref_name }}_aarch64-apple-darwin.tar.gz
128+
curl -L -O https://uploads.github.com/repos/wighawag/forge-exec/releases/$id/assets?name=forge-exec-ipc-client_${{ github.ref_name }}_x86_64-apple-darwin.tar.gz
129+
curl -L -O https://uploads.github.com/repos/wighawag/forge-exec/releases/$id/assets?name=forge-exec-ipc-client_${{ github.ref_name }}_x86_64-pc-windows-gnu.tar.gz
130+
curl -L -O https://uploads.github.com/repos/wighawag/forge-exec/releases/$id/assets?name=forge-exec-ipc-client_${{ github.ref_name }}_x86_64-pc-windows-msvc.tar.gz
131+
curl -L -O https://uploads.github.com/repos/wighawag/forge-exec/releases/$id/assets?name=forge-exec-ipc-client_${{ github.ref_name }}_x86_64-unknown-linux-musl.tar.gz
132+
- name: extract them in the bin folder
133+
run: |
134+
TARGET=aarch64-apple-darwin mkdir bin/$TARGET; tar -xf forge-exec-ipc-client_${{ github.ref_name }}_$TARGET.tar.gz --strip=1 -C bin/$TARGET
135+
TARGET=x86_64-apple-darwin mkdir bin/$TARGET; tar -xf forge-exec-ipc-client_${{ github.ref_name }}_$TARGET.tar.gz --strip=1 -C bin/$TARGET
136+
TARGET=x86_64-pc-windows-gnu mkdir bin/$TARGET; tar -xf forge-exec-ipc-client_${{ github.ref_name }}_$TARGET.tar.gz --strip=1 -C bin/$TARGET
137+
TARGET=x86_64-pc-windows-msvc mkdir bin/$TARGET; tar -xf forge-exec-ipc-client_${{ github.ref_name }}_$TARGET.tar.gz --strip=1 -C bin/$TARGET
138+
TARGET=x86_64-unknown-linux-musl mkdir bin/$TARGET; tar -xf forge-exec-ipc-client_${{ github.ref_name }}_$TARGET.tar.gz --strip=1 -C bin/$TARGET
139+
- name: prepare package.json
140+
run: V_REF=${{ github.ref_name }};VERSION=${V_REF:1};sed -i "s/__VERSION__/$VERSION/" package.json
141+
- name: tree
142+
run: |
143+
sudo apt-get install -y tree
144+
tree
145+
# - uses: JS-DevTools/npm-publish@v2
146+
# with:
147+
# token: ${{ secrets.NPM_AUTH_TOKEN }}
148+
149+
150+
151+

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
cache/
2+
out/
3+
node_modules/
4+
lib/

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2023 wighawag
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
# <h1 align="center"> forge-exec </h1>
2+
3+
**Execute programs from forge with am open 2-way communication channel between both**
4+
5+
## Installation
6+
7+
Install `forge-exec` as git submodules in your foundry project.
8+
9+
```bash
10+
forge install wighawag/forge-exec
11+
```
12+
13+
Install `forge-exec-ipc-client` on your machine, see [release files](https://github.com/wighawag/forge-exec/releases/tag/forge-exec-ipc-client-v0.0.2)
14+
15+
This need to be in your `PATH`
16+
17+
You can also easily instal from source, see folder: [forge-exec-ipc-client](./forge-exec-ipc-client/)
18+
19+
```bash
20+
cargo install forge-exec-ipc-client
21+
```
22+
23+
This command line tool allows `forge-exec` to maintain a 2-way commincation channel with the program being executed.
24+
25+
Tnis means the program is able to send request to forge (create, call, send, ...) and get responses and this until the program wish to stop.
26+
27+
## Usage
28+
29+
1. Add this import to your script or test:
30+
31+
```solidity
32+
import {Exec} from "forge-exec/Exec.sol";
33+
```
34+
35+
1. Execute an external program:
36+
37+
```solidity
38+
string[] memory args = new string[](1);
39+
args[0] = "./example.js";
40+
bytes memory result = Exec.execute("node", args, false); // the third parameter (false) tell whether to broadcast any tx or not
41+
```
42+
43+
1. You must enable [ffi](https://book.getfoundry.sh/cheatcodes/ffi.html) in order to use the library. You can either pass the `--ffi` flag to any forge commands you run (e.g. `forge script Script --ffi`), or you can add `ffi = true` to your `foundry.toml` file.
44+
45+
> Note The program executed need to create an IPC server to communicate back with forge, see how it works in [forge-exec-ipc-client's README.md](./forge-exec-ipc-client/README.md).
46+
>
47+
> You can use the npm package `forge-exec-ipc-server` for that. See [repo](https://github.com/wighawag/forge-exec-ipc-server-js)
48+
49+
## Javascript Setup
50+
51+
Setup your js project with npm
52+
53+
```
54+
npm init
55+
```
56+
57+
Then install `forge-exec-ipc-server` package which will let the script to communicate back with forge
58+
59+
```
60+
npm i -D forge-exec-ipc-server
61+
```
62+
63+
Now you can write your js script this way
64+
65+
```js
66+
import { execute } from "forge-exec-ipc-server";
67+
68+
execute(async (forge) => {
69+
const address = await forge.create({
70+
from: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266",
71+
data: "0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220f0cfb2159c518c3da0ad864362bad5dc0715514a9ab679237253d506773a0a1b64736f6c63430008130033",
72+
});
73+
console.log({ address: address });
74+
});
75+
```
76+
77+
for now, only create, send, call and balance are implemented
78+
79+
### Example
80+
81+
We have example usage for both [tests](./demo-js/test/Exec.t.sol) and [scripts](./demo-js/script/ExecDemo.s.sol). See [example.js](./demo-js/example.js) in the [demo-js folder](./demo-js/)
82+
83+
## Rust
84+
85+
`forge-exec` is agnostic to what program you execute, you just need to follow the ipc communication protocol. you can find a very basic rust example in the [demo-rust folder](./demo-rust/)
86+
87+
## Why?
88+
89+
[Forge scripting](https://book.getfoundry.sh/tutorials/solidity-scripting.html) allow you to perform deployment task in solidity. With forge-exec you can run external program to deploy contracts and more.
90+
91+
## Development
92+
93+
This project uses [Foundry](https://getfoundry.sh). See the [book](https://book.getfoundry.sh/getting-started/installation.html) for instructions on how to install and use Foundry.
94+
95+
96+
## Quick Start
97+
98+
```
99+
mkdir my-forge-exec-project;
100+
cd my-forge-exec-project;
101+
forge init;
102+
103+
forge install wighawag/forge-exec;
104+
105+
cat >> .gitignore <<EOF
106+
107+
node_modules/
108+
.ipc.log
109+
EOF
110+
cat > package.json <<EOF
111+
{
112+
"name": "my-forge-exec-project",
113+
"private": true,
114+
"type": "module",
115+
"devDependencies": {
116+
"forge-exec-ipc-server": "0.0.1"
117+
},
118+
"scripts": {
119+
"execute": "forge script --ffi script/Counter.s.sol -vvvvv"
120+
}
121+
}
122+
EOF
123+
124+
cat >> remappings.txt <<EOF
125+
forge-exec/=lib/forge-exec/src/
126+
EOF
127+
128+
pnpm i
129+
130+
cat > script/example.js <<EOF
131+
// @ts-check
132+
import { execute } from "forge-exec-ipc-server";
133+
execute(async (forge) => {
134+
const results = await Promise.all([
135+
forge.create({
136+
from: "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266",
137+
data: "0x608060405234801561001057600080fd5b5060f78061001f6000396000f3fe6080604052348015600f57600080fd5b5060043610603c5760003560e01c80633fb5c1cb1460415780638381f58a146053578063d09de08a14606d575b600080fd5b6051604c3660046083565b600055565b005b605b60005481565b60405190815260200160405180910390f35b6051600080549080607c83609b565b9190505550565b600060208284031215609457600080fd5b5035919050565b60006001820160ba57634e487b7160e01b600052601160045260246000fd5b506001019056fea2646970667358221220f0cfb2159c518c3da0ad864362bad5dc0715514a9ab679237253d506773a0a1b64736f6c63430008130033",
138+
}),
139+
]);
140+
141+
const tx = await forge.send({
142+
to: "0x0000000000000000000000000000000000000001",
143+
value: 1n,
144+
});
145+
console.log({ tx: tx });
146+
return {
147+
types: results.map(() => ({
148+
type: "address",
149+
})),
150+
values: results,
151+
};
152+
});
153+
EOF
154+
cat > script/Counter.s.sol <<EOF
155+
// SPDX-License-Identifier: UNLICENSED
156+
pragma solidity ^0.8.13;
157+
158+
import {Script, console} from "forge-std/Script.sol";
159+
import {Exec} from "forge-exec/Exec.sol";
160+
161+
contract CounterScript is Script {
162+
function setUp() public {}
163+
164+
function run() public {
165+
string[] memory args = new string[](1);
166+
args[0] = "./script/example.js";
167+
Exec.execute("node", args, true);
168+
}
169+
}
170+
EOF
171+
172+
# we ensure forge-exec-ipc-client is in the path
173+
# you can install it as mentioned in the README
174+
PATH=lib/forge-exec/forge-exec-ipc-client/bin:$PATH pnpm execute;
175+
```

demo-rust/.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/target
2+
cache/
3+
out/
4+
.executor*
5+
.ipc*
6+
broadcast/*/31337/
7+
.rust-executor*
8+
forge-exec-ipc-client
9+
.rust-ipc-server*

0 commit comments

Comments
 (0)