flow_client 0.2.3-arm64-darwin-21

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.
Files changed (64) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/ruby.yml +37 -0
  3. data/.gitignore +13 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +26 -0
  6. data/CHANGELOG.md +24 -0
  7. data/CODE_OF_CONDUCT.md +84 -0
  8. data/Gemfile +12 -0
  9. data/Gemfile.lock +114 -0
  10. data/Guardfile +79 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +747 -0
  13. data/Rakefile +12 -0
  14. data/bin/console +15 -0
  15. data/bin/setup +8 -0
  16. data/docker-compose.yml +12 -0
  17. data/flow.json +21 -0
  18. data/flow_client.gemspec +44 -0
  19. data/lib/cadence/contracts/NonFungibleToken.cdc +144 -0
  20. data/lib/cadence/templates/add-account-key.cdc +16 -0
  21. data/lib/cadence/templates/add-contract.cdc +5 -0
  22. data/lib/cadence/templates/create-account.cdc +21 -0
  23. data/lib/cadence/templates/remove-contract.cdc +5 -0
  24. data/lib/cadence/templates/update-contract.cdc +5 -0
  25. data/lib/flow/access/access_pb.rb +168 -0
  26. data/lib/flow/access/access_services_pb.rb +96 -0
  27. data/lib/flow/entities/account_pb.rb +30 -0
  28. data/lib/flow/entities/block_header_pb.rb +20 -0
  29. data/lib/flow/entities/block_pb.rb +25 -0
  30. data/lib/flow/entities/block_seal_pb.rb +19 -0
  31. data/lib/flow/entities/collection_pb.rb +23 -0
  32. data/lib/flow/entities/event_pb.rb +20 -0
  33. data/lib/flow/entities/transaction_pb.rb +47 -0
  34. data/lib/flow/execution/execution_pb.rb +65 -0
  35. data/lib/flow/execution/execution_services_pb.rb +43 -0
  36. data/lib/flow/legacy/access/access_pb.rb +157 -0
  37. data/lib/flow/legacy/access/access_services_pb.rb +89 -0
  38. data/lib/flow/legacy/entities/account_pb.rb +28 -0
  39. data/lib/flow/legacy/entities/block_header_pb.rb +20 -0
  40. data/lib/flow/legacy/entities/block_pb.rb +25 -0
  41. data/lib/flow/legacy/entities/block_seal_pb.rb +19 -0
  42. data/lib/flow/legacy/entities/collection_pb.rb +22 -0
  43. data/lib/flow/legacy/entities/event_pb.rb +20 -0
  44. data/lib/flow/legacy/entities/transaction_pb.rb +45 -0
  45. data/lib/flow/legacy/execution/execution_pb.rb +65 -0
  46. data/lib/flow/legacy/execution/execution_services_pb.rb +42 -0
  47. data/lib/flow_client/account.rb +31 -0
  48. data/lib/flow_client/block.rb +81 -0
  49. data/lib/flow_client/cadence_type.rb +185 -0
  50. data/lib/flow_client/client.rb +387 -0
  51. data/lib/flow_client/collection.rb +35 -0
  52. data/lib/flow_client/crypto.rb +62 -0
  53. data/lib/flow_client/event.rb +52 -0
  54. data/lib/flow_client/proposal_key.rb +23 -0
  55. data/lib/flow_client/signature.rb +23 -0
  56. data/lib/flow_client/signer.rb +22 -0
  57. data/lib/flow_client/transaction.rb +190 -0
  58. data/lib/flow_client/utils.rb +67 -0
  59. data/lib/flow_client/version.rb +5 -0
  60. data/lib/flow_client.rb +22 -0
  61. data/logo.svg +121 -0
  62. data/logo@2x.png +0 -0
  63. data/template.md +748 -0
  64. metadata +192 -0
@@ -0,0 +1,190 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "flow/entities/transaction_pb"
4
+ require "openssl"
5
+ require "rlp"
6
+
7
+ module FlowClient
8
+ # A Transaction is a full transaction object containing a payload and signatures.
9
+ class Transaction
10
+ TRANSACTION_DOMAIN_TAG = "FLOW-V0.0-transaction"
11
+
12
+ attr_accessor :script,
13
+ :arguments,
14
+ :reference_block_id,
15
+ :gas_limit,
16
+ :payer_address,
17
+ :authorizer_addresses,
18
+ :address_aliases,
19
+ :proposal_key,
20
+ :envelope_signatures,
21
+ :payload_signatures
22
+
23
+ def initialize
24
+ @authorizer_addresses = []
25
+ @arguments = []
26
+ @script = ""
27
+ @gas_limit = 999
28
+ @envelope_signatures = []
29
+ @payload_signatures = []
30
+ @address_aliases = {}
31
+ @signers = {}
32
+ @proposal_key = ProposalKey.new
33
+ end
34
+
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
40
+ end
41
+
42
+ def proposer_address=(address)
43
+ @proposal_key.address = address
44
+ end
45
+
46
+ def proposer_key_index=(index)
47
+ @proposal_key.key_id = index
48
+ end
49
+
50
+ def proposer_key_sequence_number=(sequence_number)
51
+ @proposal_key.sequence_number = sequence_number
52
+ end
53
+
54
+ def self.padded_transaction_domain_tag
55
+ Utils.right_pad_bytes(TRANSACTION_DOMAIN_TAG.bytes, 32).pack("c*")
56
+ end
57
+
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*")
60
+
61
+ @envelope_signatures << Entities::Transaction::Signature.new(
62
+ address: padded_address(signer_address),
63
+ key_id: key_index,
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)
75
+ )
76
+ end
77
+
78
+ def to_protobuf_message
79
+ payload = payload_canonical_form
80
+
81
+ proposal_key = Entities::Transaction::ProposalKey.new(
82
+ address: payload[4],
83
+ key_id: payload[5],
84
+ sequence_number: payload[6]
85
+ )
86
+
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
105
+ end
106
+
107
+ protected
108
+
109
+ def resolved_script
110
+ FlowClient::Utils.substitute_address_aliases(@script, @address_aliases)
111
+ end
112
+
113
+ def padded_address(address_hex_string)
114
+ Utils.left_pad_bytes([address_hex_string].pack("H*").bytes, 8).pack("C*")
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
189
+ end
190
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowClient
4
+ # A collection of utilities.
5
+ module Utils
6
+ # Left pads a byte array with 0 to length
7
+ def self.left_pad_bytes(byte_array, length)
8
+ required_pad_count = length - byte_array.count
9
+ padding = []
10
+ (1..required_pad_count).each do |_i|
11
+ padding << 0
12
+ end
13
+ padding + byte_array
14
+ end
15
+
16
+ # Right pads a byte array with 0 to length
17
+ def self.right_pad_bytes(byte_array, length)
18
+ required_pad_count = length - byte_array.count
19
+ padding = []
20
+ (1..required_pad_count).each do |_i|
21
+ padding << 0
22
+ end
23
+ byte_array + padding
24
+ end
25
+
26
+ # Substitutes Candence import statements using aliases with addresses
27
+ # e.g. import FungibleToken from 0xFUNGIBLE_TOKEN_ADDRESS.
28
+ #
29
+ # aliases is a hash with aliases as string keys and addresses as values,
30
+ # e.g. { "0xFUNGIBLE_TOKEN_ADDRESS": "0x0" }
31
+ def self.substitute_address_aliases(script_or_transaction, aliases = {})
32
+ new_string = script_or_transaction
33
+ aliases.each do |key, value|
34
+ new_string = new_string.gsub(key.to_s, value.to_s)
35
+ end
36
+ new_string
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
51
+ end
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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FlowClient
4
+ VERSION = "0.2.3"
5
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "flow_client/version"
4
+ require "openssl"
5
+ require "rlp"
6
+
7
+ # Collection of classes to interact with the Flow blockchain
8
+ module FlowClient
9
+ class Error < StandardError; end
10
+ require "flow_client/crypto"
11
+ require "flow_client/utils"
12
+ require "flow_client/client"
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"
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