Coder Social home page Coder Social logo

fleekhq / space-sdk Goto Github PK

View Code? Open in Web Editor NEW
194.0 21.0 22.0 6.63 MB

The Space SDK is a JavaScript/Typescript library for building web and mobile applications leveraging Open Web and distributed protocols like IPFS, Textile, GunDB, and Ethereum.

Home Page: https://fleekhq.github.io/space-sdk/docs/

License: MIT License

HTML 0.21% TypeScript 94.86% JavaScript 4.35% CSS 0.37% Shell 0.21%
storage filecoin textile ipfs gundb sdk

space-sdk's Introduction

Space SDK

Fleek Dev Slack License

Javascript/Typescript library for interacting with Space in web/browser applications via an implementation of the Space API. Build websites or applications that can easily leverage Open Web protocols (IPFS, Textile, GunDB, Ethereum) to enable Web3-ready features like:

  • File and directory storage / retrieval in user-controlled, encrypted, and distributed storage.
  • Key-pair based identity management and challenge-based authentication.
  • Decentralized and secure key and bucket metadata storage.
  • Private and end-to-end encrypted, or public file sharing.

The Space SDK is a close friend of the Space Daemon, its desktop-focused counterpart.

You can find the SDK's documentation here:

Default Implementations

The Space SDK is modular and protocol agnostic. You can use the APIs and interfaces as is, with Space's default implementations, or replace them with your own custom ones.

Feature Description Service/Protocol
Users Key-pair based identity creation, and challenge authentication. Textile Users API
Storage File, directory, and bucket creation/listing. IPFS / Textile
Metadata Secure Bucket/directory schema storage GunDB
Sharing Private and public file sharing Textile

Introduction

@spacehq/sdk provides a suit of functionality to perform different action on Space.

Installation

Install the sdk using this npm command:

npm install @spacehq/sdk

Usage

Space SDK provides an interface perform the following actions:

  • Creating identities

  • Create files and directories

  • List files and directories

  • Creating buckets

  • Sharing buckets

Full SDK Documentation with examples can be found here

1. Identities

This involves managing users and their identities.

import { Users } from '@spacehq/sdk';

const users = new Users({ endpoint: 'wss://dev.space.storage' });

// createIdentity generate a random keypair identity
const identity = await users.createIdentity();

// the new keypair can be used to authenticate a new user
// `users.authenticate()` generates hub API session tokens for the keypair identity.
const user = await users.authenticate(identity);
// `user` can be used with the storage class to provide identity.

// user's identity can also be backed up with a special recovery phrase
const uuid = 'specify-uuid-representing-user-in-your-system';
const passphrase = 'specify-unique-pass-phrase-related-to-backup-type';
const backupType = VaultBackupType.Google;
await users.backupKeysByPassphrase(uuid, passphrase, backupType, user.identity);

// backed up users identity can also be recovered later
const recoveredUser = await users.recoverKeysByPassphrase(uuid, passphrase, backupType);
// `recoveredUser` has same authentication as `user` above.

Check the User's class for more examples of how to manage users with the sdk.

2. Storage

This involves operations to create and list files and directories in space storage.

import { UserStorage, AddItemsResultSummary } from '@spacehq/sdk';

const storage = new UserStorage(user);
await storage.createFolder({ bucket: 'personal', path: 'topFolder' });
const result = await storage.listDirectory({ bucket: 'personal', path: '' });
// result contains `topFolder` items

// upload a file
const uploadResponse = await spaceStorage.addItems({
   bucket: 'personal',
   files: [
     {
       path: 'file.txt',
       content: '',
     },
     {
       path: 'space.png',
       content: '',
     }
   ],
});
// uploadresponse is an event listener
uploadResponse.once('done', (data: AddItemsEventData) => {
  const summary = data as AddItemsResultSummary;
  // returns a summary of all files and their upload status
});

3. Sharing

This includes operations to share your storage items with existing user (identities)

import { UserStorage } from '@space/sdk';

const storage = new UserStorage(user);

// you can share privately with existing users via their public key:
await storage.shareViaPublicKey({
    publicKeys: [{
      id: '[email protected]', // or any identifier for the user
      pk: 'user-pk-hex-or-multibase', // optional, omit if user doesn't exist yet, it would generate temp access key
    }],
    paths: [{
        bucket: 'personal',
        path: '/file/path/here'
    }],
});

// or you could share the file publicly by generating a link. Generated link references
await spaceStorage.setFilePublicAccess({
  bucket: 'personal',
  path: '/file.txt',
  allowAccess: true, // <- set to false to revoke public access
});

Migrating from Space Daemon

If you are already familiar with the space daemon and its gRPC methods and would like to start using the space-sdk here are some pointers on how those gRPC methods correspond to functionalities exposed by the space-sdk.

Key Pairs (GenerateKeyPair)

In the sdk the concept of Key Pairs is represented as an Identity. To create a new Identity similar to the GenerateKeyPair method, you would do:

import { Users, BrowserStorage } from '@spacehq/sdk';

const users = new Users({ endpoint: 'wss://auth-dev.space.storage' });

// createIdentity generate a random keypair identity
const identity = await users.createIdentity();

identity represents a keypair and its primary key is accessible via identity.public.toString().

Managing authenticated users

In space-daemon the generated keypair is stored in the operating systems keychain but in space-sdk you would need to provide an IdentityStorage to the Users class when initializing it. For the browser environment there exists a BrowserStorage implementation you can use.

import { Users, BrowserStorage } from '@spacehq/sdk';

const users = await Users.withStorage(
    new BrowserStorage(), 
    { endpoint: 'wss://auth-dev.space.storage' }
);

Users.withStorage will load and authenticate all identities that exist inside the provided IdentityStorage. You can access all authenticated users through the Users.list method.

const spaceUsers = await users.list();

To authenticate a new user identity and get a SpaceUser, you can call the Users.authenticate method:

const spaceUser = await users.authenticate(identity);

Users.authentication would do two things:

  • Generate a SpaceUser.
  • Stores the new users information in the IdentityStorage, so subsequent initialization of Users.withStorage() would have the users loaded.

NOTE: An existing space user can also be gotten from Users.recoverKeysByPassphrase.

To delete a user from users lists, you can delete the user by pass the publicKey of that user to Users.remove.

await users.remove(spaceUser.identity.public.toString());

Managing current active user

If you have the concept of a current active user in your application that uses space-sdk. We recommend that you keep track of that users public key in your application and use it to filter the list method's result to get the authenticated SpaceUser for that public key.

On logout, you can call the remove method to stop tracking the user.

GetAPISessionToken

In space daemon GetAPISessionToken returns the message:

message GetAPISessionTokensResponse {
  string hubToken = 1;
  string servicesToken = 2;
}

In order to get the servicesToken and hubToken for a particular user, you would need to authenticate that user identity:

const spaceUser = await users.authenticate(identity);

The spaceUser.token value is the servicesToken, while the spaceUser.storageAuth.token is the hubToken.

Also, note that when an existing user is recovered via the Users.recoverKeysByPassphrase method, the SpaceUser returns is also authenticated and has the session tokens.

GetPublicKey

In space daemon GetPublicKey returned the id of the current keypair in keychain, but since space-sdk returns the identity object. You can get the public key bytes for a particular identity through identity.public.pubKey.

Also, an authenticated SpaceUser identity can be found in the identity field.

Storage Methods (createFolder, listDirectory, openFile, addItems)

The storage gRPC methods on space daemon can now be performed using the UserStorage class of the space-sdk.

import { UserStorage, AddItemsResultSummary } from '@spacehq/sdk';

const storage = new UserStorage(user);
await storage.createFolder({ bucket: 'personal', path: 'topFolder' });
const result = await storage.listDirectory({ path: '' });
// result contains `topFolder` items

// upload a file
const uploadResponse = await spaceStorage.addItems({
   bucket: 'personal',
   files: [
     {
       path: 'file.txt',
       content: 'plain-text-value',
     },
     {
       path: 'space.png',
       content: '', // could also be a ReadableStream<Uint8Array> or ArrayBuffer
     }
   ],
});
// uploadresponse is an event listener
uploadResponse.once('done', (data: AddItemsEventData) => {
  const summary = data as AddItemsResultSummary;
  // returns a summary of all files and their upload status
});

// read content of an uploaded file
const fileResponse = await storage.openFile({ bucket: 'personal', path: '/file.txt'});
const fileContent = await fileResponse.consumeStream();
// new TextDecoder('utf8').decode(actualTxtContent) == 'plain-text-value'

Contributing

All contributions are welcome. Before getting started, kindly take some time to review our contributing guidelines and code of conduct.

LICENSE

MIT

space-sdk's People

Contributors

0xflotus avatar dmerrill6 avatar jsonsivar avatar perfectmak avatar qx-nico avatar samuelea avatar studna avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

space-sdk's Issues

module ready to use in browsers?

Hi,

first of all, I have to tell you: what a fantastic idea and what a great project.
Of course I wanted to try it out right away. However, I can't really get it to work.
I use NodeJS 14.16.0.
The install command only works like this:

npm install @spacehq/sdk --legacy-peer-deps

Otherwise I get the following error:

ERESOLVE overriding peer dependency
npm WARN Found: [email protected]
npm WARN node_modules/@spacehq/storage/node_modules/react
npm WARN   peer react@">=16.4" from @gooddollar/[email protected]
npm WARN   node_modules/@spacehq/storage/node_modules/@gooddollar/react-native-webview-crypto
npm WARN     peer @gooddollar/react-native-webview-crypto@"^0.*" from [email protected]
npm WARN     node_modules/@spacehq/storage/node_modules/gun
npm WARN 
npm WARN Could not resolve dependency:
npm WARN peer react@"17.0.1" from [email protected]
npm WARN node_modules/@spacehq/storage/node_modules/react-native
npm WARN   peer react-native@">=0.56" from @gooddollar/[email protected]
npm WARN   node_modules/@spacehq/storage/node_modules/@gooddollar/react-native-webview-crypto
npm WARN ERESOLVE overriding peer dependency
npm WARN Found: [email protected]
npm WARN node_modules/@spacehq/storage/node_modules/react-native
npm WARN   peer react-native@">=0.56" from @gooddollar/[email protected]
npm WARN   node_modules/@spacehq/storage/node_modules/@gooddollar/react-native-webview-crypto
npm WARN     peer @gooddollar/react-native-webview-crypto@"^0.*" from [email protected]
npm WARN     node_modules/@spacehq/storage/node_modules/gun
npm WARN 
npm WARN Could not resolve dependency:
npm WARN peer react-native@">=0.60 <0.62" from [email protected]
npm WARN node_modules/@spacehq/storage/node_modules/react-native-webview
npm WARN   peer react-native-webview@"^8.*" from @gooddollar/[email protected]
npm WARN   node_modules/@spacehq/storage/node_modules/@gooddollar/react-native-webview-crypto
npm WARN ERESOLVE overriding peer dependency
npm WARN Found: [email protected]
npm WARN node_modules/@spacehq/storage/node_modules/react
npm WARN   peer react@">=16.4" from @gooddollar/[email protected]
npm WARN   node_modules/@spacehq/storage/node_modules/@gooddollar/react-native-webview-crypto
npm WARN     peer @gooddollar/react-native-webview-crypto@"^0.*" from [email protected]
npm WARN     node_modules/@spacehq/storage/node_modules/gun
npm WARN 
npm WARN Could not resolve dependency:
npm WARN peer react@"16.9.0" from [email protected]
npm WARN node_modules/@spacehq/storage/node_modules/react-native-windows
npm WARN   peer react-native-windows@"^0.61.0-beta.58" from [email protected]
npm WARN   node_modules/@spacehq/storage/node_modules/react-native-webview
npm WARN ERESOLVE overriding peer dependency
npm WARN Found: [email protected]
npm WARN node_modules/@spacehq/storage/node_modules/react-native
npm WARN   peer react-native@">=0.56" from @gooddollar/[email protected]
npm WARN   node_modules/@spacehq/storage/node_modules/@gooddollar/react-native-webview-crypto
npm WARN     peer @gooddollar/react-native-webview-crypto@"^0.*" from [email protected]
npm WARN     node_modules/@spacehq/storage/node_modules/gun
npm WARN 
npm WARN Could not resolve dependency:
npm WARN peer react-native@"0.61.5" from [email protected]
npm WARN node_modules/@spacehq/storage/node_modules/react-native-windows
npm WARN   peer react-native-windows@"^0.61.0-beta.58" from [email protected]
npm WARN   node_modules/@spacehq/storage/node_modules/react-native-webview
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR! 
npm ERR! Found: [email protected]
npm ERR! node_modules/@spacehq/storage/node_modules/react
npm ERR!   peer react@">=16.4" from @gooddollar/[email protected]
npm ERR!   node_modules/@spacehq/storage/node_modules/@gooddollar/react-native-webview-crypto
npm ERR!     peer @gooddollar/react-native-webview-crypto@"^0.*" from [email protected]
npm ERR!     node_modules/@spacehq/storage/node_modules/gun
npm ERR!       gun@"^0.2020.520" from @spacehq/[email protected]
npm ERR!       node_modules/@spacehq/storage
npm ERR!         @spacehq/storage@"^0.0.30" from @spacehq/[email protected]
npm ERR!         node_modules/@spacehq/sdk
npm ERR! 
npm ERR! Could not resolve dependency:
npm ERR! peer react@"^16.9" from [email protected]
npm ERR! node_modules/@spacehq/storage/node_modules/react-native-webview
npm ERR!   peer react-native-webview@"^8.*" from @gooddollar/[email protected]
npm ERR!   node_modules/@spacehq/storage/node_modules/@gooddollar/react-native-webview-crypto
npm ERR!     peer @gooddollar/react-native-webview-crypto@"^0.*" from [email protected]
npm ERR!     node_modules/@spacehq/storage/node_modules/gun
npm ERR!       gun@"^0.2020.520" from @spacehq/[email protected]
npm ERR!       node_modules/@spacehq/storage
npm ERR! 
npm ERR! Fix the upstream dependency conflict, or retry
npm ERR! this command with --force, or --legacy-peer-deps
npm ERR! to accept an incorrect (and potentially broken) dependency resolution.

However, if I want to run it in my browser,

import { Users } from '@spacehq/sdk';

or

import { UserStorage, AddItemsResultSummary } from '@spacehq/sdk';

I always get the following error:

./node_modules/@spacehq/users/dist/identity/fileStorage.jsModule not found: Error: Can't resolve 'fs' in './node_modules/@spacehq/users/dist/identity'

When do you guys think you'll get this fixed? I am a bit excited because I really want to try this package and get it working.

Cheers

Error addItems setImmediate is not defined

code:

const users = new Users({ endpoint: 'wss://auth.space.storage' });
    const id = await users.createIdentity();
    const user = await users.authenticate(id);

    const storage = new UserStorage(user);
    await storage.createFolder({ bucket: 'personal', path: '' });

    const response = await storage.addItems({
      bucket: 'personal',
      files: [
        {
          path: 'file.txt',
          data: '',
          mimeType: 'plain/text',
        },
      ],
    });

    response.once('done', (data: AddItemsEventData) => {
      const summary = data as AddItemsResultSummary;
    });

Error:

- ERROR Error: Uncaught (in promise): ReferenceError: setImmediate is not defined
mDXs/</addItems/<@http://localhost:4200/vendor.js:231085:13
fulfilled@http://localhost:4200/vendor.js:230510:58
invoke@http://localhost:4200/polyfills.js:4777:30
onInvoke@http://localhost:4200/vendor.js:186616:33
invoke@http://localhost:4200/polyfills.js:4776:36
run@http://localhost:4200/polyfills.js:4536:47
scheduleResolveOrReject/<@http://localhost:4200/polyfills.js:5270:40
invokeTask@http://localhost:4200/polyfills.js:4812:35
onInvokeTask@http://localhost:4200/vendor.js:186603:33
invokeTask@http://localhost:4200/polyfills.js:4811:40
runTask@http://localhost:4200/polyfills.js:4580:51
drainMicroTaskQueue@http://localhost:4200/polyfills.js:4982:39
invokeTask@http://localhost:4200/polyfills.js:4897:25
ZoneTask/this.invoke@http://localhost:4200/polyfills.js:4882:52
timer@http://localhost:4200/polyfills.js:6965:33
setTimeout handler*scheduleTask@http://localhost:4200/polyfills.js:6986:39
scheduleTask@http://localhost:4200/polyfills.js:4798:30
onScheduleTask@http://localhost:4200/polyfills.js:4685:69
scheduleTask@http://localhost:4200/polyfills.js:4791:55
scheduleTask@http://localhost:4200/polyfills.js:4623:47
scheduleMacroTask@http://localhost:4200/polyfills.js:4646:29
scheduleMacroTaskWithCurrentZone@http://localhost:4200/polyfills.js:5547:29
patchTimer/setNative</<@http://localhost:4200/polyfills.js:6999:66
patchMethod/proto[name]@http://localhost:4200/polyfills.js:5862:52
nifk/</e.exports</t.default@http://localhost:4200/vendor.js:236405:1525
nifk/</e.exports</e.prototype.rawOnEnd/<@http://localhost:4200/vendor.js:236405:5282
nifk/</e.exports</e.prototype.rawOnEnd@http://localhost:4200/vendor.js:236405:5259
nifk/</e.exports</e.prototype.onTransportEnd@http://localhost:4200/vendor.js:236405:4417
nifk/</p/start/r.onclose@http://localhost:4200/vendor.js:236405:29476
wrapFn@http://localhost:4200/polyfills.js:5631:43
invokeTask@http://localhost:4200/polyfills.js:4812:35
onInvokeTask@http://localhost:4200/vendor.js:186603:33
invokeTask@http://localhost:4200/polyfills.js:4811:40
runTask@http://localhost:4200/polyfills.js:4580:51
invokeTask@http://localhost:4200/polyfills.js:4893:38
invokeTask@http://localhost:4200/polyfills.js:6034:18
globalZoneAwareCallback@http://localhost:4200/polyfills.js:6060:31
EventListener.handleEvent*customScheduleGlobal@http://localhost:4200/polyfills.js:6186:47
scheduleTask@http://localhost:4200/polyfills.js:4798:30
onScheduleTask@http://localhost:4200/polyfills.js:4685:69
scheduleTask@http://localhost:4200/polyfills.js:4791:55
scheduleTask@http://localhost:4200/polyfills.js:4623:47
scheduleEventTask@http://localhost:4200/polyfills.js:4649:29
makeAddListener/<@http://localhost:4200/polyfills.js:6341:39
patchProperty/desc.set@http://localhost:4200/polyfills.js:5692:24
start@http://localhost:4200/vendor.js:236405:29411
nifk/</e.exports</e.prototype.start@http://localhost:4200/vendor.js:236405:6409
nifk/</e.exports</t.unary@http://localhost:4200/vendor.js:236405:24934
nifk/</unary/<@http://localhost:4200/vendor.js:236405:30002
ZoneAwarePromise@http://localhost:4200/polyfills.js:5373:33
unary@http://localhost:4200/vendor.js:236405:29895
bucketsList/<@http://localhost:4200/vendor.js:121936:506821
__awaiter/<@http://localhost:4200/vendor.js:121936:291
ZoneAwarePromise@http://localhost:4200/polyfills.js:5373:33
__awaiter@http://localhost:4200/vendor.js:121936:36
bucketsList@http://localhost:4200/vendor.js:121936:506703
list/<@http://localhost:4200/vendor.js:121936:521012
__awaiter/<@http://localhost:4200/vendor.js:121936:291
ZoneAwarePromise@http://localhost:4200/polyfills.js:5373:33
__awaiter@http://localhost:4200/vendor.js:121936:36
list@http://localhost:4200/vendor.js:121936:520932
_getOrCreate/<@http://localhost:4200/vendor.js:121936:519768
    Angular 2
    rejected tslib.es6.js:74
    Angular 22
    default index.js:1
    rawOnEnd index.js:1
    rawOnEnd index.js:1
    onTransportEnd index.js:1
    onclose index.js:1
    Angular 16
    start index.js:1
    start index.js:1
    unary index.js:1
    unary index.js:1
    ZoneAwarePromise Angular
    unary index.js:1
    bucketsList index.js:16
    __awaiter index.js:16
    ZoneAwarePromise Angular
    __awaiter index.js:16
    bucketsList index.js:16
    list index.js:16
    __awaiter index.js:16
    ZoneAwarePromise Angular
    __awaiter index.js:16
    list index.js:16
    _getOrCreate index.js:16
core.js:6142

info:

@spacehq/sdk: 0.0.30
Angular v11.1.4

Getting "Error: gundb failed to authenticate user: Unverified data." when trying to create a folder in UserStorage

code:

import { Users, UserStorage } from '@spacehq/sdk'

const users = new Users({ endpoint: 'wss://auth-dev.space.storage' })

const identity = await users.createIdentity()

const user = await users.authenticate(identity)

const storage = new UserStorage(user)

await storage.createFolder({ bucket: 'bucket', path: 'pkg' })

error:

/home/v1rtl/Coding/x/node_modules/.pnpm/@[email protected]/node_modules/@spacehq/storage/dist/metadata/gundbMetadataStore.js:501
                            reject(new Error(`gundb failed to authenticate user: ${auth.err}`));
                                   ^

Error: gundb failed to authenticate user: Unverified data.
    at Object.ack (/home/v1rtl/Coding/xnode_modules/.pnpm/@[email protected]/node_modules/@spacehq/storage/src/metadata/gundbMetadataStore.ts:579:20)

info:

  • @spacehq/sdk: 0.0.30
  • Node v16

Question to shareViaPublicKey

Hi,

I would like to use your shareViaPublicKey API.

await storage.shareViaPublicKey({
    publicKeys: [{
      id: '[email protected]', // or any identifier for the user
      pk: 'user-pk-hex-or-multibase', // optional, omit if user doesn't exist yet, it would generate temp access key
    }],
    paths: [{
        bucket: 'personal',
        path: '/file/path/here'
    }],
});

However, I currently do not understand which value I should store behind the attribute 'id' or where I resolve this value.

publicKeys: [{
      id: '[email protected]', // or any identifier for the user
      pk: 'user-pk-hex-or-multibase', // optional, omit if user doesn't exist yet, it would generate temp access key
    }]

Can you explain this to me in more detail?
Currently i use a modified Version of the class BrowserStorage to Authenticate users on the local device by Webauthn.

Thanks in advance
Stephan

Somone please help I'm getting this issue but I have no idea what it means. thanks

Deploy started at 7:09:11 PM 04/20/2021

7:09:12 PM 04/20/2021: Deploy started
7:09:15 PM 04/20/2021: Docker image: 'fleek/create-react-app'
7:09:15 PM 04/20/2021: Build command: 'yarn && yarn build'
7:09:15 PM 04/20/2021: Triggering build execution...
7:10:14 PM 04/20/2021: yarn install v1.22.5
7:10:14 PM 04/20/2021: [1/4] Resolving packages...
7:10:15 PM 04/20/2021: [2/4] Fetching packages...
7:10:25 PM 04/20/2021: error Command failed.
7:10:25 PM 04/20/2021: Exit code: 128
7:10:25 PM 04/20/2021: Command: git
7:10:25 PM 04/20/2021: Arguments: ls-remote --tags --heads ssh://[email protected]/ethereumjs/ethereumjs-abi.git
7:10:25 PM 04/20/2021: Directory: /workspace
7:10:25 PM 04/20/2021: Output:
7:10:25 PM 04/20/2021: Host key verification failed.
7:10:25 PM 04/20/2021: fatal: Could not read from remote repository.
7:10:25 PM 04/20/2021: Please make sure you have the correct access rights
7:10:25 PM 04/20/2021: and the repository exists.
7:10:25 PM 04/20/2021: info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
7:11:15 PM 04/20/2021: Error occured during the build.

Space SDK fails on import

Steps to reproduce:
import {Users} from '@spacehq/sdk'

Import this into a create-react-app.

It will fail with this message:

`
uncaught TypeError: TextDecoder is not a constructor
at Object../node_modules/multibase/src/util.js (util.js:6)
at webpack_require (bootstrap:856)
at fn (bootstrap:150)
at Object../node_modules/multibase/src/base.js (base.js:3)
at webpack_require (bootstrap:856)
at fn (bootstrap:150)
at Object../node_modules/multibase/src/constants.js (constants.js:4)
at webpack_require (bootstrap:856)
at fn (bootstrap:150)
at Object../node_modules/multibase/src/index.js (index.js:7)
at webpack_require (bootstrap:856)
at fn (bootstrap:150)
at Object. (fsUtils.ts:2)
at Object../node_modules/@spacehq/storage/dist/utils/fsUtils.js (fs)

`

I tried adding 'web-encoding' to my node-modules, but it didn't make a difference.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.