From 1516fc7c0c13b09c08881e7c621f587a1b35b5d8 Mon Sep 17 00:00:00 2001 From: Csongor Kiss Date: Sun, 25 Feb 2024 18:10:57 -0500 Subject: [PATCH 1/2] cli: initial prototype with bun --- cli/.gitignore | 175 +++++++++++++++++++++++++++++ cli/README.md | 19 ++++ cli/bun.lockb | Bin 0 -> 9719 bytes cli/package-lock.json | 250 ++++++++++++++++++++++++++++++++++++++++++ cli/package.json | 18 +++ cli/src/index.ts | 101 +++++++++++++++++ cli/tsconfig.json | 27 +++++ solana/package.json | 1 + 8 files changed, 591 insertions(+) create mode 100644 cli/.gitignore create mode 100644 cli/README.md create mode 100755 cli/bun.lockb create mode 100644 cli/package-lock.json create mode 100644 cli/package.json create mode 100755 cli/src/index.ts create mode 100644 cli/tsconfig.json diff --git a/cli/.gitignore b/cli/.gitignore new file mode 100644 index 000000000..9b1ee42e8 --- /dev/null +++ b/cli/.gitignore @@ -0,0 +1,175 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/cli/README.md b/cli/README.md new file mode 100644 index 000000000..cfec958ce --- /dev/null +++ b/cli/README.md @@ -0,0 +1,19 @@ +# NTT cli + +To install dependencies: + +```bash +bun install --frozen-lockfile +``` + +To install `ntt` binary: + +``` bash +bun link cli +``` + +To run: + +```bash +ntt --help +``` diff --git a/cli/bun.lockb b/cli/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..b75a8a08398b2817884635e4fdf8f167818bb6ea GIT binary patch literal 9719 zcmeHNd010d7EfqUmI{K3LcszdbNCc5WurD4h%raEzuLX(q2XtaEx?p{fX!pIH4z_b@ z5B14*RJsiOQW(D8b9~Kt?=GA3A1EpBJFaKSIyoO7>$dpm{6s+zT6$v*%Wb zGhIW{`yKKdY%KFF`E~NfV;K!~`CiJV7C+JD$OTL1_8sw<`S{)m#i>^kW?`(uh+B3J zwS7(*I~)mNZmt^nJUe!`jCWAd6p_^!88Yp*@2L@YZ%;laerOlASG?=m#cn68UP{iq z8b2#(cCY@ag32xYNz<-2_Dzv>ojJkv^j7P#Gu^}E`uYW!ntNZFk$-vg)9icT&i^Ta z`{?8XpT6K1a2EqyOh0sijt_#5hI*d>9{Pk%Y_-%S2>vis90m9uY5>}xPa^nMsO$-N z;*ZYyfT0e-`vMT{CwSWq;#UCB1MoP5(1$oL^hrejNx=I6zB_b8Lgr9O$^N5U6(z+?ZR@5p;y9Hibp_=5Ve|DY-KqYI1W1pgSmxT)>O_hco)@9iam zcYpyC0C*Nu#&;bZKdS(M;~$m>I$<01Nko688c+P*QG8c0d^+gY*KT4P(H{kPf57YO zx3}@z06zxs$oJp$UlZU*s`1E8{6O@yC5inW0Pt3~AN7;>ZQ;m!QcnVSzE=A?>i;~z zp09onI9!n&kBO5}j%&oZC_cu4yHXh*Ag zD>m#MCniJ1`>v@8FB!LJHmlg|nBdaA=-MMi=We{7n8>pp*~@`hzQ(3t`iaF)#`N!@ zbog*v__~p+d(PT9uH-|n(*@J|)F)*xTE0fKI^e-zxa4SG0flJXv|C21j4oR$sl?TeZ`!_q}d1Tz({q4=buu`Yo%Fn*HZF2+?AEy*S9TN#Pt89Qv22fZ>) z{UCVk-qwfgP0vfr761|9g*%fbu}hnL25z2P@D4?9p~BPZL}EV6ttvi zN#nW+uWz33yq%x&xb@KdRryD19uKKLyX|_Z(Cv8NhO~YZo}CFV+>tbi6|ty?pM7=y z(0L}AqTy9dqm%QGHoVB8(zc1#JjmI#H^s~PQoy?DNBj1y995Givse;2`(#C$QDgq4 zBO?wR3JSif#cQTv1^?#PO$rOHm=ylZWzm$$DZZbY_Npth$?D})e_+a{A6S)zpLM(7 z^~pHrguYbi$JDE@M)Rjyo&5Y)@B6Q|R|t7SO;l%0)p`bZKTTp?a^CSv!->Lymb2Ke zc3#g)4?SbmJj}UtOoGeJ=yhCMbFUFaRZWULHi@A|aeFJQ{he2R?`ABSSywc<-p3+r z{V-r6e(0)U1$%i;H_MCDy}R^2#e8sSIB)x6*=e)=8JzJSEr>};JJ7JIhe^g2f8&N5 zzb*M^{pOz>rk0ztjwx=thgr@uzBWaWTCc@R_C=&;Es%`pbF#2d7Psel#Qq~ut}&~4 z9(8uM4E|9Ei=WxM&bx0ZJn3iBGV<*3(frCUp8d$&6!^k()apc^*Quih9NYRri`Nnf z)rn5z_dL;jO7X9wmu_ z_wEjAnmDbSU9(S%K#P~0E6`|`VDhpIvCW2qYtEUa@7qw{xo5@c(x;{8!uE^2^X?A1 z_5PDq{$pcCYr^2*E6yj}hivRW+c5Bs zXVlj|U1EPJF|EloTVM8S!h+f->^mhv#yO78TD*8(B8jDFJW*}>)$M{p&%;3uKU;72 zVy~RHVrt7`*OpCjnF|LeoXI_Rr{)oVde+cILD^$3q~@dz-nBUH;dMVBR;MtAO8^kz zxj`(A6ee*M__Gb2$R0{0dH-I%_rQA(y!XI+54`ul-@*e)>hQ%%wKVai-OXb;+jHlbeRCwlM>hq~|#i2BhEv={A0`_Wdknb=R-f@d(a zo#e3%Xz#z&w$-VBv@!9W#UB(J?+rd5r12T=k3J`HA`)jYV21I$xL#a7@X=N%Nu`M84MEBA~7KY=I4AjE|14`Cs8jFHG&dvt|yo0_7@nUheXCmWC<{yT>c=g z2gcm!m==i%fe*aF1RjGyqFy9w1SRfV9+r@}7>O%E2_GPVyuO3-TXHHqbsSQwPJt4c`Jk3`L& zWDt}gm&yVXFC_6cDDhC0{G}ck3T^6v5)ySJ zQ9EG6Ucml=Nroel#POiF(QO_O1?jCCcd=^u$Hj^g#v};k+`uG-P%afnrYhuOsmPzr zdozK&|1g0RR0K_Ts-^pO`P$XpF>s9U%zw)DZL*6ys-P&L92i5dvKLQ@8r#f<+BkPo zy*)27lgwJTsI8dosIm&yIGC@zwx%m1K#?3Pq+B5;t^P(&VESc*TpX)V=~wBDRw!aA zA6HkoP$Z@l@?@?wHfAoxmB~e}Zvd_wtqjML>kfYkQA#^lZN-454dB3{feQdawaYoN z0y!9?C!4yqhExUSz<>vC{j37V031X12=YP@X6W{|V}+)U8cf%xDfr%6ZIa3&h3e)d zQti-b>Hu9L#Zj$I`ZWMm015?1wc5cav?5*_DUJ~9Y>0L>pwZ4k=fZO5slyDqI{~Tb zR@e&=A`&V%@Gk%op`3&N2q727#f#-aP9%IpC}i?v7+^3{IEms&MYIa5v+K31X*9m+ zbDXcBxE(j+vWY+t&^R|P-Bs<>*R~OG+F1_05~Dt0jBKu$19L{0B&Ik~@e&E$CQbzQ zNUTgORUj^wBal*J9lBJN)S6To4!z!@9>lBEw8QeI60p3<(5==8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/bun-types": { + "version": "1.0.28", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "~20.11.3", + "@types/ws": "~8.5.10" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", + "engines": { + "node": ">=6" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/typescript": { + "version": "5.3.3", + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "engines": { + "node": ">=12" + } + } + } +} diff --git a/cli/package.json b/cli/package.json new file mode 100644 index 000000000..6c6987b51 --- /dev/null +++ b/cli/package.json @@ -0,0 +1,18 @@ +{ + "name": "cli", + "module": "src/index.ts", + "type": "module", + "devDependencies": { + "@types/bun": "latest", + "@types/yargs": "^17.0.32" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "bin": { + "ntt": "src/index.ts" + }, + "dependencies": { + "yargs": "^17.7.2" + } +} diff --git a/cli/src/index.ts b/cli/src/index.ts new file mode 100755 index 000000000..206dd93cc --- /dev/null +++ b/cli/src/index.ts @@ -0,0 +1,101 @@ +#!/usr/bin/env bun +import yargs from "yargs"; +import { $ } from "bun"; +import { hideBin } from "yargs/helpers"; + +type Network = "mainnet" | "testnet" | "devnet"; + +// TODO: grab this from sdkv2 +export function assertNetwork(n: string): asserts n is Network { + if (n !== "mainnet" && n !== "testnet" && n !== "devnet") { + throw Error(`Unknown network: ${n}`); + } +} + +export const NETWORK_OPTIONS = { + alias: "n", + describe: "Network", + choices: ["mainnet", "testnet", "devnet"], + demandOption: true, +} as const; + +yargs(hideBin(process.argv)) + .scriptName("ntt") + .command( + "solana", + "Solana commands", + (yargs) => { + yargs + .command( + "deploy", + "deploy the solana program", + (yargs) => { + yargs.option("network", NETWORK_OPTIONS) + }, + (argv) => { + throw new Error("Not implemented"); + }) + .command( + "upgrade", + "upgrade the solana program", + (yargs) => { + yargs + .option("network", NETWORK_OPTIONS) + .option("dir", { + alias: "d", + describe: "Path to the solana workspace", + default: ".", + demandOption: false, + type: "string", + }) + .option("keypair", { + alias: "k", + describe: "Path to the keypair", + demandOption: true, + type: "string", + }) + }, + async (argv) => { + // TODO: the hardcoded stuff should be factored out once + // we support other networks and programs + // TODO: currently the keypair is the upgrade authority. we should support governance program too + // TODO: why does typescript not like the yargs types? + const network: string = argv.network as string; + const keypair: string = argv.keypair as string; + const dir: string = argv.dir as string; + const objectFile = "example_native_token_transfers.so"; + const programId = "nttiK1SepaQt6sZ4WGW5whvc9tEnGXGxuKeptcQPCcS"; + assertNetwork(network); + await $`cargo build-sbf --manifest-path=${dir}/Cargo.toml --features "${cargoNetworkFeature(network)}"` + await $`solana program deploy --program-id ${programId} ${dir}/target/deploy/${objectFile} --keypair ${keypair} -u ${solanaMoniker(network)}` + }) + .demandCommand() + } + ) + .help() + .strict() + .demandCommand() + .parse(); + +function cargoNetworkFeature(network: Network): string { + switch (network) { + case "mainnet": + return "mainnet"; + case "testnet": + return "solana-devnet"; + case "devnet": + return "tilt-devnet"; + } +} + + +function solanaMoniker(network: Network): string { + switch (network) { + case "mainnet": + return "m"; + case "testnet": + return "d"; + case "devnet": + return "l"; + } +} diff --git a/cli/tsconfig.json b/cli/tsconfig.json new file mode 100644 index 000000000..0fef23a36 --- /dev/null +++ b/cli/tsconfig.json @@ -0,0 +1,27 @@ +{ + "compilerOptions": { + // Enable latest features + "lib": ["ESNext"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true, + + // Best practices + "strict": true, + "skipLibCheck": true, + "noFallthroughCasesInSwitch": true, + + // Some stricter flags (disabled by default) + "noUnusedLocals": false, + "noUnusedParameters": false, + "noPropertyAccessFromIndexSignature": false + } +} diff --git a/solana/package.json b/solana/package.json index 8ac8941f1..835f0a024 100644 --- a/solana/package.json +++ b/solana/package.json @@ -1,4 +1,5 @@ { + "name": "example-native-token-transfers-solana", "license": "Apache-2.0", "scripts": { "lint:fix": "prettier */*.js \"*/**/*{.js,.ts}\" -w", From f78b859d69e1cc6e26bc71c23712d7865e1f7fc7 Mon Sep 17 00:00:00 2001 From: Csongor Kiss Date: Mon, 26 Feb 2024 11:18:37 -0500 Subject: [PATCH 2/2] solana: make network flags mutually exclusive --- cli/src/index.ts | 2 +- .../example-native-token-transfers/src/lib.rs | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/cli/src/index.ts b/cli/src/index.ts index 206dd93cc..2b77a2571 100755 --- a/cli/src/index.ts +++ b/cli/src/index.ts @@ -66,7 +66,7 @@ yargs(hideBin(process.argv)) const objectFile = "example_native_token_transfers.so"; const programId = "nttiK1SepaQt6sZ4WGW5whvc9tEnGXGxuKeptcQPCcS"; assertNetwork(network); - await $`cargo build-sbf --manifest-path=${dir}/Cargo.toml --features "${cargoNetworkFeature(network)}"` + await $`cargo build-sbf --manifest-path=${dir}/Cargo.toml --no-default-features --features "${cargoNetworkFeature(network)}"` await $`solana program deploy --program-id ${programId} ${dir}/target/deploy/${objectFile} --keypair ${keypair} -u ${solanaMoniker(network)}` }) .demandCommand() diff --git a/solana/programs/example-native-token-transfers/src/lib.rs b/solana/programs/example-native-token-transfers/src/lib.rs index 74c4974e9..225f574f2 100644 --- a/solana/programs/example-native-token-transfers/src/lib.rs +++ b/solana/programs/example-native-token-transfers/src/lib.rs @@ -1,5 +1,16 @@ use anchor_lang::prelude::*; +// TODO: is there a more elegant way of checking that these 3 features are mutually exclusive? + +#[cfg(all(feature = "mainnet", feature = "solana-devnet"))] +compile_error!("Cannot enable both mainnet and solana-devnet features at the same time"); + +#[cfg(all(feature = "mainnet", feature = "tilt-devnet"))] +compile_error!("Cannot enable both mainnet and tilt-devnet features at the same time"); + +#[cfg(all(feature = "solana-devnet", feature = "tilt-devnet"))] +compile_error!("Cannot enable both solana-devnet and tilt-devnet features at the same time"); + pub mod bitmap; pub mod clock; pub mod config;