From 9996aa9c57b611dfc9f2cf13ee5cbebea540957d Mon Sep 17 00:00:00 2001 From: Tim McMackin Date: Mon, 20 Jan 2025 09:35:38 -0500 Subject: [PATCH] Remove old NFT tutorial applications that are replaced by create-nfts --- nft-taquito/.gitignore | 6 - nft-taquito/README.md | 50 - nft-taquito/backend/Procfile | 1 - nft-taquito/backend/package.json | 35 - nft-taquito/backend/src/PinataKeys.ts | 4 - nft-taquito/backend/src/index.ts | 107 - nft-taquito/backend/src/types.ts | 15 - nft-taquito/backend/tsconfig.json | 16 - nft-taquito/contract/NFTS_contract.mligo | 541 -- nft-taquito/frontend/index.html | 22 - nft-taquito/frontend/package.json | 30 - nft-taquito/frontend/public/Roman-SD.ttf | Bin 50408 -> 0 bytes nft-taquito/frontend/public/Roman-SD.woff | Bin 16952 -> 0 bytes .../frontend/public/images/taquito.png | Bin 35018 -> 0 bytes nft-taquito/frontend/src/App.svelte | 299 -- nft-taquito/frontend/src/main.ts | 9 - nft-taquito/frontend/src/styles/index.scss | 18 - nft-taquito/frontend/svelte.config.js | 7 - nft-taquito/frontend/tsconfig.json | 18 - nft-taquito/frontend/vite.config.js | 35 - simple-nft-svelte/README.md | 10 - simple-nft-svelte/contract/simple-nft.py | 210 - simple-nft-svelte/index.html | 19 - simple-nft-svelte/jsconfig.json | 32 - simple-nft-svelte/package-lock.json | 4520 ----------------- simple-nft-svelte/package.json | 25 - simple-nft-svelte/src/App.svelte | 95 - simple-nft-svelte/src/app.css | 80 - simple-nft-svelte/src/main.js | 7 - simple-nft-svelte/src/vite-env.d.ts | 2 - simple-nft-svelte/svelte.config.js | 7 - simple-nft-svelte/vite.config.js | 36 - 32 files changed, 6256 deletions(-) delete mode 100644 nft-taquito/.gitignore delete mode 100644 nft-taquito/README.md delete mode 100644 nft-taquito/backend/Procfile delete mode 100644 nft-taquito/backend/package.json delete mode 100644 nft-taquito/backend/src/PinataKeys.ts delete mode 100644 nft-taquito/backend/src/index.ts delete mode 100644 nft-taquito/backend/src/types.ts delete mode 100644 nft-taquito/backend/tsconfig.json delete mode 100644 nft-taquito/contract/NFTS_contract.mligo delete mode 100644 nft-taquito/frontend/index.html delete mode 100644 nft-taquito/frontend/package.json delete mode 100644 nft-taquito/frontend/public/Roman-SD.ttf delete mode 100644 nft-taquito/frontend/public/Roman-SD.woff delete mode 100644 nft-taquito/frontend/public/images/taquito.png delete mode 100644 nft-taquito/frontend/src/App.svelte delete mode 100644 nft-taquito/frontend/src/main.ts delete mode 100644 nft-taquito/frontend/src/styles/index.scss delete mode 100644 nft-taquito/frontend/svelte.config.js delete mode 100644 nft-taquito/frontend/tsconfig.json delete mode 100644 nft-taquito/frontend/vite.config.js delete mode 100644 simple-nft-svelte/README.md delete mode 100644 simple-nft-svelte/contract/simple-nft.py delete mode 100644 simple-nft-svelte/index.html delete mode 100644 simple-nft-svelte/jsconfig.json delete mode 100644 simple-nft-svelte/package-lock.json delete mode 100644 simple-nft-svelte/package.json delete mode 100644 simple-nft-svelte/src/App.svelte delete mode 100644 simple-nft-svelte/src/app.css delete mode 100644 simple-nft-svelte/src/main.js delete mode 100644 simple-nft-svelte/src/vite-env.d.ts delete mode 100644 simple-nft-svelte/svelte.config.js delete mode 100644 simple-nft-svelte/vite.config.js diff --git a/nft-taquito/.gitignore b/nft-taquito/.gitignore deleted file mode 100644 index c66f727..0000000 --- a/nft-taquito/.gitignore +++ /dev/null @@ -1,6 +0,0 @@ -frontend/node_modules -backend/node_modules -backend/dist -backend/uploads/* -*/package-lock.json -.DS_Store diff --git a/nft-taquito/README.md b/nft-taquito/README.md deleted file mode 100644 index 8fe5687..0000000 --- a/nft-taquito/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Tutorial application: Create a web app that mints NFTs - -This is the completed application from the tutorial [Create a web app that mints NFTs](https://docs.tezos.com/tutorials/create-an-nft/nft-taquito/). - -## Project structure - -This project contains two applications that you run on your computer and one smart contract that you deploy to Tezos: - -- The `frontend` folder contains a Vite and Svelte application that allows users to upload files and send a request to mint and NFT based on that file. -- The `backend` folder contains an Express application that receives the files and NFT information and mints NFTs. -- The `contract` folder contains a smart contract written in CameLIGO that manages the NFTs. - -## Running the application - -To run the application, you must deploy (originate) the contract and start the backend and frontend applications: - -1. If you don't have an account on Pinata, set one up at . - -1. On Pinata, create an API key with the `pinFileToIFPS` and `pinJSONToIFPS` permissions and copy the API key and secret. - -1. Originate the `contract/NFTS_contract.mligo` file to Tezos, using the commented text at the end as the initial storage value. -For example, you can use the web IDE for LIGO at to originate the contract. - -1. Copy the address of the originated contract. - -1. Start the backend app: - - 1. Go to the `backend` folder. - - 1. Install the dependencies by running `npm install`. - - 1. In the file `src/PinataKeys.ts`, enter your Pinata API key and secret. - - 1. Start the app by running `npm run dev`. - -1. Start the frontend app: - - 1. Go to the `frontend` folder. - - 1. Install the dependencies by running `npm install`. - - 1. Update the `src/App.svelte` file to set the address of the contract you originated in this line: - - ```ts - const contractAddress = "KT1XKSMfewg86885Q25ezFdNVTr995XVhVCf"; - ``` - - 1. Start the app by running `npm run dev`. - -1. Open the frontend app in a web browser by going to . diff --git a/nft-taquito/backend/Procfile b/nft-taquito/backend/Procfile deleted file mode 100644 index 4e4926a..0000000 --- a/nft-taquito/backend/Procfile +++ /dev/null @@ -1 +0,0 @@ -web: node dist/index.js \ No newline at end of file diff --git a/nft-taquito/backend/package.json b/nft-taquito/backend/package.json deleted file mode 100644 index 3e5fb16..0000000 --- a/nft-taquito/backend/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "nft-taquito-pinata-tutorial", - "version": "1.0.0", - "description": "A tutorial about using Taquito and Pinata to mint NFTs on Tezos", - "main": "dist/index.js", - "scripts": { - "build": "tsc", - "postinstall": "tsc", - "prestart": "npm run build", - "start": "node dist/index.js", - "dev": "nodemon --watch \"src/**\" --ext \"ts,json\" --exec \"ts-node src/index.ts\"", - "test": "echo \"Error: no test specified\" && exit 1", - "deploy": "git add . && git commit -m Heroku && git push heroku main" - }, - "author": "Claude Barde", - "license": "ISC", - "engines": { - "node": ">=18.0" - }, - "dependencies": { - "@pinata/sdk": "^2.1.0", - "axios": "^1.3.2", - "cors": "^2.8.5", - "express": "^4.18.2", - "multer": "^1.4.2", - "uuid": "^9.0.0" - }, - "devDependencies": { - "@types/express": "^4.17.17", - "@types/node": "^18.11.19", - "nodemon": "^2.0.20", - "ts-node": "^10.9.1", - "typescript": "^4.9.5" - } -} diff --git a/nft-taquito/backend/src/PinataKeys.ts b/nft-taquito/backend/src/PinataKeys.ts deleted file mode 100644 index 5304aae..0000000 --- a/nft-taquito/backend/src/PinataKeys.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default { - apiKey: "DUMMY_KEY", - apiSecret: "DUMMY_SECRET" -}; diff --git a/nft-taquito/backend/src/index.ts b/nft-taquito/backend/src/index.ts deleted file mode 100644 index 75b0563..0000000 --- a/nft-taquito/backend/src/index.ts +++ /dev/null @@ -1,107 +0,0 @@ -import express from "express"; -import pinataSDK from "@pinata/sdk"; -import fs from "fs"; -const cors = require("cors"); -const multer = require("multer"); - -const app = express(); -const upload = multer({ dest: "uploads/" }); -const port = process.env.NODE_ENV === "production" ? process.env.PORT : 8080; // default port to listen -let pinata: any; -if (process.env.NODE_ENV === "production") { - pinata = new pinataSDK( - process.env.PINATA_API_KEY, - process.env.PINATA_SECRET_KEY - ); -} else { - const PinataKeys = require("./PinataKeys").default; - pinata = new pinataSDK(PinataKeys.apiKey, PinataKeys.apiSecret); -} - -const corsOptions = { - origin: ["http://localhost:5173", "https://my-cool-nft-app.com"], - optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204 -}; -app.use(cors(corsOptions)); -app.use(express.json({ limit: "50mb" })); -app.use( - express.urlencoded({ limit: "50mb", extended: true, parameterLimit: 50000 }) -); - -// defines a route handler for the default home page -app.get("/", (req, res) => { - res.send("Hello developers!"); -}); - -// handles minting -app.post("/mint", upload.single("image"), async (req, res) => { - const multerReq = req as any; - //console.log(multerReq.file, req.body); - if (!multerReq.file) { - res.status(500).json({ status: false, msg: "no file provided" }); - } else { - const fileName = multerReq.file.filename; - // tests Pinata authentication - await pinata - .testAuthentication() - .catch((err: any) => res.status(500).json(JSON.stringify(err))); - // creates readable stream - const readableStreamForFile = fs.createReadStream(`./uploads/${fileName}`); - const options: any = { - pinataMetadata: { - name: req.body.title.replace(/\s/g, "-"), - keyvalues: { - description: req.body.description - } - } - }; - const pinnedFile = await pinata.pinFileToIPFS( - readableStreamForFile, - options - ); - if (pinnedFile.IpfsHash && pinnedFile.PinSize > 0) { - // remove file from server - fs.unlinkSync(`./uploads/${fileName}`); - // pins metadata - const metadata = { - name: req.body.title, - description: req.body.description, - symbol: "TUT", - artifactUri: `ipfs://${pinnedFile.IpfsHash}`, - displayUri: `ipfs://${pinnedFile.IpfsHash}`, - creators: [req.body.creator], - decimals: 0, - thumbnailUri: "https://tezostaquito.io/img/favicon.png", - is_transferable: true, - shouldPreferSymbol: false - }; - - const pinnedMetadata = await pinata.pinJSONToIPFS(metadata, { - pinataMetadata: { - name: "TUT-metadata" - } - }); - - if (pinnedMetadata.IpfsHash && pinnedMetadata.PinSize > 0) { - res.status(200).json({ - status: true, - msg: { - imageHash: pinnedFile.IpfsHash, - metadataHash: pinnedMetadata.IpfsHash - } - }); - } else { - res - .status(500) - .json({ status: false, msg: "metadata were not pinned" }); - } - } else { - res.status(500).json({ status: false, msg: "file was not pinned" }); - } - } -}); - -// starts the Express server -app.listen(port, () => { - console.log(`server started at http://localhost:${port}`); -}); diff --git a/nft-taquito/backend/src/types.ts b/nft-taquito/backend/src/types.ts deleted file mode 100644 index c386359..0000000 --- a/nft-taquito/backend/src/types.ts +++ /dev/null @@ -1,15 +0,0 @@ -export interface NFT { - name: string; - description: string; - symbol: string; - decimals: number; - artifactUri: string; - displayUri: string; - thumbnailUri: string; - creators: string[]; - is_transferable: boolean; - lastUpdate: number; - formats: { uri: string; mimeType: string }[]; - isBooleanAmount: boolean; - shouldPreferSymbol: boolean; -} diff --git a/nft-taquito/backend/tsconfig.json b/nft-taquito/backend/tsconfig.json deleted file mode 100644 index 35cc4e4..0000000 --- a/nft-taquito/backend/tsconfig.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "esModuleInterop": true, - "target": "es6", - "noImplicitAny": true, - "moduleResolution": "node", - "sourceMap": true, - "outDir": "dist", - "baseUrl": ".", - "paths": { - "*": ["node_modules/*"] - } - }, - "include": ["src/**/*"] -} diff --git a/nft-taquito/contract/NFTS_contract.mligo b/nft-taquito/contract/NFTS_contract.mligo deleted file mode 100644 index 2348fcc..0000000 --- a/nft-taquito/contract/NFTS_contract.mligo +++ /dev/null @@ -1,541 +0,0 @@ -(** -Implementation of the FA2 interface for the NFT contract supporting multiple -types of NFTs. Each NFT type is represented by the range of token IDs - `token_def`. - *) - -type token_id = nat - -type transfer_destination = -[@layout:comb] -{ - to_ : address; - token_id : token_id; - amount : nat; -} - -type transfer = -[@layout:comb] -{ - from_ : address; - txs : transfer_destination list; -} - -type balance_of_request = -[@layout:comb] -{ - owner : address; - token_id : token_id; -} - -type balance_of_response = -[@layout:comb] -{ - request : balance_of_request; - balance : nat; -} - -type balance_of_param = -[@layout:comb] -{ - requests : balance_of_request list; - callback : (balance_of_response list) contract; -} - -type operator_param = -[@layout:comb] -{ - owner : address; - operator : address; - token_id: token_id; -} - -type update_operator = -[@layout:comb] - | Add_operator of operator_param - | Remove_operator of operator_param - -type token_metadata = -[@layout:comb] -{ - token_id : token_id; - token_info : (string, bytes) map; -} - -(* -One of the options to make token metadata discoverable is to declare -`token_metadata : token_metadata_storage` field inside the FA2 contract storage -*) -type token_metadata_storage = (token_id, token_metadata) big_map - -(** -Optional type to define view entry point to expose token_metadata on chain or -as an external view - *) -type token_metadata_param = -[@layout:comb] -{ - token_ids : token_id list; - handler : (token_metadata list) -> unit; -} - -type mint_params = -[@layout:comb] -{ - link_to_metadata: bytes; - owner: address; -} - -(* - TZIP-16 contract metadata storage field type. - The contract storage MUST have a field - `metadata : contract_metadata` -*) -type contract_metadata = (string, bytes) big_map - -(* FA2 hooks interface *) - -type transfer_destination_descriptor = -[@layout:comb] -{ - to_ : address option; - token_id : token_id; - amount : nat; -} - -type transfer_descriptor = -[@layout:comb] -{ - from_ : address option; - txs : transfer_destination_descriptor list -} - -type transfer_descriptor_param = -[@layout:comb] -{ - batch : transfer_descriptor list; - operator : address; -} - -(* -Entrypoints for sender/receiver hooks - -type fa2_token_receiver = - ... - | Tokens_received of transfer_descriptor_param - -type fa2_token_sender = - ... - | Tokens_sent of transfer_descriptor_param -*) - - -(** One of the specified `token_id`s is not defined within the FA2 contract *) -let fa2_token_undefined = "FA2_TOKEN_UNDEFINED" -(** -A token owner does not have sufficient balance to transfer tokens from -owner's account -*) -let fa2_insufficient_balance = "FA2_INSUFFICIENT_BALANCE" -(** A transfer failed because of `operator_transfer_policy == No_transfer` *) -let fa2_tx_denied = "FA2_TX_DENIED" -(** -A transfer failed because `operator_transfer_policy == Owner_transfer` and it is -initiated not by the token owner -*) -let fa2_not_owner = "FA2_NOT_OWNER" -(** -A transfer failed because `operator_transfer_policy == Owner_or_operator_transfer` -and it is initiated neither by the token owner nor a permitted operator - *) -let fa2_not_operator = "FA2_NOT_OPERATOR" -(** -`update_operators` entrypoint is invoked and `operator_transfer_policy` is -`No_transfer` or `Owner_transfer` -*) -let fa2_operators_not_supported = "FA2_OPERATORS_UNSUPPORTED" -(** -Receiver hook is invoked and failed. This error MUST be raised by the hook -implementation - *) -let fa2_receiver_hook_failed = "FA2_RECEIVER_HOOK_FAILED" -(** -Sender hook is invoked and failed. This error MUST be raised by the hook -implementation - *) -let fa2_sender_hook_failed = "FA2_SENDER_HOOK_FAILED" -(** -Receiver hook is required by the permission behavior, but is not implemented by -a receiver contract - *) -let fa2_receiver_hook_undefined = "FA2_RECEIVER_HOOK_UNDEFINED" -(** -Sender hook is required by the permission behavior, but is not implemented by -a sender contract - *) -let fa2_sender_hook_undefined = "FA2_SENDER_HOOK_UNDEFINED" -(** -Reference implementation of the FA2 operator storage, config API and -helper functions -*) - - -(* - Permission policy definition. - Stored in the TZIP-16 contract metadata JSON -*) - -type operator_transfer_policy = - [@layout:comb] - | No_transfer - | Owner_transfer - | Owner_or_operator_transfer - -type owner_hook_policy = - [@layout:comb] - | Owner_no_hook - | Optional_owner_hook - | Required_owner_hook - -type custom_permission_policy = -[@layout:comb] -{ - tag : string; - config_api: address option; -} - -type permissions_descriptor = -[@layout:comb] -{ - operator : operator_transfer_policy; - receiver : owner_hook_policy; - sender : owner_hook_policy; - custom : custom_permission_policy option; -} - -(** -(owner, operator, token_id) -> unit -To be part of FA2 storage to manage permitted operators -*) -type operator_storage = ((address * (address * token_id)), unit) big_map - -(** - Updates operator storage using an `update_operator` command. - Helper function to implement `Update_operators` FA2 entrypoint -*) -let update_operators (update, storage : update_operator * operator_storage) - : operator_storage = - match update with - | Add_operator op -> - Big_map.update (op.owner, (op.operator, op.token_id)) (Some unit) storage - | Remove_operator op -> - Big_map.remove (op.owner, (op.operator, op.token_id)) storage - -(** -Validate if operator update is performed by the token owner. -@param updater an address that initiated the operation; usually `Tezos.get_sender ()`. -*) -let validate_update_operators_by_owner (update, updater : update_operator * address) - : unit = - let op = match update with - | Add_operator op -> op - | Remove_operator op -> op - in - if op.owner = updater then unit else failwith fa2_not_owner - -(** - Generic implementation of the FA2 `%update_operators` entrypoint. - Assumes that only the token owner can change its operators. - *) -let fa2_update_operators (updates, storage - : (update_operator list) * operator_storage) : operator_storage = - let updater = Tezos.get_sender () in - let process_update = (fun (ops, update : operator_storage * update_operator) -> - let _u = validate_update_operators_by_owner (update, updater) in - update_operators (update, ops) - ) in - List.fold process_update updates storage - -(** - owner * operator * token_id * ops_storage -> unit -*) -type operator_validator = (address * address * token_id * operator_storage)-> unit - -(** -Create an operator validator function based on provided operator policy. -@param tx_policy operator_transfer_policy defining the constrains on who can transfer. -@return (owner, operator, token_id, ops_storage) -> unit - *) -let make_operator_validator (tx_policy : operator_transfer_policy) : operator_validator = - let can_owner_tx, can_operator_tx = match tx_policy with - | No_transfer -> (failwith fa2_tx_denied : bool * bool) - | Owner_transfer -> true, false - | Owner_or_operator_transfer -> true, true - in - (fun (owner, operator, token_id, ops_storage - : address * address * token_id * operator_storage) -> - if can_owner_tx && owner = operator - then unit (* transfer by the owner *) - else if not can_operator_tx - then failwith fa2_not_owner (* an operator transfer not permitted by the policy *) - else if Big_map.mem (owner, (operator, token_id)) ops_storage - then unit (* the operator is permitted for the token_id *) - else failwith fa2_not_operator (* the operator is not permitted for the token_id *) - ) - -(** -Default implementation of the operator validation function. -The default implicit `operator_transfer_policy` value is `Owner_or_operator_transfer` - *) -let default_operator_validator : operator_validator = - (fun (owner, operator, token_id, ops_storage - : address * address * token_id * operator_storage) -> - if owner = operator - then unit (* transfer by the owner *) - else if Big_map.mem (owner, (operator, token_id)) ops_storage - then unit (* the operator is permitted for the token_id *) - else failwith fa2_not_operator (* the operator is not permitted for the token_id *) - ) - -(** -Validate operators for all transfers in the batch at once -@param tx_policy operator_transfer_policy defining the constrains on who can transfer. -*) -let validate_operator (tx_policy, txs, ops_storage - : operator_transfer_policy * (transfer list) * operator_storage) : unit = - let validator = make_operator_validator tx_policy in - List.iter (fun (tx : transfer) -> - List.iter (fun (dst: transfer_destination) -> - validator (tx.from_, Tezos.get_sender (), dst.token_id ,ops_storage) - ) tx.txs - ) txs - -(* range of nft tokens *) -type token_def = -[@layout:comb] -{ - from_ : nat; - to_ : nat; -} - -type nft_meta = (token_def, token_metadata) big_map - -type token_storage = { - token_defs : token_def set; - next_token_id : token_id; - metadata : nft_meta; -} - -type ledger = (token_id, address) big_map -type reverse_ledger = (address, token_id list) big_map - -type nft_token_storage = { - ledger : ledger; - operators : operator_storage; - reverse_ledger: reverse_ledger; - metadata: (string, bytes) big_map; - token_metadata: token_metadata_storage; - next_token_id: token_id; - admin: address; -} - -type return_value = operation list * nft_token_storage - -(** -Retrieve the balances for the specified tokens and owners -@return callback operation -*) -let get_balance (p, ledger : balance_of_param * ledger) : operation = - let to_balance = fun (r : balance_of_request) -> - let owner = Big_map.find_opt r.token_id ledger in - match owner with - | None -> (failwith fa2_token_undefined : balance_of_response) - | Some o -> - let bal = if o = r.owner then 1n else 0n in - { request = r; balance = bal; } - in - let responses = List.map to_balance p.requests in - Tezos.transaction responses 0mutez p.callback - -(** -Update ledger balances according to the specified transfers. Fails if any of the -permissions or constraints are violated. -@param txs transfers to be applied to the ledger -@param validate_op function that validates of the tokens from the particular owner can be transferred. - *) -let transfer_nfts (txs, validate_op, ops_storage, ledger, reverse_ledger - : (transfer list) * operator_validator * operator_storage * ledger * reverse_ledger) : ledger * reverse_ledger = - (* process individual transfer *) - let make_transfer = (fun ((l, rv_l), tx : (ledger * reverse_ledger) * transfer) -> - List.fold - (fun ((ll, rv_ll), dst : (ledger * reverse_ledger) * transfer_destination) -> - if dst.amount = 0n - then ll, rv_ll - else if dst.amount <> 1n - then (failwith fa2_insufficient_balance : ledger * reverse_ledger) - else - let owner = Big_map.find_opt dst.token_id ll in - match owner with - | None -> (failwith fa2_token_undefined : ledger * reverse_ledger) - | Some o -> - if o <> tx.from_ - then (failwith fa2_insufficient_balance : ledger * reverse_ledger) - else - begin - let _u = validate_op (o, Tezos.get_sender (), dst.token_id, ops_storage) in - let new_ll = Big_map.update dst.token_id (Some dst.to_) ll in - (* removes token id from sender *) - let new_rv_ll = - match Big_map.find_opt tx.from_ rv_ll with - | None -> (failwith fa2_insufficient_balance : reverse_ledger) - | Some tk_id_l -> - Big_map.update - tx.from_ - (Some (List.fold ( - fun (new_list, token_id: token_id list * token_id) -> - if token_id = dst.token_id - then new_list - else token_id :: new_list - ) tk_id_l ([]: token_id list))) - rv_ll - in - (* adds token id to recipient *) - let updated_rv_ll = - match Big_map.find_opt dst.to_ new_rv_ll with - | None -> Big_map.add dst.to_ [dst.token_id] new_rv_ll - | Some tk_id_l -> Big_map.update dst.to_ (Some (dst.token_id :: tk_id_l)) new_rv_ll in - - new_ll, updated_rv_ll - end - ) tx.txs (l, rv_l) - ) - in - - List.fold make_transfer txs (ledger, reverse_ledger) - -(** Finds a definition of the token type (token_id range) associated with the provided token id *) -let find_token_def (tid, token_defs : token_id * (token_def set)) : token_def = - let tdef = Set.fold (fun (res, d : (token_def option) * token_def) -> - match res with - | Some _ -> res - | None -> - if tid >= d.from_ && tid < d.to_ - then Some d - else (None : token_def option) - ) token_defs (None : token_def option) - in - match tdef with - | None -> (failwith fa2_token_undefined : token_def) - | Some d -> d - -let get_metadata (tokens, meta : (token_id list) * token_storage ) - : token_metadata list = - List.map (fun (tid: token_id) -> - let tdef = find_token_def (tid, meta.token_defs) in - let meta = Big_map.find_opt tdef meta.metadata in - match meta with - | Some m -> { m with token_id = tid; } - | None -> (failwith "NO_DATA" : token_metadata) - ) tokens - -let mint (p, s: mint_params * nft_token_storage): nft_token_storage = - let { link_to_metadata; owner } = p in - let token_id = s.next_token_id in - (* Updates the ledger *) - let new_ledger = Big_map.add token_id owner s.ledger in - (* Updates the reverse ledger *) - let new_reverse_ledger = - match Big_map.find_opt owner s.reverse_ledger with - | None -> Big_map.add owner [token_id] s.reverse_ledger - | Some l -> Big_map.update owner (Some (token_id :: l)) s.reverse_ledger in - (* Stores the metadata *) - let new_entry = { token_id = token_id; token_info = Map.literal [("", link_to_metadata)] } in - - { - s with - ledger = new_ledger; - reverse_ledger = new_reverse_ledger; - token_metadata = Big_map.add token_id new_entry s.token_metadata; - next_token_id = token_id + 1n; - } - -let burn (p, s: token_id * nft_token_storage): nft_token_storage = - (* removes token from the ledger *) - let new_ledger: ledger = - match Big_map.find_opt p s.ledger with - | None -> (failwith "UNKNOWN_TOKEN": ledger) - | Some owner -> - if owner <> Tezos.get_sender () - then (failwith "NOT_TOKEN_OWNER": ledger) - else - Big_map.remove p s.ledger - in - (* removes token from the reverse ledger *) - let new_reverse_ledger: reverse_ledger = - let sender = Tezos.get_sender () in - - match Big_map.find_opt sender s.reverse_ledger with - | None -> (failwith "NOT_A_USER": reverse_ledger) - | Some tk_id_l -> - Big_map.update - sender - (Some (List.fold ( - fun (new_list, token_id: token_id list * token_id) -> - if token_id = p - then new_list - else token_id :: new_list - ) tk_id_l ([]: token_id list))) - s.reverse_ledger - in { s with ledger = new_ledger; reverse_ledger = new_reverse_ledger } - -(** entrypoints *) - -(** Transfer entrypoint *) -[@entry] -let transfer (txs : transfer list) (storage : nft_token_storage) : return_value = - let (new_ledger, new_reverse_ledger) = transfer_nfts - (txs, default_operator_validator, storage.operators, storage.ledger, storage.reverse_ledger) in - let new_storage = { storage with ledger = new_ledger; reverse_ledger = new_reverse_ledger } in - ([] : operation list), new_storage - -(** Balance entrypoint *) -[@entry] -let balance_of (p : balance_of_param) (storage : nft_token_storage) : return_value = - let op = get_balance (p, storage.ledger) in - [op], storage - -(** Update operators entrypoint *) -[@entry] -let update_operators (updates : update_operator list) (storage : nft_token_storage) : return_value = - let new_ops = fa2_update_operators (updates, storage.operators) in - let new_storage = { storage with operators = new_ops; } in - ([] : operation list), new_storage - -(** Mint NFT entrypoint *) -[@entry] -let mint (p : mint_params) (storage : nft_token_storage) : return_value = - ([]: operation list), mint (p, storage) - -(** Burn NFT entrypoint *) -[@entry] -let burn (p : token_id) (storage : nft_token_storage) : return_value = - ([]: operation list), burn (p, storage) - -(* - -{ - ledger = (Big_map.empty: (token_id, address) big_map); - operators = (Big_map.empty: ((address * (address * token_id)), unit) big_map); - reverse_ledger = (Big_map.empty: (address, token_id list) big_map); - metadata = Big_map.literal [ - ("", Bytes.pack("tezos-storage:contents")); - ("contents", ("7b2276657273696f6e223a2276312e302e30222c226e616d65223a2254555473222c22617574686f7273223a5b2240636c617564656261726465225d2c22696e7465726661636573223a5b22545a49502d303132222c22545a49502d303136225d7d": bytes)) - ]; - token_metadata = (Big_map.empty: (token_id, token_metadata) big_map); - next_token_id = 0n; - admin = ("tz1Me1MGhK7taay748h4gPnX2cXvbgL6xsYL": address); -} - -{"version":"v1.0.0","name":"TUTs","authors":["@claudebarde"],"interfaces":["TZIP-012","TZIP-016"]} - - -*) \ No newline at end of file diff --git a/nft-taquito/frontend/index.html b/nft-taquito/frontend/index.html deleted file mode 100644 index 60e29b4..0000000 --- a/nft-taquito/frontend/index.html +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - Mint an NFT - - - - - - -
- - - diff --git a/nft-taquito/frontend/package.json b/nft-taquito/frontend/package.json deleted file mode 100644 index a595bba..0000000 --- a/nft-taquito/frontend/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "nft-taquito-pinata-tutorial", - "version": "1.0.0", - "type": "module", - "devDependencies": { - "@sveltejs/vite-plugin-svelte": "^2.0.2", - "@tsconfig/svelte": "^3.0.0", - "svelte": "^3.55.1", - "svelte-check": "^3.0.3", - "svelte-preprocess": "^5.0.1", - "tslib": "^2.5.0", - "typescript": "^4.9.5", - "vite": "^4.1.1" - }, - "scripts": { - "dev": "vite", - "build": "vite build", - "serve": "vite preview", - "check": "svelte-check --tsconfig ./tsconfig.json" - }, - "dependencies": { - "@airgap/beacon-sdk": "^3.3.2", - "@taquito/beacon-wallet": "^15.1.0", - "@taquito/taquito": "^15.1.0", - "@taquito/utils": "^15.1.0", - "file-loader": "^6.2.0", - "sass": "^1.67.0", - "vite-compatible-readable-stream": "^3.6.1" - } -} diff --git a/nft-taquito/frontend/public/Roman-SD.ttf b/nft-taquito/frontend/public/Roman-SD.ttf deleted file mode 100644 index 2a2a0cef290d7cb48c430198e73ade9e7af1db83..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 50408 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 T00000v+y4h00000#=|zLWt3nu diff --git a/nft-taquito/frontend/public/images/taquito.png b/nft-taquito/frontend/public/images/taquito.png deleted file mode 100644 index 292cd8d1f896daf3dad62abd6b50a9d30137edcc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35018 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

`0#)|zr-Lf?*HPh@F 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 - import { onMount } from "svelte"; - import { TezosToolkit, MichelCodecPacker } from "@taquito/taquito"; - import { char2Bytes, bytes2Char } from "@taquito/utils"; - import { BeaconWallet } from "@taquito/beacon-wallet"; - import { NetworkType } from "@airgap/beacon-sdk"; - - let Tezos: TezosToolkit; - let wallet: BeaconWallet; - const walletOptions = { - name: "Create NFTs", - preferredNetwork: NetworkType.GHOSTNET - }; - let userAddress: string; - let files, title, description; - - if (process.env.NODE_ENV === "dev") { - title = "uranus"; - description = "this is Uranus"; - } - - const rpcUrl = "https://ghostnet.ecadinfra.com"; - const serverUrl = - process.env.NODE_ENV !== "production" - ? "http://localhost:8080" - : "https://my-cool-backend-app.com"; - const contractAddress = "KT1VbJAzSAHQMvf5HC9zfEVMPbT2UcBvaMXb"; - let nftStorage = undefined; - let userNfts: { tokenId: number; ipfsHash: string }[] = []; - let pinningMetadata = false; - let mintingToken = false; - let newNft: - | undefined - | { imageHash: string; metadataHash: string; opHash: string }; - - const getUserNfts = async (address: string) => { - // finds user's NFTs - const contract = await Tezos.wallet.at(contractAddress); - nftStorage = await contract.storage(); - const getTokenIds = await nftStorage.reverse_ledger.get(address); - if (getTokenIds) { - userNfts = await Promise.all([ - ...getTokenIds.map(async id => { - const tokenId = id.toNumber(); - const metadata = await nftStorage.token_metadata.get(tokenId); - const tokenInfoBytes = metadata.token_info.get(""); - const tokenInfo = bytes2Char(tokenInfoBytes); - return { - tokenId, - ipfsHash: - tokenInfo.slice(0, 7) === "ipfs://" ? tokenInfo.slice(7) : null - }; - }) - ]); - } - }; - - const connect = async () => { - if (!wallet) { - wallet = new BeaconWallet(walletOptions); - } - - try { - await wallet.requestPermissions({ - network: { - type: NetworkType.GHOSTNET, - rpcUrl - } - }); - userAddress = await wallet.getPKH(); - Tezos.setWalletProvider(wallet); - await getUserNfts(userAddress); - } catch (err) { - console.error(err); - } - }; - - const disconnect = () => { - wallet.client.destroy(); - wallet = undefined; - userAddress = ""; - }; - - const upload = async () => { - try { - pinningMetadata = true; - const data = new FormData(); - data.append("image", files[0]); - data.append("title", title); - data.append("description", description); - data.append("creator", userAddress); - - const response = await fetch(`${serverUrl}/mint`, { - method: "POST", - headers: { - "Access-Control-Allow-Origin": "*" - }, - body: data - }); - if (response) { - const data = await response.json(); - if ( - data.status === true && - data.msg.metadataHash && - data.msg.imageHash - ) { - pinningMetadata = false; - mintingToken = true; - // saves NFT on-chain - const contract = await Tezos.wallet.at(contractAddress); - const op = await contract.methods - .mint(char2Bytes("ipfs://" + data.msg.metadataHash), userAddress) - .send(); - console.log("Op hash:", op.opHash); - await op.confirmation(); - - newNft = { - imageHash: data.msg.imageHash, - metadataHash: data.msg.metadataHash, - opHash: op.opHash - }; - - files = undefined; - title = ""; - description = ""; - - // refreshes storage - await getUserNfts(userAddress); - } else { - throw "No IPFS hash"; - } - } else { - throw "No response"; - } - } catch (error) { - console.log(error); - } finally { - pinningMetadata = false; - mintingToken = false; - } - }; - - onMount(async () => { - Tezos = new TezosToolkit(rpcUrl); - Tezos.setPackerProvider(new MichelCodecPacker()); - wallet = new BeaconWallet(walletOptions); - if (await wallet.client.getActiveAccount()) { - userAddress = await wallet.getPKH(); - Tezos.setWalletProvider(wallet); - await getUserNfts(userAddress); - } - }); - - - - -

-
-

Create NFTs

- {#if userAddress} -
-
- Your NFTs: - {#if nftStorage} - [ {#each userNfts.reverse() as nft, index} - - {nft.tokenId} - - {#if index < userNfts.length - 1} - - {/if} - {/each} ] - {/if} -
-
- -
- {#if newNft} -
Your NFT has been successfully minted!
- - - -
- -
- {:else} -
-
Select your picture
-
- -
-
- -
-
-