wrap-cli
wrap-cli copied to clipboard
allow wrappers to know about their URIs
We should allow a wrapper to know about its URI.
~~Canonical uri of the wrapper should be read from wrap.info during codegen and exported as a constant in the bindings~~ ~~Also see polywrap/technical-council#69~~
We can pass an InvokeContext on every invoke
, and invocables will have access to their and their caller's URI and perhaps more metadata in the future.
This will require an update to the invocation standard.
// wrapper
import { InvokeContext } from "./wrap";
function getThisUri() {
InvokeContext.callerUri();
}
// wrapper bindings
InvokeContext {
callerUri() {
buffer = "thisUri".to_buf();
__wrap_invoke_context_get_prop_size(&buffer, buffer.size) => value_size
value = new Buffer(value_size)
__wrap_invoke_context_load_prop(&value, value.size) => boolean
value.to_str() // "wrap://..."
}
}
// plugin bindings
interface InvokeContext {
contextId: string;
callerUri?: Uri;
thisUri: Uri;
}
interface PluginContext extends InvokeContext {
client: Client;
}
abstract pluginMethod(
args: Args_pluginMethod,
context: PluginContext
): MaybeAsync<type>;
I don't think wrap.info should contain URI information. Instead we could add this info at resolution time in the client, so that the Wrapper class knows about it's URI
Left a comment here: https://github.com/polywrap/technical-council/issues/69#issuecomment-1211143701
I think the best way to do this is to allow wrappers to use their current URI within their code. For example, this.uri
inside of a wasm wrapper.
I think we could maybe replace the current method name, and args with Context This means it'd be preencoded. Also, when talking about wrapper URI and caller URI we need to know about which URIs we're referring to and which to add to the context:
- A wrapper can have multiple URIs (ens -> ipfs) are we treating the final URI as the wrapper URI or the origin one before URI resolution? Are we also including all the redirects during resolution?
- Same thing for the caller URI, which of those URIs is the "caller"?
I think we could maybe replace the current method name, and args with Context
Preencoding context along with the args is a good point. I don't know what's cleaner, to pass this type separately or with the args. Either way we should consider that in the future we might pass additional metadata with the context, e.g. instance id for concurrency management.
are we treating the final URI as the wrapper URI or the origin one before URI resolution?
The final URI is "closer" to the invocable instance, but it might be inconsistent with URI usage in the rest of the app.
I'd say the original "canonical" URI of caller
and this
is sufficient, because any call to that URI would follow the redirects and resolve properly anyways.
In other words, if an invoker calls client.invoke({uri: "ens/wrapper.eth", method, args})
, the invocable should always receive "ens/wrapper.eth" as InvokeContext.thisUri
.
Are we also including all the redirects during resolution?
Do we need the resolution history in the Context if it is already accessible via the client plugin?
Okay after doing more thinking about this here's what I'm thinking:
- Wrappers can indeed have multiple URIs (ex:
domain.eth
->ipfs/QmHASH
) - We want to support 2 ways of accessing the wrapper's URI:
- Get the canonical "uri" which is the ending URI of the URI resolution path (i.e.
ipfs/QmHash
) - Get the URI resolution path, so you can see what other URIs are associated with this wrapper
- Get the canonical "uri" which is the ending URI of the URI resolution path (i.e.
- We do not want to do a "push" model here, where we push this URI data into every wasm wrapper by default.
- We should support a "pull" interface, where a wrapper can get (1) and (2) described above.
Some psuedo code for what this might look like (in AssemblyScript):
import { URIs } from "./wrap";
// get the final URI: "wrap://ipfs/QmHASH"
URIs.this();
// get the URI resolution: ["wrap://ens/domain.eth", "wrap://ipfs/QmHash"]
URIs.path()
Another name for URIs
could be UriResolution
or UriResolver
. Thoughts @fetsorn @nerfZael ?
NOTE: the above solution does not account for "parallel paths" where you may have multiple URI resolution paths that point to the same resulting URI. Example:
ens/a.eth -> ipfs/QmHash
ens/b.eth -> ipfs/QmHash
Could be solved by simply changing path()
to paths()
, or even supporting both methods.
@fetsorn @ramilexe can you please explain the OmniBlocks use-case that requires this feature? It will make it easier to know how to best support it.
One cool things about this feature is that it would enable recursive wrapper calls.
For example, the IPFS resolver wrapper uses two wrappers and a plugin for parallel resolution requests.
sync call: wrapper_a --> wrapper_b async call: wrapper_a --> concurrency plugin --> wrapper_b
But if it knew its own URI, it could call its own implementation of the ipfs cat method.
sync call: wrapper_a async call: wrapper_a --> concurrency plugin --> wrapper_a
:100: agreed, this is hyper useful for concurrent calls to a wrapper's own exported functions.