Skip to content

Commit 4af6943

Browse files
committed
ESIP6 fix
1 parent 9d5ecff commit 4af6943

File tree

4 files changed

+51
-33
lines changed

4 files changed

+51
-33
lines changed

app/models/collections_params_extractor.rb

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,9 @@ def extract(content_uri)
100100

101101
begin
102102
# Parse JSON (preserves key order)
103-
json_str = content_uri[6..] # Remove 'data:,'
103+
# Use DataUri to correctly handle optional parameters like ESIP6
104+
json_str = DataUri.new(content_uri).decoded_data
105+
# TODO: make sure this is safe
104106
data = JSON.parse(json_str)
105107

106108
# Must be an object
@@ -135,7 +137,7 @@ def extract(content_uri)
135137
private
136138

137139
def valid_data_uri?(uri)
138-
uri.is_a?(String) && uri.start_with?('data:,')
140+
DataUri.valid?(uri)
139141
end
140142

141143
def encode_operation(operation, data, schema)
@@ -353,4 +355,4 @@ def build_lock_collection_values(data)
353355
def build_sync_ownership_values(data)
354356
[data['collection_id'], data['ethscription_ids']]
355357
end
356-
end
358+
end

app/models/generic_protocol_extractor.rb

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def self.extract(content_uri)
2525
def extract(content_uri)
2626
return DEFAULT_PARAMS unless valid_data_uri?(content_uri)
2727
begin
28-
# Extract JSON from data URI
29-
json_str = content_uri[6..] # Remove 'data:,'
28+
# Extract JSON from data URI using DataUri to support optional params (e.g., ESIP6)
29+
json_str = DataUri.new(content_uri).decoded_data
3030

3131
# Parse with security checks
3232
data = parse_json_safely(json_str)
@@ -54,7 +54,16 @@ def extract(content_uri)
5454
private
5555

5656
def valid_data_uri?(uri)
57-
uri.is_a?(String) && uri.start_with?('data:,{')
57+
return false unless uri.is_a?(String)
58+
return false unless DataUri.valid?(uri)
59+
60+
# Ensure the payload is JSON (starts with '{')
61+
begin
62+
payload = DataUri.new(uri).decoded_data
63+
payload.is_a?(String) && payload.start_with?('{')
64+
rescue StandardError
65+
false
66+
end
5867
end
5968

6069
def valid_protocol_fields?(protocol, operation)
@@ -563,4 +572,4 @@ def self.extract_token_params(content_uri)
563572
# Use the strict regex-based extractor for token protocol
564573
TokenParamsExtractor.extract(content_uri)
565574
end
566-
end
575+
end

app/models/protocol_extractor.rb

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,14 @@ class ProtocolExtractor
88
def self.extract(content_uri)
99
return nil unless content_uri.is_a?(String)
1010

11-
# Quick check if it starts with data:,
12-
return nil unless content_uri.start_with?('data:,')
11+
# Centralized validation: must be a valid data URI and JSON payload
12+
return nil unless DataUri.valid?(content_uri)
13+
begin
14+
payload = DataUri.new(content_uri).decoded_data
15+
rescue StandardError
16+
return nil
17+
end
18+
return nil unless payload.start_with?('{')
1319

1420
# Try extractors in order of strictness
1521
# 1. Token protocol (most strict - exact character position matters)
@@ -25,8 +31,8 @@ def self.extract(content_uri)
2531
return result if result
2632

2733
# Try generic extractor last (most flexible)
28-
result = try_generic_extractor(content_uri)
29-
return result if result
34+
# result = try_generic_extractor(content_uri)
35+
# return result if result
3036

3137
# No protocol could be extracted
3238
nil
@@ -36,6 +42,7 @@ def self.extract(content_uri)
3642

3743
def self.try_token_extractor(content_uri)
3844
# TokenParamsExtractor uses strict regex and returns DEFAULT_PARAMS if no match
45+
# This enforces non-ESIP6 and exact JSON formatting implicitly.
3946
params = TokenParamsExtractor.extract(content_uri)
4047

4148
# Check if extraction succeeded (returns non-default params)
@@ -162,4 +169,4 @@ def self.encode_token_data(params)
162169
''.b
163170
end
164171
end
165-
end
172+
end

spec/integration/tokens_protocol_spec.rb

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
create_input(
2525
creator: alice,
2626
to: dummy_recipient,
27-
data_uri: "data:;rule=esip6," + token_data.to_json
27+
data_uri: "data:," + token_data.to_json
2828
)
2929
) do |results|
3030
# Verify the ethscription was created
@@ -57,7 +57,7 @@
5757
create_input(
5858
creator: alice,
5959
to: dummy_recipient,
60-
data_uri: "data:;rule=esip6," + token_data.to_json
60+
data_uri: "data:," + token_data.to_json
6161
)
6262
) do |results|
6363
# Verify the ethscription was created with large numbers
@@ -82,7 +82,7 @@
8282
create_input(
8383
creator: alice,
8484
to: dummy_recipient,
85-
data_uri: "data:;rule=esip6," + malformed_data.to_json
85+
data_uri: "data:," + malformed_data.to_json
8686
)
8787
) do |results, stored|
8888
# Ethscription created but protocol extraction failed
@@ -110,7 +110,7 @@
110110
create_input(
111111
creator: alice,
112112
to: dummy_recipient,
113-
data_uri: "data:;rule=esip6," + deploy_data.to_json
113+
data_uri: "data:," + deploy_data.to_json
114114
)
115115
)
116116
end
@@ -128,7 +128,7 @@
128128
create_input(
129129
creator: bob,
130130
to: dummy_recipient,
131-
data_uri: "data:;rule=esip6," + mint_data.to_json
131+
data_uri: "data:," + mint_data.to_json
132132
)
133133
) do |results|
134134
# Verify the ethscription was created
@@ -162,7 +162,7 @@
162162
create_input(
163163
creator: bob,
164164
to: dummy_recipient,
165-
data_uri: "data:;rule=esip6," + mint1_data.to_json
165+
data_uri: "data:," + mint1_data.to_json
166166
)
167167
)
168168

@@ -179,7 +179,7 @@
179179
create_input(
180180
creator: bob,
181181
to: dummy_recipient,
182-
data_uri: "data:;rule=esip6," + mint2_data.to_json
182+
data_uri: "data:," + mint2_data.to_json
183183
)
184184
)
185185

@@ -203,7 +203,7 @@
203203
create_input(
204204
creator: bob,
205205
to: dummy_recipient,
206-
data_uri: "data:;rule=esip6," + mint_data.to_json
206+
data_uri: "data:," + mint_data.to_json
207207
)
208208
)
209209

@@ -212,7 +212,7 @@
212212
create_input(
213213
creator: charlie,
214214
to: dummy_recipient,
215-
data_uri: "data:;rule=esip6," + mint_data.to_json
215+
data_uri: "data:," + mint_data.to_json
216216
)
217217
) do |results|
218218
# TODO: Check contract state - mint should be rejected
@@ -234,7 +234,7 @@
234234
create_input(
235235
creator: alice,
236236
to: dummy_recipient,
237-
data_uri: "data:;rule=esip6," + invalid_format
237+
data_uri: "data:," + invalid_format
238238
)
239239
) do |results, stored|
240240
# The token regex requires exact format with no extra spaces
@@ -259,7 +259,7 @@
259259
create_input(
260260
creator: alice,
261261
to: dummy_recipient,
262-
data_uri: "data:;rule=esip6," + uppercase_tick.to_json
262+
data_uri: "data:," + uppercase_tick.to_json
263263
)
264264
)
265265
end
@@ -277,7 +277,7 @@
277277
create_input(
278278
creator: alice,
279279
to: dummy_recipient,
280-
data_uri: "data:;rule=esip6," + long_tick.to_json
280+
data_uri: "data:," + long_tick.to_json
281281
)
282282
)
283283
end
@@ -295,7 +295,7 @@
295295
create_input(
296296
creator: alice,
297297
to: dummy_recipient,
298-
data_uri: "data:;rule=esip6," + negative_max.to_json
298+
data_uri: "data:," + negative_max.to_json
299299
)
300300
)
301301
end
@@ -313,7 +313,7 @@
313313
create_input(
314314
creator: alice,
315315
to: dummy_recipient,
316-
data_uri: "data:;rule=esip6," + leading_zero.to_json
316+
data_uri: "data:," + leading_zero.to_json
317317
)
318318
)
319319
end
@@ -333,7 +333,7 @@
333333
create_input(
334334
creator: alice,
335335
to: dummy_recipient,
336-
data_uri: "data:;rule=esip6," + token_data.to_json
336+
data_uri: "data:," + token_data.to_json
337337
)
338338
) do |results|
339339
ethscription_id = results[:ethscription_ids].first
@@ -367,7 +367,7 @@
367367
create_input(
368368
creator: alice,
369369
to: dummy_recipient,
370-
data_uri: "data:;rule=esip6," + deploy_data.to_json
370+
data_uri: "data:," + deploy_data.to_json
371371
)
372372
)
373373

@@ -385,7 +385,7 @@
385385
create_input(
386386
creator: bob,
387387
to: dummy_recipient,
388-
data_uri: "data:;rule=esip6," + mint_data.to_json
388+
data_uri: "data:," + mint_data.to_json
389389
)
390390
)
391391
end
@@ -407,7 +407,7 @@
407407
create_input(
408408
creator: charlie,
409409
to: dummy_recipient,
410-
data_uri: "data:;rule=esip6," + mint_data.to_json
410+
data_uri: "data:," + mint_data.to_json
411411
)
412412
) do |results|
413413
# TODO: Check that mint was rejected
@@ -432,7 +432,7 @@
432432
create_input(
433433
creator: alice,
434434
to: dummy_recipient,
435-
data_uri: "data:;rule=esip6," + deploy_data.to_json
435+
data_uri: "data:," + deploy_data.to_json
436436
)
437437
)
438438

@@ -453,7 +453,7 @@
453453
create_input(
454454
creator: bob,
455455
to: bob, # Mint to Bob so he owns the ethscription and can transfer it
456-
data_uri: "data:;rule=esip6," + mint_data.to_json
456+
data_uri: "data:," + mint_data.to_json
457457
)
458458
)
459459

@@ -505,4 +505,4 @@
505505
# # Get information about a specific mint
506506
# # TODO: Implement when contract is available
507507
# end
508-
end
508+
end

0 commit comments

Comments
 (0)