Skip to content

Commit 41fb7c3

Browse files
committed
cli: implement ntt cli
1 parent fac72a5 commit 41fb7c3

18 files changed

+3034
-78
lines changed

Dockerfile.cli

+51
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
FROM ubuntu:latest as base
2+
3+
RUN apt update
4+
5+
RUN apt install -y python3
6+
RUN apt install -y build-essential
7+
RUN apt install -y git
8+
RUN apt install -y curl
9+
RUN apt install -y unzip
10+
11+
RUN curl -fsSL https://bun.sh/install | bash
12+
13+
RUN curl -L https://foundry.paradigm.xyz | bash
14+
RUN bash -ci "foundryup"
15+
16+
RUN apt install -y jq
17+
18+
FROM base as cli-remote
19+
# NOTE: when invoking the installer outside of the source tree, it clones the
20+
# repo and installs that way.
21+
# This build stage tests that path.
22+
COPY cli/install.sh cli/install.sh
23+
RUN bash -ci "./cli/install.sh"
24+
RUN bash -ci "which ntt"
25+
26+
FROM base as cli-local
27+
# NOTE: when invoking the installer inside of the source tree, it installs from
28+
# the local source tree.
29+
# This build stage tests that path.
30+
WORKDIR /app
31+
COPY tsconfig.json tsconfig.json
32+
COPY tsconfig.esm.json tsconfig.esm.json
33+
COPY tsconfig.cjs.json tsconfig.cjs.json
34+
COPY package.json package.json
35+
COPY package-lock.json package-lock.json
36+
COPY sdk sdk
37+
COPY solana/package.json solana/package.json
38+
COPY solana/ts solana/ts
39+
COPY evm/ts evm/ts
40+
COPY solana/tsconfig.*.json solana/
41+
COPY cli/package.json cli/package.json
42+
COPY cli/package-lock.json cli/package-lock.json
43+
COPY cli/src cli/src
44+
COPY cli/install.sh cli/install.sh
45+
RUN bash -ci "./cli/install.sh"
46+
RUN bash -ci "which ntt"
47+
48+
FROM cli-local as cli-local-test
49+
COPY cli/test cli/test
50+
COPY evm evm
51+
RUN bash -ci "./cli/test/sepolia-bsc.sh"

cli/example-overrides.json

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"chains": {
3+
"Bsc": {
4+
"rpc": "http://127.0.0.1:8545"
5+
},
6+
"Sepolia": {
7+
"rpc": "http://127.0.0.1:8546"
8+
},
9+
"Solana": {
10+
"rpc": "http://127.0.0.1:8899"
11+
}
12+
}
13+
}

cli/install.sh

+164
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
#!/usr/bin/env bash
2+
3+
set -euo pipefail
4+
5+
# check that 'bun' is installed
6+
7+
if ! command -v bun > /dev/null; then
8+
echo "bun is not installed. Follow the instructions at https://bun.sh/docs/installation"
9+
exit 1
10+
fi
11+
12+
REPO="https://github.com/wormhole-foundation/example-native-token-transfers.git"
13+
14+
function main {
15+
branch=""
16+
17+
while [[ $# -gt 0 ]]; do
18+
key="$1"
19+
20+
case $key in
21+
-b|--branch)
22+
branch="$2"
23+
shift
24+
shift
25+
;;
26+
-r|--repo)
27+
REPO="$2"
28+
shift
29+
shift
30+
;;
31+
*)
32+
echo "Unknown option $key"
33+
exit 1
34+
;;
35+
esac
36+
done
37+
38+
path=""
39+
mkdir -p "$HOME/.ntt-cli"
40+
41+
# check if there's a package.json in the parent directory, with "name": "@wormhole-foundation/ntt-cli"
42+
if [ -f "$(dirname $0)/package.json" ] && grep -q '"name": "@wormhole-foundation/ntt-cli"' "$(dirname $0)/package.json"; then
43+
path="$(dirname $0)/.."
44+
version=$(git -C "$path" rev-parse HEAD 2>/dev/null || echo "unknown")
45+
dirty=$(git -C "$path" diff --quiet 2>/dev/null || echo "-dirty")
46+
echo "$version$dirty" > "$HOME/.ntt-cli/version"
47+
else
48+
check_commit_included_in_main="false"
49+
# if branch is set, use it. otherwise use the latest tag of the form "vX.Y.Z+cli"
50+
if [ -z "$branch" ]; then
51+
branch="$(select_branch)"
52+
# if the branch was not set, we want to check that the default is included
53+
# in the main branch, i.e. it has been reviewed
54+
check_commit_included_in_main="true"
55+
else
56+
branch="origin/$branch"
57+
fi
58+
59+
# clone to $HOME/.ntt-cli if it doesn't exist, otherwise update it
60+
echo "Cloning $REPO $branch"
61+
62+
path="$HOME/.ntt-cli/.checkout"
63+
64+
if [ ! -d "$path" ]; then
65+
git clone "$REPO" "$path"
66+
fi
67+
pushd "$path"
68+
# update origin url to REPO
69+
git remote set-url origin "$REPO"
70+
git fetch origin
71+
if [ "$check_commit_included_in_main" = "true" ]; then
72+
# check that the commit is included in the main branch
73+
if ! git merge-base --is-ancestor "$branch" "origin/main"; then
74+
echo "ref '$branch' is not included in the main branch"
75+
exit 1
76+
fi
77+
fi
78+
# reset hard
79+
git reset --hard "$branch"
80+
version=$(git rev-parse HEAD)
81+
dirty=$(git diff --quiet || echo "-dirty")
82+
echo "$version$dirty" > "$HOME/.ntt-cli/version"
83+
popd
84+
fi
85+
86+
absolute_path="$(cd $path && pwd)"
87+
echo $absolute_path >> "$HOME/.ntt-cli/version"
88+
89+
# jq would be nicer but it's not portable
90+
# here we make the assumption that the file uses 2 spaces for indentation.
91+
# this is a bit fragile, but we don't want to catch further nested objects
92+
# (there might be a "version" in the scripts section, for example)
93+
version=$(cat "$path/cli/package.json" | grep '^ "version":' | cut -d '"' -f 4)
94+
echo "$version" >> "$HOME/.ntt-cli/version"
95+
96+
remote_url=$(git -C "$path" remote get-url origin 2>/dev/null || echo "unknown")
97+
echo "$remote_url" >> "$HOME/.ntt-cli/version"
98+
99+
echo "Installing ntt CLI version $version"
100+
install_cli "$path"
101+
}
102+
103+
# function that determines which branch/tag to clone
104+
function select_branch {
105+
# if the repo has a tag of the form "vX.Y.Z+cli", use that (the latest one)
106+
branch=""
107+
regex="refs/tags/v[0-9]*\.[0-9]*\.[0-9]*+cli"
108+
if git ls-remote --tags "$REPO" | grep -q "$regex"; then
109+
branch="$(git ls-remote --tags "$REPO" | grep "$regex" | sort -V | tail -n 1 | awk '{print $2}')"
110+
else
111+
# otherwise error
112+
echo "No tag of the form vX.Y.Z+cli found" >&2
113+
exit 1
114+
fi
115+
116+
echo "$branch"
117+
}
118+
119+
function install_cli {
120+
cd "$1"
121+
122+
# if 'ntt' is already installed, uninstall it
123+
# just check with 'which'
124+
if which ntt > /dev/null; then
125+
echo "Removing existing ntt CLI"
126+
rm $(which ntt)
127+
fi
128+
129+
# swallow the output of the first install
130+
# TODO: figure out why it fails the first time.
131+
bun install > /dev/null 2>&1 || true
132+
bun install
133+
134+
# make a temporary directory
135+
136+
tmpdir="$(mktemp -d)"
137+
138+
# create a temporary symlink 'npm' to 'bun'
139+
140+
ln -s "$(command -v bun)" "$tmpdir/npm"
141+
142+
# add the temporary directory to the PATH
143+
144+
export PATH="$tmpdir:$PATH"
145+
146+
# swallow the output of the first build
147+
# TODO: figure out why it fails the first time.
148+
bun --bun run --filter '*' build > /dev/null 2>&1 || true
149+
bun --bun run --filter '*' build
150+
151+
# remove the temporary directory
152+
153+
rm -r "$tmpdir"
154+
155+
# now link the CLI
156+
157+
cd cli
158+
159+
bun link
160+
161+
bun link @wormhole-foundation/ntt-cli
162+
}
163+
164+
main "$@"

cli/package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
2-
"name": "cli",
2+
"name": "@wormhole-foundation/ntt-cli",
3+
"version": "1.0.0-beta",
34
"module": "src/index.ts",
45
"type": "module",
56
"devDependencies": {
@@ -13,7 +14,7 @@
1314
"ntt": "src/index.ts"
1415
},
1516
"dependencies": {
17+
"chalk": "^5.3.0",
1618
"yargs": "^17.7.2"
17-
},
18-
"version": "0.2.0"
19-
}
19+
}
20+
}

0 commit comments

Comments
 (0)