Skip to content

Commit

Permalink
Merge pull request #340 from kommitters/v0.18
Browse files Browse the repository at this point in the history
Release v0.18.1
  • Loading branch information
EdwinGuayacan authored Oct 11, 2023
2 parents a203ad2 + cca764a commit e2d3d49
Show file tree
Hide file tree
Showing 21 changed files with 636 additions and 120 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 0.18.1 (11.10.2023)

* Add remaining changes for Protocol 20: Soroban.
- Add function to be able to obtain native value from a `SCVal`.
- Fix Horizon API responses related to Effects, Assets, and Soroban Operations.

## 0.18.0 (20.09.2023)

* Add Soroban Preview 11 support.
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@ The **Stellar SDK** enables the construction, signing and encoding of Stellar [t

This library is aimed at developers building Elixir applications that interact with the [**Stellar network**][stellar].

> **Note**
> If you are a smart contract developer building on Soroban, we recommend using [Soroban.ex][soroban.ex], a library built on top of Stellar SDK which offers a developer-friendly interface for interacting with Soroban smart contracts and Soroban-RPC server.
#### Protocol Version Support
| Protocol | Version |
| --------- | ------------ |
| 18 | >= v0.8 |
| 19 | >= v0.9 |
| 20 | >= v0.18 |

## Documentation
The **Stellar SDK** is composed of two complementary components: **`TxBuild`** + **`Horizon`**.
Expand All @@ -31,7 +35,7 @@ The **Stellar SDK** is composed of two complementary components: **`TxBuild`** +
```elixir
def deps do
[
{:stellar_sdk, "~> 0.18.0"}
{:stellar_sdk, "~> 0.18.1"}
]
end
```
Expand Down Expand Up @@ -920,3 +924,4 @@ Made with 💙 by [kommitters Open Source](https://kommit.co)
[stellar-cap-27]: https://stellar.org/protocol/cap-27
[stellar-protocol-19]: https://stellar.org/blog/announcing-protocol-19
[stellar-docs-account-seq-num-age]: https://developers.stellar.org/docs/glossary/accounts/#sequence-time-and-ledger
[soroban.ex]: https://github.com/kommitters/soroban.ex
28 changes: 18 additions & 10 deletions lib/horizon/asset.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,30 +8,38 @@ defmodule Stellar.Horizon.Asset do
alias Stellar.Horizon.Mapping

@type t :: %__MODULE__{
paging_token: String.t(),
asset_type: String.t(),
asset_code: String.t(),
asset_issuer: String.t(),
accounts: map(),
paging_token: String.t(),
num_accounts: non_neg_integer(),
num_claimable_balances: non_neg_integer(),
balances: map(),
claimable_balances_amount: String.t(),
num_liquidity_pools: non_neg_integer(),
num_contracts: non_neg_integer(),
amount: String.t(),
num_accounts: non_neg_integer(),
accounts: map(),
claimable_balances_amount: String.t(),
liquidity_pools_amount: String.t(),
contracts_amount: String.t(),
balances: map(),
flags: map()
}

defstruct [
:paging_token,
:asset_type,
:asset_code,
:asset_issuer,
:accounts,
:paging_token,
:num_accounts,
:num_claimable_balances,
:balances,
:claimable_balances_amount,
:num_liquidity_pools,
:num_contracts,
:amount,
:num_accounts,
:accounts,
:claimable_balances_amount,
:liquidity_pools_amount,
:contracts_amount,
:balances,
:flags
]

Expand Down
5 changes: 5 additions & 0 deletions lib/horizon/operation.ex
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ defmodule Stellar.Horizon.Operation do
AccountMerge,
AllowTrust,
BeginSponsoringFutureReserves,
BumpFootprintExpiration,
BumpSequence,
ChangeTrust,
CreateAccount,
CreateClaimableBalance,
ClaimClaimableBalance,
CreatePassiveSellOffer,
EndSponsoringFutureReserves,
InvokeHostFunction,
LiquidityPoolDeposit,
LiquidityPoolWithdraw,
ManageBuyOffer,
Expand Down Expand Up @@ -113,6 +115,7 @@ defmodule Stellar.Horizon.Operation do

@spec operation_type_mapping(type :: any()) :: Keyword.t()
defp operation_type_mapping(nil), do: @mapping
defp operation_type_mapping("restore_footprint"), do: @mapping

defp operation_type_mapping(type),
do: Keyword.merge(@mapping, body: {:struct, operation_type(type)})
Expand All @@ -138,4 +141,6 @@ defmodule Stellar.Horizon.Operation do
defp operation_type("revoke_sponsorship"), do: RevokeSponsorship
defp operation_type("liquidity_pool_deposit"), do: LiquidityPoolDeposit
defp operation_type("liquidity_pool_withdraw"), do: LiquidityPoolWithdraw
defp operation_type("invoke_host_function"), do: InvokeHostFunction
defp operation_type("bump_footprint_expiration"), do: BumpFootprintExpiration
end
20 changes: 20 additions & 0 deletions lib/horizon/operation/bump_footprint_expiration.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
defmodule Stellar.Horizon.Operation.BumpFootprintExpiration do
@moduledoc """
Represents a `BumpFootprintExpiration` operation from Horizon API.
"""

@behaviour Stellar.Horizon.Resource

alias Stellar.Horizon.Mapping

@type t :: %__MODULE__{ledgers_to_expire: non_neg_integer()}

defstruct [:ledgers_to_expire]

@impl true
def new(attrs, opts \\ [])

def new(attrs, _opts) do
Mapping.build(%__MODULE__{}, attrs)
end
end
26 changes: 26 additions & 0 deletions lib/horizon/operation/invoke_host_function.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
defmodule Stellar.Horizon.Operation.InvokeHostFunction do
@moduledoc """
Represents an `InvokeHostFunction` operation from Horizon API.
"""

@behaviour Stellar.Horizon.Resource

alias Stellar.Horizon.Mapping

@type t :: %__MODULE__{
function: String.t(),
parameters: list(map()) | nil,
address: String.t(),
salt: String.t(),
asset_balance_changes: list(map()) | nil
}

defstruct [:function, :parameters, :address, :salt, :asset_balance_changes]

@impl true
def new(attrs, opts \\ [])

def new(attrs, _opts) do
Mapping.build(%__MODULE__{}, attrs)
end
end
177 changes: 177 additions & 0 deletions lib/tx_build/sc_val.ex
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ defmodule Stellar.TxBuild.SCVal do
@moduledoc """
`SCVal` struct definition.
"""
import Bitwise

@behaviour Stellar.TxBuild.XDR

Expand Down Expand Up @@ -72,6 +73,8 @@ defmodule Stellar.TxBuild.SCVal do
| atom()
| SCAddress.t()

@type map_entry :: StellarBase.XDR.SCMapEntry.t()

@type t :: %__MODULE__{
type: type(),
value: value()
Expand Down Expand Up @@ -322,6 +325,180 @@ defmodule Stellar.TxBuild.SCVal do
|> SCVal.new(type)
end

@spec to_native_from_xdr(xdr :: String.t()) :: any
def to_native_from_xdr(xdr) when is_binary(xdr) do
with {:ok, {scval, _rest}} <- validate_xdr_decoding(xdr) do
to_native(scval)
end
end

def to_native_from_xdr(_xdr), do: {:error, :invalid_xdr}

@spec to_native(SCVal.t()) :: any
def to_native(%SCVal{
value: %StellarBase.XDR.SCSymbol{value: value},
type: %StellarBase.XDR.SCValType{identifier: :SCV_SYMBOL}
}) do
value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_VEC},
value: %StellarBase.XDR.OptionalSCVec{
sc_vec: %StellarBase.XDR.SCVec{
items: items
}
}
}) do
Enum.map(items, &to_native/1)
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_VEC},
value: %StellarBase.XDR.OptionalSCVec{
sc_vec: nil
}
}) do
[]
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_VOID},
value: _value
}) do
nil
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_BOOL},
value: %StellarBase.XDR.Bool{value: value}
}) do
value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_U128},
value: %StellarBase.XDR.UInt128Parts{
hi: %StellarBase.XDR.UInt64{datum: hi_value},
lo: %StellarBase.XDR.UInt64{datum: lo_value}
}
}) do
(hi_value <<< 64) + lo_value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_U64},
value: %StellarBase.XDR.UInt64{datum: value}
}) do
value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_I64},
value: %StellarBase.XDR.Int64{datum: value}
}) do
value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_U32},
value: %StellarBase.XDR.UInt32{datum: value}
}) do
value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_I32},
value: %StellarBase.XDR.Int32{datum: value}
}) do
value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_I128},
value: %StellarBase.XDR.Int128Parts{
hi: %StellarBase.XDR.Int64{datum: hi_value},
lo: %StellarBase.XDR.UInt64{datum: lo_value}
}
}) do
(hi_value <<< 64) + lo_value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_U256},
value: %StellarBase.XDR.UInt256Parts{
hi_hi: %StellarBase.XDR.UInt64{datum: hi_hi_value},
hi_lo: %StellarBase.XDR.UInt64{datum: hi_lo_value},
lo_hi: %StellarBase.XDR.UInt64{datum: lo_hi_value},
lo_lo: %StellarBase.XDR.UInt64{datum: lo_lo_value}
}
}) do
(hi_hi_value <<< 192) + (hi_lo_value <<< 128) + (lo_hi_value <<< 64) + lo_lo_value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_I256},
value: %StellarBase.XDR.Int256Parts{
hi_hi: %StellarBase.XDR.Int64{datum: hi_hi_value},
hi_lo: %StellarBase.XDR.UInt64{datum: hi_lo_value},
lo_hi: %StellarBase.XDR.UInt64{datum: lo_hi_value},
lo_lo: %StellarBase.XDR.UInt64{datum: lo_lo_value}
}
}) do
(hi_hi_value <<< 192) + (hi_lo_value <<< 128) + (lo_hi_value <<< 64) + lo_lo_value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_BYTES},
value: %StellarBase.XDR.SCBytes{value: value}
}) do
value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_STRING},
value: %StellarBase.XDR.SCString{value: value}
}) do
value
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_MAP},
value: %StellarBase.XDR.OptionalSCMap{
sc_map: %StellarBase.XDR.SCMap{
items: items
}
}
}) do
Enum.reduce(items, %{}, fn entry, acc ->
{key, val} = map_entry_to_native(entry)
Map.put(acc, key, val)
end)
end

def to_native(%SCVal{
type: %StellarBase.XDR.SCValType{identifier: :SCV_MAP},
value: %StellarBase.XDR.OptionalSCMap{
sc_map: nil
}
}) do
%{}
end

def to_native(_sc_val), do: {:error, :invalid_or_not_supported_sc_val}

@spec validate_xdr_decoding(xdr :: String.t()) :: validation()
defp validate_xdr_decoding(xdr) when is_binary(xdr) do
case Base.decode64(xdr) do
{:ok, decoded_xdr} -> SCVal.decode_xdr(decoded_xdr)
_ -> {:error, :invalid_base64}
end
end

@spec map_entry_to_native(map_entry :: map_entry()) :: tuple()
defp map_entry_to_native(%StellarBase.XDR.SCMapEntry{key: key, val: val}),
do: {to_native(key), to_native(val)}

@spec validate_sc_val(tuple :: tuple()) :: validation()
defp validate_sc_val({type, value})
when type in ~w(u32 u64 time_point duration)a and is_integer(value) and value >= 0,
Expand Down
2 changes: 1 addition & 1 deletion mix.exs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ defmodule Stellar.MixProject do
use Mix.Project

@github_url "https://github.com/kommitters/stellar_sdk"
@version "0.18.0"
@version "0.18.1"

def project do
[
Expand Down
6 changes: 4 additions & 2 deletions test/horizon/accounts_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -249,9 +249,11 @@ defmodule Stellar.Horizon.AccountsTest do
records: [
%Effect{type: "account_created", created_at: ~U[2015-09-30 17:15:54Z]},
%Effect{type: "account_debited", created_at: ~U[2015-09-30 17:16:54Z]},
%Effect{type: "signer_created", created_at: ~U[2015-09-30 17:17:54Z]}
%Effect{type: "signer_created", created_at: ~U[2015-09-30 17:17:54Z]},
%Effect{type: "contract_debited", created_at: ~U[2023-10-10 15:53:13Z]},
%Effect{type: "contract_credited", created_at: ~U[2023-10-10 15:52:40Z]}
]
}} = Accounts.list_effects(account_id, limit: 3)
}} = Accounts.list_effects(account_id, limit: 5)
end

test "list_offers/1", %{account_id: account_id} do
Expand Down
Loading

0 comments on commit e2d3d49

Please sign in to comment.