nft.storage
nft.storage copied to clipboard
Upload via UCAN token receives 500 with code: TypeError "Cannot read properties of null (reading 'split')"
Trying to upload a file with
curl --verbose -X POST \
-H "Authorization: Bearer $API_TOKEN" \
-H 'accept: application/json' \
-H 'Content-Type: */*' \
-H "x-agent-did: $DID" https://api.nft.storage/upload \
--data-binary '@x'
fails when
xis a local file called x containing 2 characters$DIDis the one registered with the normal API key with thePOST user/didendpoint$API_TOKENis the$UCAN_TOKENtoken issued via the steps below
When $API_TOKEN is swapped with the normal API key $STORAGE_API_KEY the token is linked to this works fine
Failing UCAN Token Creation
Step 1 - Make API Key
Login to the NFT.storage site and generate a standard API token called $STORAGE_API_KEY
Step 2 - Make Keys
Use the ucan-storage keypair command to make a primary keypair mapped to the following new variables
> npx ucan-storage keypair
DID: $DID
Public Key: $PUBLIC_KEY
Private Key: $PRIVATE_KEY
Step 3 - Link the new Keypair with the API token
> curl -X POST \
-H "Authorization: Bearer $STORAGE_API_KEY" \
-H 'Content-Type: application/json' \
--data "{\"did\": \"$DID\"}" \
https://api.nft.storage/user/did
{"ok":true,"value":"$DID"}
Step 4 - Issue own primary long lasting token and receive $UCAN_TOKEN
> npx ucan-storage ucan \
--audience $DID \
--with $DID \
--can 'upload/*' \
--expiration 2099-04-20 \
--issuer $PRIVATE_KEY
{
"aud": "$DID",
"att": [
{
"with": "storage://$DID",
"can": "upload/*"
}
],
"exp": 4080326400,
"iss": "$DID",
"prf": [
null
]
}
UCAN:
$UCAN_TOKEN
Step 5
Try to upload a file with the new UCAN token
> curl --verbose -X POST -H "Authorization: Bearer $UCAN_TOKEN" -H 'accept: application/json' -H 'Content-Type: */*' -H "x-agent-did: $DID" https://api.nft.storage/upload --data-binary '@x'
* Trying 104.x.x.x:443...
* Connected to api.nft.storage (104.x.x.x) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/cert.pem
* CApath: none
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* (304) (IN), TLS handshake, Unknown (8):
* (304) (IN), TLS handshake, Certificate (11):
* (304) (IN), TLS handshake, CERT verify (15):
* (304) (IN), TLS handshake, Finished (20):
* (304) (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / AEAD-AES256-GCM-SHA384
* ALPN, server accepted to use h2
* Server certificate:
* subject: C=US; ST=California; L=San Francisco; O=Cloudflare, Inc.; CN=nft.storage
* start date: Dec 9 00:00:00 2021 GMT
* expire date: Dec 8 23:59:59 2022 GMT
* subjectAltName: host "api.nft.storage" matched cert's "*.nft.storage"
* issuer: C=US; O=Cloudflare, Inc.; CN=Cloudflare Inc ECC CA-3
* SSL certificate verify ok.
* Using HTTP2, server supports multiplexing
* Connection state changed (HTTP/2 confirmed)
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* Using Stream ID: 1 (easy handle 0x7f7e3480ca00)
> POST /upload HTTP/2
> Host: api.nft.storage
> user-agent: curl/7.84
> authorization: Bearer $UCAN_TOKEN
> accept: application/json
> content-type: */*
> x-agent-did: $DID
> content-length: 3
>
* We are completely uploaded and fine
* Connection state changed (MAX_CONCURRENT_STREAMS == 256)!
< HTTP/2 500
< date: Fri, 26 Aug 2022 05:08:07 GMT
< content-type: application/json;charset=UTF-8
< content-length: 102
< access-control-allow-origin: *
< expect-ct: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
< server: cloudflare
< cf-ray: 740a0c3c18b022d8-HKG
< alt-svc: h3=":443"; ma=86400, h3-29=":443"; ma=86400
<
* Connection #0 to host api.nft.storage left intact
{"ok":false,"error":{"code":"TypeError","message":"Cannot read properties of null (reading 'split')"}}
Step 6
Also tried using this token as a parent token and issuing child tokens through the CLI and the JS SDK but received the same error message.
I created a child token in the CLI like this:
> npx ucan-storage ucan \
--audience $DID \
--with storage://$DID \
--can 'upload/*' \
--expiration 2099-04-20 \
--issuer $PRIVATE_KEY \
--proof $UCAN_TOKEN
{
"aud": "$DID",
"att": [
{
"with": "storage://$DID",
"can": "upload/*"
}
],
"exp": 4080326400,
"iss": "$DID",
"prf": [
"$UCAN_TOKEN"
]
}
UCAN:
$CHILD_UCAN_TOKEN
to include a proof but the result is the same
Not 100% sure here, but I think what's going on is that the token you create in Step 4 should have a token from the nft.storage service's /ucan/token endpoint in its proof chain (the prf array).
If you request a token from /ucan/token and pass it to the --proof flag when creating your token, that should hopefully work. Please let us know either way - if it does work, we at least need to update our error messages in the case where you use a token without any proofs.
Closing as this ticket is over 1 year old. If you still need support, please re-open this issue and provide more detail. Thanks!