diff --git a/lib/archethic/contracts/interpreter/action.ex b/lib/archethic/contracts/interpreter/action.ex index 984bbeffa6..fc96983de1 100644 --- a/lib/archethic/contracts/interpreter/action.ex +++ b/lib/archethic/contracts/interpreter/action.ex @@ -151,7 +151,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "to"}, address}, _acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}} ) - when not is_binary(address) do + when not is_tuple(address) and not is_binary(address) do throw({:error, "invalid add_uco_transfer arguments", node}) end @@ -159,7 +159,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "amount"}, amount}, _acc = {:ok, %{scope: {:function, "add_uco_transfer", {:actions, _}}}} ) - when not is_integer(amount) or amount <= 0 do + when (not is_tuple(amount) and not is_integer(amount)) or amount <= 0 do throw({:error, "invalid add_uco_transfer arguments", node}) end @@ -176,7 +176,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "to"}, address}, _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} ) - when not is_binary(address) do + when not is_tuple(address) and not is_binary(address) do throw({:error, "invalid add_token_transfer arguments", node}) end @@ -184,7 +184,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "amount"}, amount}, _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} ) - when not is_integer(amount) or amount <= 0 do + when (not is_tuple(amount) and not is_integer(amount)) or amount <= 0 do throw({:error, "invalid add_token_transfer arguments", node}) end @@ -192,7 +192,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "token_address"}, address}, _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} ) - when not is_binary(address) do + when not is_tuple(address) and not is_binary(address) do throw({:error, "invalid add_token_transfer arguments", node}) end @@ -200,7 +200,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "token_id"}, id}, _acc = {:ok, %{scope: {:function, "add_token_transfer", {:actions, _}}}} ) - when not is_integer(id) or id < 0 do + when (not is_tuple(id) and not is_integer(id)) or id < 0 do throw({:error, "invalid add_token_transfer arguments", node}) end @@ -217,7 +217,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "secret"}, secret}, _acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}} ) - when not is_binary(secret) do + when not is_tuple(secret) and not is_binary(secret) do throw({:error, "invalid add_ownership arguments", node}) end @@ -225,7 +225,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "secret_key"}, secret_key}, _acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}} ) - when not is_binary(secret_key) do + when not is_tuple(secret_key) and not is_binary(secret_key) do throw({:error, "invalid add_ownership arguments", node}) end @@ -233,7 +233,7 @@ defmodule Archethic.Contracts.ActionInterpreter do node = {{:atom, "authorized_public_keys"}, authorized_public_keys}, _acc = {:ok, %{scope: {:function, "add_ownership", {:actions, _}}}} ) - when not is_list(authorized_public_keys) do + when not is_tuple(authorized_public_keys) and not is_list(authorized_public_keys) do throw({:error, "invalid add_ownership arguments", node}) end diff --git a/test/archethic/contracts/interpreter/action_test.exs b/test/archethic/contracts/interpreter/action_test.exs index 5598a3d125..74784e4bfb 100644 --- a/test/archethic/contracts/interpreter/action_test.exs +++ b/test/archethic/contracts/interpreter/action_test.exs @@ -539,6 +539,64 @@ defmodule Archethic.Contracts.ActionInterpreterTest do |> ActionInterpreter.parse() end + test "should parse when arguments are variables" do + assert {:ok, :transaction, _ast} = + ~S""" + actions triggered_by: transaction do + address = "ABC123" + add_uco_transfer to: address, amount: 64 + add_token_transfer to: address, amount: 64, token_id: 0, token_address: "012" + add_ownership secret: address, secret_key: "s3cr3t", authorized_public_keys: ["ADE459"] + end + """ + |> Interpreter.sanitize_code() + |> elem(1) + |> ActionInterpreter.parse() + end + + test "should parse when arguments are fields" do + assert {:ok, :transaction, _ast} = + ~S""" + actions triggered_by: transaction do + add_uco_transfer to: transaction.address, amount: 64 + add_token_transfer to: transaction.address, amount: 64, token_id: 0, token_address: "012" + add_ownership secret: transaction.address, secret_key: "s3cr3t", authorized_public_keys: ["ADE459"] + end + """ + |> Interpreter.sanitize_code() + |> elem(1) + |> ActionInterpreter.parse() + end + + test "should parse when arguments are functions" do + assert {:ok, :transaction, _ast} = + ~S""" + actions triggered_by: transaction do + add_uco_transfer to: regex_extract("@addr", ".*"), amount: 64 + add_token_transfer to: regex_extract("@addr", ".*"), amount: 64, token_id: 0, token_address: "012" + add_ownership secret: regex_extract("@addr", ".*"), secret_key: "s3cr3t", authorized_public_keys: ["ADE459"] + end + """ + |> Interpreter.sanitize_code() + |> elem(1) + |> ActionInterpreter.parse() + end + + test "should parse when arguments are string interpolation" do + assert {:ok, :transaction, _ast} = + ~S""" + actions triggered_by: transaction do + name = "sophia" + add_uco_transfer to: "hello #{name}", amount: 64 + add_token_transfer to: "hello #{name}", amount: 64, token_id: 0, token_address: "012" + add_ownership secret: "hello #{name}", secret_key: "s3cr3t", authorized_public_keys: ["ADE459"] + end + """ + |> Interpreter.sanitize_code() + |> elem(1) + |> ActionInterpreter.parse() + end + test "should parse when building a keyword list" do assert {:ok, :transaction, _ast} = ~S""" @@ -559,6 +617,16 @@ defmodule Archethic.Contracts.ActionInterpreterTest do end test "should not parse when arguments are not allowed" do + assert {:error, "invalid add_uco_transfer arguments - amount"} = + ~S""" + actions triggered_by: transaction do + add_uco_transfer to: "abc123", amount: 0 + end + """ + |> Interpreter.sanitize_code() + |> elem(1) + |> ActionInterpreter.parse() + assert {:error, "invalid add_uco_transfer arguments - hello"} = ~S""" actions triggered_by: transaction do