Skip to content
Open

V9 #2186

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
2 changes: 1 addition & 1 deletion .github/workflows/add-to-devrel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
name: Add issue/PR to project
runs-on: ubuntu-latest
steps:
- uses: actions/[email protected].0
- uses: actions/[email protected].2
with:
# add to DevRel Project #117
project-url: https://github.com/orgs/near/projects/117
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install modules
run: npm install
- name: Run ESLint
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/test-contract-rs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,18 @@ jobs:
strategy:
matrix:
platform: [ubuntu-latest]
template: [auction, auction-adv]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
- name: Install modules
run: npm install
- name: Create Contract RS
run: npm run start -- hello-near --frontend none --contract rs
- name: Create Contract RS - ${{ matrix.template }}
run: npm run start -- test-app --frontend none --contract rs --template ${{ matrix.template }}
- name: Install cargo-near
run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/near/cargo-near/releases/latest/download/cargo-near-installer.sh | sh
- name: Run tests
run: cd hello-near && cargo test
run: cd test-app && cargo test
13 changes: 9 additions & 4 deletions .github/workflows/test-contract-ts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ jobs:
strategy:
matrix:
platform: [ubuntu-latest, macos-latest]
node-version: [18, 20, 22]
node-version: [22, 24]
template: [auction, auction-adv]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
Expand All @@ -16,7 +17,11 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Install modules
run: npm install
- name: Create Contract TS
run: npm run start -- hello-near --frontend none --contract ts
- name: Create Contract TS - ${{ matrix.template }}
run: npm run start -- test-app --frontend none --contract ts --template ${{ matrix.template }}
- name: Install test app dependencies
working-directory: test-app
run: npm install
- name: Run tests
run: cd hello-near && npm install && npm run test
working-directory: test-app
run: npm run test
9 changes: 5 additions & 4 deletions .github/workflows/test-frontend.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ jobs:
strategy:
matrix:
platform: [ubuntu-latest, macos-latest]
node-version: [18, 20, 22]
node-version: [22, 24]
frontend: [next-page, next-app, vite-react]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v4
Expand All @@ -16,7 +17,7 @@ jobs:
node-version: ${{ matrix.node-version }}
- name: Install modules
run: npm install
- name: Create Frontend No Components
run: npm run start -- hello-near --frontend next-page
- name: Create Frontend - ${{ matrix.frontend }}
run: npm run start -- test-app --frontend ${{ matrix.frontend }}
- name: Install
run: cd hello-near && npm install
run: cd test-app && npm install
2 changes: 1 addition & 1 deletion .github/workflows/test-matrix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
platform: [ubuntu-latest]
runs-on: ${{ matrix.platform }}
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '22'
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
"@types/jest": "^29.5.2",
"@types/ncp": "^2.0.5",
"@types/node": "^20.3.2",
"@types/node-dir": "^0.0.37",
"@types/prompts": "^2.4.4",
"@types/semver": "^7.5.0",
"eslint": "^8.43.0",
Expand Down
2 changes: 2 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import { isCargoNearInstalled } from './utils';
config: {
projectName,
contract,
template,
frontend,
install,
},
Expand All @@ -32,6 +33,7 @@ import { isCargoNearInstalled } from './utils';
try {
createSuccess = await createProject({
contract,
template: template || 'auction',
frontend,
templatesDir: path.resolve(__dirname, '../templates'),
projectPath,
Expand Down
15 changes: 7 additions & 8 deletions src/make.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,26 @@ import * as show from './messages';
import { downloadFile } from './utils';
import { CreateContractParams, CreateGatewayParams } from './types';

export async function createProject({ contract, frontend, projectPath, templatesDir }: CreateContractParams & CreateGatewayParams): Promise<boolean> {
export async function createProject({ contract, template, frontend, projectPath, templatesDir }: CreateContractParams & CreateGatewayParams): Promise<boolean> {
if (contract !== 'none') {
await createContract({ contract, projectPath, templatesDir });
} else {
await createContract({ contract, template, projectPath, templatesDir });
} else if (frontend !== 'none') {
await createGateway({ frontend, projectPath, templatesDir });
}

return true;
}

async function createContract({ contract, projectPath, templatesDir }: CreateContractParams) {
await createContractFromTemplate({ contract, projectPath, templatesDir });
async function createContract({ contract, template, projectPath, templatesDir }: CreateContractParams) {
await createContractFromTemplate({ contract, template, projectPath, templatesDir });

if (contract === 'rs') {
await updateTemplateFiles(projectPath);
}
}

async function createContractFromTemplate({ contract, projectPath, templatesDir }: CreateContractParams) {
// contract folder
const sourceContractDir = path.resolve(templatesDir, 'contracts', contract);
async function createContractFromTemplate({ contract, template, projectPath, templatesDir }: CreateContractParams) {
const sourceContractDir = path.resolve(templatesDir, 'contracts', template, contract);
fs.mkdirSync(projectPath, { recursive: true });
await copyDir(sourceContractDir, projectPath);
}
Expand Down
6 changes: 0 additions & 6 deletions src/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ const mapContractLanguage = (contract: Contract) => {
return 'Typescript';
case 'rs':
return 'Rust';
case 'py':
return 'Python';
default:
return '';
}
Expand Down Expand Up @@ -104,8 +102,6 @@ export const contractInstructions = (

if (contract === 'ts') {
message += chalk` {blue npm {bold run build}}\n`;
} else if (contract === 'py') {
message += chalk` {blue {bold uvx nearc contract.py --create-venv}}\n`;
} else {
message += chalk` {blue {bold cargo near build}}\n`;
}
Expand All @@ -114,8 +110,6 @@ export const contractInstructions = (

if (contract === 'ts') {
message += chalk` {blue npm {bold run test}}\n`;
} else if (contract === 'py') {
message += chalk` {blue {bold uv run pytest}}\n`;
} else {
message += chalk` {blue {bold cargo near test}}\n`;
}
Expand Down
9 changes: 7 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
export type Contract = 'ts' | 'rs' | 'py' |'none';
export const CONTRACTS: Contract[] = ['ts', 'rs', 'py', 'none'];
export type Contract = 'ts' | 'rs' | 'none';
export const CONTRACTS: Contract[] = ['ts', 'rs', 'none'];

export type Template = 'auction' | 'auction-adv';
export const TEMPLATES: Template[] = ['auction', 'auction-adv'];

export type Frontend = 'next-app' | 'next-page' | 'vite-react' | 'none';
export const FRONTENDS: Frontend[] = ['next-app', 'next-page', 'vite-react', 'none'];
Expand All @@ -11,6 +14,7 @@ export type ProjectName = string;

export interface UserConfig {
contract: Contract;
template?: Template;
frontend: Frontend;
projectName: ProjectName;
install: boolean;
Expand All @@ -19,6 +23,7 @@ export interface UserConfig {

export type CreateContractParams = {
contract: Contract,
template: Template,
projectPath: string,
templatesDir: string,
}
Expand Down
42 changes: 34 additions & 8 deletions src/user-input.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import {
App,
Contract,
CONTRACTS,
Template,
TEMPLATES,
Frontend,
FRONTENDS,
ProjectName,
Expand All @@ -17,17 +19,18 @@ import fs from 'fs';
export async function getUserArgs(): Promise<UserConfig> {
program
.argument('[projectName]')
.option('--frontend [next-page|next-app|none]')
.option('--frontend [next-page|next-app|vite-react|none]')
.option('--contract [ts|rs|none]')
.option('--template [auction-adv|auction]')
.option('--install')
.addHelpText('after', 'You can create a frontend or a contract with tests');

program.parse();

const options = program.opts();
const [projectName] = program.args;
const { contract, frontend, install } = options;
return { contract, frontend, projectName, install, error: undefined };
const { contract, frontend, template, install } = options;
return { contract, frontend, template, projectName, install, error: undefined };
}

type Choices<T> = { title: string, description?: string, value: T }[];
Expand All @@ -38,10 +41,15 @@ const appChoices: Choices<App> = [
title: 'A Smart Contract', description: 'A smart contract to be deployed in the Near Blockchain', value: 'contract',
},
];

const templateChoices: Choices<Template> = [
{ title: 'Auction', description: 'A simple auction smart contract', value: 'auction' },
{ title: 'Auction (advance)', description: 'An auction contract were users can bid with FT and the winner gets a NFT', value: 'auction-adv' },
];

const contractChoices: Choices<Contract> = [
{ title: 'JS/TS Contract', description: 'A Near contract written in javascript/typescript', value: 'ts' },
{ title: 'TS Contract', description: 'A Near contract written in typescript', value: 'ts' },
{ title: 'Rust Contract', description: 'A Near contract written in Rust', value: 'rs' },
{ title: 'Python Contract', description: 'A Near contract written in Python', value: 'py' },
];

const frontendChoices: Choices<Frontend> = [
Expand All @@ -57,6 +65,13 @@ const appPrompt: PromptObject = {
choices: appChoices,
};

const templatePrompt: PromptObject = {
type: 'select',
name: 'template',
message: 'Select a contract template',
choices: templateChoices,
};

const frontendPrompt: PromptObject = {
type: 'select',
name: 'frontend',
Expand All @@ -68,7 +83,7 @@ const contractPrompt: PromptObject[] = [
{
type: 'select',
name: 'contract',
message: 'Select a smart contract template for your project',
message: 'Select a language for your contract',
choices: contractChoices,
}
];
Expand Down Expand Up @@ -106,12 +121,13 @@ export async function getUserAnswers(): Promise<UserConfig> {
return { frontend: 'none', contract: 'none', projectName: '', install: false, error: show.windowsWarning };
}

// If contract, ask for the language for the contract
// If contract, ask for the template and language
const { template } = await promptUser(templatePrompt);
let { contract } = await promptUser(contractPrompt);

const { projectName } = await promptUser(namePrompts);
const install = contract === 'ts' ? (await promptUser(npmPrompt)).install as boolean : false;
return { frontend: 'none', contract, projectName, install, error: undefined };
return { frontend: 'none', contract, template, projectName, install, error: undefined };
}
}

Expand Down Expand Up @@ -164,6 +180,11 @@ const validateUserArgs = (args: UserConfig) => {
return false;
}

if (args.template && !TEMPLATES.includes(args.template)) {
show.argsError(`Invalid template type: ${args.template}`);
return false;
}

if (!args.projectName) {
show.argsError('Please provide a project name');
return false;
Expand All @@ -174,5 +195,10 @@ const validateUserArgs = (args: UserConfig) => {
return false;
}

if (args.contract !== 'none' && !args.template) {
show.argsError('Please specify a template for your contract');
return false;
}

return true;
};
26 changes: 26 additions & 0 deletions templates/contracts/auction-adv/rs/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "auction-contract"
description = "Auction Example Part 3"
version = "0.1.0"
edition = "2021"

[lib]
crate-type = ["cdylib", "rlib"]

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
near-sdk = "5.17"

[dev-dependencies]
near-sdk = { version = "5.17", features = ["unit-testing"] }
near-workspaces = { version = "0.21", features = ["unstable"] }
tokio = { version = "1.12.0", features = ["full"] }
serde_json = "1"

[profile.release]
codegen-units = 1
opt-level = "z"
lto = true
debug = false
panic = "abort"
overflow-checks = true
35 changes: 35 additions & 0 deletions templates/contracts/auction-adv/rs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Auction contract with FTs

This directory contains a Rust contract that is used as part of the [Bidding with FTs](https://docs.near.org/tutorials/auction/bidding-with-fts) section of the auction tutorial.

In this part the contract is adapted so users can bid in fungible tokens (FTs) instead of NEAR tokens. It is a great way to learn how to work with FTs in NEAR.

## How to Build Locally?

Install [`cargo-near`](https://github.com/near/cargo-near) and run:

```bash
cargo near build
```

## How to Test Locally?

```bash
cargo test
```

## How to Deploy?

To deploy manually, install [NEAR CLI](https://docs.near.org/tools/near-cli#installation) and run:

```bash
# Create a new account
near create <contractId> --useFaucet

# Deploy the contract on it
near deploy <contractId> ./target/near/auction-contract.wasm

# Initialize the contract
TWO_MINUTES_FROM_NOW=$(date -v+2M +%s000000000)
near call <contractId> init '{"end_time": "'$TWO_MINUTES_FROM_NOW'", "auctioneer": "<auctioneerAccountId>", "ft_contract": "<ftContractId>", "nft_contract": "<nftContractId>", "token_id": "<tokenId>", "starting_price": "<startingPrice>"}' --accountId <contractId>
```
4 changes: 4 additions & 0 deletions templates/contracts/auction-adv/rs/rust-toolchain.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[toolchain]
channel = "stable"
components = ["rustfmt"]
targets = ["wasm32-unknown-unknown"]
Loading