I have done it. A block that allows you to create custom blocks.
Credits: Thanks to wunder_wulfe for creating this block:
and the js for this script
(the [scratchblocks] (name) [/scratchblocks] part was me)
(thanks to @ego-lay_atman-bay for telling me this)
project
source
xml
<blocks app="Snap! 7, https://snap.berkeley.edu" version="2"><palette><category name="Developer Version" color="150,150,150,1"/></palette><block-definition s="create block name %'name' category %'category' type %'type' code %'typecode' %'code'" type="command" category="Developer Version"><comment w="161" collapsed="false">Created by Mr_OwlsssSnap
----------------------------------------------------
Creates a block with the code you give it. It has two options: XML or blocks. If you are using blocks, make sure to put in a ring. 
Requires JS.</comment><variables><list struct="atomic" id="3">xml,block xml</list></variables><header></header><code></code><translations></translations><inputs><input type="%s"></input><input type="%s">other<options>motion
looks
sound
pen
control
sensing
operators
variables
other</options></input><input type="%s" readonly="true">command<options>command
booleen
reporter</options></input><input type="%s">blocks<options>blocks
xml</options></input><input type="%txt"></input></inputs><script><custom-block s="Created by Mr_OwlsssSnap"></custom-block><block s="doIfElse"><custom-block s="JavaScript enabled?"></custom-block><script><block s="doIfElse"><block s="reportEquals"><block var="typecode"/><l>blocks</l></block><script><block s="doSetVar"><l>block xml</l><custom-block s="Script : Export %cmdRing"><block var="code"/></custom-block></block><block s="doRun"><block s="reportJSFunction"><list><l>xmlString</l><l>silent</l></list><block s="reportJoinWords"><list><l>this.parentThatIsA(IDE_Morph).rawOpenBlocksString(xmlString, "</l><block var="name"/><l>", true)</l></list></block></block><list><block s="reportJoinWords"><list><l><blocks app="Snap! 7, https://snap.berkeley.edu" version="2"><block-definition s="</l><block var="name"/><l>" type="</l><block var="type"/><l>" category="</l><block var="category"/><l>"><header></header><code></code><translations></translations><inputs></inputs></l><block var="block xml"/><l></block-definition></blocks></l></list></block><l></l><l></l></list></block></script><script><block s="doRun"><block s="reportJSFunction"><list><l>xmlString</l><l>silent</l></list><block s="reportJoinWords"><list><l>this.parentThatIsA(IDE_Morph).rawOpenBlocksString(xmlString, "</l><block var="name"/><l>", true)</l></list></block></block><list><block s="reportJoinWords"><list><l><blocks app="Snap! 7, https://snap.berkeley.edu" version="2"><block-definition s="</l><block var="name"/><l>" type="</l><block var="type"/><l>" category="</l><block var="category"/><l>"><header></header><code></code><translations></translations><inputs></inputs></l><block var="code"/><l></block-definition></blocks></l></list></block><l></l><l></l></list></block></script></block></script><script><block s="doApplyExtension"><l>err_error(msg)</l><list><l>You need to enable JavaScript in order for this block to run.</l></list></block></script></block><custom-block s="Created by Mr_OwlsssSnap"></custom-block></script></block-definition><block-definition s="JavaScript enabled?" type="predicate" category="sensing"><comment x="0" y="0" w="90" collapsed="false">Tells you if JavaScript is enabled with no error if it is not.</comment><header></header><code></code><translations></translations><inputs></inputs><script><block s="doDeclareVariables"><list><l>a</l></list></block><block s="doSetVar"><l>a</l><block s="reportBoolean"><l><bool>false</bool></l></block></block><custom-block s="safely try %cs then if %upvar %cs"><script><block s="doSetVar"><l>a</l><block s="evaluate"><block s="reportJSFunction"><list></list><l>return true;</l></block><list></list></block></block></script><l>error</l><script><block s="doIf"><block s="reportEquals"><block var="error"/><l>JavaScript extensions for Snap! are off</l></block><script><block s="doSetVar"><l>a</l><block s="reportBoolean"><l><bool>false</bool></l></block></block></script></block></script></custom-block><block s="doReport"><block var="a"/></block></script><scripts><script x="167" y="95.46666666666664"><block s="fork"><block s="reifyScript"><script><block s="doWarp"><script></script></block></script><list></list></block><list></list></block></script><script x="316" y="201.80000000000007"><block s="doDeclareVariables"><list><l>a</l></list></block><block s="doSetVar"><l>a</l><block s="reportBoolean"><l><bool>false</bool></l></block></block><block s="fork"><block s="reifyScript"><script><block s="doWarp"><script><block s="doSetVar"><l>a</l><block s="evaluate"><block s="reportJSFunction"><list></list><l>return true;</l></block><list></list></block></block></script></block></script><list></list></block><list></list></block><block s="doRepeat"><l>1</l><script><block s="doWait"><l>0</l></block></script></block><block s="doReport"><block var="a"/></block></script></scripts></block-definition><block-definition s="safely try %'action' then if %'error' %'handler'" type="command" category="control"><comment x="0" y="0" w="276" collapsed="false">Catch errors.

Runs the first script. If it succeeds, nothing else happens.
But if it has an error (something that would otherwise result
in a red halo around the block), then the second script is run,
with the text of the error message that would have been shown in the variable ERROR.</comment><header></header><code></code><translations>pt:tenta executar _ e, em caso de erro _ , executa _
ca:prova de forma segura _ i si _ _
</translations><inputs><input type="%cs"></input><input type="%upvar"></input><input type="%cs"></input></inputs><script><block s="doApplyExtension"><l>err_try(cmd, catch, err)</l><list><block var="action"/><block var="handler"/><block var="error"/></list></block><block s="doApplyExtension"><l>err_reset</l><list></list></block></script></block-definition><block-definition s="Script : Export %'script'" type="reporter" category="control"><header></header><code></code><translations></translations><inputs><input type="%cmdRing"></input></inputs><script><block s="doReport"><block s="evaluate"><block s="reportJSFunction"><list><l>script</l></list><l>var ide = this.parentThatIsA(IDE_Morph),
 blockEditor = this.parentThatIsA(BlockEditorMorph);
if (!ide && blockEditor) {
 ide = blockEditor.target.parentThatIsA(IDE_Morph);
}
if (ide) {
 return ide.serializer.serialize( script.expression);
}</l></block><list><block var="script"/></list></block></block></script></block-definition><block-definition s="Created by Mr_OwlsssSnap" type="command" category="other" helper="true"><header></header><code></code><translations></translations><inputs></inputs></block-definition></blocks>
Idk what you would use this for, but here ya go.
(C) 2022 Mr_OwlsssSnap