Skip to content

Commit

Permalink
Merge pull request #30 from ovnanova/cid
Browse files Browse the repository at this point in the history
working Multicodec + CID!!
  • Loading branch information
mekaem authored Feb 27, 2024
2 parents bd26b6a + 21f57cd commit 23c9e86
Show file tree
Hide file tree
Showing 6 changed files with 879 additions and 5 deletions.
3 changes: 2 additions & 1 deletion config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ config :hexpds,
plc_server: "plc.bsky-sandbox.dev",
appview_server: "api.bsky-sandbox.dev",
relay_server: "bgs.bsky-sandbox.dev",
pds_host: "pds.shreyanjain.net" # ignore pls for now
pds_host: "abyss.computer", # ignore pls for now
multicodec_csv_path: "multicodec.csv"
2 changes: 1 addition & 1 deletion lib/hexpds/k256.ex
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ defmodule Hexpds.K256 do
(pubkey
|> compress()
|> Base.decode16!(case: :lower)
|> Hexpds.Multicodec.encode(:"secp256k1-pub")
|> Hexpds.Multicodec.encode!(:"secp256k1-pub")
|> Multibase.encode!(:base58_btc))
end
end
Expand Down
77 changes: 74 additions & 3 deletions lib/hexpds/multicodec.ex
Original file line number Diff line number Diff line change
@@ -1,6 +1,77 @@
defmodule Hexpds.Multicodec do
@spec encode(binary(), :"secp256k1-pub") :: binary()
def encode(pubkey, :"secp256k1-pub") do
<<0xE7, 0x01, pubkey::binary>>
use GenServer

def start_link(multicodec_csv \\ Application.get_env(:hexpds, :multicodec_csv_path)) do
GenServer.start_link(__MODULE__, multicodec_csv, name: __MODULE__)
end

@impl GenServer
def init(csv_path) do
{:ok, csv} = File.read(csv_path)
{:ok, read_csv(csv)}
end

@impl GenServer
def handle_call(:multicodec_map, _from, state) do
{:reply, state, state}
end

def read_csv(csv) do
csv
|> String.split("\n", trim: true)
|> Stream.map(&String.replace(&1, " ", ""))
|> Stream.map(&String.split(&1, ",", trim: true))
|> Enum.reduce(%{}, fn [name, _tag, "0x" <> code, _status], acc ->
Map.put(acc, String.to_atom(name), Integer.parse(code, 16) |> elem(0))
end)
end

def multicodec_map() do
GenServer.call(__MODULE__, :multicodec_map)
end

def bytes_to_codec() do
for {codec, bytes} <- multicodec_map(), into: %{} do
{bytes, codec}
end
end

def encode!(bytes, "" <> codec) do
<<Varint.LEB128.encode(multicodec_map()[String.to_atom(codec)])::binary, bytes::binary>>
end

def encode!(bytes, codec) do
encode!(bytes, to_string(codec))
end

@spec encode(binary(), String.t() | atom()) ::
{:error, any()} | {:ok, binary()}
def encode(b, c) do
try do
{:ok, encode!(b, c)}
catch
_, e -> {:error, e}
end
end

def codec_decode("" <> encoded) do
try do
with {prefix, rest} <- Varint.LEB128.decode(<<encoded::binary>>),
codec <- bytes_to_codec()[prefix],
do: {:ok, {rest, to_string(codec)}}
catch
_, e -> {:error, e}
end
end

@spec codec?(binary()) :: boolean()
def codec?("" <> codec) do
Map.has_key?(multicodec_map(), String.to_atom(codec))
end

def codecs do
multicodec_map()
|> Map.keys()
|> Enum.map(&to_string/1)
end
end
Loading

0 comments on commit 23c9e86

Please sign in to comment.