hzrd149 / blossom-client-sdk

A simple client for managing blobs on blossom servers
https://hzrd149.github.io/blossom-client-sdk/
MIT License
6 stars 2 forks source link

TypeError: signer is not a function in BlossomClient.getUploadAuth() #2

Open Sebastix opened 3 months ago

Sebastix commented 3 months ago

When I try to create an upload aut event, the following errors returns:

Uncaught (in promise) TypeError: signer is not a function
    at _BlossomClient.getUploadAuth (blossom-client-sdk.js?v=e943c541:568:18)
    at Proxy.getUploadAuth (blossom-client-sdk.js?v=e943c541:611:33)

I'm using NDK 2.8.1 and blossom-client-sdk version 0.5.1 here in nuxstr trying to upload a blob with a signed upload event: https://nuxstr.nostrver.se/blossom Source code: https://github.com/Sebastix/nuxstr/blob/master/pages/blossom.vue#L42

My browser is Brave and I'm using the nos2x browser extension as a signer.

The code of this logic which return the error is, please have a look at the comments which methods I've tried:

  try {
    // Trigger input file element
    const inputFile = document.createElement('input')
    inputFile.type = 'file'
    inputFile.click()
    inputFile.onchange = async e => {
      const file = e.target.files[0]
      // Create and sign an upload event with NDK
      const uploadEvent = new NDKEvent(NdkStore.ndk)
      uploadEvent.kind = 24242
      uploadEvent.created_at = Math.floor(Date.now() / 1000)
      uploadEvent.pubkey = UserStore.pubkey
      uploadEvent.content = 'Upload ' + file.name
      uploadEvent.tags = [
        ['t', 'upload'],
        ['name', file.name],
        ['size', file.size]
      ]
      console.log(uploadEvent)
      const signedEvent = await uploadEvent.sign(NdkStore.ndk.signer)
      console.log(signedEvent)

      // @todo work in progress uploading a blob
      //const uploadAuthEvent = await BlossomClientRef.value.getUploadAuth(file, 'Upload ' + file.name)
      /**
       * Error:
       * Uncaught (in promise) TypeError: signer is not a function
       *     at _BlossomClient.getUploadAuth (blossom-client-sdk.js?v=e943c541:568:18)
       *     at Proxy.getUploadAuth (blossom-client-sdk.js?v=e943c541:611:33)
       *     at inputFile.onchange (blossom.vue:65:60)
        */
      const res = await BlossomClientRef.value.uploadBlob('https://nstore.nostrver.se', file)
      // Error without uploadAuthEvent: 500 internal server error response from the server 'Something went wrong'
      // Error with uploadAuthEvent: see above, signer is not a function
      console.log(res)

      // encode it using base64
      //const encodedAuthHeader = const encodedAuthHeader = "Nostr " + btoa(signedEvent)
      //const res = await fetch(new URL("/upload", 'https://nstore.nostrver.se'), {
      //  method: "PUT",
      //  body: file,
      //  headers: { authorization: encodedAuthHeader },
      //});
      //Error: see above, signer is not a function
      //console.log(res)
      //if (res.ok) {
      //  // @todo reload list with blobs after successful upload
      //}
    }
  } catch (e) {
    console.log(e)
    alert(e)
  }

Also the manual way for uploading a blob is not working, a 500 is returned from https://nstore.nostrver.se. What I'm missing out while creating and signing the event? @hzrd149

When I connect the server to https://blossom.hzrd149.com/, everything works as expected when I upload a blob via that client.

hzrd149 commented 3 months ago

I don't know what BlossomClientRef.value refers to but there are two uploadBlob methods in the library.

if your using new BlossomClient then you have to either pass a signer in when the instance is created or manually pass the auth event when calling the uploadBlob method https://hzrd149.github.io/blossom-client-sdk/classes/BlossomClient.html#uploadBlob

async function signer(event) {
  return await window.nostr.signEvent(event);
}

const client = new BlossomClient('https://nstore.nostrver.se/', signer)

// this will try to call signer to sign an auth event
client.uploadBlob(file)
// or
client.uploadBlob(file, customAuth)

If your using the static method BlossomClient.uploadBlob then you have to construct the auth event manually and pass it in https://hzrd149.github.io/blossom-client-sdk/classes/BlossomClient.html#uploadBlob-2

const auth = {...}
const signed = await window.nostr.signEvent(auth)

await BlossomClient.uploadBlob("https://nstore.nostrver.se/", file, signed)
Sebastix commented 3 months ago

In my code BlossomClientRef is a Vue ref :) Vue refs documentation: https://vuejs.org/guide/essentials/reactivity-fundamentals.html#ref

It's working now :)

Using the uploadBlob() method I've added the signer function and attached it to the BlossomClient when it's initialized.

const uploadAuthEvent = await BlossomClientRef.value.getUploadAuth(file, 'Upload ' + file.name)
const resBC = await BlossomClientRef.value.uploadBlob(file, uploadAuthEvent)
// and yes, this also works:
await BlossomClientRef.value.uploadBlob(file)

Now works as expected :)

NDK + Javascript method (which I prefer) As I'm constructing the auth event with NDK, I needed to use uploadEvent.toNostrEvent() to get a valid JSON object for the methods. With the JS fetch method it now works to upload a file:

const uploadEventToJSON = await uploadEvent.toNostrEvent() // uploadEvent is a NDKEvent object here
const res = await fetch('https://nstore.nostrver.se/upload', {
    method: "PUT",
    body: file,
    headers: { authorization: "Nostr " + btoa(JSON.stringify(uploadEventToJSON)) },
});

Your example at https://github.com/hzrd149/blossom-server/blob/master/public/index.html also helped me figuring out what I was missing.

The update I've just pushed: https://github.com/Sebastix/nuxstr/commit/83ba928e40c4800288b867a15350069e3afd5630#diff-8b4e022d7b2211fa2207cbe8323e0609c03238efcc9f326aef04cba89175d12f