Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: Alpha Release Iteration #7

Merged
merged 16 commits into from
Oct 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions .github/workflows/lint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
name: Lint

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [20.x]

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm run check
- run: npm run format -- --check
27 changes: 27 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: Release

on:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
build:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x]

steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
- env:
NODE_AUTH_TOKEN:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add in when ready

${{ secrets.NPM_TOKEN }}
- run: npm install
- run: npm run release
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:

strategy:
matrix:
node-version: [16.x, 18.x]
node-version: [20.x]

steps:
- uses: actions/checkout@v3
Expand Down
38 changes: 27 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,48 @@ A CLI tool to create a new Nillion app with Next.js integration.

## Usage

This will create a new Nillion app in the `my-nillion-app` directory.
This will create a new Nillion app in the your desired directory.

`npx create-nillion-app`
`npx @nillion/create-nillion-app`

## What it does

1. Installs `nilup`, the Nillion SDK tool installer and version manager
2. Install an Nada projects
3. Clones an example Next.js project with App Router
a. Installs `@nillion/client-react-hooks`
b.
2. Clones an example Next.js project with App Router Settings
a. Installs `@nillion/client-react-hooks` which has all your needs to use Nillion and Nada.
3. Installs an Nada projects with a pyenv
4. Then follow along the QuickStart [guide](https://github.com/NillionNetwork/awesome-nillion/issues/2) to do the following:
- Create a simple Nada App
- Connect a Nextjs <> Nada Program

Directory tree should look like:

```
.
├── nada_quickstart_programs
│   ├── XXX
└── nillion-app
├── XXX
├── README.md
├── app
│ ├── components
│ ├── home
│ ├── layout.tsx
│ ├── lib
│ └── page.tsx
├── nada
│ ├── .venv
│ ├── nada-project.toml
│ ├── requirements.txt
│ ├── src
│ └── tests
├── next.config.mjs
├── node_modules
├── package-lock.json
├── package.json
└── tsconfig.json

```

## Requirements

- Node.js 14.0.0 or later
- Node.js 18.0.0 or later
- npm 6.0.0 or later

## License
Expand Down
4 changes: 4 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default [
...eslintPluginPrettier.configs.recommended.rules,
"prettier/prettier": "error",
...eslintPluginJest.configs.recommended.rules,
"@typescript-eslint/no-unused-vars": "error",
},
},
js.configs.recommended,
Expand All @@ -39,4 +40,7 @@ export default [
...eslintPluginJest.configs.recommended.rules,
},
},
{
ignores: ["examples/**/*"],
},
];
3 changes: 3 additions & 0 deletions examples/nextjs/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": ["next/core-web-vitals", "next/typescript"]
}
36 changes: 36 additions & 0 deletions examples/nextjs/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js
.yarn/install-state.gz

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*

# local env files
.env*.local

# vercel
.vercel

# typescript
*.tsbuildinfo
next-env.d.ts
8 changes: 8 additions & 0 deletions examples/nextjs/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"trailingComma": "all",
"tabWidth": 2,
"arrowParens": "always",
"semi": true,
"useTabs": false,
"singleQuote": false
}
21 changes: 21 additions & 0 deletions examples/nextjs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
## Nextjs Example for Create Nillion App (CNA)

![Example Demo](./public/example_demo.png)

Welcome the Nextjs Example for CNA.

Once the CLI insturctions have finished, you can run the developent server:

```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```

Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

Then follow the rest of the instructions from the Quickstart guide [here.](https://github.com/NillionNetwork/awesome-nillion/issues/2)
11 changes: 11 additions & 0 deletions examples/nextjs/app/components/ClientWrapper.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"use client";

import { ReactNode } from "react";

import { NillionProvider } from "@nillion/client-react-hooks";

export const ClientWrapper: React.FC<{ children: ReactNode }> = ({
children,
}) => {
return <NillionProvider network="devnet">{children}</NillionProvider>;
};
87 changes: 87 additions & 0 deletions examples/nextjs/app/components/Compute.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
"use client";

import { type FC, useState } from "react";
import {
NadaValue,
NadaValues,
NamedValue,
PartyName,
ProgramBindings,
ProgramId,
} from "@nillion/client-core";
import { useNilCompute, useNillion } from "@nillion/client-react-hooks";

export const Compute: FC = () => {
const { client } = useNillion();
const nilCompute = useNilCompute();
const [programId, setProgramId] = useState<ProgramId | string>("");
const [copiedComputeOutputID, setCopiedComputeOutputID] = useState(false);

const handleClick = () => {
if (!programId) throw new Error("compute: program id required");

const bindings = ProgramBindings.create(programId)
.addInputParty(PartyName.parse("Party1"), client.partyId)
.addOutputParty(PartyName.parse("Party1"), client.partyId);

// Note: This is hardcoded for demo purposes.
// Feel free to change the NamedValue to your required program values.
const values = NadaValues.create()
.insert(NamedValue.parse("my_int1"), NadaValue.createSecretInteger(2))
.insert(NamedValue.parse("my_int2"), NadaValue.createSecretInteger(4));

nilCompute.execute({ bindings, values });
};

return (
<div className="border border-gray-400 rounded-lg p-4 w-full max-w-md">
<h2 className="text-2xl font-bold mb-4">Compute</h2>
<input
className="w-full p-2 mb-4 border border-gray-300 rounded text-black"
placeholder="Program id"
value={programId}
onChange={(e) => setProgramId(e.target.value)}
/>
<button
className={`flex items-center justify-center px-4 py-2 border rounded text-black mb-4 ${
nilCompute.isLoading || !programId
? "opacity-50 cursor-not-allowed bg-gray-200"
: "bg-white hover:bg-gray-100"
}`}
onClick={handleClick}
disabled={nilCompute.isLoading || !programId}
>
{nilCompute.isLoading ? (
<div className="w-5 h-5 border-t-2 border-b-2 border-gray-900 rounded-full animate-spin"></div>
) : (
"Compute"
)}
</button>
<p className="my-2 italic text-sm mt-2">
Current values are 4 & 2. Refer to ComputeOutput.tsx
</p>
<ul className="list-disc pl-5 mt-4">
<li className="mt-2">Status: {nilCompute.status}</li>
<li className="mt-2">
Compute output id:
{nilCompute.isSuccess ? (
<>
{`${nilCompute.data?.substring(0, 4)}...${nilCompute.data?.substring(nilCompute.data.length - 4)}`}
<button
onClick={() => {
setCopiedComputeOutputID(true);
navigator.clipboard.writeText(nilCompute.data);
setTimeout(() => setCopiedComputeOutputID(false), 2000);
}}
>
{!copiedComputeOutputID ? " 📋" : " ✅"}
</button>
</>
) : (
"idle"
)}
</li>
</ul>
</div>
);
};
56 changes: 56 additions & 0 deletions examples/nextjs/app/components/ComputeOutput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
"use client";

import { type FC, useState } from "react";
import { useNilComputeOutput } from "@nillion/client-react-hooks";
import { ComputeOutputId } from "@nillion/client-core";

export const ComputeOutput: FC = () => {
const nilComputeOutput = useNilComputeOutput();
const [computeId, setComputeId] = useState<ComputeOutputId | string>("");

const handleClick = () => {
if (!computeId) throw new Error("compute-output: Compute id is required");
nilComputeOutput.execute({ id: computeId });
};

let computeOutput = "idle";
if (nilComputeOutput.isSuccess) {
computeOutput = JSON.stringify(nilComputeOutput.data, (key, value) => {
if (typeof value === "bigint") {
return value.toString();
}
return value;
});
}

return (
<div className="border border-gray-400 rounded-lg p-4 w-full max-w-md">
<h2 className="text-2xl font-bold mb-4">Compute Output</h2>
<input
className="w-full p-2 mb-4 border border-gray-300 rounded text-black"
placeholder="Compute output id"
value={computeId}
onChange={(e) => setComputeId(e.target.value)}
/>
<button
className={`flex items-center justify-center px-4 py-2 border rounded text-black ${
!computeId || nilComputeOutput.isLoading
? "opacity-50 cursor-not-allowed bg-gray-200"
: "bg-white hover:bg-gray-100"
}`}
onClick={handleClick}
disabled={!computeId || nilComputeOutput.isLoading}
>
{nilComputeOutput.isLoading ? (
<div className="w-5 h-5 border-t-2 border-b-2 border-gray-900 rounded-full animate-spin"></div>
) : (
"Fetch"
)}
</button>
<ul className="list-disc pl-5 mt-4">
<li className="mt-2">Status: {nilComputeOutput.status}</li>
<li className="mt-2">Output: {computeOutput}</li>
</ul>
</div>
);
};
Loading
Loading