From f5b8a56572fa6f234a5560fddda31f1297e6858b Mon Sep 17 00:00:00 2001 From: Blockmaker <202785564+blockmaker-ai@users.noreply.github.com> Date: Tue, 7 Jul 2026 10:07:36 +0100 Subject: [PATCH 1/2] Fix WebGL builds: emscripten-safe syntax in wallet bridge jslib Unity's emscripten acorn-optimizer (JSDCE/minify pass) cannot convert dynamic import() and optional-chaining AST nodes, failing every WebGL build that includes this plugin with 'MOZ_TO_ME[node.type] is not a function'. Rewrite the 5 dynamic imports via Function-constructor indirection (string bodies are not parsed) and the 3 optional chains as explicit guards. Behavior unchanged. Co-Authored-By: Claude Fable 5 --- Plugins/WebGL/BlockmakerWalletBridge.jslib | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Plugins/WebGL/BlockmakerWalletBridge.jslib b/Plugins/WebGL/BlockmakerWalletBridge.jslib index 1c60714..3c4cdda 100644 --- a/Plugins/WebGL/BlockmakerWalletBridge.jslib +++ b/Plugins/WebGL/BlockmakerWalletBridge.jslib @@ -122,7 +122,7 @@ mergeInto(LibraryManager.library, { if (window._bmSignClientPromise && !window._bmSignClientFailed) return window._bmSignClientPromise; window._bmSignClientFailed = false; window._bmSignClientPromise = - import('https://cdn.jsdelivr.net/npm/@walletconnect/sign-client@2.17.3/+esm') + (new Function('return import(\"https://cdn.jsdelivr.net/npm/@walletconnect/sign-client@2.17.3/+esm\")'))() .then(function(mod) { var SC = mod.SignClient || (mod.default && mod.default.SignClient); if (!SC) throw new Error('SignClient not found in module'); @@ -506,8 +506,8 @@ mergeInto(LibraryManager.library, { if (window._bmMagicPromise && !window._bmMagicFailed) return window._bmMagicPromise; window._bmMagicFailed = false; window._bmMagicPromise = Promise.all([ - import('https://cdn.jsdelivr.net/npm/magic-sdk@33.7.1/+esm'), - import('https://cdn.jsdelivr.net/npm/@magic-ext/algorand@26.2.0/+esm') + (new Function('return import(\"https://cdn.jsdelivr.net/npm/magic-sdk@33.7.1/+esm\")'))(), + (new Function('return import(\"https://cdn.jsdelivr.net/npm/@magic-ext/algorand@26.2.0/+esm\")'))() ]).then(function(mods) { var Magic = mods[0].Magic || (mods[0].default && mods[0].default.Magic) || mods[0].default; var AlgorandExtension = mods[1].AlgorandExtension || (mods[1].default && mods[1].default.AlgorandExtension) || mods[1].default; @@ -743,13 +743,13 @@ mergeInto(LibraryManager.library, { if (window._bmXChainPromise && !window._bmXChainFailed) return window._bmXChainPromise; window._bmXChainFailed = false; window._bmXChainPromise = - import('https://cdn.jsdelivr.net/npm/@algorandfoundation/xchain-js/+esm') + (new Function('return import(\"https://cdn.jsdelivr.net/npm/@algorandfoundation/xchain-js/+esm\")'))() .then(function(mod) { window._bmXChain = mod; return mod; }) .catch(function() { - return import('https://cdn.jsdelivr.net/npm/algo-models/+esm') + return (new Function('return import(\"https://cdn.jsdelivr.net/npm/algo-models/+esm\")'))() .then(function(mod) { window._bmXChain = mod; return mod; @@ -790,7 +790,7 @@ mergeInto(LibraryManager.library, { return loadXChainSDK(); }) .then(function(xchain) { - var deriveAddress = xchain.deriveAddress || xchain.getAlgorandAddress || xchain.default?.deriveAddress; + var deriveAddress = xchain.deriveAddress || xchain.getAlgorandAddress || (xchain.default && xchain.default.deriveAddress); if (!deriveAddress) throw new Error('xChain SDK: address derivation function not found.'); var algoAddr = deriveAddress(evmAddress); window._bmEvmAddress = evmAddress; @@ -833,7 +833,7 @@ mergeInto(LibraryManager.library, { } var xchain = window._bmXChain; - var signTransaction = xchain.signTransaction || xchain.default?.signTransaction; + var signTransaction = xchain.signTransaction || (xchain.default && xchain.default.signTransaction); if (!signTransaction) { SendMessage(gameObjectName, errorCb, 'xChain SDK: signTransaction function not found.'); return; @@ -928,7 +928,7 @@ mergeInto(LibraryManager.library, { return loadXChainSDK(); }) .then(function(xchain) { - var deriveAddress = xchain.deriveAddress || xchain.getAlgorandAddress || xchain.default?.deriveAddress; + var deriveAddress = xchain.deriveAddress || xchain.getAlgorandAddress || (xchain.default && xchain.default.deriveAddress); if (!deriveAddress) throw new Error('xChain SDK: address derivation function not found.'); var algoAddr = deriveAddress(window._bmEvmAddress); window._bmXChainAlgoAddr = algoAddr; From 74032f77903a0d68524b5d0b4a6344a370079399 Mon Sep 17 00:00:00 2001 From: Blockmaker <202785564+blockmaker-ai@users.noreply.github.com> Date: Tue, 7 Jul 2026 10:11:27 +0100 Subject: [PATCH 2/2] Key stripper: stash to Library file, not SessionState MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SessionState dies with the editor session — a failed/cancelled batchmode build exits before OnPostprocessBuild, losing the stash and permanently blanking every BlockmakerConfig apiKey. A Library/ file survives editor restarts, so the InitializeOnLoadMethod safety net can actually restore. Co-Authored-By: Claude Fable 5 --- Editor/BlockmakerBuildKeyStripper.cs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/Editor/BlockmakerBuildKeyStripper.cs b/Editor/BlockmakerBuildKeyStripper.cs index ab5d337..9879ff1 100644 --- a/Editor/BlockmakerBuildKeyStripper.cs +++ b/Editor/BlockmakerBuildKeyStripper.cs @@ -20,9 +20,13 @@ public class BlockmakerBuildKeyStripper : IPreprocessBuildWithReport, IPostproce { public int callbackOrder => 0; - // Distinct from any game-local stripper so the two can coexist safely - // (each captures/restores only its own SessionState). - private const string StateKey = "blockmaker.sdk.strippedApiKeys"; + // Stash lives in Library/ (gitignored, survives editor restarts) rather + // than SessionState: a failed or cancelled batchmode build exits the + // editor session, and a SessionState stash would be lost — permanently + // blanking every config's key. Distinct file from any game-local + // stripper so the two coexist safely. + private static string StashPath => System.IO.Path.Combine( + System.IO.Path.GetDirectoryName(Application.dataPath), "Library", "blockmaker-stripped-keys.json"); [System.Serializable] private class Entry { public string path; public string key; } [System.Serializable] private class Entries { public List items = new List(); } @@ -43,13 +47,10 @@ public void OnPreprocessBuild(BuildReport report) if (saved.items.Count > 0) { AssetDatabase.SaveAssets(); - SessionState.SetString(StateKey, JsonUtility.ToJson(saved)); + System.IO.File.WriteAllText(StashPath, JsonUtility.ToJson(saved)); Debug.LogWarning($"[Blockmaker] Stripped the dev apiKey from {saved.items.Count} BlockmakerConfig(s) for this build — it will not ship. Restored automatically after the build."); } - else - { - SessionState.EraseString(StateKey); - } + } public void OnPostprocessBuild(BuildReport report) => RestoreKeys(); @@ -64,7 +65,8 @@ [InitializeOnLoadMethod] private static void RestoreOnLoad() private static void RestoreKeys() { - var json = SessionState.GetString(StateKey, ""); + if (!System.IO.File.Exists(StashPath)) return; + var json = System.IO.File.ReadAllText(StashPath); if (string.IsNullOrEmpty(json)) return; var saved = JsonUtility.FromJson(json); @@ -81,7 +83,7 @@ private static void RestoreKeys() } AssetDatabase.SaveAssets(); } - SessionState.EraseString(StateKey); + System.IO.File.Delete(StashPath); } } }