Ethereum Unity3D Boilerplate Questions

Hi. Current stable version of Unity is 2020.3.27. However I will pull the version you indicated and give it a try. It may be a few hours before I get back on this …

I was able to get this to run out of the box on 2021.2.5f (after setting the Server Url and Application ID).

Did you remember the follow the new step to set ‘Unsafe code allowed’? This is required for Nethereum.
image

thank you for your super fast reply and confirmation.

1 Like

Hi @dgoodrich

I’m able to successfully run code in unity editor but when I try to make a WebGL build for deployment, I’m getting the above errors. I’m using Mac and Visual Studio 2019 for Mac external tool in unity 2021.2.5f.

I can make a WebGL build in 2020.3.27 successfully.

1 Like

What errors are you seeing with 2021.2.5? The same as in your previous message?

When you reported it I was able to import and run the demo with no errors, but it was on Windows. I will try with 2021.2.5f on Mac.

I have attached a screenshot again same as my previous message. Thank you for testing on Mac.

1 Like

I spent several hours on this and am not close to a solution. I did some online research and found a lot of reports of the same issue. I tried several of the suggestions but have not found a solution that works yet.

Thank you for checking the problem, really appreciate your effort. I suppose the best option, for now, is to downgrade the unity version to 2020.3.27.

Please update if you find a solution in the future.

1 Like

Just learnt that Node.js dislikes atob and btoa and suggests using the Buffer class instead.

Have you tried using an IReadOnlyCollection<byte>?

1 Like

Is there a way to query the error messages in case a Cloud Function fails for some reason?

1 Like

So while working with v1.0.2, I was able to get everything working smoothly, until this error started appearing:

System.NullReferenceException: Object reference not set to an instance of an object
  at Banzan.UltraCore.Cryptofied.ActivityTracker+<SendActivitySignal>d__1.MoveNext () [0x00017] in D:\dev\Banzan\UltraCore\Runtime\Cryptofied\ActivityTracker.cs:17 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () [0x0000c] in <695d1cc93cca45069c528c15c9fdd749>:0 
  at Cysharp.Threading.Tasks.UniTask+ExceptionResultSource`1[T].GetResult (System.Int16 token) [0x00000] in D:\dev\Banzan\UltraCore\MoralisWeb3ApiSdk\Plugins\UniTask\Runtime\UniTask.Factory.cs:235 
  at Banzan.UltraCore.ActivityTrackerBase+<<Start>g__ActivityClock|13_5>d.MoveNext () [0x00114] in D:\dev\Banzan\UltraCore\Runtime\ActivityTrackerBase.cs:72 
UnityEngine.Debug:LogError (object)
Banzan.UltraCore.ActivityTrackerBase/<<Start>g__ActivityClock|13_5>d:MoveNext () (at D:/dev/Banzan/UltraCore/Runtime/ActivityTrackerBase.cs:84)
Cysharp.Threading.Tasks.CompilerServices.AsyncUniTask`1<Banzan.UltraCore.ActivityTrackerBase/<<Start>g__ActivityClock|13_5>d>:Run () (at D:/dev/Banzan/UltraCore/MoralisWeb3ApiSdk/Plugins/UniTask/Runtime/CompilerServices/StateMachineRunner.cs:189)
Cysharp.Threading.Tasks.AwaiterActions:Continuation (object) (at D:/dev/Banzan/UltraCore/MoralisWeb3ApiSdk/Plugins/UniTask/Runtime/UniTask.cs:21)
Cysharp.Threading.Tasks.UniTaskCompletionSourceCore`1<object>:TrySetResult (object) (at D:/dev/Banzan/UltraCore/MoralisWeb3ApiSdk/Plugins/UniTask/Runtime/UniTaskCompletionSource.cs:139)
Cysharp.Threading.Tasks.UniTask/DelayPromise:MoveNext () (at D:/dev/Banzan/UltraCore/MoralisWeb3ApiSdk/Plugins/UniTask/Runtime/UniTask.Delay.cs:564)
Cysharp.Threading.Tasks.Internal.PlayerLoopRunner:RunCore () (at D:/dev/Banzan/UltraCore/MoralisWeb3ApiSdk/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs:175)
Cysharp.Threading.Tasks.Internal.PlayerLoopRunner:Update () (at D:/dev/Banzan/UltraCore/MoralisWeb3ApiSdk/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs:145)
Cysharp.Threading.Tasks.Internal.PlayerLoopRunner:Run () (at D:/dev/Banzan/UltraCore/MoralisWeb3ApiSdk/Plugins/UniTask/Runtime/Internal/PlayerLoopRunner.cs:104)

Apparently UniTask is encountering some error suddenly. This has never happened before.

The only change was to some top level .asmdef file where I added an entry after UniTask. This error comes from this:

        protected override async UniTask<bool> SendActivitySignal(bool wasActive)
        {
            try
            {
                Debug.Log($"Calling Moralis Cloud Function \"{CfNameSendActivitySignal}\"...");
                return await MoralisInterface.GetClient().Cloud
                    .RunAsync<bool>(CfNameSendActivitySignal, new Dictionary<string, object> { ["signal"] = wasActive })
                    .AsUniTask();
            }
            catch (MoralisFailureException e)
            {
#if UNITY_EDITOR || DEVELOPMENT_BUILD
                Debug.LogError($"Moralis SDK encountered an error: {e}");
#endif
                throw;
            }
        }
{
    "name": "Banzan.UltraCore",
    "rootNamespace": "Banzan.UltraCore",
    "references": [
        "Banzan.Lib.ScenePersistence",
        "UniTask",
        "Banzan.Lib.Utility"
    ],
    "includePlatforms": [],
    "excludePlatforms": [],
    "allowUnsafeCode": false,
    "overrideReferences": false,
    "precompiledReferences": [],
    "autoReferenced": true,
    "defineConstraints": [],
    "versionDefines": [],
    "noEngineReferences": false
}
1 Like

I will open an issue in GitHub to make sure this is tracked.

It will show in your log. You can also trap exceptions and return them in your response.

Is the Cloud Function is throwing an error? Anything in the server log?

No updates on the server log. UniTask doesn’t seem to work, suddenly, so the request is never made.

I just checked and confirmed that even regular System.Task related to the WalletConnectSharp code was throwing a similar error.

EDIT: the problem had to do with Moralis initialisation not getting the required host manifest data.

1 Like

Of course, but the error is already available in the code: https://github.com/ethereum-boilerplate/ethereum-unity-boilerplate/blob/63f04cfe798d086cc54c29bb35cfae44c703ef30/Assets/MoralisWeb3ApiSdk/Moralis/MoralisDotNet/Platform/Services/ClientServices/MoralisCloudFunctionService.cs#L36-L52

1 Like

Okay here’s another issue. I’m trying to use this logic in a new Unity app:

private static async Task<bool> IsLoggedInOnMoralisWorkaround() =>
    await MoralisInterface.GetClient().UserFromSession(MoralisInterface.GetUser().sessionToken) != null;

// Start is called before the first frame update
protected override async void Start()
{
    base.Start();

    walletConnect = GetComponentInChildren<WalletConnect>();

    Application.quitting += Cleanup;

    authPanel.gameObject.SetActive(false);

    await MoralisInterface.Initialize(moralisAppId, moralisServerUri, new HostManifestData
    {
        Identifier = appName,
        Name = appName,
        ShortVersion = buildVersion,
        Version = buildVersion
    });

    if (await IsLoggedInOnMoralisWorkaround())
    {
        Debug.Log(UserIsAlreadyLoggedInToMoralis);
    }
    else
    {
        authPanel.gameObject.SetActive(true);
    }

    async void Cleanup()
    {
        Debug.Log("QUITTING");

        await walletConnect.Session.Disconnect();
        walletConnect.CLearSession();
        await MoralisInterface.LogOutAsync();
    }
}

This works well in another game I’ve built, but somehow in this app it fails with

NullReferenceException: Object reference not set to an instance of an object
Banzan.UltraCore.Cryptofied.MoralisLoginUI+<IsLoggedInOnMoralisWorkaround>d__10.MoveNext () (at D:/dev/Banzan/UltraCore/Runtime/Cryptofied/MoralisLoginUI.cs:49)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Threading.Tasks.Task task) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Threading.Tasks.Task task) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.CompilerServices.TaskAwaiter.ValidateEnd (System.Threading.Tasks.Task task) (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.CompilerServices.TaskAwaiter`1[TResult].GetResult () (at <695d1cc93cca45069c528c15c9fdd749>:0)
Banzan.UltraCore.Cryptofied.MoralisLoginUI+<Start>d__11.MoveNext () (at D:/dev/Banzan/UltraCore/Runtime/Cryptofied/MoralisLoginUI.cs:70)
--- End of stack trace from previous location where exception was thrown ---
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw () (at <695d1cc93cca45069c528c15c9fdd749>:0)
System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) (at <695d1cc93cca45069c528c15c9fdd749>:0)
UnityEngine.UnitySynchronizationContext+WorkRequest.Invoke () (at <d3b66f0ad4e34a55b6ef91ab84878193>:0)
UnityEngine.UnitySynchronizationContext:ExecuteTasks()

I’m unsure why this is happening. Has this been fixed in v1.0.3?

EDIT: It’s stopped working in this game as well. I had a teammate try and run it but he didn’t get the authentication panel, and had this same error pop up. New authentications are suddenly not working.

EDIT 2: I got the panel to appear again by replacing the workaround call with MoralisInterface.IsLoggedIn() but when I try to click the authenticate button and call:

        /// <summary>
        /// Used to start the authentication process and then run the game. If the 
        /// user has a valid Moralis session the user is redirected to the next 
        /// scene.
        /// </summary>
        public async void Authenticate()
        {
            Debug.Log("AUTHENTICATE");

            if (MoralisInterface.IsLoggedIn())
            {
                Debug.Log(UserIsAlreadyLoggedInToMoralis);
            }
            else
            {
                Debug.Log("User is not logged in.");
                await LogInViaMoralisConnectionPage();

                async Task LogInViaMoralisConnectionPage()
                {
                    var user = await MobileLogin.LogIn(moralisServerUri, moralisAppId);

                    authPanel.gameObject.SetActive(user == null);
                }
            }
        }

…the mobile login fails and the user is still set to null.

I dug deep and found that internally the HTTP POST request sent to the server with the required params was encountering a 400 Bad Request error:

StatusCode: 400, ReasonPhrase: 'Bad Request', Version: 1.1, Content: System.Net.Http.StreamContent, Headers:
{
Date: Fri, 04 Feb 2022 10:32:15 GMT
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET,PUT,POST,DELETE,OPTIONS
Access-Control-Allow-Headers: X-Parse-Master-Key, X-Parse-REST-API-Key, X-Parse-Javascript-Key, X-Parse-Application-Id, X-Parse-Client-Version, X-Parse-Session-Token, X-Requested-With, X-Parse-Revocable-Session, X-Parse-Request-Id, Content-Type, Pragma, Cache-Control, X-Parse-Installation-Id
Access-Control-Expose-Headers: X-Parse-Job-Status-Id, X-Parse-Push-Status-Id
ETag: W/"3a-0JTlHXO2pC/ju0QshHRxP75EkI0"
CF-Cache-Status: DYNAMIC
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 6d833be97ed3dca9-MAA
Content-Type: application/json; charset=utf-8
Content-Length: 58
}

I’m also seeing a limitation where I can’t use the same wallet credentials on multiple devices due to differing session tokens.

Server logs:

2022-02-04T07:17:04.566Z - Error: Invalid session token
    at Object.getAuthForSessionToken (/moralis-server/lib/Auth.js:114:11)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
1 Like

I am not sure what you are asking - is this code throwing an error?

This concerns me as I have not encountered any problems with log in. Can you trace the call into the CommandRunner and capture the path, headers, and request?

Does the Authentication always fail? The only thing I can think of is - any chance your server needs to updated?

Thanks,

David

Please explain this a bit further - are you saying you cannot log into the same account from multiple devices?

Please let me know. I will need to confer with some other teams members with that.