Skip to content

Commit

Permalink
keysets, keys and check state methods
Browse files Browse the repository at this point in the history
  • Loading branch information
StringNick committed Sep 8, 2024
1 parent 3f3a9c2 commit f1c6504
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 3 deletions.
2 changes: 1 addition & 1 deletion src/core/database/mint_memory.zig
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ pub const MintMemoryDatabase = struct {
}

// caller must free result
pub fn getProofsStates(self: *Self, allocator: std.mem.Allocator, ys: []secp256k1.PublicKey) !std.ArrayList(?nuts.nut07.State) {
pub fn getProofsStates(self: *Self, allocator: std.mem.Allocator, ys: []const secp256k1.PublicKey) !std.ArrayList(?nuts.nut07.State) {
self.lock.lockShared();
defer self.lock.unlockShared();

Expand Down
48 changes: 48 additions & 0 deletions src/core/mint/mint.zig
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,54 @@ pub const Mint = struct {
defer self.keysets.lock.unlock();
try self.keysets.value.put(id, keyset);
}

/// Check state
pub fn checkState(
self: *Mint,
allocator: std.mem.Allocator,
check_state: core.nuts.nut07.CheckStateRequest,
) !core.nuts.nut07.CheckStateResponse {
const _states = try self.localstore.value.getProofsStates(allocator, check_state.ys);
defer _states.deinit();

var states = try std.ArrayList(core.nuts.nut07.ProofState).initCapacity(allocator, _states.items.len);
errdefer {
for (states.items) |s| s.deinit(allocator);
states.deinit();
}

const min_length = @min(_states.items.len, check_state.ys.len);

for (check_state.ys[0..min_length], _states.items[0..min_length]) |y, s| {
const state: core.nuts.nut07.State = s orelse .unspent;

states.appendAssumeCapacity(.{
.y = y,
.state = state,
.witness = null,
});
}

return .{ .states = try states.toOwnedSlice() };
}

/// Retrieve the public keys of the active keyset for distribution to wallet clients
pub fn keysetPubkeys(self: *Mint, allocator: std.mem.Allocator, keyset_id: nuts.Id) !nuts.KeysResponse {
try self.ensureKeysetLoaded(keyset_id);
self.keysets.lock.lock();
defer self.keysets.lock.unlock();

const keyset = self.keysets.value.get(keyset_id) orelse return error.UnknownKeySet;

const keysets = try allocator.alloc(nuts.KeySet, 1);
errdefer allocator.free(keysets);

keysets[0] = try keyset.toKeySet(allocator);

return .{
.keysets = keysets,
};
}
};

/// Generate new [`MintKeySetInfo`] from path
Expand Down
4 changes: 2 additions & 2 deletions src/core/nuts/nut02/nut02.zig
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,11 @@ pub const MintKeySet = struct {
self.keys.deinit();
}

pub fn toKeySet(self: MintKeySet, arena: std.mem.Allocator) !KeySet {
pub fn toKeySet(self: MintKeySet, allocator: std.mem.Allocator) !KeySet {
return .{
.id = self.id,
.unit = self.unit,
.keys = try Keys.fromMintKeys(arena, self.keys),
.keys = try Keys.fromMintKeys(allocator, self.keys),
};
}

Expand Down
4 changes: 4 additions & 0 deletions src/core/nuts/nut07/nut07.zig
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ pub const ProofState = struct {
},
),
);

pub fn deinit(self: ProofState, allocator: std.mem.Allocator) void {
if (self.witness) |witness| allocator.free(witness);
}
};

/// Check Spendable Response [NUT-07]
Expand Down
4 changes: 4 additions & 0 deletions src/router/router.zig
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ const core = @import("../core/lib.zig");
const httpz = @import("httpz");
const std = @import("std");
const router_handlers = @import("router_handlers.zig");
const zul = @import("zul");

const Mint = core.mint.Mint;
const CurrencyUnit = core.nuts.CurrencyUnit;
Expand Down Expand Up @@ -32,6 +33,9 @@ pub fn createMintServer(
var router = srv.router(.{});

router.get("/v1/keys", router_handlers.getKeys, .{});
router.get("/v1/keysets", router_handlers.getKeysets, .{});
router.get("/v1/keys/:keyset_id", router_handlers.getKeysetPubkeys, .{});
router.post("/v1/checkstate", router_handlers.postCheck, .{});

return srv;
}
Expand Down
30 changes: 30 additions & 0 deletions src/router/router_handlers.zig
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
const std = @import("std");
const httpz = @import("httpz");
const core = @import("../core/lib.zig");

const MintState = @import("router.zig").MintState;

Expand All @@ -8,3 +9,32 @@ pub fn getKeys(state: MintState, req: *httpz.Request, res: *httpz.Response) !voi

return try res.json(pubkeys, .{});
}

pub fn getKeysets(state: MintState, req: *httpz.Request, res: *httpz.Response) !void {
const keysets = try state.mint.getKeysets(req.arena);

return try res.json(keysets, .{});
}

pub fn getKeysetPubkeys(
state: MintState,
req: *httpz.Request,
res: *httpz.Response,
) !void {
const ks_id = try core.nuts.Id.fromStr(req.param("keyset_id") orelse return error.ExpectKeysetId);
const pubkeys = try state.mint.keysetPubkeys(req.arena, ks_id);

return try res.json(pubkeys, .{});
}

pub fn postCheck(
state: MintState,
req: *httpz.Request,
res: *httpz.Response,
) !void {
if (try req.json(core.nuts.nut07.CheckStateRequest)) |r| {
return try res.json(try state.mint.checkState(res.arena, r), .{});
}

return error.ExpectedBody;
}

0 comments on commit f1c6504

Please sign in to comment.