difftreelog
Add collection creation example
in: master
12 files changed
examples/.gitignorediffbeforeafterboth--- /dev/null
+++ b/examples/.gitignore
@@ -0,0 +1 @@
+node_modules
\ No newline at end of file
examples/package.jsondiffbeforeafterboth--- /dev/null
+++ b/examples/package.json
@@ -0,0 +1,43 @@
+{
+ "name": "SubstraPunks",
+ "version": "1.0.0",
+ "description": "Substrate Based Remake of CryptoPunks",
+ "main": "",
+ "directories": {
+ "test": "test"
+ },
+ "devDependencies": {
+ "got": "^10.7.0"
+ },
+ "scripts": {
+ "test": ""
+ },
+ "author": "",
+ "license": "Apache 2.0",
+ "homepage": "",
+ "dependencies": {
+ "bn.js": "^5.1.2",
+ "body-parser": "^1.18.3",
+ "express": "^4.17.1",
+ "express-session": "^1.17.0",
+ "fs": "^0.0.1-security",
+ "path": "^0.12.7",
+ "png-crop": "^0.0.2",
+ "@polkadot/api": "1.27.1",
+ "@polkadot/api-contract": "1.27.1",
+ "@polkadot/extension-dapp": "0.31.1",
+ "pug": "^2.0.4",
+ "sprintf-js": "^1.1.2"
+ },
+ "standard": {
+ "globals": [
+ "it",
+ "assert",
+ "beforeEach",
+ "afterEach",
+ "describe",
+ "contract",
+ "artifacts"
+ ]
+ }
+}
examples/re-fungible/collection.txtdiffbeforeafterboth--- /dev/null
+++ b/examples/re-fungible/collection.txt
@@ -0,0 +1,10 @@
+https://conv.darkbyte.ru/
+
+Artwork
+65 114 116 119 111 114 107
+
+Collection of photos
+67 111 108 108 101 99 116 105 111 110 32 111 102 32 112 104 111 116 111 115
+
+ART
+65 82 84
examples/re-fungible/config.jsdiffbeforeafterboth--- /dev/null
+++ b/examples/re-fungible/config.js
@@ -0,0 +1,19 @@
+// Local
+// const config = {
+// wsEndpoint : 'ws://127.0.0.1:9944',
+// collectionDataSize: 0,
+// decimalPoints: 4,
+
+// ownerSeed : '//Alice',
+// };
+
+// Production
+const config = {
+ wsEndpoint : 'wss://unique.usetech.com',
+ collectionDataSize: 0,
+ decimalPoints: 4,
+
+ ownerSeed : 'tunnel hair company air cage velvet egg crunch height fetch resource estate',
+};
+
+module.exports = config;
\ No newline at end of file
examples/re-fungible/create_collection.jsdiffbeforeafterboth--- /dev/null
+++ b/examples/re-fungible/create_collection.js
@@ -0,0 +1,67 @@
+const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api');
+const config = require('./config');
+const fs = require('fs');
+
+function submitTransaction(sender, transaction) {
+ return new Promise(async function(resolve, reject) {
+ try {
+ const unsub = await transaction
+ .signAndSend(sender, (result) => {
+ console.log(`Current tx status is ${result.status}`);
+
+ if (result.status.isInBlock) {
+ console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
+ resolve();
+ unsub();
+ } else if (result.status.isFinalized) {
+ console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`);
+ resolve();
+ unsub();
+ }
+ });
+ }
+ catch (e) {
+ reject(e.toString());
+ }
+ });
+}
+
+async function createCollectionAsync(api, alice) {
+ // Artwork
+ const name = [65, 114, 116, 119, 111, 114, 107];
+ // Collection of photos
+ const description = [67, 111, 108, 108, 101, 99, 116, 105, 111, 110, 32, 111, 102, 32, 112, 104, 111, 116, 111, 115];
+ // ART
+ const tokenPrefix = [65, 82, 84];
+
+ // Mode: Re-Fungible
+ const tx = api.tx.nft.createCollection(name, description, tokenPrefix, {"ReFungible": [config.collectionDataSize, config.decimalPoints]});
+ await submitTransaction(alice, tx);
+
+ const tx2 = api.tx.nft.setOffchainSchema(2, "https://ipfs-gateway.usetech.com/ipfs/QmUSv64cUmL2m44QYkUFWmH89qykC8VLPFwjhpeAScjejS/image{id}.jpg");
+ await submitTransaction(alice, tx2);
+}
+
+async function main() {
+ // Initialise the provider to connect to the node
+ const wsProvider = new WsProvider(config.wsEndpoint);
+ const rtt = JSON.parse(fs.readFileSync("runtime_types.json"));
+
+ // Create the API and wait until ready
+ const api = await ApiPromise.create({
+ provider: wsProvider,
+ types: rtt
+ });
+
+ // Owners's keypair
+ const keyring = new Keyring({ type: 'sr25519' });
+ const owner = keyring.addFromUri(config.ownerSeed);
+ console.log("Collection owner address: ", owner.address);
+
+ // Create collection as owner
+ console.log("=== Create collection ===");
+ await createCollectionAsync(api, owner);
+
+}
+
+main().catch(console.error).finally(() => process.exit());
examples/re-fungible/ipfs.txtdiffbeforeafterboth--- /dev/null
+++ b/examples/re-fungible/ipfs.txt
@@ -0,0 +1,4 @@
+https://ipfs-gateway.usetech.com/ipfs/QmUSv64cUmL2m44QYkUFWmH89qykC8VLPFwjhpeAScjejS/image{id}.jpg
+
+Orchids:
+https://ipfs-gateway.usetech.com/ipfs/QmUSv64cUmL2m44QYkUFWmH89qykC8VLPFwjhpeAScjejS/image1.jpg
\ No newline at end of file
examples/re-fungible/runtime_types.jsondiffbeforeafterbothno changes
examples/testnft/config.jsdiffbeforeafterboth--- /dev/null
+++ b/examples/testnft/config.js
@@ -0,0 +1,19 @@
+// Local
+// const config = {
+// wsEndpoint : 'ws://127.0.0.1:9944',
+// collectionDataSize: 0,
+// totalTokens: 10,
+
+// ownerSeed : '//Alice',
+// };
+
+// Testnet
+const config = {
+ wsEndpoint : 'wss://unique.usetech.com',
+ collectionDataSize: 0,
+ totalTokens: 10,
+
+ ownerSeed : 'tunnel hair company air cage velvet egg crunch height fetch resource estate',
+};
+
+module.exports = config;
\ No newline at end of file
examples/testnft/create_collection.jsdiffbeforeafterboth--- /dev/null
+++ b/examples/testnft/create_collection.js
@@ -0,0 +1,69 @@
+const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api');
+const config = require('./config');
+var BigNumber = require('bn.js');
+const fs = require('fs');
+
+function submitTransaction(sender, transaction) {
+ return new Promise(async function(resolve, reject) {
+ try {
+ const unsub = await transaction
+ .signAndSend(sender, (result) => {
+ console.log(`Current tx status is ${result.status}`);
+
+ if (result.status.isInBlock) {
+ console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
+ resolve();
+ unsub();
+ } else if (result.status.isFinalized) {
+ console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`);
+ resolve();
+ unsub();
+ }
+ });
+ }
+ catch (e) {
+ reject(e.toString());
+ }
+ });
+}
+
+async function createCollectionAsync(api, alice) {
+ // Test NFT
+ const name = [0x54, 0x65, 0x73, 0x74, 0x20, 0x4e, 0x46, 0x54];
+ // Test NFT Collection
+ const description = [0x54, 0x65, 0x73, 0x74, 0x20, 0x4e, 0x46, 0x54, 0x20, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e];
+ // TestNFT
+ const tokenPrefix = [0x54, 0x65, 0x73, 0x74, 0x4e, 0x46, 0x54];
+
+ // Mode: NFT
+ const tx = api.tx.nft.createCollection(name, description, tokenPrefix, {"NFT": config.collectionDataSize});
+ await submitTransaction(alice, tx);
+
+ const collectionId = 1;
+
+ const tx2 = api.tx.nft.setOffchainSchema(collectionId, "https://ipfs-gateway.usetech.com/ipfs/QmVdFFZjnq6i3fNDjm6FQe2tfAtUDnqMNkBh8e4sYWUmbH/images/image{id}.png");
+ await submitTransaction(alice, tx2);
+}
+
+async function main() {
+ // Initialise the provider to connect to the node
+ const wsProvider = new WsProvider(config.wsEndpoint);
+ const rtt = JSON.parse(fs.readFileSync("runtime_types.json"));
+
+ // Create the API and wait until ready
+ const api = await ApiPromise.create({
+ provider: wsProvider,
+ types: rtt
+ });
+
+ // Owners's keypair
+ const keyring = new Keyring({ type: 'sr25519' });
+ const owner = keyring.addFromUri(config.ownerSeed);
+ console.log("Collection owner address: ", owner.address);
+
+ // Create collection as owner
+ console.log("=== Create collection ===");
+ await createCollectionAsync(api, owner);
+}
+
+main().catch(console.error).finally(() => process.exit());
examples/testnft/create_tokens.jsdiffbeforeafterboth--- /dev/null
+++ b/examples/testnft/create_tokens.js
@@ -0,0 +1,77 @@
+const { ApiPromise, WsProvider, Keyring } = require('@polkadot/api');
+const config = require('./config');
+const fs = require('fs');
+
+const collectionId = 1;
+
+function checkOwner(owner) {
+ for (let i=0; i<32; i++) {
+ if (owner[i] != 0) return true;
+ }
+ return false;
+}
+
+function mintAsync(api, admin) {
+ return new Promise(async function(resolve, reject) {
+ const unsub = await api.tx.nft
+ .createItem(collectionId, "0x", admin.address)
+ .signAndSend(admin, (result) => {
+ console.log(`Current tx status is ${result.status}`);
+
+ if (result.status.isInBlock) {
+ console.log(`Transaction included at blockHash ${result.status.asInBlock}`);
+ resolve();
+ unsub();
+ } else if (result.status.isFinalized) {
+ console.log(`Transaction finalized at blockHash ${result.status.asFinalized}`);
+ resolve();
+ unsub();
+ }
+ });
+ });
+}
+
+async function main() {
+ // Initialise the provider to connect to the node
+ const wsProvider = new WsProvider(config.wsEndpoint);
+ const rtt = require("./runtime_types.json");
+
+ // Create the API and wait until ready
+ const api = await ApiPromise.create({
+ provider: wsProvider,
+ types: rtt
+ });
+
+ // Retrieve the chain & node information information via rpc calls
+ const [chain, nodeName, nodeVersion, collection] = await Promise.all([
+ api.rpc.system.chain(),
+ api.rpc.system.name(),
+ api.rpc.system.version(),
+ api.query.nft.collection(collectionId)
+ ]);
+
+ console.log(`You are connected to chain ${chain} using ${nodeName} v${nodeVersion}`);
+ console.log(`Collection: ${collection}`);
+
+ if (checkOwner(collection.Owner.toString())) {
+ // Import account from mnemonic phrase in config file
+ const keyring = new Keyring({ type: 'sr25519' });
+ const owner = keyring.addFromUri(config.ownerSeed);
+ console.log("Owner address: ", owner.address)
+
+ // Create Tokens
+ for (let i=0; i<config.totalTokens; i++) {
+ console.log(`=== Importing Token ${i+1} of ${config.totalTokens} ===`);
+
+ // Mint
+ await mintAsync(api, owner);
+ }
+
+ }
+ else {
+ console.log("\nERROR: Collection not found.\nCheck the ID and make sure you have created collection and set the admin");
+ }
+
+}
+
+main().catch(console.error).finally(() => process.exit());
examples/testnft/info.txtdiffbeforeafterboth--- /dev/null
+++ b/examples/testnft/info.txt
@@ -0,0 +1,9 @@
+Collection ID: 3
+
+
+IPFS:
+https://ipfs-gateway.usetech.com/ipfs/QmVdFFZjnq6i3fNDjm6FQe2tfAtUDnqMNkBh8e4sYWUmbH/images/image{id}.png
+
+
+
+https://conv.darkbyte.ru/
examples/testnft/runtime_types.jsondiffbeforeafterboth--- /dev/null
+++ b/examples/testnft/runtime_types.json
@@ -0,0 +1,64 @@
+{
+ "Schedule": {
+ "version": "u32",
+ "put_code_per_byte_cost": "Gas",
+ "grow_mem_cost": "Gas",
+ "regular_op_cost": "Gas",
+ "return_data_per_byte_cost": "Gas",
+ "event_data_per_byte_cost": "Gas",
+ "event_per_topic_cost": "Gas",
+ "event_base_cost": "Gas",
+ "call_base_cost": "Gas",
+ "instantiate_base_cost": "Gas",
+ "dispatch_base_cost": "Gas",
+ "sandbox_data_read_cost": "Gas",
+ "sandbox_data_write_cost": "Gas",
+ "transfer_cost": "Gas",
+ "instantiate_cost": "Gas",
+ "max_event_topics": "u32",
+ "max_stack_height": "u32",
+ "max_memory_pages": "u32",
+ "max_table_size": "u32",
+ "enable_println": "bool",
+ "max_subject_len": "u32"
+ },
+ "CollectionMode": {
+ "_enum": {
+ "Invalid": null,
+ "NFT": "u32",
+ "Fungible": "u32",
+ "ReFungible": "(u32, u32)"
+ }
+ },
+ "NftItemType": {
+ "Collection": "u64",
+ "Owner": "AccountId",
+ "Data": "Vec<u8>"
+ },
+ "Ownership": {
+ "owner": "AccountId",
+ "fraction": "u128"
+ },
+ "ReFungibleItemType": {
+ "Collection": "u64",
+ "Owner": "Vec<Ownership<AccountId>>",
+ "Data": "Vec<u8>"
+ },
+ "CollectionType": {
+ "Owner": "AccountId",
+ "Mode": "CollectionMode",
+ "Access": "u8",
+ "DecimalPoints": "u32",
+ "Name": "Vec<u16>",
+ "Description": "Vec<u16>",
+ "TokenPrefix": "Vec<u8>",
+ "CustomDataSize": "u32",
+ "OffchainSchema": "Vec<u8>",
+ "Sponsor": "AccountId",
+ "UnconfirmedSponsor": "AccountId"
+ },
+ "RawData": "Vec<u8>",
+ "Address": "AccountId",
+ "LookupSource": "AccountId",
+ "Weight": "u64"
+}
\ No newline at end of file