diff --git a/solana/Dockerfile b/solana/Dockerfile new file mode 100644 index 0000000..af94ff7 --- /dev/null +++ b/solana/Dockerfile @@ -0,0 +1,45 @@ +FROM ubuntu:latest + +# Éviter les prompts interactifs +ENV DEBIAN_FRONTEND=noninteractive +ENV TZ=Europe/Paris + +# Installer les dépendances système +RUN apt-get update && apt-get install -y \ + curl \ + wget \ + gnupg2 \ + build-essential \ + pkg-config \ + libssl-dev \ + libudev-dev \ + usbutils \ + git \ + nano \ + htop \ + && rm -rf /var/lib/apt/lists/* + +# Installer Rust +RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y +ENV PATH="/root/.cargo/bin:${PATH}" +RUN rustup component add rustfmt clippy + +# Installer Solana CLI (dernière version stable) +RUN sh -c "$(curl -sSfL https://release.anza.xyz/stable/install)" && \ + echo 'export PATH="/root/.local/share/solana/install/active_release/bin:$PATH"' >> ~/.bashrc + +# Ajouter Solana au PATH immédiatement +ENV PATH="/root/.local/share/solana/install/active_release/bin:${PATH}" + +# Installer SPL Token CLI +RUN cargo install spl-token-cli +RUN cargo install mpl-token-metadata-cli +# Vérifier les installations +RUN solana --version && spl-token --version && rustc --version + +# Créer dossier de travail +WORKDIR /solana-dev +VOLUME ["/solana-dev"] + +# Par défaut : shell interactif avec Solana prêt +CMD ["/bin/bash"] diff --git a/solana/NFT/beasts/Beasts.psd b/solana/NFT/beasts/Beasts.psd new file mode 100644 index 0000000..7b9bdd1 Binary files /dev/null and b/solana/NFT/beasts/Beasts.psd differ diff --git a/solana/NFT/beasts/generate.js b/solana/NFT/beasts/generate.js new file mode 100644 index 0000000..832ee57 --- /dev/null +++ b/solana/NFT/beasts/generate.js @@ -0,0 +1,91 @@ +const { createCanvas, loadImage } = require('canvas'); +const fs = require('fs'); + +const width = 1000; +const height = 1000; +const canvas = createCanvas(width, height); +const ctx = canvas.getContext('2d'); + +// Configuration des calques et de la rareté (poids) +const layers = [ + { + name: "Background", + elements: [ + { name: "Island", file: "Island.png", weight: 20 }, + { name: "Jungle", file: "Jungle.png", weight: 35 }, + { name: "Mountain", file: "Mountain.png", weight: 15 }, + { name: "Plain", file: "Plain.png", weight: 25 }, + { name: "Jurrasic", file: "Jurrasic.png", weight: 5 } + ] + }, + { + name: "beasts", + elements: [ + { name: "Flicko", file: "Flicko.png", weight: 20 }, + { name: "Darm", file: "Darm.png", weight: 15 }, + { name: "Shiny Darm", file: "Shiny Darm.png", weight: 5 }, + { name: "Marven", file: "Marven.png", weight: 20 }, + { name: "Jii", file: "Jii.png", weight: 20 }, + { name: "Tiro", file: "Tiro.png", weight: 15 }, + { name: "Shiny Tiro", file: "Shiny Tiro.png", weight: 5 }, + ] + }, + { + name: "hat", + elements: [ + { name: "No hat", file: "No hat.png", weight: 35 }, + { name: "Cap", file: "Cap.png", weight: 25 }, + { name: "Fish", file: "Fish.png", weight: 10 }, + { name: "Magic", file: "Magic.png", weight: 30 }, + { name: "Pirate", file: "Pirate.png", weight: 20 } + ] + } +]; + +// Fonction pour choisir un élément selon son poids (Rareté) +function pickElement(layer) { + let totalWeight = layer.elements.reduce((acc, el) => acc + el.weight, 0); + let random = Math.random() * totalWeight; + for (let el of layer.elements) { + if (random < el.weight) return el; + random -= el.weight; + } +} + +async function createNFT(editionId) { + let attributes = []; + ctx.clearRect(0, 0, width, height); + + // 1. Sélectionner et dessiner chaque calque + for (const layer of layers) { + const element = pickElement(layer); + const image = await loadImage(`./layers/${layer.name}/${element.file}`); + ctx.drawImage(image, 0, 0, width, height); + + attributes.push({ trait_type: layer.name, value: element.name }); + } + + // 2. Sauvegarder l'image finale + const buffer = canvas.toBuffer('image/png'); + fs.writeFileSync(`./output/${editionId}.png`, buffer); + + // 3. Créer le fichier JSON Metadata (Standard Solana/Metaplex) + const metadata = { + name: `Beast #${editionId}`, + symbol: "BSTS", + image: `${editionId}.png`, // Sera remplacé par l'URL IPFS plus tard + attributes: attributes, + properties: { + files: [{ uri: `${editionId}.png`, type: "image/png" }] + } + }; + fs.writeFileSync(`./output/${editionId}.json`, JSON.stringify(metadata, null, 2)); +} + +// Générer 10 NFTs +(async () => { + for (let i = 1; i <= 20; i++) { + await createNFT(i); + console.log(`NFT ${i} généré !`); + } +})(); \ No newline at end of file diff --git a/solana/NFT/beasts/layers/Background/Island.png b/solana/NFT/beasts/layers/Background/Island.png new file mode 100644 index 0000000..56886b7 Binary files /dev/null and b/solana/NFT/beasts/layers/Background/Island.png differ diff --git a/solana/NFT/beasts/layers/Background/Jungle.png b/solana/NFT/beasts/layers/Background/Jungle.png new file mode 100644 index 0000000..0da84a0 Binary files /dev/null and b/solana/NFT/beasts/layers/Background/Jungle.png differ diff --git a/solana/NFT/beasts/layers/Background/Jurrasic.png b/solana/NFT/beasts/layers/Background/Jurrasic.png new file mode 100644 index 0000000..2c30074 Binary files /dev/null and b/solana/NFT/beasts/layers/Background/Jurrasic.png differ diff --git a/solana/NFT/beasts/layers/Background/Mountain.png b/solana/NFT/beasts/layers/Background/Mountain.png new file mode 100644 index 0000000..2d071fb Binary files /dev/null and b/solana/NFT/beasts/layers/Background/Mountain.png differ diff --git a/solana/NFT/beasts/layers/Background/Plain.png b/solana/NFT/beasts/layers/Background/Plain.png new file mode 100644 index 0000000..9106060 Binary files /dev/null and b/solana/NFT/beasts/layers/Background/Plain.png differ diff --git a/solana/NFT/beasts/layers/beasts/Darm.png b/solana/NFT/beasts/layers/beasts/Darm.png new file mode 100644 index 0000000..727167e Binary files /dev/null and b/solana/NFT/beasts/layers/beasts/Darm.png differ diff --git a/solana/NFT/beasts/layers/beasts/Flicko.png b/solana/NFT/beasts/layers/beasts/Flicko.png new file mode 100644 index 0000000..f4ca5ae Binary files /dev/null and b/solana/NFT/beasts/layers/beasts/Flicko.png differ diff --git a/solana/NFT/beasts/layers/beasts/Jii.png b/solana/NFT/beasts/layers/beasts/Jii.png new file mode 100644 index 0000000..f756507 Binary files /dev/null and b/solana/NFT/beasts/layers/beasts/Jii.png differ diff --git a/solana/NFT/beasts/layers/beasts/Marven.png b/solana/NFT/beasts/layers/beasts/Marven.png new file mode 100644 index 0000000..537d6cc Binary files /dev/null and b/solana/NFT/beasts/layers/beasts/Marven.png differ diff --git a/solana/NFT/beasts/layers/beasts/Shiny Darm.png b/solana/NFT/beasts/layers/beasts/Shiny Darm.png new file mode 100644 index 0000000..9ccada7 Binary files /dev/null and b/solana/NFT/beasts/layers/beasts/Shiny Darm.png differ diff --git a/solana/NFT/beasts/layers/beasts/Shiny Tiro.png b/solana/NFT/beasts/layers/beasts/Shiny Tiro.png new file mode 100644 index 0000000..4dfd9fd Binary files /dev/null and b/solana/NFT/beasts/layers/beasts/Shiny Tiro.png differ diff --git a/solana/NFT/beasts/layers/beasts/Tiro.png b/solana/NFT/beasts/layers/beasts/Tiro.png new file mode 100644 index 0000000..9dd400c Binary files /dev/null and b/solana/NFT/beasts/layers/beasts/Tiro.png differ diff --git a/solana/NFT/beasts/layers/hat/Cap.png b/solana/NFT/beasts/layers/hat/Cap.png new file mode 100644 index 0000000..e6a4a6f Binary files /dev/null and b/solana/NFT/beasts/layers/hat/Cap.png differ diff --git a/solana/NFT/beasts/layers/hat/Christmas.png b/solana/NFT/beasts/layers/hat/Christmas.png new file mode 100644 index 0000000..46e32f7 Binary files /dev/null and b/solana/NFT/beasts/layers/hat/Christmas.png differ diff --git a/solana/NFT/beasts/layers/hat/Fish.png b/solana/NFT/beasts/layers/hat/Fish.png new file mode 100644 index 0000000..8b8a74a Binary files /dev/null and b/solana/NFT/beasts/layers/hat/Fish.png differ diff --git a/solana/NFT/beasts/layers/hat/Magic.png b/solana/NFT/beasts/layers/hat/Magic.png new file mode 100644 index 0000000..5c26c9e Binary files /dev/null and b/solana/NFT/beasts/layers/hat/Magic.png differ diff --git a/solana/NFT/beasts/layers/hat/No hat.png b/solana/NFT/beasts/layers/hat/No hat.png new file mode 100644 index 0000000..381896e Binary files /dev/null and b/solana/NFT/beasts/layers/hat/No hat.png differ diff --git a/solana/NFT/beasts/layers/hat/Pirate.png b/solana/NFT/beasts/layers/hat/Pirate.png new file mode 100644 index 0000000..9b01e22 Binary files /dev/null and b/solana/NFT/beasts/layers/hat/Pirate.png differ diff --git a/solana/NFT/beasts/layers/hat/Viking.png b/solana/NFT/beasts/layers/hat/Viking.png new file mode 100644 index 0000000..ac4705e Binary files /dev/null and b/solana/NFT/beasts/layers/hat/Viking.png differ diff --git a/solana/NFT/beasts/package-lock.json b/solana/NFT/beasts/package-lock.json new file mode 100644 index 0000000..d1c9a52 --- /dev/null +++ b/solana/NFT/beasts/package-lock.json @@ -0,0 +1,458 @@ +{ + "name": "beasts", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "beasts", + "version": "1.0.0", + "license": "ISC", + "dependencies": { + "canvas": "^3.2.1" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/canvas": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/canvas/-/canvas-3.2.1.tgz", + "integrity": "sha512-ej1sPFR5+0YWtaVp6S1N1FVz69TQCqmrkGeRvQxZeAB1nAIcjNTHVwrZtYtWFFBmQsF40/uDLehsW5KuYC99mg==", + "hasInstallScript": true, + "license": "MIT", + "dependencies": { + "node-addon-api": "^7.0.0", + "prebuild-install": "^7.1.3" + }, + "engines": { + "node": "^18.12.0 || >= 20.9.0" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "license": "ISC" + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "license": "MIT", + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, + "node_modules/end-of-stream": { + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", + "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", + "license": "MIT", + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/expand-template": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", + "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", + "license": "(MIT OR WTFPL)", + "engines": { + "node": ">=6" + } + }, + "node_modules/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "license": "MIT" + }, + "node_modules/github-from-package": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", + "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", + "license": "MIT" + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, + "node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "license": "MIT" + }, + "node_modules/napi-build-utils": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", + "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", + "license": "MIT" + }, + "node_modules/node-abi": { + "version": "3.86.0", + "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.86.0.tgz", + "integrity": "sha512-sn9Et4N3ynsetj3spsZR729DVlGH6iBG4RiDMV7HEp3guyOW6W3S0unGpLDxT50mXortGUMax/ykUNQXdqc/Xg==", + "license": "MIT", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "license": "MIT" + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/prebuild-install": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", + "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "license": "MIT", + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/pump": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", + "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "license": "MIT", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/rc": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/semver": { + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/simple-concat": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", + "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/simple-get": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", + "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/tar-fs": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.4.tgz", + "integrity": "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==", + "license": "MIT", + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "license": "MIT", + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tunnel-agent": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", + "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "license": "MIT" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" + } + } +} diff --git a/solana/NFT/beasts/package.json b/solana/NFT/beasts/package.json new file mode 100644 index 0000000..2fbb487 --- /dev/null +++ b/solana/NFT/beasts/package.json @@ -0,0 +1,15 @@ +{ + "name": "beasts", + "version": "1.0.0", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "keywords": [], + "author": "", + "license": "ISC", + "description": "", + "dependencies": { + "canvas": "^3.2.1" + } +} diff --git a/solana/README.md b/solana/README.md new file mode 100644 index 0000000..82d7c1d --- /dev/null +++ b/solana/README.md @@ -0,0 +1,166 @@ + +# Local scripts for Solana actions + +This directory contains scripts for performing actions on the Solana blockchain. + + +## Docker + +```bash +cd solana + +# Build the image +docker build --tag solana:local . + +# Launch the image +docker run -ti solana:local /bin/bash +``` + +## Commands + +### Setup + +``` +# Vérifier les versions +solana --version +spl-token --version + +# Configurer devnet +solana config set --url https://api.devnet.solana.com + +# Créer un wallet +solana-keygen new --no-bip39-passphrase --outfile ~/.config/solana/id.json +solana config set --keypair ~/.config/solana/id.json + +# Vérifier adresse et balance +solana address +solana balance + +# Airdrop SOL sur devnet (2 SOL max par jour) +solana airdrop 2 + +``` + +### Créer le token + +```bash +root@d8bdd9efc445:/solana-dev# spl-token create-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb --enable-metadata --decimals 6 +root@d8bdd9efc445:/solana-dev# spl-token initialize-metadata "" "" "https://gateway.pinata.cloud/ipfs/ +root@d8bdd9efc445:/solana-dev# spl-token create-account +root@d8bdd9efc445:/solana-dev# spl-token mint 1000000000 +root@d8bdd9efc445:/solana-dev# spl-token accounts +root@d8bdd9efc445:/solana-dev# spl-token authorize mint --disable +root@d8bdd9efc445:/solana-dev# spl-token accounts + +``` + + +Exemple: +```bash + +# Créer ton premier token ! +root@d8bdd9efc445:/solana-dev# spl-token create-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb --enable-metadata --decimals 6 +Creating token HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM under program TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb +To initialize metadata inside the mint, please run `spl-token initialize-metadata HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM `, and sign with the mint authority. + +Address: HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM +Decimals: 9 + +Signature: 2hJ8f1D62Xs784w1yEyyv6QniWKsCUmU7iT2zfCPf2omxS1BJaewubLGrGMyKodmsZVrW2v6ySAoRipzUDfgSkV6 + +root@d8bdd9efc445:/solana-dev# spl-token initialize-metadata HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM "PSIT" "PSIT" "https://gateway.pinata.cloud/ipfs/bafkreifdhduevz3xi6hkgy7fec42flit73n2mo3itihgbiaccvgfbgiuly" + +Signature: 2QwbjKCg7KVQHRthV3zRoYNCm3m9N1RFBPjWApFjh5wV7HjDysuw6jLL4FDAEZw73wZaQa7uV48hhbFRNu1WhDyN + +root@d8bdd9efc445:/solana-dev# spl-token create-account HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM +Creating account Bkzb9daQK6urCH8Ff3SoYe1Lk9sECoCr1i85kEEPSkhz + +Signature: vpYs1RFtAZon4q3WeLaCwbjQVTua6SgsLfjp8biJit3EaYEeM2gXzcfW7VQyPb742ffGFnCdwGFhJjdPTietp5Z + +root@d8bdd9efc445:/solana-dev# spl-token mint HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM 1000000000 +Minting 1000000000 tokens + Token: HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM + Recipient: Bkzb9daQK6urCH8Ff3SoYe1Lk9sECoCr1i85kEEPSkhz + +Signature: 2Pz5ed7cAQpEg3CcfxZKCyAbwX7QoN1Ud6PAa9ZrddhtTcbqNUs4CZYWf2d1rkeAcmbtnAnygkaRZWTy99fXPAfV + +root@d8bdd9efc445:/solana-dev# spl-token accounts +Token Balance +-------------------------------------------------------- +4mookDy5M6wpzyausGhfw9EeTPpBsp9vwefb76qKBscW 100000000 +HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM 1000000000 + +root@d8bdd9efc445:/solana-dev# spl-token authorize HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM mint --disable +Updating HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM + Current mint: 7Q9y2AUAJHSzjedDZoK3XMKuGNN6GkFTbNX6J8je4UXi + New mint: disabled + +Signature: 5pZL61zAP5k3nhEUzwzd9BbddotyFA6mDBG2yY3fpxK7DzaD7wpPGVcA2kiutUA3F66c9RZgSgwSSui9ZGNhZrWz + +root@d8bdd9efc445:/solana-dev# spl-token accounts +Token Balance +-------------------------------------------------------- +4mookDy5M6wpzyausGhfw9EeTPpBsp9vwefb76qKBscW 100000000 +HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM 1000000000 + + +``` + +### Voir le token sur la blockchain +https://explorer.solana.com/address/HnaHN6Xjvb1Kvm9y8VLYDtx2sXQseXxtaRdymBtGcdRM?cluster=devnet + +### Vanity mint +```bash +# Cherche une adresse qui commence par "PSIT" +# L'option --starts-with prend le format PREFIX:NOMBRE_D_OCCURENCES +solana-keygen grind --starts-with PLEXUS:1 +# Utilise le programme Token-2022 et ton fichier forgé +spl-token create-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb --enable-metadata PSIT7xW...json +``` + +## NFT + +### Créer le parent +```bash +# 1. Créer le token avec l'extension "Group" +# On utilise --enable-group pour qu'il puisse être un parent +spl-token create-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \ + --enable-metadata \ + --enable-group \ + --decimals 0 + +# 2. Initialiser les metadata de la collection +spl-token initialize-metadata "Ma Collection PSIT" "PSIT" "https://ipfs.../collection.json" + +# 3. Initialiser le groupe (indiquer que ce NFT peut avoir 100 membres) +# Max-size 100 n'est pas obligatoire mais conseillé +spl-token initialize-group 100 + +# 4. Créer votre exemplaire unique et bloquer la création +spl-token create-account +spl-token mint 1 +spl-token authorize mint --disable +``` + +### Créer les enfants +```bash +# 1. Créer le token avec l'extension "Group Member" +spl-token create-token --program-id TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb \ + --enable-metadata \ + --enable-group-member \ + --decimals 0 + +# 2. Initialiser ses metadata propres +spl-token initialize-metadata "PSIT #1" "PSIT" "https://ipfs.../1.json" + +# 3. LIER ce NFT au parent +# On indique que ce NFT appartient au groupe +spl-token initialize-group-member + +# 4. Créer l'exemplaire et bloquer +spl-token create-account +spl-token mint 1 +spl-token authorize mint --disable +``` + + diff --git a/solana/metadata.json b/solana/metadata.json new file mode 100644 index 0000000..23c99f3 --- /dev/null +++ b/solana/metadata.json @@ -0,0 +1,15 @@ +{ + "name": "Plexus", + "symbol": "PLEXUS", + "description": "Plexus Social Club", + "image": "https://gateway.pinata.cloud/ipfs/bafybeidr4qshfwjmanxcjgvhbzjrkd4ujf4jjph25xoc7apr7rn2mfrrku", + "attributes": [], + "properties": { + "files": [ + { + "uri": "https://gateway.pinata.cloud/ipfs/bafybeidr4qshfwjmanxcjgvhbzjrkd4ujf4jjph25xoc7apr7rn2mfrrku", + "type": "image/png" + } + ] + } +} \ No newline at end of file