generated from kommitters/.template
-
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #42 from kommitters/v0.5
Release v0.5.0
- Loading branch information
Showing
9 changed files
with
707 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,3 @@ | ||
import Config | ||
|
||
config :stellar_sdk, network: :future |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
defmodule Soroban.Contract do | ||
@moduledoc """ | ||
Exposes the function to invoke Soroban smart contracts | ||
""" | ||
|
||
alias Soroban.Contract.InvokeHostFunction | ||
|
||
defdelegate invoke( | ||
contract_id, | ||
source_secret_key, | ||
function_name, | ||
function_args \\ [], | ||
auth_accounts \\ [] | ||
), | ||
to: InvokeHostFunction, | ||
as: :invoke | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,173 @@ | ||
defmodule Soroban.Contract.InvokeHostFunction do | ||
@moduledoc """ | ||
`InvokeHostFunction` implementation to invoke authorized and not authorized contract functions. | ||
""" | ||
|
||
alias Soroban.RPC | ||
alias Soroban.RPC.{SendTransactionResponse, SimulateTransactionResponse} | ||
alias Stellar.{Horizon.Accounts, TxBuild} | ||
|
||
alias Stellar.TxBuild.{ | ||
Account, | ||
ContractAuth, | ||
HostFunction, | ||
InvokeHostFunction, | ||
SCVal, | ||
SequenceNumber, | ||
Signature | ||
} | ||
|
||
@type account :: Account.t() | ||
@type function_args :: list(struct()) | ||
@type auth :: String.t() | nil | ||
@type auth_account :: String.t() | nil | ||
@type auth_accounts :: list(binary()) | ||
@type invoke_host_function :: InvokeHostFunction.t() | ||
@type function_name :: String.t() | ||
@type contract_id :: binary() | ||
@type source_secret_key :: binary() | ||
@type simulate_response :: {:ok, SimulateTransactionResponse.t()} | ||
@type send_response :: {:ok, SendTransactionResponse.t()} | ||
@type signature :: Signature.t() | ||
@type sequence_number :: SequenceNumber.t() | ||
@type sc_val_list :: list(SCVal.t()) | ||
|
||
@spec invoke( | ||
contract_id :: contract_id(), | ||
source_secret_key :: source_secret_key(), | ||
function_name :: function_name(), | ||
function_args :: function_args(), | ||
auth_accounts :: auth_accounts() | ||
) :: send_response() | ||
def invoke( | ||
contract_id, | ||
source_secret_key, | ||
function_name, | ||
function_args, | ||
auth_accounts \\ [] | ||
) do | ||
with {public_key, _secret} = keypair <- Stellar.KeyPair.from_secret_seed(source_secret_key), | ||
{:ok, seq_num} <- Accounts.fetch_next_sequence_number(public_key), | ||
{:ok, function_args} <- convert_to_sc_val(function_args), | ||
signature <- Signature.new(keypair), | ||
source_account <- Account.new(public_key), | ||
sequence_number <- SequenceNumber.new(seq_num), | ||
auth_account <- Enum.at(auth_accounts, 0) do | ||
invoke_host_function_op = create_host_function_op(contract_id, function_name, function_args) | ||
|
||
invoke_host_function_op | ||
|> simulate(source_account, sequence_number) | ||
|> send_transaction( | ||
source_account, | ||
sequence_number, | ||
signature, | ||
auth_account, | ||
invoke_host_function_op | ||
) | ||
end | ||
end | ||
|
||
@spec simulate( | ||
invoke_host_function_op :: invoke_host_function(), | ||
source_account :: account(), | ||
sequence_number :: sequence_number() | ||
) :: simulate_response() | ||
defp simulate( | ||
invoke_host_function_op, | ||
source_account, | ||
sequence_number | ||
) do | ||
{:ok, envelop_xdr} = | ||
source_account | ||
|> TxBuild.new(sequence_number: sequence_number) | ||
|> TxBuild.add_operation(invoke_host_function_op) | ||
|> TxBuild.envelope() | ||
|
||
RPC.simulate_transaction(envelop_xdr) | ||
end | ||
|
||
@spec send_transaction( | ||
simulate_response :: simulate_response(), | ||
source_account :: account(), | ||
sequence_number :: sequence_number(), | ||
signature :: signature(), | ||
auth_account :: auth_account(), | ||
invoke_host_function_op :: invoke_host_function() | ||
) :: send_response() | simulate_response() | ||
defp send_transaction( | ||
{:ok, %SimulateTransactionResponse{results: [%{footprint: footprint, auth: auth}]}}, | ||
source_account, | ||
sequence_number, | ||
signature, | ||
auth_account, | ||
invoke_host_function_op | ||
) do | ||
invoke_host_function_op = | ||
set_invoke_host_function_params(invoke_host_function_op, footprint, auth, auth_account) | ||
|
||
{:ok, envelope_xdr} = | ||
source_account | ||
|> TxBuild.new(sequence_number: sequence_number) | ||
|> TxBuild.add_operation(invoke_host_function_op) | ||
|> TxBuild.sign(signature) | ||
|> TxBuild.envelope() | ||
|
||
RPC.send_transaction(envelope_xdr) | ||
end | ||
|
||
defp send_transaction( | ||
{:ok, %SimulateTransactionResponse{}} = response, | ||
_source_account, | ||
_sequence_number, | ||
_signature, | ||
_auth_account, | ||
_invoke_host_function_op | ||
), | ||
do: response | ||
|
||
@spec create_host_function_op( | ||
contract_id :: contract_id(), | ||
function_name :: function_name(), | ||
function_args :: function_args() | ||
) :: invoke_host_function() | ||
defp create_host_function_op(contract_id, function_name, function_args) do | ||
function = | ||
HostFunction.new( | ||
type: :invoke, | ||
contract_id: contract_id, | ||
function_name: function_name, | ||
args: function_args | ||
) | ||
|
||
InvokeHostFunction.new(function: function) | ||
end | ||
|
||
@spec set_invoke_host_function_params( | ||
invoke_host_function :: invoke_host_function(), | ||
footprint :: String.t(), | ||
auth :: auth(), | ||
auth_account :: auth_account() | ||
) :: invoke_host_function() | {:error, :required_auth} | ||
defp set_invoke_host_function_params(invoke_host_function_op, footprint, [auth], nil) do | ||
invoke_host_function_op | ||
|> InvokeHostFunction.set_footprint(footprint) | ||
|> InvokeHostFunction.set_contract_auth(auth) | ||
end | ||
|
||
defp set_invoke_host_function_params(invoke_host_function_op, footprint, [auth], auth_account) do | ||
authorization = ContractAuth.sign_xdr(auth, auth_account) | ||
|
||
invoke_host_function_op | ||
|> InvokeHostFunction.set_footprint(footprint) | ||
|> InvokeHostFunction.set_contract_auth(authorization) | ||
end | ||
|
||
defp set_invoke_host_function_params(invoke_host_function_op, footprint, nil, _auth_account), | ||
do: InvokeHostFunction.set_footprint(invoke_host_function_op, footprint) | ||
|
||
@spec convert_to_sc_val(function_args :: function_args()) :: {:ok, sc_val_list()} | ||
defp convert_to_sc_val(function_args) do | ||
sc_vals = Enum.map(function_args, fn %{__struct__: struct} = arg -> struct.to_sc_val(arg) end) | ||
{:ok, sc_vals} | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.