flow_client 0.1.1 → 0.2.2

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,10 @@ 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
+ :proposal_key
22
20
 
23
21
  attr_reader :envelope_signatures, :payload_signatures
24
22
 
@@ -26,95 +24,59 @@ module FlowClient
26
24
  @authorizer_addresses = []
27
25
  @arguments = []
28
26
  @script = ""
29
- @gas_limit = 0
27
+ @gas_limit = 999
30
28
  @envelope_signatures = []
31
29
  @payload_signatures = []
32
- @proposer_key_index = 0
33
- @proposer_key_sequence_number = 0
34
30
  @address_aliases = {}
31
+ @signers = {}
32
+ @proposal_key = ProposalKey.new
35
33
  end
36
34
 
37
- def self.padded_transaction_domain_tag
38
- Utils.right_pad_bytes(TRANSACTION_DOMAIN_TAG.bytes, 32).pack("c*")
35
+ def arguments=(arguments)
36
+ arguments.to_a.each do |arg|
37
+ processed_arg = arg.instance_of?(OpenStruct) ? Utils.openstruct_to_json(arg) : arg
38
+ @arguments << processed_arg
39
+ end
39
40
  end
40
41
 
41
- def payload_canonical_form
42
- [
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),
51
- @authorizer_addresses.map { |address| padded_address(address) }
52
- ]
42
+ def proposer_address=(address)
43
+ @proposal_key.address = address
53
44
  end
54
45
 
55
- def payload_message
56
- 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
- RLP.encode(payload)
46
+ def proposer_key_index=(index)
47
+ @proposal_key.key_id = index
74
48
  end
75
49
 
76
- 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 !!!!!!!!!!!!!!!!!!!!!!!!!"
82
- [
83
- payload_canonical_form,
84
- []
85
- ]
50
+ def proposer_key_sequence_number=(sequence_number)
51
+ @proposal_key.sequence_number = sequence_number
86
52
  end
87
53
 
88
- 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
- RLP.encode(envelope_canonical_form)
54
+ def self.padded_transaction_domain_tag
55
+ Utils.right_pad_bytes(TRANSACTION_DOMAIN_TAG.bytes, 32).pack("c*")
102
56
  end
103
57
 
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*")
58
+ def add_envelope_signature(signer_address, key_index, signer)
59
+ domain_tagged_envelope = (Transaction.padded_transaction_domain_tag.bytes + envelope_message.bytes).pack("C*")
106
60
 
107
61
  @envelope_signatures << Entities::Transaction::Signature.new(
108
62
  address: padded_address(signer_address),
109
63
  key_id: key_index,
110
- signature: FlowClient::Crypto.sign(domain_tagged_payload, key)
64
+ signature: signer.sign(domain_tagged_envelope)
65
+ )
66
+ end
67
+
68
+ def add_payload_signature(signer_address, key_index, signer)
69
+ domain_tagged_payload = (Transaction.padded_transaction_domain_tag.bytes + payload_message.bytes).pack("C*")
70
+
71
+ @payload_signatures << Entities::Transaction::Signature.new(
72
+ address: padded_address(signer_address),
73
+ key_id: key_index,
74
+ signature: signer.sign(domain_tagged_payload)
111
75
  )
112
76
  end
113
77
 
114
78
  def to_protobuf_message
115
79
  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
80
 
119
81
  proposal_key = Entities::Transaction::ProposalKey.new(
120
82
  address: payload[4],
@@ -122,17 +84,24 @@ module FlowClient
122
84
  sequence_number: payload[6]
123
85
  )
124
86
 
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
- )
87
+ Entities::Transaction.new(script: payload[0], arguments: payload[1],
88
+ reference_block_id: payload[2], gas_limit: payload[3], proposal_key: proposal_key,
89
+ payer: payload[7], authorizers: payload[8], payload_signatures: @payload_signatures,
90
+ envelope_signatures: @envelope_signatures)
91
+ end
92
+
93
+ def self.parse_grpc_type(type)
94
+ tx = Transaction.new
95
+ tx.script = type.script
96
+ tx.arguments = type.arguments
97
+ tx.reference_block_id = type.reference_block_id.unpack1("H*")
98
+ tx.gas_limit = type.gas_limit
99
+ tx.authorizer_addresses = type.authorizers.map { |address| address.unpack1("H*") }
100
+ tx.envelope_signatures = type.envelope_signatures.map { |sig| Signature.parse_grpc_type(sig) }
101
+ tx.payload_signatures = type.payload_signatures.map { |sig| Signature.parse_grpc_type(sig) }
102
+ tx.proposal_key = ProposalKey.parse_grpc_type(type.proposal_key)
103
+ tx.payer_address = type.payer.unpack1("H*")
104
+ tx
136
105
  end
137
106
 
138
107
  protected
@@ -144,5 +113,78 @@ module FlowClient
144
113
  def padded_address(address_hex_string)
145
114
  Utils.left_pad_bytes([address_hex_string].pack("H*").bytes, 8).pack("C*")
146
115
  end
116
+
117
+ def payload_canonical_form
118
+ [
119
+ resolved_script, @arguments,
120
+ [@reference_block_id].pack("H*"), @gas_limit,
121
+ padded_address(@proposal_key.address), @proposal_key.key_id,
122
+ @proposal_key.sequence_number, padded_address(@payer_address),
123
+ @authorizer_addresses.map { |address| padded_address(address) }
124
+ ]
125
+ end
126
+
127
+ def payload_message
128
+ payload = payload_canonical_form
129
+ RLP.encode(payload)
130
+ end
131
+
132
+ def envelope_canonical_form
133
+ @signers[@proposal_key.address] = 0
134
+
135
+ @payload_signatures.each do |sig|
136
+ @signers[sig.address] = @signers.keys.count
137
+ end
138
+
139
+ signatures = []
140
+ @payload_signatures.each do |sig|
141
+ signatures << [
142
+ @signers[sig.address.unpack1("H*")],
143
+ sig.key_id,
144
+ sig.signature
145
+ ]
146
+ end
147
+
148
+ [
149
+ payload_canonical_form,
150
+ signatures
151
+ ]
152
+ end
153
+
154
+ def envelope_message
155
+ RLP.encode(envelope_canonical_form)
156
+ end
157
+
158
+ def payload_message
159
+ RLP.encode(payload_canonical_form)
160
+ end
161
+ end
162
+
163
+ class TransactionResult
164
+ attr_accessor :status,
165
+ :status_code,
166
+ :error_message,
167
+ :events,
168
+ :block_id
169
+
170
+ def self.parse_grpc_type(type)
171
+ result = TransactionResult.new
172
+ result.block_id = type.block_id.unpack1("H*")
173
+ result.status = type.status
174
+ result.status_code = type.status_code
175
+ result.error_message = type.error_message
176
+ result.events = type.events.to_a.map { |event| FlowClient::Event.parse_grpc_type(event) }
177
+ result
178
+ end
179
+ end
180
+
181
+ class TransactionResponse
182
+ attr_accessor :id
183
+
184
+ def self.parse_grpc_type(type)
185
+ response = TransactionResponse.new
186
+ response.id = type.id.unpack1("H*")
187
+ response
188
+ end
147
189
  end
148
190
  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,33 @@ 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
+ end
37
51
  end
38
52
  end
53
+
54
+ class OpenStruct
55
+ def deep_to_h
56
+ each_pair.map do |key, value|
57
+ [
58
+ key,
59
+ case value
60
+ when OpenStruct then value.deep_to_h
61
+ when Array then value.map {|el| el.class == OpenStruct ? el.deep_to_h : el}
62
+ else value
63
+ end
64
+ ]
65
+ end.to_h
66
+ end
67
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FlowClient
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.2"
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"
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