ord icon indicating copy to clipboard operation
ord copied to clipboard

Add documentation to clarify that inscriptions are served from /content/<INSCRIPTION_ID>

Open Vanniix opened this issue 11 months ago • 16 comments

Closes #2903 Closes #3208

Adds a few lines to the documentation to make it clear that inscriptions are served from /content/<INSCRIPTION_ID>. Many inscriptions rely on this fact to get their own inscription ID, so it is important that this is properly documented so we know we can rely on this.

Also added clarification regarding the url of inscriptions that have delegates. Happy to remove this if people think it is implicit in the other sentences, but since ord.io is currently making this mistake, I thought it is better to clarify.

Also added an example for how inscriptions can self reference and fetch their own inscription ID. Also happy to remove this, as it isn't directly about the protocol, but rather how to use it. But a lot of people ask how to do this, so having it in the handbook would be helpful.

Vanniix avatar Mar 02 '24 23:03 Vanniix

Looks great!

lifofifoX avatar Mar 03 '24 13:03 lifofifoX

It would also be helpful if the handbook documented that the content-type and content-encoding are delegated along with the body when delegating.

Some sites don't implement this. If you view a delegate inscription on MagicEden it won't display correctly unless the delegate inscription has its own copy of the content-type tag, which is obviously wasteful.

gmart7t2 avatar Mar 03 '24 18:03 gmart7t2

It is too opinionated to make it part of the protocol that when you build a client an inscription needs to "retrieve its own inscription ID from window.location.pathname". Not a fan of this PR. People should be able to build clients however they want as long as they implement the recursive endpoints. If people want to self reference then add a recursive endpoint. We should not start mandating that clients implement very specific arbitrary client side code to match ordinals dot com.

leonidasord avatar Mar 03 '24 20:03 leonidasord

Thanks for the feedback @leonidasord. I actually agree with you. I made similar comments towards the end of the issue I raised about this: #3208. But after talking with a few people, I feel like the pathname is the only option for self referencing.

A self endpoint is a great idea in principle, but I don't see how it would work in practice. If the server receives a request to /r/self, how on earth does it know which inscription is requesting it, and how does it know what payload to send back? None of the endpoints so far are context dependent. They all have every piece of information they need in the path, but an /r/self would need some extra context (the id of the requesting inscription) and I can't see how it would get this. If anyone has any ideas about how to achieve this, I would love to know, because I prefer the idea of a self endpoint too.

I know that dictating the structure of the url is not ideal, but I think it's important we work out some way to self reference. Without it, you can't make dynamic/recursive collections with delegates (unless every item is identical), and for certain projects, this would be a significant cost saving.

Would love to hear other proposals for how inscriptions can self reference.

Vanniix avatar Mar 03 '24 22:03 Vanniix

@leonidasord Problem is, server would have no way of figuring out what self is for the recursive endpoint you're proposing. Only workaround is using HTTP Referral field, which would defeat the purpose.

lifofifoX avatar Mar 03 '24 22:03 lifofifoX

What I am imagining is a /self recursive endpoint where all it does is return the inscription ID of the inscription that is calling it. This can happen completely client side. I haven't thought through the edge cases very hard though like if you recursively bring in an inscription and that inscription uses /self the client would need to know to give it its id still.

What are the best reasons for why this wouldn't work?

The alternative of calling window like this and relying on clients implementing several things a specific way for that to work feels overly constraining to devs. If for some reason it doesn't end up making sense to do the /self endpoint client side idea I would like to see an improved version of this PR that mandates that all clients attach an object with a specific set of key value pairs to the window that includes the inscription id so that there is a very clear spec for for developers to implement. The current form of this PR is yucky to me because it's basically telling devs they have to structure their client a very specific way in order for people to do this hacky window call. If we are going to do the window call just make devs be required to provide a specific set of data in an object and that is all.

leonidasord avatar Mar 03 '24 22:03 leonidasord

/self recursive endpoint where all it does is return the inscription ID of the inscription that is calling it.

As I said, the caller of /self would have to pass the inscription ID along with the request in order for the ord server to know what self is.

lifofifoX avatar Mar 03 '24 22:03 lifofifoX

Yeah, I'm not sure having the /self endpoint completely client side is possible. The client can't intercept certain routes and handle them client side (that I know of), all requests will automatically go to the server, and the server won't be able to handle self requests.

I do like the idea of injecting some global object into the window/iframe though. Depending on how it is designed, it may be possible that the inscription code runs before the global object is set, so you may also need to fire an event to indicate it's been set, and the inscription code can listen for the event. Similar to the design pattern used for the DOMContentLoaded event. i.e. You might do the following in an inscription (if the global var is called inscription)

if (window.inscription === undefined) {
  document.addEventListener("InscriptionDataLoaded", () => console.log(window.inscription))
} else {
  console.log(window.inscription)
}

The variable would need to be called something non-obvious though. If we chose a name that an existing inscription is already using as a global variable, then that inscription would break, because we just overwrote it with something it wasn't expecting. Maybe add a couple of underscores or something like that (i.e. __inscription)

Vanniix avatar Mar 04 '24 01:03 Vanniix

@Vanniix Seems very convoluted for explorers to inject the state like that into 3rd party content, just in order to avoid relying on specific URL paths.

"Recursion" is essentially a CSP directive, which is a very web/HTTP specific thing. I am not sure why protocol cannot take a position on how content/preview URLs must look like, considering all recursive endpoints are tied to specific URLs + the fact that using window.location.pathname has been officially suggested by the protocol team numerous times.

lifofifoX avatar Mar 04 '24 01:03 lifofifoX

inscription ID from window.location.pathname". Not a fan of this PR. People should be able to build clients however they want as long as they implement the recursive endpoints. If people want to self reference then add a recursive endpoint. We should not start mandating that clients implement very specific arbitrary client side code to match ordinals dot com.

I agree this PR is to specific should not enforce any examples of front end implementation. The intent of the issue that raised this PR was that its clear from the rules of recursion and prior that an inscription is returned from a server using the /content/:id.

From the handbook this just needs updating to be more explicit that it needs to be returned from /content/ that is all:

The inscription content model is that of the web. An inscription consists of a content type, also known as a MIME type, and the content itself, which is a byte string. This allows inscription content to be returned from a web server, and for creating HTML inscriptions that use and remix the content of other inscriptions.

elocremarc avatar Mar 04 '24 03:03 elocremarc

It would also be helpful if the handbook documented that the content-type and content-encoding are delegated along with the body when delegating.

@gmart7t2, yep, good point. delegate.md does actually mention the content type, but doesn't mention the content encoding, so I added that in there too

Vanniix avatar Mar 04 '24 05:03 Vanniix

The more I think about this the less I like my ideas of a client-side /self endpoint or appending an object to window. Yall are making good points. I also agree that it would be very helpful for inscriptions to be able to know their ID. All of that said it still feels yucky to me to make it part of the Ordinals protocol that for the next 100 years clients have to support allowing people to call window.location.pathname to parse out the inscription id. Maybe that is the best option though if we decide inscriptions need to be self aware of the id.

leonidasord avatar Mar 04 '24 05:03 leonidasord

The more I think about this the less I like my ideas of a client-side /self endpoint or appending an object to window. Yall are making good points. I also agree that it would be very helpful for inscriptions to be able to know their ID. All of that said it still feels yucky to me to make it part of the Ordinals protocol that for the next 100 years clients have to support allowing people to call window.location.pathname to parse out the inscription id. Maybe that is the best option though if we decide inscriptions need to be self aware of the id.

This is a similar conclusion to what I came to as well, initially I wasn’t a fan of it not being fully contained within the inscription as it does feel a little hacky but the benefits of self referencing would unlock a lot of cool development and it seems like there aren’t many better options.

Unless @rot13maxi @casey or @raphjaph have any ideas on cleaner ways to achieve an inscription self referencing?

sanjfomojis avatar Mar 04 '24 05:03 sanjfomojis

Yeah, I think we are agreed on this @leonidasord. I have felt for a long time that getting the id from the url felt "wrong" in some way, but since everyone was doing it, I just went along with it. It would be awesome to have a better solution, but I can't think of anything better. The idea of adding a global object would work, but as @devords mentions, its convoluted, and ultimately it has similar problems to the url in that it relies on the client doing something specific. I think the url is just the simplest option to self reference even if it does lock explorers into a specific front end implementation

It's probably also going to be the case that ordinals implementations will find it easier and simpler to just use include the id in the url than adding an extra endpoint or doing some other complex workaround.

Vanniix avatar Mar 04 '24 05:03 Vanniix

The more I think about this the less I like my ideas of a client-side /self endpoint or appending an object to window. Yall are making good points. I also agree that it would be very helpful for inscriptions to be able to know their ID. All of that said it still feels yucky to me to make it part of the Ordinals protocol that for the next 100 years clients have to support allowing people to call window.location.pathname to parse out the inscription id. Maybe that is the best option though if we decide inscriptions need to be self aware of the id.

There really isn't a better way than the url, which is already mandated to work for the /inscription/ endpoint anyways because of recursion. Stateless web means the server can't know the inscription id of the caller without passing it first (cookie, header, injecting into content, etc), and any other way of client getting it is messier for server to push it.

While it would be nice to store a delegate once on say a CDN....there you are also stuck in that you still have a way to inject the id in the response, url or otherwise.

So - if the key problem with a site like ord.io is the CDN duplication - maybe they have a way to push a alt/vanity url of some type that doesn't redirect but returns the content stored another place from more than one endpoint?

This might be what is needed to achieve unique inscription urls for delegates on ord.io @leonidasord https://vercel.com/docs/edge-network/rewrites

thinginab avatar Mar 26 '24 22:03 thinginab

I've thought of one solution that may sound convoluted at first but it avoids URLs and feels more self-contained. It's similar to the method I'm using currently (passing target sat number via JS) but would be much more efficient. You could implement a special type of delegation whereby a tiny "sat_number:reinscription_point" file/metadata is inscribed for each batch/delegated inscription. The inscriber would need to inscribe onto specific sats, but this is fairly straightforward with batch inscribing, and could even be coded into the batch process behind the scenes, so that the inscriber doesn't need to think/plan it out. That way each inscription knows which sat it's on and which reinscription it is on that sat. It should only be a few extra bytes per inscription.

e.g. I inscribe on sat range 10000 to 20000 and set postage to 500. Inscription 1 is passed "10000:0", Inscription 2 is passed "10500:0" etc. The number after the colon designates reinscription number, so this would be incremented if inscriptions already exist on the sat. Ord still delegates the inscriptions to the delegation target (is there a proper name for this? [Edit: guess it's called the "delegate" but it's confusing when the verb is the same as the noun for the thing not doing the verb!]), but it passes along the sat_number:reinscription_point data that can be read via an endpoint. Then the inscriptions can refer to themselves using /r/sat/SAT_NUMBER/at/REINSCRIPTION_POINT.

In short, ord knows which sats it's inscribing on, so it attaches that sat number to each delegated inscription at the time of inscribing. The delegation target then uses this data to identify each inscription. Thoughts?

ZedZeroth avatar Apr 11 '24 21:04 ZedZeroth