Module: Mpp::Methods::Tempo::FeePayer
- Defined in:
- lib/mpp/methods/tempo/fee_payer_envelope.rb
Constant Summary collapse
- TYPE_ID =
0x78
Class Method Summary collapse
-
.decode(data) ⇒ Object
Decode a 0x78 fee payer envelope.
-
.encode(signed_tx) ⇒ Object
Encode a sender-signed transaction as a 0x78 fee payer envelope.
- .encode_optional_uint(value) ⇒ Object
- .normalize_signature(signature) ⇒ Object
- .pack_hex(value) ⇒ Object
Class Method Details
.decode(data) ⇒ Object
Decode a 0x78 fee payer envelope.
Returns [decoded_fields, sender_address_bytes, sender_signature_bytes, key_authorization_or_nil]
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/mpp/methods/tempo/fee_payer_envelope.rb', line 48 def decode(data) Kernel.require "rlp" Kernel.raise ArgumentError, "Not a fee payer envelope (expected 0x78 prefix)" unless data.getbyte(0) == TYPE_ID decoded = RLP.decode(data[1..]) Kernel.raise ArgumentError, "Malformed fee payer envelope" unless decoded.is_a?(Array) && decoded.length >= 14 sender_address = decoded[11] sender_signature = decoded[-1] # 15 fields = key_authorization present (index 13), signature at 14 # 14 fields = no key_authorization, signature at 13 = (RLP.encode(decoded[13]) if decoded.length == 15) [decoded, sender_address.to_s.b, sender_signature.to_s.b, ] end |
.encode(signed_tx) ⇒ Object
Encode a sender-signed transaction as a 0x78 fee payer envelope. Requires the ‘rlp` gem.
Wire format: 0x78 || RLP()
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/mpp/methods/tempo/fee_payer_envelope.rb', line 16 def encode(signed_tx) Kernel.require "rlp" sender_sig = signed_tx.sender_signature sig_bytes = normalize_signature(sender_sig.respond_to?(:to_bytes) ? sender_sig.to_bytes : sender_sig.to_s.b) sender_addr = pack_hex(signed_tx.sender_address) fields = [ signed_tx.chain_id, signed_tx.max_priority_fee_per_gas, signed_tx.max_fee_per_gas, signed_tx.gas_limit, signed_tx.calls.map(&:as_rlp_list), signed_tx.access_list.map { |entry| entry.respond_to?(:as_rlp_list) ? entry.as_rlp_list : entry }, signed_tx.nonce_key, signed_tx.nonce, encode_optional_uint(signed_tx.valid_before), encode_optional_uint(signed_tx.valid_after), signed_tx.fee_token ? pack_hex(signed_tx.fee_token) : "".b, sender_addr, signed_tx..to_a ] fields << RLP.decode(signed_tx.) if signed_tx. fields << sig_bytes [TYPE_ID].pack("C") + RLP.encode(fields) end |
.encode_optional_uint(value) ⇒ Object
66 67 68 69 70 |
# File 'lib/mpp/methods/tempo/fee_payer_envelope.rb', line 66 def encode_optional_uint(value) return "".b unless value value.is_a?(Integer) ? value : value.to_i end |
.normalize_signature(signature) ⇒ Object
76 77 78 79 80 81 82 83 84 85 |
# File 'lib/mpp/methods/tempo/fee_payer_envelope.rb', line 76 def normalize_signature(signature) bytes = signature.b Kernel.raise ArgumentError, "signature must be 65 bytes, got #{bytes.bytesize}" unless bytes.bytesize == 65 v = bytes.getbyte(64) parity = (v >= 27) ? v - 27 : v Kernel.raise ArgumentError, "signature parity must be 0 or 1, got #{v}" unless [0, 1].include?(parity) bytes[0, 64] + [parity].pack("C") end |
.pack_hex(value) ⇒ Object
72 73 74 |
# File 'lib/mpp/methods/tempo/fee_payer_envelope.rb', line 72 def pack_hex(value) [value.to_s.delete_prefix("0x")].pack("H*") end |