Re: Nostrscript/Nostr Extensions spec and ABI

> On 15 Jul 2023, at 21:10, William Casarin <jb55@jb55.com> wrote:
> 
> On Mon, Jul 10, 2023 at 08:29:44PM +0300, Semisol wrote:
>>>> On 10 Jul 2023, at 18:24, William Casarin <jb55@jb55.com> wrote:
>>> 
>>> On Mon, Jul 10, 2023 at 06:19:34PM +0300, Semisol wrote:
>>>> 
>>>> … snipped …
>>>> My ABI exposes one import per command (I recommend you read it if you did not yet), which has some advantages, compared to a single interface:
>>>> 
>>>> * You can know what a module can do beforehand, and modules that use
>>>> unsupported features will never be able to load, which helps
>>>> simplify development
>>>> * You still get to retain the typing on arguments
>>> 
>>> Can you link or ideally mail it as a patch(set) for review? Then I would
>>> be able to respond inline here to comment on it.
>> Here you go:
>> # Types
>> - `u32`: Unsigned 32 bit integer.
>> - `i32`: Signed 32 bit integer.
>> - `u64`: Unsigned 64 bit integer.
>> - `i64`: Signed 64 bit integer.
>> - `usize`: Unsigned size, same as `u32`.
> 
> why not just use u32 directly? is this planned to change?
The goal here was to in the future be able to adapt to Wasm64. It also helps with clarification of what is memory related

>> - `byte[n]`: An amount of bytes of length n.
>> - `discard`: Alias for `i32`, the application should discard the value.
> 
> This is strange to me, this isn't a wasm thing. wouldn't you just not
> push a value on the stack if you don't want a return value?
Ah yeah I’ll remove that

>> NOTE: Unsigned integers must be converted to signed while passing *to* wasm and
>> must be converted back to unsigned when received *from* wasm.
> 
> why?

Unsigned integers don’t exist in wasm when returning, so it has to be manually converted

>> # Custom Sections
>> The custom section `nostr` SHOULD be present on a module, which is a JSON object containing the following properties:
>> - `name`: Module name
>> - `version`: Module version as SemVer
> 
> I never bothered with this because I figured this meta information could
> be included in a new nostr note type so that it can be covered by
> publisher's signature. Then a hash of the wasm binary could be signed,
> with the blob hosted elsewhere or in a note itself if its small enough.
I think having it be self contained is better than having to look up a note for this information. You can easily load from a file and don’t have to publish a note 

>> # Structs
>> 
>> ### ByteBuf
>> - `usize`: length
>> - `byte[length]`: the actual data
>> 
>> ### String
>> - `usize`: length
>> - `byte[length * 2]`: string data, encoded in UTF-16 LE
> 
> I absolutely hate the utf-16 representation but it seems assemblyscript
> forces it on us due to legacy javascript reasons =/
> 
> I would create my own script that doesn't make strings like this if I
> had the time.
AS strings are just another class so you can implement your own string class

>> Adds timer functionality.
>> 
>> ### Export: `nostr_timer__tick(): u32`
>> If this function exists, this should be called every second.
>> Returns 0 if it succeeded, 1 otherwise.
> 
> Do you have examples on what you would use this for?
You can probably clean up some temporary state with this, but it isn’t that necessary so I will remove it.

>> 
>> ## nostr_persist
>> 
>> Adds persistence functionality.
>> 
>> ### Import: `nostr_persist__persist_ephemeral(usize ptr): discard`
>> The application should call this function when it wants to persist "ephemeral" data, such as state, through a reinstantiation, but not through an app reload/restart. This data should not be persisted after the app restarts or the module is restarted.
>> 
>> ### Export: `nostr_persist__load_ephemeral(usize ptr): u32`
>> Loads the given `ByteBuf` that was previously persisted using persist_ephemeral upon module instantiation.
>> Returns 0 if it succeeded, 1 otherwise.
>> 
>> ### Import: `nostr_persist__persist(usize ptr): discard`
>> The application should call this function when it wants to persist data. The ptr should point to a ByteBuf.
>> 
>> ### Export: `nostr_persist__load(usize ptr): u32`
>> Loads the given `ByteBuf` that was previously persisted using persist upon module instantiation.
>> Returns 0 if it succeeded, 1 otherwise.
> 
> Do you have examples that use these? just trying to understand what this
> is for
The ephemeral part is for __reinstantiate, which helps reset the wasm memory since you cannot shrink it right now. This is so that you can transfer say relay connection handles through a reinstantiate.

The persistent part could be used to store state. Currently it’s useful only in a few cases, but in the future I think it would be a good idea to have some way to have module settings etc.

>> ## nostr_filter
>> 
>> Adds filtering functionality.
>> 
>> ### Export: `nostr_filter__filter(Event event): u32`
>> Should return 0 if this post should not be filtered, any other value otherwise. The value is used to convey why filtering was done.
>> - `1`: Generic
>> - `2`: Spam
> 
> nice! I guess the app can just detect this export and assume the module has filtering capabilities?
yeah. the capabilities and permissions a module has is strictly defined by what it imports or exports 

Received on Sunday, 16 July 2023 16:17:38 UTC