-
Notifications
You must be signed in to change notification settings - Fork 100
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support NEP-11 in RpcClient #739
Labels
Comments
Tokens/TokensOf should return IAsyncEnumerable. Possible implementation (as extension methods): public static IAsyncEnumerable<ByteString> TokensOfAsync(this RpcClient rpcClient, UInt160 scriptHash, UInt160 owner)
{
const string METHOD = "tokensOf";
var script = Neo.VM.Helper.MakeScript(scriptHash, "tokensOf", owner);
return rpcClient.ParseTokenResults(script, METHOD);
}
public static IAsyncEnumerable<ByteString> TokensAsync(this RpcClient rpcClient, UInt160 scriptHash)
{
const string METHOD = "tokens";
var script = Neo.VM.Helper.MakeScript(scriptHash, METHOD);
return rpcClient.ParseTokenResults(script, METHOD);
}
static async IAsyncEnumerable<ByteString> ParseTokenResults(this RpcClient rpcClient, byte[] script, string method = null)
{
method ??= "InvokeScript";
var result = await rpcClient.InvokeScriptAsync(script).ConfigureAwait(false);
if (result.State != Neo.VM.VMState.HALT)
{
var message = string.IsNullOrEmpty(result.Exception) ? $"{method} returned {result.State}" : result.Exception;
throw new Exception(message);
}
if (!string.IsNullOrEmpty(result.Session)
&& result.Stack.Length > 0
&& TryGetIteratorId(result.Stack[0], out var iteratorId))
{
await foreach (var json in rpcClient.TraverseIteratorAsync(result.Session, iteratorId))
{
yield return (ByteString)StackItemFromJson(json);
}
}
throw new Exception($"{method} returned unexpected results");
static bool TryGetIteratorId(Neo.VM.Types.StackItem item, out string iteratorId)
{
if (item is Neo.VM.Types.InteropInterface interop)
{
var @object = interop.GetInterface<object>();
if (@object is JObject json)
{
iteratorId = json["id"]?.AsString() ?? "";
if (json["interface"]?.AsString() == "IIterator"
&& !string.IsNullOrEmpty(iteratorId))
{
return true;
}
}
}
iteratorId = string.Empty;
return false;
}
} |
And a possible implementation of PropertiesAsync public static async Task<IReadOnlyDictionary<string, StackItem>> PropertiesAsync(this RpcClient rpcClient, UInt160 scriptHash, ByteString tokenId)
{
const string METHOD = "properties";
var script = Neo.VM.Helper.MakeScript(scriptHash, METHOD, tokenId.GetSpan().ToArray());
var result = await rpcClient.InvokeScriptAsync(script);
if (result.State != Neo.VM.VMState.HALT)
{
var message = string.IsNullOrEmpty(result.Exception) ? $"{METHOD} returned {result.State}" : result.Exception;
throw new Exception(message);
}
if (result.Stack.Length > 0
&& result.Stack[0] is Neo.VM.Types.Map map)
{
return map.ToDictionary(kvp => kvp.Key.GetString(), kvp => kvp.Value);
}
throw new Exception($"{METHOD} returned unexpected results");
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Support NEP-11 in RpcClient
e.g.
Nep17API
The text was updated successfully, but these errors were encountered: