defmodule NearApi.Wallet.RequestSignin do
@moduledoc """
Request Signin struct
"""
@type t :: %__MODULE__{
contract_id: String.t(),
methond_names: [String.t()],
success_url: String.t(),
failure_url: String.t()
}
defstruct [:contract_id, :methond_names, :success_url, :failure_url]
@doc """
Wallet sign in URL builder
Params are:
`contract_id` - address of the wallet where smart contract in deployed
`method_names` - list of all smart contract methods we need to give access
`success_url` - redirect URL when successful login
`failure_url` - redirect URL when failed login
Function returns a tuple with sign in url and a key pair generated for creating smart contract access, e.g.:
{
"https://wallet.testnet.near.org/login?contract_id=smart_contract_address.testnet&failure_url=https%3A%2F%2Ffailure_url.com&public_key=336ttyrZRPSKSWESkbRx6fBe3DUEP1MMbJHMQ3Es9Cex&success_url=https%3A%2F%2Fsuccess_url.com",
%NearApi.KeyPair{
public_key: %NearApi.PublicKey{
data: <<public key bitstring here>>,
key_type: 0
},
secret_key: "secret key string here, Base58 encoded"
}
}
Function generates a public key we'll use to create access for the smart contract.
This puclic key will be returned in the success_url on successful sign in.
When successful sign in the Wallet redirects back to `success_url` with additional params:
e.g.:
if `success_url` == "https://success_url.com"
then redirect URL will be:
https://success_url.com/?account_id=wallet_account.testnet&public_key=PUBLIC_KEY_32&all_keys=ED25519_ACCESS_KEY
"""
@spec build_url(params :: map, net :: atom | String.t()) :: {url :: String.t(), key_pair :: NearApi.KeyPair.t()}
def build_url(params, :mainnet), do: do_build(params, "https://wallet.near.org")
def build_url(params, :testnet), do: do_build(params, "https://wallet.testnet.near.org")
def build_url(params, wallet_base_url), do: do_build(params, wallet_base_url)
defp do_build(
%{contract_id: contract_id, method_names: method_names, success_url: success_url, failure_url: failure_url},
wallet_base_url
) do
key_pair = NearApi.KeyPair.from_random()
public_key = B58.encode58(key_pair.public_key.data)
query =
%{
success_url: success_url,
failure_url: failure_url,
contract_id: contract_id,
public_key: public_key
}
|> URI.encode_query()
|> append_method_names(method_names)
url = [wallet_base_url, "/login?", query] |> Enum.join("")
{url, key_pair}
end
defp do_build(%{contract_id: _, success_url: _, failure_url: _} = params, wallet_base_url) do
Map.put(params, :method_names, []) |> do_build(wallet_base_url)
end
defp append_method_names(query, []), do: query
defp append_method_names(query, [name | rest]) do
append_method_names("#{query}&methodNames[]=#{URI.encode(name)}", rest)
end
end