Skip to content
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

Release v0.12.0 #216

Merged
merged 11 commits into from
Jan 3, 2023
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 0.12.0 (03.01.2023)

- Removed [List types](https://github.com/kommitters/kadena.ex/issues/169)
- Added [Renovate](https://github.com/renovatebot/renovate) as dependency update tool
- Added [Handling duplicate signers on commands](https://github.com/kommitters/kadena.ex/issues/210)

## 0.11.1 (27.12.2022)

- Hardened GitHub Actions.
Expand Down
105 changes: 51 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ alias Kadena.Cryptography.KeyPair

{:ok,
%Kadena.Types.KeyPair{
clist: %Kadena.Types.OptionalCapsList{clist: nil},
clist: nil,
pub_key: "37e60c00779cacaef1f0a8697387a5945ef3cb82963980db486dc26ec5f424d9",
secret_key: "e53faf1774d30e7cec2878d2e4a617c34045f53f0579eb05e127a7808aac229d"
}}
Expand All @@ -76,7 +76,7 @@ alias Kadena.Cryptography.KeyPair

{:ok,
%Kadena.Types.KeyPair{
clist: %Kadena.Types.OptionalCapsList{clist: nil},
clist: nil,
pub_key: "37e60c00779cacaef1f0a8697387a5945ef3cb82963980db486dc26ec5f424d9",
secret_key: "e53faf1774d30e7cec2878d2e4a617c34045f53f0579eb05e127a7808aac229d"
}}
Expand All @@ -86,33 +86,27 @@ alias Kadena.Cryptography.KeyPair

```elixir
alias Kadena.Cryptography.KeyPair
alias Kadena.Types.CapsList
alias Kadena.Types.Cap

{:ok, keypair} = KeyPair.from_secret_key("e53faf1774d30e7cec2878d2e4a617c34045f53f0579eb05e127a7808aac229d")

clist = Kadena.Types.CapsList.new([
[name: "coin.GAS", args: [keypair.pub_key]]
])
clist = [
Cap.new(name: "coin.GAS", args: [keypair.pub_key])
]

keypair_with_caps = Kadena.Types.KeyPair.add_caps(keypair, clist)

%Kadena.Types.KeyPair{
clist: %Kadena.Types.OptionalCapsList{
clist: %Kadena.Types.CapsList{
caps: [
%Kadena.Types.Cap{
args: %Kadena.Types.PactValuesList{
pact_values: [
%Kadena.Types.PactValue{
literal: "37e60c00779cacaef1f0a8697387a5945ef3cb82963980db486dc26ec5f424d9"
}
]
},
name: "coin.GAS"
clist: [
%Kadena.Types.Cap{
args: [
%Kadena.Types.PactValue{
literal: "37e60c00779cacaef1f0a8697387a5945ef3cb82963980db486dc26ec5f424d9"
}
]
],
name: "coin.GAS"
}
},
],
pub_key: "37e60c00779cacaef1f0a8697387a5945ef3cb82963980db486dc26ec5f424d9",
secret_key: "e53faf1774d30e7cec2878d2e4a617c34045f53f0579eb05e127a7808aac229d"
}
Expand Down Expand Up @@ -299,9 +293,10 @@ alias Kadena.Pact
# set the command attributes
{:ok, raw_keypair} = Cryptography.KeyPair.from_secret_key("99f7e1e8f2f334ae8374aa28bebdb997271a0e0a5e92c80be9609684a3d6f0d4")

caps = Kadena.Types.CapsList.new([
[name: "coin.GAS", args: [raw_keypair.pub_key]]
])
caps = [
Kadena.Types.Cap.new(name: "coin.GAS", args: [raw_keypair.pub_key])
]


keypair = Kadena.Types.KeyPair.add_caps(raw_keypair, caps)

Expand Down Expand Up @@ -333,19 +328,20 @@ env_data = %{accounts_admin_keyset: [keypair.pub_key]}
|> Pact.ExecCommand.add_keypair(keypair)
|> Pact.ExecCommand.build()

{:ok, %Kadena.Types.Command{
cmd: "{\"meta\":{\"chainId\":\"0\",\"creationTime\":1667249173,\"gasLimit\":2500,\"gasPrice\":0.01,\"sender\":\"k:6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"ttl\":28800},\"networkId\":\"testnet04\",\"nonce\":\"2023-01-01 00:00:00.000000 UTC\",\"payload\":{\"exec\":{\"code\":\"(+ 1 2)\",\"data\":{\"accounts-admin-keyset\":[\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\"]}}},\"signers\":[{\"addr\":\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"clist\":[{\"args\":[\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\"],\"name\":\"coin.GAS\"}],\"pubKey\":\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"scheme\":\"ED25519\"}]}",
hash: %Kadena.Types.PactTransactionHash{
hash: "TAGG_ar-gxdeOhyYAJyF4ZtTwV7_3UGHZMUzRB2nVfY"
},
sigs: %Kadena.Types.SignaturesList{
signatures: [
%Kadena.Types.Signature{
sig: "5f4ce544aef7c439d97720c12eb8996f013d966abdf754dc6b0d353196fc962781ed5a9b982d9b7156bcd4bf19c868053c64e7fb1ad5edf695bfbd8a3225e304"
}
]
}
}}
{:ok,
%Kadena.Types.Command{
cmd:
"{\"meta\":{\"chainId\":\"0\",\"creationTime\":1667249173,\"gasLimit\":2500,\"gasPrice\":0.01,\"sender\":\"k:6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"ttl\":28800},\"networkId\":\"testnet04\",\"nonce\":\"2023-01-01 00:00:00.000000 UTC\",\"payload\":{\"exec\":{\"code\":\"(+ 1 2)\",\"data\":{\"accounts_admin_keyset\":[\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\"]}}},\"signers\":[{\"addr\":null,\"clist\":[{\"args\":[\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\"],\"name\":\"coin.GAS\"}],\"pubKey\":\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"scheme\":\"ED25519\"}]}",
hash: %Kadena.Types.PactTransactionHash{
hash: "ZOsqP9Wkfj5NnY9WS_XMnO9KfYv0GvK_8QMPTX6BfaA"
},
sigs: [
%Kadena.Types.Signature{
sig:
"5b0635c2376949103d8ce8243a1fd34a1a8964900d69eebb1ff4d38ffde437a317f887f864fa9c1b27a97e8d9e57eef8dd58b054edf30b4e6fe89d0208290f02"
}
]
}}
```

### Building a Continuation Command
Expand All @@ -357,9 +353,9 @@ alias Kadena.Pact
# set the command attributes
{:ok, raw_keypair} = Cryptography.KeyPair.from_secret_key("99f7e1e8f2f334ae8374aa28bebdb997271a0e0a5e92c80be9609684a3d6f0d4")

caps = Kadena.Types.CapsList.new([
[name: "coin.GAS", args: [raw_keypair.pub_key]]
])
caps = [
Kadena.Types.Cap.new(name: "coin.GAS", args: [raw_keypair.pub_key])
]

keypair = Kadena.Types.KeyPair.add_caps(raw_keypair, caps)

Expand Down Expand Up @@ -397,19 +393,20 @@ rollback = true
|> Pact.ContCommand.set_rollback(rollback)
|> Pact.ContCommand.build()

{:ok, %Kadena.Types.Command{
cmd: "{\"meta\":{\"chainId\":\"0\",\"creationTime\":1667249173,\"gasLimit\":2500,\"gasPrice\":0.01,\"sender\":\"k:6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"ttl\":28800},\"networkId\":\"testnet04\",\"nonce\":\"2023-01-01 00:00:00.000000 UTC\",\"payload\":{\"cont\":{\"data\":{\"accounts-admin-keyset\":[\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\"]},\"pactId\":\"yxM0umrtdcvSUZDc_GSjwadH6ELYFCjOqI59Jzqapi4\",\"proof\":null,\"rollback\":true,\"step\":1}},\"signers\":[{\"addr\":\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"clist\":[{\"args\":[\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\"],\"name\":\"coin.GAS\"}],\"pubKey\":\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"scheme\":\"ED25519\"}]}",
hash: %Kadena.Types.PactTransactionHash{
hash: "teDAH5S3H0DgzYWL-NKOTA-D2sIT01hDYHxpKRZv6zc"
},
sigs: %Kadena.Types.SignaturesList{
signatures: [
%Kadena.Types.Signature{
sig: "708777a672ebf3f29d936a75677305a2a77add7380abede734696dddc4cbbfd62d8cfc1e236e7a8e1df07632233a05c697157ef7a58fcf67a91d6c4791ca7807"
}
]
}
}}
{:ok,
%Kadena.Types.Command{
cmd:
"{\"meta\":{\"chainId\":\"0\",\"creationTime\":1667249173,\"gasLimit\":2500,\"gasPrice\":0.01,\"sender\":\"k:6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"ttl\":28800},\"networkId\":\"testnet04\",\"nonce\":\"2023-01-01 00:00:00.000000 UTC\",\"payload\":{\"cont\":{\"data\":{\"accounts_admin_keyset\":[\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\"]},\"pactId\":\"yxM0umrtdcvSUZDc_GSjwadH6ELYFCjOqI59Jzqapi4\",\"proof\":null,\"rollback\":true,\"step\":1}},\"signers\":[{\"addr\":null,\"clist\":[{\"args\":[\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\"],\"name\":\"coin.GAS\"}],\"pubKey\":\"6ffea3fabe4e7fe6a89f88fc6d662c764ed1359fbc03a28afdac3935415347d7\",\"scheme\":\"ED25519\"}]}",
hash: %Kadena.Types.PactTransactionHash{
hash: "DIMUpcB9NahL3746TTm1A8Wrr-JRVCT5Rk0rPdxZItg"
},
sigs: [
%Kadena.Types.Signature{
sig:
"98de12eda675334c7fddb6ca453017bf2df5af928c2c0763f8748b950f81b7b075f74fc2294f6a16099aa51955a035889767f048a76f7a272eaf639140dbd20a"
}
]
}}
```

## Chainweb Pact API
Expand Down Expand Up @@ -753,13 +750,13 @@ Chainweb.Pact.spv(payload, network_id: :testnet04, chain_id: 1)

## Roadmap

The latest updated branch to target a PR is `v0.12`
The latest updated branch to target a PR is `v0.13`

You can see a big picture of the roadmap here: [**ROADMAP**][roadmap]

### What we're working on now 🎉

- [Remove List Types](https://github.com/kommitters/kadena.ex/issues/169)
- [Chainweb P2P API](https://github.com/kommitters/kadena.ex/milestone/1)

### Done - What we've already developed! 🚀

Expand Down
48 changes: 17 additions & 31 deletions lib/chainweb/pact/command_payload.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,29 @@ defmodule Kadena.Chainweb.Pact.CommandPayload do
alias Kadena.Types.{
Base16String,
Cap,
CapsList,
ChainID,
ContPayload,
EnvData,
ExecPayload,
MetaData,
NetworkID,
OptionalCapsList,
PactCode,
PactDecimal,
PactInt,
PactPayload,
PactTransactionHash,
PactValue,
PactValuesList,
Proof,
Rollback,
Signer,
SignersList,
Step
}

@behaviour Kadena.Chainweb.Pact.Type

@type network_id :: NetworkID.t() | nil
@type payload :: PactPayload.t()
@type signers :: SignersList.t()
@type signers :: list(Signer.t())
@type meta :: MetaData.t()
@type nonce :: String.t()
@type value :: network_id() | payload() | signers() | meta() | nonce()
Expand All @@ -44,15 +40,15 @@ defmodule Kadena.Chainweb.Pact.CommandPayload do
@type valid_list :: {:ok, list()}
@type map_return :: map() | nil
@type string_value :: String.t() | nil
@type pact_values :: PactValuesList.t()
@type pact_values :: list(PactValue.t())
@type scheme :: :ed25519 | nil
@type scheme_return :: :ED25519 | nil
@type cap :: Cap.t()
@type data :: EnvData.t() | nil
@type proof :: Proof.t() | nil
@type signer :: Signer.t()
@type raw_value :: integer() | string_value() | boolean() | Decimal.t()
@type clist :: CapsList.t() | nil
@type clist :: list(cap()) | nil
@type addr :: Base16String.t() | nil
@type pact_payload :: PactPayload.t()
@type literal ::
Expand All @@ -61,7 +57,7 @@ defmodule Kadena.Chainweb.Pact.CommandPayload do
| String.t()
| PactInt.t()
| PactDecimal.t()
| PactValuesList.t()
| list(PactValue.t())

@type t :: %__MODULE__{
network_id: network_id(),
Expand Down Expand Up @@ -139,14 +135,9 @@ defmodule Kadena.Chainweb.Pact.CommandPayload do
end

@spec validate_signers(signers :: signers()) :: validation()
defp validate_signers(%SignersList{} = signers), do: {:ok, signers}

defp validate_signers(signers) do
case SignersList.new(signers) do
%SignersList{} = signers -> {:ok, signers}
_error -> {:error, [signers: :invalid]}
end
end
defp validate_signers([%Signer{} | _rest] = signers), do: {:ok, signers}
defp validate_signers([] = signers), do: {:ok, signers}
defp validate_signers(_signers), do: {:error, [signers: :invalid]}

@spec validate_meta(meta :: meta()) :: validation()
defp validate_meta(%MetaData{} = meta), do: {:ok, meta}
Expand Down Expand Up @@ -223,9 +214,9 @@ defmodule Kadena.Chainweb.Pact.CommandPayload do
|> (&{:ok, &1}).()
end

@spec extract_signers_list(signers :: signers()) :: valid_list()
defp extract_signers_list(%SignersList{signers: list}) do
signers = Enum.map(list, fn sig -> extract_signer_info(sig) end)
@spec extract_signers_list(signer_list :: signers()) :: valid_list()
defp extract_signers_list(signer_list) do
signers = Enum.map(signer_list, fn sig -> extract_signer_info(sig) end)
{:ok, signers}
end

Expand All @@ -234,7 +225,7 @@ defmodule Kadena.Chainweb.Pact.CommandPayload do
addr: addr,
scheme: scheme,
pub_key: %Base16String{value: pub_key},
clist: %OptionalCapsList{clist: clist}
clist: clist
}) do
MapCase.to_camel!(%{
addr: extract_addr(addr),
Expand All @@ -254,23 +245,18 @@ defmodule Kadena.Chainweb.Pact.CommandPayload do

@spec extract_clist(clist()) :: list()
defp extract_clist(nil), do: []

defp extract_clist(%CapsList{caps: caps}) do
Enum.map(caps, fn cap -> extract_cap_info(cap) end)
end
defp extract_clist(caps), do: Enum.map(caps, &extract_cap_info/1)

@spec extract_cap_info(cap()) :: map_return()
defp extract_cap_info(%Cap{name: name, args: args}) do
%{name: name, args: extract_values(args)}
end
defp extract_cap_info(%Cap{name: name, args: args}),
do: %{name: name, args: extract_values(args)}

@spec extract_values(pact_values()) :: list()
defp extract_values(%PactValuesList{pact_values: pact_values}) do
Enum.map(pact_values, fn %PactValue{literal: pact_value} -> extract_value(pact_value) end)
end
defp extract_values(pact_values),
do: Enum.map(pact_values, fn %PactValue{literal: pact_value} -> extract_value(pact_value) end)

@spec extract_value(literal()) :: raw_value()
defp extract_value(%PactValuesList{} = pact_value), do: extract_values(pact_value)
defp extract_value(value) when is_list(value), do: extract_values(value)
defp extract_value(%PactInt{raw_value: value}), do: value
defp extract_value(%PactDecimal{raw_value: value}), do: value
defp extract_value(value), do: value
Expand Down
8 changes: 4 additions & 4 deletions lib/chainweb/pact/local_request_body.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,13 @@ defmodule Kadena.Chainweb.Pact.LocalRequestBody do
`LocalRequestBody` struct definition.
"""

alias Kadena.Types.{Command, PactTransactionHash, SignaturesList}
alias Kadena.Types.{Command, PactTransactionHash, Signature}

@behaviour Kadena.Chainweb.Pact.Type

@type command :: Command.t()
@type hash :: PactTransactionHash.t()
@type sigs :: SignaturesList.t()
@type sigs :: list(Signature.t())
@type cmd :: String.t()
@type error :: {:error, Keyword.t()}
@type raw_sigs :: list(map())
Expand Down Expand Up @@ -37,8 +37,8 @@ defmodule Kadena.Chainweb.Pact.LocalRequestBody do
end

@spec to_signature_list(signatures :: sigs()) :: {:ok, raw_sigs()}
defp to_signature_list(%SignaturesList{signatures: list}) do
sigs = Enum.map(list, fn sig -> Map.from_struct(sig) end)
defp to_signature_list(signatures) do
sigs = Enum.map(signatures, &Map.from_struct/1)
{:ok, sigs}
end
end
30 changes: 16 additions & 14 deletions lib/chainweb/pact/poll_request_body.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,20 @@ defmodule Kadena.Chainweb.Pact.PollRequestBody do
`PollRequestBody` struct definition.
"""

alias Kadena.Types.{Base64Url, Base64UrlsList}
alias Kadena.Types.Base64Url

@behaviour Kadena.Chainweb.Pact.Type

@type request_keys :: Base64UrlsList.t()
@type base64_urls :: Base64UrlsList.t()
@type urls :: list(String.t())
@type request_keys :: list(Base64Url.t())
@type error :: {:error, Keyword.t()}

@type t :: %__MODULE__{request_keys: request_keys()}

defstruct request_keys: []

@impl true
def new(request_keys) when is_list(request_keys) do
case Base64UrlsList.new(request_keys) do
%Base64UrlsList{} = request_keys -> %__MODULE__{request_keys: request_keys}
{:error, _reasons} -> {:error, [request_keys: :invalid]}
end
end

def new(%Base64UrlsList{} = request_keys), do: %__MODULE__{request_keys: request_keys}
def new(request_keys) when is_list(request_keys), do: build_list(%__MODULE__{}, request_keys)
def new(_request_keys), do: {:error, [request_keys: :not_a_list]}

@impl true
Expand All @@ -32,7 +25,16 @@ defmodule Kadena.Chainweb.Pact.PollRequestBody do
Jason.encode!(%{requestKeys: keys})
end

@spec extract_keys(base64_urls()) :: urls()
defp extract_keys(%Base64UrlsList{urls: list}),
do: Enum.map(list, fn %Base64Url{url: url} -> url end)
@spec build_list(list :: t(), urls :: list()) :: t() | error()
defp build_list(result, []), do: result

defp build_list(%__MODULE__{request_keys: urls}, [url | rest]) do
case Base64Url.new(url) do
%Base64Url{} = url -> build_list(%__MODULE__{request_keys: urls ++ [url]}, rest)
{:error, reason} -> {:error, reason}
end
end

@spec extract_keys(key_list :: request_keys()) :: urls()
defp extract_keys(key_list), do: Enum.map(key_list, fn %Base64Url{url: url} -> url end)
end
Loading