flow_client 0.1.2 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,12 +13,12 @@ module FlowClient
13
13
  :arguments,
14
14
  :reference_block_id,
15
15
  :gas_limit,
16
- :proposer_address,
17
- :proposer_key_index,
18
- :proposer_key_sequence_number,
19
16
  :payer_address,
20
17
  :authorizer_addresses,
21
- :address_aliases
18
+ :address_aliases,
19
+ :envelope_signatures,
20
+ :payload_signatures,
21
+ :proposal_key
22
22
 
23
23
  attr_reader :envelope_signatures, :payload_signatures
24
24
 
@@ -29,9 +29,28 @@ module FlowClient
29
29
  @gas_limit = 0
30
30
  @envelope_signatures = []
31
31
  @payload_signatures = []
32
- @proposer_key_index = 0
33
- @proposer_key_sequence_number = 0
34
32
  @address_aliases = {}
33
+ @signers = {}
34
+ @proposal_key = ProposalKey.new
35
+ end
36
+
37
+ def arguments=(arguments)
38
+ arguments.to_a.each do |arg|
39
+ processed_arg = arg.class == OpenStruct ? Utils.openstruct_to_json(arg) : arg
40
+ @arguments << processed_arg
41
+ end
42
+ end
43
+
44
+ def proposer_address=(address)
45
+ @proposal_key.address = address
46
+ end
47
+
48
+ def proposer_key_index=(index)
49
+ @proposal_key.key_id = index
50
+ end
51
+
52
+ def proposer_key_sequence_number=(sequence_number)
53
+ @proposal_key.sequence_number = sequence_number
35
54
  end
36
55
 
37
56
  def self.padded_transaction_domain_tag
@@ -40,81 +59,71 @@ module FlowClient
40
59
 
41
60
  def payload_canonical_form
42
61
  [
43
- resolved_script,
44
- @arguments,
45
- [@reference_block_id].pack("H*"),
46
- @gas_limit,
47
- padded_address(@proposer_address),
48
- @proposer_key_index,
49
- @proposer_key_sequence_number,
50
- padded_address(@payer_address),
62
+ resolved_script, @arguments,
63
+ [@reference_block_id].pack("H*"), @gas_limit,
64
+ padded_address(@proposal_key.address), @proposal_key.key_id,
65
+ @proposal_key.sequence_number, padded_address(@payer_address),
51
66
  @authorizer_addresses.map { |address| padded_address(address) }
52
67
  ]
53
68
  end
54
69
 
55
70
  def payload_message
56
71
  payload = payload_canonical_form
57
-
58
- # example = %w[248 114 176 116 114 97 110 115 97 99 116 105 111 110 32 123 32 101 120 101 99 117 116 101 32 123 32 108 111 103 40 34 72 101 108 108 111 44 32 87 111 114 108 100 33 34 41 32 125 32 125 192 160 72 121 153 246 93 184 142 181 159 21 71 108 105 182 234 79 105 166 51 159 166 79 128 92 248 80 65 251 159 240 90 36 100 136 243 252 210 193 167 143 94 238 128 128 136 243 252 210 193 167 143 94 238 201 136 243 252 210 193 167 143 94 238].map(&:to_i).pack("c*")
59
- # decoded_example = RLP.decode(example)
60
- # puts "----------"
61
- # puts decoded_example.inspect
62
- # puts "----------"
63
- # puts RLP.decode(RLP.encode(payload)).inspect
64
-
65
- # # puts Utils.left_pad_bytes(ref_block_id.bytes, 32).pack('i*').inspect
66
- # puts RLP.decode(RLP.encode(payload)).inspect
67
- # ref_block_id = "da8d80c775d75c86064aa0e35a418d02c83cbc198f26d906a4441a90069b63b6"
68
- # puts [ref_block_id].pack("H*").unpack("C*")
69
- # puts ["192440c99cb17282"].pack("H*").unpack("C*")
70
- # # puts RLP.encode(payload).inspect
71
-
72
- # puts RLP.encode(payload).bytes.inspect
73
72
  RLP.encode(payload)
74
73
  end
75
74
 
76
75
  def envelope_canonical_form
77
- # puts "1 !!!!!!!!!!!!!!!!!!!!!!!!!"
78
- # puts payload_canonical_form.inspect
79
- # puts "2 !!!!!!!!!!!!!!!!!!!!!!!!!"
80
- # puts %w[248 117 248 114 176 116 114 97 110 115 97 99 116 105 111 110 32 123 32 101 120 101 99 117 116 101 32 123 32 108 111 103 40 34 72 101 108 108 111 44 32 87 111 114 108 100 33 34 41 32 125 32 125 192 160 72 121 153 246 93 184 142 181 159 21 71 108 105 182 234 79 105 166 51 159 166 79 128 92 248 80 65 251 159 240 90 36 100 136 243 252 210 193 167 143 94 238 128 128 136 243 252 210 193 167 143 94 238 201 136 243 252 210 193 167 143 94 238 192].map(&:to_i).pack("c*").inspect
81
- # puts "3 !!!!!!!!!!!!!!!!!!!!!!!!!"
76
+ @signers[@proposal_key.address] = 0
77
+
78
+ @payload_signatures.each do |sig|
79
+ @signers[sig.address] = @signers.keys.count
80
+ end
81
+
82
+ signatures = []
83
+ @payload_signatures.each do |sig|
84
+ signatures << [
85
+ @signers[sig.address.unpack1("H*")],
86
+ sig.key_id,
87
+ sig.signature
88
+ ]
89
+ end
90
+
82
91
  [
83
92
  payload_canonical_form,
84
- []
93
+ signatures
85
94
  ]
86
95
  end
87
96
 
88
97
  def envelope_message
89
- # example = %w[248 117 248 114 176 116 114 97 110 115 97 99 116 105 111 110 32 123 32 101 120 101 99 117 116 101 32 123 32 108 111 103 40 34 72 101 108 108 111 44 32 87 111 114 108 100 33 34 41 32 125 32 125 192 160 191 126 254 24 34 116 225 100 48 61 146 58 249 107 64 242 242 137 30 200 85 212 68 73 165 214 72 89 185 86 47 53 100 136 4 90 23 99 201 48 6 202 128 128 136 4 90 23 99 201 48 6 202 201 136 4 90 23 99 201 48 6 202 192].map(&:to_i).pack("c*")
90
- # decoded_example = RLP.decode(example)
91
- # puts "----------"
92
- # puts decoded_example.inspect
93
- # puts RLP.decode(RLP.encode(envelope_canonical_form)).inspect
94
- # puts "----------"
95
-
96
- # puts "**********"
97
- # puts "RLP ENCODED ENVELOPE MESSAGE"
98
- # puts "----------------"
99
- # puts RLP.encode(envelope_canonical_form).bytes.inspect
100
- # puts "**********"
101
98
  RLP.encode(envelope_canonical_form)
102
99
  end
103
100
 
104
- def add_envelope_signature(signer_address, key_index, key)
105
- domain_tagged_payload = (Transaction.padded_transaction_domain_tag.bytes + envelope_message.bytes).pack("C*")
101
+ def payload_message
102
+ RLP.encode(payload_canonical_form)
103
+ end
104
+
105
+ def add_envelope_signature(signer_address, key_index, signer)
106
+ domain_tagged_envelope = (Transaction.padded_transaction_domain_tag.bytes + envelope_message.bytes).pack("C*")
106
107
 
107
108
  @envelope_signatures << Entities::Transaction::Signature.new(
108
109
  address: padded_address(signer_address),
109
110
  key_id: key_index,
110
- signature: FlowClient::Crypto.sign(domain_tagged_payload, key)
111
+ signature: signer.sign(domain_tagged_envelope)
112
+ )
113
+ end
114
+
115
+ def add_payload_signature(signer_address, key_index, signer)
116
+ domain_tagged_payload = (Transaction.padded_transaction_domain_tag.bytes + payload_message.bytes).pack("C*")
117
+
118
+ @payload_signatures << Entities::Transaction::Signature.new(
119
+ address: padded_address(signer_address),
120
+ key_id: key_index,
121
+ signature: signer.sign(domain_tagged_payload)
111
122
  )
112
123
  end
113
124
 
114
125
  def to_protobuf_message
115
126
  payload = payload_canonical_form
116
- # puts envelope_signature.inspect
117
- # puts %w[201 159 186 250 20 195 169 176 16 128 200 154 50 249 239 220 221 149 255 210 230 181 237 96 56 158 51 241 110 139 34 201 93 88 248 235 55 206 229 231 39 47 106 31 54 122 59 252 171 165 245 9 112 33 175 6 70 180 157 77 148 130 69 225].map(&:to_i).pack("c*").inspect
118
127
 
119
128
  proposal_key = Entities::Transaction::ProposalKey.new(
120
129
  address: payload[4],
@@ -122,17 +131,24 @@ module FlowClient
122
131
  sequence_number: payload[6]
123
132
  )
124
133
 
125
- Entities::Transaction.new(
126
- script: payload[0],
127
- arguments: payload[1],
128
- reference_block_id: payload[2],
129
- gas_limit: payload[3],
130
- proposal_key: proposal_key,
131
- payer: payload[7],
132
- authorizers: payload[8],
133
- payload_signatures: [],
134
- envelope_signatures: @envelope_signatures
135
- )
134
+ Entities::Transaction.new(script: payload[0], arguments: payload[1],
135
+ reference_block_id: payload[2], gas_limit: payload[3], proposal_key: proposal_key,
136
+ payer: payload[7], authorizers: payload[8], payload_signatures: @payload_signatures,
137
+ envelope_signatures: @envelope_signatures)
138
+ end
139
+
140
+ def self.parse_grpc_type(type)
141
+ tx = Transaction.new
142
+ tx.script = type.script
143
+ tx.arguments = type.arguments
144
+ tx.reference_block_id = type.reference_block_id.unpack1("H*")
145
+ tx.gas_limit = type.gas_limit
146
+ tx.authorizer_addresses = type.authorizers.map { |address| address.unpack1("H*") }
147
+ tx.envelope_signatures = type.envelope_signatures.map { |sig| Signature.parse_grpc_type(sig) }
148
+ tx.payload_signatures = type.payload_signatures.map { |sig| Signature.parse_grpc_type(sig) }
149
+ tx.proposal_key = ProposalKey.parse_grpc_type(type.proposal_key)
150
+ tx.payer_address = type.payer.unpack1("H*")
151
+ tx
136
152
  end
137
153
 
138
154
  protected
@@ -145,4 +161,32 @@ module FlowClient
145
161
  Utils.left_pad_bytes([address_hex_string].pack("H*").bytes, 8).pack("C*")
146
162
  end
147
163
  end
148
- end
164
+
165
+ class TransactionResult
166
+ attr_accessor :status,
167
+ :status_code,
168
+ :error_message,
169
+ :events,
170
+ :block_id
171
+
172
+ def self.parse_grpc_type(type)
173
+ result = TransactionResult.new
174
+ result.block_id = type.block_id.unpack1("H*")
175
+ result.status = type.status
176
+ result.status_code = type.status_code
177
+ result.error_message = type.error_message
178
+ result.events = type.events.to_a.map { |event| FlowClient::Event.parse_grpc_type(event) }
179
+ result
180
+ end
181
+ end
182
+
183
+ class TransactionResponse
184
+ attr_accessor :id
185
+
186
+ def self.parse_grpc_type(type)
187
+ response = TransactionResponse.new
188
+ response.id = type.id.unpack1("H*")
189
+ response
190
+ end
191
+ end
192
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlowClient
4
+ # A collection of utilities.
4
5
  module Utils
5
6
  # Left pads a byte array with 0 to length
6
7
  def self.left_pad_bytes(byte_array, length)
@@ -34,5 +35,44 @@ module FlowClient
34
35
  end
35
36
  new_string
36
37
  end
38
+
39
+ def self.strip_address_prefix(address)
40
+ address[0..1]
41
+ end
42
+
43
+ def self.parse_protobuf_timestamp(timestamp)
44
+ epoch_micros = timestamp.nanos / 10 ** 6
45
+ Time.at(timestamp.seconds, epoch_micros)
46
+ end
47
+
48
+ def self.openstruct_to_json(struct)
49
+ struct.deep_to_h.to_json
50
+ # struct.each_pair.map do |key, value|
51
+ # [
52
+ # key,
53
+ # case value
54
+ # when OpenStruct then value.deep_to_h
55
+ # when Array then value.map {|el| el.class == OpenStruct ? el.deep_to_h : el}
56
+ # else value
57
+ # end
58
+ # ]
59
+ # end.to_h.to_json
60
+ end
61
+
37
62
  end
38
63
  end
64
+
65
+ class OpenStruct
66
+ def deep_to_h
67
+ each_pair.map do |key, value|
68
+ [
69
+ key,
70
+ case value
71
+ when OpenStruct then value.deep_to_h
72
+ when Array then value.map {|el| el.class == OpenStruct ? el.deep_to_h : el}
73
+ else value
74
+ end
75
+ ]
76
+ end.to_h
77
+ end
78
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlowClient
4
- VERSION = "0.1.2"
4
+ VERSION = "0.2.0"
5
5
  end
data/lib/flow_client.rb CHANGED
@@ -11,4 +11,12 @@ module FlowClient
11
11
  require "flow_client/utils"
12
12
  require "flow_client/client"
13
13
  require "flow_client/transaction"
14
+ require "flow_client/account"
15
+ require "flow_client/block"
16
+ require "flow_client/collection"
17
+ require "flow_client/signer"
18
+ require "flow_client/proposal_key"
19
+ require "flow_client/event"
20
+ require "flow_client/cadence_type.rb"
21
+ require "flow_client/signature"
14
22
  end
data/logo.svg ADDED
@@ -0,0 +1,121 @@
1
+ <svg width="520" height="520" viewBox="0 0 520 520" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <path d="M259.501 0L389.251 34.8334L484.235 130L519.002 260L484.235 390L389.251 485.167L259.501 520L129.75 485.167L34.7665 390L0 260L34.7665 130L129.75 34.8334L259.501 0Z" fill="#9B1106"/>
3
+ <path d="M266.488 391L369.026 131L484.069 390.301L266.488 391Z" fill="url(#paint0_linear_10:64)"/>
4
+ <path d="M34.9328 390.301L149.002 131L266.487 391L34.9328 390.301Z" fill="url(#paint1_linear_10:64)"/>
5
+ <path d="M34.9328 390.298L68.7848 313L266.487 391L34.9328 390.298Z" fill="url(#paint2_linear_10:64)"/>
6
+ <path d="M266.488 391L369.11 131L394.242 391H266.488Z" fill="url(#paint3_linear_10:64)"/>
7
+ <path d="M369.29 131H148.714L259.853 390L369.29 131Z" fill="url(#paint4_linear_10:64)"/>
8
+ <path d="M369.29 131H148.714L322.522 249L369.29 131Z" fill="url(#paint5_linear_10:64)"/>
9
+ <path d="M484.069 130L369.29 130.699L484.069 390V130Z" fill="url(#paint6_linear_10:64)"/>
10
+ <path d="M425.661 131H369.29L484.069 390L425.661 131Z" fill="url(#paint7_linear_10:64)"/>
11
+ <path d="M484.069 130L520 260L484.069 390V130Z" fill="url(#paint8_linear_10:64)"/>
12
+ <path d="M34.9328 130L148.714 130.699L34.9328 390V130Z" fill="url(#paint9_linear_10:64)"/>
13
+ <path d="M96.7071 131H148.714L34.9328 390L96.7071 131Z" fill="url(#paint10_linear_10:64)"/>
14
+ <path d="M34.9328 130L-2.28882e-05 260L34.9328 390V130Z" fill="url(#paint11_linear_10:64)"/>
15
+ <path d="M369.02 131L484.069 130.299L259.501 0L369.02 131Z" fill="url(#paint12_linear_10:64)"/>
16
+ <path d="M388.846 34.5923L484.069 130L259.501 0L388.846 34.5923Z" fill="url(#paint13_linear_10:64)"/>
17
+ <path d="M148.984 131L34.9328 130.299L259.501 0L148.984 131Z" fill="url(#paint14_linear_10:64)"/>
18
+ <path d="M129.26 34.5923L34.9328 130L259.501 0L129.26 34.5923Z" fill="url(#paint15_linear_10:64)"/>
19
+ <path d="M42.9175 391L259.119 520L266.488 391H42.9175Z" fill="url(#paint16_linear_10:64)"/>
20
+ <path d="M34.9328 390L259.501 520V390.699L34.9328 390Z" fill="url(#paint17_linear_10:64)"/>
21
+ <path d="M34.9328 390L259.501 520L129.985 484.85L34.9328 390Z" fill="url(#paint18_linear_10:64)"/>
22
+ <path d="M484.069 390L259.501 520V390.699L484.069 390Z" fill="url(#paint19_linear_10:64)"/>
23
+ <path d="M484.069 390L259.501 520L395.687 485.753L484.069 390Z" fill="url(#paint20_linear_10:64)"/>
24
+ <path d="M369.29 131H148.714L259.7 0L369.29 131Z" fill="url(#paint21_linear_10:64)"/>
25
+ <path d="M259.501 131H148.714L259.501 0V131Z" fill="url(#paint22_linear_10:64)"/>
26
+ <path fill-rule="evenodd" clip-rule="evenodd" d="M402.71 183.598H326.687C312.821 183.598 301.346 195.096 301.346 208.988V217.611H233.928V208.988C233.928 157.729 275.526 116.052 326.687 116.052H402.71V183.598ZM233.928 285.158L233.928 217.611L208.587 217.611C157.427 217.611 115.829 259.289 115.829 310.548C115.829 361.807 157.427 403.485 208.587 403.485C259.748 403.485 301.346 361.807 301.346 310.548V285.158H233.928ZM233.928 285.158V310.548C233.928 324.441 222.453 335.938 208.587 335.938C194.721 335.938 183.246 324.441 183.246 310.548C183.246 296.656 194.721 285.158 208.587 285.158H233.928ZM368.764 217.611H301.346V285.158H368.764V217.611Z" fill="white"/>
27
+ <defs>
28
+ <linearGradient id="paint0_linear_10:64" x1="445.058" y1="354.656" x2="336.044" y2="254.925" gradientUnits="userSpaceOnUse">
29
+ <stop stop-color="#D9190A"/>
30
+ <stop offset="1" stop-color="#9A1106"/>
31
+ </linearGradient>
32
+ <linearGradient id="paint1_linear_10:64" x1="70.4467" y1="246.323" x2="207.909" y2="346.264" gradientUnits="userSpaceOnUse">
33
+ <stop stop-color="#D9190A"/>
34
+ <stop offset="1" stop-color="#9A1106"/>
35
+ </linearGradient>
36
+ <linearGradient id="paint2_linear_10:64" x1="91.3021" y1="353.11" x2="253.431" y2="390.337" gradientUnits="userSpaceOnUse">
37
+ <stop stop-color="#FF3323"/>
38
+ <stop offset="1" stop-color="#9A1106"/>
39
+ </linearGradient>
40
+ <linearGradient id="paint3_linear_10:64" x1="362.827" y1="177.129" x2="336.238" y2="363.733" gradientUnits="userSpaceOnUse">
41
+ <stop stop-color="#9A1106"/>
42
+ <stop offset="1" stop-color="#9A1106" stop-opacity="0"/>
43
+ </linearGradient>
44
+ <linearGradient id="paint4_linear_10:64" x1="318.334" y1="268.528" x2="181.125" y2="126.36" gradientUnits="userSpaceOnUse">
45
+ <stop stop-color="#D9190A"/>
46
+ <stop offset="1" stop-color="#A91004"/>
47
+ </linearGradient>
48
+ <linearGradient id="paint5_linear_10:64" x1="325.314" y1="189.651" x2="172.62" y2="124.665" gradientUnits="userSpaceOnUse">
49
+ <stop stop-color="#A91004" stop-opacity="0"/>
50
+ <stop offset="1" stop-color="#961106"/>
51
+ </linearGradient>
52
+ <linearGradient id="paint6_linear_10:64" x1="457.674" y1="134.194" x2="473.116" y2="350.851" gradientUnits="userSpaceOnUse">
53
+ <stop stop-color="#CF190A"/>
54
+ <stop offset="1" stop-color="#FF2312"/>
55
+ </linearGradient>
56
+ <linearGradient id="paint7_linear_10:64" x1="457.674" y1="134.491" x2="468.878" y2="217.557" gradientUnits="userSpaceOnUse">
57
+ <stop stop-color="#CF190A"/>
58
+ <stop offset="1" stop-color="#FF2312"/>
59
+ </linearGradient>
60
+ <linearGradient id="paint8_linear_10:64" x1="456.972" y1="134.194" x2="500.804" y2="357.522" gradientUnits="userSpaceOnUse">
61
+ <stop offset="0.522094" stop-color="#CF190A"/>
62
+ <stop offset="1" stop-color="#FF2312"/>
63
+ </linearGradient>
64
+ <linearGradient id="paint9_linear_10:64" x1="49.5543" y1="339.677" x2="109.359" y2="136.545" gradientUnits="userSpaceOnUse">
65
+ <stop stop-color="#CF190A"/>
66
+ <stop offset="1" stop-color="#FF2312"/>
67
+ </linearGradient>
68
+ <linearGradient id="paint10_linear_10:64" x1="103.641" y1="202.208" x2="149.194" y2="115.195" gradientUnits="userSpaceOnUse">
69
+ <stop stop-color="#CF190A"/>
70
+ <stop offset="1" stop-color="#FF2312"/>
71
+ </linearGradient>
72
+ <linearGradient id="paint11_linear_10:64" x1="19.4657" y1="246.72" x2="-53.0048" y2="146.796" gradientUnits="userSpaceOnUse">
73
+ <stop stop-color="#CF190A"/>
74
+ <stop offset="1" stop-color="#FF2312"/>
75
+ </linearGradient>
76
+ <linearGradient id="paint12_linear_10:64" x1="445.753" y1="121.893" x2="239.447" y2="-12.5097" gradientUnits="userSpaceOnUse">
77
+ <stop stop-color="#9E1206"/>
78
+ <stop offset="1" stop-color="#FC2312"/>
79
+ </linearGradient>
80
+ <linearGradient id="paint13_linear_10:64" x1="370.415" y1="65" x2="389.301" y2="35.6784" gradientUnits="userSpaceOnUse">
81
+ <stop stop-color="#9E1206"/>
82
+ <stop offset="1" stop-color="#FC2312"/>
83
+ </linearGradient>
84
+ <linearGradient id="paint14_linear_10:64" x1="76.0017" y1="127.497" x2="226.893" y2="24.2219" gradientUnits="userSpaceOnUse">
85
+ <stop stop-color="#FF4E40"/>
86
+ <stop offset="1" stop-color="#FC2312"/>
87
+ </linearGradient>
88
+ <linearGradient id="paint15_linear_10:64" x1="124.657" y1="38.4409" x2="129.576" y2="84.5642" gradientUnits="userSpaceOnUse">
89
+ <stop stop-color="#FF4E40"/>
90
+ <stop offset="1" stop-color="#FC2312"/>
91
+ </linearGradient>
92
+ <linearGradient id="paint16_linear_10:64" x1="112.565" y1="411.919" x2="267.243" y2="480.12" gradientUnits="userSpaceOnUse">
93
+ <stop stop-color="#A21207"/>
94
+ <stop offset="1" stop-color="#FE4132"/>
95
+ </linearGradient>
96
+ <linearGradient id="paint17_linear_10:64" x1="112.981" y1="411.667" x2="267.752" y2="479.734" gradientUnits="userSpaceOnUse">
97
+ <stop stop-color="#A21207"/>
98
+ <stop offset="1" stop-color="#FF2412"/>
99
+ </linearGradient>
100
+ <linearGradient id="paint18_linear_10:64" x1="93.4836" y1="419.355" x2="148.744" y2="488.347" gradientUnits="userSpaceOnUse">
101
+ <stop stop-color="#A21207"/>
102
+ <stop offset="1" stop-color="#F82312"/>
103
+ </linearGradient>
104
+ <linearGradient id="paint19_linear_10:64" x1="374.101" y1="438.925" x2="258.309" y2="374.99" gradientUnits="userSpaceOnUse">
105
+ <stop stop-color="#A21207"/>
106
+ <stop offset="1" stop-color="#EA1F0F"/>
107
+ </linearGradient>
108
+ <linearGradient id="paint20_linear_10:64" x1="356.693" y1="471.075" x2="453.582" y2="432.186" gradientUnits="userSpaceOnUse">
109
+ <stop stop-color="#A21207"/>
110
+ <stop offset="1" stop-color="#F92413"/>
111
+ </linearGradient>
112
+ <linearGradient id="paint21_linear_10:64" x1="259.002" y1="0" x2="259.002" y2="99.4759" gradientUnits="userSpaceOnUse">
113
+ <stop stop-color="#FC2312"/>
114
+ <stop offset="1" stop-color="#AE1508"/>
115
+ </linearGradient>
116
+ <linearGradient id="paint22_linear_10:64" x1="241.385" y1="38.5294" x2="189.428" y2="119.538" gradientUnits="userSpaceOnUse">
117
+ <stop stop-color="#FC2312"/>
118
+ <stop offset="1" stop-color="#A01106"/>
119
+ </linearGradient>
120
+ </defs>
121
+ </svg>
data/logo@2x.png ADDED
Binary file