justfile 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562
  1. alias b := build
  2. alias c := check
  3. alias t := test
  4. default:
  5. @just --list
  6. # Create a new SQL migration file
  7. new-migration target name:
  8. #!/usr/bin/env bash
  9. set -euo pipefail
  10. if [ "{{target}}" != "mint" ] && [ "{{target}}" != "wallet" ]; then
  11. echo "Error: target must be either 'mint' or 'wallet'"
  12. exit 1
  13. fi
  14. timestamp=$(date +%Y%m%d%H%M%S)
  15. migration_path="./crates/cdk-sql-common/src/{{target}}/migrations/${timestamp}_{{name}}.sql"
  16. # Create the file
  17. mkdir -p "$(dirname "$migration_path")"
  18. touch "$migration_path"
  19. echo "Created new migration: $migration_path"
  20. final-check: typos format clippy test
  21. # run `cargo build` on everything
  22. build *ARGS="--workspace --all-targets":
  23. #!/usr/bin/env bash
  24. set -euo pipefail
  25. if [ ! -f Cargo.toml ]; then
  26. cd {{invocation_directory()}}
  27. fi
  28. cargo build {{ARGS}}
  29. # run `cargo check` on everything
  30. check *ARGS="--workspace --all-targets":
  31. #!/usr/bin/env bash
  32. set -euo pipefail
  33. if [ ! -f Cargo.toml ]; then
  34. cd {{invocation_directory()}}
  35. fi
  36. cargo check {{ARGS}}
  37. # run code formatters
  38. format:
  39. #!/usr/bin/env bash
  40. set -euo pipefail
  41. if [ ! -f Cargo.toml ]; then
  42. cd {{invocation_directory()}}
  43. fi
  44. cargo fmt --all
  45. nixpkgs-fmt $(echo **.nix)
  46. # run doc tests
  47. test:
  48. #!/usr/bin/env bash
  49. set -euo pipefail
  50. if [ ! -f Cargo.toml ]; then
  51. cd {{invocation_directory()}}
  52. fi
  53. cargo test --lib
  54. # Run pure integration tests
  55. cargo test -p cdk-integration-tests --test mint
  56. # run doc tests
  57. test-pure db="memory":
  58. #!/usr/bin/env bash
  59. set -euo pipefail
  60. if [ ! -f Cargo.toml ]; then
  61. cd {{invocation_directory()}}
  62. fi
  63. # Run pure integration tests (cargo test will only build what's needed for the test)
  64. CDK_TEST_DB_TYPE={{db}} cargo test -p cdk-integration-tests --test integration_tests_pure -- --test-threads 1
  65. # Run swap flow tests (detailed testing of swap operation)
  66. CDK_TEST_DB_TYPE={{db}} cargo test -p cdk-integration-tests --test test_swap_flow -- --test-threads 1
  67. test-all db="memory":
  68. #!/usr/bin/env bash
  69. set -euo pipefail
  70. just test {{db}}
  71. ./misc/itests.sh "{{db}}"
  72. ./misc/fake_itests.sh "{{db}}" external_signatory
  73. ./misc/fake_itests.sh "{{db}}"
  74. test-nutshell:
  75. #!/usr/bin/env bash
  76. set -euo pipefail
  77. # Function to cleanup docker containers
  78. cleanup() {
  79. echo "Cleaning up docker containers..."
  80. docker stop nutshell 2>/dev/null || true
  81. docker rm nutshell 2>/dev/null || true
  82. unset CDK_ITESTS_DIR
  83. }
  84. # Trap to ensure cleanup happens on exit (success or failure)
  85. trap cleanup EXIT
  86. docker run -d -p 3338:3338 --name nutshell -e MINT_LIGHTNING_BACKEND=FakeWallet -e MINT_LISTEN_HOST=0.0.0.0 -e MINT_LISTEN_PORT=3338 -e MINT_PRIVATE_KEY=TEST_PRIVATE_KEY -e MINT_INPUT_FEE_PPK=100 cashubtc/nutshell:latest poetry run mint
  87. export CDK_ITESTS_DIR=$(mktemp -d)
  88. # Wait for the Nutshell service to be ready
  89. echo "Waiting for Nutshell to start..."
  90. max_attempts=30
  91. attempt=0
  92. while ! curl -s http://127.0.0.1:3338/v1/info > /dev/null; do
  93. attempt=$((attempt+1))
  94. if [ $attempt -ge $max_attempts ]; then
  95. echo "Nutshell failed to start after $max_attempts attempts"
  96. exit 1
  97. fi
  98. echo "Waiting for Nutshell to start (attempt $attempt/$max_attempts)..."
  99. sleep 1
  100. done
  101. echo "Nutshell is ready!"
  102. # Set environment variables and run tests
  103. export CDK_TEST_MINT_URL=http://127.0.0.1:3338
  104. export LN_BACKEND=FAKEWALLET
  105. # Track test results
  106. test_exit_code=0
  107. # Run first test and capture exit code
  108. echo "Running happy_path_mint_wallet test..."
  109. if ! cargo test -p cdk-integration-tests --test happy_path_mint_wallet; then
  110. echo "ERROR: happy_path_mint_wallet test failed"
  111. test_exit_code=1
  112. fi
  113. # Run second test and capture exit code
  114. echo "Running test_fees test..."
  115. if ! cargo test -p cdk-integration-tests --test test_fees; then
  116. echo "ERROR: test_fees test failed"
  117. test_exit_code=1
  118. fi
  119. unset CDK_TEST_MINT_URL
  120. unset LN_BACKEND
  121. # Exit with error code if any test failed
  122. if [ $test_exit_code -ne 0 ]; then
  123. echo "One or more tests failed"
  124. exit $test_exit_code
  125. fi
  126. echo "All tests passed successfully"
  127. # run `cargo clippy` on everything
  128. clippy *ARGS="--locked --offline --workspace --all-targets":
  129. cargo clippy {{ARGS}}
  130. # run `cargo clippy --fix` on everything
  131. clippy-fix *ARGS="--locked --offline --workspace --all-targets":
  132. cargo clippy {{ARGS}} --fix
  133. typos:
  134. typos
  135. # fix all typos
  136. [no-exit-message]
  137. typos-fix:
  138. just typos -w
  139. # Goose AI Recipe Commands
  140. # Update changelog from staged changes using Goose AI
  141. goose-git-msg:
  142. #!/usr/bin/env bash
  143. set -euo pipefail
  144. goose run --recipe ./misc/recipes/git-commit-message.yaml --interactive
  145. # Create git message from staged changes using Goose AI
  146. goose-changelog-staged:
  147. #!/usr/bin/env bash
  148. set -euo pipefail
  149. goose run --recipe ./misc/recipes/changelog-update.yaml --interactive
  150. # Update changelog from recent commits using Goose AI
  151. # Usage: just goose-changelog-commits [number_of_commits]
  152. goose-changelog-commits *COMMITS="5":
  153. #!/usr/bin/env bash
  154. set -euo pipefail
  155. COMMITS={{COMMITS}} goose run --recipe ./misc/recipes/changelog-from-commits.yaml --interactive
  156. itest db:
  157. #!/usr/bin/env bash
  158. set -euo pipefail
  159. ./misc/itests.sh "{{db}}"
  160. fake-mint-itest db:
  161. #!/usr/bin/env bash
  162. set -euo pipefail
  163. ./misc/fake_itests.sh "{{db}}" external_signatory
  164. ./misc/fake_itests.sh "{{db}}"
  165. itest-payment-processor ln:
  166. #!/usr/bin/env bash
  167. set -euo pipefail
  168. ./misc/mintd_payment_processor.sh "{{ln}}"
  169. fake-auth-mint-itest db openid_discovery:
  170. #!/usr/bin/env bash
  171. set -euo pipefail
  172. ./misc/fake_auth_itests.sh "{{db}}" "{{openid_discovery}}"
  173. nutshell-wallet-itest:
  174. #!/usr/bin/env bash
  175. set -euo pipefail
  176. ./misc/nutshell_wallet_itest.sh
  177. # Start interactive regtest environment (Bitcoin + 4 LN nodes + 2 CDK mints)
  178. regtest db="sqlite":
  179. #!/usr/bin/env bash
  180. set -euo pipefail
  181. ./misc/interactive_regtest_mprocs.sh {{db}}
  182. # Lightning Network Commands (require regtest environment to be running)
  183. # Get CLN node 1 info
  184. ln-cln1 *ARGS:
  185. #!/usr/bin/env bash
  186. set -euo pipefail
  187. ./misc/regtest_helper.sh ln-cln1 {{ARGS}}
  188. # Get CLN node 2 info
  189. ln-cln2 *ARGS:
  190. #!/usr/bin/env bash
  191. set -euo pipefail
  192. ./misc/regtest_helper.sh ln-cln2 {{ARGS}}
  193. # Get LND node 1 info
  194. ln-lnd1 *ARGS:
  195. #!/usr/bin/env bash
  196. set -euo pipefail
  197. ./misc/regtest_helper.sh ln-lnd1 {{ARGS}}
  198. # Get LND node 2 info
  199. ln-lnd2 *ARGS:
  200. #!/usr/bin/env bash
  201. set -euo pipefail
  202. ./misc/regtest_helper.sh ln-lnd2 {{ARGS}}
  203. # Bitcoin regtest commands
  204. btc *ARGS:
  205. #!/usr/bin/env bash
  206. set -euo pipefail
  207. ./misc/regtest_helper.sh btc {{ARGS}}
  208. # Mine blocks in regtest
  209. btc-mine blocks="10":
  210. #!/usr/bin/env bash
  211. set -euo pipefail
  212. ./misc/regtest_helper.sh btc-mine {{blocks}}
  213. # Show mint information
  214. mint-info:
  215. #!/usr/bin/env bash
  216. set -euo pipefail
  217. ./misc/regtest_helper.sh mint-info
  218. # Run integration tests against regtest environment
  219. mint-test:
  220. #!/usr/bin/env bash
  221. set -euo pipefail
  222. ./misc/regtest_helper.sh mint-test
  223. # Restart mints after recompiling (useful for development)
  224. restart-mints:
  225. #!/usr/bin/env bash
  226. set -euo pipefail
  227. ./misc/regtest_helper.sh restart-mints
  228. # Show regtest environment status
  229. regtest-status:
  230. #!/usr/bin/env bash
  231. set -euo pipefail
  232. ./misc/regtest_helper.sh show-status
  233. # Show regtest environment logs
  234. regtest-logs:
  235. #!/usr/bin/env bash
  236. set -euo pipefail
  237. ./misc/regtest_helper.sh show-logs
  238. run-examples:
  239. cargo r --example p2pk
  240. cargo r --example mint-token
  241. cargo r --example melt-token
  242. cargo r --example proof_selection
  243. cargo r --example wallet
  244. check-wasm *ARGS="--target wasm32-unknown-unknown":
  245. #!/usr/bin/env bash
  246. set -euo pipefail
  247. if [ ! -f Cargo.toml ]; then
  248. cd {{invocation_directory()}}
  249. fi
  250. buildargs=(
  251. "-p cdk"
  252. "-p cdk --no-default-features"
  253. "-p cdk --no-default-features --features wallet"
  254. "-p cdk --no-default-features --features mint"
  255. )
  256. for arg in "${buildargs[@]}"; do
  257. echo "Checking '$arg'"
  258. cargo check $arg {{ARGS}}
  259. echo
  260. done
  261. release m="":
  262. #!/usr/bin/env bash
  263. set -euo pipefail
  264. args=(
  265. "-p cashu"
  266. "-p cdk-prometheus"
  267. "-p cdk-common"
  268. "-p cdk-sql-common"
  269. "-p cdk-sqlite"
  270. "-p cdk-postgres"
  271. "-p cdk-redb"
  272. "-p cdk-signatory"
  273. "-p cdk"
  274. "-p cdk-ffi"
  275. "-p cdk-axum"
  276. "-p cdk-mint-rpc"
  277. "-p cdk-cln"
  278. "-p cdk-lnd"
  279. "-p cdk-lnbits"
  280. "-p cdk-ldk-node"
  281. "-p cdk-fake-wallet"
  282. "-p cdk-payment-processor"
  283. "-p cdk-cli"
  284. "-p cdk-mintd"
  285. )
  286. for arg in "${args[@]}";
  287. do
  288. echo "Publishing '$arg'"
  289. cargo publish $arg {{m}}
  290. echo
  291. done
  292. # Extract version from the cdk-ffi crate
  293. VERSION=$(cargo metadata --format-version 1 --no-deps | jq -r '.packages[] | select(.name == "cdk-ffi") | .version')
  294. # Trigger Swift package release after Rust crates are published
  295. echo "📦 Triggering Swift package release for version $VERSION..."
  296. just ffi-release-swift $VERSION
  297. check-docs:
  298. #!/usr/bin/env bash
  299. set -euo pipefail
  300. args=(
  301. "-p cashu"
  302. "-p cdk-common"
  303. "-p cdk-sql-common"
  304. "-p cdk"
  305. "-p cdk-redb"
  306. "-p cdk-sqlite"
  307. "-p cdk-axum"
  308. "-p cdk-cln"
  309. "-p cdk-lnd"
  310. "-p cdk-lnbits"
  311. "-p cdk-fake-wallet"
  312. "-p cdk-mint-rpc"
  313. "-p cdk-payment-processor"
  314. "-p cdk-signatory"
  315. "-p cdk-cli"
  316. "-p cdk-mintd"
  317. )
  318. for arg in "${args[@]}"; do
  319. echo "Checking '$arg' docs"
  320. cargo doc $arg --all-features
  321. echo
  322. done
  323. # Build docs for all crates and error on warnings
  324. docs-strict:
  325. #!/usr/bin/env bash
  326. set -euo pipefail
  327. args=(
  328. "-p cashu"
  329. "-p cdk-common"
  330. "-p cdk-sql-common"
  331. "-p cdk"
  332. "-p cdk-redb"
  333. "-p cdk-sqlite"
  334. "-p cdk-axum"
  335. "-p cdk-cln"
  336. "-p cdk-lnd"
  337. "-p cdk-lnbits"
  338. "-p cdk-fake-wallet"
  339. "-p cdk-mint-rpc"
  340. "-p cdk-payment-processor"
  341. "-p cdk-signatory"
  342. "-p cdk-cli"
  343. "-p cdk-mintd"
  344. )
  345. for arg in "${args[@]}"; do
  346. echo "Building docs for $arg with strict warnings"
  347. RUSTDOCFLAGS="-D warnings" cargo doc $arg --all-features --no-deps
  348. echo
  349. done
  350. # =============================================================================
  351. # FFI Commands - CDK Foreign Function Interface bindings
  352. # =============================================================================
  353. # Helper function to get library extension based on platform
  354. _ffi-lib-ext:
  355. #!/usr/bin/env bash
  356. if [[ "$OSTYPE" == "darwin"* ]]; then
  357. echo "dylib"
  358. else
  359. echo "so"
  360. fi
  361. # Build the FFI library
  362. ffi-build *ARGS="--release":
  363. cargo build {{ARGS}} --package cdk-ffi --features postgres
  364. # Generate bindings for a specific language
  365. ffi-generate LANGUAGE *ARGS="--release": ffi-build
  366. #!/usr/bin/env bash
  367. set -euo pipefail
  368. LANG="{{LANGUAGE}}"
  369. # Validate language
  370. case "$LANG" in
  371. python|swift|kotlin)
  372. ;;
  373. *)
  374. echo "❌ Unsupported language: $LANG"
  375. echo "Supported languages: python, swift, kotlin"
  376. exit 1
  377. ;;
  378. esac
  379. # Set emoji and build type
  380. case "$LANG" in
  381. python) EMOJI="🐍" ;;
  382. swift) EMOJI="🍎" ;;
  383. kotlin) EMOJI="🎯" ;;
  384. esac
  385. # Determine build type and library path
  386. if [[ "{{ARGS}}" == *"--release"* ]] || [[ "{{ARGS}}" == "" ]]; then
  387. BUILD_TYPE="release"
  388. else
  389. BUILD_TYPE="debug"
  390. cargo build --package cdk-ffi --features postgres
  391. fi
  392. LIB_EXT=$(just _ffi-lib-ext)
  393. echo "$EMOJI Generating $LANG bindings..."
  394. mkdir -p target/bindings/$LANG
  395. cargo run --bin uniffi-bindgen generate \
  396. --library target/$BUILD_TYPE/libcdk_ffi.$LIB_EXT \
  397. --language $LANG \
  398. --out-dir target/bindings/$LANG
  399. echo "✅ $LANG bindings generated in target/bindings/$LANG/"
  400. # Generate Python bindings (shorthand)
  401. ffi-generate-python *ARGS="--release":
  402. just ffi-generate python {{ARGS}}
  403. # Generate Swift bindings (shorthand)
  404. ffi-generate-swift *ARGS="--release":
  405. just ffi-generate swift {{ARGS}}
  406. # Generate Kotlin bindings (shorthand)
  407. ffi-generate-kotlin *ARGS="--release":
  408. just ffi-generate kotlin {{ARGS}}
  409. # Generate bindings for all supported languages
  410. ffi-generate-all *ARGS="--release": ffi-build
  411. @echo "🔧 Generating UniFFI bindings for all languages..."
  412. just ffi-generate python {{ARGS}}
  413. just ffi-generate swift {{ARGS}}
  414. just ffi-generate kotlin {{ARGS}}
  415. @echo "✅ All bindings generated successfully!"
  416. # Build debug version and generate Python bindings quickly (for development)
  417. ffi-dev-python:
  418. #!/usr/bin/env bash
  419. set -euo pipefail
  420. # Generate Python bindings first
  421. just ffi-generate python --debug
  422. # Copy library to Python bindings directory
  423. LIB_EXT=$(just _ffi-lib-ext)
  424. echo "📦 Copying library to Python bindings directory..."
  425. cp target/debug/libcdk_ffi.$LIB_EXT target/bindings/python/
  426. # Launch Python REPL with CDK FFI loaded
  427. cd target/bindings/python
  428. echo "🐍 Launching Python REPL with CDK FFI library loaded..."
  429. echo "💡 The 'cdk_ffi' module is pre-imported and ready to use!"
  430. python3 -i -c "from cdk_ffi import *; print('✅ CDK FFI library loaded successfully!');"
  431. # Test language bindings with a simple import
  432. ffi-test-bindings LANGUAGE: (ffi-generate LANGUAGE "--debug")
  433. #!/usr/bin/env bash
  434. set -euo pipefail
  435. LANG="{{LANGUAGE}}"
  436. LIB_EXT=$(just _ffi-lib-ext)
  437. echo "📦 Copying library to $LANG bindings directory..."
  438. cp target/debug/libcdk_ffi.$LIB_EXT target/bindings/$LANG/
  439. cd target/bindings/$LANG
  440. echo "🧪 Testing $LANG bindings..."
  441. case "$LANG" in
  442. python)
  443. python3 -c "import cdk_ffi; print('✅ Python bindings work!')"
  444. ;;
  445. *)
  446. echo "✅ $LANG bindings generated (manual testing required)"
  447. ;;
  448. esac
  449. # Test Python bindings (shorthand)
  450. ffi-test-python:
  451. just ffi-test-bindings python
  452. # Trigger Swift Package release workflow
  453. ffi-release-swift VERSION:
  454. #!/usr/bin/env bash
  455. set -euo pipefail
  456. echo "🚀 Triggering Publish Swift Package workflow..."
  457. echo " Version: {{VERSION}}"
  458. echo " CDK Ref: v{{VERSION}}"
  459. # Trigger the workflow using GitHub CLI
  460. gh workflow run "Publish Swift Package" \
  461. --repo cashubtc/cdk-swift \
  462. --field version="{{VERSION}}" \
  463. --field cdk_repo="cashubtc/cdk" \
  464. --field cdk_ref="v{{VERSION}}"
  465. echo "✅ Workflow triggered successfully!"