diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0c7d2b1..1264b21 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -96,7 +96,7 @@ jobs:
platform: linux_amd64
env:
- TEST_VERSION: '0.0.1'
+ TEST_VERSION: '0.0.2'
TEST_REPO: 'stringintech/kernel-bindings-tests'
TEST_DIR: '.conformance-tests'
diff --git a/tools/kernel-bindings-test-handler/Handlers/ScriptVerifyHandler.cs b/tools/kernel-bindings-test-handler/Handlers/ScriptVerifyHandler.cs
index e55a479..7e0c29f 100644
--- a/tools/kernel-bindings-test-handler/Handlers/ScriptVerifyHandler.cs
+++ b/tools/kernel-bindings-test-handler/Handlers/ScriptVerifyHandler.cs
@@ -22,7 +22,7 @@ public ScriptVerifyHandler(KernelContext context)
///
/// Handles a script verification request.
///
- public Response Handle(string requestId, ScriptVerifyParams parameters)
+ public Response Handle(string requestId, BtckScriptPubkeyVerifyParams parameters)
{
try
{
@@ -37,7 +37,7 @@ public Response Handle(string requestId, ScriptVerifyParams parameters)
foreach (var output in parameters.SpentOutputs)
{
var outputScriptPubKey = ScriptPubKey.FromHex(output.ScriptPubKeyHex);
- spentOutputs.Add(new TxOut(outputScriptPubKey, output.Amount));
+ spentOutputs.Add(new TxOut(outputScriptPubKey, output.Value));
}
}
@@ -58,7 +58,7 @@ public Response Handle(string requestId, ScriptVerifyParams parameters)
return new Response
{
Id = requestId,
- Success = new { }
+ Result = true
};
}
catch (ArgumentOutOfRangeException ex) when (ex.ParamName == "inputIndex")
@@ -66,45 +66,41 @@ public Response Handle(string requestId, ScriptVerifyParams parameters)
return new Response
{
Id = requestId,
+ Result = null,
Error = new ErrorResponse
{
- Type = "ScriptVerify",
- Variant = "TxInputIndex"
+ Code = new ErrorCode
+ {
+ Type = "btck_ScriptVerifyStatus",
+ Member = "TxInputIndex"
+ }
}
};
}
catch (ScriptVerificationException ex)
{
- return new Response
+ // If status is OK, the script just failed verification (result: false)
+ // If status is not OK, it's an actual error condition
+ if (ex.Status == ScriptVerifyStatus.OK)
{
- Id = requestId,
- Error = new ErrorResponse
+ return new Response
{
- Type = "ScriptVerify",
- Variant = MapScriptVerifyStatus(ex.Status)
- }
- };
- }
- catch (Exception
-#if DEBUG
- ex
-#endif
- )
- {
- // Log to stderr for debugging (can be disabled in production)
-#if DEBUG
- Console.Error.WriteLine($"Exception: {ex.GetType().Name}: {ex.Message}");
- Console.Error.WriteLine($"StackTrace: {ex.StackTrace}");
-#endif
+ Id = requestId,
+ Result = false
+ };
+ }
- // Generic error for unexpected exceptions
return new Response
{
Id = requestId,
+ Result = null,
Error = new ErrorResponse
{
- Type = "ScriptVerify",
- Variant = "Invalid"
+ Code = new ErrorCode
+ {
+ Type = "btck_ScriptVerifyStatus",
+ Member = MapScriptVerifyStatus(ex.Status)
+ }
}
};
}
@@ -132,9 +128,18 @@ private ScriptVerificationFlags ParseFlags(object? flags)
{
return (ScriptVerificationFlags)jsonElement.GetUInt32();
}
- else if (jsonElement.ValueKind == System.Text.Json.JsonValueKind.String)
+ else if (jsonElement.ValueKind == System.Text.Json.JsonValueKind.Array)
{
- return ParseFlagString(jsonElement.GetString() ?? string.Empty);
+ // Handle array of string flags - combine them with OR
+ ScriptVerificationFlags combinedFlags = ScriptVerificationFlags.None;
+ foreach (var element in jsonElement.EnumerateArray())
+ {
+ if (element.ValueKind == System.Text.Json.JsonValueKind.String)
+ {
+ combinedFlags |= ParseFlagString(element.GetString() ?? string.Empty);
+ }
+ }
+ return combinedFlags;
}
}
@@ -152,18 +157,24 @@ private ScriptVerificationFlags ParseFlags(object? flags)
///
private ScriptVerificationFlags ParseFlagString(string flagStr)
{
+ // Handle btck_ prefixed format (e.g., "btck_ScriptVerificationFlags_WITNESS")
+ if (flagStr.StartsWith("btck_ScriptVerificationFlags_", StringComparison.OrdinalIgnoreCase))
+ {
+ flagStr = flagStr.Substring("btck_ScriptVerificationFlags_".Length);
+ }
+
return flagStr.ToUpperInvariant() switch
{
- "VERIFY_NONE" or "NONE" => ScriptVerificationFlags.None,
- "VERIFY_P2SH" or "P2SH" => ScriptVerificationFlags.P2SH,
- "VERIFY_DERSIG" or "DERSIG" => ScriptVerificationFlags.DerSig,
- "VERIFY_NULLDUMMY" or "NULLDUMMY" => ScriptVerificationFlags.NullDummy,
- "VERIFY_CHECKLOCKTIMEVERIFY" or "CHECKLOCKTIMEVERIFY" => ScriptVerificationFlags.CheckLockTimeVerify,
- "VERIFY_CHECKSEQUENCEVERIFY" or "CHECKSEQUENCEVERIFY" => ScriptVerificationFlags.CheckSequenceVerify,
- "VERIFY_WITNESS" or "WITNESS" => ScriptVerificationFlags.Witness,
- "VERIFY_TAPROOT" or "TAPROOT" => ScriptVerificationFlags.Taproot,
- "VERIFY_ALL" or "ALL" => ScriptVerificationFlags.All,
- "VERIFY_ALL_PRE_TAPROOT" or "ALL_PRE_TAPROOT" => ScriptVerificationFlags.AllPreTaproot,
+ "NONE" => ScriptVerificationFlags.None,
+ "P2SH" => ScriptVerificationFlags.P2SH,
+ "DERSIG" => ScriptVerificationFlags.DerSig,
+ "NULLDUMMY" => ScriptVerificationFlags.NullDummy,
+ "CHECKLOCKTIMEVERIFY" => ScriptVerificationFlags.CheckLockTimeVerify,
+ "CHECKSEQUENCEVERIFY" => ScriptVerificationFlags.CheckSequenceVerify,
+ "WITNESS" => ScriptVerificationFlags.Witness,
+ "TAPROOT" => ScriptVerificationFlags.Taproot,
+ "ALL" => ScriptVerificationFlags.All,
+ "ALL_PRE_TAPROOT" => ScriptVerificationFlags.AllPreTaproot,
_ => throw new ArgumentException($"Unknown flag: {flagStr}")
};
}
@@ -175,12 +186,9 @@ private string MapScriptVerifyStatus(ScriptVerifyStatus status)
{
return status switch
{
- ScriptVerifyStatus.ERROR_TX_INPUT_INDEX => "TxInputIndex",
- ScriptVerifyStatus.ERROR_INVALID_FLAGS => "InvalidFlags",
- ScriptVerifyStatus.ERROR_INVALID_FLAGS_COMBINATION => "InvalidFlagsCombination",
- ScriptVerifyStatus.ERROR_SPENT_OUTPUTS_MISMATCH => "SpentOutputsMismatch",
- ScriptVerifyStatus.ERROR_SPENT_OUTPUTS_REQUIRED => "SpentOutputsRequired",
- _ => "Invalid"
+ ScriptVerifyStatus.ERROR_INVALID_FLAGS_COMBINATION => "ERROR_INVALID_FLAGS_COMBINATION",
+ ScriptVerifyStatus.ERROR_SPENT_OUTPUTS_REQUIRED => "ERROR_SPENT_OUTPUTS_REQUIRED",
+ _ => "ERROR_INVALID"
};
}
}
diff --git a/tools/kernel-bindings-test-handler/Program.cs b/tools/kernel-bindings-test-handler/Program.cs
index ccd89e1..8c4d7ae 100644
--- a/tools/kernel-bindings-test-handler/Program.cs
+++ b/tools/kernel-bindings-test-handler/Program.cs
@@ -46,7 +46,10 @@ static async Task Main(string[] args)
Id = "unknown",
Error = new ErrorResponse
{
- Type = "InvalidRequest"
+ Code = new ErrorCode
+ {
+ Type = "InvalidRequest"
+ }
}
};
}
@@ -62,7 +65,10 @@ static async Task Main(string[] args)
Id = "unknown",
Error = new ErrorResponse
{
- Type = "InvalidRequest"
+ Code = new ErrorCode
+ {
+ Type = "InvalidRequest"
+ }
}
};
}
@@ -91,7 +97,7 @@ private static Response HandleRequest(Request request, ScriptVerifyHandler scrip
{
switch (request.Method)
{
- case "script_pubkey.verify":
+ case "btck_script_pubkey_verify":
if (request.Params == null)
{
return new Response
@@ -99,26 +105,32 @@ private static Response HandleRequest(Request request, ScriptVerifyHandler scrip
Id = request.Id,
Error = new ErrorResponse
{
- Type = "InvalidParams"
+ Code = new ErrorCode
+ {
+ Type = "InvalidParams"
+ }
}
};
}
- var scriptVerifyParams = JsonSerializer.Deserialize(request.Params.Value, jsonOptions);
+ var btckScriptPubkeyVerifyParams = JsonSerializer.Deserialize(request.Params.Value, jsonOptions);
- if (scriptVerifyParams == null)
+ if (btckScriptPubkeyVerifyParams == null)
{
return new Response
{
Id = request.Id,
Error = new ErrorResponse
{
- Type = "InvalidParams"
+ Code = new ErrorCode
+ {
+ Type = "InvalidParams"
+ }
}
};
}
- return scriptVerifyHandler.Handle(request.Id, scriptVerifyParams);
+ return scriptVerifyHandler.Handle(request.Id, btckScriptPubkeyVerifyParams);
default:
return new Response
@@ -126,7 +138,10 @@ private static Response HandleRequest(Request request, ScriptVerifyHandler scrip
Id = request.Id,
Error = new ErrorResponse
{
- Type = "MethodNotFound"
+ Code = new ErrorCode
+ {
+ Type = "MethodNotFound"
+ }
}
};
}
@@ -138,7 +153,10 @@ private static Response HandleRequest(Request request, ScriptVerifyHandler scrip
Id = request.Id,
Error = new ErrorResponse
{
- Type = "InternalError"
+ Code = new ErrorCode
+ {
+ Type = "InternalError"
+ }
}
};
}
diff --git a/tools/kernel-bindings-test-handler/Protocol/Request.cs b/tools/kernel-bindings-test-handler/Protocol/Request.cs
index 0d75185..79f9cd8 100644
--- a/tools/kernel-bindings-test-handler/Protocol/Request.cs
+++ b/tools/kernel-bindings-test-handler/Protocol/Request.cs
@@ -19,17 +19,17 @@ public class Request
}
///
-/// Parameters for script_pubkey.verify method.
+/// Parameters for btck_script_pubkey_verify method.
///
-public class ScriptVerifyParams
+public class BtckScriptPubkeyVerifyParams
{
- [JsonPropertyName("script_pubkey_hex")]
+ [JsonPropertyName("script_pubkey")]
public string ScriptPubKeyHex { get; set; } = string.Empty;
[JsonPropertyName("amount")]
public long Amount { get; set; }
- [JsonPropertyName("tx_hex")]
+ [JsonPropertyName("tx_to")]
public string TxHex { get; set; } = string.Empty;
[JsonPropertyName("input_index")]
@@ -39,7 +39,7 @@ public class ScriptVerifyParams
public List? SpentOutputs { get; set; }
[JsonPropertyName("flags")]
- public object? Flags { get; set; } // Can be uint or string
+ public JsonElement? Flags { get; set; } // Can be uint, or array
}
///
@@ -47,9 +47,9 @@ public class ScriptVerifyParams
///
public class SpentOutput
{
- [JsonPropertyName("script_pubkey_hex")]
+ [JsonPropertyName("script_pubkey")]
public string ScriptPubKeyHex { get; set; } = string.Empty;
[JsonPropertyName("amount")]
- public long Amount { get; set; }
+ public long Value { get; set; }
}
diff --git a/tools/kernel-bindings-test-handler/Protocol/Response.cs b/tools/kernel-bindings-test-handler/Protocol/Response.cs
index 1c49f2a..e75f655 100644
--- a/tools/kernel-bindings-test-handler/Protocol/Response.cs
+++ b/tools/kernel-bindings-test-handler/Protocol/Response.cs
@@ -10,9 +10,9 @@ public class Response
[JsonPropertyName("id")]
public string Id { get; set; } = string.Empty;
- [JsonPropertyName("success")]
+ [JsonPropertyName("result")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
- public object? Success { get; set; }
+ public object? Result { get; set; }
[JsonPropertyName("error")]
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
@@ -23,11 +23,19 @@ public class Response
/// Represents an error response.
///
public class ErrorResponse
+{
+ [JsonPropertyName("code")]
+ public ErrorCode Code { get; set; } = new();
+}
+
+///
+/// Represents an error code with type and member information.
+///
+public class ErrorCode
{
[JsonPropertyName("type")]
public string Type { get; set; } = string.Empty;
- [JsonPropertyName("variant")]
- [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
- public string? Variant { get; set; }
+ [JsonPropertyName("member")]
+ public string Member { get; set; } = string.Empty;
}