Class: Mpp::Methods::Tempo::TempoMethod
- Inherits:
-
Object
- Object
- Mpp::Methods::Tempo::TempoMethod
- Defined in:
- lib/mpp/methods/tempo/client_method.rb
Overview
Tempo payment method implementation. Handles client-side credential creation for Tempo payments.
Instance Attribute Summary collapse
-
#account ⇒ Object
readonly
Returns the value of attribute account.
-
#chain_id ⇒ Object
readonly
Returns the value of attribute chain_id.
-
#client_id ⇒ Object
readonly
Returns the value of attribute client_id.
-
#currency ⇒ Object
readonly
Returns the value of attribute currency.
-
#decimals ⇒ Object
readonly
Returns the value of attribute decimals.
-
#expected_recipients ⇒ Object
readonly
Returns the value of attribute expected_recipients.
-
#fee_payer ⇒ Object
readonly
Returns the value of attribute fee_payer.
-
#fee_payer_allowed_fee_tokens ⇒ Object
readonly
Returns the value of attribute fee_payer_allowed_fee_tokens.
-
#intents ⇒ Object
Returns the value of attribute intents.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
-
#recipient ⇒ Object
readonly
Returns the value of attribute recipient.
-
#root_account ⇒ Object
readonly
Returns the value of attribute root_account.
-
#rpc_url ⇒ Object
readonly
Returns the value of attribute rpc_url.
Instance Method Summary collapse
-
#create_credential(challenge, mode: nil) ⇒ Object
Create a credential to satisfy the given challenge.
-
#initialize(account: nil, fee_payer: nil, root_account: nil, rpc_url: Defaults::RPC_URL, chain_id: nil, currency: nil, recipient: nil, decimals: 6, client_id: nil, expected_recipients: nil, fee_payer_allowed_fee_tokens: nil) ⇒ TempoMethod
constructor
A new instance of TempoMethod.
-
#transform_request(request, _credential) ⇒ Object
Transform request - adds default methodDetails if needed.
Constructor Details
#initialize(account: nil, fee_payer: nil, root_account: nil, rpc_url: Defaults::RPC_URL, chain_id: nil, currency: nil, recipient: nil, decimals: 6, client_id: nil, expected_recipients: nil, fee_payer_allowed_fee_tokens: nil) ⇒ TempoMethod
Returns a new instance of TempoMethod.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 25 def initialize(account: nil, fee_payer: nil, root_account: nil, rpc_url: Defaults::RPC_URL, chain_id: nil, currency: nil, recipient: nil, decimals: 6, client_id: nil, expected_recipients: nil, fee_payer_allowed_fee_tokens: nil) @name = "tempo" @account = account @fee_payer = fee_payer @fee_payer_allowed_fee_tokens = fee_payer_allowed_fee_tokens&.map { |token| token.to_s.downcase } @root_account = root_account @rpc_url = rpc_url @chain_id = chain_id @currency = currency @recipient = recipient @decimals = decimals @client_id = client_id @expected_recipients = expected_recipients&.map(&:downcase)&.to_set @intents = {} end |
Instance Attribute Details
#account ⇒ Object (readonly)
Returns the value of attribute account.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def account @account end |
#chain_id ⇒ Object (readonly)
Returns the value of attribute chain_id.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def chain_id @chain_id end |
#client_id ⇒ Object (readonly)
Returns the value of attribute client_id.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def client_id @client_id end |
#currency ⇒ Object (readonly)
Returns the value of attribute currency.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def currency @currency end |
#decimals ⇒ Object (readonly)
Returns the value of attribute decimals.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def decimals @decimals end |
#expected_recipients ⇒ Object (readonly)
Returns the value of attribute expected_recipients.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def expected_recipients @expected_recipients end |
#fee_payer ⇒ Object (readonly)
Returns the value of attribute fee_payer.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def fee_payer @fee_payer end |
#fee_payer_allowed_fee_tokens ⇒ Object (readonly)
Returns the value of attribute fee_payer_allowed_fee_tokens.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def fee_payer_allowed_fee_tokens @fee_payer_allowed_fee_tokens end |
#intents ⇒ Object
Returns the value of attribute intents.
23 24 25 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 23 def intents @intents end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def name @name end |
#recipient ⇒ Object (readonly)
Returns the value of attribute recipient.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def recipient @recipient end |
#root_account ⇒ Object (readonly)
Returns the value of attribute root_account.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def root_account @root_account end |
#rpc_url ⇒ Object (readonly)
Returns the value of attribute rpc_url.
20 21 22 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 20 def rpc_url @rpc_url end |
Instance Method Details
#create_credential(challenge, mode: nil) ⇒ Object
Create a credential to satisfy the given challenge.
mode: :pull (default) — return signed transaction for server to broadcast
:push — broadcast on-chain, return transaction hash
:proof — zero-amount transaction proving account ownership
50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 50 def create_credential(challenge, mode: nil) raise ArgumentError, "No account configured for signing" unless @account raise ArgumentError, "Unsupported intent: #{challenge.intent}" unless challenge.intent == "charge" mode ||= :pull request = challenge.request method_details = request["methodDetails"] method_details = {} unless method_details.is_a?(Hash) validate_recipients(request, method_details) if @expected_recipients use_fee_payer = method_details.fetch("feePayer", false) nonce_key = request.fetch("nonce_key", 0) if nonce_key.is_a?(String) nonce_key = nonce_key.start_with?("0x") ? nonce_key.to_i(16) : nonce_key.to_i end memo = method_details["memo"] memo ||= Attribution.encode(server_id: challenge.realm, client_id: @client_id, challenge_id: challenge.id) # Resolve RPC URL from challenge's chainId. Normalize the configured pin # once (it may be a String from ENV/config) so it compares equal to # integer chain ids everywhere, including the downstream RPC check. resolved_rpc_url = @rpc_url expected_chain_id = nil configured_chain_id = @chain_id.nil? ? nil : Integer(@chain_id) challenge_chain_id = method_details["chainId"] if challenge_chain_id begin parsed_chain_id = Integer(challenge_chain_id) # Chain pinning: reject a challenge whose chainId conflicts with the # configured chain, before any RPC call or signing. if configured_chain_id && parsed_chain_id != configured_chain_id raise TransactionError, "Chain ID mismatch: expected #{configured_chain_id}, got #{parsed_chain_id}" end resolved = Defaults::CHAIN_RPC_URLS[parsed_chain_id] if resolved resolved_rpc_url = resolved expected_chain_id = parsed_chain_id end rescue ArgumentError, TypeError # ignore end end expected_chain_id ||= configured_chain_id # Proof mode: sign EIP-712 typed data (no transaction needed) if mode == :proof chain_id = expected_chain_id || @chain_id raise ArgumentError, "chain_id required for proof mode" unless chain_id signature = Proof.sign( account: @account, chain_id: chain_id, challenge_id: challenge.id, realm: challenge.realm ) return Mpp::Credential.new( challenge: challenge.to_echo, payload: {"type" => "proof", "signature" => signature}, source: Proof.source(address: @account.address, chain_id: chain_id) ) end raw_tx, chain_id = build_tempo_transfer( amount: request["amount"], currency: request["currency"], recipient: request["recipient"], nonce_key: nonce_key, memo: memo, rpc_url: resolved_rpc_url, expected_chain_id: expected_chain_id, awaiting_fee_payer: use_fee_payer ) payload = if mode == :push tx_hash = Rpc.call(resolved_rpc_url, "eth_sendRawTransaction", [raw_tx]) raise TransactionError, "No transaction hash returned" unless tx_hash {"type" => "hash", "hash" => tx_hash} else {"type" => "transaction", "signature" => raw_tx} end Mpp::Credential.new( challenge: challenge.to_echo, payload: payload, source: "did:pkh:eip155:#{chain_id}:#{@account.address}" ) end |
#transform_request(request, _credential) ⇒ Object
Transform request - adds default methodDetails if needed.
144 145 146 |
# File 'lib/mpp/methods/tempo/client_method.rb', line 144 def transform_request(request, _credential) request end |