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

SEP-29 as implemented in JS/GO SDK's #78

Merged
merged 6 commits into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
81 changes: 71 additions & 10 deletions lib/stellar/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,15 @@
require 'securerandom'

module Stellar
class InvalidSep10ChallengeError < StandardError; end
class AccountRequiresMemoError < StandardError
attr_reader :account_id, :operation_index

def initialize(message, account_id, operation_index)
super(message)
@account_id = account_id
@operation_index = operation_index
end
end

class Client
include Contracts
Expand Down Expand Up @@ -81,8 +89,8 @@ def account_merge(options={})
sequence: sequence
})

envelope_base64 = transaction.to_envelope(account.keypair).to_xdr(:base64)
@horizon.transactions._post(tx: envelope_base64)
envelope = transaction.to_envelope(account.keypair)
submit_transaction(tx_envelope: envelope)
end

def friendbot(account)
Expand Down Expand Up @@ -111,8 +119,8 @@ def create_account(options={})
fee: fee,
})

envelope_base64 = payment.to_envelope(funder.keypair).to_xdr(:base64)
@horizon.transactions._post(tx: envelope_base64)
envelope = payment.to_envelope(funder.keypair)
submit_transaction(tx_envelope: envelope)
end

Contract ({
Expand Down Expand Up @@ -145,8 +153,8 @@ def send_payment(options={})
signers = [tx_source_account, op_source_account].uniq(&:address)
to_envelope_args = signers.map(&:keypair)

envelope_base64 = payment.to_envelope(*to_envelope_args).to_xdr(:base64)
@horizon.transactions._post(tx: envelope_base64)
envelope = payment.to_envelope(*to_envelope_args)
submit_transaction(tx_envelope: envelope)
end

Contract ({
Expand Down Expand Up @@ -192,8 +200,61 @@ def change_trust(

tx = Stellar::Transaction.change_trust(args)

envelope_base64 = tx.to_envelope(source.keypair).to_xdr(:base64)
horizon.transactions._post(tx: envelope_base64)
envelope = tx.to_envelope(source.keypair)
submit_transaction(tx_envelope: envelope)
end

Contract(C::KeywordArgs[
tx_envelope: Stellar::TransactionEnvelope,
options: Maybe[{ skip_memo_required_check: C::Bool }]
] => Any)
def submit_transaction(tx_envelope:, options: { skip_memo_required_check: false })
leighmcculloch marked this conversation as resolved.
Show resolved Hide resolved
if !options[:skip_memo_required_check]
check_memo_required(tx_envelope)
end
@horizon.transactions._post(tx: tx_envelope.to_xdr(:base64))
end

Contract Stellar::TransactionEnvelope => Any
def check_memo_required(tx_envelope)
tx = tx_envelope.tx
# Check transactions where the .memo field is nil or of type MemoType.memo_none
if !tx.memo.nil? && tx.memo.type != Stellar::MemoType.memo_none
return
end
destinations = Set.new
tx.operations.each_with_index do |op, idx|
if op.body.type == Stellar::OperationType.payment
destination = op.body.value.destination
elsif op.body.type == Stellar::OperationType.path_payment_strict_receive
destination = op.body.value.destination
elsif op.body.type == Stellar::OperationType.path_payment_strict_send
destination = op.body.value.destination
elsif op.body.type == Stellar::OperationType.account_merge
# There is no AccountMergeOp, op.body is an Operation object
# and op.body.value is a PublicKey (or AccountID) object.
destination = op.body.value
else
return
end

if destinations.include?(destination)
next
end
destinations.add(destination)

kp = Stellar::KeyPair.from_public_key(destination.value)
begin
info = account_info(kp.address)
rescue Faraday::ResourceNotFound
# Don't raise an error if its a 404, but throw one otherwise
next
end
if info.data["config.memo_required"] == "MQ=="
# MQ== is the base64 encoded string for the string "1"
raise AccountRequiresMemoError.new("account requires memo", destination, idx)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JakeUrban nice! can you update the test to assert this and also update the demo code so people know what attrs they can work with?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure thing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you say demo code you're referring to the /examples files right? I don't want to update the examples before the functionality is released. I think doing so would confuse people.

But I'll add that test.

end
end
end

Contract(C::KeywordArgs[
Expand Down Expand Up @@ -254,6 +315,6 @@ def verify_tx_signed_by(transaction_envelope:, keypair:)
tx_envelope: transaction_envelope, keypair: keypair
)
end

end
end
Loading