Skip to content

Commit 96ebd3f

Browse files
committed
controller call & interop
1 parent 1b29fec commit 96ebd3f

File tree

2 files changed

+149
-4
lines changed

2 files changed

+149
-4
lines changed

Assets/Dojo/Runtime/Controller.cs

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,29 @@ public dojo.Policy ToNative()
2929
}
3030
}
3131

32+
[Serializable]
33+
public struct ControllerCall {
34+
public FieldElement contractAddress;
35+
public string entrypoint;
36+
public FieldElement[] calldata;
37+
38+
public ControllerCall(FieldElement contractAddress, string entrypoint, FieldElement[] calldata)
39+
{
40+
this.contractAddress = contractAddress;
41+
this.entrypoint = entrypoint;
42+
this.calldata = calldata;
43+
}
44+
45+
public dojo.Call ToNative()
46+
{
47+
return new dojo.Call {
48+
to = contractAddress.Inner,
49+
selector = entrypoint,
50+
calldata = calldata.Select(c => c.Inner).ToArray()
51+
};
52+
}
53+
}
54+
3255
public unsafe class Controller
3356
{
3457
private dojo.ControllerAccount* controller;
@@ -113,10 +136,11 @@ public static bool Clear(Policy[] policies, FieldElement chainId)
113136
return result.ok;
114137
}
115138

116-
public FieldElement ExecuteRaw(dojo.Call[] calls)
139+
public FieldElement ExecuteRaw(ControllerCall[] calls)
117140
{
141+
var nativeCalls = calls.Select(c => c.ToNative()).ToArray();
118142
dojo.Call* callsPtr;
119-
fixed (dojo.Call* ptr = &calls[0])
143+
fixed (dojo.Call* ptr = &nativeCalls[0])
120144
{
121145
callsPtr = ptr;
122146
}
@@ -130,10 +154,11 @@ public FieldElement ExecuteRaw(dojo.Call[] calls)
130154
return new FieldElement(result.ok);
131155
}
132156

133-
public FieldElement ExecuteFromOutside(dojo.Call[] calls)
157+
public FieldElement ExecuteFromOutside(ControllerCall[] calls)
134158
{
159+
var nativeCalls = calls.Select(c => c.ToNative()).ToArray();
135160
dojo.Call* callsPtr;
136-
fixed (dojo.Call* ptr = &calls[0])
161+
fixed (dojo.Call* ptr = &nativeCalls[0])
137162
{
138163
callsPtr = ptr;
139164
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#if UNITY_WEBGL && !UNITY_EDITOR
2+
3+
using System;
4+
using System.Threading.Tasks;
5+
using System.Runtime.InteropServices;
6+
using AOT;
7+
using bottlenoselabs.C2CS.Runtime;
8+
using Newtonsoft.Json;
9+
using UnityEngine;
10+
using System.Linq;
11+
12+
namespace Dojo
13+
{
14+
public static class ControllerInterop
15+
{
16+
[DllImport("__Internal")]
17+
private static extern void NewController(CString rpcUrl, CString chainId, CString policies);
18+
19+
[DllImport("__Internal")]
20+
private static extern void Probe(Action<bool> cb);
21+
22+
private static class ProbeHelper
23+
{
24+
public static TaskCompletionSource<bool> Tcs;
25+
26+
[MonoPInvokeCallback(typeof(Action<bool>))]
27+
public static void Callback(bool result)
28+
{
29+
Tcs.SetResult(result);
30+
}
31+
}
32+
33+
public static Task<bool> Probe()
34+
{
35+
ProbeHelper.Tcs = new TaskCompletionSource<bool>();
36+
Probe(ProbeHelper.Callback);
37+
return ProbeHelper.Tcs.Task;
38+
}
39+
40+
41+
[DllImport("__Internal")]
42+
private static extern void Connect(Action<bool> cb);
43+
44+
private static class ConnectHelper
45+
{
46+
public static TaskCompletionSource<bool> Tcs;
47+
48+
[MonoPInvokeCallback(typeof(Action<bool>))]
49+
public static void Callback(bool result)
50+
{
51+
Tcs.SetResult(result);
52+
}
53+
}
54+
55+
public static Task<bool> Connect()
56+
{
57+
ConnectHelper.Tcs = new TaskCompletionSource<bool>();
58+
Connect(ConnectHelper.Callback);
59+
return ConnectHelper.Tcs.Task;
60+
}
61+
62+
63+
[DllImport("__Internal")]
64+
private static extern void Disconnect(Action cb);
65+
66+
private static class DisconnectHelper
67+
{
68+
public static TaskCompletionSource<bool> Tcs; // Using bool to signal completion
69+
70+
[MonoPInvokeCallback(typeof(Action))]
71+
public static void Callback()
72+
{
73+
Tcs.SetResult(true); // Signal completion
74+
}
75+
}
76+
77+
public static Task Disconnect()
78+
{
79+
DisconnectHelper.Tcs = new TaskCompletionSource<bool>();
80+
Disconnect(DisconnectHelper.Callback);
81+
return DisconnectHelper.Tcs.Task;
82+
}
83+
84+
85+
[DllImport("__Internal")]
86+
private static extern void Execute(Action<string> cb, CString calls);
87+
88+
private static class ExecuteHelper
89+
{
90+
public static TaskCompletionSource<string> Tcs;
91+
92+
[MonoPInvokeCallback(typeof(Action<string>))]
93+
public static void Callback(string result)
94+
{
95+
// The result is the transaction hash from the JS side
96+
Tcs.SetResult(result);
97+
}
98+
}
99+
100+
101+
// Takes ControllerCall structs, serializes them into the expected JSON format
102+
public static Task<string> Execute(ControllerCall[] calls)
103+
{
104+
ExecuteHelper.Tcs = new TaskCompletionSource<string>();
105+
var serializedCalls = calls.Select(call => new SerializedCall(
106+
new FieldElement(call.to),
107+
call.selector,
108+
// Ensure dojo.FieldElement can be converted to Dojo.Starknet.FieldElement if they differ
109+
// Assuming direct conversion or access to underlying data works:
110+
call.calldata.ToArray().Select(f => new FieldElement(f)).ToArray()
111+
)).ToArray();
112+
113+
var jsonCalls = JsonConvert.SerializeObject(serializedCalls);
114+
Execute(ExecuteHelper.Callback, new CString(jsonCalls));
115+
return ExecuteHelper.Tcs.Task;
116+
}
117+
}
118+
}
119+
120+
#endif // UNITY_WEBGL && !UNITY_EDITOR

0 commit comments

Comments
 (0)