diff --git a/404.html b/404.html index 4b450324..6108d446 100644 --- a/404.html +++ b/404.html @@ -6,7 +6,7 @@ - + @@ -30,11 +30,11 @@ - + - + - +
tokenData
object that contains on-chain metadata for the NFT, including the token's hash and ID.The HTML document created by the Generator may look something like the following:
<html>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.9.0/p5.min.js"></script>
+ <script>
+ // Dependencies from the Art Blocks Dependency Registry injected here if populated in the Flex project
+ </script>
<script>
let tokenData = {
hash: "0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
diff --git a/creator-docs/art-blocks-101/on-chain/index.html b/creator-docs/art-blocks-101/on-chain/index.html
index 44a9defa..f4fcfa5e 100644
--- a/creator-docs/art-blocks-101/on-chain/index.html
+++ b/creator-docs/art-blocks-101/on-chain/index.html
@@ -6,7 +6,7 @@
-
+
@@ -35,11 +35,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-api/api-overview/index.html b/creator-docs/art-blocks-api/api-overview/index.html
index f4c3de96..18e1f10a 100644
--- a/creator-docs/art-blocks-api/api-overview/index.html
+++ b/creator-docs/art-blocks-api/api-overview/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,12 +33,12 @@
-
+
-
+
-
-
+
+
diff --git a/creator-docs/art-blocks-api/artblocks-viewer/index.html b/creator-docs/art-blocks-api/artblocks-viewer/index.html
index a78955ef..7fe9caf3 100644
--- a/creator-docs/art-blocks-api/artblocks-viewer/index.html
+++ b/creator-docs/art-blocks-api/artblocks-viewer/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-api/entities/index.html b/creator-docs/art-blocks-api/entities/index.html
index 758c3c1d..28a62607 100644
--- a/creator-docs/art-blocks-api/entities/index.html
+++ b/creator-docs/art-blocks-api/entities/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-api/queries/index.html b/creator-docs/art-blocks-api/queries/index.html
index aa89e1fe..8abe2822 100644
--- a/creator-docs/art-blocks-api/queries/index.html
+++ b/creator-docs/art-blocks-api/queries/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,12 +33,12 @@
-
+
-
+
-
-
+
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/custom-dashboard-mutations/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/custom-dashboard-mutations/index.html
index 1d07719e..44a092ea 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/custom-dashboard-mutations/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/custom-dashboard-mutations/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/embroidery-on-art-blocks-engine/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/embroidery-on-art-blocks-engine/index.html
index 300f6196..b894866d 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/embroidery-on-art-blocks-engine/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/embroidery-on-art-blocks-engine/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,12 +33,12 @@
-
+
-
+
-
-
+
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-opensea-setup/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-opensea-setup/index.html
index 40b75ce1..8a0b6783 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-opensea-setup/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-opensea-setup/index.html
@@ -6,7 +6,7 @@
-
+
@@ -35,11 +35,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-partner-onboarding-steps/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-partner-onboarding-steps/index.html
index d02c8f12..07945090 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-partner-onboarding-steps/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-partner-onboarding-steps/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-project-launch/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-project-launch/index.html
index 98de65c4..77e9c19c 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-project-launch/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-project-launch/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-royalty-registry-setup-(v2-only)/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-royalty-registry-setup-(v2-only)/index.html
index f71aaa5d..227be5e7 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-royalty-registry-setup-(v2-only)/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-royalty-registry-setup-(v2-only)/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-technical-details/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-technical-details/index.html
index 0fdb1a54..2ccd26a3 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-technical-details/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-technical-details/index.html
@@ -6,7 +6,7 @@
-
+
@@ -24,21 +24,23 @@
+
+
-
+
-
+
-
-
+
+
@@ -361,6 +363,18 @@
Your project script can then easily make use of these dependencies by combining the CID of the asset with the appropriate gateway, if you are dealing with IPFS/Arweave dependencies. As a simple example: If you have an external asset dependency with a CID QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg
and a dependencyType of IPFS
, you can construct the full url of your external asset dependency by combining the preferredIPFSGateway
, which let's assume is https://ipfs.io/ipfs/
, with the asset CID. This gives you the full url of the asset, https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg
, and allows your project script to download it with fetch
and use it as it sees fit. For fully onchain external asset dependencies, the full data string that is stored on the blockchain will be injected.
Note that for IPFS/Arweave external asset dependencies if your CID is pointing to a directory of assets, rather than a single asset, your project script will need to be aware of the file naming structure of this directory to fetch the assets individually. Using the previous example, imagine that CID QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg
was pointing to a directory of 10 PNG images, with filenames corresponding to the numbers 1-10. Your project script would generate the same full url with the information provided, https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg
, but also append the specific file you want to fetch by being aware of the naming conventions, ie https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg/1.png
.
+
+
+ #
+ Leveraging the Art Blocks Dependency Registry
+
+
+If you want to include additional libraries (e.g., Tone.js) supported by the Art Blocks Dependency Registry, you can add them to your project's external asset dependencies. Libraries that are fully on-chain will be clearly labeled in the drop-down as <script_type_and_version> (fully on-chain).
+
+
#
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/faqs/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/faqs/index.html
index 745ab35d..8d871917 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/faqs/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/faqs/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/filebase-ipfs/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/filebase-ipfs/index.html
index fa722b53..a2b0aef3 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/filebase-ipfs/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/filebase-ipfs/index.html
@@ -6,7 +6,7 @@
-
+
@@ -35,11 +35,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/index.html
index 6e55309c..d6eb33d7 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/ipfs-setup/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/ipfs-setup/index.html
index 480ab0a0..95944116 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/ipfs-setup/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/ipfs-setup/index.html
@@ -6,7 +6,7 @@
-
+
@@ -35,11 +35,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/minter-suite-migration-runbook/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/minter-suite-migration-runbook/index.html
index 25f907b0..ef73b10c 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/minter-suite-migration-runbook/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/minter-suite-migration-runbook/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/mobile-minter/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/mobile-minter/index.html
index 636e1548..860515c4 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/mobile-minter/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/mobile-minter/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/what-is-art-blocks-engine/index.html b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/what-is-art-blocks-engine/index.html
index cc70a250..30a3650b 100644
--- a/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/what-is-art-blocks-engine/index.html
+++ b/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/what-is-art-blocks-engine/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/core-contract-v3/dashboard/index.html b/creator-docs/core-contract-v3/dashboard/index.html
index 938410e1..5c1c88b1 100644
--- a/creator-docs/core-contract-v3/dashboard/index.html
+++ b/creator-docs/core-contract-v3/dashboard/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/core-contract-v3/erc2981-royalties/index.html b/creator-docs/core-contract-v3/erc2981-royalties/index.html
index 3536d98b..420f1d01 100644
--- a/creator-docs/core-contract-v3/erc2981-royalties/index.html
+++ b/creator-docs/core-contract-v3/erc2981-royalties/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/core-contract-v3/manual-admin-operations/index.html b/creator-docs/core-contract-v3/manual-admin-operations/index.html
index 8cbefa1f..4e331789 100644
--- a/creator-docs/core-contract-v3/manual-admin-operations/index.html
+++ b/creator-docs/core-contract-v3/manual-admin-operations/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/core-contract-v3/overview/index.html b/creator-docs/core-contract-v3/overview/index.html
index d19fbf59..4474623f 100644
--- a/creator-docs/core-contract-v3/overview/index.html
+++ b/creator-docs/core-contract-v3/overview/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/creator-onboarding/creators/index.html b/creator-docs/creator-onboarding/creators/index.html
index c0759829..cdaa3b83 100644
--- a/creator-docs/creator-onboarding/creators/index.html
+++ b/creator-docs/creator-onboarding/creators/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/index.html b/creator-docs/index.html
index 4166a640..d4f57a94 100644
--- a/creator-docs/index.html
+++ b/creator-docs/index.html
@@ -6,7 +6,7 @@
-
+
@@ -31,11 +31,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/minter-suite/custom-minters/index.html b/creator-docs/minter-suite/custom-minters/index.html
index e3480ac1..7dcf4bb2 100644
--- a/creator-docs/minter-suite/custom-minters/index.html
+++ b/creator-docs/minter-suite/custom-minters/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,12 +33,12 @@
-
+
-
+
-
-
+
+
diff --git a/creator-docs/minter-suite/minter-suite-supplemental/index.html b/creator-docs/minter-suite/minter-suite-supplemental/index.html
index 87d23c94..7468958d 100644
--- a/creator-docs/minter-suite/minter-suite-supplemental/index.html
+++ b/creator-docs/minter-suite/minter-suite-supplemental/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,12 +33,12 @@
-
+
-
+
-
-
+
+
diff --git a/creator-docs/minter-suite/minting-philosophy/index.html b/creator-docs/minter-suite/minting-philosophy/index.html
index addc7370..22770698 100644
--- a/creator-docs/minter-suite/minting-philosophy/index.html
+++ b/creator-docs/minter-suite/minting-philosophy/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/creator-docs/minter-suite/seadrop-integration/index.html b/creator-docs/minter-suite/seadrop-integration/index.html
index 887a2522..68aafb34 100644
--- a/creator-docs/minter-suite/seadrop-integration/index.html
+++ b/creator-docs/minter-suite/seadrop-integration/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,12 +33,12 @@
-
+
-
+
-
-
+
+
diff --git a/creator-docs/minter-suite/shared-minter-suite/index.html b/creator-docs/minter-suite/shared-minter-suite/index.html
index 42eb5401..44f33f33 100644
--- a/creator-docs/minter-suite/shared-minter-suite/index.html
+++ b/creator-docs/minter-suite/shared-minter-suite/index.html
@@ -6,7 +6,7 @@
-
+
@@ -33,11 +33,11 @@
-
+
-
+
-
+
diff --git a/index.html b/index.html
index e07f4b8b..190aa056 100644
--- a/index.html
+++ b/index.html
@@ -6,7 +6,7 @@
-
+
@@ -35,11 +35,11 @@
-
+
-
+
-
+
diff --git a/resources/js/config.js b/resources/js/config.js
index 1fa1c0b2..03518407 100644
--- a/resources/js/config.js
+++ b/resources/js/config.js
@@ -1 +1 @@
-var __DOCS_CONFIG__ = {"id":"T4WYO45rYN6nfR141ua+0Y7ubydYyT0zOtp","key":"1Kgds4sTzBBFQ+aj4VOojt2ePH2MRxjqp8mXX85s84w.fXSl9t6fPftnKsWzWl8JIOAca+0UGdAcFQIgncMn3OdwPqS+759O8EmNm6tAUDgEFbWTJwhqPUEKHpsFLoWzhw.308272","base":"/","host":"docs.artblocks.io","version":"1.0.0","useRelativePaths":true,"documentName":"index.html","appendDocumentName":false,"trailingSlash":true,"preloadSearch":false,"cacheBustingToken":"3.6.0.783110110059","cacheBustingStrategy":"query","sidebarFilterPlaceholder":"Filter","toolbarFilterPlaceholder":"Filter","showSidebarFilter":true,"filterNotFoundMsg":"No member names found containing the query \"{query}\"","maxHistoryItems":15,"homeIcon":" ","access":[{"value":"public","label":"Public"},{"value":"protected","label":"Protected"}],"toolbarLinks":[{"id":"fields","label":"Fields"},{"id":"properties","label":"Properties"},{"id":"methods","label":"Methods"},{"id":"events","label":"Events"}],"sidebar":[{"n":"/","l":"Welcome","s":" "},{"n":"/creator-docs/art-blocks-101","l":"Art Blocks 101","c":false,"o":true,"i":[{"n":"on-chain","l":"NFT Metadata Storage at Art Blocks"},{"n":"generator","l":"Art Blocks Generator"}]},{"n":"/creator-docs/art-blocks-engine-onboarding","l":"Art Blocks Engine Onboarding","c":false,"o":true,"i":[{"n":"art-blocks-engine-101","l":"Art Blocks Engine 101","i":[{"n":"what-is-art-blocks-engine","l":"What is Art Blocks Engine and Engine Flex?"},{"n":"engine-partner-onboarding-steps","l":"Engine Partner Onboarding Steps"},{"n":"engine-project-launch","l":"Engine Project Deployment and Launch Guide"},{"n":"engine-opensea-setup","l":"Art Blocks Engine OpenSea Setup"},{"n":"engine-royalty-registry-setup-(v2-only)","l":"Art Blocks Engine Royalty Registry Setup (V2 contracts only)"},{"n":"embroidery-on-art-blocks-engine","l":"Embroidery on Art Blocks Engine"},{"n":"mobile-minter","l":"Mobile Minting for In-Person Activations"},{"n":"ipfs-setup","l":"Using Pinata for External Assets"},{"n":"filebase-ipfs","l":"Using Filebase for External Assets"},{"n":"faqs","l":"FAQs"},{"n":"engine-technical-details","l":"Art Blocks Engine Flex Technical Details"},{"n":"custom-dashboard-mutations","l":"Common Custom Dashboard Mutations"},{"n":"minter-suite-migration-runbook","l":"Minter Suite Migration Runbook"}]}],"s":" "},{"n":"/creator-docs/core-contract-v3","l":"Core Contract (V3)","c":false,"o":true,"i":[{"n":"overview","l":"Overview of V3 Core Contract"},{"n":"dashboard","l":"Creator Dashboard"},{"n":"erc2981-royalties","l":"ERC-2981 Royalties"},{"n":"manual-admin-operations","l":"Manual Admin Operations"}]},{"n":"/creator-docs/creator-onboarding","l":"Creator Onboarding","c":false,"i":[{"n":"creators","l":"Moved! - Creator Onboarding Documentation"}],"s":" "},{"n":"/creator-docs/minter-suite","l":"Minter Suite","c":false,"o":true,"i":[{"n":"minting-philosophy","l":"Minting Philosophy"},{"n":"shared-minter-suite","l":"Shared Minter Suite"},{"n":"custom-minters","l":"Custom, One-Off Minters"},{"n":"minter-suite-supplemental","l":"Minter Suite Supplemental Information"},{"n":"seadrop-integration","l":"SeaDrop Integration"}]},{"n":"/creator-docs/art-blocks-api","l":"Art Blocks API","c":false,"o":true,"i":[{"n":"api-overview","l":"API Overview"},{"n":"artblocks-viewer","l":"Artblocks Viewer"},{"n":"queries","l":"Querying and API Overview"},{"n":"entities","l":"Subgraph Entities"}],"s":" "}],"search":{"mode":0,"minChars":2,"maxResults":20,"placeholder":"Search","hotkeys":["k"],"noResultsFoundMsg":"Sorry, no results found.","recognizeLanguages":true,"languages":[0],"preload":false},"resources":{"History_Title_Label":"History","History_ClearLink_Label":"Clear","History_NoHistory_Label":"No history items","API_AccessFilter_Label":"Access","API_ParameterSection_Label":"PARAMETERS","API_SignatureSection_Label":"SIGNATURE","API_CopyHint_Label":"Copy","API_CopyNameHint_Label":"Copy name","API_CopyLinkHint_Label":"Copy link","API_CopiedAckHint_Label":"Copied!","API_MoreOverloads_Label":"more","API_MoreDropdownItems_Label":"More","API_OptionalParameter_Label":"optional","API_DefaultParameterValue_Label":"Default value","API_InheritedFilter_Label":"Inherited","Search_Input_Placeholder":"Search","Toc_Contents_Label":"Contents","Toc_RelatedClasses_Label":"Related Classes","History_JustNowTime_Label":"just now","History_AgoTime_Label":"ago","History_YearTime_Label":"y","History_MonthTime_Label":"mo","History_DayTime_Label":"d","History_HourTime_Label":"h","History_MinuteTime_Label":"m","History_SecondTime_Label":"s"}};
+var __DOCS_CONFIG__ = {"id":"ywCZbbqI2In141Gx3fLYdTlUkrbiU55Dh/J","key":"0ENyMYbnXvzqGlui96Eo4bNI1ejBffk8coEP7NsyhZA.syzEBbDoP/dfzOyYMIM62iUJKeAMH7fiQhx13n6lEQebRTcV8jKIpakOJycjlkehYpU7xhT+HCANEYnILKsq/w.308281","base":"/","host":"docs.artblocks.io","version":"1.0.0","useRelativePaths":true,"documentName":"index.html","appendDocumentName":false,"trailingSlash":true,"preloadSearch":false,"cacheBustingToken":"3.6.0.783525977999","cacheBustingStrategy":"query","sidebarFilterPlaceholder":"Filter","toolbarFilterPlaceholder":"Filter","showSidebarFilter":true,"filterNotFoundMsg":"No member names found containing the query \"{query}\"","maxHistoryItems":15,"homeIcon":" ","access":[{"value":"public","label":"Public"},{"value":"protected","label":"Protected"}],"toolbarLinks":[{"id":"fields","label":"Fields"},{"id":"properties","label":"Properties"},{"id":"methods","label":"Methods"},{"id":"events","label":"Events"}],"sidebar":[{"n":"/","l":"Welcome","s":" "},{"n":"/creator-docs/art-blocks-101","l":"Art Blocks 101","c":false,"o":true,"i":[{"n":"on-chain","l":"NFT Metadata Storage at Art Blocks"},{"n":"generator","l":"Art Blocks Generator"}]},{"n":"/creator-docs/art-blocks-engine-onboarding","l":"Art Blocks Engine Onboarding","c":false,"o":true,"i":[{"n":"art-blocks-engine-101","l":"Art Blocks Engine 101","i":[{"n":"what-is-art-blocks-engine","l":"What is Art Blocks Engine and Engine Flex?"},{"n":"engine-partner-onboarding-steps","l":"Engine Partner Onboarding Steps"},{"n":"engine-project-launch","l":"Engine Project Deployment and Launch Guide"},{"n":"engine-opensea-setup","l":"Art Blocks Engine OpenSea Setup"},{"n":"engine-royalty-registry-setup-(v2-only)","l":"Art Blocks Engine Royalty Registry Setup (V2 contracts only)"},{"n":"embroidery-on-art-blocks-engine","l":"Embroidery on Art Blocks Engine"},{"n":"mobile-minter","l":"Mobile Minting for In-Person Activations"},{"n":"ipfs-setup","l":"Using Pinata for External Assets"},{"n":"filebase-ipfs","l":"Using Filebase for External Assets"},{"n":"faqs","l":"FAQs"},{"n":"engine-technical-details","l":"Art Blocks Engine Flex Technical Details"},{"n":"custom-dashboard-mutations","l":"Common Custom Dashboard Mutations"},{"n":"minter-suite-migration-runbook","l":"Minter Suite Migration Runbook"}]}],"s":" "},{"n":"/creator-docs/core-contract-v3","l":"Core Contract (V3)","c":false,"o":true,"i":[{"n":"overview","l":"Overview of V3 Core Contract"},{"n":"dashboard","l":"Creator Dashboard"},{"n":"erc2981-royalties","l":"ERC-2981 Royalties"},{"n":"manual-admin-operations","l":"Manual Admin Operations"}]},{"n":"/creator-docs/creator-onboarding","l":"Creator Onboarding","c":false,"i":[{"n":"creators","l":"Moved! - Creator Onboarding Documentation"}],"s":" "},{"n":"/creator-docs/minter-suite","l":"Minter Suite","c":false,"o":true,"i":[{"n":"minting-philosophy","l":"Minting Philosophy"},{"n":"shared-minter-suite","l":"Shared Minter Suite"},{"n":"custom-minters","l":"Custom, One-Off Minters"},{"n":"minter-suite-supplemental","l":"Minter Suite Supplemental Information"},{"n":"seadrop-integration","l":"SeaDrop Integration"}]},{"n":"/creator-docs/art-blocks-api","l":"Art Blocks API","c":false,"o":true,"i":[{"n":"api-overview","l":"API Overview"},{"n":"artblocks-viewer","l":"Artblocks Viewer"},{"n":"queries","l":"Querying and API Overview"},{"n":"entities","l":"Subgraph Entities"}],"s":" "}],"search":{"mode":0,"minChars":2,"maxResults":20,"placeholder":"Search","hotkeys":["k"],"noResultsFoundMsg":"Sorry, no results found.","recognizeLanguages":true,"languages":[0],"preload":false},"resources":{"History_Title_Label":"History","History_ClearLink_Label":"Clear","History_NoHistory_Label":"No history items","API_AccessFilter_Label":"Access","API_ParameterSection_Label":"PARAMETERS","API_SignatureSection_Label":"SIGNATURE","API_CopyHint_Label":"Copy","API_CopyNameHint_Label":"Copy name","API_CopyLinkHint_Label":"Copy link","API_CopiedAckHint_Label":"Copied!","API_MoreOverloads_Label":"more","API_MoreDropdownItems_Label":"More","API_OptionalParameter_Label":"optional","API_DefaultParameterValue_Label":"Default value","API_InheritedFilter_Label":"Inherited","Search_Input_Placeholder":"Search","Toc_Contents_Label":"Contents","Toc_RelatedClasses_Label":"Related Classes","History_JustNowTime_Label":"just now","History_AgoTime_Label":"ago","History_YearTime_Label":"y","History_MonthTime_Label":"mo","History_DayTime_Label":"d","History_HourTime_Label":"h","History_MinuteTime_Label":"m","History_SecondTime_Label":"s"}};
diff --git a/resources/js/search.json b/resources/js/search.json
index ee06aef9..f9b82d05 100644
--- a/resources/js/search.json
+++ b/resources/js/search.json
@@ -1 +1 @@
-[[{"i":"welcome-to-the-art-blocks-docs","l":"Welcome to the Art Blocks Docs!","p":["This documentation seeks to provide guidance for 3 primary audiences:","artists/creators preparing their projects to launch on Art Blocks or an Art Blocks Engine platform","current and prospective Engine partners","integrators/aggregators/marketplaces etc., looking to integrate with the Art Blocks APIs","You will find the three main sections in our documentation mirrors these three primary audiences. Please explore the docs here, and let us know if you have any questions.","For any issues with the docs, please file a bug here, or send us a PR with a suggested change!","GitPOAPs"]}],[{"i":"#","p":["An overview of different NFT metadata storage mechanisms used by Art Blocks NFTs."]},{"l":"NFT Metadata Storage at Art Blocks","p":["An overview of NFT metadata storage philosophy and implementations at Art Blocks."]},{"l":"Summary","p":["Art Blocks tokens store their metadata fully on-chain, ensuring collectors that their NFTs will always remain accessible and immutable.","For projects that require dependencies (e.g. p5js), Art Blocks provides the Art Blocks Dependency Registry, a fully on-chain software registry that can be used to optionally store dependency releases on-chain, as well as reference preferred software storage networks.","Art Blocks Engine Flex NFTs also provide the option to store metadata on decentralized storage networks, such as IPFS or Arweave, to enable larger sized assets to be used when generating outputs."]},{"l":"Overview of NFT Metadata Storage Options","p":["~ Yes","~ Yes 3","Cost","Decentralized","Decentralized Storage Network","Fully On-Chain","Guaranteed to Persist Forever 1","Hash On-Chain","High","Immutable","Low","Medium","No","No 2","No, Very Low Risk","Servers/Hosting","Software Registry","Storage Type","While all NFTs track token ownership on a blockchain, the metadata for the NFT (image or audio information, artist information, etc.) may be stored in a variety of ways. Common options include:","Yes"]},{"i":"servershosting","l":"Servers/Hosting","p":["The metadata are stored on a server or cloud hosting service, such as AWS. This is a convenient and cheap option, but it has a few drawbacks:","The metadata can be changed by the server owner, so the NFT is not immutable.","The metadata can be lost if the server goes down or an admin decides not to discontinue paying for the service.","The metadata can be censored by the server owner."]},{"l":"Hash On-Chain","p":["The hash of the metadata is stored on-chain, and the metadata is stored on a server. Storing the hash of the metadata makes the NFT immutable, while keeping it much cheaper than storing all of the metadata on-chain. However, it has a few drawbacks:","The metadata can be lost if the server goes down or an admin decides not to discontinue paying for the service.","The metadata can be censored by the server owner.","Projects such as CryptoPunks originally stored the hash of the metadata on-chain, but the metadata was stored on a server. They have since upgraded to a fully on-chain solution."]},{"l":"Decentralized Storage Network","p":["The metadata are stored on a decentralized storage network, such as IPFS or Arweave. This is a popular option, and enables the NFT to be immutable. Drawbacks include:","The metadata must remain pinned by at least one party in order to be accessible."]},{"l":"Fully On-Chain","p":["The metadata are stored on the blockchain. This is the most expensive option, but it has many advantages. The metadata are always accessible and available, as long as the NFT exists. Collectors and artists never have to worry about a token's outputs disappearing."]},{"l":"Software Registries","p":["Some NFTs (like some Art Blocks project tokens) may rely on published software libraries when generating outputs. In these cases, the NFT metadata may include information about dependencies and where to find them (e.g. \"p5js, v1.0.0 on the cdnjs software registry\"). Software registries are a special form of decentralized storage, because of the distributed nature of the software repositories and many downloads on developers' computers worldwide."]},{"l":"Art Blocks Storage Solutions"},{"l":"Art Blocks Fully On-Chain","p":["Art Blocks Flagship and Art Blocks Engine NFTs only rely on fully on-chain storage solutions, plus allowing a single dependency to be housed on a software registry. This provides an extremely high level of confidence that the NFTs will remain fully accessible and immutable for the foreseeable future.","While Art Blocks originally relied on widely used software registries to house dependencies, the Art Blocks team has since created a fully on-chain software registry called the Art Blocks Dependency Registry. The registry is fully decentralized and is used by all Art Blocks Flagship NFTs. The registry enables dependencies to be stored fully on-chain, when the gas costs are justified. Art Blocks uploaded their first dependency, p5js v1.0.0, to the registry in January 2024, retiring any doubt that projects relying on p5js@1.0.0 would ever be unable to generate their outputs in the future."]},{"l":"Engine Flex","p":["Art Blocks Engine Flex NFTs provide an additional option for storing metadata. Flex NFTs can store metadata on-chain, or they can store the metadata immutably on the IPFS or Arweave decentralized storage networks. This allows Flex NFTs to utilize larger sized assets when generating outputs, while still providing the option for fully on-chain metadata where possible."]},{"l":"Examples"},{"l":"On-Chain Script Example","p":["Let's review an example of how to retrieve the token and script metadata for the first Art Blocks Token, token zero of project 0, Chromie Squiggle by Snowfro.","Note: Newer versions of Art Blocks core contracts have different function names than the V0 Art Blocks core contract shown in this example.","While we could query the Art Blocks Subgraph or API to retrieve the metadata, we will retrieve the metadata directly from the blockchain.","Visit the original Art Blocks Core Contract on Etherscan: 0x059EDD72Cd353dF5106D2B9cC5ab83a52287aC3a","Get project 0's metadata by calling the projectDetails function with the project ID as the input parameter:","projectDetails","Get project 0's script details by calling the projectScriptInfo function with the project ID as the input parameter:","scriptDetails","Get the script javascript by calling the projectScriptByIndex function with the project ID and index 0 as the input parameter. The returned text is the javascript code that is used to generate Chromie Squiggles!","scriptByIndex","Get token 0's token hash by calling the showTokenHashes function with the token ID as the input parameter. This is the hash that is injected into the script to generate the token's unique output.","tokenHash"]},{"l":"On-Chain Dependency Example","p":["Let's review an example of how to retrieve the dependency metadata for the first Art Blocks Token, token zero of project 0, Chromie Squiggle by Snowfro.","In this case, the project uses the p5js v1.0.0 dependency, which is stored fully on-chain via the Art Blocks Dependency Registry. While we could query the Art Blocks Subgraph or API to retrieve the metadata, we will retrieve the metadata directly from the blockchain.","Visit the Art Blocks Dependency Registry on Etherscan: 0x37861f95882ACDba2cCD84F5bFc4598e2ECDDdAF","Get the dependency details by calling the getDependencyDetails function with the dependency name and version as the input parameters. At this time, we translate from the string p5@1.0.0 to its bytes representation 0x703540312e302e30:","dependencyDetails","Get the dependency code by calling the getDependencyScript function with the dependency name and version as the input parameters. We again translate to the bytes representation 0x703540312e302e30, and can increment the index to get all 10 chunks of the dependency code:","dependencyScript","And that's it! We now have all of the information we need to generate the token's output, and we can be confident that the metadata will always be available and immutable!","Note: At this time, dependency scripts are stored compressed via gzip on-chain. Updates are planned to store code that can unzip the dependencies.","As long as the blockchain network continues to exist.↩","Requires ≥1 interested party↩","Typically hash of release is published to prevent tampering/changes↩"]}],[{"i":"#","p":["Art Blocks Generator."]},{"l":"Art Blocks Generator","p":["The Art Blocks Generator combines artist scripts with token metadata to create unique generative art NFTs. This document outlines the basics of how the generator works, the structure of the token metadata, and related requirements for artist scripts."]},{"l":"HTML Document","p":["The Art Blocks Generator builds an html document that includes:","A tokenData object that contains on-chain metadata for the NFT, including the token's hash and ID.","The artist's on-chain project script","(optional) A dependency used by the script. p5js, for example, is a common dependency.","The HTML document created by the Generator may look something like the following:","An on-chain version of he Art Blocks Generator is in development, which will allow for even more robust preservation of Art Blocks projects."]},{"l":"The tokenData Object","p":["The tokenData object is injected into the html document by the Art Blocks Generator. It contains the following fields:","For Art Blocks Flex projects, the tokenData object may also include:","The dependency_type field will be one of the following values:","IPFS","ARWEAVE","ONCHAIN","ART_BLOCKS_DEPENDENCY_REGISTRY","Note that project scripts are responsible for fetching any IPFS or Arweave assets."]},{"l":"Learning More","p":["For additional technical resources and documentation, please refer to the Technical Requirements described in the help.artblocks.io documentation."]}],[{"l":"Art Blocks Engine 101","p":["** Note: ** It is possible to use multisig wallets if our client's front-end properly populates access lists in their front end, but minting from Etherscan will not work.","8.** Repeat steps 2-7 for mainnet deployment.**","A high-level process map for Art Blocks Engine onboarding.","After testnet deployment, there are two steps that may proceed in parallel.","After the above has all been performed, you should run through the following \"pre-flight\" checklist and ensure there are no loose threads:","After the complete end-to-end integration has been vetted on testnet, the above process may proceed on mainnet.","After the terms of engagement are finalized, you’ll sign the Engine service and setup agreement.","After you've set up and tested an Engine project, you can request a script audit from Art Blocks to guarantee resolution-agnosticism and determinism.","An ETA for this infrastructure integration piece will be given at the time of testnet contract deployment. On average, this will take 1 week from the time of testnet deployment.","Art Blocks will need to integrate your newly deployed testnet smart contracts with our rendering infrastructure on testnet. After that, your team will connect to the staging site https://artist-staging.artblocks.io and interact with projects on the testing network you created as if they were on Art Blocks.","Art Blocks' will deploy a set of testnet smart contracts for your team to begin integrating with.","artist website","Create a new mainnet project shell on your smart contract using addProject, and upload all project details and project script using the artist interface at https://artblocks.io.","Deploy mainnet contracts.","etc.","If a 0% margin is used during a live NFT sale, the blockchain state will likely change between a user-submitted transaction and when it's mined. Therefore, small changes in the required Gas Limit will likely result in transaction failures if the gas necessary increases.","If accepting ETH, check that the wallets are not multisig wallets like Gnosis Safe (check the minter owner, rendering provider, artist, and any additional payee).","If actions of changing max invocations are expected, test those actions.","If actions of whitelisting/removing minters are expected, test those actions.","If you need help, the Art Blocks team will help guide you through the process.","Important for mainnet: Test-mint a token in each currency that will be accepted for a project. Verify that your front end is used to successfully mint using each currency to ensure a proper end-to-end test.","In summary, mainnet deployment entails:","Integrate mainnet contracts with Art Blocks' rendering and API infrastructure.","Interested in learning about an Art Blocks Engine partnership? Email engine@artblocks.io to get the conversation started!","Mint at least one piece (mint #0) in a controlled environment on mainnet, being sure to mint in each format you plan to for your open release.","project description","Provide the following information to Art Blocks for your Engine project: 1 The admin address to own these contracts. This address controls the core contract and the minter contract. 2 The name of tokens from your contract (e.g. for Art Blocks it is \"Art Blocks\" https://etherscan.io/address/0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270#code). 3 The ticker for tokens from your contract (e.g. for Art Blocks it is \"BLOCKS\" https://etherscan.io/address/0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270#code).","the license associated with outputs","To create a new project shell, you should use the addProject method of your newly deployed Engine Core Contract. This can be done by connecting to the contract via Etherscan.","Update your mainnet website to reference deployed mainnet contracts.","Vetting includes minting in (1) each minting format, (2) from the Engine partner's frontend minting experience, and (3) while integrated with the Art Blocks' provided rendering infrastructure.","Warning: if you opt-out of this step, it may result in undiagnosed issues with the rendered outputs. An unaudited project may not conform to the Art Blocks resolution-agnostic and deterministic standards. This means outputs may differ between screen sizes, devices, and operating systems or could be different from view to view.","When using your front-end to mint, ensure at least a 10% margin is added to each transaction's estimated Gas Limit, as originated by your frontend logic.","You are now ready to sync with the Art Blocks team on planning for a launch date, which is at least 1 week from when the above steps have all been completed.","Your team can integrate your front end to allow for minting via your new Engine smart contract (using deployed Engine smart contracts).","Your team will integrate a custom web frontend with your deployed Engine smart contracts (e.g., implementing their own purchase + display flow) and with the Art Blocks API as needed. An example of frontend purchase flow logic is provided here as a reference for integrating partners:","Your team will use https://artist-staging.artblocks.io site to upload your project script source code and configure all project metadata details:"]}],[{"i":"what-is-art-blocks-engine-and-engine-flex","l":"What is Art Blocks Engine and Engine Flex?","p":["Art Blocks Engine and Engine Flex are custom branded solutions from Art Blocks. Our offerings allow the generative NFT minting technology used by artists at Art Blocks to be integrated with third-party sites.","Engine allows partners to release generative outputs using our existing smart contracts and rendering infrastructure resulting in turnkey and branded generative projects. Engine partners own their smart contracts and can use them to release as many projects as they like as often as they like.","We currently partner with organizations from every sector that are interested in launching generative collections, but are particularly interested in the fashion, sports, media, manufacturing, and fine art industries.","For more information on Art Blocks Engine partnerships please contact: info@artblocks.io"]},{"i":"what-is-the-difference-between-art-blocks-engine-and-engine-flex","l":"What is the difference between Art Blocks Engine and Engine Flex?","p":["Art Blocks Engine is our offering that aligns most closely with the Art Blocks flagship product ( https://artblocks.io), and has the same technical approach to on-chain art where artists store the entirety of their generative algorithms on-chain within the Engine smart contract and are limited to a single, widely-distributed, off-chain dependency (e.g. p5js).","With Art Blocks Engine Flex artists are able to include off-chain assets, stored on the decentralized storage solutions of IPFS or Arweave, as additional inputs into their creative coding practice. This allows, for example, a project that takes an image as an input and creates 1of1ofX outputs applying a generative practice to this input image. This final output combines a generative script, a token hash, and additional off-chain assets."]},{"i":"how-does-art-blocks-engine-flex-work","l":"How does Art Blocks Engine Flex work?","p":["With Art Blocks Engine Flex contracts, a per-project (as opposed to per-contract) field is available on all projects that allow an artist to set a single off-chain dependency or set of multiple off-chain dependencies based on the content ID locations where these dependencies are stored on IPFS or Arweave.","Currently, we do not yet support the turnkey ability to programmatically upload/pin these dependencies to IPFS/Arweave within the Engine experience directly; however, our team is more than happy to assist partners in the process of uploading/pinning assets on IPFS/Arweave using existing third party solutions for doing so (e.g. Pinata in the case of IPFS).","Note that for a single project, it is possible to have a single off-chain dependency (e.g. a single image file) or a set of off-chain dependencies (e.g. a series of images from a set). This means that is possible, for example, to have a project that creates 1of1ofX generative variants of a single base image asset, or one in which for a given token a random image is selected from the base image asset set, and then a generative process is applied to it.","It is also important to note that images are not the only supported external asset dependency type. It is possible to reference any file type that can be pinned/uploaded to IPFS or Arweave and intelligibly incorporated into a generative algorithm to create interesting artistic outputs. For example, a project could use tensorflow.js as its single-dependency, have its generative script be a tensorflow based creative coding algorithm, and store the model file for the machine learning model on IPFS or Arweave to support a ML/AI based project."]},{"i":"what-is-the-smart-contract-architecture-for-art-blocks-engine","l":"What is the smart contract architecture for Art Blocks Engine?","p":["The Art Blocks Engine offers two core contract options: the V3 Engine core contract and the V3 Engine Flex core contract. These contracts are mutually exclusive, and partners should select the appropriate core contract based on their needs and whether they require the flex capabilities.","The V3 Engine core contract is an ERC-721 NFT contract that manages metadata for all Art Blocks NFTs, including artist scripts, token hashes, and token royalty data.","The V3 Engine Flex core contract includes everything in the V3 Engine contract, but also allows artists to use external assets in their Engine tokens. These external assets can be images, videos, audio, or other data and may be stored on decentralized storage systems such as IPFS, Arweave, or on the Ethereum blockchain","Both core contracts integrate with various peripheral contracts to provide flexible, customizable, and extensible functionality. These peripheral contracts are:","Admin Access Control List (ACL) contract: Manages granting admin access to the core contract and related contracts. It is designed to be highly flexible, extensible, and upgradable.","Randomizer contract: Generates pseudo-random numbers for the core contract when new tokens are minted. This architecture is designed to be highly flexible, enabling designs that may desire asynchronous random number generation or other hash generation methods.","Core Registry contract: Notifies the subgraph indexing service of new Art Blocks Engine tokens. When the Core Registry emits an event, the subgraph indexing service is notified, and the Engine contract is indexed and made available for querying on the Art Blocks subgraph. It also notifies a shared minter suite to allow the new Engine contract to be used by minters.","Minter Suite contracts: A collection of contracts used to mint Art Blocks Engine tokens. The Minter Suite is designed to be highly flexible and can be used to mint tokens in various ways.","Partners should choose between the V3 Engine core contract and the V3 Engine Flex core contract based on their project's goals and technical capabilities. The smart contract architecture for Art Blocks Engine provides a robust and flexible system for managing and creating generative NFTs while integrating with various peripheral contracts to extend its capabilities.","For additional context, please check out this architecture overview (with accompanying diagrams)."]},{"i":"what-is-the-minter-suite","l":"What is the \"minter suite\"?","p":["A summary of the division of responsibilities between the MinterFilter and individual Minters can be summarized as:","Assigns a specific minter to each project, which can be updated by the project's artist or the platform's Admin ACL.","Checks if the minter is the assigned minter for a project before allowing the token to be minted.","Checks that a project is on a registered Art Blocks Engine contract before allowing a minter to be assigned.","Defines price information for tokens in a project, including token price in wei, currency symbol, and currency address.","For additional context, please check out this architecture overview (with accompanying diagrams).","Handles the token purchase process through the \"purchase\" and \"purchaseTo\" functions for specific projects.","Legacy Minter Suite","Maintains a list of approved minters that can mint tokens for projects on the platform.","Managed the maximum number of invocations (for the given minter) for each project.","MinterFilter:","Minters:","Provides information about the minter type and associated core contract and MinterFilter addresses.","Shared Minter Suite","The Art Blocks minter suite is a collection of smart contracts that facilitate the secure and efficient minting of generative art tokens for all Art Blocks contracts in the V3 architecture. Originally, each contract had its own minter suite. The new shared minter suite enables Engine contracts use the same minting contracts as Art Blocks Flagship, which enables a seamless experience for collectors and artists.","The legacy minter suite is very similar to the new, shared minter suite, except that each minter filter and minter contract is connected to a single core contract. The general roles and responsibilities of the Minter Filter and Minter contracts are the same, except that they limit minting to a single core contract instead of a set of allowlisted core contracts.","tl;dr: The MinterFilter serves as a control layer that ensures the correct minter is used for each project, while Minters handle token purchase processes and project-specific settings. This division of responsibilities enables a secure, efficient, and flexible set of contracts that we call the \"minter suite\"."]},{"i":"what-is-generative-art","l":"What is generative art?","p":["Generative art is about developing systems that define rules for creating art. By introducing randomness to those systems, core concepts are expressed through unique outputs. In a contemporary sense, this means writing computer algorithms to define the system and introduce randomness, which allows for conceptual exploration and rapid iteration.","Creative coders write scripts with specific parameters that introduce and explore features, which generate the final outputs in a collection. With Art Blocks’ generative minting technology, collectors participate in the creation of the art. No one knows exactly what a piece will look like before it's minted, not even the artist. Each NFT is generated at the time of purchase using the buyer’s unique transaction hash to create a ‘1 of 1 of X’, which adds an extra layer of magic as the creator and collector watch a project come alive.","The interesting part of modern generative art is that it involves working in series - often a large series. So instead of pursuing a single compelling work of art, a generative artist creates an algorithm capable of tens, hundreds, or thousands of compelling works of art. Which, when taken as a whole, expresses the range of possibilities contained in a single algorithm."]},{"i":"what-are-nfts","l":"What are NFTs?","p":["Nonfungible tokens (NFT) are unique digital assets stored on blockchain technology that can represent any digital or physical asset."]},{"l":"On-chain vs. off-chain","p":["Art Blocks Engine enables creators to immutably store their generative NFT directly on the Ethereum blockchain (on-chain) or reference an external library or asset (off-chain). For an off-chain implementation, partners can reference external off-chain assets using decentralized storage solutions like IPFS.","Decentralized and fully on-chain content is the most durable digital asset available. Typically, a creative coder writes a generative script in JavaScript and stores it directly on the blockchain. As long as you have access to a computer, a web browser, and Ethereum’s public ledger, you’ll always be able to reproduce the NFT in its original form and track ownership since creation. An on-chain NFT inherits the provenance, security, and durability of Ethereum itself, making them the highest quality digital asset available.","So, if Art Blocks ever shut down, all on-chain work would still be accessible since it's stored on the decentralized Ethereum blockchain and able to be viewed, bought, sold, and transferred without involving Art Blocks at all.","In contrast, if we store generative algorithms on an Art Blocks-owned database, the NFTs would rely on Art Blocks to return the assets - and if we go offline, the assets would not be retrievable. Similarly, if a script is stored on-chain but uses data from off-chain sources, it's vulnerable to the host of that off-chain data going offline.","Off-chain NFTs rely on assets stored on external servers. There are many reasons to reference off-chain assets - data storage is expensive on Ethereum, and using external assets can reduce the cost of putting data on-chain. It also allows for interesting applications of generative art using external assets. However, if your NFT references external sources and those sources go offline, the NFT will only track ownership of unretrievable data.","For this reason, we only allow certain external libraries to be used in project scripts given their general recognition as extremely reliable file storage sources.","Art Blocks Engine offers on-chain and off-chain solutions with our generative NFT minting technology. Which one is right for you depends on your project’s goals and technical capabilities."]},{"l":"Creating durable digital assets","p":["Creating on-chain generative NFTs ensures your collectors can expect their digital assets to stay the same forever. But if you choose to launch a generative project with off-chain assets, there are ways to mitigate the risk of going off-line using technology like IPFS or Arweave. We’re happy to chat about the right Art Blocks Engine implementation for your next project."]},{"l":"Potential use-cases","p":["The landscape of on-demand generative content has plenty of room to experiment. Some of our current partners include artists, galleries, art houses, online publications, and game developers. If you’re exploring an interesting project, get in touch, and let’s build together.","Current and upcoming use cases:","Fashion","Premier Artists","Media / Tech / Consumer brands","Gaming","Sports","BYOP - build your own platform"]}],[{"l":"Engine Partner Onboarding Steps","p":["An overview of the steps required to onboard as an Art Blocks Engine partner."]},{"l":"1. Initial outreach","p":["Interested in using Art Blocks Engine to launch a generative content platform?","Reach out to info@artblocks.io to get started. We'll discuss your needs, explain what we offer in a partnership, and align expectations.","Timeline: typically 1-2 weeks"]},{"l":"2. Project scope","p":["The Art Blocks team will work with you to determine the scope of the Art Blocks Engine project.","Timeline: 1-2 weeks"]},{"l":"3. Contract agreement","p":["Once the project objectives and scope are agreed upon, you'll work with our operations team to sign our partnership agreement.","Timeline: 1 week"]},{"l":"4. Smart contract details","p":["To get started, you'll provide our team with:","An Ethereum wallet address (that you currently own and control) you'll use to manage your Art Blocks Engine smart contracts","The name you’ll use for tokens from your contract (e.g., for Art Blocks, it is \"Art Blocks\")","The ticker symbol you’ll use for tokens from your contract (e.g., for Art Blocks, it is \"BLOCKS\")","Deployment Type: V3 Engine or V3 Engine Flex","Minter Type: flat price eth only, set price custom erc20, merkle tree allowlist, holder-gated, linear DA, exponential DA, and exponential DA with settlement","Starting project ID # (>=0):","Set autoApproveArtistSplitProposals: true or false","Regarding \"autoApproveArtistSplitProposals\" - It needs to be set at deployment and cannot be changed later.","tldr - if true, artist royalty wallet changes are auto-approved. If false, the contract admin will need to approve the artist's royalty wallet changes. This is an added check to ensure your artists aren't changing royalty wallets to a random address, which could complicate accounting/ OFAC compliance.","Note: We cannot deploy your contract until you provide the above information. The name and symbol tied to your contract cannot change once it’s deployed._","Timeline: 1-2 days"]},{"i":"5-contract-configuration--testnet-deployment","l":"5. Contract configuration & testnet deployment","p":["We will configure your smart contract before transferring ownership to Ethereum address provided in Step 4. Once we deploy your contract on the test network, you can start testing your generative script.","Timeline: 1 week"]},{"l":"6. Testnet infrastructure integration","p":["Art Blocks will integrate your contracts with our rendering infrastructure and provide access to our staging website for you to perform project onboarding and configuration via the Art Blocks site on the test network.","Contracts are deployed twice per month and typically take 1 week to complete and transfer.","Timeline: 1 week"]},{"i":"7-integration-with-partners-site","l":"7. Integration with partner’s site","p":["Your team will integrate your site’s front-end with the contract created by Art Blocks to test your outputs on the testnet.","Timeline: weeks-months (depends on partner)","Connect your front end to testnet contracts"]},{"l":"8. Test mints on partner site","p":["Your team ensures the minting process is working on the test network by minting your NFTs using the front-end of your site.","Timeline: weeks-months (depends on partner)","Mint test outputs","Test drop mechanic (flat price, Dutch Auction, whitelists, etc.)","Test purchase with custom ERC20 (if applicable)","Request a script audit from Art Blocks","Test your script across different hardware/software ( browserstack.com)","Let the Art Blocks team know testing is complete and you're ready for a mainnet deployment"]},{"l":"9. Deployment to mainnet","p":["Art Blocks deploys the mainnet version of your contract and integrates it with our infrastructure.","Timeline: 2 weeks"]},{"i":"10-infrastructure-integration-mainnet","l":"10. Infrastructure integration (mainnet)","p":["Your team integrates the mainnet contract with your site and prepares to generate your first NFT (mint #0)","Timeline: Depends on partner","Connect your front end with the new mainnet contracts, using the same minting mechanics from testnet (drop type & currency)","Mint #0 from your front end"]},{"i":"11-mint-0","l":"11. Mint #0","p":["You can mint your project's first official token via your site!"]},{"l":"12. Set secondary royalties","p":["Art Blocks will set our secondary royalty before we transfer contract ownership, but you are responsible for setting your own secondary royalty across all secondary marketplaces.","OpenSea - https://docs.opensea.io/docs/10-setting-fees-on-secondary-sales LooksRare - https://docs.looksrare.org/guides/collection-management/set-or-edit-collection-royalties x2y2 - https://docs.x2y2.io/guides/collection-management/manage-your-collection","Note: The vast majority of secondary activity takes place on OpenSea. Currently, OpenSea does not recognize on-chain royalties and needs to be set through their interface. However, they plan to recognize Roylaty Registry in the near-ish future. We highly encourage you to sign up for the Royalty Registry to avoid missed secondary royalties.","Instructions on setting up Royalty Registry - https://docs.artblocks.io/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-royalty-registry-setup/"]},{"l":"13. Project launch","p":["You can choose a launch date for your project. Please allow at least one week between a successful mint #0 and a go-live date.","Timeline: 1 week from completion of step 11"]}],[{"l":"Engine Project Deployment and Launch Guide","p":["This guide provides basic instructions for deploying and launching a new project on the V2 and V3 Engine smart contracts. You will learn how to create a project shell, assign a minter to each project, and setup the necessary configurations before minting and launching your project. This documentation aims to simplify the process and ensure a smooth project launch on the Art Blocks Engine platform.","There are slight variations between V2 and V3 contracts, which will be noted in the relevant sections."]},{"l":"Project Shell Deployment","p":["Collect the required information for the project:","Project title (e.g., \"Fun Lines\")","Artist's wallet address (e.g., 0x78592a6fBE68fEBf226040a5D25ad7e69F2FeAb6)","(V2 only) Price-per-mint specified in WEI (e.g., 350000000000000000, or 0.35 ETH)","Navigate to your Engine Core Contract on Etherscan and connect your wallet. You can find this link in your DEPLOYMENTS.md log. https://goerli.etherscan.io/address/0xd2363Acbf8CdF01A5FdfcB8f0295e0a5dF94518D#code)","Click the \"Write contract\" tab and use the addProject method to create a new project shell, specifying the information collected in step 1.","Connect to the Art Blocks website with the artist wallet used in Step 3. Your artist should be able to begin entering project details.","Testnet URL: https://artist-staging.artblocks.io/engine/[flex OR fullyonchain]/projects/[coreContractAddress]/[projectID] example: https://artist-staging.artblocks.io/engine/flex/projects/0x28b82AA5bb6d00363ae0FBC5ecaD689Ae49BC82B/0","Mainnet URL: https://www.artblocks.io/engine/[flex OR fullyonchain]/projects/[coreContractAddress]/[projectID] example: https://www.artblocks.io/engine/fullyonchain/projects/0xa319C382a702682129fcbF55d514E61a16f97f9c/1","If you encounter issues finding or seeing your project on the Art Blocks site, disconnect and reconnect your wallet, ensuring you are connected with the previously specified artist wallet."]},{"i":"assigning-a-minter-v3-only-new-shared-minter-suite","l":"Assigning a Minter (V3 only, New Shared Minter Suite)","p":["Minters are assigned on a per-project basis on V3 contracts, and minters must be assigned by the artist's wallet.","note: for legacy minter suite directions, see the next section","Art Blocks is working on a new creator dashboard that will more easily facilitate the minter assignment process. This will only be possible using the new shared minter suite, because those minters are indexed by the subgraph. Until the new creator dashboard is released, please follow these instructions to assign a minter to your project.","Assign the minter to your project by using the MinterFilterV2 contract found in your deployment file. The artist's wallet should use function #9 setMinterForProject, entering the _projectID, _coreContract address, and _minter address. You can get the globally approved minter addresses via the getAllGloballyApprovedMinters() view function on the MinterFilterV2 contract.","Once the minter is linked to your project, set the project details on the minter contract.","For example, if you are using a shared Dutch Auction minter, navigate to the contract on Etherscan. Then, use the function setAuctionDetails to enter details like _projectId, _coreContract, _auctionTimestampStart, _priceDecayHalfLifeSeconds, _startPrice, and _basePrice. This must be done using the artist's wallet."]},{"i":"assigning-a-minter-v3-only-legacy-non-shared-minter-suite","l":"Assigning a Minter (V3 only, Legacy Non-Shared Minter Suite)","p":["We recommend using the new shared minter suite, which is easier to use and more flexible. If you are using the legacy non-shared minter suite, follow these instructions. For more information about migrating to the new shared minter suite, please see the Minter Suite Migration Runbook.","Minters are assigned on a per-project basis on V3 contracts, and minters must be assigned by the artist's wallet. For the artist wallet to assign a minter, follow these steps:","Assign the minter to your project by using the MinterFilterV1 contract found in your deployment file. The artist's wallet should use function #6 setMinterForProject, entering the _projectID and _minterAddress. You can find the minter address in your deployment log, which is pinned in your partner channel.","Once the minter is linked to your project, set the project details on the minter contract. The deployed minter addresses can be found in your deployment file.","For example, if Art Blocks deployed a Dutch Auction minter for your core contract, navigate to the MinterDAExpV4 contract on Etherscan (in your DEPLOYMENT.md log). Then, use the function setAuctionDetails to enter details like _projectId, _auctionTimestampStart, _priceDecayHalfLifeSeconds, _startPrice, and _basePrice. Make sure this is done using the artist's wallet."]},{"i":"pre-mint-0-flight-check","l":"Pre-mint-#0 Flight Check","p":["Before minting your first token (#0) on your new project shell, verify the following:","The baseTokenURI has been set, following the format:","Mainnet: http://token.artblocks.io/{CORE_CONTRACT_ADDRESS}/","Testnet: https://token.staging.artblocks.io/{CONTRACT_ADDRESS}/","The max invocations for the project have been set. (note: project size cannot be increased once set on V3 contracts)","Mint through your own front end. On testnet, you'll want to test each minter type and currency you plan to use on mainnet."]},{"i":"pre-launch-pre-open-minting-flight-check","l":"Pre-launch (pre-open-minting) Flight Check","p":["For a project to be available for public purchase, the project must be activated by the admin, and unpaused by the artist.","tldr: inactive + paused (default state) = private project shell and unable to purchase active + paused = public project shell and only the artist wallet can purchase active + unpaused = open to purchase","Before launching your project for open minting, verify the following:","The project has been activated by the contract admin.","The project is not yet unpaused.","Once unpaused the project will be open, depending on the minter being used (DA will not open until specified startTime)"]}],[{"l":"Art Blocks Engine OpenSea Setup","p":["Setting up the OpenSea storefront for your Art Blocks Engine contract."]},{"l":"OpenSea Storefront Ownership Transfer","p":["After the first token has been minted on your new Art Blocks Engine contract, you should be able to see this token in the OpenSea storefront. You will find this in the format https://opensea.io/assets/{CONTRACT_ADDRESS}/{TOKEN_ID} e.g. https://opensea.io/assets/0x13aae6f9599880edbb7d144bb13f1212cee99533/1000167.","Once this first token is populated, the Art Blocks team will be able to transfer the OpenSea collection for your project to a wallet that you control. By default, the Art Blocks team will plan to use the same address for the OpenSea collection ownership as it is designated to be the admin of your smart contract. However, if you prefer that a different wallet address manages the OpenSea collection, please reach out to Art Blocks to request this before the project has been transferred to your team.","After your OpenSea collection has your designated wallet added as the collection administrator, you may remove the wallet that Art Blocks controls from being an additional admin. It’s added automatically at the time of collection creation based on the contract deployer wallet address at the time of collection creation. We recommend that you do so. That way, only you control your OpenSea storefront.","Please contact the Art Blocks and/or OpenSea teams if you have any issues during this process."]},{"l":"OpenSea Storefront Options","p":["For Art Blocks Engine projects, there are two options that OpenSea can provide for collection organization:","1. All projects are grouped in one large collection, where individual projects within a collection are shown as filter traits on the sidebar of the OpenSea UI.","All projects in one collection.","2. Each new project on your contract is handled as its own collection on OpenSea, where project traits are properties.","Each project as its own collection.","By default, collections are organized via method 1. above. However, if you would like your collection to be handled via method 2., please reach out to the Art Blocks team, and we can facilitate this change by OpenSea on your behalf."]}],[{"i":"art-blocks-engine-royalty-registry-setup-v2-contracts-only","l":"Art Blocks Engine Royalty Registry Setup (V2 contracts only)"},{"l":"Royalty Registry","p":["The Royalty Registry is an on-chain tool used by many marketplaces ((soon) OpenSea, Coinbase NFT, etc.) to query royalty payment addresses and percentages when a token is sold. The Royalty Registry lives on the Ethereum blockchain and is decentralized.","Art Blocks Engine contracts integrate with the Royalty Registry directly to handle many projects and artists on a single contract. Please do not use the Royalty Registry's \"Configure\" UI to configure the royalties for your Engine contracts. Doing so will result in incorrect royalty payments across many projects. Instead, see the documentation below.","Note that the Royalty Registry's \"Lookup\" UI is a great tool for confirming that your Engine contracts are configured correctly after the configuration steps below have been completed."]},{"l":"Royalty Payment Addresses","p":["For Engine contracts, the following addresses may receive royalties:","Party","Typical Royalty Percentage","Platform (Engine Partner)","default 2.5%","Render Provider (Art Blocks)","Artist","typically 5%, but configurable by artist","Additional Payee","split between Artist & Additional Payee varies across projects"]},{"l":"Configuring Royalties","p":["V3 and V2 Engine contracts are configured differently. V3 Engine contracts are the latest version of the Art Blocks Engine contracts. Since they were designed after the Royalty Registry was released, they automatically integrate with the Royalty Registry. V2 Engine contracts also integrate with the Royalty Registry, but have a shim-layer that must also be configured. This is because V2 Engine contracts were designed before the Royalty Registry was released."]},{"l":"Configuring V3 Engine Contracts","p":["Simply configure the relevant royalty payment details on the token contract itself:","admin (contract-wide):","Ensuring platform and render provider payment addresses are correct, updateable by contract admin by calling updateProviderSalesAddresses on the Engine core contract","Ensuring platform and render provider payment percentages are correct, updateable by contract admin by calling updateProviderSecondarySalesBPS on the Engine core contract","artist (project-specific):","Ensuring the project's artist royalty percentage is correct, updateable on the website by the artist in their project dashboard.","Ensuring the project's artist and additional payee splits are correct, updateable on the website by the artist in their project dashboard."]},{"l":"Configuring V2 Engine Contracts"},{"l":"Required V2 Setup","p":["A. Pre-setup:","B. Royalty Registry Integration:","Call the setRoyaltyLookupAddress function with the following arguments:","Call the updatePlatformRoyaltyAddressForContract function with your Engine token contract address as _tokenContract, and your desired platform royalty payment address as _platformRoyaltyAddress","Connect your Engine admin wallet to the Art Blocks Engine royalty override contract, 0x31E1cC72E6f9E27C2ECbB500d978de1691173F5f, on etherscan","Create a new override on the Royalty Registry for your Engine core contract","Ensure every project has the desired artist royalty percentage set on the Engine contract.","IMPORTANT: This percentage represents the percentage of the total token sale that will be paid to a combination of artist & additional payee. It is typically 5%. Additionally, the default 2.5% to the Engine platform (you) and 2.5% to render provider (Art Blocks) will be also added by the Royalty Registry override contracts below.","Note: This percentage is different than what OpenSea has asked us to do with their off-chain royalty system. In the old system, typically 5%+2.5%+2.5%=10% was set on OpenSea's website because they only supported bulk payments to a single address. In the new on-chain system, payments to more than a single address will be supported.","Now you will automatically be receiving royalties from sales on secondary markets that support use of the Royalty Registry!","Only artists may update their project's royalty percentage. They can call updateProjectSecondaryMarketRoyaltyPercentage(_projectId, _royaltyPercentage) on the Engine contract from their artist wallet. Typically royalty percentage would be the number 5, representing 5%.","royaltyLookupAddress: The address of the standard Art Blocks Engine Royalty Registry override contract, 0x31E1cC72E6f9E27C2ECbB500d978de1691173F5f","Set your Platform royalty payment address","The following steps are required before Art Blocks Engine contracts will integrate properly with the Royalty Registry.","tokenAddress: The address of your Engine core contract","Using the Connect to Web3 button, connect your Engine admin wallet to etherscan when on the \"Write as Proxy\" tab.","View the Royalty Registry's mainnet registry contract on etherscan: https://etherscan.io/address/0xad2184fb5dbcfc05d8f056542fb25b04fa32a95d#writeProxyContract"]},{"l":"Optional V2 Configuring","p":["Royalty percentages of 2.5% are used by default by the Art Blocks Engine royalty override contract. The admin of any given Engine core contract can override these percentages by calling updatePlatformBpsForContract or updateRenderProviderBpsForContract on the Art Blocks Engine royalty override contract, 0x31E1cC72E6f9E27C2ECbB500d978de1691173F5f, on etherscan","Note that royalty proportions are defined in terms of Basis points. For example, 250 BPS = 2.5% royalty. See this article for more information.","After initial setup, the Platform (Engine partner) royalty payment address may be updated at any time by the admin of a given Engine core contract by calling the updatePlatformRoyaltyAddressForContract function on the Art Blocks Engine royalty override contract, 0x31E1cC72E6f9E27C2ECbB500d978de1691173F5f, on etherscan"]}],[{"l":"Embroidery on Art Blocks Engine","p":["In addition to providing a browser-based live view and media files generated from your project script, Art Blocks Engine provides tools to embroider your generative artwork on garments and accessories."]},{"l":"Requirements","p":["In order to get started, you will need:","Testnet project shell on Art Blocks Engine Refer to documentation for setup instructions*","Embroidery machine and software drivers compatible with DST or PES files If you are new to embroidery, we recommend the Brother PE800","JavaScript utilities for manipulating SVG markup Clone the embroidery template repository for an example: ‣"]},{"l":"Quick Start","p":["Deploy a new project shell to your Art Blocks Engine testnet contract","Upload a project script that includes a global function named generateEmbroiderySVG that returns a string containing SVG markup for embroidery","Use the Embroidery File Downloader to generate embroidery files for minted tokens"]},{"l":"Project Script Requirements","p":["In addition to following the typical guidelines and constraints for Art Blocks projects, your project script should include a global function that is only used for embroidery."]},{"l":"Generating SVG for Embroidery","p":["Implement a global function with the following type signature:","For example, you may include a function similar to code below:"]},{"l":"Functional Requirements","p":["In order to correctly generate files for embroidery, you must:","Implement a generateEmbroiderySVG global function that returns the full markup of an svg element as a string","Optional: accept a width and height parameter (millimeters) used to resize the contents of the SVG to accommodate different garment sizes","Render a digital-only version of the art using a separate svg or canvas that is displayed to the user and thumbnailed in token metadata (similar to any digital-only Art Blocks project)","Inline all libraries and code used in your project that are not configured as an on-chain dependency"]},{"l":"Known Limitations","p":["Avoid using SVG fills - instead, to create the visual appearance of a fill, the SVG should contain the exact paths the embroidery needle should follow","Avoid using asynchronous code or promises inside of the generateEmbroiderySVG function - the function should return valid SVG markup immediately","Provide margins (bleed) matching the precision of the embroidery machine to improve manufacturing yield","Match all colors used in your design to the colors of thread available to you for embroidering"]},{"l":"Embroidery in Production","p":["In addition to the typical steps required for moving an Art Blocks Engine project to mainnet, there are additional considerations for embroidery projects."]},{"l":"Logistics and Fulfillment","p":["There are three primary customer experiences enabled for embroidery on Art Blocks Engine:","Drop-shipped or batched production Consider the lead times, available materials, and the process for sending files to embroidery service providers.","Live in-person pop-up events Consider space constraints and measure the amount of time required to fulfill a single embroidered object.","At-home embroidery for token holders Consider how and when you would like to provide your users with a link to download embroidery files for a project."]},{"i":"option-1-batched-production","l":"Option 1: Batched Production","p":["To facilitate automated testing and batched production, we provide a rate-limited API for converting Art Blocks Engine projects into DST and PES embroidery files. Note: the API endpoints provided for batched production are rate-limited, and cannot be linked from a public web site.","For example, the following commands illustrate how you can download individual embroidery files for tokens on an Art Blocks Engine project:"]},{"i":"option-2-live-events","l":"Option 2: Live Events","p":["To facilitate live events, operators of a pop-up booth can use the Embroidery File Downloader on a laptop or iPad to quickly download the relevant embroidery files for a given minted token.","Embroidery File Downloader"]},{"i":"option-3-home-embroidery","l":"Option 3: Home Embroidery","p":["If you would like to provide your token holders with a link to download DST or PES files of their minted tokens, please contact us for access to the API dashboard. To generate embroidery files in an S3 bucket that may be linked from a public web site, you will need to add your project in the API dashboard here: https://minting-api.artblocks.io/admin/embroidery/embroideryproject/"]},{"l":"References","p":["https://github.com/embroidepy/vpype-embroidery/","https://github.com/EmbroidePy/pyembroidery","10 Best Print on Demand Companies and Sites (2023)","The 7 Best Embroidery Machines of 2023"]}],[{"l":"Mobile Minting for In-Person Activations","p":["The Art Blocks Mobile Minter is a specialized app for iPad and iPhone designed to streamline the minting process during in-person events. Unlike the standard Art Blocks website, which is accessible from any device, the Mobile Minter is tailored for events where minting is exclusive to attendees or offered as an event gift."]},{"l":"Features","p":["The Mobile Minter is capable of:","Minting Art Blocks tokens with a pre-funded wallet to cover gas fees","Minting tokens to an ENS name or a copied Ethereum address","Authenticating users with FaceID/TouchID for quick access during live events","Minting tokens without requiring manual signing and submission of Ethereum transactions"]},{"l":"Requirements","p":["The Mobile Minter is perfect for situations where:","A project is paused and not available for online minting","An artist wants to distribute their work at a live event","An iPad or iPhone with the latest iOS version is available","A small amount of Ethereum is on hand to cover gas fees for token recipients","You've set up a Stripe account to accept fiat payment (optional)"]},{"l":"Getting Started","p":["To use the Mobile Minter, follow these steps to set up your project and device according to the system requirements."]},{"l":"Step 1. Project Configuration","p":["To set up the Mobile Minter for your project:","Send a Slack message in Slack requesting access to the Mobile Minter","Art Blocks staff (@Shantanu Bala) will provide a wallet address that will be used to pay for gas fees for transactions Note: The app manages this wallet, and any remaining funds can be returned to you at any time","Pause your project to restrict minting to the artist only","Transfer artist ownership to the wallet address from Step #2, making the Mobile Minter the sole minting wallet for the project","After completing these steps, Art Blocks staff (@Shantanu Bala) will give you login details to start using the mobile app"]},{"l":"Step 2. Device Setup","p":["To prepare your mobile device:","Update your iPhone or iPad to the latest iOS version","Set up and ensure FaceID or TouchID is functional on your device","Download the TestFlight app from the App Store: TestFlight","Join the Mobile Minter beta on TestFlight:","Sign in, set up FaceID, and proceed to minting"]},{"l":"Step 3. Minting","p":["Mobile Minter iPad app","Click the link above to view a screen recording of the Mobile Minter app on iPad. This test demonstrates the steps to mint a project on the Goerli test network. To mint a new token, users follow these steps:","Open the Mobile Minter app on an iPhone or iPad device","Sign in using FaceID","Select a project from the list of available projects","Input an ENS name or wallet address","Confirm the minting details","Wait for the token minting transaction to be confirmed"]},{"l":"Payment Processing","p":["The Mobile Minter utilizes Stripe Terminal for handling payments. Art Blocks does not offer merchant accounts or handle tax remittance for partners. To process fiat payments with Stripe Terminal, all Art Blocks Engine partners must create and configure their own Stripe account.","The backend (Art Blocks Minting API) and point of sale (Mobile Minter app) software are provided by Art Blocks. However, the hardware must be procured by Art Blocks Engine customers."]},{"l":"Stripe Reader M2","p":["We recommend using the Stripe Reader M2 with the Mobile Minter due to its convenient NFC payment support, Bluetooth connectivity, long-term SDK support, and reliable chip/magstripe fallback. You will need to order the M2 directly from Stripe."]},{"l":"Direct Charges","p":["The Mobile Minter uses Stripe Connect to make a direct charge using your Stripe account. Stripe Connect processes direct charges for your Art Blocks Engine project using your own Stripe account (connected account) while using our platform - note that the charge amounts and fees are mock examples provided by Stripe."]},{"l":"Stripe API Secrets","p":["Do not share your live Stripe API keys with anyone, including Art Blocks employees. Instead, Art Blocks will supply a secure OAuth link from Stripe for your usage. Connected accounts are managed using the process outlined by Stripe:","Managing connected accounts with the Dashboard"]},{"l":"Displaying Live Mints","p":["Web-enabled TVs or displays can showcase a real-time view of the latest tokens minted through the Mobile Minter. The Art Blocks documentation site offers an overview of configuration options for the live viewer."]},{"l":"Example Embed","p":["You can embed live.artblocks.io using an iframe on a web page containing your organization’s branding.","[Example embed of live.artblocks.io without any configuration parameters ( docs)]( https://live.artblocks.io/)","Example embed of live.artblocks.io without any configuration parameters ( docs)"]},{"l":"Frequently Asked Questions"},{"i":"can-the-mobile-minter-be-used-with-projects-that-are-not-paused","l":"Can the Mobile Minter be used with projects that are not paused?","p":["Yes, the Mobile Minter can be used for active projects. However, pausing the project and transferring artist ownership to the app restricts minting exclusively through the app. If a project remains unpaused, anyone online can mint tokens."]},{"i":"can-users-pay-for-gas-fees-themselves","l":"Can users pay for gas fees themselves?","p":["Currently, gas fees must be pre-funded by the artist or the organization using the Mobile Minter app, through the Mobile Minter's hot wallet."]},{"i":"can-my-prepaid-gas-fee-balance-be-returned-to-me","l":"Can my prepaid gas fee balance be returned to me?","p":["Yes, please contact us to arrange the return of any remaining funds to the original depositing wallet. To have the remaining ETH returned, ensure that the funds were initially transferred to the Mobile Minter's hot wallet from an address capable of receiving ETH on behalf of your organization. The unspent ETH can only be sent back to the original sender's wallet."]},{"i":"can-multiple-projects-be-managed-simultaneously-through-the-mobile-minter-app","l":"Can multiple projects be managed simultaneously through the Mobile Minter app?","p":["Yes, the Mobile Minter app allows you to manage multiple projects for in-person events. You can easily switch between projects during the event, ensuring a seamless minting experience for attendees."]},{"i":"what-currencies-are-supported-for-payments-in-the-mobile-minter-app","l":"What currencies are supported for payments in the Mobile Minter app?","p":["The Mobile Minter app processes fiat payments via Stripe Terminal, which supports a variety of currencies. The available currencies depend on your Stripe account and the country where your business operates. You will be the merchant of record, and Art Blocks will collect its platform fees in ETH or USD. For a list of supported currencies for your customers, please refer to the Stripe documentation."]},{"i":"is-it-possible-to-customize-the-appearance-of-the-mobile-minter-app-for-my-event","l":"Is it possible to customize the appearance of the Mobile Minter app for my event?","p":["While the Mobile Minter app does not offer customization, you can embed live.artblocks.io inside of a page that showcases your event's theme and branding. Please refer to the Art Blocks documentation site for an overview of configuration options for the live viewer."]}],[{"l":"Using Pinata for External Assets","p":["Pinata is an excellent IPFS resource built with creators and non-technical users in mind, making it easy to upload content that you can use inside Art Blocks! This will walk you through the basics of uploading content to Pinata."]},{"l":"Signing Up","p":["You can sign up for a free account which will allow up to 100 files and 1GB of storage! To get started visit pinata.cloud and click the “Sign Up” button in the top right. It will ask you for a name, email, and password."]},{"l":"Uploading Content","p":["Once you’re signed in you will see the Files Page which looks something like this: setup","To start uploading content, simply click on the “Upload +” button and select “File” upload","Of course from there click “Select File” and choose the file on your computer select","Then give it a name, and click upload; that’s it! name","Once it’s done uploading you will see the file listed on your files page! complete","What’s important to note is the “CID” which stands for “Content Identifier.” It’s the core of IPFS and how files can be shared across the IPFS network. This is what you would input into the “cid” portion of an Art Blocks generative script and would look something like this:","QmNrCnsNazd54aAQixQCVtikJNfizEXGKR6yLhr9P1TTJV","If you want to preview your file you can simply click on the name of the file on the left side and it will open a preview in a new window.","The default Pinata gateway is https://gateway.pinata.cloud but keep in mind that it should only be used for testing files. For production work you may want to consider getting a Dedicated Gateway on a paid plan.","If you have further questions be sure to visit Pinata's docs and do not hesitate to send them an email at team@pinata.cloud! or reach out directly to the Art Blocks team."]}],[{"l":"Using Filebase for External Assets","p":["Filebase is a geo-redundant IPFS pinning service and decentralized storage provider. When a file is uploaded to an IPFS bucket on Filebase, it is automatically pinned to the IPFS network with 3 duplicate copies, each of which is stored on an IPFS node located across 3 unique, geographic regions.","Filebase offers an easy-to-use Web Console Dashboard for non-technical users, and an S3-compatible API for developers to utilize in a wide variety of tool configurations or SDKs."]},{"l":"Signing Up","p":["Filebase uses a web-based console that can be found at https://filebase.com/signup. Existing accounts can go directly to https://console.filebase.com.","To sign up for a Filebase account, navigate to https://filebase.com. To make a new account, click the ‘Try for Free’ button in the top right corner of the webpage. signup","Filebase is a free-to-use platform for all users. All users can store up to 5GB of data, with a maximum of 1,000 individual files on the IPFS network with no credit card required.","Next, fill out the fields of the form, including an email address and password, and agree to the Filebase terms to create your account.","You will receive an email with confirmation instructions. Click the link included in the email to confirm your account and finish the registration process. Once you’ve completed these steps, your Filebase account has been created."]},{"l":"Uploading Content","p":["Once signed in, you will be brought to the Filebase dashboard. web_dashboard","To upload content, first you will need an IPFS bucket. Select 'Buckets' from the left menu bar, then select 'Create Bucket'. buckets","Give your bucket a name, then select IPFS for the network. bucket_ipfs","Then, select your bucket from the Buckets menu and select 'Upload'. You can choose to upload a File, Folder, or existing IPFS CID to Filebase. For this example, we'll use a single file. upload","You will be prompted to select a file from your computer. Once uploaded, it'll be displayed in the Filebase web console and it will be given an IPFS CID value. cid","When a file is uploaded to IPFS, the file’s contents are used to generate a cryptographic hash value. Then, this hash value is used to generate another value, which is used as the file’s content identifier (CID). CIDs are used to access files stored on IPFS, but instead of locating the file on the network based on its name, the CID is based on the file's contents. Any changes to the file's contents or metadata will result in a new, unique CID.","The CID value is what is used within an Art Blocks generative script, under the 'CID' field.","To preview your file using its IPFS CID and the Filebase public gateway, you can use the following URL format in any web browser:","https://ipfs.filebase.io/ipfs/[CID]","The Filebase public IPFS gateway is https://ipfs.filebase.io/ipfs and can be used by all Filebase uses to host Filebase pinned CIDs. For increased configuration options, performance, content whitelisting, and custom branding, a Filebase Dedicated Gateway can be used through one of Filebase's paid IPFS plans.","For more information, visit Filebase's extensive documentation or send them an email at hello@filebase.com! or reach out directly to the Art Blocks team."]}],[{"l":"FAQs","p":["Core contract vs. Minter contract?","Does Art Blocks create a front-end site for our project?","Flex: Can JS external asset dependencies make external calls to other APIs/assets?","Flex: What are the limitations around file size and file type for external assets? How many external assets can a project have?","How can we add more team members to Discord?","How do we list Art Blocks Engine pieces on OpenSea?","How does autoApproveArtistSplitProposals work?","How does project size work on the Minter contract vs Core contract?","How long will each stage of the process take?","How long will the process take from start to public launch?","What are the Art Blocks Engine offerings?","What effect does ‘locking’ a project have?","What information do we need to provide?","What's included with Art Blocks Engine?","What's the difference between a testnet token and a mainnet token?","When should I enable GPU rendering?"]},{"i":"what-are-the-art-blocks-engine-offerings","l":"What are the Art Blocks Engine offerings?","p":["Art Blocks Engine: Used for on-chain storage of generative systems. Projects can use no dependencies or one dependency from a list of decentralized libraries. See the allowed dependencies here.","Art Blocks Engine Flex: Allows generative systems to reference off-chain assets stored on IPFS or Arweave, enabling creative tools like photography, AI, and GAN.","Email us at Engine@artblocks.io to discuss which offering best suits your needs."]},{"i":"whats-included-with-art-blocks-engine","l":"What's included with Art Blocks Engine?","p":["For a new partnership, the standard current Art Blocks Engine offerings include:","Deployment of Engine smart contracts suite to testnet and mainnet (includes gas costs).","Integration of deployed Core contract with decentralized Graph indexing architecture on testnet and mainnet, includes GRT costs incurred for subgraph update deployment.","Integration of deployed contracts and subgraph with Art Blocks' project setup site and rendering/metadata infrastructure (APIs: Token, Generator, Rendered Image).","(in-migration) Integration with the shared Art Blocks Minter Suite. Art Blocks is rolling out a shared minter suite that will be available for Engine Partners to use to mint their projects. Previously deployed V3 Engine contracts will have the ability to migrate to the new shared minter suite. This means the same minting contracts used for Art Blocks Flagship will be available for Engine partners. In addition to the ability to query minter state via subgraph or Hasura queries, Art Blocks has future plans to expand our offering to include the ability to configure minter settings in an Artist Dashboard, and the ability to use a new Art Blocks minting SDK to more easily mint tokens on your frontend."]},{"i":"what-effect-does-locking-a-project-have","l":"What effect does ‘locking’ a project have?","p":["A summary of how the smart contract functions behave:","addProjectScript","after being locked, maximum invocations may only be decreased","before being locked, maximum invocations may be increased","can only lock projects (i.e. locked projects can not be unlocked)","Locked projects can not be unlocked","Locking a project (specifically on V2 Contracts) permanently freezes the artist name, project name, project scripts, project license, and project IPFS hash on the blockchain. Additionally, maximum invocations of a project can never be increased.","only callable by admin whitelisted wallets on the core contract","project script changes:","removeProjectLastScript","The following functionality is affected by a project being unlocked vs. locked:","The following functionality is only allowed on unlocked projects:","toggleProjectIsLocked","updateProjectArtistName","updateProjectIpfsHash","updateProjectLicense","updateProjectMaxInvocations","updateProjectName","updateProjectScript","updateProjectScriptJSON"]},{"i":"changes-for-v3-contracts-deployed-after-march-23","l":"Changes for V3 contracts (deployed after March '23)","p":["In addition to the above, artists can update project description when project is unlocked. However, only contract admins can update project the description when the project is locked.","V3 contracts autolock four weeks after a project is complete."]},{"i":"how-can-we-add-more-team-members-to-discord","l":"How can we add more team members to Discord?","p":["Contact your account manager for an invite link to the private Discord server."]},{"i":"how-long-will-the-process-take-from-start-to-public-launch","l":"How long will the process take from start to public launch?","p":["The process typically takes 10 weeks from initial conversation to public launch, but is highly dependent on partner's resource allocation. To reduce delays, have a front-end developer, artist, go-to-market strategy, and sufficient onboarding time ready."]},{"i":"what-information-do-we-need-to-provide-to-deploy-our-smart-contracts","l":"What information do we need to provide to deploy our smart contracts?","p":["To get started, you'll provide our team with:","Network: (Mainnet or Testnet)","A testnet/mainnet Ethereum wallet address (that you currently own and control) you'll use to manage your Art Blocks Engine smart contracts.","The name you’ll use for tokens from your contract (e.g., for Art Blocks, it is \"Art Blocks\")","The ticker symbol you’ll use for tokens from your contract (e.g., for Art Blocks, it is \"BLOCKS\")","Deployment Type: V3 Onchain Engine or V3 Flex Engine","Minter Type: set price eth only, set price custom erc20, merkle tree allowlist holder-gated, linear DA, exponential DA, and exponential DA with settlement","note: minter selection will not be needed after migrating to shared minter suite","Starting project ID # (>=0):","Set autoApproveArtistSplitProposals true or false**","**It needs to be set at deployment and cannot be changed later.","tldr - if true, artist royalty wallet changes are auto-approved. If false, the contract admin will need to approve the artist's royalty wallet changes. This is an added check to ensure your artists aren't changing royalty wallets to a random address, which could complicate accounting/ OFAC compliance.","We cannot deploy your contract until you provide the above information. The name and symbol tied to your contract cannot change once your contract is deployed."]},{"i":"does-art-blocks-create-a-front-end-site-for-our-project","l":"Does Art Blocks create a front-end site for our project?","p":["No, partners are responsible for creating and designing their customer-facing experience.","However, we do have a front-end React template with web3 functionality you need to launch a minting site. You will still be responsible for designing the user experience, but this significantly reduces the time needed to complete a front-end."]},{"i":"how-long-will-each-stage-of-the-process-take","l":"How long will each stage of the process take?","p":["Initial outreach - 1-2 weeks","Project scope - 1-2 weeks","Contract agreement - 1 week","Smart contract details - 1-2 days","Contract configuration & testnet deployment - 1 week","Testnet infrastructure integration -** 1 week**","Integration with partner’s site - Varies(dependent on partner)","Test mints on partner site - Varies(dependent on partner)","Deployment to mainnet - 1-2 weeks","Mainnet infrastructure integration -** Varies**(dependent on partner)","Mint #0 - Instant","Project launch! - 1 week after step 11"]},{"l":"Contract Ecosystem","p":["Core contract: This is the smart contract that controls the artwork created by the artist. No financial transactions occur on this smart contract.","AdminACL: By default, Engine smart contracts have two sets of permissions, Admin and Artist. The AdminACL contract controls which wallets can access which functions on your core contract. If you'd like to assign more granular control of your smart contract to different wallets, you can fork and customize the AdminACL contract.","Minter Filer: The minter filter configures minter-types to specific projects.","Minter contract: These smart contracts receive funds and split them between the artist(s) and the platform. Artists receive funds directly from these contracts."]},{"i":"how-do-we-list-art-blocks-engine-pieces-on-secondary-markets","l":"How do we list Art Blocks Engine pieces on secondary markets?","p":["Secondary marketplaces will automatically detect and display projects on your contract. If you’d like each project to have its own storefront on OpenSea, please contact an account manager to facilitate the change."]},{"i":"whats-the-difference-between-a-testnet-token-and-a-mainnet-token","l":"What's the difference between a testnet token and a mainnet token?","p":["Testnet tokens are free, unlimited, and worthless. They only exist as a tool for the testing environment before spending actual money (Ether) deploying on Ethereum’s mainnet."]},{"i":"flex-what-are-the-limitations-around-file-size-and-file-type-for-external-assets-how-many-external-assets-can-a-project-have","l":"Flex: What are the limitations around file size and file type for external assets? How many external assets can a project have?","p":["There are no explicit limitations on the contract side, neither for file size or type or how many external assets a project can have. Ultimately, this is at the discretion of the artist, but Art Blocks recommends paying close attention to ensure that artworks are as accessible as possible for as many different types of users as possible. Generally speaking, the above factors should be influenced by trying to achieve the best user experience for the artwork in terms of performance and load time.","Some additional recommendations:","Try to keep the overall download size for users viewing the work to be under ~ 10mb OR ensure the artwork description mentions the heavier load/longer loading time. Additionally, consider whether or not it may make sense to have a loading indicator as part of the artwork itself.","When working with less common file types, remember to test on various platforms/browsers, to ensure the best cross-platform compatibility possible."]},{"i":"flex-can-js-external-asset-dependencies-make-external-calls-to-other-apisassets","l":"Flex: Can JS external asset dependencies make external calls to other APIs/assets?","p":["Having your JS external asset dependencies making external calls, whether it's to an API or other assets, is not a supported use of the Engine Flex offering, as it breaks the assumption of only utilizing off-chain decentralized platforms. We encourage you to, instead, serialize any data you may need from these external calls into assets (JSON, TXT, etc) that are also stored on the platforms Engine Flex currently supports (IPFS and Arweave)."]},{"i":"for-the-status-of-a-project-on-the-contract-how-does-active-and-paused-differ","l":"For the status of a project on the contract, how does 'active' and 'paused' differ?","p":["The value of paused is determined by artist, whereas active is determined by contract admin. Both need to be in a mintable state ( paused=false, active=true) for a project to be publicly available to mint."]},{"i":"why-is-there-a-small-delay-between-the-tokens-mint-transaction-confirming-and-it-being-viewable-on-the-art-blocks-generator-live-view","l":"Why is there a small delay between the token's mint transaction confirming and it being viewable on the Art Blocks Generator (live view)?","p":["Art Blocks uses the decentralized Graph network to index on-chain data in our publicly available subgraph. There can be a slight delay between the first block confirmation on the ethereum network for a transaction and that transaction being indexed by our subgraph. To mitigate this, as an Art Blocks engine provider, your client should be waiting multiple block confirmations (we recommend at least 2 blocks) before it shows the generator view to the user. The generator will return an error message if the token is not indexed yet, accompanied by 4XX status code. Many clients also employ a polling strategy, only showing the requested generator view once the requested generator url is returning a 2XX status code."]},{"i":"how-does-project-size-work-on-the-minter-contract-vs-core-contract","l":"How does project size work on the Minter contract vs Core contract?","p":["A project's max invocations on Art Blocks contracts are handled differently on the Core contract and the Minter contract.","On the Core contract, setting a project size establishes the project's maximum size, and this value cannot be increased once set. The max invocations on the core contract define the absolute upper limit for the number of mints for a specific project.","On the other hand, each Minter contract allows you to set max invocations for the specific minter using the manuallyLimitProjectMaxInvocations function. This setting does not lock the project size but controls the maximum number of mints allowed by that particular minter. When updating the maxInvocations value for a project in the Minter contract, you must adhere to these conditions:","The new value of _maxInvocations should not be greater than the maxInvocations set in the core contract.","The new value of _maxInvocations should not be less than the current number of invocations."]},{"i":"how-does-autoapproveartistsplitproposals-work","l":"How does autoApproveArtistSplitProposals work?","p":["When true, aproveArtistSplitProposals is a feature that allows artists to automatically change their royalty split payout address and the split percentage without requiring approval from the contract admin. This makes the process faster and more convenient for artists but may increase the risk of unauthorized changes to royalty wallets, which could complicate accounting or OFAC compliance.","If set to else the contract admin will need to approve any changes to the artist's royalty wallet, adding a layer of security and control."]},{"i":"when-should-i-enable-gpu-rendering","l":"When should I enable GPU rendering?","p":["If your image preview is showing a blank, incomplete, or invalid rendering for a token, turning on GPU rendering may resolve the issue. GPU rendering is managed by the Art Blocks team and enabling is determined on a case-by-case basis. Before requesting GPU rendering, check your project script code for any potential issues and/or try increasing your render delay (up to 10min). Reach out to the Art Blocks team to enable GPU rendering on a specific project if the token issues continue after adjusting the delay."]}],[{"l":"Art Blocks Engine Flex Technical Details","p":["This page goes deeper into some technical considerations when working with the most current version of Artblocks Engine Flex. The latest version of the Engine Flex contract (v3) and interface can be found here:","https://github.com/ArtBlocks/artblocks-contracts/blob/main/packages/contracts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol","https://github.com/ArtBlocks/artblocks-contracts/blob/main/packages/contracts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol"]},{"l":"Introduction To External Asset Dependencies","p":["The Engine Flex contract introduces the concept of external asset dependencies. These essentially function as on-chain pointers to off-chain assets stored using decentralized storage technologies and, with the latest version of flex, also supports fully on-chain data storage. An external asset dependency is comprised of its content identifier (CID), if it's using Arweave or IPFS, a bytecodeAddress if it's specifically dealing with fully on-chain data, and a dependencyType, which maps to an Engine Flex supported platform.","Engine Flex currently supports adding external asset dependencies of the following types:","IPFS","Arweave","Onchain (data lives entirely on the blockchain)"]},{"i":"adding-updating--removing-external-asset-dependencies","l":"Adding, Updating & Removing External Asset Dependencies","p":["When working with and manipulating a project's external asset dependencies, you'll be relying on the following functions:","Note the parameter _cidOrData, which allows you to either pass in a CID if you are working with the IPFS/Arweave dependencyTypes or a data string if you are working with the onchain dependencyType.","For convenience and utility, the contract also provides the following function, allowing you to easily grab a project's external asset dependency at a specific index:","This convenience function returns data in the form of the following format:","Note that for dependencyTypes other than onchain (IPFS, Arweave), the returned bytecodeAddress will be the zero address and data will be an empty string. Conversely, if the dependencyType is onchain, the returned cid will be an empty string.","Some important factors to keep in mind with the above functions:","Only allowlisted/artist addresses can call these.","ExternalAssetDependencyType _dependencyType is a solidity enum, which can be passed into these functions as a uint8. This enum only defines three options as of now, IPFS, ARWEAVE, and ONCHAIN, which can be represented as 0, 1, and 2 respectively."]},{"l":"Note On Removing External Asset Dependencies","p":["In the interest of saving gas, the removeProjectExternalAssetDependency() function is implemented in such a way that it does not preserve the order of the project's external asset dependency mapping. Specifically, the way this removal logic works is as follows: when an index to remove is passed in, the element at that index being removed is swapped with the element at the last index of the list of assets. Now that the last index holds the element to be removed, that element is removed off the list. This method, in addition to being more gas efficient, also ensures that our list/mapping does not have any \"holes\". The tradeoff, however, is that the removal causes the order of the external asset dependencies in this list to change, albeit in a deterministic manner: the element at the last index always moves to the removed index. This is important to keep in mind when writing your project script, though you can always update the ordering manually as you see fit by utilizing the updateProjectExternalAssetDependency() function.","You can view directly the full implementation of this removal function here: https://github.com/ArtBlocks/artblocks-contracts/blob/main/packages/contracts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol#L524"]},{"l":"Preferred Gateways","p":["The Engine Flex contract allows you to specify preferred gateways for the currently supported dependency types (IPFS & Arweave). Gateways are accessible HTTP interfaces and, when combined with an asset CID, expose urls for assets being stored on these off-chain decentralized platforms. These preferred gateways are updateable with a string param via the following functions: updateArweaveGateway()& updateIPFSGateway().","Please note that these preferred gateways are set per-contract, not per-project."]},{"l":"Working With External Asset Dependencies In Your Project Script","p":["When you request the live view for a given token of a project, the hash and tokenId of the token are provided in the tokenData object and the Art Blocks Generator injects this into the served HTML live view. This tokenData object has now been extended with the following external asset dependency related data, if it is available:","Your project script can then easily make use of these dependencies by combining the CID of the asset with the appropriate gateway, if you are dealing with IPFS/Arweave dependencies. As a simple example: If you have an external asset dependency with a CID QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg and a dependencyType of IPFS, you can construct the full url of your external asset dependency by combining the preferredIPFSGateway, which let's assume is https://ipfs.io/ipfs/, with the asset CID. This gives you the full url of the asset, https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg, and allows your project script to download it with fetch and use it as it sees fit. For fully onchain external asset dependencies, the full data string that is stored on the blockchain will be injected.","Note that for IPFS/Arweave external asset dependencies if your CID is pointing to a directory of assets, rather than a single asset, your project script will need to be aware of the file naming structure of this directory to fetch the assets individually. Using the previous example, imagine that CID QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg was pointing to a directory of 10 PNG images, with filenames corresponding to the numbers 1-10. Your project script would generate the same full url with the information provided, https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg, but also append the specific file you want to fetch by being aware of the naming conventions, ie https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg/1.png."]},{"l":"Loading JS Libraries As External Asset Dependencies","p":["If you are specifically looking to utilize an IPFS/ARWEAVE type external asset dependency as a JavaScript library in your project script, you cannot simply add it as a script element onto the page. You must load it in a blocking manner so that the browser does not attempt to run your project script code before the lib is fully loaded. Here is an example of how to do this with ES6 dynamic imports (supported by most modern browsers: https://caniuse.com/es6-module-dynamic-import):","Here's another method without using ES6 dynamic imports, instead relying on using a callback that gets fired after the JS external asset dependency is injected into the html via a script tag:"]},{"i":"locking-a-projects-external-asset-dependencies","l":"Locking A Project's External Asset Dependencies","p":["Artists and allowlisted addresses also have the ability to lock a project's external asset dependencies:","This irreversible action removes the ability to add, update or remove from a project's external asset dependencies.","Important notes:","Preferred gateways do not get locked with this action and, in general, cannot be locked. This is intentional to allow support for modifying the preferred gateway over time, which may change while CIDs remain fixed/permanent.","You can lock a project's external asset dependencies regardless of whether or not the project itself is locked. And you can continue to modify a project's external dependencies even if the project is locked, as long as the external asset dependencies for the project are not locked."]},{"i":"why-should-i-use-the-engine-flex-specific-fields-for-cids-and-ipfs-gateways-rather-than-hard-coding-these-values-in-the-script","l":"Why should I use the Engine Flex specific fields for CIDs and IPFS gateways rather than hard-coding these values in the script?","p":["The Engine Flex contract was designed to expose specific on-contract fields for storing external asset dependencies (either via auxiliary on-chain storage, IPFS CIDs, or Arweave CIDs). For collectors and archivists preserving these art works, this increases the introspect-ability of where these external assets are stored, e.g. allowing for a more streamlined and robust process for replicating external assets stored on IPFS for a given project in the future.","Additionally, after project scripts are locked, if an IPFS gateway is hardcoded it isn't possible to update this in the future if the gateway (but not the underlying asset CIDs) needs to change for whatever reason (partner is migrating gateway providers from Pinata to Infura, partner is shutting down private gateway in favor of a public one, etc.). If using the specified on-chain fields, the CIDs can be locked independently from the gateway, allowing flexibility to preserve future compatibility of the on-chain generator down the road."]}],[{"l":"Common Custom Dashboard Mutations"},{"l":"Introduction","p":["As an Engine partner, you have the option to create a custom artist/admin dashboard. While the majority of your project configuration will occur through on-chain transactions, there are specific off-chain fields that need to be set directly via our GraphQL API.","This documentation outlines the permissions necessary for executing relevant actions and mutations. Please note that a user can only execute a mutation with the artist role for a project if their public address matches the artist address set for the project. A user can execute a mutation with the allowlisted role only if they are the super admin on the project's contract's ACL contract (V3 and up), or if they have been whitelisted on the project's contract (V2 and below).","For all mutations listed in this documentation, the user must include the x-hasura-role header in their request, specifying either artist or allowlisted as the role, as appropriate."]},{"l":"Actions","p":["Actions are specialized mutations that go beyond simple CRUD operations. Within your custom creator dashboard, you might find the updateFeatures and updateProjectMedia actions particularly useful.","The updateFeatures action initiates a test run of a feature script for a test token. Upon validating that the output aligns with the provided feature fields, it updates both the feature_fields and feature_script on the project. Both artists and allowlisted users can execute this action. Artists can make updates either before the project is completed, or afterwards, if the allowlisted user has toggled the enable_artist_update_after_completion flag on the project's associated features row.","The updateProjectMedia action refreshes various media assets linked to a project's tokens. The refreshed media depends on the parameters passed to the action, which may include different formats of preview images and features. This action is accessible to both artists and allowlisted users. However, the execution of this action is rate-limited to once 24 hours for artists.","Here are the parameters accepted by the updateProjectMedia action:","projectId: The ID of the project to be updated.","features: A boolean that indicates whether to recalculate features for the project's tokens.","render: A boolean that indicates whether to re-render the preview images for the project.","renderVideo: A boolean that indicates whether to re-render preview videos/gifs for the project.","All these actions are executed via specific mutations in the GraphQL API."]},{"l":"Tags","p":["Tags and projects share a many-to-many relationship, managed through the entity_tags table. Tags serve as non-functional descriptors that can be used to categorize projects. To associate a tag with a project, the insert_entity_tags mutation is used.","In the context of an Engine dashboard, you're likely most interested in presentation tags, which can be fetched with the following query:","Both the artist and contract admin roles have the permissions to execute the insert_entity_tags mutation. Here's an example of how to use this mutation:"]},{"l":"Project","p":["-","All these fields are updated using the update_projects_metadata_by_pk mutation.","Allowlisted Permission","Allows artists to acknowledge contributors, inspirations, or other sources of influence.","Artist Permission","artist_display_notes","artist_interview","charitable_giving_details","Contains the artist's intentions for how the artwork should be displayed.","creative_credit","Description","Determines whether GIFs and MP4s are generated during individual token refreshes, batch token refreshes, and new token mints.","disable_sample_generator","Enables the artist to specify a token ID to feature. Determines the token displayed as the project's cover image on our flagship site.","featured_token_id","Field","generate_video_assets*","Indicates the artist's preference for displaying project previews. Influences whether the \"explore possibilities\" modal is displayed on the project page on our flagship site.","link_to_license","Outlines any charitable giving aspects associated with the project.","Please note: In the tables above, 'X' stands for write permissions, and '-' stands for no write permissions.","preview_render_type","primary_render_type","Provides a link to an interview with the artist.","Provides a link to the copyright license for the project (e.g., \"https://creativecommons.org/licenses/by-nc-nd/4.0/\").","Provides specific details about the sales mechanics of the project.","render_delay*","sales_notes","Sets the delay (in seconds) before our renderer captures a snapshot of the project for preview images.","Sets the intended start time of the project, indicating when it will become unpaused and active.","Specifies the preferred format for displaying the project on detail pages.","Specifies the preferred format for the project's preview images.","start_date","The table below lists permissions for directly updating relevant off-chain fields on the project row. Many of these fields are optional and are intended to enrich the descriptive content on your frontend. Fields marked with an asterisk (*) have a functional impact on the project.","X"]}],[{"l":"Minter Suite Migration Runbook","p":["This documentation is a work in progress. Minter suite migration is ongoing, and initial migrations are being actively worked. Please reach out to the Art Blocks team with any questions.","This page provides a step-by-step guide on how to migrate a V3 Art Blocks Engine core contract from the legacy non-shared minter suite to the new shared minter suite. This migration is required for all V3 Engine contracts that want to use the new shared minter suite, which has the following benefits:","All minter contracts are indexed by the Art Blocks subgraph, and can therefore be configured in the new Artist Dashboard website (coming soon)","All minter Art Blocks Flagship minting contracts become available for use by Engine projects","Collectors can purchase from the same trusted contract they interact with on Flagship.","Art Blocks will release an SDK to simplify the minting process for Engine projects (coming soon)","Migration is not available for V2 Engine contracts; for Engine partners that wish to upgrade to a V3 Engine contract, please contact the Art Blocks team.","Migration is not required for V3 Engine contracts that wish to continue using the legacy non-shared minter suite. However, we recommend migrating to the new shared minter suite for the benefits listed above."]},{"l":"Migration Steps"},{"l":"1. Engine partner frontend updated to support new minter suite","p":["In the coming months, the Art Blocks team will be releasing a new minting SDK that can be used to support the new shared minter suite. Documentation for the SDK will be referenced here when it becomes available.","MinterDAExpHolderV5","MinterDAExpSettlementV3","MinterDAExpV5","MinterDALinHolderV5","MinterDALinV5","MinterSetPriceERC20V5","MinterSetPriceHolderV5","MinterSetPriceMerkleV5","MinterSetPricePolyptychERC20V5","MinterSetPricePolyptychV5","MinterSetPriceV5","The Engine partner's frontend must be updated to support the new shared minter suite. In general, the new shared minter suite requires the following changes:","The source code of all new, shared minter contracts is available on the Art Blocks smart contracts monrorepo. The complete list of all new, shared minter contracts is:","View functions on the minter contracts may have changed slightly. This is due to some minor architectural changes to the minter contracts that we believe simplifies their codebase and make them more extensible.","When specifying a project to configure or purchase from, an additional input arg of coreContract(address) must be specified. This is because one minter/minter filter contract is used for many core contracts."]},{"l":"2. Schedule downtime for any live projects","p":["The migration process requires all artists with live projects configure a new minter. All live projects should be paused during the migration process. Switching to the new minter filter is simple, but after migrating to the new minter filter, the artist of every live project must configure their minter in the new minter suite. This is also only a few transactions, but it is fully reliant on coordinating with artists to be ready to re-configure minters of open projects after switching to the new minter filter."]},{"i":"3-core-contract-admin-sends-migration-transactions-testnet-before-mainnet","l":"3. Core contract admin sends migration transactions (testnet before mainnet)","p":["0x13178A7a8A1A9460dBE39f7eCcEbD91B31752b91","0x28f2D3805652FB5d359486dFfb7D08320D403240","0x6a5976391E708fBf918c3786cd1FcbB88732fbc1","0x94560abECb897f359ee1A6Ed0E922315Da11752d","0xa07f47c30C262adcC263A4D44595972c50e04db7","0xa2ccfE293bc2CDD78D8166a82D1e18cD2148122b","0xC91CFC2062D8B4Ff53A7c8836CAEf925a7C78c81","0xD1d9aD8B1B520F19DFE43Cc975b9470840e8b824","Arbitrum One","Artist Staging Arbitrum-Sepolia","Artist Staging Goerli","Artist Staging Sepolia","Engine Admin calls updateMinterContract on the core contract, passing in the address of the shared minter filter.","Engine Admin calls updateRandomizerAddress on the core contract, passing in the address of the shared randomizer","Mainnet (Ethereum)","Network","Shared Minter Filter Contract Address","Shared Randomizer Contract Address","The Engine partner's core contract admin should send 2 transactions to the core contract:","You are now using the new shared minter suite!"]},{"l":"4. Artists re-configure minters for ALL LIVE PROJECTS","p":["AFTER step 3, artists must re-configure their minters for all live projects. This is a quick process, but requires coordination with artists to ensure they are ready to re-configure their minters after the switch.","Artists can re-configure their minters manually by following the instructions documented in the engine project launch/assigning a minter section. Additionally, soon, artists will be able to configure their project minters via the (new) Artist Dashboard.","The process for most open projects will likely be to switch to a fixed price minter.","After configuring a minter, the project is now using the new shared minter suite and live for minting!"]},{"l":"5. Engine partner monitors migration progress","p":["It is recommended that the Engine partner monitor the migration process to ensure that all artists have successfully re-configured their minters. Additionally, the Engine partner should use diligence to ensure that purchases and payment splits after the migration are working as expected."]},{"i":"6-add-any-custom-one-off-minters-to-the-shared-minter-suite","l":"6. Add any custom, one-off minters to the shared minter suite","p":["The new shared minter suite provides all Art Blocks Flagship minters to Engine projects. However, if the Engine partner has any custom, one-off minters that they would like to use for their core contract, they can be added for their specific contract. Please see please see the Adding custom, one-off minters page for steps on how to do this.","Note that at this time, custom, one-off minters will not be indexed in the Art Blocks Subgraph or API. This is likely not a change for custom minters being used prior to migration."]},{"l":"7. Explore new minter suite features","p":["The new shared minter suite provides all Art Blocks Flagship minters to Engine projects. Feel free to explore integrating new minters into your product!"]},{"l":"Migration FAQ"},{"i":"what-happens-if-an-artist-does-not-re-configure-their-minter","l":"What happens if an artist does not re-configure their minter?","p":["If an artist does not re-configure their minter, their project will not be able to mint tokens. The artist will need to re-configure their minter before their project can mint tokens."]},{"i":"what-happens-if-an-artist-re-configures-their-minter-incorrectly","l":"What happens if an artist re-configures their minter incorrectly?","p":["If an artist re-configures their minter incorrectly, best case scenario is that their project will not be able to mint tokens, and troubleshooting can identify the issue. Worst case scenario is that their project will be able to mint tokens, but the price per token will be incorrect (e.g. incorrect price entered) or the maximum invocations will be too high (e.g. forgot to set minter-max-invocations to a lower value than set on the core contract, if desired). For these reasons, artists should use diligence when re-configuring their minters."]},{"i":"what-happens-if-i-migrate-to-the-new-shared-minter-suite","l":"What happens if I migrate to the new shared minter suite?","p":["If you migrate to the new shared minter suite, you will be able to use any new minters developed for Art Blocks Flagship. Additionally, you will be able to use the Artist Dashboard to configure your minters, because your minter suite will be indexed. You will also be able to use the new minting SDK to simplify your minting process."]},{"i":"what-happens-if-i-do-not-migrate-to-the-new-shared-minter-suite","l":"What happens if I do not migrate to the new shared minter suite?","p":["If you do not migrate to the new shared minter suite, nothing will change, but you will miss out on new developments. You will not be able to use any new minters developed for Art Blocks Flagship. Additionally, you will not be able to use the Artist Dashboard to configure your minters, because your minter suite will not be indexed. You will need to continue to use the legacy non-shared minter suite."]},{"i":"what-happens-if-i-migrate-to-the-new-shared-minter-suite-but-i-do-not-want-to-use-the-coming-soon-artist-dashboard-to-configure-my-minters","l":"What happens if I migrate to the new shared minter suite, but I do not want to use the (coming soon) Artist Dashboard to configure my minters?","p":["There are many reasons why a partner might want to do this!","If you migrate to the new shared minter suite, but you do not want to use the Artist Dashboard to configure your minters, you can continue to configure your minters via your frontend, etherscan, etc., but your process will be slightly updated to support the new shared minter suite. Comparing the new minter contracts and the legacy minter contracts will help you understand the changes."]},{"i":"what-happens-if-i-migrate-to-the-new-shared-minter-suite-but-i-do-not-want-to-use-the-new-coming-soon-minting-sdk","l":"What happens if I migrate to the new shared minter suite, but I do not want to use the new (coming soon) minting SDK?","p":["No problem!","If you migrate to the new shared minter suite, but you do not want to use the new minting SDK, you can continue to use your existing minting process, but your process will be slightly updated to support the new shared minter suite."]}],[{"l":"Overview of V3 Core Contract","p":["The Art Blocks V3 Core Contract allows Art Blocks Curated artists, Studio artists, and Engine partners to create generative art projects on the blockchain. The contract is a shared contract that allows for multiple projects to be created and managed by different artists and creators. The V3 Core Contract is designed to be flexible and extensible, allowing for a wide range of generative art projects to be created."]},{"l":"Variants","p":["The V3 Core Contract comes in two variants:","V3 Engine","V3 Engine Flex","Both of these implementations are available for use by Art Blocks Studio artists and Engine partners.","The V3 Engine contract offers the same functionality as the original Art Blocks contract, with an artist's script being fully defined only on the blockchain. The V3 Engine Flex extends the ways artists may store additional metadata, with options of using re-usable on-chain assets, using decentralized storage networks such as IPFS or Arweave, or pointing to assets defined on the Art Blocks Dependency Registry (some of which are fully defined on-chain, some of which are defined on preferred CDN services).","For more discussion about different NFT metadata storage mechanisms, see the NFT Metadata Storage at Art Blocks page."]}],[{"l":"Creator Dashboard","p":["V3 core contracts may be managed by partners, artists and creators using the Art Blocks Creator Dashboard. The dashboard provides a user-friendly interface for managing projects, tokens, and other contract settings. The dashboard is accessible at https://create.artblocks.io.","Various features are available to creators, including:","Project Management: Create, edit, and manage projects.","Project Creation: Add new projects to your contract.","Payment Management: Manage payment addresses, view current royalty splitter address, etc."]}],[{"l":"ERC-2981 Royalties","p":["For v3.2+ contracts (all Studio contracts, Engine contracts deployed after May 2024), Art Blocks contracts conform to the ERC-2981 standard for royalties.","Note: All versions of Art Blocks core contracts integrate seamlessly with the Royalty Registry, which is supported by all major secondary marketplaces.","The ERC-2981 standard requires that royalty payments be made to a single address. Art Blocks contracts support this standard by integrating with 0xSplits to facilitate multi-party royalty payments to multiple addresses, all funneled through a single, permissionless, immutable \"splitter contract\" address.","Artists may view their current royalty splitter address in the Art Blocks Creator Dashboard. The royalty splitter address is deployed and set automatically by the v3.2+ Art Blocks core contract when payment information is configured. A link to the current splitter is available in the dashboard, and distribution of funds in the splitter may be viewed and executed via the 0xSplits website. Note that 0xSplits provides a user-friendly interface for viewing splitter balances and executing distributions, as well as robust report generation tooling.","Note: 0xSplits is a third-party service and is not affiliated with Art Blocks."]}],[{"l":"Manual Admin Operations","p":["Some rarely used admin operations are not available in the Art Blocks Creator Dashboard. These operations are available via direct interaction with the contract via a service such as Etherscan or Gnosis Safe's Transaction Builder.","A few manual admin operations are detailed below."]},{"l":"Update provider secondary royalties payment addresses or basis points","p":["Note: this describes the process for updating provider secondary royalty information - artist updates are handled within the Art Blocks Creator Dashboard.","For all V3 contracts, the contract admin can update the provider secondary royalties payment addresses or basis points by calling any of the following functions on the contract:","function updateProviderSalesAddresses","function updateProviderPrimarySalesPercentages","function updateProviderSecondarySalesBPS or function updateProviderDefaultSecondarySalesBPS(depending on minor version)","For v3.2+ contracts (deployed after May 2024), the contract admin must also propagate the contract-level changes to every project in the contract by calling the following function on the contract for each project:","syncProviderSecondaryForProjectToDefaults(uint256 projectId)","Note: The additional step of syncing provider secondary royalties to defaults was added in v3.2 to enable conformance to the ERC-2981 royalty info standard while remaining scalable within ethereum's block gas limit."]}],[{"i":"#","p":["Updated location of Creator Onboarding documentation."]},{"i":"moved---creator-onboarding-documentation","l":"Moved! - Creator Onboarding Documentation","p":["To keep things more up to date, we have moved the Creator Onboarding documentation to a new location. Navigate there for the most recent information!"]}],[{"i":"#","p":["An overview of minting philosophy at Art Blocks."]},{"l":"Minting Philosophy","p":["An overview of the generative art minting philosophy at Art Blocks."]},{"l":"Introduction","p":["At Art Blocks, minting is a particularly special occasion where a new generative art piece is created. It is the final step in the generative art creation process, and enables collectors to partner with artists to create a unique, one-of-a-kind piece of generative art!","On a blockchain, \"minting\" is the process of creating new tokens. So not only is minting the process of creating new generative art pieces, it is also the process of creating new tokens on a blockchain. Typically, minting is also the point where a collector will pay for the generative art piece.","A few key points about minting at Art Blocks:","Minting is the process of creating new generative art pieces.","Minting is the process of creating new tokens on a blockchain.","Minting generally involves a collector paying for the right to create a generative art piece."]},{"l":"Core Principles","p":["At Art Blocks, we are committed to providing a transparent minting toolkit for artists, and a transparent minting experience for collectors.","The following principles, when used together, are important ideals that we believe enable artists to achieve some sort of \"fairness\" during their drop. They also are key to collector safety when interacting on a blockchain."]},{"l":"1. Transparency","p":["We believe that minting should be transparent and easy to understand for collectors. Verified source code is provided for all minter smart contracts, and we develop our minters publically in our open source GitHub repository."]},{"i":"2-decentralized--trust-minimized","l":"2. Decentralized & Trust-Minimized","p":["We believe that minting should rely heavily on immutable smart contract code deployed to decentralized networks, and should be as trustless as possible. We aim to minimize the amount of trust in any centralized party when minting. This is important because collectors must feel safe when purchasing high-value generative art pieces, and trusting a centralized party to mint a generative art piece is often not an acceptable option.","Of course Artists and Art Blocks will have some elevated privileges, such as configuring auctions, but we aim to minimize those privileges and implement only when necessary. Those privileges will be documented and transparent, and should align incentives."]},{"l":"3. Non-Custodial","p":["Minting should be a transaction between the collector and the minter smart contract, and the contract should handle logic related to settlements, price changes over time, etc.","The minter smart contract should empower the collector to make their own decisions, and should not be custodial in nature."]},{"l":"4. Honest","p":["Blockchains have a unique set of technical quirks that can be exploited by opportunistic or malicious actors. These result in frequent discussions about bots, \"flipping\", and front-running.","We are committed to providing solutions to help alleviate these issues, but we are also committed to being honest about their limitations. Solutions must have sound fundamentals, and ones that only hide or obfuscate minting bots or other issues are not real solutions, and therefore should not be implemented. See the Lessons Learned section for more examples of this."]},{"l":"5. Flexible","p":["In some situations, a project may desire to mint in a way that is highly centralized or in some other non-traditional manner. An example of this would be a project that utilizes in-person minting at an event. In this case, the project may choose to mint from a single, centralized mobile device, but should be transparent about that decision."]},{"i":"fairness-ideals","l":"\"Fairness\" Ideals","p":["Fairness is a concept that is often discussed in the context of minting, and is worth investigating in some amount of nuance.","In an abstract sense, fairness is easy to define. Merriam-Webster defines fairness as:","\"marked by impartiality and honesty: free from self-interest, prejudice, or favoritism\".","In practice, however, fairness of a project's mint is much more difficult to define. In one sense, Art Blocks drops are entirely fair:","Open sale at a defined price or auction","Mint success is determined by transaction time/order","Transaction confirmation time is determined by the network's gas price auction","In another sense, there are many different ways to define fairness, and each definition has its own set of tradeoffs. In general, we believe there are a few types of fairness that are important to consider when an artist is considering how to distribute their project to collectors:"]},{"l":"1. Capitalist Fairness","p":["Capitalist fairness suggests that those who are willing to pay the most for a given drop should be the ones who are able to participate.","An example of a drop paradigm that is capitalist fair is a Dutch auction. In a Dutch auction, the price of a generative art piece starts high, and decreases over time until a collector is willing to pay the price. This ensures that the collector who is willing to pay the most for a generative art piece is the one who is able to mint it."]},{"l":"2. Insider Fairness","p":["Insider fairness suggests that those within an existing community should be the ones who are able to participate.","An example of a drop paradigm that is insider fair is an allowlist. In that paradigm, a collector must have reached out to an artist before the project was released to be allowed to mint. This ensures that the collector who is most involved and interested in a community is the one who is able to mint a generative art piece."]},{"l":"3. Communist Fairness","p":["Communist fairness suggests that all collectors should have an equal chance to participate, regardless of their technical skills or willingness to pay.","An example of a drop paradigm that optimizes for communist fairness would be a pure lottery, where all collectors have an equal chance to mint a generative art piece. This ensures that all collectors have an equal chance to mint a generative art piece."]},{"l":"Fairness in Practice","p":["In practice, it is difficult to achieve any of the above definitions of fairness in a pure sense. For example, a pure lottery is not possible on Ethereum, because the network is not able to discern humans from bots, and therefore a pure lottery would be susceptible to bots spamming entries and disproportionately winning the lottery.","Art Blocks aims to provide a variety of minting options for artists to choose from, each with their own set of tradeoffs. We believe that artists should be able to choose the minting paradigm that best fits their project's goals.","The minters provided by Art Blocks are intended to follow our design principles while also achieving some kind of fairness. However, each minter's amount of fairness and susceptibility to bots will vary based on:","project demand/hype","project price","market conditions","gas prices","etc.","For example, if a highly-anticipated project is sold at a low fixed-price, it is likely that bots will be able to mint a large number of generative art pieces. However, if a less-anticipated project is sold at a fixed-price, it is likely that bots will not mint a large number of generative art pieces because the speculative value of the generative art piece is not high enough to flip for a short-term profit.","The minters provided by Art Blocks are not inherently fair or unfair in nature, but when used carefully, they can provide a minting experience that stays true to our principles while also providing some amount of fairness. We believe that it is important for artists to understand the tradeoffs of each minter, and to choose the minter(s) that best fits their project's goals."]},{"l":"Minter Suite","p":["The minter suite is a collection of smart contracts that aim to provide different options for artists to distribute their project's tokens to collectors. A variety of minters are available for artists to choose from that can be used to create a variety of different minting experiences. The minters are designed to be flexible and extensible, but also to provide a consistent and familiar minting experience for collectors.","The shared minter suite is used by Art Blocks, and is also available for use with Art Blocks Engine contracts (V3 only).","More details will be added regarding the shared minter suite in the future, but for now, please see the Shared Minter Suite page for an overview of all available flagship minters at this time."]},{"l":"Lessons Learned","p":["Below is a collection of lessons that we have learned from our experience with minting generative art pieces on Ethereum."]},{"i":"one-mint-per-wallet-does-not-prevent-bots-without-an-allowlist","l":"One mint per wallet does not prevent bots (without an allowlist)","p":["In the past, we have implemented a \"1 mint per wallet\" rule, which was intended to prevent bots from minting a large number of generative art pieces. However, this rule was not effective, and actually gave an advantage to bots.","For a botter, minting from 1 or 100 wallets is nearly the same difficulty. However, for a typical collector not using bots, minting from multiple wallets adds a lot of difficulty. Ultimately, the \"1-per\" restriction puts the average collector at a huge disadvantage relative to a botter.","The \"1 mint per wallet\" rule is also somewhat misleading because it may lead collectors to believe that a project's distribution is well-diversified, when in reality, it might only be owned by a network of bots operating at many addresses.","In the end, this rule was not effective, harmed less-technical collectors, and was therefore abandoned.","Note: Limiting the number of mints per wallet on an allowlist is a different paradigm, and is a valid way to limit the number of mints per wallet."]},{"l":"Disabling minting from smart contracts does not prevent bots","p":["In the past, we have implemented a rule that prevented minting from smart contracts. This was intended to prevent bots from minting a large number of generative art pieces. However, this rule was not effective, because bots are able to mint from EOAs (externally owned accounts), and therefore are still able to mint a large number of generative art pieces.","The \"no minting from smart contracts\" rule is also somewhat misleading because it may cause collectors to believe that a project's was bot-resistant, when in reality, it is not an effective way to prevent bots from minting.","In the end, this rule was not effective, harmed collectors that wanted to mint from a smart contract (including from security-forward multi-sig wallets such as Gnosis Safe), and was therefore abandoned."]},{"l":"One mint per transaction does not prevent bots","p":["This is a rule that is implemented by some NFT projects, and is intended to prevent bots from minting a large number of generative art pieces. However, this rule is not effective, because bots are able to mint a large number of generative art pieces by submitting multiple transactions to the network's pending transaction pool.","Additionally, most implementations of this rule prevent minting from smart contracts, which is harmful to collectors that want to mint from multi-sig wallets. Other solutions require collectors to pay for additional gas fees for on-chain storage to support the rule's logic, which is also harmful to collectors.","In the end, this rule is not effective, harms less-technical and/or security-conscious collectors, and was therefore abandoned."]},{"i":"low-fixed-prices-favor-bots","l":"Low, fixed prices favor bots","p":["In general, low, fixed prices favor bots because they are able to mint a large number of generative art pieces and flip them for a short-term profit. This is especially true when the project is highly-anticipated, and when the project's generative art pieces are expected to have a high speculative value.","Bots have a large advantage over humans when it comes to minting at low, fixed prices, because they are able to submit transactions to the network's pending transaction pool at a high rate, and are able to pay high gas prices to ensure that their transactions are confirmed quickly.","In general, we recommend that artists consider using a Dutch auction or an allowlist to mitigate the effects of bots when minting at low, fixed prices."]}],[{"l":"Shared Minter Suite","p":["This page provides an overview of the Art Blocks Shared Minter Suite, which enables artists to choose how they distribute their artwork to collectors.","The Shared Minter Suite is available for all projects, including Art Blocks Engine projects.","For legacy contracts, core contract admins can view the Minter Migration Runbok for details about how to migrate to the shared minter suite."]},{"l":"Mix-and-Match","p":["Artists can mix-and-match minter options to create a custom minter configuration for their project. For example, an artist could initially use the allowlist minter to allow a specific set of collectors to mint one token per allowlisted wallet, and then could open up minting to the public via a switch to a Dutch auction with settlement minter.","Each minter supports limiting to a certain number of project invocations. For example, an artist could allow Minter A to be used for the first 1000 project invocations, and then switch to Minter B for the remaining project invocations."]},{"l":"Globally Available Minter Options","p":["The current available Minter options are discussed below. We are continually expanding our shared minter suite over time."]},{"i":"set-price---eth","l":"Set price - ETH","p":["The set price minter is used for fixed price releases. It is the simplest minter and prices all tokens at the same price, in ETH."]},{"i":"set-price---eth-allowlisted-users-only","l":"Set price - ETH, allowlisted users only","p":["Extends the functionality of the Set price, ETH minter to allow only wallets on an allowlist to mint. The allowlist can be configured to limit minting to a predetermined list of wallet addresses, and artists can specify the number of mints allowed per wallet."]},{"i":"set-price---eth-token-holders-only","l":"Set price - ETH, token holders only","p":["Extends the functionality of the Set price, ETH minter to allow only holders of a specific ERC-721 token to mint."]},{"i":"set-price---custom-erc20","l":"Set Price - custom ERC20","p":["Set price in ERC20 is a fixed price minter that allows accepting any ERC20 token as payment for your sale of tokens.","Custom ERC20 tokens can be used for a variety of purposes, including for a \"mint pass\" style experience."]},{"i":"dutch-auction-wsettlement---exponential-price-decrease","l":"Dutch auction (w/settlement) - exponential price decrease","p":["When this minter is used, all collectors will pay the same net-price as the final purchaser. This is typically the most fair and equitable Dutch auction type for buyers because all buyers pay the same price, making it a great auction type for many projects.","Collectors who purchase above the lowest price will be able to claim a settlement after the auction. The settlement will be the difference between the price they purchased at and the final purchase price. All funds are held non-custodially by the smart contract until the auction ends and revenues are collected by the artist or admin.","Exponential price curves approximate a constant percent decrease over time, making them a popular choice for Dutch auctions.","If an artist reduces the max supply of their project mid-auction, and the project sells out above auction base price, revenues must be withdrawn by core contract admin. This was implemented to protect collectors from an artist unilaterally potentially inflating sellout price during an action, and immediately withdrawing revenues. Admin concurrence is required to withdraw revenues in this case.","For supplemental information about the auction reset process, please see the Auction Reset Process section."]},{"i":"dutch-auction---exponential-price-decrease","l":"Dutch auction - exponential price decrease","p":["For Dutch auctions without settlement, artists specify the starting price, ending price, and the half-life for price drops. Collectors will pay more for tokens purchased earlier in the auction, and less for tokens purchased later in the auction.","Exponential price curves approximate a constant percent decrease over time, making them a popular choice for Dutch auctions.","For supplemental information about the auction reset process, please see the Auction Reset Process section."]},{"i":"dutch-auction---linear-price-decrease","l":"Dutch auction - linear price decrease","p":["For Dutch auctions without settlement, artists specify the starting price, ending price, and the duration of the auction. Collectors will pay more for tokens purchased earlier in the auction, and less for tokens purchased later in the auction.","Linear price curves provide a constant price decrease over time.","Two price curves are available for Dutch auctions without settlement: exponential and linear. Exponential price curves approximate a constant percent decrease over time, while linear price curves provide a constant price decrease over time.","For supplemental information about the auction reset process, please see the Auction Reset Process section."]},{"i":"dutch-auction---exponential-price-decrease-token-holders-only","l":"Dutch auction - exponential price decrease, token holders only","p":["This minter extends the functionality of the Dutch auction minter to allow only holders of a specific ERC-721 token to mint."]},{"i":"dutch-auction---linear-price-decrease-token-holders-only","l":"Dutch auction - linear price decrease, token holders only","p":["This minter extends the functionality of the Dutch auction minter to allow only holders of a specific ERC-721 token to mint."]},{"l":"Ranked auction","p":["The Ranked Auction minter allows for a ranked auction process where collectors can submit bids for a limited number of tokens. The highest bidders will receive tokens, while losing bidders will receive a refund.","All winning bids pay the same price, which is the lowest winning bid.","The ranked auction process happens non-custodially on-chain, and is scalable to arbitrarily large projects. Artists may incur gas costs associated with minting tokens for winning bidders."]},{"l":"Serial English auction","p":["The Serial English Auction (SEA) minter allows for a series of English auctions for individual tokens to be run in sequence. The minter was originally inspired by the popular nouns.wtf project, and was implemented with minor adjustments to provide a seamless experience for Art Blocks artists and collectors.","Artists may configure future token auction parameters, such as starting auction price and minimum auction length. Collectors may then kick off token auctions by submitting a bid for a pre-minted token. Once an auction begins, any wallet may submit a higher bid for the token up for sale. Losing bids are refunded automatically when outbid. If a bid is submitted near the end of an auction, the auction is extended such that a human is able to submit a higher bid, ensuring a human can fairly compete against a bot.","Once an auction is complete, another token auction may be started by any collector submitting a bid for the next token, while also sending the previous auction winner their token.","The minter pre-mints tokens before their auction, so bids are placed on an already-existing token, not on hypothetical tokens.","The minter may be used for any project, and is certainly ideal for projects that have a series of tokens that are released in a sequence. It may also be used to auction off a 1:1 token. The minter is also ideal for projects that have a strong community, as it allows for community members to participate in the auction process over a long period of time, carefully considering each generative output.","Bids and auction parameters are stored on-chain, and the Art Blocks subgraph and API index all historical bids in bids_metadata as well as auction parameters in project_minter_configurations."]},{"l":"Minimum price minter","p":["This minter enables artists to distribute tokens at a minimal price to collectors.","A small mint fee is sent to the render provider to help with the costs of rendering and indexing tokens."]},{"i":"minimum-price-minter-allowlisted-users-only","l":"Minimum price minter, allowlisted users only","p":["This minter enables artists to distribute tokens at a minimal price to an allowlisted set of collectors. The allowlist can be configured to limit minting to a predetermined list of wallet addresses, and artists can specify the number of mints allowed per wallet.","A small mint fee is sent to the render provider to help with the costs of rendering and indexing tokens."]},{"i":"polyptych-copy-hash-minter","l":"Polyptych (copy-hash) minter","p":["This minter enables the artist to mint tokens with identical token hashes. This is useful for projects that are intended to be displayed as a polyptych.","This minter allows either artists to mint child tokens to a parent token holder's wallet, or allows the parent token holder to mint child tokens.","An artist's script must work closely with the minter to ensure that the correct frame is used for each token number. For example, if a project has 3 frames, the artist's script must ensure that e.g. tokens 0-99 are minted with frame 1, tokens 100-199 are minted with frame 2, and tokens 200-299 are minted with frame 3. The artist is able to increment the frame number for their project on the minter.","This minter is technically complex, and artists must also configure the shared randomizer when using this minter.","Limited creator dashboard support is available for this minter at this time, so some interactions with the minter must be done via a service such as [Etherscan]]( https://etherscan.io/).","Despite the complexity of this minter, the resulting outputs can be very powerful and rewarding for artists and collectors!"]},{"i":"polyptych-copy-hash-minter-custom-erc20","l":"Polyptych (copy-hash) minter, custom ERC20","p":["This minter extends the functionality of the polyptych minter to allow accepting any ERC20 token as payment for your sale of tokens."]},{"i":"custom-one-off-minters","l":"Custom, One-Off Minters","p":["Engine partners can also create custom, one-off minters for their projects. These minters are only available to projects on the Engine contract that approves them, extending the globally set of available minters for their contract.","For more information about adding custom minters to your Engine contract, please see the custom minters page."]}],[{"i":"custom-one-off-minters","l":"Custom, One-Off Minters","p":["Some Engine partners may wish to add custom, one-off minters to the shared minter suite. This is able to be done by the admin of an Engine partner's core contract.","Due to the high flexibility available to custom minters, they are not indexed by the Art Blocks subgraph, and therefore are not able to be configured by artists via the Art Blocks frontend. Instead, the custom minter will need to be configured via the Engine partner's frontend, etherscan, etc.","The steps to add a custom, one-off minter to the shared minter suite are as follows:"]},{"l":"1. Write the custom minter contract","p":["The Engine partner will need to write the custom minter contract. The Art Blocks team can assist with providing guidance on how to translate a previously written, non-shared custom minter contract to be compatible with the new shared minter suite, if needed.","At a minimum, the custom minter contract will need to implement the ISharedMinterRequired interface, which is available in the Art Blocks smart contracts monrorepo. This interface requires the custom minter contract to implement the following functions:","Additionally, the custom minter contract will need to call the mint_joo function on the shared minter filter contract to mint tokens. This function is included in the IMinterFilterV1 interface in the Art Blocks smart contracts monrorepo."]},{"l":"2. Deploy the custom minter contract","p":["The Engine partner will need to deploy the custom minter contract to the desired network."]},{"l":"3. Allowlist the minter for the core contract on the shared minter filter contract","p":["The Engine partner will need to allowlist the custom minter contract for their contract, on the shared minter filter contract. This is done by doing the following:","Engine Admin calls approveMinterForContract on the shared minter filter contract, passing in the address of their core contract, and the custom minter contract","The custom minter is now ready to be used by projects on the Engine partner's core contract!"]},{"l":"4. Artist configures the custom minter for their project","p":["The artist will need to configure the custom minter for their project. Custom, one-off minters are not indexed by the Art Blocks subgraph (due to the minter being arbitrary and open-ended), so the artist will need to configure the custom minter via the Engine partner's frontend, etherscan, etc. Note that the typical minter filter function for setting a minter for a project, setMinterForProject should be used by the artist or admin to assign the custom minter for the project."]}],[{"l":"Minter Suite Supplemental Information","p":["This page provides supplemental information for the Art Blocks Shared Minter Suite.","The information below is generally most relevant for Engine core contract admins."]},{"l":"Auction Reset Process","p":["A subset of minters utilizes automated, scheduled auctions to distribute artwork to collectors. The auction reset process is a mechanism that allows artists to pause and reschedule their auction, within certain limitations, if an issue arises during a live project release. Example situations may be:","Unexpected website downtime","Artist unintentionally left project in a paused state","Auction parameters were not set as intended","Some of the possible failure modes above can result in a state where:","Collectors are not able to purchase tokens from the website","Bots are still able to purchase tokens by submitting transactions directly to the blockchain","If in a state where bots can purchase but humans can not, the situation requires immediate action to prevent or minimize damage."]},{"i":"1-urgent-pause-the-auction","l":"1. [URGENT] Pause the Auction","p":["The most important step in the auction reset process is for the Artist pause the auction. This prevents any further purchases from being made.","Tips:","Ensure that the project is not already paused (i.e. this step is already complete), and do not toggle the pause button more than once (i.e. pause then unpause)","Artist should use a very high gas price to ensure that the pause transaction is mined quickly","Artist should use a tool like Etherscan to monitor the status of the pause transaction","Verify the paused state of the contract by checking the project's core contract on a tool like Etherscan","DA with Settlement: This step is especially urgent! Settlement minters require that every new purchase price is less than or equal to the previous purchase price (even after an auction is reset). If a bot purchases a token prior to a project being paused, that project’s reconfigured auction (even after reset) is constrained to only be able to start at the bot’s purchase price."]},{"l":"2. Reset auction","p":["When using a Dutch auction, the auction will need to be reset and reconfigured.","This is a 2-step process, and requires admin-intervention for security:","ADMIN - Call resetAuctionDetails on the minter contract","ARTIST - Configure the auction parameters via your typical process (e.g. artist dashboard)"]},{"i":"3-communicate-and-enjoy","l":"3. Communicate and enjoy!","p":["Ensure your collectors are aware of the new auction parameters, and enjoy the new auction!"]},{"i":"allowlist-minter-details-non-shared-minter-suite-only","l":"Allowlist Minter Details (non-shared minter suite only)","p":["The Allowlist Minter uses a Merkle tree to gas-efficiently allow a set of addresses to mint tokens from a project.","Merkle trees are a data structure that allows for efficient verification of whether a given element is contained in a set. In the case of the Allowlist Minter, the Merkle root is stored on-chain, and Merkle proofs are included with every purchase transaction to verify that a given address is allowed to mint a token.","The information below is included to assist Engine partners in using the Allowlist minter with their projects. However, if using the shared minter suite, the Art Blocks subgraph and api are available to index Engine minter suite data, and this information is not required.","Fundamentals","The Merkle allowlist minter follows the following basic process:","An allowlist of wallet addresses is stored off-chain (e.g. in a csv file)","The artist uploads the Merkle root of the list of addresses to the Minter contract via function updateMerkleRoot","Collectors calculate and include a Merkle proof with their purchase transaction to verify that their address is included in the allowlist","Example Usage","The following typescript code demonstrates how a Merkle root and proof may be calculated for a given allowlist:"]},{"l":"Pre-Assigning Token Hash Seeds","p":["After minting is complete, the artist should call toggleProjectUseAssignedHashSeed() to disable the use of assigned hash seeds for the project, and allow the randomizer to pseudorandomly assign hash seeds to tokens as normal.","Confirm on SharedRandomizerV0's read function hashSeedSetterContracts() that the hash seed setter contract is now set to the artist wallet for the project.","Confirm on SharedRandomizerV0's read function projectUsesHashSeedSetter() that the project is now configured to use pre-assigned hash seeds (should return true).","coreContract: The address of the core contract for the project","hashSeed: The hash seed to assign to the token","hashSeedSetterContract: The address that will assign hash seeds to tokens - recommend in this use-case to set this to the artist wallet","Identify and confirm that your contract is using a SharedRandomizerV0 contract. Visit your core contract on etherscan (or appropriate L2 explorer, e.g. basescan) and inspect the read-only function randomizerContract() to confirm that the randomizer contract is a SharedRandomizerV0.","MINT! Ordering may be critical if minting specific tokens to specific addresses, so the artist may need to keep the project paused and call purchaseTo in a specific order. No other changes to the minting process are required. Confirming token hashes are as expected along the way is highly recommended.","Navigate to the SharedRandomizerV0 contract on etherscan (or appropriate L2 explorer, e.g. basescan), and connect your artist wallet. Alternatively, if your artist wallet is a multisig, interact with the sharedRandomizerV0 in something like Gnosis Safe's Transaction Builder (this is more efficient and convenient when assigning hash seeds for many tokens).","On SharedRandomizerV0, call the toggleProjectUseAssignedHashSeed() function with the artist wallet the following parameters:","On SharedRandomizerV0, from the artist wallet, call preSetHashSeed() for each token that you want to assign a hash seed to (Multicall using something like a gnosis safe is very helpful if assigning many tokens here). This function takes the following parameters:","On SharedRandomizerV0, from the artist wallet, call to the setHashSeedSetterContract function with the following parameters:","ProjectId: The ID of the project to toggle the use of assigned hash seeds for","Set the hash seed setter contract back to the zero address by calling setHashSeedSetterContract from the artist wallet.","The process for pre-assigning token hash seeds is as follows:","The shared randomizer SharedRandomizerV0 enables an artist to pre-assign token hash seeds for tokens on a project. This allows an artist to assign a specific hash seed to a token before it is minted, and then mint the token with that hash seed at a later time.","The steps above follow the pattern implemented in the following test case: shared-randomizer-v0/configure.test.ts:assigns_expected_token_when_polyptych\"","tokenId: The token ID to assign the hash seed for","tokenId: The token ID to check the hash seed for","You may confirm that token hash seeds have been properly assigned by calling the preAssignedHashSeed() read-only function on SharedRandomizerV0 with the following parameters:"]}],[{"l":"SeaDrop Integration","p":["This page provides an overview of an integration solution for the Art Blocks Shared Minter Suite with OpenSea's SeaDrop system. This is a special integration that allows Art Blocks projects to be minted and sold on OpenSea via SeaDrop, and is not a standard integration with the Shared Minter Suite.","The integration requires a few non-standard steps to ensure that the SeaDrop contract can interact with the minter suite. The steps below outline the process for integrating SeaDrop with the Art Blocks Shared Minter Suite."]},{"l":"Integration Process","p":["The integration process follows the custom, one-off minter steps, and supports minting on any project that uses the Shared Minter Suite."]},{"l":"1. Artist configures their project","p":["The artist configures their project as they normally would, using the Art Blocks Creator Dashboard.","The only exception is that the artist does not need to configure the minter for their project, as the minter will be configured separately as described in the following steps."]},{"l":"2. Deploy SeaDropXArtBlocksShim Contract","p":["The SeaDropXArtBlocksShim contract is a custom contract that allows the SeaDrop contract to interact with the Shared Minter Suite. This contract must be deployed for each project that will be integrated with SeaDrop, in order to satisfy a 1:1 mapping between the shim contract and the project.","Deployment of the SeaDropXArtBlocksShim contract is a one-time process for each project, and may be deployed by anyone. Deployment of the shim contract requires the following parameters:","Note: The allowedSeaDrop_ parameter should be set to the address of the SeaDrop contract that will be used for the project, defined by OpenSea here: https://github.com/ProjectOpenSea/seadrop/blob/main/README.md#deployments"]},{"l":"3. Admin approve minter for contract","p":["Following the custom, one-off minter steps, the admin must approve the minter for the project's core contract.","Engine Admin calls approveMinterForContract on the shared minter filter contract (via e.g. etherscan or gnosis safe tx builder), passing in the address of their core contract, and the SeaDropXArtBlocksShim custom minter contract"]},{"l":"3. Artist configures the custom minter for their project","p":["Following the custom, one-off minter steps, the artist will need to configure the custom minter for their project. The artist will need to configure the custom minter via etherscan, etc. Note that the typical minter filter function for setting a minter for a project, setMinterForProject should be used by the artist or admin to assign the custom minter for the project."]},{"i":"4-artist-configures-their-drop-on-openseas-studio","l":"4. Artist configures their drop on OpenSea's Studio","p":["The artist will need to configure their drop on OpenSea's Studio.","A general guide for configuring a drop on OpenSea Studio is published by OpenSea here: https://docs.opensea.io/docs/part-2-edit-collection-settings","In OpenSea Studio, the artist should see a new contract available to edit, which will be the SeaDropXArtBlocksShim contract. The artist should configure the drop as they normally would, using the OpenSea Studio interface.","A few options that don't make sense for Art Blocks projects, such as IPFS metadata (Art Blocks projects are on-chain), should be left blank.","If SeaDrop is configured to sell less tokens than the project's max invocations, minting on OpenSea will be limited to whatever is configured in SeaDrop.","Important: The artist must set their primary sales payment address on OpenSea Studio in a manner that properly splits the payment between the artist and the platform and/or render provider. A manually created splitter contract (e.g. using 0xSplits) may be an appropriate solution. Secondary sales will be handled automatically by the Art Blocks Core contract, but primary sales must be configured correctly in SeaDrop by the artist."]},{"l":"5. Notify OpenSea of the integration","p":["The artist should notify Art Blocks and OpenSea of the integration, so that the OpenSea team can ensure that the integration is properly displayed on their website. The shim contract must be properly configured to point to the correct project ID for items to intuitively show up in the OpenSea UI."]},{"i":"6-enjoy","l":"6. Enjoy!","p":["Your Art Blocks tokens are now available for sale on OpenSea via SeaDrop!"]},{"l":"Shim Contract Details","p":["The diagram below illustrates the relationship between different entities and the SeaDropXArtBlocksShim contract, the Shared Minter Suite, and the SeaDrop contract."]}],[{"l":"API Overview","p":["An overview of the current Art Blocks APIs.","Quick Links:","Token API","Generator API","Media API/Media Server","Art Blocks Subgraph","GraphQL API"]},{"l":"Hosted APIs","p":["As a quick overview, the main APIs that exist currently are:"]},{"l":"Token API","p":["Arbitrum One","Arbitrum Testnet","Base Mainnet","Contract Type","Engine","Flagship","https://token.arbitrum-sepolia.artblocks.io/{contractAddress}/{tokenID}","https://token.arbitrum.artblocks.io/{contractAddress}/{tokenID}","https://token.artblocks.io/{contractAddress}/{tokenID}","https://token.artblocks.io/{tokenID}","https://token.artblocks.io/0","https://token.artblocks.io/0x0a1bbd57033f57e7b6743621b79fcb9eb2ce3676/110000","https://token.base.artblocks.io/{contractAddress}/{tokenID}","https://token.sepolia.artblocks.io/{contractAddress}/{tokenID}","https://token.sepolia.artblocks.io/0x6ceab51fc8ee931df84d3db66e747b617eb7de21/12","https://token.staging.artblocks.io/{contractAddress}/{tokenID}","https://token.staging.artblocks.io/0xda62f67be7194775a75be91cbf9feedcc5776d4b/103000000","Mainnet","Note: Contract address is required","Note: Contract address is required for Engine","Pattern","Provides the token metadata for a given Art Blocks token.","Sample","Testnet"]},{"l":"Generator API","p":["Arbitrum One","Arbitrum Testnet","Base Mainnet","Contract Type","Engine","Flagship","https://generator-staging-goerli.artblocks.io/0xda62f67be7194775a75be91cbf9feedcc5776d4b/8000002","https://generator-staging-goerli.artblocks.io/0xe745243b82ebc46e5c23d9b1b968612c65d45f3d/1000001","https://generator-staging-sepolia.artblocks.io/{contractAddress}/{tokenID}","https://generator.arbitrum-sepolia.artblocks.io/{contractAddress}/{tokenID}","https://generator.arbitrum.artblocks.io/{contractAddress}/{tokenID}","https://generator.artblocks.io/{contractAddress}/{tokenID}","https://generator.artblocks.io/{tokenID}","https://generator.artblocks.io/0","https://generator.artblocks.io/0x0a1bbd57033f57e7b6743621b79fcb9eb2ce3676/11000083","https://generator.base.artblocks.io/{contractAddress}/{tokenID}","Mainnet","Note: Contract address is required","Note: Contract address is required for Engine","Pattern","Provides an i-frame-able live-view for the art associated with a given Art Blocks token.","Sample","Testnet"]},{"i":"media-apimedia-server","l":"Media API/Media server","p":["Arbitrum One","Arbitrum Testnet","Base Mainnet","Contract Type","Engine","Flagship","HD Renders – https://media.artblocks.io/hd/{tokenID}.png","https://media-proxy-arbitrum-staging.artblocks.io/{contractAddress}/{tokenID}","https://media-proxy-arbitrum.artblocks.io/{contractAddress}/{tokenID}","https://media-proxy-base.artblocks.io/{contractAddress}/{tokenID}","https://media-proxy-staging.artblocks.io/{contractAddress}/{tokenID}.png","https://media-proxy-staging.artblocks.io/{tokenID}.png","https://media-proxy-staging.artblocks.io/0.png","https://media-proxy-staging.artblocks.io/0xe745243b82ebc46e5c23d9b1b968612c65d45f3d/1000001","https://media-proxy.artblocks.io/{contractAddress}/{tokenId}.png","https://media-proxy.artblocks.io/0x145789247973c5d612bf121e9e4eef84b63eb707/782.png","https://media.artblocks.io/{tokenID}.png","https://media.artblocks.io/0.png","In addition to the standard static renders provided for each token, there are two other static renders currently provided: \"HD\" and \"thumbnail\". These items can be found at:","Mainnet","Note: Contract address is required","Pattern","Please also note that the Generator API and Media API links for a given token are included in the token response for that token from the Token API.","Please note that these additional static render formats are still currently being back-filled and may not yet be present for all tokens. Our current recommendation for those looking to depend on the \"HD\" or \"thumbnail\" responses is to a) first attempt the HD/thumb image resource that you would prefer, b) if this resource is not available, fall back to the standard sized image resource. For the current state of the ongoing backfill of HD and thumbnail assets, please refer to this spreadsheet.","Provides a static snapshot of the rendered live-view for a given Art Blocks token.","Sample","Testnet","Thumbnail Renders – https://media.artblocks.io/thumb/{tokenID}.png"]},{"l":"Art Blocks Subgraph","p":["Art Blocks has subgraphs deployed to The Graph Network for every supported network.","These subgraphs can be used to query for on-chain data related to the Art Blocks contracts, including minter suite data, token data, and project data. They provide a way to access on-chain data in a more efficient and user-friendly way than directly querying the blockchain, while keeping infrastructure decentralized, transparent, and reliable.","As of June 12, 2024, Hosted Service subgraphs are deprecated. Please use the Decentralized Graph Network subgraphs listed below for all networks, or use the Art Blocks' Hasura GraphQL API as an alternative.","The Art Blocks subgraph is developed in public, and all source code and development activity can be found in the Art Blocks subgraph repository."]},{"l":"Ethereum Mainnet","p":["Explorer Page","Graphql Endpoint: https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/6bR1oVsRUUs6czNiB6W7NNenTXtVfNd5iSiwvS4QbRPB"]},{"l":"Arbitrum One","p":["Explorer Page","Graphql Endpoint: https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/5WwGsBwJ2hVBpc3DphX4VHVMsoPnRkVkuZF4HTArZjCm"]},{"i":"artist-staging---sepolia-testnet","l":"Artist Staging - Sepolia Testnet","p":["Explorer Page","Graphql Endpoint: https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/9G5q5avz4X8GZ8UEGdu197433nSWSCsFa2eo6vHNBooc"]},{"i":"artist-staging---arbitrum-sepolia-testnet","l":"Artist Staging - Arbitrum-Sepolia Testnet","p":["Explorer Page","Graphql Endpoint: https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/33E6obKFpWGUhnWD5eja74Gt6oTXktiHMZVFrshg9xGe"]},{"l":"Helpful Resources","p":["Video Tutorial on creating an API Key","Managing your API Key & setting your indexer preferences","Querying from an application","How to use the explorer and playground to query on-chain data"]},{"l":"Querying the Subgraph","p":["The Art Blocks subgraphs can be queried at any of the graphql endpoints listed in the previous section."]},{"l":"Getting Minter Details","p":["A few example queries are provided below to help you get started with querying the Art Blocks subgraph for data related to a project's minter. In addition to the subgraph, the fields are also able to be queried from our Hasura GraphQL API. In the future, Art Blocks will release an SDK that will interact with these data in an even more convenient way.","Note that only Engine contracts that have migrated to the shared minter suite will have their minters indexed and available on the subgraph and Hasura GraphQL API. Only globally approved minters are indexed, so custom, one-off minters designed by Engine partners will not be indexed.","A project's active minter configuration (as configured in the artist dashboard) may be queried by pulling it from the Project entity:","note: if querying the Hasura GraphQL API, use projects_metadata instead of project","The extraMinterDetails json field of minterConfiguration will contain a JSON string that can be parsed to obtain the project-minter-configuration details that may be specific to the minter type. For example, for a Dutch Auction minter, the extraMinterDetails field may contain the following JSON string:","note: if querying the Hasura GraphQL API, the returned type will be a JSONB","Additionally, the minter's extraMinterDetails will contain a JSON string that can be parsed to obtain any minter-specific configuration details. For example, for a Dutch Auction minter, the extraMinterDetails field may contain the following JSON string:","note: if querying the Hasura GraphQL API, use minters_metadata instead of minters, and the returned type will be a JSONB","All of these queries can help you to obtain information about a project's minter configuration, which can be used to display purchase information for the project on your website. The data are available on both the subgraph, and the Hasura GraphQL API."]},{"l":"GraphQL API","p":["Arbitrum","Base","Chain","Environment","Ethereum","https://ab-prod-arbitrum.hasura.app/v1/graphql","https://ab-prod-base.hasura.app/v1/graphql","https://ab-staging-arbitrum.hasura.app/v1/graphql","https://ab-staging-goerli.hasura.app/v1/graphql","https://ab-staging-sepolia.hasura.app/v1/graphql","https://data.artblocks.io/v1/graphql","Mainnet","Production","Provides a broader set of the data that our front-end consumes — this includes both on-chain and off-chain data.","Staging","Staging (deprecated)","URL"]},{"l":"Authentication","p":["The following documentation explains how to authenticate with the Art Blocks API to retrieve a JSON Web Token (JWT). This JWT can then be used to gain authenticated access to our GraphQL API. The methods explained here are intended for a client-side environment where a signer is available to sign messages. The procedures are explained using two approaches: Direct API endpoints and GraphQL.","We recommend using the GraphQL-based approach as we have more control over it and can ensure its stability even if underlying API endpoints change. Note that the domain for authentication may change in the future for the Direct API-based approach, while the GraphQL endpoint will remain the same."]},{"i":"graphql-based-authentication-flow-recommended","l":"GraphQL-based Authentication Flow (Recommended)","p":["The GraphQL-based approach leverages the GraphQL schema provided by Art Blocks. This is the recommended approach for stability and future-proofing your implementation.","Here are the functions used in this flow:"]},{"l":"Direct API-based Authentication Flow","p":["The Direct API-based approach involves interacting with the https://artblocks.io/api/get-auth-message and https://artblocks.io/api/authenticate endpoints. We recommend using the GraphQL-based flow instead because of its improved stability and future-proofing, but we're providing the Direct API-based method for those who prefer it.","⚠️ Warning: The domain for authentication may change in the future for the Direct API-based approach. Using the GraphQL-based approach is recommended to avoid future disruptions.","Here are the functions used in this flow:","In both methods, you will find a placeholder /* code to sign message goes here */ where you should implement your code to sign the message using your client-side signer."]},{"l":"Using the JWT for Authenticated Access","p":["Once the JWT has been obtained using either of the above methods, it can be used to make authenticated requests to the Art Blocks GraphQL API. The JWT should be included in the Authorization header of the request. Here's an example:","For a full detailed overview of this GraphQL API, please reference: https://docs.artblocks.io/public-api-docs/","Additionally, you can use this interactive Hasura playground to test out queries: https://cloud.hasura.io/public/graphiql?endpoint=https://data.artblocks.io/v1/graphql"]}],[{"l":"Artblocks Viewer","p":["An overview of live.artblocks.io"]},{"l":"Routes","p":["All routes are for the environment specified in .env file and act as such. i.e. Ropsten contracts will not work on mainnet and vice versa","live.artblocks.io/ Home page of the site which returns the latest rendered minted token from any of the Art Blocks contracts","live.artblocks.io/{CONTRACT_ADDRESS} enter any Art Blocks or Engine contract and you be presented with the latest rendered mint.","Example: Latest Artblocks_VO mint","live.artblocks.io/{CONTRACT_ADDRESS}/{PROJECT_INDEX} enter any Art Blocks or Engine contract followed by the index of the project and you be presented with the latest rendered mint.","Example: Latest Chromie Squiggle mint","live.artblocks.io/token/{TOKEN_ID} enter any Art Blocks or Engine token id and you are presented with that token.","Example: Chromie Squiggle mint #71","live.artblocks.io/random/{CONTRACT_ADDRESS} enter any Art Blocks or Engine contract address and you are presented with a random active project","Example: Random Art Blocks v3 contract","live.artblocks.io/random/{CONTRACT_ADDRESS}/{PROJECT_INDEX} enter any Art Blocks or Engine contract address and a project index you are presented with a random token from that project","Example: Random Chromie Squiggles"]},{"l":"Random Query Params","p":["You can add any query params from the customizable display listed below as well as two random specific query params.","reloadClick: this is to turn on click reloading where if you click the token it will give you a new token from that project. default: false","reloadDelay: this is to turn on auto refreshing after the specified time in seconds to give you a new token from that project. default: none","Example URLs:","Click turned on","Delay of 30 seconds and click turned on","Delay of 30 seconds with no click"]},{"l":"Contracts","p":["This is a running list of contract addresses for various Art Blocks and Engine","Mainnet:","Artblocks_VO: 0x059edd72cd353df5106d2b9cc5ab83a52287ac3a","Artblocks_V1: 0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270","ARTCODE: 0xd10e3dee203579fcee90ed7d0bdd8086f7e53beb","Doodle Labs: 0x28f2d3805652fb5d359486dffb7d08320d403240","CryptoCitizens: 0xbdde08bd57e5c9fd563ee7ac61618cb2ecdc0ce0","Flutter: 0x13aae6f9599880edbb7d144bb13f1212cee99533","MOMENT: 0x0a1bbd57033f57e7b6743621b79fcb9eb2ce3676","Plottables: 0xa319c382a702682129fcbf55d514e61a16f97f9c","TBOA: 0x62e37f664b5945629b6549a87f8e10ed0b6d923b"]},{"l":"Customizable Display","p":["A Plottables project (full screen)","Algobots (with text)","All of the customization that can be done and the default values are as follows:","backgroundColor: this can be any six digit hex color and is the background color of the page default: ffffff","Example URLs:","fontSize: this can be any valid html size and is the size of the text default: 20px","height: this can be any valid html size and is the height of the token being displayed default: 90vh","Latest Artblocks Mint","Latest Chimera","showText: this is whether or not to show the text information about the currently displayed token. All other text params depend on this to be true to work default: false","Streamlines #414","textBackground: this can be any six digit hex color and is the background color of the text default: none","textBottom: this can be any valid html size and is the distance from the bottom of the screen of the text default: 3em","textColor: this can be any six digit hex color and is the color of the text default: 000000","useCustomViewParams: this is to specify you are using the custom view display and all other params require this to be true. default: false","width: this can be any valid html size and is the width of the token being displayed default: 90vw","You can create a customizable display for any route on artblocks-viewer. This is done through query params added to the end of the url. In order to activate this ability you must first add ?useCustomViewParams=true to the end of whatever route you are using. Here is the most basic customized url of Chromie Squiggle mint #71 with just the squiggle centered in the middle of the page."]}],[{"l":"Querying","p":["Below are some sample queries you can use to gather information from the Art Blocks contracts.","You can build your own queries using a GraphQL Explorer and enter your endpoint to limit the data to exactly what you need."]},{"l":"Subgraph Querying Walkthrough","p":["The following provides some examples of how to use the Art Blocks subgraph to perform a handful of common queries."]},{"l":"Important Notes","p":["Performance/indexing on the hosted subgraph service is oftentimes slower compared to the decentralized subgraph. That being said, the hosted subgraph is free while the decentralized one requires pay-per-query in GRT.","The Art Blocks subgraphs currently also index any PBAB (Powered by Artblocks) contracts, in addition to the core Art Blocks contracts. Please keep that in mind and make use of the contract_in filter to ensure you are working with Art Blocks data only, if that is your intention.","While querying against the mainnet subgraph if using the contract_in filter the Art Blocks contracts to restrict for are 0x059edd72cd353df5106d2b9cc5ab83a52287ac3a(for the V0 contract that supports projects 0-3) and 0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270(for the V1 contract that supports projects 4-current).","The Art Blocks contract to restrict for is 0xda62f67be7194775a75be91cbf9feedcc5776d4b on testnet."]},{"l":"The Basics","p":["Retrieving a specific Art Blocks project by short ID (no contract):","Retrieving a specific Art Blocks project by full ID (includes contract):","Retrieving a specific Art Blocks token by short ID (no contract):","Retrieving a specific Art Blocks token by full ID (includes contract):"]},{"l":"Beyond The Basics","p":["Retrieve the last 5 most recently created projects across Art Blocks and Powered by Art Blocks (remember that you can use a contract_in filter to restrict this to only specific contracts):","Retrieve the top 10 projects across Art Blocks and Powered by Art Blocks, based on # of invocations:","Retrieve the most recently minted Art Blocks token:","Retrieve all tokens owned by a specific address, across Art Blocks and Powered by Art Blocks:","Retrieve the general metadata/status for the Art Blocks subgraph (useful for debugging):","Retrieve the project script for a given project id","Pagination should be used for large queries. The Graph enforces upper limits on first and skip parameters since they generally perform poorly when set to large values (limits as of 01/2022 are first=1000 and skip=5000). It is much better to page through entities based on an attribute such as token ID, block number, or some other parameter. For more information, see The Graph documentation"]},{"l":"Project info","p":["Pull all projects and return their name, as well as lots of additional data:","Get all the wallet owners of a project (Replace PROJECT with the project name you are looking for)","If you're looking for the addresses of anyone that owns a mint from a project","Get that txnhash for squiggle 0, you could run the following query on the AB subgraph playground"]}],[{"l":"Entities","p":["Account","AccountProject","Contract","CoreRegistry","Dependency","DependencyAdditionalCDN","DependencyAdditionalRepository","DependencyRegistry","DependencyScript","Minter","MinterFilter","MinterFilterContractAllowlist","Project","ProjectExternalAssetDependency","ProjectMinterConfiguration","ProjectScript","ProposedArtistAddressesAndSplit","Receipt","Token","Transfer","Whitelisting"]},{"l":"Project","p":["A project is complete when it has reached its maximum invocations","Account!","AccountProject!","Accounts that own tokens of the project","activatedAt","active","additionalPayee","additionalPayeePercentage","additionalPayeeSecondarySalesAddress","additionalPayeeSecondarySalesPercentage","Address to split primary sales with the artist","Address to split Secondary sales with the artist","artist","Artist description of the project","Artist name","Artist or project website","Artist that created the project","Artist/additional payee royalty percentage","artistAddress","artistName","Aspect ratio of the project (see scriptJSON if null)","aspectRatio","baseIpfsUri","baseUri","BigInt","BigInt!","Boolean","Boolean!","Bytes","Bytes!","complete","completedAt","contract","Contract associated to project","Contract!","createdAt","Curated, playground, factory. A project with no curation status is considered factory","curationStatus","Currency symbol for ERC-20","currencyAddress","currencySymbol","Description","Description: get various details about a specific project","Determines if the project should be visible to the public","Does the project actually use the hash string","Does the project use media from ipfs","dynamic","ERC-20 contract address if the project is purchasable via ERC-20","externalAssetDependencies","externalAssetDependenciesLocked","externalAssetDependencyCount","Extra information about the script and rendering options","Field","For V3 and-on, this field is null, and projects lock 4 weeks after completedAt. Once the project is locked its script may never be updated again","id","ID of the project on the contract","ID!","Interplanetary File System function that meets the encrypted demands needed to solve for a blockchain computation","invocations","ipfsHash","Is the project dynamic or a static image","license","License for the project","locked","Lookup table to get the Sale history of the project","Maximum number of invocations allowed for the project","maxInvocations","Minter configuration for this project (not implemented prior to minter filters)","minterConfiguration","name","Number of times the project has been invoked - number of tokens of the project","Once the project's external asset dependencies are locked they may never be modified again","owners","Parts of the project script","paused","Percentage of artist's share of primary sales that goes to additional payee","Percentage of artist's share of secondary sales that goes to additional payee","pricePerTokenInWei","Project name","Project!","ProjectExternalAssetDependency!","projectId","ProjectMinterConfiguration","Projects external asset dependencies","Proposed Artist addresses and payment split percentages","ProposedArtistAddressesAndSplit","proposedArtistAddressesAndSplits","Purchases paused","royaltyPercentage","SaleLookupTable!","saleLookupTables","script","Script type and version (see scriptJSON if null)","scriptCount","scriptJSON","scripts","scriptTypeAndVersion","scriptUpdatedAt","String","The base URI is the mutual part among each NFT's URI. By default, the URI is baseURI/tokenId","The full script composed of scripts","The number of external asset dependencies stored on-chain","The number of scripts stored on-chain","Timestamp at which a project was completed","Token!","tokens","Tokens of the project","Type","Uniform Resource Identifier Interplanetary File System (IPFS) of a nonfungible token","Unique identifier made up of contract address and project id","updatedAt","useHashString","useIpfs","Wallet address of the artist","website","Wei is the smallest denomination of ether—the cryptocurrency coin used on the Ethereum network. One ether = 1,000,000,000,000,000,000 wei (1018)","WHen project activated","When project initiated","When project updated","when the script was updated"]},{"l":"ProjectScript","p":["BigInt!","Description","Description: get specific details of the project script","Field","id","ID!","index","Name of project","project","Project!","script","Script of the project","String!","The dependency index","Type","Unique identifier made up of contract address and project id"]},{"l":"ProposedArtistAddressesAndSplit","p":["additionalPayeePrimarySalesAddress","additionalPayeePrimarySalesPercentage","additionalPayeeSecondarySalesAddress","additionalPayeeSecondarySalesPercentage","artistAddress","BigInt!","Bytes!","createdAt","Description","Description: get specific details on the pay flow for a specified artist","Field","id","ID!","project","Project associated with this proposed artist addresses and splits","Project!","Proposed artist additional payee address for primary sales","Proposed artist additional payee address for secondary sales","Proposed artist additional payee percentage for primary sales","Proposed artist additional payee percentage for secondary sales","Proposed artist address","Type","Unique identifier made up of contract address and project id","When address initiated"]},{"l":"CoreRegistry","p":["Description: Get specific details on the Art Blocks Core registry. At this time, this is used for indexing purposes of V3 contracts, as well as acting as an allowlist of core contracts that may mint on a shared minter filter.","Field","Type","Description","id","ID!","Unique identifier made up of the Core Registry's contract address. note: for legacy MinterFilters, this is a dummy ID, equal to the address of the single core contract associated with the minter filter","registeredContracts","[Contract!]","All core contracts that are registered on this CoreRegistry, when this is the most recent Core Registry to add the contract"]},{"l":"Contract","p":["[Bytes!]!","Accounts whitelisted on the contract","Address that receives primary sales platform fees","Address that receives primary sales platform fees, only for V3_Engine contracts","Address that receives secondary sales platform royalties (null for pre-V3 contracts, check Royalty Registry)","Address that receives secondary sales platform royalties, only for V3_Engine contracts","Associated minter filter (if applicable)","autoApproveArtistSplitProposals","Automatically approve all artist split proposals (used on V3 Engine contracts)","Basis points of secondary sales allocated to the platform (null for pre-V3 contracts, check Royalty Registry)","Basis points of secondary sales allocated to the platform, only for V3_Engine contracts","BigInt","BigInt!","Boolean","Boolean!","Bytes","Bytes!","Core contract type","CoreType!","createdAt","Curation registry contract address","curationRegistry","Dependency registry contract address","dependencyRegistry","Description","Description: get specific information about contracts","enginePlatformProviderAddress","enginePlatformProviderPercentage","enginePlatformProviderSecondarySalesAddress","enginePlatformProviderSecondarySalesBPS","EngineRegistry","Field","id","ID!","Latest engine registry that this contract is registered with, if any (used for indexing purposes)","List of contracts that are allowed to mint","List of projects on the contract","List of tokens on the contract","minterFilter","mintWhitelisted","New projects forbidden (can only be true on V3+ contracts)","newProjectsForbidden","nextProjectId","Percentage of primary sales allocated to the platform","Percentage of primary sales allocated to the platform, only for V3_Engine contracts","preferredArweaveGateway","preferredIPFSGateway","Project ID listed on the contract","Project!","projects","Randomizer contract used to generate token hashes","randomizerContract","registeredOn","renderProviderAddress","renderProviderPercentage","renderProviderSecondarySalesAddress","renderProviderSecondarySalesBPS","String","The Engine Flex contract allows you to specify preferred gateways for the currently supported dependency types (IPFS & Arweave)","Token!","tokens","Type","Unique identifier made up of contract address","updatedAt","When contract initiated","When contract updated","whitelisted","Whitelisting!"]},{"l":"Whitelisting","p":["Description: get whitelist information","Field","Type","Description","id","ID!","Unique identifier whitelist account id","account","Account!","Account associated to whitelisting","contract","Contract!","contract associated to whitelisting"]},{"l":"Account","p":["AccountProject!","Contracts the account is whitelisted on","Description","Description: get specific information about an account","Field","id","ID!","Project!","Projects the account is listed as artist for","Projects the account owns tokens from","projectsCreated","projectsOwned","Token!","tokens","Tokens the account has","Type","Unique identifier account id","whitelistedOn","Whitelisting!"]},{"l":"AccountProject","p":["account","Account associated to project","Account!","count","Description","Description: get project account information","Field","id","ID!","Int!","Name of project","project","Project!","Total count of the project","Type","Unique identifier token id"]},{"l":"Token","p":["Account!","BigInt!","Bytes!","contract","Contract the token is on","Contract!","createdAt","Current owner of the token","Description","Description: get various token information","Field","hash","id","ID of the token on the contract","ID!","invocation","Invocation number of the project","Lookup table to get the Sale history","Next available sale id","nextSaleId","owner","project","Project of the token","Project!","SaleLookupTable!","saleLookupTables","Specifies the endpoint for retrieving access tokens when OAuth 2.0 authentication is enabled","String","tokenId","Transaction hash of token mint","transactionHash","Transfer!","transfers","Transfers of the token","Type","Unique identifier made up of contract address and token id","Unique string used as input to the tokens project script","updatedAt","uri","When token initiated","When token updated"]},{"l":"MinterFilter","p":["[Minter!]!","[MinterFilterContractAllowlist!]!","BigInt!","Core contract registry used by this MinterFilter. Note: For MinterFilter V0 and V1, a dummy CoreRegistry is used","coreRegistry","CoreRegistry!","Description","Description: get details about minters on a project","Field","id","ID!","Known minters that are tied to this MinterFilter, but are not necessarily approved on this MinterFilter","knownMinters","Minter!","minterFilterContractAllowlists","minterGlobalAllowlist","Minters allowlisted at a contract-level on this MinterFilter","Minters allowlisted globally on this MinterFilter","Type","Unique identifier made up of minter contract address","updatedAt","When minter updated"]},{"l":"MinterFilterContractAllowlist","p":["[Minter!]!","BigInt!","contract","Contract!","Core contract","Description","Description: Defines a contract-specific allowlist of minters specifically approved on a given shared minter filter. This is used to extend the set of allowlisted minters beyond a shared minter filter's set of globally allowlisted minters.","Field","id","ID!","Minter contract addresses allowed at the contract level (extending global MinterFilter allowlist)","minterContractAllowlist","minterFilter","MinterFilter contract","MinterFilter!","Type","Unique identifier made up of -","updatedAt","When last updated"]},{"l":"Minter","p":["[Receipt!]","Associated Minter Filter","BigInt!","Boolean representing if the Minter is globally allowed on its associated minter filter","Boolean!","Configuration details used by specific minters (json string)","Description","Description: get details about mint on a project","extraMinterDetails","Field","id","ID!","isGloballyAllowlistedOnMinterFilter","Minter type","minterFilter","MinterFilter!","MinterType!","receipts","Receipts for this minter, only for minters with settlement","String!","Type","Unique identifier made up of minter contract address","updatedAt","When the minter updated"]},{"l":"ProjectMinterConfiguration","p":["basePrice","BigInt","Boolean!","Bytes!","Configuration details used by specific minter project configurations (json string)","currency address as defined on minter - address(0) reserved for ether","currency symbol as defined on minter - ETH reserved for ether","currencyAddress","currencySymbol","Defines if purchasing token to another is allowed","Description","Description: get details of a specific mint","extraMinterDetails","Field","id","ID!","Maximum number of invocations allowed for the project (on the minter)","maxInvocations","minter","Minter!","price of token or resting price of Duch auction, in wei","priceIsConfigured","project","Project!","purchaseToDisabled","String!","The associated minter","The associated project","true if project's token price has been configured on minter","Type","Unique identifier made up of --"]},{"l":"Receipt","p":["account","Account!","BigInt!","Description","Description: get details about purchases on a minter with settlement","Field","id","ID!","Last updated timestamp","minter","Minter!","netPosted","numPurchased","project","Project!","The associated account","The associated minter","The associated project","The total net amount posted (set to settlement contract) for tokens","The total quantity of tokens purchased on the project","Type","Unique identifier made up of ---","updatedAt"]},{"l":"Transfer","p":["address transferred from","address transferred to","BigInt!","Bytes!","createdAt","Description","Description: transfer info on an NFT","Field","from","id","ID!","to","token","token address of NFT","Token!","transaction hash of transfer","transactionHash","Type","Unique identifier of transfer","when transfer initiated"]},{"l":"ProjectExternalAssetDependency","p":["BigInt!","cid","dependencyType","Description","Description: get info about projects external asset dependency","Field","id","ID!","index","project","Project!","ProjectExternalAssetDependencyType!","String!","The associated project","The dependency cid","The dependency index","The dependency type","Type","Unique identifier made up of projectId-index"]},{"l":"Dependency","p":["[DependencyAdditionalCDN!]!","[DependencyAdditionalRepository!]!","[DependencyScript!]!","Additional CDNs for this dependency","Additional repositories for this dependency","additionalCDNCount","additionalCDNs","additionalRepositories","additionalRepositoryCount","BigInt!","Concatenated string of all scripts for this dependency","Dependency registry contract that this dependency is registered on","dependencyRegistry","DependencyRegistry!","Description","Description: information about registered dependency (e.g. p5js@1.0.0)","Field","id","ID!","List of on-chain scripts that for this dependency","Number of additional CDNs for this dependency","Number of additional repositories for this dependency","Number of on-chain scripts for this dependency","Preferred CDN for this dependency","Preferred repository for this dependency","preferredCDN","preferredRepository","Reference website for this dependency (e.g. https://p5js.org)","referenceWebsite","script","scriptCount","scripts","String","String!","Timestamp of last update","Type","Unique identifier made up of dependency name and version separated by an @ symbol (e.g. p5js@1.0.0)","updatedAt"]},{"l":"DependencyRegistry","p":["[Contract!]!","[Dependency!]","BigInt!","Bytes!","Core contracts that this registry can provide dependency overrides for","Current owner of this contract","dependencies","Description","Description: information about a dependency registry contract","Field","id","List of dependencies that are registered on this registry contract","owner","supportedCoreContracts","Timestamp of last update","Type","Unique identifier made up of dependency registry contract address","updatedAt"]},{"l":"DependencyAdditionalCDN","p":["BigInt!","cdn","dependency","Dependency this additional CDN belongs to","Dependency!","Description","Description: information about an additional CDN for a dependency","Field","id","ID!","index","Index of this additional CDN","String!","Type","Unique identifier made up of dependency id and index","URL of the CDN"]},{"l":"DependencyAdditionalRepository","p":["BigInt!","dependency","Dependency this additional repository belongs to","Dependency!","Description","Description: information about an additional repository for a dependency","Field","id","ID!","index","Index of this additional repository","repository","String!","Type","Unique identifier made up of dependency id and index","URL of the repository"]},{"l":"DependencyScript","p":["address","Address of the bytecode storage contract for this script","BigInt!","Bytes!","Contents of script","dependency","Dependency this script belongs to","Dependency!","Description","Description: information about a script for a dependency","Field","id","ID!","index","Index of this script","script","String!","Type","Unique identifier made up of dependency id and index"]}]]
\ No newline at end of file
+[[{"i":"welcome-to-the-art-blocks-docs","l":"Welcome to the Art Blocks Docs!","p":["This documentation seeks to provide guidance for 3 primary audiences:","artists/creators preparing their projects to launch on Art Blocks or an Art Blocks Engine platform","current and prospective Engine partners","integrators/aggregators/marketplaces etc., looking to integrate with the Art Blocks APIs","You will find the three main sections in our documentation mirrors these three primary audiences. Please explore the docs here, and let us know if you have any questions.","For any issues with the docs, please file a bug here, or send us a PR with a suggested change!","GitPOAPs"]}],[{"i":"#","p":["An overview of different NFT metadata storage mechanisms used by Art Blocks NFTs."]},{"l":"NFT Metadata Storage at Art Blocks","p":["An overview of NFT metadata storage philosophy and implementations at Art Blocks."]},{"l":"Summary","p":["Art Blocks tokens store their metadata fully on-chain, ensuring collectors that their NFTs will always remain accessible and immutable.","For projects that require dependencies (e.g. p5js), Art Blocks provides the Art Blocks Dependency Registry, a fully on-chain software registry that can be used to optionally store dependency releases on-chain, as well as reference preferred software storage networks.","Art Blocks Engine Flex NFTs also provide the option to store metadata on decentralized storage networks, such as IPFS or Arweave, to enable larger sized assets to be used when generating outputs."]},{"l":"Overview of NFT Metadata Storage Options","p":["~ Yes","~ Yes 3","Cost","Decentralized","Decentralized Storage Network","Fully On-Chain","Guaranteed to Persist Forever 1","Hash On-Chain","High","Immutable","Low","Medium","No","No 2","No, Very Low Risk","Servers/Hosting","Software Registry","Storage Type","While all NFTs track token ownership on a blockchain, the metadata for the NFT (image or audio information, artist information, etc.) may be stored in a variety of ways. Common options include:","Yes"]},{"i":"servershosting","l":"Servers/Hosting","p":["The metadata are stored on a server or cloud hosting service, such as AWS. This is a convenient and cheap option, but it has a few drawbacks:","The metadata can be changed by the server owner, so the NFT is not immutable.","The metadata can be lost if the server goes down or an admin decides not to discontinue paying for the service.","The metadata can be censored by the server owner."]},{"l":"Hash On-Chain","p":["The hash of the metadata is stored on-chain, and the metadata is stored on a server. Storing the hash of the metadata makes the NFT immutable, while keeping it much cheaper than storing all of the metadata on-chain. However, it has a few drawbacks:","The metadata can be lost if the server goes down or an admin decides not to discontinue paying for the service.","The metadata can be censored by the server owner.","Projects such as CryptoPunks originally stored the hash of the metadata on-chain, but the metadata was stored on a server. They have since upgraded to a fully on-chain solution."]},{"l":"Decentralized Storage Network","p":["The metadata are stored on a decentralized storage network, such as IPFS or Arweave. This is a popular option, and enables the NFT to be immutable. Drawbacks include:","The metadata must remain pinned by at least one party in order to be accessible."]},{"l":"Fully On-Chain","p":["The metadata are stored on the blockchain. This is the most expensive option, but it has many advantages. The metadata are always accessible and available, as long as the NFT exists. Collectors and artists never have to worry about a token's outputs disappearing."]},{"l":"Software Registries","p":["Some NFTs (like some Art Blocks project tokens) may rely on published software libraries when generating outputs. In these cases, the NFT metadata may include information about dependencies and where to find them (e.g. \"p5js, v1.0.0 on the cdnjs software registry\"). Software registries are a special form of decentralized storage, because of the distributed nature of the software repositories and many downloads on developers' computers worldwide."]},{"l":"Art Blocks Storage Solutions"},{"l":"Art Blocks Fully On-Chain","p":["Art Blocks Flagship and Art Blocks Engine NFTs only rely on fully on-chain storage solutions, plus allowing a single dependency to be housed on a software registry. This provides an extremely high level of confidence that the NFTs will remain fully accessible and immutable for the foreseeable future.","While Art Blocks originally relied on widely used software registries to house dependencies, the Art Blocks team has since created a fully on-chain software registry called the Art Blocks Dependency Registry. The registry is fully decentralized and is used by all Art Blocks Flagship NFTs. The registry enables dependencies to be stored fully on-chain, when the gas costs are justified. Art Blocks uploaded their first dependency, p5js v1.0.0, to the registry in January 2024, retiring any doubt that projects relying on p5js@1.0.0 would ever be unable to generate their outputs in the future."]},{"l":"Engine Flex","p":["Art Blocks Engine Flex NFTs provide an additional option for storing metadata. Flex NFTs can store metadata on-chain, or they can store the metadata immutably on the IPFS or Arweave decentralized storage networks. This allows Flex NFTs to utilize larger sized assets when generating outputs, while still providing the option for fully on-chain metadata where possible."]},{"l":"Examples"},{"l":"On-Chain Script Example","p":["Let's review an example of how to retrieve the token and script metadata for the first Art Blocks Token, token zero of project 0, Chromie Squiggle by Snowfro.","Note: Newer versions of Art Blocks core contracts have different function names than the V0 Art Blocks core contract shown in this example.","While we could query the Art Blocks Subgraph or API to retrieve the metadata, we will retrieve the metadata directly from the blockchain.","Visit the original Art Blocks Core Contract on Etherscan: 0x059EDD72Cd353dF5106D2B9cC5ab83a52287aC3a","Get project 0's metadata by calling the projectDetails function with the project ID as the input parameter:","projectDetails","Get project 0's script details by calling the projectScriptInfo function with the project ID as the input parameter:","scriptDetails","Get the script javascript by calling the projectScriptByIndex function with the project ID and index 0 as the input parameter. The returned text is the javascript code that is used to generate Chromie Squiggles!","scriptByIndex","Get token 0's token hash by calling the showTokenHashes function with the token ID as the input parameter. This is the hash that is injected into the script to generate the token's unique output.","tokenHash"]},{"l":"On-Chain Dependency Example","p":["Let's review an example of how to retrieve the dependency metadata for the first Art Blocks Token, token zero of project 0, Chromie Squiggle by Snowfro.","In this case, the project uses the p5js v1.0.0 dependency, which is stored fully on-chain via the Art Blocks Dependency Registry. While we could query the Art Blocks Subgraph or API to retrieve the metadata, we will retrieve the metadata directly from the blockchain.","Visit the Art Blocks Dependency Registry on Etherscan: 0x37861f95882ACDba2cCD84F5bFc4598e2ECDDdAF","Get the dependency details by calling the getDependencyDetails function with the dependency name and version as the input parameters. At this time, we translate from the string p5@1.0.0 to its bytes representation 0x703540312e302e30:","dependencyDetails","Get the dependency code by calling the getDependencyScript function with the dependency name and version as the input parameters. We again translate to the bytes representation 0x703540312e302e30, and can increment the index to get all 10 chunks of the dependency code:","dependencyScript","And that's it! We now have all of the information we need to generate the token's output, and we can be confident that the metadata will always be available and immutable!","Note: At this time, dependency scripts are stored compressed via gzip on-chain. Updates are planned to store code that can unzip the dependencies.","As long as the blockchain network continues to exist.↩","Requires ≥1 interested party↩","Typically hash of release is published to prevent tampering/changes↩"]}],[{"i":"#","p":["Art Blocks Generator."]},{"l":"Art Blocks Generator","p":["The Art Blocks Generator combines artist scripts with token metadata to create unique generative art NFTs. This document outlines the basics of how the generator works, the structure of the token metadata, and related requirements for artist scripts."]},{"l":"HTML Document","p":["The Art Blocks Generator builds an html document that includes:","A tokenData object that contains on-chain metadata for the NFT, including the token's hash and ID.","The artist's on-chain project script","(optional) A dependency used by the script. p5js, for example, is a common dependency.","(optional) For flex projects, external asset dependencies from the Art Blocks Dependency Registry.","The HTML document created by the Generator may look something like the following:","An on-chain version of he Art Blocks Generator is in development, which will allow for even more robust preservation of Art Blocks projects."]},{"l":"The tokenData Object","p":["The tokenData object is injected into the html document by the Art Blocks Generator. It contains the following fields:","For Art Blocks Flex projects, the tokenData object may also include:","The dependency_type field will be one of the following values:","IPFS","ARWEAVE","ONCHAIN","ART_BLOCKS_DEPENDENCY_REGISTRY","Note that project scripts are responsible for fetching any IPFS or Arweave assets."]},{"l":"Learning More","p":["For additional technical resources and documentation, please refer to the Technical Requirements described in the help.artblocks.io documentation."]}],[{"l":"Art Blocks Engine 101","p":["** Note: ** It is possible to use multisig wallets if our client's front-end properly populates access lists in their front end, but minting from Etherscan will not work.","8.** Repeat steps 2-7 for mainnet deployment.**","A high-level process map for Art Blocks Engine onboarding.","After testnet deployment, there are two steps that may proceed in parallel.","After the above has all been performed, you should run through the following \"pre-flight\" checklist and ensure there are no loose threads:","After the complete end-to-end integration has been vetted on testnet, the above process may proceed on mainnet.","After the terms of engagement are finalized, you’ll sign the Engine service and setup agreement.","After you've set up and tested an Engine project, you can request a script audit from Art Blocks to guarantee resolution-agnosticism and determinism.","An ETA for this infrastructure integration piece will be given at the time of testnet contract deployment. On average, this will take 1 week from the time of testnet deployment.","Art Blocks will need to integrate your newly deployed testnet smart contracts with our rendering infrastructure on testnet. After that, your team will connect to the staging site https://artist-staging.artblocks.io and interact with projects on the testing network you created as if they were on Art Blocks.","Art Blocks' will deploy a set of testnet smart contracts for your team to begin integrating with.","artist website","Create a new mainnet project shell on your smart contract using addProject, and upload all project details and project script using the artist interface at https://artblocks.io.","Deploy mainnet contracts.","etc.","If a 0% margin is used during a live NFT sale, the blockchain state will likely change between a user-submitted transaction and when it's mined. Therefore, small changes in the required Gas Limit will likely result in transaction failures if the gas necessary increases.","If accepting ETH, check that the wallets are not multisig wallets like Gnosis Safe (check the minter owner, rendering provider, artist, and any additional payee).","If actions of changing max invocations are expected, test those actions.","If actions of whitelisting/removing minters are expected, test those actions.","If you need help, the Art Blocks team will help guide you through the process.","Important for mainnet: Test-mint a token in each currency that will be accepted for a project. Verify that your front end is used to successfully mint using each currency to ensure a proper end-to-end test.","In summary, mainnet deployment entails:","Integrate mainnet contracts with Art Blocks' rendering and API infrastructure.","Interested in learning about an Art Blocks Engine partnership? Email engine@artblocks.io to get the conversation started!","Mint at least one piece (mint #0) in a controlled environment on mainnet, being sure to mint in each format you plan to for your open release.","project description","Provide the following information to Art Blocks for your Engine project: 1 The admin address to own these contracts. This address controls the core contract and the minter contract. 2 The name of tokens from your contract (e.g. for Art Blocks it is \"Art Blocks\" https://etherscan.io/address/0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270#code). 3 The ticker for tokens from your contract (e.g. for Art Blocks it is \"BLOCKS\" https://etherscan.io/address/0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270#code).","the license associated with outputs","To create a new project shell, you should use the addProject method of your newly deployed Engine Core Contract. This can be done by connecting to the contract via Etherscan.","Update your mainnet website to reference deployed mainnet contracts.","Vetting includes minting in (1) each minting format, (2) from the Engine partner's frontend minting experience, and (3) while integrated with the Art Blocks' provided rendering infrastructure.","Warning: if you opt-out of this step, it may result in undiagnosed issues with the rendered outputs. An unaudited project may not conform to the Art Blocks resolution-agnostic and deterministic standards. This means outputs may differ between screen sizes, devices, and operating systems or could be different from view to view.","When using your front-end to mint, ensure at least a 10% margin is added to each transaction's estimated Gas Limit, as originated by your frontend logic.","You are now ready to sync with the Art Blocks team on planning for a launch date, which is at least 1 week from when the above steps have all been completed.","Your team can integrate your front end to allow for minting via your new Engine smart contract (using deployed Engine smart contracts).","Your team will integrate a custom web frontend with your deployed Engine smart contracts (e.g., implementing their own purchase + display flow) and with the Art Blocks API as needed. An example of frontend purchase flow logic is provided here as a reference for integrating partners:","Your team will use https://artist-staging.artblocks.io site to upload your project script source code and configure all project metadata details:"]}],[{"i":"what-is-art-blocks-engine-and-engine-flex","l":"What is Art Blocks Engine and Engine Flex?","p":["Art Blocks Engine and Engine Flex are custom branded solutions from Art Blocks. Our offerings allow the generative NFT minting technology used by artists at Art Blocks to be integrated with third-party sites.","Engine allows partners to release generative outputs using our existing smart contracts and rendering infrastructure resulting in turnkey and branded generative projects. Engine partners own their smart contracts and can use them to release as many projects as they like as often as they like.","We currently partner with organizations from every sector that are interested in launching generative collections, but are particularly interested in the fashion, sports, media, manufacturing, and fine art industries.","For more information on Art Blocks Engine partnerships please contact: info@artblocks.io"]},{"i":"what-is-the-difference-between-art-blocks-engine-and-engine-flex","l":"What is the difference between Art Blocks Engine and Engine Flex?","p":["Art Blocks Engine is our offering that aligns most closely with the Art Blocks flagship product ( https://artblocks.io), and has the same technical approach to on-chain art where artists store the entirety of their generative algorithms on-chain within the Engine smart contract and are limited to a single, widely-distributed, off-chain dependency (e.g. p5js).","With Art Blocks Engine Flex artists are able to include off-chain assets, stored on the decentralized storage solutions of IPFS or Arweave, as additional inputs into their creative coding practice. This allows, for example, a project that takes an image as an input and creates 1of1ofX outputs applying a generative practice to this input image. This final output combines a generative script, a token hash, and additional off-chain assets."]},{"i":"how-does-art-blocks-engine-flex-work","l":"How does Art Blocks Engine Flex work?","p":["With Art Blocks Engine Flex contracts, a per-project (as opposed to per-contract) field is available on all projects that allow an artist to set a single off-chain dependency or set of multiple off-chain dependencies based on the content ID locations where these dependencies are stored on IPFS or Arweave.","Currently, we do not yet support the turnkey ability to programmatically upload/pin these dependencies to IPFS/Arweave within the Engine experience directly; however, our team is more than happy to assist partners in the process of uploading/pinning assets on IPFS/Arweave using existing third party solutions for doing so (e.g. Pinata in the case of IPFS).","Note that for a single project, it is possible to have a single off-chain dependency (e.g. a single image file) or a set of off-chain dependencies (e.g. a series of images from a set). This means that is possible, for example, to have a project that creates 1of1ofX generative variants of a single base image asset, or one in which for a given token a random image is selected from the base image asset set, and then a generative process is applied to it.","It is also important to note that images are not the only supported external asset dependency type. It is possible to reference any file type that can be pinned/uploaded to IPFS or Arweave and intelligibly incorporated into a generative algorithm to create interesting artistic outputs. For example, a project could use tensorflow.js as its single-dependency, have its generative script be a tensorflow based creative coding algorithm, and store the model file for the machine learning model on IPFS or Arweave to support a ML/AI based project."]},{"i":"what-is-the-smart-contract-architecture-for-art-blocks-engine","l":"What is the smart contract architecture for Art Blocks Engine?","p":["The Art Blocks Engine offers two core contract options: the V3 Engine core contract and the V3 Engine Flex core contract. These contracts are mutually exclusive, and partners should select the appropriate core contract based on their needs and whether they require the flex capabilities.","The V3 Engine core contract is an ERC-721 NFT contract that manages metadata for all Art Blocks NFTs, including artist scripts, token hashes, and token royalty data.","The V3 Engine Flex core contract includes everything in the V3 Engine contract, but also allows artists to use external assets in their Engine tokens. These external assets can be images, videos, audio, or other data and may be stored on decentralized storage systems such as IPFS, Arweave, or on the Ethereum blockchain","Both core contracts integrate with various peripheral contracts to provide flexible, customizable, and extensible functionality. These peripheral contracts are:","Admin Access Control List (ACL) contract: Manages granting admin access to the core contract and related contracts. It is designed to be highly flexible, extensible, and upgradable.","Randomizer contract: Generates pseudo-random numbers for the core contract when new tokens are minted. This architecture is designed to be highly flexible, enabling designs that may desire asynchronous random number generation or other hash generation methods.","Core Registry contract: Notifies the subgraph indexing service of new Art Blocks Engine tokens. When the Core Registry emits an event, the subgraph indexing service is notified, and the Engine contract is indexed and made available for querying on the Art Blocks subgraph. It also notifies a shared minter suite to allow the new Engine contract to be used by minters.","Minter Suite contracts: A collection of contracts used to mint Art Blocks Engine tokens. The Minter Suite is designed to be highly flexible and can be used to mint tokens in various ways.","Partners should choose between the V3 Engine core contract and the V3 Engine Flex core contract based on their project's goals and technical capabilities. The smart contract architecture for Art Blocks Engine provides a robust and flexible system for managing and creating generative NFTs while integrating with various peripheral contracts to extend its capabilities.","For additional context, please check out this architecture overview (with accompanying diagrams)."]},{"i":"what-is-the-minter-suite","l":"What is the \"minter suite\"?","p":["A summary of the division of responsibilities between the MinterFilter and individual Minters can be summarized as:","Assigns a specific minter to each project, which can be updated by the project's artist or the platform's Admin ACL.","Checks if the minter is the assigned minter for a project before allowing the token to be minted.","Checks that a project is on a registered Art Blocks Engine contract before allowing a minter to be assigned.","Defines price information for tokens in a project, including token price in wei, currency symbol, and currency address.","For additional context, please check out this architecture overview (with accompanying diagrams).","Handles the token purchase process through the \"purchase\" and \"purchaseTo\" functions for specific projects.","Legacy Minter Suite","Maintains a list of approved minters that can mint tokens for projects on the platform.","Managed the maximum number of invocations (for the given minter) for each project.","MinterFilter:","Minters:","Provides information about the minter type and associated core contract and MinterFilter addresses.","Shared Minter Suite","The Art Blocks minter suite is a collection of smart contracts that facilitate the secure and efficient minting of generative art tokens for all Art Blocks contracts in the V3 architecture. Originally, each contract had its own minter suite. The new shared minter suite enables Engine contracts use the same minting contracts as Art Blocks Flagship, which enables a seamless experience for collectors and artists.","The legacy minter suite is very similar to the new, shared minter suite, except that each minter filter and minter contract is connected to a single core contract. The general roles and responsibilities of the Minter Filter and Minter contracts are the same, except that they limit minting to a single core contract instead of a set of allowlisted core contracts.","tl;dr: The MinterFilter serves as a control layer that ensures the correct minter is used for each project, while Minters handle token purchase processes and project-specific settings. This division of responsibilities enables a secure, efficient, and flexible set of contracts that we call the \"minter suite\"."]},{"i":"what-is-generative-art","l":"What is generative art?","p":["Generative art is about developing systems that define rules for creating art. By introducing randomness to those systems, core concepts are expressed through unique outputs. In a contemporary sense, this means writing computer algorithms to define the system and introduce randomness, which allows for conceptual exploration and rapid iteration.","Creative coders write scripts with specific parameters that introduce and explore features, which generate the final outputs in a collection. With Art Blocks’ generative minting technology, collectors participate in the creation of the art. No one knows exactly what a piece will look like before it's minted, not even the artist. Each NFT is generated at the time of purchase using the buyer’s unique transaction hash to create a ‘1 of 1 of X’, which adds an extra layer of magic as the creator and collector watch a project come alive.","The interesting part of modern generative art is that it involves working in series - often a large series. So instead of pursuing a single compelling work of art, a generative artist creates an algorithm capable of tens, hundreds, or thousands of compelling works of art. Which, when taken as a whole, expresses the range of possibilities contained in a single algorithm."]},{"i":"what-are-nfts","l":"What are NFTs?","p":["Nonfungible tokens (NFT) are unique digital assets stored on blockchain technology that can represent any digital or physical asset."]},{"l":"On-chain vs. off-chain","p":["Art Blocks Engine enables creators to immutably store their generative NFT directly on the Ethereum blockchain (on-chain) or reference an external library or asset (off-chain). For an off-chain implementation, partners can reference external off-chain assets using decentralized storage solutions like IPFS.","Decentralized and fully on-chain content is the most durable digital asset available. Typically, a creative coder writes a generative script in JavaScript and stores it directly on the blockchain. As long as you have access to a computer, a web browser, and Ethereum’s public ledger, you’ll always be able to reproduce the NFT in its original form and track ownership since creation. An on-chain NFT inherits the provenance, security, and durability of Ethereum itself, making them the highest quality digital asset available.","So, if Art Blocks ever shut down, all on-chain work would still be accessible since it's stored on the decentralized Ethereum blockchain and able to be viewed, bought, sold, and transferred without involving Art Blocks at all.","In contrast, if we store generative algorithms on an Art Blocks-owned database, the NFTs would rely on Art Blocks to return the assets - and if we go offline, the assets would not be retrievable. Similarly, if a script is stored on-chain but uses data from off-chain sources, it's vulnerable to the host of that off-chain data going offline.","Off-chain NFTs rely on assets stored on external servers. There are many reasons to reference off-chain assets - data storage is expensive on Ethereum, and using external assets can reduce the cost of putting data on-chain. It also allows for interesting applications of generative art using external assets. However, if your NFT references external sources and those sources go offline, the NFT will only track ownership of unretrievable data.","For this reason, we only allow certain external libraries to be used in project scripts given their general recognition as extremely reliable file storage sources.","Art Blocks Engine offers on-chain and off-chain solutions with our generative NFT minting technology. Which one is right for you depends on your project’s goals and technical capabilities."]},{"l":"Creating durable digital assets","p":["Creating on-chain generative NFTs ensures your collectors can expect their digital assets to stay the same forever. But if you choose to launch a generative project with off-chain assets, there are ways to mitigate the risk of going off-line using technology like IPFS or Arweave. We’re happy to chat about the right Art Blocks Engine implementation for your next project."]},{"l":"Potential use-cases","p":["The landscape of on-demand generative content has plenty of room to experiment. Some of our current partners include artists, galleries, art houses, online publications, and game developers. If you’re exploring an interesting project, get in touch, and let’s build together.","Current and upcoming use cases:","Fashion","Premier Artists","Media / Tech / Consumer brands","Gaming","Sports","BYOP - build your own platform"]}],[{"l":"Engine Partner Onboarding Steps","p":["An overview of the steps required to onboard as an Art Blocks Engine partner."]},{"l":"1. Initial outreach","p":["Interested in using Art Blocks Engine to launch a generative content platform?","Reach out to info@artblocks.io to get started. We'll discuss your needs, explain what we offer in a partnership, and align expectations.","Timeline: typically 1-2 weeks"]},{"l":"2. Project scope","p":["The Art Blocks team will work with you to determine the scope of the Art Blocks Engine project.","Timeline: 1-2 weeks"]},{"l":"3. Contract agreement","p":["Once the project objectives and scope are agreed upon, you'll work with our operations team to sign our partnership agreement.","Timeline: 1 week"]},{"l":"4. Smart contract details","p":["To get started, you'll provide our team with:","An Ethereum wallet address (that you currently own and control) you'll use to manage your Art Blocks Engine smart contracts","The name you’ll use for tokens from your contract (e.g., for Art Blocks, it is \"Art Blocks\")","The ticker symbol you’ll use for tokens from your contract (e.g., for Art Blocks, it is \"BLOCKS\")","Deployment Type: V3 Engine or V3 Engine Flex","Minter Type: flat price eth only, set price custom erc20, merkle tree allowlist, holder-gated, linear DA, exponential DA, and exponential DA with settlement","Starting project ID # (>=0):","Set autoApproveArtistSplitProposals: true or false","Regarding \"autoApproveArtistSplitProposals\" - It needs to be set at deployment and cannot be changed later.","tldr - if true, artist royalty wallet changes are auto-approved. If false, the contract admin will need to approve the artist's royalty wallet changes. This is an added check to ensure your artists aren't changing royalty wallets to a random address, which could complicate accounting/ OFAC compliance.","Note: We cannot deploy your contract until you provide the above information. The name and symbol tied to your contract cannot change once it’s deployed._","Timeline: 1-2 days"]},{"i":"5-contract-configuration--testnet-deployment","l":"5. Contract configuration & testnet deployment","p":["We will configure your smart contract before transferring ownership to Ethereum address provided in Step 4. Once we deploy your contract on the test network, you can start testing your generative script.","Timeline: 1 week"]},{"l":"6. Testnet infrastructure integration","p":["Art Blocks will integrate your contracts with our rendering infrastructure and provide access to our staging website for you to perform project onboarding and configuration via the Art Blocks site on the test network.","Contracts are deployed twice per month and typically take 1 week to complete and transfer.","Timeline: 1 week"]},{"i":"7-integration-with-partners-site","l":"7. Integration with partner’s site","p":["Your team will integrate your site’s front-end with the contract created by Art Blocks to test your outputs on the testnet.","Timeline: weeks-months (depends on partner)","Connect your front end to testnet contracts"]},{"l":"8. Test mints on partner site","p":["Your team ensures the minting process is working on the test network by minting your NFTs using the front-end of your site.","Timeline: weeks-months (depends on partner)","Mint test outputs","Test drop mechanic (flat price, Dutch Auction, whitelists, etc.)","Test purchase with custom ERC20 (if applicable)","Request a script audit from Art Blocks","Test your script across different hardware/software ( browserstack.com)","Let the Art Blocks team know testing is complete and you're ready for a mainnet deployment"]},{"l":"9. Deployment to mainnet","p":["Art Blocks deploys the mainnet version of your contract and integrates it with our infrastructure.","Timeline: 2 weeks"]},{"i":"10-infrastructure-integration-mainnet","l":"10. Infrastructure integration (mainnet)","p":["Your team integrates the mainnet contract with your site and prepares to generate your first NFT (mint #0)","Timeline: Depends on partner","Connect your front end with the new mainnet contracts, using the same minting mechanics from testnet (drop type & currency)","Mint #0 from your front end"]},{"i":"11-mint-0","l":"11. Mint #0","p":["You can mint your project's first official token via your site!"]},{"l":"12. Set secondary royalties","p":["Art Blocks will set our secondary royalty before we transfer contract ownership, but you are responsible for setting your own secondary royalty across all secondary marketplaces.","OpenSea - https://docs.opensea.io/docs/10-setting-fees-on-secondary-sales LooksRare - https://docs.looksrare.org/guides/collection-management/set-or-edit-collection-royalties x2y2 - https://docs.x2y2.io/guides/collection-management/manage-your-collection","Note: The vast majority of secondary activity takes place on OpenSea. Currently, OpenSea does not recognize on-chain royalties and needs to be set through their interface. However, they plan to recognize Roylaty Registry in the near-ish future. We highly encourage you to sign up for the Royalty Registry to avoid missed secondary royalties.","Instructions on setting up Royalty Registry - https://docs.artblocks.io/creator-docs/art-blocks-engine-onboarding/art-blocks-engine-101/engine-royalty-registry-setup/"]},{"l":"13. Project launch","p":["You can choose a launch date for your project. Please allow at least one week between a successful mint #0 and a go-live date.","Timeline: 1 week from completion of step 11"]}],[{"l":"Engine Project Deployment and Launch Guide","p":["This guide provides basic instructions for deploying and launching a new project on the V2 and V3 Engine smart contracts. You will learn how to create a project shell, assign a minter to each project, and setup the necessary configurations before minting and launching your project. This documentation aims to simplify the process and ensure a smooth project launch on the Art Blocks Engine platform.","There are slight variations between V2 and V3 contracts, which will be noted in the relevant sections."]},{"l":"Project Shell Deployment","p":["Collect the required information for the project:","Project title (e.g., \"Fun Lines\")","Artist's wallet address (e.g., 0x78592a6fBE68fEBf226040a5D25ad7e69F2FeAb6)","(V2 only) Price-per-mint specified in WEI (e.g., 350000000000000000, or 0.35 ETH)","Navigate to your Engine Core Contract on Etherscan and connect your wallet. You can find this link in your DEPLOYMENTS.md log. https://goerli.etherscan.io/address/0xd2363Acbf8CdF01A5FdfcB8f0295e0a5dF94518D#code)","Click the \"Write contract\" tab and use the addProject method to create a new project shell, specifying the information collected in step 1.","Connect to the Art Blocks website with the artist wallet used in Step 3. Your artist should be able to begin entering project details.","Testnet URL: https://artist-staging.artblocks.io/engine/[flex OR fullyonchain]/projects/[coreContractAddress]/[projectID] example: https://artist-staging.artblocks.io/engine/flex/projects/0x28b82AA5bb6d00363ae0FBC5ecaD689Ae49BC82B/0","Mainnet URL: https://www.artblocks.io/engine/[flex OR fullyonchain]/projects/[coreContractAddress]/[projectID] example: https://www.artblocks.io/engine/fullyonchain/projects/0xa319C382a702682129fcbF55d514E61a16f97f9c/1","If you encounter issues finding or seeing your project on the Art Blocks site, disconnect and reconnect your wallet, ensuring you are connected with the previously specified artist wallet."]},{"i":"assigning-a-minter-v3-only-new-shared-minter-suite","l":"Assigning a Minter (V3 only, New Shared Minter Suite)","p":["Minters are assigned on a per-project basis on V3 contracts, and minters must be assigned by the artist's wallet.","note: for legacy minter suite directions, see the next section","Art Blocks is working on a new creator dashboard that will more easily facilitate the minter assignment process. This will only be possible using the new shared minter suite, because those minters are indexed by the subgraph. Until the new creator dashboard is released, please follow these instructions to assign a minter to your project.","Assign the minter to your project by using the MinterFilterV2 contract found in your deployment file. The artist's wallet should use function #9 setMinterForProject, entering the _projectID, _coreContract address, and _minter address. You can get the globally approved minter addresses via the getAllGloballyApprovedMinters() view function on the MinterFilterV2 contract.","Once the minter is linked to your project, set the project details on the minter contract.","For example, if you are using a shared Dutch Auction minter, navigate to the contract on Etherscan. Then, use the function setAuctionDetails to enter details like _projectId, _coreContract, _auctionTimestampStart, _priceDecayHalfLifeSeconds, _startPrice, and _basePrice. This must be done using the artist's wallet."]},{"i":"assigning-a-minter-v3-only-legacy-non-shared-minter-suite","l":"Assigning a Minter (V3 only, Legacy Non-Shared Minter Suite)","p":["We recommend using the new shared minter suite, which is easier to use and more flexible. If you are using the legacy non-shared minter suite, follow these instructions. For more information about migrating to the new shared minter suite, please see the Minter Suite Migration Runbook.","Minters are assigned on a per-project basis on V3 contracts, and minters must be assigned by the artist's wallet. For the artist wallet to assign a minter, follow these steps:","Assign the minter to your project by using the MinterFilterV1 contract found in your deployment file. The artist's wallet should use function #6 setMinterForProject, entering the _projectID and _minterAddress. You can find the minter address in your deployment log, which is pinned in your partner channel.","Once the minter is linked to your project, set the project details on the minter contract. The deployed minter addresses can be found in your deployment file.","For example, if Art Blocks deployed a Dutch Auction minter for your core contract, navigate to the MinterDAExpV4 contract on Etherscan (in your DEPLOYMENT.md log). Then, use the function setAuctionDetails to enter details like _projectId, _auctionTimestampStart, _priceDecayHalfLifeSeconds, _startPrice, and _basePrice. Make sure this is done using the artist's wallet."]},{"i":"pre-mint-0-flight-check","l":"Pre-mint-#0 Flight Check","p":["Before minting your first token (#0) on your new project shell, verify the following:","The baseTokenURI has been set, following the format:","Mainnet: http://token.artblocks.io/{CORE_CONTRACT_ADDRESS}/","Testnet: https://token.staging.artblocks.io/{CONTRACT_ADDRESS}/","The max invocations for the project have been set. (note: project size cannot be increased once set on V3 contracts)","Mint through your own front end. On testnet, you'll want to test each minter type and currency you plan to use on mainnet."]},{"i":"pre-launch-pre-open-minting-flight-check","l":"Pre-launch (pre-open-minting) Flight Check","p":["For a project to be available for public purchase, the project must be activated by the admin, and unpaused by the artist.","tldr: inactive + paused (default state) = private project shell and unable to purchase active + paused = public project shell and only the artist wallet can purchase active + unpaused = open to purchase","Before launching your project for open minting, verify the following:","The project has been activated by the contract admin.","The project is not yet unpaused.","Once unpaused the project will be open, depending on the minter being used (DA will not open until specified startTime)"]}],[{"l":"Art Blocks Engine OpenSea Setup","p":["Setting up the OpenSea storefront for your Art Blocks Engine contract."]},{"l":"OpenSea Storefront Ownership Transfer","p":["After the first token has been minted on your new Art Blocks Engine contract, you should be able to see this token in the OpenSea storefront. You will find this in the format https://opensea.io/assets/{CONTRACT_ADDRESS}/{TOKEN_ID} e.g. https://opensea.io/assets/0x13aae6f9599880edbb7d144bb13f1212cee99533/1000167.","Once this first token is populated, the Art Blocks team will be able to transfer the OpenSea collection for your project to a wallet that you control. By default, the Art Blocks team will plan to use the same address for the OpenSea collection ownership as it is designated to be the admin of your smart contract. However, if you prefer that a different wallet address manages the OpenSea collection, please reach out to Art Blocks to request this before the project has been transferred to your team.","After your OpenSea collection has your designated wallet added as the collection administrator, you may remove the wallet that Art Blocks controls from being an additional admin. It’s added automatically at the time of collection creation based on the contract deployer wallet address at the time of collection creation. We recommend that you do so. That way, only you control your OpenSea storefront.","Please contact the Art Blocks and/or OpenSea teams if you have any issues during this process."]},{"l":"OpenSea Storefront Options","p":["For Art Blocks Engine projects, there are two options that OpenSea can provide for collection organization:","1. All projects are grouped in one large collection, where individual projects within a collection are shown as filter traits on the sidebar of the OpenSea UI.","All projects in one collection.","2. Each new project on your contract is handled as its own collection on OpenSea, where project traits are properties.","Each project as its own collection.","By default, collections are organized via method 1. above. However, if you would like your collection to be handled via method 2., please reach out to the Art Blocks team, and we can facilitate this change by OpenSea on your behalf."]}],[{"i":"art-blocks-engine-royalty-registry-setup-v2-contracts-only","l":"Art Blocks Engine Royalty Registry Setup (V2 contracts only)"},{"l":"Royalty Registry","p":["The Royalty Registry is an on-chain tool used by many marketplaces ((soon) OpenSea, Coinbase NFT, etc.) to query royalty payment addresses and percentages when a token is sold. The Royalty Registry lives on the Ethereum blockchain and is decentralized.","Art Blocks Engine contracts integrate with the Royalty Registry directly to handle many projects and artists on a single contract. Please do not use the Royalty Registry's \"Configure\" UI to configure the royalties for your Engine contracts. Doing so will result in incorrect royalty payments across many projects. Instead, see the documentation below.","Note that the Royalty Registry's \"Lookup\" UI is a great tool for confirming that your Engine contracts are configured correctly after the configuration steps below have been completed."]},{"l":"Royalty Payment Addresses","p":["For Engine contracts, the following addresses may receive royalties:","Party","Typical Royalty Percentage","Platform (Engine Partner)","default 2.5%","Render Provider (Art Blocks)","Artist","typically 5%, but configurable by artist","Additional Payee","split between Artist & Additional Payee varies across projects"]},{"l":"Configuring Royalties","p":["V3 and V2 Engine contracts are configured differently. V3 Engine contracts are the latest version of the Art Blocks Engine contracts. Since they were designed after the Royalty Registry was released, they automatically integrate with the Royalty Registry. V2 Engine contracts also integrate with the Royalty Registry, but have a shim-layer that must also be configured. This is because V2 Engine contracts were designed before the Royalty Registry was released."]},{"l":"Configuring V3 Engine Contracts","p":["Simply configure the relevant royalty payment details on the token contract itself:","admin (contract-wide):","Ensuring platform and render provider payment addresses are correct, updateable by contract admin by calling updateProviderSalesAddresses on the Engine core contract","Ensuring platform and render provider payment percentages are correct, updateable by contract admin by calling updateProviderSecondarySalesBPS on the Engine core contract","artist (project-specific):","Ensuring the project's artist royalty percentage is correct, updateable on the website by the artist in their project dashboard.","Ensuring the project's artist and additional payee splits are correct, updateable on the website by the artist in their project dashboard."]},{"l":"Configuring V2 Engine Contracts"},{"l":"Required V2 Setup","p":["A. Pre-setup:","B. Royalty Registry Integration:","Call the setRoyaltyLookupAddress function with the following arguments:","Call the updatePlatformRoyaltyAddressForContract function with your Engine token contract address as _tokenContract, and your desired platform royalty payment address as _platformRoyaltyAddress","Connect your Engine admin wallet to the Art Blocks Engine royalty override contract, 0x31E1cC72E6f9E27C2ECbB500d978de1691173F5f, on etherscan","Create a new override on the Royalty Registry for your Engine core contract","Ensure every project has the desired artist royalty percentage set on the Engine contract.","IMPORTANT: This percentage represents the percentage of the total token sale that will be paid to a combination of artist & additional payee. It is typically 5%. Additionally, the default 2.5% to the Engine platform (you) and 2.5% to render provider (Art Blocks) will be also added by the Royalty Registry override contracts below.","Note: This percentage is different than what OpenSea has asked us to do with their off-chain royalty system. In the old system, typically 5%+2.5%+2.5%=10% was set on OpenSea's website because they only supported bulk payments to a single address. In the new on-chain system, payments to more than a single address will be supported.","Now you will automatically be receiving royalties from sales on secondary markets that support use of the Royalty Registry!","Only artists may update their project's royalty percentage. They can call updateProjectSecondaryMarketRoyaltyPercentage(_projectId, _royaltyPercentage) on the Engine contract from their artist wallet. Typically royalty percentage would be the number 5, representing 5%.","royaltyLookupAddress: The address of the standard Art Blocks Engine Royalty Registry override contract, 0x31E1cC72E6f9E27C2ECbB500d978de1691173F5f","Set your Platform royalty payment address","The following steps are required before Art Blocks Engine contracts will integrate properly with the Royalty Registry.","tokenAddress: The address of your Engine core contract","Using the Connect to Web3 button, connect your Engine admin wallet to etherscan when on the \"Write as Proxy\" tab.","View the Royalty Registry's mainnet registry contract on etherscan: https://etherscan.io/address/0xad2184fb5dbcfc05d8f056542fb25b04fa32a95d#writeProxyContract"]},{"l":"Optional V2 Configuring","p":["Royalty percentages of 2.5% are used by default by the Art Blocks Engine royalty override contract. The admin of any given Engine core contract can override these percentages by calling updatePlatformBpsForContract or updateRenderProviderBpsForContract on the Art Blocks Engine royalty override contract, 0x31E1cC72E6f9E27C2ECbB500d978de1691173F5f, on etherscan","Note that royalty proportions are defined in terms of Basis points. For example, 250 BPS = 2.5% royalty. See this article for more information.","After initial setup, the Platform (Engine partner) royalty payment address may be updated at any time by the admin of a given Engine core contract by calling the updatePlatformRoyaltyAddressForContract function on the Art Blocks Engine royalty override contract, 0x31E1cC72E6f9E27C2ECbB500d978de1691173F5f, on etherscan"]}],[{"l":"Embroidery on Art Blocks Engine","p":["In addition to providing a browser-based live view and media files generated from your project script, Art Blocks Engine provides tools to embroider your generative artwork on garments and accessories."]},{"l":"Requirements","p":["In order to get started, you will need:","Testnet project shell on Art Blocks Engine Refer to documentation for setup instructions*","Embroidery machine and software drivers compatible with DST or PES files If you are new to embroidery, we recommend the Brother PE800","JavaScript utilities for manipulating SVG markup Clone the embroidery template repository for an example: ‣"]},{"l":"Quick Start","p":["Deploy a new project shell to your Art Blocks Engine testnet contract","Upload a project script that includes a global function named generateEmbroiderySVG that returns a string containing SVG markup for embroidery","Use the Embroidery File Downloader to generate embroidery files for minted tokens"]},{"l":"Project Script Requirements","p":["In addition to following the typical guidelines and constraints for Art Blocks projects, your project script should include a global function that is only used for embroidery."]},{"l":"Generating SVG for Embroidery","p":["Implement a global function with the following type signature:","For example, you may include a function similar to code below:"]},{"l":"Functional Requirements","p":["In order to correctly generate files for embroidery, you must:","Implement a generateEmbroiderySVG global function that returns the full markup of an svg element as a string","Optional: accept a width and height parameter (millimeters) used to resize the contents of the SVG to accommodate different garment sizes","Render a digital-only version of the art using a separate svg or canvas that is displayed to the user and thumbnailed in token metadata (similar to any digital-only Art Blocks project)","Inline all libraries and code used in your project that are not configured as an on-chain dependency"]},{"l":"Known Limitations","p":["Avoid using SVG fills - instead, to create the visual appearance of a fill, the SVG should contain the exact paths the embroidery needle should follow","Avoid using asynchronous code or promises inside of the generateEmbroiderySVG function - the function should return valid SVG markup immediately","Provide margins (bleed) matching the precision of the embroidery machine to improve manufacturing yield","Match all colors used in your design to the colors of thread available to you for embroidering"]},{"l":"Embroidery in Production","p":["In addition to the typical steps required for moving an Art Blocks Engine project to mainnet, there are additional considerations for embroidery projects."]},{"l":"Logistics and Fulfillment","p":["There are three primary customer experiences enabled for embroidery on Art Blocks Engine:","Drop-shipped or batched production Consider the lead times, available materials, and the process for sending files to embroidery service providers.","Live in-person pop-up events Consider space constraints and measure the amount of time required to fulfill a single embroidered object.","At-home embroidery for token holders Consider how and when you would like to provide your users with a link to download embroidery files for a project."]},{"i":"option-1-batched-production","l":"Option 1: Batched Production","p":["To facilitate automated testing and batched production, we provide a rate-limited API for converting Art Blocks Engine projects into DST and PES embroidery files. Note: the API endpoints provided for batched production are rate-limited, and cannot be linked from a public web site.","For example, the following commands illustrate how you can download individual embroidery files for tokens on an Art Blocks Engine project:"]},{"i":"option-2-live-events","l":"Option 2: Live Events","p":["To facilitate live events, operators of a pop-up booth can use the Embroidery File Downloader on a laptop or iPad to quickly download the relevant embroidery files for a given minted token.","Embroidery File Downloader"]},{"i":"option-3-home-embroidery","l":"Option 3: Home Embroidery","p":["If you would like to provide your token holders with a link to download DST or PES files of their minted tokens, please contact us for access to the API dashboard. To generate embroidery files in an S3 bucket that may be linked from a public web site, you will need to add your project in the API dashboard here: https://minting-api.artblocks.io/admin/embroidery/embroideryproject/"]},{"l":"References","p":["https://github.com/embroidepy/vpype-embroidery/","https://github.com/EmbroidePy/pyembroidery","10 Best Print on Demand Companies and Sites (2023)","The 7 Best Embroidery Machines of 2023"]}],[{"l":"Mobile Minting for In-Person Activations","p":["The Art Blocks Mobile Minter is a specialized app for iPad and iPhone designed to streamline the minting process during in-person events. Unlike the standard Art Blocks website, which is accessible from any device, the Mobile Minter is tailored for events where minting is exclusive to attendees or offered as an event gift."]},{"l":"Features","p":["The Mobile Minter is capable of:","Minting Art Blocks tokens with a pre-funded wallet to cover gas fees","Minting tokens to an ENS name or a copied Ethereum address","Authenticating users with FaceID/TouchID for quick access during live events","Minting tokens without requiring manual signing and submission of Ethereum transactions"]},{"l":"Requirements","p":["The Mobile Minter is perfect for situations where:","A project is paused and not available for online minting","An artist wants to distribute their work at a live event","An iPad or iPhone with the latest iOS version is available","A small amount of Ethereum is on hand to cover gas fees for token recipients","You've set up a Stripe account to accept fiat payment (optional)"]},{"l":"Getting Started","p":["To use the Mobile Minter, follow these steps to set up your project and device according to the system requirements."]},{"l":"Step 1. Project Configuration","p":["To set up the Mobile Minter for your project:","Send a Slack message in Slack requesting access to the Mobile Minter","Art Blocks staff (@Shantanu Bala) will provide a wallet address that will be used to pay for gas fees for transactions Note: The app manages this wallet, and any remaining funds can be returned to you at any time","Pause your project to restrict minting to the artist only","Transfer artist ownership to the wallet address from Step #2, making the Mobile Minter the sole minting wallet for the project","After completing these steps, Art Blocks staff (@Shantanu Bala) will give you login details to start using the mobile app"]},{"l":"Step 2. Device Setup","p":["To prepare your mobile device:","Update your iPhone or iPad to the latest iOS version","Set up and ensure FaceID or TouchID is functional on your device","Download the TestFlight app from the App Store: TestFlight","Join the Mobile Minter beta on TestFlight:","Sign in, set up FaceID, and proceed to minting"]},{"l":"Step 3. Minting","p":["Mobile Minter iPad app","Click the link above to view a screen recording of the Mobile Minter app on iPad. This test demonstrates the steps to mint a project on the Goerli test network. To mint a new token, users follow these steps:","Open the Mobile Minter app on an iPhone or iPad device","Sign in using FaceID","Select a project from the list of available projects","Input an ENS name or wallet address","Confirm the minting details","Wait for the token minting transaction to be confirmed"]},{"l":"Payment Processing","p":["The Mobile Minter utilizes Stripe Terminal for handling payments. Art Blocks does not offer merchant accounts or handle tax remittance for partners. To process fiat payments with Stripe Terminal, all Art Blocks Engine partners must create and configure their own Stripe account.","The backend (Art Blocks Minting API) and point of sale (Mobile Minter app) software are provided by Art Blocks. However, the hardware must be procured by Art Blocks Engine customers."]},{"l":"Stripe Reader M2","p":["We recommend using the Stripe Reader M2 with the Mobile Minter due to its convenient NFC payment support, Bluetooth connectivity, long-term SDK support, and reliable chip/magstripe fallback. You will need to order the M2 directly from Stripe."]},{"l":"Direct Charges","p":["The Mobile Minter uses Stripe Connect to make a direct charge using your Stripe account. Stripe Connect processes direct charges for your Art Blocks Engine project using your own Stripe account (connected account) while using our platform - note that the charge amounts and fees are mock examples provided by Stripe."]},{"l":"Stripe API Secrets","p":["Do not share your live Stripe API keys with anyone, including Art Blocks employees. Instead, Art Blocks will supply a secure OAuth link from Stripe for your usage. Connected accounts are managed using the process outlined by Stripe:","Managing connected accounts with the Dashboard"]},{"l":"Displaying Live Mints","p":["Web-enabled TVs or displays can showcase a real-time view of the latest tokens minted through the Mobile Minter. The Art Blocks documentation site offers an overview of configuration options for the live viewer."]},{"l":"Example Embed","p":["You can embed live.artblocks.io using an iframe on a web page containing your organization’s branding.","[Example embed of live.artblocks.io without any configuration parameters ( docs)]( https://live.artblocks.io/)","Example embed of live.artblocks.io without any configuration parameters ( docs)"]},{"l":"Frequently Asked Questions"},{"i":"can-the-mobile-minter-be-used-with-projects-that-are-not-paused","l":"Can the Mobile Minter be used with projects that are not paused?","p":["Yes, the Mobile Minter can be used for active projects. However, pausing the project and transferring artist ownership to the app restricts minting exclusively through the app. If a project remains unpaused, anyone online can mint tokens."]},{"i":"can-users-pay-for-gas-fees-themselves","l":"Can users pay for gas fees themselves?","p":["Currently, gas fees must be pre-funded by the artist or the organization using the Mobile Minter app, through the Mobile Minter's hot wallet."]},{"i":"can-my-prepaid-gas-fee-balance-be-returned-to-me","l":"Can my prepaid gas fee balance be returned to me?","p":["Yes, please contact us to arrange the return of any remaining funds to the original depositing wallet. To have the remaining ETH returned, ensure that the funds were initially transferred to the Mobile Minter's hot wallet from an address capable of receiving ETH on behalf of your organization. The unspent ETH can only be sent back to the original sender's wallet."]},{"i":"can-multiple-projects-be-managed-simultaneously-through-the-mobile-minter-app","l":"Can multiple projects be managed simultaneously through the Mobile Minter app?","p":["Yes, the Mobile Minter app allows you to manage multiple projects for in-person events. You can easily switch between projects during the event, ensuring a seamless minting experience for attendees."]},{"i":"what-currencies-are-supported-for-payments-in-the-mobile-minter-app","l":"What currencies are supported for payments in the Mobile Minter app?","p":["The Mobile Minter app processes fiat payments via Stripe Terminal, which supports a variety of currencies. The available currencies depend on your Stripe account and the country where your business operates. You will be the merchant of record, and Art Blocks will collect its platform fees in ETH or USD. For a list of supported currencies for your customers, please refer to the Stripe documentation."]},{"i":"is-it-possible-to-customize-the-appearance-of-the-mobile-minter-app-for-my-event","l":"Is it possible to customize the appearance of the Mobile Minter app for my event?","p":["While the Mobile Minter app does not offer customization, you can embed live.artblocks.io inside of a page that showcases your event's theme and branding. Please refer to the Art Blocks documentation site for an overview of configuration options for the live viewer."]}],[{"l":"Using Pinata for External Assets","p":["Pinata is an excellent IPFS resource built with creators and non-technical users in mind, making it easy to upload content that you can use inside Art Blocks! This will walk you through the basics of uploading content to Pinata."]},{"l":"Signing Up","p":["You can sign up for a free account which will allow up to 100 files and 1GB of storage! To get started visit pinata.cloud and click the “Sign Up” button in the top right. It will ask you for a name, email, and password."]},{"l":"Uploading Content","p":["Once you’re signed in you will see the Files Page which looks something like this: setup","To start uploading content, simply click on the “Upload +” button and select “File” upload","Of course from there click “Select File” and choose the file on your computer select","Then give it a name, and click upload; that’s it! name","Once it’s done uploading you will see the file listed on your files page! complete","What’s important to note is the “CID” which stands for “Content Identifier.” It’s the core of IPFS and how files can be shared across the IPFS network. This is what you would input into the “cid” portion of an Art Blocks generative script and would look something like this:","QmNrCnsNazd54aAQixQCVtikJNfizEXGKR6yLhr9P1TTJV","If you want to preview your file you can simply click on the name of the file on the left side and it will open a preview in a new window.","The default Pinata gateway is https://gateway.pinata.cloud but keep in mind that it should only be used for testing files. For production work you may want to consider getting a Dedicated Gateway on a paid plan.","If you have further questions be sure to visit Pinata's docs and do not hesitate to send them an email at team@pinata.cloud! or reach out directly to the Art Blocks team."]}],[{"l":"Using Filebase for External Assets","p":["Filebase is a geo-redundant IPFS pinning service and decentralized storage provider. When a file is uploaded to an IPFS bucket on Filebase, it is automatically pinned to the IPFS network with 3 duplicate copies, each of which is stored on an IPFS node located across 3 unique, geographic regions.","Filebase offers an easy-to-use Web Console Dashboard for non-technical users, and an S3-compatible API for developers to utilize in a wide variety of tool configurations or SDKs."]},{"l":"Signing Up","p":["Filebase uses a web-based console that can be found at https://filebase.com/signup. Existing accounts can go directly to https://console.filebase.com.","To sign up for a Filebase account, navigate to https://filebase.com. To make a new account, click the ‘Try for Free’ button in the top right corner of the webpage. signup","Filebase is a free-to-use platform for all users. All users can store up to 5GB of data, with a maximum of 1,000 individual files on the IPFS network with no credit card required.","Next, fill out the fields of the form, including an email address and password, and agree to the Filebase terms to create your account.","You will receive an email with confirmation instructions. Click the link included in the email to confirm your account and finish the registration process. Once you’ve completed these steps, your Filebase account has been created."]},{"l":"Uploading Content","p":["Once signed in, you will be brought to the Filebase dashboard. web_dashboard","To upload content, first you will need an IPFS bucket. Select 'Buckets' from the left menu bar, then select 'Create Bucket'. buckets","Give your bucket a name, then select IPFS for the network. bucket_ipfs","Then, select your bucket from the Buckets menu and select 'Upload'. You can choose to upload a File, Folder, or existing IPFS CID to Filebase. For this example, we'll use a single file. upload","You will be prompted to select a file from your computer. Once uploaded, it'll be displayed in the Filebase web console and it will be given an IPFS CID value. cid","When a file is uploaded to IPFS, the file’s contents are used to generate a cryptographic hash value. Then, this hash value is used to generate another value, which is used as the file’s content identifier (CID). CIDs are used to access files stored on IPFS, but instead of locating the file on the network based on its name, the CID is based on the file's contents. Any changes to the file's contents or metadata will result in a new, unique CID.","The CID value is what is used within an Art Blocks generative script, under the 'CID' field.","To preview your file using its IPFS CID and the Filebase public gateway, you can use the following URL format in any web browser:","https://ipfs.filebase.io/ipfs/[CID]","The Filebase public IPFS gateway is https://ipfs.filebase.io/ipfs and can be used by all Filebase uses to host Filebase pinned CIDs. For increased configuration options, performance, content whitelisting, and custom branding, a Filebase Dedicated Gateway can be used through one of Filebase's paid IPFS plans.","For more information, visit Filebase's extensive documentation or send them an email at hello@filebase.com! or reach out directly to the Art Blocks team."]}],[{"l":"FAQs","p":["Core contract vs. Minter contract?","Does Art Blocks create a front-end site for our project?","Flex: Can JS external asset dependencies make external calls to other APIs/assets?","Flex: What are the limitations around file size and file type for external assets? How many external assets can a project have?","How can we add more team members to Discord?","How do we list Art Blocks Engine pieces on OpenSea?","How does autoApproveArtistSplitProposals work?","How does project size work on the Minter contract vs Core contract?","How long will each stage of the process take?","How long will the process take from start to public launch?","What are the Art Blocks Engine offerings?","What effect does ‘locking’ a project have?","What information do we need to provide?","What's included with Art Blocks Engine?","What's the difference between a testnet token and a mainnet token?","When should I enable GPU rendering?"]},{"i":"what-are-the-art-blocks-engine-offerings","l":"What are the Art Blocks Engine offerings?","p":["Art Blocks Engine: Used for on-chain storage of generative systems. Projects can use no dependencies or one dependency from a list of decentralized libraries. See the allowed dependencies here.","Art Blocks Engine Flex: Allows generative systems to reference off-chain assets stored on IPFS or Arweave, enabling creative tools like photography, AI, and GAN.","Email us at Engine@artblocks.io to discuss which offering best suits your needs."]},{"i":"whats-included-with-art-blocks-engine","l":"What's included with Art Blocks Engine?","p":["For a new partnership, the standard current Art Blocks Engine offerings include:","Deployment of Engine smart contracts suite to testnet and mainnet (includes gas costs).","Integration of deployed Core contract with decentralized Graph indexing architecture on testnet and mainnet, includes GRT costs incurred for subgraph update deployment.","Integration of deployed contracts and subgraph with Art Blocks' project setup site and rendering/metadata infrastructure (APIs: Token, Generator, Rendered Image).","(in-migration) Integration with the shared Art Blocks Minter Suite. Art Blocks is rolling out a shared minter suite that will be available for Engine Partners to use to mint their projects. Previously deployed V3 Engine contracts will have the ability to migrate to the new shared minter suite. This means the same minting contracts used for Art Blocks Flagship will be available for Engine partners. In addition to the ability to query minter state via subgraph or Hasura queries, Art Blocks has future plans to expand our offering to include the ability to configure minter settings in an Artist Dashboard, and the ability to use a new Art Blocks minting SDK to more easily mint tokens on your frontend."]},{"i":"what-effect-does-locking-a-project-have","l":"What effect does ‘locking’ a project have?","p":["A summary of how the smart contract functions behave:","addProjectScript","after being locked, maximum invocations may only be decreased","before being locked, maximum invocations may be increased","can only lock projects (i.e. locked projects can not be unlocked)","Locked projects can not be unlocked","Locking a project (specifically on V2 Contracts) permanently freezes the artist name, project name, project scripts, project license, and project IPFS hash on the blockchain. Additionally, maximum invocations of a project can never be increased.","only callable by admin whitelisted wallets on the core contract","project script changes:","removeProjectLastScript","The following functionality is affected by a project being unlocked vs. locked:","The following functionality is only allowed on unlocked projects:","toggleProjectIsLocked","updateProjectArtistName","updateProjectIpfsHash","updateProjectLicense","updateProjectMaxInvocations","updateProjectName","updateProjectScript","updateProjectScriptJSON"]},{"i":"changes-for-v3-contracts-deployed-after-march-23","l":"Changes for V3 contracts (deployed after March '23)","p":["In addition to the above, artists can update project description when project is unlocked. However, only contract admins can update project the description when the project is locked.","V3 contracts autolock four weeks after a project is complete."]},{"i":"how-can-we-add-more-team-members-to-discord","l":"How can we add more team members to Discord?","p":["Contact your account manager for an invite link to the private Discord server."]},{"i":"how-long-will-the-process-take-from-start-to-public-launch","l":"How long will the process take from start to public launch?","p":["The process typically takes 10 weeks from initial conversation to public launch, but is highly dependent on partner's resource allocation. To reduce delays, have a front-end developer, artist, go-to-market strategy, and sufficient onboarding time ready."]},{"i":"what-information-do-we-need-to-provide-to-deploy-our-smart-contracts","l":"What information do we need to provide to deploy our smart contracts?","p":["To get started, you'll provide our team with:","Network: (Mainnet or Testnet)","A testnet/mainnet Ethereum wallet address (that you currently own and control) you'll use to manage your Art Blocks Engine smart contracts.","The name you’ll use for tokens from your contract (e.g., for Art Blocks, it is \"Art Blocks\")","The ticker symbol you’ll use for tokens from your contract (e.g., for Art Blocks, it is \"BLOCKS\")","Deployment Type: V3 Onchain Engine or V3 Flex Engine","Minter Type: set price eth only, set price custom erc20, merkle tree allowlist holder-gated, linear DA, exponential DA, and exponential DA with settlement","note: minter selection will not be needed after migrating to shared minter suite","Starting project ID # (>=0):","Set autoApproveArtistSplitProposals true or false**","**It needs to be set at deployment and cannot be changed later.","tldr - if true, artist royalty wallet changes are auto-approved. If false, the contract admin will need to approve the artist's royalty wallet changes. This is an added check to ensure your artists aren't changing royalty wallets to a random address, which could complicate accounting/ OFAC compliance.","We cannot deploy your contract until you provide the above information. The name and symbol tied to your contract cannot change once your contract is deployed."]},{"i":"does-art-blocks-create-a-front-end-site-for-our-project","l":"Does Art Blocks create a front-end site for our project?","p":["No, partners are responsible for creating and designing their customer-facing experience.","However, we do have a front-end React template with web3 functionality you need to launch a minting site. You will still be responsible for designing the user experience, but this significantly reduces the time needed to complete a front-end."]},{"i":"how-long-will-each-stage-of-the-process-take","l":"How long will each stage of the process take?","p":["Initial outreach - 1-2 weeks","Project scope - 1-2 weeks","Contract agreement - 1 week","Smart contract details - 1-2 days","Contract configuration & testnet deployment - 1 week","Testnet infrastructure integration -** 1 week**","Integration with partner’s site - Varies(dependent on partner)","Test mints on partner site - Varies(dependent on partner)","Deployment to mainnet - 1-2 weeks","Mainnet infrastructure integration -** Varies**(dependent on partner)","Mint #0 - Instant","Project launch! - 1 week after step 11"]},{"l":"Contract Ecosystem","p":["Core contract: This is the smart contract that controls the artwork created by the artist. No financial transactions occur on this smart contract.","AdminACL: By default, Engine smart contracts have two sets of permissions, Admin and Artist. The AdminACL contract controls which wallets can access which functions on your core contract. If you'd like to assign more granular control of your smart contract to different wallets, you can fork and customize the AdminACL contract.","Minter Filer: The minter filter configures minter-types to specific projects.","Minter contract: These smart contracts receive funds and split them between the artist(s) and the platform. Artists receive funds directly from these contracts."]},{"i":"how-do-we-list-art-blocks-engine-pieces-on-secondary-markets","l":"How do we list Art Blocks Engine pieces on secondary markets?","p":["Secondary marketplaces will automatically detect and display projects on your contract. If you’d like each project to have its own storefront on OpenSea, please contact an account manager to facilitate the change."]},{"i":"whats-the-difference-between-a-testnet-token-and-a-mainnet-token","l":"What's the difference between a testnet token and a mainnet token?","p":["Testnet tokens are free, unlimited, and worthless. They only exist as a tool for the testing environment before spending actual money (Ether) deploying on Ethereum’s mainnet."]},{"i":"flex-what-are-the-limitations-around-file-size-and-file-type-for-external-assets-how-many-external-assets-can-a-project-have","l":"Flex: What are the limitations around file size and file type for external assets? How many external assets can a project have?","p":["There are no explicit limitations on the contract side, neither for file size or type or how many external assets a project can have. Ultimately, this is at the discretion of the artist, but Art Blocks recommends paying close attention to ensure that artworks are as accessible as possible for as many different types of users as possible. Generally speaking, the above factors should be influenced by trying to achieve the best user experience for the artwork in terms of performance and load time.","Some additional recommendations:","Try to keep the overall download size for users viewing the work to be under ~ 10mb OR ensure the artwork description mentions the heavier load/longer loading time. Additionally, consider whether or not it may make sense to have a loading indicator as part of the artwork itself.","When working with less common file types, remember to test on various platforms/browsers, to ensure the best cross-platform compatibility possible."]},{"i":"flex-can-js-external-asset-dependencies-make-external-calls-to-other-apisassets","l":"Flex: Can JS external asset dependencies make external calls to other APIs/assets?","p":["Having your JS external asset dependencies making external calls, whether it's to an API or other assets, is not a supported use of the Engine Flex offering, as it breaks the assumption of only utilizing off-chain decentralized platforms. We encourage you to, instead, serialize any data you may need from these external calls into assets (JSON, TXT, etc) that are also stored on the platforms Engine Flex currently supports (IPFS and Arweave)."]},{"i":"for-the-status-of-a-project-on-the-contract-how-does-active-and-paused-differ","l":"For the status of a project on the contract, how does 'active' and 'paused' differ?","p":["The value of paused is determined by artist, whereas active is determined by contract admin. Both need to be in a mintable state ( paused=false, active=true) for a project to be publicly available to mint."]},{"i":"why-is-there-a-small-delay-between-the-tokens-mint-transaction-confirming-and-it-being-viewable-on-the-art-blocks-generator-live-view","l":"Why is there a small delay between the token's mint transaction confirming and it being viewable on the Art Blocks Generator (live view)?","p":["Art Blocks uses the decentralized Graph network to index on-chain data in our publicly available subgraph. There can be a slight delay between the first block confirmation on the ethereum network for a transaction and that transaction being indexed by our subgraph. To mitigate this, as an Art Blocks engine provider, your client should be waiting multiple block confirmations (we recommend at least 2 blocks) before it shows the generator view to the user. The generator will return an error message if the token is not indexed yet, accompanied by 4XX status code. Many clients also employ a polling strategy, only showing the requested generator view once the requested generator url is returning a 2XX status code."]},{"i":"how-does-project-size-work-on-the-minter-contract-vs-core-contract","l":"How does project size work on the Minter contract vs Core contract?","p":["A project's max invocations on Art Blocks contracts are handled differently on the Core contract and the Minter contract.","On the Core contract, setting a project size establishes the project's maximum size, and this value cannot be increased once set. The max invocations on the core contract define the absolute upper limit for the number of mints for a specific project.","On the other hand, each Minter contract allows you to set max invocations for the specific minter using the manuallyLimitProjectMaxInvocations function. This setting does not lock the project size but controls the maximum number of mints allowed by that particular minter. When updating the maxInvocations value for a project in the Minter contract, you must adhere to these conditions:","The new value of _maxInvocations should not be greater than the maxInvocations set in the core contract.","The new value of _maxInvocations should not be less than the current number of invocations."]},{"i":"how-does-autoapproveartistsplitproposals-work","l":"How does autoApproveArtistSplitProposals work?","p":["When true, aproveArtistSplitProposals is a feature that allows artists to automatically change their royalty split payout address and the split percentage without requiring approval from the contract admin. This makes the process faster and more convenient for artists but may increase the risk of unauthorized changes to royalty wallets, which could complicate accounting or OFAC compliance.","If set to else the contract admin will need to approve any changes to the artist's royalty wallet, adding a layer of security and control."]},{"i":"when-should-i-enable-gpu-rendering","l":"When should I enable GPU rendering?","p":["If your image preview is showing a blank, incomplete, or invalid rendering for a token, turning on GPU rendering may resolve the issue. GPU rendering is managed by the Art Blocks team and enabling is determined on a case-by-case basis. Before requesting GPU rendering, check your project script code for any potential issues and/or try increasing your render delay (up to 10min). Reach out to the Art Blocks team to enable GPU rendering on a specific project if the token issues continue after adjusting the delay."]}],[{"l":"Art Blocks Engine Flex Technical Details","p":["This page goes deeper into some technical considerations when working with the most current version of Artblocks Engine Flex. The latest version of the Engine Flex contract (v3) and interface can be found here:","https://github.com/ArtBlocks/artblocks-contracts/blob/main/packages/contracts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol","https://github.com/ArtBlocks/artblocks-contracts/blob/main/packages/contracts/contracts/interfaces/0.8.x/IGenArt721CoreContractV3_Engine_Flex.sol"]},{"l":"Introduction To External Asset Dependencies","p":["The Engine Flex contract introduces the concept of external asset dependencies. These essentially function as on-chain pointers to off-chain assets stored using decentralized storage technologies and, with the latest version of flex, also supports fully on-chain data storage. An external asset dependency is comprised of its content identifier (CID), if it's using Arweave or IPFS, a bytecodeAddress if it's specifically dealing with fully on-chain data, and a dependencyType, which maps to an Engine Flex supported platform.","Engine Flex currently supports adding external asset dependencies of the following types:","IPFS","Arweave","Onchain (data lives entirely on the blockchain)"]},{"i":"adding-updating--removing-external-asset-dependencies","l":"Adding, Updating & Removing External Asset Dependencies","p":["When working with and manipulating a project's external asset dependencies, you'll be relying on the following functions:","Note the parameter _cidOrData, which allows you to either pass in a CID if you are working with the IPFS/Arweave dependencyTypes or a data string if you are working with the onchain dependencyType.","For convenience and utility, the contract also provides the following function, allowing you to easily grab a project's external asset dependency at a specific index:","This convenience function returns data in the form of the following format:","Note that for dependencyTypes other than onchain (IPFS, Arweave), the returned bytecodeAddress will be the zero address and data will be an empty string. Conversely, if the dependencyType is onchain, the returned cid will be an empty string.","Some important factors to keep in mind with the above functions:","Only allowlisted/artist addresses can call these.","ExternalAssetDependencyType _dependencyType is a solidity enum, which can be passed into these functions as a uint8. This enum only defines three options as of now, IPFS, ARWEAVE, and ONCHAIN, which can be represented as 0, 1, and 2 respectively."]},{"l":"Note On Removing External Asset Dependencies","p":["In the interest of saving gas, the removeProjectExternalAssetDependency() function is implemented in such a way that it does not preserve the order of the project's external asset dependency mapping. Specifically, the way this removal logic works is as follows: when an index to remove is passed in, the element at that index being removed is swapped with the element at the last index of the list of assets. Now that the last index holds the element to be removed, that element is removed off the list. This method, in addition to being more gas efficient, also ensures that our list/mapping does not have any \"holes\". The tradeoff, however, is that the removal causes the order of the external asset dependencies in this list to change, albeit in a deterministic manner: the element at the last index always moves to the removed index. This is important to keep in mind when writing your project script, though you can always update the ordering manually as you see fit by utilizing the updateProjectExternalAssetDependency() function.","You can view directly the full implementation of this removal function here: https://github.com/ArtBlocks/artblocks-contracts/blob/main/packages/contracts/contracts/engine/V3/GenArt721CoreV3_Engine_Flex.sol#L524"]},{"l":"Preferred Gateways","p":["The Engine Flex contract allows you to specify preferred gateways for the currently supported dependency types (IPFS & Arweave). Gateways are accessible HTTP interfaces and, when combined with an asset CID, expose urls for assets being stored on these off-chain decentralized platforms. These preferred gateways are updateable with a string param via the following functions: updateArweaveGateway()& updateIPFSGateway().","Please note that these preferred gateways are set per-contract, not per-project."]},{"l":"Working With External Asset Dependencies In Your Project Script","p":["When you request the live view for a given token of a project, the hash and tokenId of the token are provided in the tokenData object and the Art Blocks Generator injects this into the served HTML live view. This tokenData object has now been extended with the following external asset dependency related data, if it is available:","Your project script can then easily make use of these dependencies by combining the CID of the asset with the appropriate gateway, if you are dealing with IPFS/Arweave dependencies. As a simple example: If you have an external asset dependency with a CID QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg and a dependencyType of IPFS, you can construct the full url of your external asset dependency by combining the preferredIPFSGateway, which let's assume is https://ipfs.io/ipfs/, with the asset CID. This gives you the full url of the asset, https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg, and allows your project script to download it with fetch and use it as it sees fit. For fully onchain external asset dependencies, the full data string that is stored on the blockchain will be injected.","Note that for IPFS/Arweave external asset dependencies if your CID is pointing to a directory of assets, rather than a single asset, your project script will need to be aware of the file naming structure of this directory to fetch the assets individually. Using the previous example, imagine that CID QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg was pointing to a directory of 10 PNG images, with filenames corresponding to the numbers 1-10. Your project script would generate the same full url with the information provided, https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg, but also append the specific file you want to fetch by being aware of the naming conventions, ie https://ipfs.io/ipfs/QmXxgX5Qyhqz1t9wDFkvJtjVKYe1f8Uj714RV2n1LS76Pg/1.png."]},{"l":"Leveraging the Art Blocks Dependency Registry","p":["If you want to include additional libraries (e.g., Tone.js) supported by the Art Blocks Dependency Registry, you can add them to your project's external asset dependencies. Libraries that are fully on-chain will be clearly labeled in the drop-down as (fully on-chain).","The drop-down label for the flex asset."]},{"l":"Loading JS Libraries As External Asset Dependencies","p":["If you are specifically looking to utilize an IPFS/ARWEAVE type external asset dependency as a JavaScript library in your project script, you cannot simply add it as a script element onto the page. You must load it in a blocking manner so that the browser does not attempt to run your project script code before the lib is fully loaded. Here is an example of how to do this with ES6 dynamic imports (supported by most modern browsers: https://caniuse.com/es6-module-dynamic-import):","Here's another method without using ES6 dynamic imports, instead relying on using a callback that gets fired after the JS external asset dependency is injected into the html via a script tag:"]},{"i":"locking-a-projects-external-asset-dependencies","l":"Locking A Project's External Asset Dependencies","p":["Artists and allowlisted addresses also have the ability to lock a project's external asset dependencies:","This irreversible action removes the ability to add, update or remove from a project's external asset dependencies.","Important notes:","Preferred gateways do not get locked with this action and, in general, cannot be locked. This is intentional to allow support for modifying the preferred gateway over time, which may change while CIDs remain fixed/permanent.","You can lock a project's external asset dependencies regardless of whether or not the project itself is locked. And you can continue to modify a project's external dependencies even if the project is locked, as long as the external asset dependencies for the project are not locked."]},{"i":"why-should-i-use-the-engine-flex-specific-fields-for-cids-and-ipfs-gateways-rather-than-hard-coding-these-values-in-the-script","l":"Why should I use the Engine Flex specific fields for CIDs and IPFS gateways rather than hard-coding these values in the script?","p":["The Engine Flex contract was designed to expose specific on-contract fields for storing external asset dependencies (either via auxiliary on-chain storage, IPFS CIDs, or Arweave CIDs). For collectors and archivists preserving these art works, this increases the introspect-ability of where these external assets are stored, e.g. allowing for a more streamlined and robust process for replicating external assets stored on IPFS for a given project in the future.","Additionally, after project scripts are locked, if an IPFS gateway is hardcoded it isn't possible to update this in the future if the gateway (but not the underlying asset CIDs) needs to change for whatever reason (partner is migrating gateway providers from Pinata to Infura, partner is shutting down private gateway in favor of a public one, etc.). If using the specified on-chain fields, the CIDs can be locked independently from the gateway, allowing flexibility to preserve future compatibility of the on-chain generator down the road."]}],[{"l":"Common Custom Dashboard Mutations"},{"l":"Introduction","p":["As an Engine partner, you have the option to create a custom artist/admin dashboard. While the majority of your project configuration will occur through on-chain transactions, there are specific off-chain fields that need to be set directly via our GraphQL API.","This documentation outlines the permissions necessary for executing relevant actions and mutations. Please note that a user can only execute a mutation with the artist role for a project if their public address matches the artist address set for the project. A user can execute a mutation with the allowlisted role only if they are the super admin on the project's contract's ACL contract (V3 and up), or if they have been whitelisted on the project's contract (V2 and below).","For all mutations listed in this documentation, the user must include the x-hasura-role header in their request, specifying either artist or allowlisted as the role, as appropriate."]},{"l":"Actions","p":["Actions are specialized mutations that go beyond simple CRUD operations. Within your custom creator dashboard, you might find the updateFeatures and updateProjectMedia actions particularly useful.","The updateFeatures action initiates a test run of a feature script for a test token. Upon validating that the output aligns with the provided feature fields, it updates both the feature_fields and feature_script on the project. Both artists and allowlisted users can execute this action. Artists can make updates either before the project is completed, or afterwards, if the allowlisted user has toggled the enable_artist_update_after_completion flag on the project's associated features row.","The updateProjectMedia action refreshes various media assets linked to a project's tokens. The refreshed media depends on the parameters passed to the action, which may include different formats of preview images and features. This action is accessible to both artists and allowlisted users. However, the execution of this action is rate-limited to once 24 hours for artists.","Here are the parameters accepted by the updateProjectMedia action:","projectId: The ID of the project to be updated.","features: A boolean that indicates whether to recalculate features for the project's tokens.","render: A boolean that indicates whether to re-render the preview images for the project.","renderVideo: A boolean that indicates whether to re-render preview videos/gifs for the project.","All these actions are executed via specific mutations in the GraphQL API."]},{"l":"Tags","p":["Tags and projects share a many-to-many relationship, managed through the entity_tags table. Tags serve as non-functional descriptors that can be used to categorize projects. To associate a tag with a project, the insert_entity_tags mutation is used.","In the context of an Engine dashboard, you're likely most interested in presentation tags, which can be fetched with the following query:","Both the artist and contract admin roles have the permissions to execute the insert_entity_tags mutation. Here's an example of how to use this mutation:"]},{"l":"Project","p":["-","All these fields are updated using the update_projects_metadata_by_pk mutation.","Allowlisted Permission","Allows artists to acknowledge contributors, inspirations, or other sources of influence.","Artist Permission","artist_display_notes","artist_interview","charitable_giving_details","Contains the artist's intentions for how the artwork should be displayed.","creative_credit","Description","Determines whether GIFs and MP4s are generated during individual token refreshes, batch token refreshes, and new token mints.","disable_sample_generator","Enables the artist to specify a token ID to feature. Determines the token displayed as the project's cover image on our flagship site.","featured_token_id","Field","generate_video_assets*","Indicates the artist's preference for displaying project previews. Influences whether the \"explore possibilities\" modal is displayed on the project page on our flagship site.","link_to_license","Outlines any charitable giving aspects associated with the project.","Please note: In the tables above, 'X' stands for write permissions, and '-' stands for no write permissions.","preview_render_type","primary_render_type","Provides a link to an interview with the artist.","Provides a link to the copyright license for the project (e.g., \"https://creativecommons.org/licenses/by-nc-nd/4.0/\").","Provides specific details about the sales mechanics of the project.","render_delay*","sales_notes","Sets the delay (in seconds) before our renderer captures a snapshot of the project for preview images.","Sets the intended start time of the project, indicating when it will become unpaused and active.","Specifies the preferred format for displaying the project on detail pages.","Specifies the preferred format for the project's preview images.","start_date","The table below lists permissions for directly updating relevant off-chain fields on the project row. Many of these fields are optional and are intended to enrich the descriptive content on your frontend. Fields marked with an asterisk (*) have a functional impact on the project.","X"]}],[{"l":"Minter Suite Migration Runbook","p":["This documentation is a work in progress. Minter suite migration is ongoing, and initial migrations are being actively worked. Please reach out to the Art Blocks team with any questions.","This page provides a step-by-step guide on how to migrate a V3 Art Blocks Engine core contract from the legacy non-shared minter suite to the new shared minter suite. This migration is required for all V3 Engine contracts that want to use the new shared minter suite, which has the following benefits:","All minter contracts are indexed by the Art Blocks subgraph, and can therefore be configured in the new Artist Dashboard website (coming soon)","All minter Art Blocks Flagship minting contracts become available for use by Engine projects","Collectors can purchase from the same trusted contract they interact with on Flagship.","Art Blocks will release an SDK to simplify the minting process for Engine projects (coming soon)","Migration is not available for V2 Engine contracts; for Engine partners that wish to upgrade to a V3 Engine contract, please contact the Art Blocks team.","Migration is not required for V3 Engine contracts that wish to continue using the legacy non-shared minter suite. However, we recommend migrating to the new shared minter suite for the benefits listed above."]},{"l":"Migration Steps"},{"l":"1. Engine partner frontend updated to support new minter suite","p":["In the coming months, the Art Blocks team will be releasing a new minting SDK that can be used to support the new shared minter suite. Documentation for the SDK will be referenced here when it becomes available.","MinterDAExpHolderV5","MinterDAExpSettlementV3","MinterDAExpV5","MinterDALinHolderV5","MinterDALinV5","MinterSetPriceERC20V5","MinterSetPriceHolderV5","MinterSetPriceMerkleV5","MinterSetPricePolyptychERC20V5","MinterSetPricePolyptychV5","MinterSetPriceV5","The Engine partner's frontend must be updated to support the new shared minter suite. In general, the new shared minter suite requires the following changes:","The source code of all new, shared minter contracts is available on the Art Blocks smart contracts monrorepo. The complete list of all new, shared minter contracts is:","View functions on the minter contracts may have changed slightly. This is due to some minor architectural changes to the minter contracts that we believe simplifies their codebase and make them more extensible.","When specifying a project to configure or purchase from, an additional input arg of coreContract(address) must be specified. This is because one minter/minter filter contract is used for many core contracts."]},{"l":"2. Schedule downtime for any live projects","p":["The migration process requires all artists with live projects configure a new minter. All live projects should be paused during the migration process. Switching to the new minter filter is simple, but after migrating to the new minter filter, the artist of every live project must configure their minter in the new minter suite. This is also only a few transactions, but it is fully reliant on coordinating with artists to be ready to re-configure minters of open projects after switching to the new minter filter."]},{"i":"3-core-contract-admin-sends-migration-transactions-testnet-before-mainnet","l":"3. Core contract admin sends migration transactions (testnet before mainnet)","p":["0x13178A7a8A1A9460dBE39f7eCcEbD91B31752b91","0x28f2D3805652FB5d359486dFfb7D08320D403240","0x6a5976391E708fBf918c3786cd1FcbB88732fbc1","0x94560abECb897f359ee1A6Ed0E922315Da11752d","0xa07f47c30C262adcC263A4D44595972c50e04db7","0xa2ccfE293bc2CDD78D8166a82D1e18cD2148122b","0xC91CFC2062D8B4Ff53A7c8836CAEf925a7C78c81","0xD1d9aD8B1B520F19DFE43Cc975b9470840e8b824","Arbitrum One","Artist Staging Arbitrum-Sepolia","Artist Staging Goerli","Artist Staging Sepolia","Engine Admin calls updateMinterContract on the core contract, passing in the address of the shared minter filter.","Engine Admin calls updateRandomizerAddress on the core contract, passing in the address of the shared randomizer","Mainnet (Ethereum)","Network","Shared Minter Filter Contract Address","Shared Randomizer Contract Address","The Engine partner's core contract admin should send 2 transactions to the core contract:","You are now using the new shared minter suite!"]},{"l":"4. Artists re-configure minters for ALL LIVE PROJECTS","p":["AFTER step 3, artists must re-configure their minters for all live projects. This is a quick process, but requires coordination with artists to ensure they are ready to re-configure their minters after the switch.","Artists can re-configure their minters manually by following the instructions documented in the engine project launch/assigning a minter section. Additionally, soon, artists will be able to configure their project minters via the (new) Artist Dashboard.","The process for most open projects will likely be to switch to a fixed price minter.","After configuring a minter, the project is now using the new shared minter suite and live for minting!"]},{"l":"5. Engine partner monitors migration progress","p":["It is recommended that the Engine partner monitor the migration process to ensure that all artists have successfully re-configured their minters. Additionally, the Engine partner should use diligence to ensure that purchases and payment splits after the migration are working as expected."]},{"i":"6-add-any-custom-one-off-minters-to-the-shared-minter-suite","l":"6. Add any custom, one-off minters to the shared minter suite","p":["The new shared minter suite provides all Art Blocks Flagship minters to Engine projects. However, if the Engine partner has any custom, one-off minters that they would like to use for their core contract, they can be added for their specific contract. Please see please see the Adding custom, one-off minters page for steps on how to do this.","Note that at this time, custom, one-off minters will not be indexed in the Art Blocks Subgraph or API. This is likely not a change for custom minters being used prior to migration."]},{"l":"7. Explore new minter suite features","p":["The new shared minter suite provides all Art Blocks Flagship minters to Engine projects. Feel free to explore integrating new minters into your product!"]},{"l":"Migration FAQ"},{"i":"what-happens-if-an-artist-does-not-re-configure-their-minter","l":"What happens if an artist does not re-configure their minter?","p":["If an artist does not re-configure their minter, their project will not be able to mint tokens. The artist will need to re-configure their minter before their project can mint tokens."]},{"i":"what-happens-if-an-artist-re-configures-their-minter-incorrectly","l":"What happens if an artist re-configures their minter incorrectly?","p":["If an artist re-configures their minter incorrectly, best case scenario is that their project will not be able to mint tokens, and troubleshooting can identify the issue. Worst case scenario is that their project will be able to mint tokens, but the price per token will be incorrect (e.g. incorrect price entered) or the maximum invocations will be too high (e.g. forgot to set minter-max-invocations to a lower value than set on the core contract, if desired). For these reasons, artists should use diligence when re-configuring their minters."]},{"i":"what-happens-if-i-migrate-to-the-new-shared-minter-suite","l":"What happens if I migrate to the new shared minter suite?","p":["If you migrate to the new shared minter suite, you will be able to use any new minters developed for Art Blocks Flagship. Additionally, you will be able to use the Artist Dashboard to configure your minters, because your minter suite will be indexed. You will also be able to use the new minting SDK to simplify your minting process."]},{"i":"what-happens-if-i-do-not-migrate-to-the-new-shared-minter-suite","l":"What happens if I do not migrate to the new shared minter suite?","p":["If you do not migrate to the new shared minter suite, nothing will change, but you will miss out on new developments. You will not be able to use any new minters developed for Art Blocks Flagship. Additionally, you will not be able to use the Artist Dashboard to configure your minters, because your minter suite will not be indexed. You will need to continue to use the legacy non-shared minter suite."]},{"i":"what-happens-if-i-migrate-to-the-new-shared-minter-suite-but-i-do-not-want-to-use-the-coming-soon-artist-dashboard-to-configure-my-minters","l":"What happens if I migrate to the new shared minter suite, but I do not want to use the (coming soon) Artist Dashboard to configure my minters?","p":["There are many reasons why a partner might want to do this!","If you migrate to the new shared minter suite, but you do not want to use the Artist Dashboard to configure your minters, you can continue to configure your minters via your frontend, etherscan, etc., but your process will be slightly updated to support the new shared minter suite. Comparing the new minter contracts and the legacy minter contracts will help you understand the changes."]},{"i":"what-happens-if-i-migrate-to-the-new-shared-minter-suite-but-i-do-not-want-to-use-the-new-coming-soon-minting-sdk","l":"What happens if I migrate to the new shared minter suite, but I do not want to use the new (coming soon) minting SDK?","p":["No problem!","If you migrate to the new shared minter suite, but you do not want to use the new minting SDK, you can continue to use your existing minting process, but your process will be slightly updated to support the new shared minter suite."]}],[{"l":"Overview of V3 Core Contract","p":["The Art Blocks V3 Core Contract allows Art Blocks Curated artists, Studio artists, and Engine partners to create generative art projects on the blockchain. The contract is a shared contract that allows for multiple projects to be created and managed by different artists and creators. The V3 Core Contract is designed to be flexible and extensible, allowing for a wide range of generative art projects to be created."]},{"l":"Variants","p":["The V3 Core Contract comes in two variants:","V3 Engine","V3 Engine Flex","Both of these implementations are available for use by Art Blocks Studio artists and Engine partners.","The V3 Engine contract offers the same functionality as the original Art Blocks contract, with an artist's script being fully defined only on the blockchain. The V3 Engine Flex extends the ways artists may store additional metadata, with options of using re-usable on-chain assets, using decentralized storage networks such as IPFS or Arweave, or pointing to assets defined on the Art Blocks Dependency Registry (some of which are fully defined on-chain, some of which are defined on preferred CDN services).","For more discussion about different NFT metadata storage mechanisms, see the NFT Metadata Storage at Art Blocks page."]}],[{"l":"Creator Dashboard","p":["V3 core contracts may be managed by partners, artists and creators using the Art Blocks Creator Dashboard. The dashboard provides a user-friendly interface for managing projects, tokens, and other contract settings. The dashboard is accessible at https://create.artblocks.io.","Various features are available to creators, including:","Project Management: Create, edit, and manage projects.","Project Creation: Add new projects to your contract.","Payment Management: Manage payment addresses, view current royalty splitter address, etc."]}],[{"l":"ERC-2981 Royalties","p":["For v3.2+ contracts (all Studio contracts, Engine contracts deployed after May 2024), Art Blocks contracts conform to the ERC-2981 standard for royalties.","Note: All versions of Art Blocks core contracts integrate seamlessly with the Royalty Registry, which is supported by all major secondary marketplaces.","The ERC-2981 standard requires that royalty payments be made to a single address. Art Blocks contracts support this standard by integrating with 0xSplits to facilitate multi-party royalty payments to multiple addresses, all funneled through a single, permissionless, immutable \"splitter contract\" address.","Artists may view their current royalty splitter address in the Art Blocks Creator Dashboard. The royalty splitter address is deployed and set automatically by the v3.2+ Art Blocks core contract when payment information is configured. A link to the current splitter is available in the dashboard, and distribution of funds in the splitter may be viewed and executed via the 0xSplits website. Note that 0xSplits provides a user-friendly interface for viewing splitter balances and executing distributions, as well as robust report generation tooling.","Note: 0xSplits is a third-party service and is not affiliated with Art Blocks."]}],[{"l":"Manual Admin Operations","p":["Some rarely used admin operations are not available in the Art Blocks Creator Dashboard. These operations are available via direct interaction with the contract via a service such as Etherscan or Gnosis Safe's Transaction Builder.","A few manual admin operations are detailed below."]},{"l":"Update provider secondary royalties payment addresses or basis points","p":["Note: this describes the process for updating provider secondary royalty information - artist updates are handled within the Art Blocks Creator Dashboard.","For all V3 contracts, the contract admin can update the provider secondary royalties payment addresses or basis points by calling any of the following functions on the contract:","function updateProviderSalesAddresses","function updateProviderPrimarySalesPercentages","function updateProviderSecondarySalesBPS or function updateProviderDefaultSecondarySalesBPS(depending on minor version)","For v3.2+ contracts (deployed after May 2024), the contract admin must also propagate the contract-level changes to every project in the contract by calling the following function on the contract for each project:","syncProviderSecondaryForProjectToDefaults(uint256 projectId)","Note: The additional step of syncing provider secondary royalties to defaults was added in v3.2 to enable conformance to the ERC-2981 royalty info standard while remaining scalable within ethereum's block gas limit."]}],[{"i":"#","p":["Updated location of Creator Onboarding documentation."]},{"i":"moved---creator-onboarding-documentation","l":"Moved! - Creator Onboarding Documentation","p":["To keep things more up to date, we have moved the Creator Onboarding documentation to a new location. Navigate there for the most recent information!"]}],[{"i":"#","p":["An overview of minting philosophy at Art Blocks."]},{"l":"Minting Philosophy","p":["An overview of the generative art minting philosophy at Art Blocks."]},{"l":"Introduction","p":["At Art Blocks, minting is a particularly special occasion where a new generative art piece is created. It is the final step in the generative art creation process, and enables collectors to partner with artists to create a unique, one-of-a-kind piece of generative art!","On a blockchain, \"minting\" is the process of creating new tokens. So not only is minting the process of creating new generative art pieces, it is also the process of creating new tokens on a blockchain. Typically, minting is also the point where a collector will pay for the generative art piece.","A few key points about minting at Art Blocks:","Minting is the process of creating new generative art pieces.","Minting is the process of creating new tokens on a blockchain.","Minting generally involves a collector paying for the right to create a generative art piece."]},{"l":"Core Principles","p":["At Art Blocks, we are committed to providing a transparent minting toolkit for artists, and a transparent minting experience for collectors.","The following principles, when used together, are important ideals that we believe enable artists to achieve some sort of \"fairness\" during their drop. They also are key to collector safety when interacting on a blockchain."]},{"l":"1. Transparency","p":["We believe that minting should be transparent and easy to understand for collectors. Verified source code is provided for all minter smart contracts, and we develop our minters publically in our open source GitHub repository."]},{"i":"2-decentralized--trust-minimized","l":"2. Decentralized & Trust-Minimized","p":["We believe that minting should rely heavily on immutable smart contract code deployed to decentralized networks, and should be as trustless as possible. We aim to minimize the amount of trust in any centralized party when minting. This is important because collectors must feel safe when purchasing high-value generative art pieces, and trusting a centralized party to mint a generative art piece is often not an acceptable option.","Of course Artists and Art Blocks will have some elevated privileges, such as configuring auctions, but we aim to minimize those privileges and implement only when necessary. Those privileges will be documented and transparent, and should align incentives."]},{"l":"3. Non-Custodial","p":["Minting should be a transaction between the collector and the minter smart contract, and the contract should handle logic related to settlements, price changes over time, etc.","The minter smart contract should empower the collector to make their own decisions, and should not be custodial in nature."]},{"l":"4. Honest","p":["Blockchains have a unique set of technical quirks that can be exploited by opportunistic or malicious actors. These result in frequent discussions about bots, \"flipping\", and front-running.","We are committed to providing solutions to help alleviate these issues, but we are also committed to being honest about their limitations. Solutions must have sound fundamentals, and ones that only hide or obfuscate minting bots or other issues are not real solutions, and therefore should not be implemented. See the Lessons Learned section for more examples of this."]},{"l":"5. Flexible","p":["In some situations, a project may desire to mint in a way that is highly centralized or in some other non-traditional manner. An example of this would be a project that utilizes in-person minting at an event. In this case, the project may choose to mint from a single, centralized mobile device, but should be transparent about that decision."]},{"i":"fairness-ideals","l":"\"Fairness\" Ideals","p":["Fairness is a concept that is often discussed in the context of minting, and is worth investigating in some amount of nuance.","In an abstract sense, fairness is easy to define. Merriam-Webster defines fairness as:","\"marked by impartiality and honesty: free from self-interest, prejudice, or favoritism\".","In practice, however, fairness of a project's mint is much more difficult to define. In one sense, Art Blocks drops are entirely fair:","Open sale at a defined price or auction","Mint success is determined by transaction time/order","Transaction confirmation time is determined by the network's gas price auction","In another sense, there are many different ways to define fairness, and each definition has its own set of tradeoffs. In general, we believe there are a few types of fairness that are important to consider when an artist is considering how to distribute their project to collectors:"]},{"l":"1. Capitalist Fairness","p":["Capitalist fairness suggests that those who are willing to pay the most for a given drop should be the ones who are able to participate.","An example of a drop paradigm that is capitalist fair is a Dutch auction. In a Dutch auction, the price of a generative art piece starts high, and decreases over time until a collector is willing to pay the price. This ensures that the collector who is willing to pay the most for a generative art piece is the one who is able to mint it."]},{"l":"2. Insider Fairness","p":["Insider fairness suggests that those within an existing community should be the ones who are able to participate.","An example of a drop paradigm that is insider fair is an allowlist. In that paradigm, a collector must have reached out to an artist before the project was released to be allowed to mint. This ensures that the collector who is most involved and interested in a community is the one who is able to mint a generative art piece."]},{"l":"3. Communist Fairness","p":["Communist fairness suggests that all collectors should have an equal chance to participate, regardless of their technical skills or willingness to pay.","An example of a drop paradigm that optimizes for communist fairness would be a pure lottery, where all collectors have an equal chance to mint a generative art piece. This ensures that all collectors have an equal chance to mint a generative art piece."]},{"l":"Fairness in Practice","p":["In practice, it is difficult to achieve any of the above definitions of fairness in a pure sense. For example, a pure lottery is not possible on Ethereum, because the network is not able to discern humans from bots, and therefore a pure lottery would be susceptible to bots spamming entries and disproportionately winning the lottery.","Art Blocks aims to provide a variety of minting options for artists to choose from, each with their own set of tradeoffs. We believe that artists should be able to choose the minting paradigm that best fits their project's goals.","The minters provided by Art Blocks are intended to follow our design principles while also achieving some kind of fairness. However, each minter's amount of fairness and susceptibility to bots will vary based on:","project demand/hype","project price","market conditions","gas prices","etc.","For example, if a highly-anticipated project is sold at a low fixed-price, it is likely that bots will be able to mint a large number of generative art pieces. However, if a less-anticipated project is sold at a fixed-price, it is likely that bots will not mint a large number of generative art pieces because the speculative value of the generative art piece is not high enough to flip for a short-term profit.","The minters provided by Art Blocks are not inherently fair or unfair in nature, but when used carefully, they can provide a minting experience that stays true to our principles while also providing some amount of fairness. We believe that it is important for artists to understand the tradeoffs of each minter, and to choose the minter(s) that best fits their project's goals."]},{"l":"Minter Suite","p":["The minter suite is a collection of smart contracts that aim to provide different options for artists to distribute their project's tokens to collectors. A variety of minters are available for artists to choose from that can be used to create a variety of different minting experiences. The minters are designed to be flexible and extensible, but also to provide a consistent and familiar minting experience for collectors.","The shared minter suite is used by Art Blocks, and is also available for use with Art Blocks Engine contracts (V3 only).","More details will be added regarding the shared minter suite in the future, but for now, please see the Shared Minter Suite page for an overview of all available flagship minters at this time."]},{"l":"Lessons Learned","p":["Below is a collection of lessons that we have learned from our experience with minting generative art pieces on Ethereum."]},{"i":"one-mint-per-wallet-does-not-prevent-bots-without-an-allowlist","l":"One mint per wallet does not prevent bots (without an allowlist)","p":["In the past, we have implemented a \"1 mint per wallet\" rule, which was intended to prevent bots from minting a large number of generative art pieces. However, this rule was not effective, and actually gave an advantage to bots.","For a botter, minting from 1 or 100 wallets is nearly the same difficulty. However, for a typical collector not using bots, minting from multiple wallets adds a lot of difficulty. Ultimately, the \"1-per\" restriction puts the average collector at a huge disadvantage relative to a botter.","The \"1 mint per wallet\" rule is also somewhat misleading because it may lead collectors to believe that a project's distribution is well-diversified, when in reality, it might only be owned by a network of bots operating at many addresses.","In the end, this rule was not effective, harmed less-technical collectors, and was therefore abandoned.","Note: Limiting the number of mints per wallet on an allowlist is a different paradigm, and is a valid way to limit the number of mints per wallet."]},{"l":"Disabling minting from smart contracts does not prevent bots","p":["In the past, we have implemented a rule that prevented minting from smart contracts. This was intended to prevent bots from minting a large number of generative art pieces. However, this rule was not effective, because bots are able to mint from EOAs (externally owned accounts), and therefore are still able to mint a large number of generative art pieces.","The \"no minting from smart contracts\" rule is also somewhat misleading because it may cause collectors to believe that a project's was bot-resistant, when in reality, it is not an effective way to prevent bots from minting.","In the end, this rule was not effective, harmed collectors that wanted to mint from a smart contract (including from security-forward multi-sig wallets such as Gnosis Safe), and was therefore abandoned."]},{"l":"One mint per transaction does not prevent bots","p":["This is a rule that is implemented by some NFT projects, and is intended to prevent bots from minting a large number of generative art pieces. However, this rule is not effective, because bots are able to mint a large number of generative art pieces by submitting multiple transactions to the network's pending transaction pool.","Additionally, most implementations of this rule prevent minting from smart contracts, which is harmful to collectors that want to mint from multi-sig wallets. Other solutions require collectors to pay for additional gas fees for on-chain storage to support the rule's logic, which is also harmful to collectors.","In the end, this rule is not effective, harms less-technical and/or security-conscious collectors, and was therefore abandoned."]},{"i":"low-fixed-prices-favor-bots","l":"Low, fixed prices favor bots","p":["In general, low, fixed prices favor bots because they are able to mint a large number of generative art pieces and flip them for a short-term profit. This is especially true when the project is highly-anticipated, and when the project's generative art pieces are expected to have a high speculative value.","Bots have a large advantage over humans when it comes to minting at low, fixed prices, because they are able to submit transactions to the network's pending transaction pool at a high rate, and are able to pay high gas prices to ensure that their transactions are confirmed quickly.","In general, we recommend that artists consider using a Dutch auction or an allowlist to mitigate the effects of bots when minting at low, fixed prices."]}],[{"l":"Shared Minter Suite","p":["This page provides an overview of the Art Blocks Shared Minter Suite, which enables artists to choose how they distribute their artwork to collectors.","The Shared Minter Suite is available for all projects, including Art Blocks Engine projects.","For legacy contracts, core contract admins can view the Minter Migration Runbok for details about how to migrate to the shared minter suite."]},{"l":"Mix-and-Match","p":["Artists can mix-and-match minter options to create a custom minter configuration for their project. For example, an artist could initially use the allowlist minter to allow a specific set of collectors to mint one token per allowlisted wallet, and then could open up minting to the public via a switch to a Dutch auction with settlement minter.","Each minter supports limiting to a certain number of project invocations. For example, an artist could allow Minter A to be used for the first 1000 project invocations, and then switch to Minter B for the remaining project invocations."]},{"l":"Globally Available Minter Options","p":["The current available Minter options are discussed below. We are continually expanding our shared minter suite over time."]},{"i":"set-price---eth","l":"Set price - ETH","p":["The set price minter is used for fixed price releases. It is the simplest minter and prices all tokens at the same price, in ETH."]},{"i":"set-price---eth-allowlisted-users-only","l":"Set price - ETH, allowlisted users only","p":["Extends the functionality of the Set price, ETH minter to allow only wallets on an allowlist to mint. The allowlist can be configured to limit minting to a predetermined list of wallet addresses, and artists can specify the number of mints allowed per wallet."]},{"i":"set-price---eth-token-holders-only","l":"Set price - ETH, token holders only","p":["Extends the functionality of the Set price, ETH minter to allow only holders of a specific ERC-721 token to mint."]},{"i":"set-price---custom-erc20","l":"Set Price - custom ERC20","p":["Set price in ERC20 is a fixed price minter that allows accepting any ERC20 token as payment for your sale of tokens.","Custom ERC20 tokens can be used for a variety of purposes, including for a \"mint pass\" style experience."]},{"i":"dutch-auction-wsettlement---exponential-price-decrease","l":"Dutch auction (w/settlement) - exponential price decrease","p":["When this minter is used, all collectors will pay the same net-price as the final purchaser. This is typically the most fair and equitable Dutch auction type for buyers because all buyers pay the same price, making it a great auction type for many projects.","Collectors who purchase above the lowest price will be able to claim a settlement after the auction. The settlement will be the difference between the price they purchased at and the final purchase price. All funds are held non-custodially by the smart contract until the auction ends and revenues are collected by the artist or admin.","Exponential price curves approximate a constant percent decrease over time, making them a popular choice for Dutch auctions.","If an artist reduces the max supply of their project mid-auction, and the project sells out above auction base price, revenues must be withdrawn by core contract admin. This was implemented to protect collectors from an artist unilaterally potentially inflating sellout price during an action, and immediately withdrawing revenues. Admin concurrence is required to withdraw revenues in this case.","For supplemental information about the auction reset process, please see the Auction Reset Process section."]},{"i":"dutch-auction---exponential-price-decrease","l":"Dutch auction - exponential price decrease","p":["For Dutch auctions without settlement, artists specify the starting price, ending price, and the half-life for price drops. Collectors will pay more for tokens purchased earlier in the auction, and less for tokens purchased later in the auction.","Exponential price curves approximate a constant percent decrease over time, making them a popular choice for Dutch auctions.","For supplemental information about the auction reset process, please see the Auction Reset Process section."]},{"i":"dutch-auction---linear-price-decrease","l":"Dutch auction - linear price decrease","p":["For Dutch auctions without settlement, artists specify the starting price, ending price, and the duration of the auction. Collectors will pay more for tokens purchased earlier in the auction, and less for tokens purchased later in the auction.","Linear price curves provide a constant price decrease over time.","Two price curves are available for Dutch auctions without settlement: exponential and linear. Exponential price curves approximate a constant percent decrease over time, while linear price curves provide a constant price decrease over time.","For supplemental information about the auction reset process, please see the Auction Reset Process section."]},{"i":"dutch-auction---exponential-price-decrease-token-holders-only","l":"Dutch auction - exponential price decrease, token holders only","p":["This minter extends the functionality of the Dutch auction minter to allow only holders of a specific ERC-721 token to mint."]},{"i":"dutch-auction---linear-price-decrease-token-holders-only","l":"Dutch auction - linear price decrease, token holders only","p":["This minter extends the functionality of the Dutch auction minter to allow only holders of a specific ERC-721 token to mint."]},{"l":"Ranked auction","p":["The Ranked Auction minter allows for a ranked auction process where collectors can submit bids for a limited number of tokens. The highest bidders will receive tokens, while losing bidders will receive a refund.","All winning bids pay the same price, which is the lowest winning bid.","The ranked auction process happens non-custodially on-chain, and is scalable to arbitrarily large projects. Artists may incur gas costs associated with minting tokens for winning bidders."]},{"l":"Serial English auction","p":["The Serial English Auction (SEA) minter allows for a series of English auctions for individual tokens to be run in sequence. The minter was originally inspired by the popular nouns.wtf project, and was implemented with minor adjustments to provide a seamless experience for Art Blocks artists and collectors.","Artists may configure future token auction parameters, such as starting auction price and minimum auction length. Collectors may then kick off token auctions by submitting a bid for a pre-minted token. Once an auction begins, any wallet may submit a higher bid for the token up for sale. Losing bids are refunded automatically when outbid. If a bid is submitted near the end of an auction, the auction is extended such that a human is able to submit a higher bid, ensuring a human can fairly compete against a bot.","Once an auction is complete, another token auction may be started by any collector submitting a bid for the next token, while also sending the previous auction winner their token.","The minter pre-mints tokens before their auction, so bids are placed on an already-existing token, not on hypothetical tokens.","The minter may be used for any project, and is certainly ideal for projects that have a series of tokens that are released in a sequence. It may also be used to auction off a 1:1 token. The minter is also ideal for projects that have a strong community, as it allows for community members to participate in the auction process over a long period of time, carefully considering each generative output.","Bids and auction parameters are stored on-chain, and the Art Blocks subgraph and API index all historical bids in bids_metadata as well as auction parameters in project_minter_configurations."]},{"l":"Minimum price minter","p":["This minter enables artists to distribute tokens at a minimal price to collectors.","A small mint fee is sent to the render provider to help with the costs of rendering and indexing tokens."]},{"i":"minimum-price-minter-allowlisted-users-only","l":"Minimum price minter, allowlisted users only","p":["This minter enables artists to distribute tokens at a minimal price to an allowlisted set of collectors. The allowlist can be configured to limit minting to a predetermined list of wallet addresses, and artists can specify the number of mints allowed per wallet.","A small mint fee is sent to the render provider to help with the costs of rendering and indexing tokens."]},{"i":"polyptych-copy-hash-minter","l":"Polyptych (copy-hash) minter","p":["This minter enables the artist to mint tokens with identical token hashes. This is useful for projects that are intended to be displayed as a polyptych.","This minter allows either artists to mint child tokens to a parent token holder's wallet, or allows the parent token holder to mint child tokens.","An artist's script must work closely with the minter to ensure that the correct frame is used for each token number. For example, if a project has 3 frames, the artist's script must ensure that e.g. tokens 0-99 are minted with frame 1, tokens 100-199 are minted with frame 2, and tokens 200-299 are minted with frame 3. The artist is able to increment the frame number for their project on the minter.","This minter is technically complex, and artists must also configure the shared randomizer when using this minter.","Limited creator dashboard support is available for this minter at this time, so some interactions with the minter must be done via a service such as [Etherscan]]( https://etherscan.io/).","Despite the complexity of this minter, the resulting outputs can be very powerful and rewarding for artists and collectors!"]},{"i":"polyptych-copy-hash-minter-custom-erc20","l":"Polyptych (copy-hash) minter, custom ERC20","p":["This minter extends the functionality of the polyptych minter to allow accepting any ERC20 token as payment for your sale of tokens."]},{"i":"custom-one-off-minters","l":"Custom, One-Off Minters","p":["Engine partners can also create custom, one-off minters for their projects. These minters are only available to projects on the Engine contract that approves them, extending the globally set of available minters for their contract.","For more information about adding custom minters to your Engine contract, please see the custom minters page."]}],[{"i":"custom-one-off-minters","l":"Custom, One-Off Minters","p":["Some Engine partners may wish to add custom, one-off minters to the shared minter suite. This is able to be done by the admin of an Engine partner's core contract.","Due to the high flexibility available to custom minters, they are not indexed by the Art Blocks subgraph, and therefore are not able to be configured by artists via the Art Blocks frontend. Instead, the custom minter will need to be configured via the Engine partner's frontend, etherscan, etc.","The steps to add a custom, one-off minter to the shared minter suite are as follows:"]},{"l":"1. Write the custom minter contract","p":["The Engine partner will need to write the custom minter contract. The Art Blocks team can assist with providing guidance on how to translate a previously written, non-shared custom minter contract to be compatible with the new shared minter suite, if needed.","At a minimum, the custom minter contract will need to implement the ISharedMinterRequired interface, which is available in the Art Blocks smart contracts monrorepo. This interface requires the custom minter contract to implement the following functions:","Additionally, the custom minter contract will need to call the mint_joo function on the shared minter filter contract to mint tokens. This function is included in the IMinterFilterV1 interface in the Art Blocks smart contracts monrorepo."]},{"l":"2. Deploy the custom minter contract","p":["The Engine partner will need to deploy the custom minter contract to the desired network."]},{"l":"3. Allowlist the minter for the core contract on the shared minter filter contract","p":["The Engine partner will need to allowlist the custom minter contract for their contract, on the shared minter filter contract. This is done by doing the following:","Engine Admin calls approveMinterForContract on the shared minter filter contract, passing in the address of their core contract, and the custom minter contract","The custom minter is now ready to be used by projects on the Engine partner's core contract!"]},{"l":"4. Artist configures the custom minter for their project","p":["The artist will need to configure the custom minter for their project. Custom, one-off minters are not indexed by the Art Blocks subgraph (due to the minter being arbitrary and open-ended), so the artist will need to configure the custom minter via the Engine partner's frontend, etherscan, etc. Note that the typical minter filter function for setting a minter for a project, setMinterForProject should be used by the artist or admin to assign the custom minter for the project."]}],[{"l":"Minter Suite Supplemental Information","p":["This page provides supplemental information for the Art Blocks Shared Minter Suite.","The information below is generally most relevant for Engine core contract admins."]},{"l":"Auction Reset Process","p":["A subset of minters utilizes automated, scheduled auctions to distribute artwork to collectors. The auction reset process is a mechanism that allows artists to pause and reschedule their auction, within certain limitations, if an issue arises during a live project release. Example situations may be:","Unexpected website downtime","Artist unintentionally left project in a paused state","Auction parameters were not set as intended","Some of the possible failure modes above can result in a state where:","Collectors are not able to purchase tokens from the website","Bots are still able to purchase tokens by submitting transactions directly to the blockchain","If in a state where bots can purchase but humans can not, the situation requires immediate action to prevent or minimize damage."]},{"i":"1-urgent-pause-the-auction","l":"1. [URGENT] Pause the Auction","p":["The most important step in the auction reset process is for the Artist pause the auction. This prevents any further purchases from being made.","Tips:","Ensure that the project is not already paused (i.e. this step is already complete), and do not toggle the pause button more than once (i.e. pause then unpause)","Artist should use a very high gas price to ensure that the pause transaction is mined quickly","Artist should use a tool like Etherscan to monitor the status of the pause transaction","Verify the paused state of the contract by checking the project's core contract on a tool like Etherscan","DA with Settlement: This step is especially urgent! Settlement minters require that every new purchase price is less than or equal to the previous purchase price (even after an auction is reset). If a bot purchases a token prior to a project being paused, that project’s reconfigured auction (even after reset) is constrained to only be able to start at the bot’s purchase price."]},{"l":"2. Reset auction","p":["When using a Dutch auction, the auction will need to be reset and reconfigured.","This is a 2-step process, and requires admin-intervention for security:","ADMIN - Call resetAuctionDetails on the minter contract","ARTIST - Configure the auction parameters via your typical process (e.g. artist dashboard)"]},{"i":"3-communicate-and-enjoy","l":"3. Communicate and enjoy!","p":["Ensure your collectors are aware of the new auction parameters, and enjoy the new auction!"]},{"i":"allowlist-minter-details-non-shared-minter-suite-only","l":"Allowlist Minter Details (non-shared minter suite only)","p":["The Allowlist Minter uses a Merkle tree to gas-efficiently allow a set of addresses to mint tokens from a project.","Merkle trees are a data structure that allows for efficient verification of whether a given element is contained in a set. In the case of the Allowlist Minter, the Merkle root is stored on-chain, and Merkle proofs are included with every purchase transaction to verify that a given address is allowed to mint a token.","The information below is included to assist Engine partners in using the Allowlist minter with their projects. However, if using the shared minter suite, the Art Blocks subgraph and api are available to index Engine minter suite data, and this information is not required.","Fundamentals","The Merkle allowlist minter follows the following basic process:","An allowlist of wallet addresses is stored off-chain (e.g. in a csv file)","The artist uploads the Merkle root of the list of addresses to the Minter contract via function updateMerkleRoot","Collectors calculate and include a Merkle proof with their purchase transaction to verify that their address is included in the allowlist","Example Usage","The following typescript code demonstrates how a Merkle root and proof may be calculated for a given allowlist:"]},{"l":"Pre-Assigning Token Hash Seeds","p":["After minting is complete, the artist should call toggleProjectUseAssignedHashSeed() to disable the use of assigned hash seeds for the project, and allow the randomizer to pseudorandomly assign hash seeds to tokens as normal.","Confirm on SharedRandomizerV0's read function hashSeedSetterContracts() that the hash seed setter contract is now set to the artist wallet for the project.","Confirm on SharedRandomizerV0's read function projectUsesHashSeedSetter() that the project is now configured to use pre-assigned hash seeds (should return true).","coreContract: The address of the core contract for the project","hashSeed: The hash seed to assign to the token","hashSeedSetterContract: The address that will assign hash seeds to tokens - recommend in this use-case to set this to the artist wallet","Identify and confirm that your contract is using a SharedRandomizerV0 contract. Visit your core contract on etherscan (or appropriate L2 explorer, e.g. basescan) and inspect the read-only function randomizerContract() to confirm that the randomizer contract is a SharedRandomizerV0.","MINT! Ordering may be critical if minting specific tokens to specific addresses, so the artist may need to keep the project paused and call purchaseTo in a specific order. No other changes to the minting process are required. Confirming token hashes are as expected along the way is highly recommended.","Navigate to the SharedRandomizerV0 contract on etherscan (or appropriate L2 explorer, e.g. basescan), and connect your artist wallet. Alternatively, if your artist wallet is a multisig, interact with the sharedRandomizerV0 in something like Gnosis Safe's Transaction Builder (this is more efficient and convenient when assigning hash seeds for many tokens).","On SharedRandomizerV0, call the toggleProjectUseAssignedHashSeed() function with the artist wallet the following parameters:","On SharedRandomizerV0, from the artist wallet, call preSetHashSeed() for each token that you want to assign a hash seed to (Multicall using something like a gnosis safe is very helpful if assigning many tokens here). This function takes the following parameters:","On SharedRandomizerV0, from the artist wallet, call to the setHashSeedSetterContract function with the following parameters:","ProjectId: The ID of the project to toggle the use of assigned hash seeds for","Set the hash seed setter contract back to the zero address by calling setHashSeedSetterContract from the artist wallet.","The process for pre-assigning token hash seeds is as follows:","The shared randomizer SharedRandomizerV0 enables an artist to pre-assign token hash seeds for tokens on a project. This allows an artist to assign a specific hash seed to a token before it is minted, and then mint the token with that hash seed at a later time.","The steps above follow the pattern implemented in the following test case: shared-randomizer-v0/configure.test.ts:assigns_expected_token_when_polyptych\"","tokenId: The token ID to assign the hash seed for","tokenId: The token ID to check the hash seed for","You may confirm that token hash seeds have been properly assigned by calling the preAssignedHashSeed() read-only function on SharedRandomizerV0 with the following parameters:"]}],[{"l":"SeaDrop Integration","p":["This page provides an overview of an integration solution for the Art Blocks Shared Minter Suite with OpenSea's SeaDrop system. This is a special integration that allows Art Blocks projects to be minted and sold on OpenSea via SeaDrop, and is not a standard integration with the Shared Minter Suite.","The integration requires a few non-standard steps to ensure that the SeaDrop contract can interact with the minter suite. The steps below outline the process for integrating SeaDrop with the Art Blocks Shared Minter Suite."]},{"l":"Integration Process","p":["The integration process follows the custom, one-off minter steps, and supports minting on any project that uses the Shared Minter Suite."]},{"l":"1. Artist configures their project","p":["The artist configures their project as they normally would, using the Art Blocks Creator Dashboard.","The only exception is that the artist does not need to configure the minter for their project, as the minter will be configured separately as described in the following steps."]},{"l":"2. Deploy SeaDropXArtBlocksShim Contract","p":["The SeaDropXArtBlocksShim contract is a custom contract that allows the SeaDrop contract to interact with the Shared Minter Suite. This contract must be deployed for each project that will be integrated with SeaDrop, in order to satisfy a 1:1 mapping between the shim contract and the project.","Deployment of the SeaDropXArtBlocksShim contract is a one-time process for each project, and may be deployed by anyone. Deployment of the shim contract requires the following parameters:","Note: The allowedSeaDrop_ parameter should be set to the address of the SeaDrop contract that will be used for the project, defined by OpenSea here: https://github.com/ProjectOpenSea/seadrop/blob/main/README.md#deployments"]},{"l":"3. Admin approve minter for contract","p":["Following the custom, one-off minter steps, the admin must approve the minter for the project's core contract.","Engine Admin calls approveMinterForContract on the shared minter filter contract (via e.g. etherscan or gnosis safe tx builder), passing in the address of their core contract, and the SeaDropXArtBlocksShim custom minter contract"]},{"l":"3. Artist configures the custom minter for their project","p":["Following the custom, one-off minter steps, the artist will need to configure the custom minter for their project. The artist will need to configure the custom minter via etherscan, etc. Note that the typical minter filter function for setting a minter for a project, setMinterForProject should be used by the artist or admin to assign the custom minter for the project."]},{"i":"4-artist-configures-their-drop-on-openseas-studio","l":"4. Artist configures their drop on OpenSea's Studio","p":["The artist will need to configure their drop on OpenSea's Studio.","A general guide for configuring a drop on OpenSea Studio is published by OpenSea here: https://docs.opensea.io/docs/part-2-edit-collection-settings","In OpenSea Studio, the artist should see a new contract available to edit, which will be the SeaDropXArtBlocksShim contract. The artist should configure the drop as they normally would, using the OpenSea Studio interface.","A few options that don't make sense for Art Blocks projects, such as IPFS metadata (Art Blocks projects are on-chain), should be left blank.","If SeaDrop is configured to sell less tokens than the project's max invocations, minting on OpenSea will be limited to whatever is configured in SeaDrop.","Important: The artist must set their primary sales payment address on OpenSea Studio in a manner that properly splits the payment between the artist and the platform and/or render provider. A manually created splitter contract (e.g. using 0xSplits) may be an appropriate solution. Secondary sales will be handled automatically by the Art Blocks Core contract, but primary sales must be configured correctly in SeaDrop by the artist."]},{"l":"5. Notify OpenSea of the integration","p":["The artist should notify Art Blocks and OpenSea of the integration, so that the OpenSea team can ensure that the integration is properly displayed on their website. The shim contract must be properly configured to point to the correct project ID for items to intuitively show up in the OpenSea UI."]},{"i":"6-enjoy","l":"6. Enjoy!","p":["Your Art Blocks tokens are now available for sale on OpenSea via SeaDrop!"]},{"l":"Shim Contract Details","p":["The diagram below illustrates the relationship between different entities and the SeaDropXArtBlocksShim contract, the Shared Minter Suite, and the SeaDrop contract."]}],[{"l":"API Overview","p":["An overview of the current Art Blocks APIs.","Quick Links:","Token API","Generator API","Media API/Media Server","Art Blocks Subgraph","GraphQL API"]},{"l":"Hosted APIs","p":["As a quick overview, the main APIs that exist currently are:"]},{"l":"Token API","p":["Arbitrum One","Arbitrum Testnet","Base Mainnet","Contract Type","Engine","Flagship","https://token.arbitrum-sepolia.artblocks.io/{contractAddress}/{tokenID}","https://token.arbitrum.artblocks.io/{contractAddress}/{tokenID}","https://token.artblocks.io/{contractAddress}/{tokenID}","https://token.artblocks.io/{tokenID}","https://token.artblocks.io/0","https://token.artblocks.io/0x0a1bbd57033f57e7b6743621b79fcb9eb2ce3676/110000","https://token.base.artblocks.io/{contractAddress}/{tokenID}","https://token.sepolia.artblocks.io/{contractAddress}/{tokenID}","https://token.sepolia.artblocks.io/0x6ceab51fc8ee931df84d3db66e747b617eb7de21/12","https://token.staging.artblocks.io/{contractAddress}/{tokenID}","https://token.staging.artblocks.io/0xda62f67be7194775a75be91cbf9feedcc5776d4b/103000000","Mainnet","Note: Contract address is required","Note: Contract address is required for Engine","Pattern","Provides the token metadata for a given Art Blocks token.","Sample","Testnet"]},{"l":"Generator API","p":["Arbitrum One","Arbitrum Testnet","Base Mainnet","Contract Type","Engine","Flagship","https://generator-staging-goerli.artblocks.io/0xda62f67be7194775a75be91cbf9feedcc5776d4b/8000002","https://generator-staging-goerli.artblocks.io/0xe745243b82ebc46e5c23d9b1b968612c65d45f3d/1000001","https://generator-staging-sepolia.artblocks.io/{contractAddress}/{tokenID}","https://generator.arbitrum-sepolia.artblocks.io/{contractAddress}/{tokenID}","https://generator.arbitrum.artblocks.io/{contractAddress}/{tokenID}","https://generator.artblocks.io/{contractAddress}/{tokenID}","https://generator.artblocks.io/{tokenID}","https://generator.artblocks.io/0","https://generator.artblocks.io/0x0a1bbd57033f57e7b6743621b79fcb9eb2ce3676/11000083","https://generator.base.artblocks.io/{contractAddress}/{tokenID}","Mainnet","Note: Contract address is required","Note: Contract address is required for Engine","Pattern","Provides an i-frame-able live-view for the art associated with a given Art Blocks token.","Sample","Testnet"]},{"i":"media-apimedia-server","l":"Media API/Media server","p":["Arbitrum One","Arbitrum Testnet","Base Mainnet","Contract Type","Engine","Flagship","HD Renders – https://media.artblocks.io/hd/{tokenID}.png","https://media-proxy-arbitrum-staging.artblocks.io/{contractAddress}/{tokenID}","https://media-proxy-arbitrum.artblocks.io/{contractAddress}/{tokenID}","https://media-proxy-base.artblocks.io/{contractAddress}/{tokenID}","https://media-proxy-staging.artblocks.io/{contractAddress}/{tokenID}.png","https://media-proxy-staging.artblocks.io/{tokenID}.png","https://media-proxy-staging.artblocks.io/0.png","https://media-proxy-staging.artblocks.io/0xe745243b82ebc46e5c23d9b1b968612c65d45f3d/1000001","https://media-proxy.artblocks.io/{contractAddress}/{tokenId}.png","https://media-proxy.artblocks.io/0x145789247973c5d612bf121e9e4eef84b63eb707/782.png","https://media.artblocks.io/{tokenID}.png","https://media.artblocks.io/0.png","In addition to the standard static renders provided for each token, there are two other static renders currently provided: \"HD\" and \"thumbnail\". These items can be found at:","Mainnet","Note: Contract address is required","Pattern","Please also note that the Generator API and Media API links for a given token are included in the token response for that token from the Token API.","Please note that these additional static render formats are still currently being back-filled and may not yet be present for all tokens. Our current recommendation for those looking to depend on the \"HD\" or \"thumbnail\" responses is to a) first attempt the HD/thumb image resource that you would prefer, b) if this resource is not available, fall back to the standard sized image resource. For the current state of the ongoing backfill of HD and thumbnail assets, please refer to this spreadsheet.","Provides a static snapshot of the rendered live-view for a given Art Blocks token.","Sample","Testnet","Thumbnail Renders – https://media.artblocks.io/thumb/{tokenID}.png"]},{"l":"Art Blocks Subgraph","p":["Art Blocks has subgraphs deployed to The Graph Network for every supported network.","These subgraphs can be used to query for on-chain data related to the Art Blocks contracts, including minter suite data, token data, and project data. They provide a way to access on-chain data in a more efficient and user-friendly way than directly querying the blockchain, while keeping infrastructure decentralized, transparent, and reliable.","As of June 12, 2024, Hosted Service subgraphs are deprecated. Please use the Decentralized Graph Network subgraphs listed below for all networks, or use the Art Blocks' Hasura GraphQL API as an alternative.","The Art Blocks subgraph is developed in public, and all source code and development activity can be found in the Art Blocks subgraph repository."]},{"l":"Ethereum Mainnet","p":["Explorer Page","Graphql Endpoint: https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/6bR1oVsRUUs6czNiB6W7NNenTXtVfNd5iSiwvS4QbRPB"]},{"l":"Arbitrum One","p":["Explorer Page","Graphql Endpoint: https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/5WwGsBwJ2hVBpc3DphX4VHVMsoPnRkVkuZF4HTArZjCm"]},{"i":"artist-staging---sepolia-testnet","l":"Artist Staging - Sepolia Testnet","p":["Explorer Page","Graphql Endpoint: https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/9G5q5avz4X8GZ8UEGdu197433nSWSCsFa2eo6vHNBooc"]},{"i":"artist-staging---arbitrum-sepolia-testnet","l":"Artist Staging - Arbitrum-Sepolia Testnet","p":["Explorer Page","Graphql Endpoint: https://gateway-arbitrum.network.thegraph.com/api/[api-key]/subgraphs/id/33E6obKFpWGUhnWD5eja74Gt6oTXktiHMZVFrshg9xGe"]},{"l":"Helpful Resources","p":["Video Tutorial on creating an API Key","Managing your API Key & setting your indexer preferences","Querying from an application","How to use the explorer and playground to query on-chain data"]},{"l":"Querying the Subgraph","p":["The Art Blocks subgraphs can be queried at any of the graphql endpoints listed in the previous section."]},{"l":"Getting Minter Details","p":["A few example queries are provided below to help you get started with querying the Art Blocks subgraph for data related to a project's minter. In addition to the subgraph, the fields are also able to be queried from our Hasura GraphQL API. In the future, Art Blocks will release an SDK that will interact with these data in an even more convenient way.","Note that only Engine contracts that have migrated to the shared minter suite will have their minters indexed and available on the subgraph and Hasura GraphQL API. Only globally approved minters are indexed, so custom, one-off minters designed by Engine partners will not be indexed.","A project's active minter configuration (as configured in the artist dashboard) may be queried by pulling it from the Project entity:","note: if querying the Hasura GraphQL API, use projects_metadata instead of project","The extraMinterDetails json field of minterConfiguration will contain a JSON string that can be parsed to obtain the project-minter-configuration details that may be specific to the minter type. For example, for a Dutch Auction minter, the extraMinterDetails field may contain the following JSON string:","note: if querying the Hasura GraphQL API, the returned type will be a JSONB","Additionally, the minter's extraMinterDetails will contain a JSON string that can be parsed to obtain any minter-specific configuration details. For example, for a Dutch Auction minter, the extraMinterDetails field may contain the following JSON string:","note: if querying the Hasura GraphQL API, use minters_metadata instead of minters, and the returned type will be a JSONB","All of these queries can help you to obtain information about a project's minter configuration, which can be used to display purchase information for the project on your website. The data are available on both the subgraph, and the Hasura GraphQL API."]},{"l":"GraphQL API","p":["Arbitrum","Base","Chain","Environment","Ethereum","https://ab-prod-arbitrum.hasura.app/v1/graphql","https://ab-prod-base.hasura.app/v1/graphql","https://ab-staging-arbitrum.hasura.app/v1/graphql","https://ab-staging-goerli.hasura.app/v1/graphql","https://ab-staging-sepolia.hasura.app/v1/graphql","https://data.artblocks.io/v1/graphql","Mainnet","Production","Provides a broader set of the data that our front-end consumes — this includes both on-chain and off-chain data.","Staging","Staging (deprecated)","URL"]},{"l":"Authentication","p":["The following documentation explains how to authenticate with the Art Blocks API to retrieve a JSON Web Token (JWT). This JWT can then be used to gain authenticated access to our GraphQL API. The methods explained here are intended for a client-side environment where a signer is available to sign messages. The procedures are explained using two approaches: Direct API endpoints and GraphQL.","We recommend using the GraphQL-based approach as we have more control over it and can ensure its stability even if underlying API endpoints change. Note that the domain for authentication may change in the future for the Direct API-based approach, while the GraphQL endpoint will remain the same."]},{"i":"graphql-based-authentication-flow-recommended","l":"GraphQL-based Authentication Flow (Recommended)","p":["The GraphQL-based approach leverages the GraphQL schema provided by Art Blocks. This is the recommended approach for stability and future-proofing your implementation.","Here are the functions used in this flow:"]},{"l":"Direct API-based Authentication Flow","p":["The Direct API-based approach involves interacting with the https://artblocks.io/api/get-auth-message and https://artblocks.io/api/authenticate endpoints. We recommend using the GraphQL-based flow instead because of its improved stability and future-proofing, but we're providing the Direct API-based method for those who prefer it.","⚠️ Warning: The domain for authentication may change in the future for the Direct API-based approach. Using the GraphQL-based approach is recommended to avoid future disruptions.","Here are the functions used in this flow:","In both methods, you will find a placeholder /* code to sign message goes here */ where you should implement your code to sign the message using your client-side signer."]},{"l":"Using the JWT for Authenticated Access","p":["Once the JWT has been obtained using either of the above methods, it can be used to make authenticated requests to the Art Blocks GraphQL API. The JWT should be included in the Authorization header of the request. Here's an example:","For a full detailed overview of this GraphQL API, please reference: https://docs.artblocks.io/public-api-docs/","Additionally, you can use this interactive Hasura playground to test out queries: https://cloud.hasura.io/public/graphiql?endpoint=https://data.artblocks.io/v1/graphql"]}],[{"l":"Artblocks Viewer","p":["An overview of live.artblocks.io"]},{"l":"Routes","p":["All routes are for the environment specified in .env file and act as such. i.e. Ropsten contracts will not work on mainnet and vice versa","live.artblocks.io/ Home page of the site which returns the latest rendered minted token from any of the Art Blocks contracts","live.artblocks.io/{CONTRACT_ADDRESS} enter any Art Blocks or Engine contract and you be presented with the latest rendered mint.","Example: Latest Artblocks_VO mint","live.artblocks.io/{CONTRACT_ADDRESS}/{PROJECT_INDEX} enter any Art Blocks or Engine contract followed by the index of the project and you be presented with the latest rendered mint.","Example: Latest Chromie Squiggle mint","live.artblocks.io/token/{TOKEN_ID} enter any Art Blocks or Engine token id and you are presented with that token.","Example: Chromie Squiggle mint #71","live.artblocks.io/random/{CONTRACT_ADDRESS} enter any Art Blocks or Engine contract address and you are presented with a random active project","Example: Random Art Blocks v3 contract","live.artblocks.io/random/{CONTRACT_ADDRESS}/{PROJECT_INDEX} enter any Art Blocks or Engine contract address and a project index you are presented with a random token from that project","Example: Random Chromie Squiggles"]},{"l":"Random Query Params","p":["You can add any query params from the customizable display listed below as well as two random specific query params.","reloadClick: this is to turn on click reloading where if you click the token it will give you a new token from that project. default: false","reloadDelay: this is to turn on auto refreshing after the specified time in seconds to give you a new token from that project. default: none","Example URLs:","Click turned on","Delay of 30 seconds and click turned on","Delay of 30 seconds with no click"]},{"l":"Contracts","p":["This is a running list of contract addresses for various Art Blocks and Engine","Mainnet:","Artblocks_VO: 0x059edd72cd353df5106d2b9cc5ab83a52287ac3a","Artblocks_V1: 0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270","ARTCODE: 0xd10e3dee203579fcee90ed7d0bdd8086f7e53beb","Doodle Labs: 0x28f2d3805652fb5d359486dffb7d08320d403240","CryptoCitizens: 0xbdde08bd57e5c9fd563ee7ac61618cb2ecdc0ce0","Flutter: 0x13aae6f9599880edbb7d144bb13f1212cee99533","MOMENT: 0x0a1bbd57033f57e7b6743621b79fcb9eb2ce3676","Plottables: 0xa319c382a702682129fcbf55d514e61a16f97f9c","TBOA: 0x62e37f664b5945629b6549a87f8e10ed0b6d923b"]},{"l":"Customizable Display","p":["A Plottables project (full screen)","Algobots (with text)","All of the customization that can be done and the default values are as follows:","backgroundColor: this can be any six digit hex color and is the background color of the page default: ffffff","Example URLs:","fontSize: this can be any valid html size and is the size of the text default: 20px","height: this can be any valid html size and is the height of the token being displayed default: 90vh","Latest Artblocks Mint","Latest Chimera","showText: this is whether or not to show the text information about the currently displayed token. All other text params depend on this to be true to work default: false","Streamlines #414","textBackground: this can be any six digit hex color and is the background color of the text default: none","textBottom: this can be any valid html size and is the distance from the bottom of the screen of the text default: 3em","textColor: this can be any six digit hex color and is the color of the text default: 000000","useCustomViewParams: this is to specify you are using the custom view display and all other params require this to be true. default: false","width: this can be any valid html size and is the width of the token being displayed default: 90vw","You can create a customizable display for any route on artblocks-viewer. This is done through query params added to the end of the url. In order to activate this ability you must first add ?useCustomViewParams=true to the end of whatever route you are using. Here is the most basic customized url of Chromie Squiggle mint #71 with just the squiggle centered in the middle of the page."]}],[{"l":"Querying","p":["Below are some sample queries you can use to gather information from the Art Blocks contracts.","You can build your own queries using a GraphQL Explorer and enter your endpoint to limit the data to exactly what you need."]},{"l":"Subgraph Querying Walkthrough","p":["The following provides some examples of how to use the Art Blocks subgraph to perform a handful of common queries."]},{"l":"Important Notes","p":["Performance/indexing on the hosted subgraph service is oftentimes slower compared to the decentralized subgraph. That being said, the hosted subgraph is free while the decentralized one requires pay-per-query in GRT.","The Art Blocks subgraphs currently also index any PBAB (Powered by Artblocks) contracts, in addition to the core Art Blocks contracts. Please keep that in mind and make use of the contract_in filter to ensure you are working with Art Blocks data only, if that is your intention.","While querying against the mainnet subgraph if using the contract_in filter the Art Blocks contracts to restrict for are 0x059edd72cd353df5106d2b9cc5ab83a52287ac3a(for the V0 contract that supports projects 0-3) and 0xa7d8d9ef8d8ce8992df33d8b8cf4aebabd5bd270(for the V1 contract that supports projects 4-current).","The Art Blocks contract to restrict for is 0xda62f67be7194775a75be91cbf9feedcc5776d4b on testnet."]},{"l":"The Basics","p":["Retrieving a specific Art Blocks project by short ID (no contract):","Retrieving a specific Art Blocks project by full ID (includes contract):","Retrieving a specific Art Blocks token by short ID (no contract):","Retrieving a specific Art Blocks token by full ID (includes contract):"]},{"l":"Beyond The Basics","p":["Retrieve the last 5 most recently created projects across Art Blocks and Powered by Art Blocks (remember that you can use a contract_in filter to restrict this to only specific contracts):","Retrieve the top 10 projects across Art Blocks and Powered by Art Blocks, based on # of invocations:","Retrieve the most recently minted Art Blocks token:","Retrieve all tokens owned by a specific address, across Art Blocks and Powered by Art Blocks:","Retrieve the general metadata/status for the Art Blocks subgraph (useful for debugging):","Retrieve the project script for a given project id","Pagination should be used for large queries. The Graph enforces upper limits on first and skip parameters since they generally perform poorly when set to large values (limits as of 01/2022 are first=1000 and skip=5000). It is much better to page through entities based on an attribute such as token ID, block number, or some other parameter. For more information, see The Graph documentation"]},{"l":"Project info","p":["Pull all projects and return their name, as well as lots of additional data:","Get all the wallet owners of a project (Replace PROJECT with the project name you are looking for)","If you're looking for the addresses of anyone that owns a mint from a project","Get that txnhash for squiggle 0, you could run the following query on the AB subgraph playground"]}],[{"l":"Entities","p":["Account","AccountProject","Contract","CoreRegistry","Dependency","DependencyAdditionalCDN","DependencyAdditionalRepository","DependencyRegistry","DependencyScript","Minter","MinterFilter","MinterFilterContractAllowlist","Project","ProjectExternalAssetDependency","ProjectMinterConfiguration","ProjectScript","ProposedArtistAddressesAndSplit","Receipt","Token","Transfer","Whitelisting"]},{"l":"Project","p":["A project is complete when it has reached its maximum invocations","Account!","AccountProject!","Accounts that own tokens of the project","activatedAt","active","additionalPayee","additionalPayeePercentage","additionalPayeeSecondarySalesAddress","additionalPayeeSecondarySalesPercentage","Address to split primary sales with the artist","Address to split Secondary sales with the artist","artist","Artist description of the project","Artist name","Artist or project website","Artist that created the project","Artist/additional payee royalty percentage","artistAddress","artistName","Aspect ratio of the project (see scriptJSON if null)","aspectRatio","baseIpfsUri","baseUri","BigInt","BigInt!","Boolean","Boolean!","Bytes","Bytes!","complete","completedAt","contract","Contract associated to project","Contract!","createdAt","Curated, playground, factory. A project with no curation status is considered factory","curationStatus","Currency symbol for ERC-20","currencyAddress","currencySymbol","Description","Description: get various details about a specific project","Determines if the project should be visible to the public","Does the project actually use the hash string","Does the project use media from ipfs","dynamic","ERC-20 contract address if the project is purchasable via ERC-20","externalAssetDependencies","externalAssetDependenciesLocked","externalAssetDependencyCount","Extra information about the script and rendering options","Field","For V3 and-on, this field is null, and projects lock 4 weeks after completedAt. Once the project is locked its script may never be updated again","id","ID of the project on the contract","ID!","Interplanetary File System function that meets the encrypted demands needed to solve for a blockchain computation","invocations","ipfsHash","Is the project dynamic or a static image","license","License for the project","locked","Lookup table to get the Sale history of the project","Maximum number of invocations allowed for the project","maxInvocations","Minter configuration for this project (not implemented prior to minter filters)","minterConfiguration","name","Number of times the project has been invoked - number of tokens of the project","Once the project's external asset dependencies are locked they may never be modified again","owners","Parts of the project script","paused","Percentage of artist's share of primary sales that goes to additional payee","Percentage of artist's share of secondary sales that goes to additional payee","pricePerTokenInWei","Project name","Project!","ProjectExternalAssetDependency!","projectId","ProjectMinterConfiguration","Projects external asset dependencies","Proposed Artist addresses and payment split percentages","ProposedArtistAddressesAndSplit","proposedArtistAddressesAndSplits","Purchases paused","royaltyPercentage","SaleLookupTable!","saleLookupTables","script","Script type and version (see scriptJSON if null)","scriptCount","scriptJSON","scripts","scriptTypeAndVersion","scriptUpdatedAt","String","The base URI is the mutual part among each NFT's URI. By default, the URI is baseURI/tokenId","The full script composed of scripts","The number of external asset dependencies stored on-chain","The number of scripts stored on-chain","Timestamp at which a project was completed","Token!","tokens","Tokens of the project","Type","Uniform Resource Identifier Interplanetary File System (IPFS) of a nonfungible token","Unique identifier made up of contract address and project id","updatedAt","useHashString","useIpfs","Wallet address of the artist","website","Wei is the smallest denomination of ether—the cryptocurrency coin used on the Ethereum network. One ether = 1,000,000,000,000,000,000 wei (1018)","WHen project activated","When project initiated","When project updated","when the script was updated"]},{"l":"ProjectScript","p":["BigInt!","Description","Description: get specific details of the project script","Field","id","ID!","index","Name of project","project","Project!","script","Script of the project","String!","The dependency index","Type","Unique identifier made up of contract address and project id"]},{"l":"ProposedArtistAddressesAndSplit","p":["additionalPayeePrimarySalesAddress","additionalPayeePrimarySalesPercentage","additionalPayeeSecondarySalesAddress","additionalPayeeSecondarySalesPercentage","artistAddress","BigInt!","Bytes!","createdAt","Description","Description: get specific details on the pay flow for a specified artist","Field","id","ID!","project","Project associated with this proposed artist addresses and splits","Project!","Proposed artist additional payee address for primary sales","Proposed artist additional payee address for secondary sales","Proposed artist additional payee percentage for primary sales","Proposed artist additional payee percentage for secondary sales","Proposed artist address","Type","Unique identifier made up of contract address and project id","When address initiated"]},{"l":"CoreRegistry","p":["Description: Get specific details on the Art Blocks Core registry. At this time, this is used for indexing purposes of V3 contracts, as well as acting as an allowlist of core contracts that may mint on a shared minter filter.","Field","Type","Description","id","ID!","Unique identifier made up of the Core Registry's contract address. note: for legacy MinterFilters, this is a dummy ID, equal to the address of the single core contract associated with the minter filter","registeredContracts","[Contract!]","All core contracts that are registered on this CoreRegistry, when this is the most recent Core Registry to add the contract"]},{"l":"Contract","p":["[Bytes!]!","Accounts whitelisted on the contract","Address that receives primary sales platform fees","Address that receives primary sales platform fees, only for V3_Engine contracts","Address that receives secondary sales platform royalties (null for pre-V3 contracts, check Royalty Registry)","Address that receives secondary sales platform royalties, only for V3_Engine contracts","Associated minter filter (if applicable)","autoApproveArtistSplitProposals","Automatically approve all artist split proposals (used on V3 Engine contracts)","Basis points of secondary sales allocated to the platform (null for pre-V3 contracts, check Royalty Registry)","Basis points of secondary sales allocated to the platform, only for V3_Engine contracts","BigInt","BigInt!","Boolean","Boolean!","Bytes","Bytes!","Core contract type","CoreType!","createdAt","Curation registry contract address","curationRegistry","Dependency registry contract address","dependencyRegistry","Description","Description: get specific information about contracts","enginePlatformProviderAddress","enginePlatformProviderPercentage","enginePlatformProviderSecondarySalesAddress","enginePlatformProviderSecondarySalesBPS","EngineRegistry","Field","id","ID!","Latest engine registry that this contract is registered with, if any (used for indexing purposes)","List of contracts that are allowed to mint","List of projects on the contract","List of tokens on the contract","minterFilter","mintWhitelisted","New projects forbidden (can only be true on V3+ contracts)","newProjectsForbidden","nextProjectId","Percentage of primary sales allocated to the platform","Percentage of primary sales allocated to the platform, only for V3_Engine contracts","preferredArweaveGateway","preferredIPFSGateway","Project ID listed on the contract","Project!","projects","Randomizer contract used to generate token hashes","randomizerContract","registeredOn","renderProviderAddress","renderProviderPercentage","renderProviderSecondarySalesAddress","renderProviderSecondarySalesBPS","String","The Engine Flex contract allows you to specify preferred gateways for the currently supported dependency types (IPFS & Arweave)","Token!","tokens","Type","Unique identifier made up of contract address","updatedAt","When contract initiated","When contract updated","whitelisted","Whitelisting!"]},{"l":"Whitelisting","p":["Description: get whitelist information","Field","Type","Description","id","ID!","Unique identifier whitelist account id","account","Account!","Account associated to whitelisting","contract","Contract!","contract associated to whitelisting"]},{"l":"Account","p":["AccountProject!","Contracts the account is whitelisted on","Description","Description: get specific information about an account","Field","id","ID!","Project!","Projects the account is listed as artist for","Projects the account owns tokens from","projectsCreated","projectsOwned","Token!","tokens","Tokens the account has","Type","Unique identifier account id","whitelistedOn","Whitelisting!"]},{"l":"AccountProject","p":["account","Account associated to project","Account!","count","Description","Description: get project account information","Field","id","ID!","Int!","Name of project","project","Project!","Total count of the project","Type","Unique identifier token id"]},{"l":"Token","p":["Account!","BigInt!","Bytes!","contract","Contract the token is on","Contract!","createdAt","Current owner of the token","Description","Description: get various token information","Field","hash","id","ID of the token on the contract","ID!","invocation","Invocation number of the project","Lookup table to get the Sale history","Next available sale id","nextSaleId","owner","project","Project of the token","Project!","SaleLookupTable!","saleLookupTables","Specifies the endpoint for retrieving access tokens when OAuth 2.0 authentication is enabled","String","tokenId","Transaction hash of token mint","transactionHash","Transfer!","transfers","Transfers of the token","Type","Unique identifier made up of contract address and token id","Unique string used as input to the tokens project script","updatedAt","uri","When token initiated","When token updated"]},{"l":"MinterFilter","p":["[Minter!]!","[MinterFilterContractAllowlist!]!","BigInt!","Core contract registry used by this MinterFilter. Note: For MinterFilter V0 and V1, a dummy CoreRegistry is used","coreRegistry","CoreRegistry!","Description","Description: get details about minters on a project","Field","id","ID!","Known minters that are tied to this MinterFilter, but are not necessarily approved on this MinterFilter","knownMinters","Minter!","minterFilterContractAllowlists","minterGlobalAllowlist","Minters allowlisted at a contract-level on this MinterFilter","Minters allowlisted globally on this MinterFilter","Type","Unique identifier made up of minter contract address","updatedAt","When minter updated"]},{"l":"MinterFilterContractAllowlist","p":["[Minter!]!","BigInt!","contract","Contract!","Core contract","Description","Description: Defines a contract-specific allowlist of minters specifically approved on a given shared minter filter. This is used to extend the set of allowlisted minters beyond a shared minter filter's set of globally allowlisted minters.","Field","id","ID!","Minter contract addresses allowed at the contract level (extending global MinterFilter allowlist)","minterContractAllowlist","minterFilter","MinterFilter contract","MinterFilter!","Type","Unique identifier made up of -","updatedAt","When last updated"]},{"l":"Minter","p":["[Receipt!]","Associated Minter Filter","BigInt!","Boolean representing if the Minter is globally allowed on its associated minter filter","Boolean!","Configuration details used by specific minters (json string)","Description","Description: get details about mint on a project","extraMinterDetails","Field","id","ID!","isGloballyAllowlistedOnMinterFilter","Minter type","minterFilter","MinterFilter!","MinterType!","receipts","Receipts for this minter, only for minters with settlement","String!","Type","Unique identifier made up of minter contract address","updatedAt","When the minter updated"]},{"l":"ProjectMinterConfiguration","p":["basePrice","BigInt","Boolean!","Bytes!","Configuration details used by specific minter project configurations (json string)","currency address as defined on minter - address(0) reserved for ether","currency symbol as defined on minter - ETH reserved for ether","currencyAddress","currencySymbol","Defines if purchasing token to another is allowed","Description","Description: get details of a specific mint","extraMinterDetails","Field","id","ID!","Maximum number of invocations allowed for the project (on the minter)","maxInvocations","minter","Minter!","price of token or resting price of Duch auction, in wei","priceIsConfigured","project","Project!","purchaseToDisabled","String!","The associated minter","The associated project","true if project's token price has been configured on minter","Type","Unique identifier made up of --"]},{"l":"Receipt","p":["account","Account!","BigInt!","Description","Description: get details about purchases on a minter with settlement","Field","id","ID!","Last updated timestamp","minter","Minter!","netPosted","numPurchased","project","Project!","The associated account","The associated minter","The associated project","The total net amount posted (set to settlement contract) for tokens","The total quantity of tokens purchased on the project","Type","Unique identifier made up of ---","updatedAt"]},{"l":"Transfer","p":["address transferred from","address transferred to","BigInt!","Bytes!","createdAt","Description","Description: transfer info on an NFT","Field","from","id","ID!","to","token","token address of NFT","Token!","transaction hash of transfer","transactionHash","Type","Unique identifier of transfer","when transfer initiated"]},{"l":"ProjectExternalAssetDependency","p":["BigInt!","cid","dependencyType","Description","Description: get info about projects external asset dependency","Field","id","ID!","index","project","Project!","ProjectExternalAssetDependencyType!","String!","The associated project","The dependency cid","The dependency index","The dependency type","Type","Unique identifier made up of projectId-index"]},{"l":"Dependency","p":["[DependencyAdditionalCDN!]!","[DependencyAdditionalRepository!]!","[DependencyScript!]!","Additional CDNs for this dependency","Additional repositories for this dependency","additionalCDNCount","additionalCDNs","additionalRepositories","additionalRepositoryCount","BigInt!","Concatenated string of all scripts for this dependency","Dependency registry contract that this dependency is registered on","dependencyRegistry","DependencyRegistry!","Description","Description: information about registered dependency (e.g. p5js@1.0.0)","Field","id","ID!","List of on-chain scripts that for this dependency","Number of additional CDNs for this dependency","Number of additional repositories for this dependency","Number of on-chain scripts for this dependency","Preferred CDN for this dependency","Preferred repository for this dependency","preferredCDN","preferredRepository","Reference website for this dependency (e.g. https://p5js.org)","referenceWebsite","script","scriptCount","scripts","String","String!","Timestamp of last update","Type","Unique identifier made up of dependency name and version separated by an @ symbol (e.g. p5js@1.0.0)","updatedAt"]},{"l":"DependencyRegistry","p":["[Contract!]!","[Dependency!]","BigInt!","Bytes!","Core contracts that this registry can provide dependency overrides for","Current owner of this contract","dependencies","Description","Description: information about a dependency registry contract","Field","id","List of dependencies that are registered on this registry contract","owner","supportedCoreContracts","Timestamp of last update","Type","Unique identifier made up of dependency registry contract address","updatedAt"]},{"l":"DependencyAdditionalCDN","p":["BigInt!","cdn","dependency","Dependency this additional CDN belongs to","Dependency!","Description","Description: information about an additional CDN for a dependency","Field","id","ID!","index","Index of this additional CDN","String!","Type","Unique identifier made up of dependency id and index","URL of the CDN"]},{"l":"DependencyAdditionalRepository","p":["BigInt!","dependency","Dependency this additional repository belongs to","Dependency!","Description","Description: information about an additional repository for a dependency","Field","id","ID!","index","Index of this additional repository","repository","String!","Type","Unique identifier made up of dependency id and index","URL of the repository"]},{"l":"DependencyScript","p":["address","Address of the bytecode storage contract for this script","BigInt!","Bytes!","Contents of script","dependency","Dependency this script belongs to","Dependency!","Description","Description: information about a script for a dependency","Field","id","ID!","index","Index of this script","script","String!","Type","Unique identifier made up of dependency id and index"]}]]
\ No newline at end of file
diff --git a/sitemap.xml.gz b/sitemap.xml.gz
index 00d3413e..613be4dc 100644
Binary files a/sitemap.xml.gz and b/sitemap.xml.gz differ
diff --git a/static/screenshot4.png b/static/screenshot4.png
new file mode 100644
index 00000000..1e901c03
Binary files /dev/null and b/static/screenshot4.png differ