Coder Social home page Coder Social logo

getscatter / scatter-js Goto Github PK

View Code? Open in Web Editor NEW
262.0 19.0 149.0 18.8 MB

Importable JavaScript library that allows web applications to directly interface with Scatter Desktop, Classic and Mobile.

License: MIT License

HTML 37.32% JavaScript 62.68%

scatter-js's Introduction

Scatter JS

type version package
core npm version @scatterjs/core
blockchain npm version @scatterjs/eosjs
blockchain npm version @scatterjs/eosjs2
blockchain npm version @scatterjs/web3
blockchain npm version @scatterjs/tron
blockchain npm version @scatterjs/fio
wallet npm version @scatterjs/lynx

Want some quick code?

Here's some boilerplates for you to just get starts quickly.

[email protected]

Installation: npm i -S @scatterjs/core @scatterjs/eosjs [email protected]

import ScatterJS from '@scatterjs/core';
import ScatterEOS from '@scatterjs/eosjs';
import Eos from 'eosjs';

ScatterJS.plugins( new ScatterEOS() );

const network = ScatterJS.Network.fromJson({
    blockchain:'eos',
    chainId:'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',
    host:'nodes.get-scatter.com',
    port:443,
    protocol:'https'
});

ScatterJS.connect('YourAppName', {network}).then(connected => {
    if(!connected) return console.error('no scatter');

    const eos = ScatterJS.eos(network, Eos);

    ScatterJS.login().then(id => {
        if(!id) return console.error('no identity');
        const account = ScatterJS.account('eos');
        const options = {authorization:[`${account.name}@${account.authority}`]};
        eos.transfer(account.name, 'safetransfer', '0.0001 EOS', account.name, options).then(res => {
            console.log('sent: ', res);
        }).catch(err => {
            console.error('error: ', err);
        });
    });
});

[email protected]

Installation: npm i -S @scatterjs/core @scatterjs/eosjs2 [email protected]

import ScatterJS from '@scatterjs/core';
import ScatterEOS from '@scatterjs/eosjs2';
import {JsonRpc, Api} from 'eosjs';

ScatterJS.plugins( new ScatterEOS() );

const network = ScatterJS.Network.fromJson({
    blockchain:'eos',
    chainId:'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',
    host:'nodes.get-scatter.com',
    port:443,
    protocol:'https'
});
const rpc = new JsonRpc(network.fullhost());

ScatterJS.connect('YourAppName', {network}).then(connected => {
    if(!connected) return console.error('no scatter');

    const eos = ScatterJS.eos(network, Api, {rpc});

    ScatterJS.login().then(id => {
        if(!id) return console.error('no identity');
        const account = ScatterJS.account('eos');

        eos.transact({
            actions: [{
                account: 'eosio.token',
                name: 'transfer',
                authorization: [{
                    actor: account.name,
                    permission: account.authority,
                }],
                data: {
                    from: account.name,
                    to: 'safetransfer',
                    quantity: '0.0001 EOS',
                    memo: account.name,
                },
            }]
        }, {
            blocksBehind: 3,
            expireSeconds: 30,
        }).then(res => {
            console.log('sent: ', res);
        }).catch(err => {
            console.error('error: ', err);
        });
    });
});

tronweb

Installation: npm i -S @scatterjs/core @scatterjs/tron tronweb

import ScatterJS from '@scatterjs/core';
import ScatterTron from '@scatterjs/tron';
import TronWeb from 'tronweb';

ScatterJS.plugins( new ScatterTron() );

const network = ScatterJS.Network.fromJson({
    blockchain:'tron',
    chainId:'1',
    host:'api.trongrid.io',
    port:443,
    protocol:'https'
});

const httpProvider = new TronWeb.providers.HttpProvider(network.fullhost());
let tron = new TronWeb(httpProvider, httpProvider, network.fullhost());
tron.setDefaultBlock('latest');

ScatterJS.connect('YourAppName', {network}).then(connected => {
    if(!connected) return console.error('no scatter');

    tron = ScatterJS.trx(network, tron);

    ScatterJS.login().then(id => {
        if(!id) return console.error('no identity');
        const account = ScatterJS.account('trx');
        tron.trx.sendTransaction('TX...', 100).then(res => {
            console.log('sent: ', res);
        }).catch(err => {
            console.error('error: ', err);
        });
    });
});

web3

Installation: npm i -S @scatterjs/core @scatterjs/web3 web3

import ScatterJS from '@scatterjs/core';
import ScatterETH from '@scatterjs/web3';
import Web3 from 'web3';

ScatterJS.plugins( new ScatterETH() );

const network = ScatterJS.Network.fromJson({
    blockchain:'eth',
    chainId:'1',
    host:'YOUR ETHEREUM NODE',
    port:443,
    protocol:'https'
});

ScatterJS.connect('YourAppName', {network}).then(connected => {
    if(!connected) return console.error('no scatter');

    const web3 = ScatterJS.web3(network, Web3);

    ScatterJS.login().then(id => {
        if(!id) return console.error('no identity');
        const account = ScatterJS.account('trx');
        web3.eth.sendTransaction({
            from: account.address,
            to: '0x...',
            value: '1000000000000000'
        }).then(res => {
            console.log('sent: ', res);
        }).catch(err => {
            console.error('error: ', err);
        });
    });
});

fio

Installation: npm i -S @scatterjs/core @scatterjs/fio @fioprotocol/fiojs

import ScatterJS from '@scatterjs/core';
import ScatterFIO from '@scatterjs/fio';
import Fio from '@fioprotocol/fiojs';

ScatterJS.plugins( new ScatterFIO() );

const network = ScatterJS.Network.fromJson({
    blockchain:'fio',
    chainId:'b20901380af44ef59c5918439a1f9a41d83669020319a80574b804a5f95cbd7e',
    host:'testnet.fioprotocol.io',
    port:443,
    protocol:'https'
});

ScatterJS.connect('YourAppName', {network}).then(connected => {
    if(!connected) return console.error('no scatter');

    const api = ScatterJS.fio(network, Fio, {
        textEncoder:new TextEncoder(),
        textDecoder:new TextDecoder(),
    });

    ScatterJS.login().then(async id => {
        if(!id) return console.error('no identity');

        const from = ScatterJS.account('fio');
        const transactionOptions = await api.getTransactionOptions();
        const tx = await api.transact(Object.assign(transactionOptions, {
            actions: [{
                account:'fio.token',
                name: 'trnsfiopubky',
                authorization: [{ actor: from.name, permission: 'active', }],
                data: {
                    payee_public_key: 'FIO6QizWWbLMkUVBfEbs7a5mHaCNSpgaJR5NEhqhqv3v4xgaMSM1a',
                    amount: '1000000000', max_fee: 2000000000,
                    tpid:'',
                    actor: from.name
                },
            }]
        }));

        console.log('result', tx);
        const result = await fetch(network.fullhost() + '/v1/chain/push_transaction', { body: JSON.stringify(tx), method: 'POST', }).then(x => x.json());
    });
});




Supported Wallets

Automatically Supported Wallets

Disclaimer: Wallets being supported by this SDK does not mean they are endorsed or vetted.

These wallets do not require you include any plugins. They run Scatter Protocols inside of their wallet and mimic our existing APIs.

Does your wallet support Scatter Protocols? Issue a Pull Request on the README.md and add it here.

dapp supported blockchains platform wallet libs
EOSIO, Tron, Ethereum Scatter Desktop Desktop [email protected], eosjs@20+, tronweb, web3
EOSIO, Ethereum Scatter Extension Desktop [email protected], web3
EOSIO TokenPocket Mobile [email protected], eosjs@20+
EOSIO MEET.ONE Mobile [email protected], eosjs@20+
EOSIO imToken Mobile [email protected]
EOSIO PocketEOS Mobile [email protected]
EOSIO MoreWallet Mobile [email protected]
EOSIO NOVAWallet Mobile [email protected]
EOSIO Chaince Wallet Mobile [email protected]
EOSIO EOS LIVE Mobile [email protected]
EOSIO Starteos Mobile [email protected], eosjs@20+
EOSIO CoinUs Wallet Mobile [email protected]
EOSIO TokenBase Wallet Mobile [email protected], eosjs@20+
EOSIO ET Wallet Mobile [email protected], eosjs@20+
EOSIO Wombat Wallet Mobile [email protected], eosjs@20+

Plugin Supported Wallets

These wallets require a plugin to support. ScatterJS will mutate standardized blockchain library requests for you into their required formats.

dapp supported blockchains wallet platform plugin libs
EOSIO Lynx Mobile scatterjs-plugin-lynx eosjs@20+



Installation

To use ScatterJS you must have at least the core. From that point forward you can mix-match the plugins you require.

blockchain library installation command
eosjs npm i -S @scatterjs/core @scatterjs/eosjs [email protected]
eosjs2 (@20+) npm i -S @scatterjs/core @scatterjs/eosjs2 [email protected]
tronweb npm i -S @scatterjs/core @scatterjs/tron tronweb
web3 npm i -S @scatterjs/core @scatterjs/web3 web3

CDN

<script src="https://cdn.scattercdn.com/file/scatter-cdn/js/latest/scatterjs-core.min.js"></script>
<script src="https://cdn.scattercdn.com/file/scatter-cdn/js/latest/scatterjs-plugin-eosjs.min.js"></script>
<script src="https://cdn.scattercdn.com/file/scatter-cdn/js/latest/scatterjs-plugin-eosjs2.min.js"></script>
<script src="https://cdn.scattercdn.com/file/scatter-cdn/js/latest/scatterjs-plugin-web3.min.js"></script>
<script src="https://cdn.scattercdn.com/file/scatter-cdn/js/latest/scatterjs-plugin-tron.min.js"></script>
<script src="https://cdn.scattercdn.com/file/scatter-cdn/js/latest/scatterjs-plugin-fio.min.js"></script>
<script src="https://cdn.scattercdn.com/file/scatter-cdn/js/latest/scatterjs-plugin-lynx.min.js"></script>

Building the minified bundles from Git

If you don't want to use Scatter's CDN, and you can't/don't want to use the NPM packages, then you can also build the Scatter-JS bundles from source.

Webpack will automatically add a version/license header to the top of the bundle files, so that you can identify the version of each Scatter-JS component after you've copied them into a project.

To generate the .min.js files from the source code in this repository, simply run the following commands:

git clone https://github.com/GetScatter/scatter-js.git
cd scatter-js
# Install NPM dependencies
yarn install        # alternative: npm install
# Generate the .min.js minified JS bundles into the folder 'bundles/' using Webpack
yarn run pack       # alternative: npm run pack



Instantiation

As early as you can in your project, instantiate both ScatterJS and your selected plugins.

Nodejs

import ScatterJS from '@scatterjs/core';
import ScatterEOS from '@scatterjs/eosjs'

ScatterJS.plugins( new ScatterEOS() );

Vanilla

<script src="scatterjs-core.min.js"></script>
<script src="scatterjs-plugin-eosjs.min.js"></script>

<script>
    ScatterJS.plugins( new ScatterEOS() );
</script>

Multiple Plugins

import ScatterJS from '@scatterjs/core';
import ScatterEOS from '@scatterjs/eosjs'
import ScatterTron from '@scatterjs/tron'
import ScatterLynx from 'scatterjs-plugin-lynx'

ScatterJS.plugins( new ScatterEOS(), new ScatterTron(), new ScatterLynx(Eos || {Api, JsonRpc}) );



Build the network object

Networks tell Scatter which blockchain nodes you're going to be working with.

const network = ScatterJS.Network.fromJson({
    blockchain:'eos',
    chainId:'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',
    host:'nodes.get-scatter.com',
    port:443,
    protocol:'https'
});



Connect to an available wallet

Once you are connected you can then call API methods on ScatterJS

ScatterJS.connect('MyAppName', {network}).then(connected => {
    if(!connected) return false;
    // ScatterJS.someMethod();
});

You can see full @scatterjs/core API docs here



Getting Blockchain Accounts

Login with the network passed into ScatterJS.connect

ScatterJS.login().then(...);

Login with multiple networks

ScatterJS.login({accounts:[network1, network2]).then(...);

Logout

ScatterJS.logout().then(...);

After a successful login, the "Identity" will be available at ScatterJS.identity. If a user refreshes the page and has already logged in, the ScatterJS.identity property will be auto-filled.



Get blockchain accounts from the identity

Because accounts are nested within the Identity there is an easy method for fetching them.

Using the helper

const account = ScatterJS.account('eos')
// Result: {name:'...', authority:'active', publicKey:'...', blockchain:'eos', chainId:'...'}

const account = ScatterJS.account('eth')
// Result: {address:'...', blockchain:'eth', chainId:'1'}

const account = ScatterJS.account('trx')
// Result: {address:'...', blockchain:'trx', chainId:'1'}

From the Identity

const account = ScatterJS.identity.accounts.find(x => {
    return x.blockchain === 'eos';
});



Using Blockchain Wrappers

Blockchain wrappers wrap the actual blockchain libraries (eosjs, tronweb, web3, etc) that you pass in. That way you don't have to relearn any APIs or be forced to use any specific version.

You can click on the libraries here below to go directly to their respective githubs.

[email protected] ( @scatterjs/eosjs )

import Eos from 'eosjs';
const eos = ScatterJS.eos(network, Eos, eosjsOptions);

const result = await eos.transfer(...);

[email protected] ( @scatterjs/eosjs2 )

import {JsonRpc, Api} from 'eosjs'
const rpc = new JsonRpc(network.fullhost());
const eos = ScatterJS.eos(network, Api, {rpc});

const result = await eos.transact({...});

tronweb

import TronWeb from 'tronweb';
const httpProvider = new TronWeb.providers.HttpProvider(network.fullhost());
let tron = new TronWeb(httpProvider, httpProvider, network.fullhost());
tron.setDefaultBlock('latest');
tron = ScatterJS.trx(network, tron);

const result = await tron.trx.sendTransaction(...)

web3

import Web3 from 'web3';
const web3 = ScatterJS.web3(network, Web3);

const result = await web3.eth.sendTransaction(...)

fio

import Fio from '@fioprotocol/fiojs';
const api = ScatterJS.fio(network, Fio, {
    textEncoder:new TextEncoder(),
    textDecoder:new TextDecoder(),
});

const transactionOptions = await api.getTransactionOptions();
const tx = await api.transact(Object.assign(transactionOptions, { actions: [...] }));
const result = await fetch('HOST/v1/chain/push_transaction', { body: JSON.stringify(tx), method: 'POST', }).then(x => x.json());



NodeJS and babel/webpack issues.

If you're having trouble packaging or compiling your project you probably need to add a babel transpiler.

  • npm i -D @babel/runtime <-- run this command and it should compile.



Fetch issues.

If you're having trouble with fetch not being defined in your nodejs environment you can add it by doing

  • npm i -S isomorphic-fetch
  • and then require('isomorphic-fetch'); at the start of your application



What now?

Head over to the Scatter Developer Documentation to learn about all the amazing things you can do with Scatter.

There's also a lot more information about proper setup in the Setting up for Web Applications section which will help you get the most out of ScatterJS, and make sure you aren't exposing your users to malicious non-Scatter plugins.


scatter-js's People

Contributors

chendatony31 avatar conr2d avatar fubin0083 avatar gtolarc avatar hzuhyb avatar leehihi12 avatar matei-radu avatar michaellee123 avatar nsjames avatar puncsky avatar shinhyo avatar shrimpliu avatar soleone avatar someguy123 avatar warrickfitz 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

scatter-js's Issues

core: use isomorphic-ws for node.js support

hi and thanks for scatter!

i am writing sunbeam, a library for both the browser and nodejs. people use it for frontends and also for cli scripts in nodejs.

it would be nice to use isomorphic-ws for the websockets. this way node users can use scatter-js out of the box. right now i have to workaround:

const Websocket = require('isomorphic-ws')
global.WebSocket = Websocket

getArbitrarySignature fails in scatter mobile

Hello,

I'm using scatter-js and it works fine in scatter chrome extension and scatter desktop.
But when I call getArbitrarySginature() in scatter mobile, the scatter app stones and callback the error.
Other actions work fine including transfer. It seems weird but probably should be updated or be sufficiently tested.

Split up EOS and ETH dependencies

Currently scatter-js requires a bunch of Ethereum/web3 dependencies wether or not developers use them. Based on my local tests this inflates the minified bundle size 190K (654K vs 464K).

Since most projects will likely not support both EOS and ETH I think it would be a good idea to not load any default plugins, and instead require developers to manually require plugins for the blockchains they want to support.

Alternatively EOS plugins could be loaded by default, and ETH plugins could be opt-in, but I think that decision would depend on how Scatter views its Ethereum support. Is Ethereum supported as a 1st class citizen equal to EOS, or is it supported as a bridge for developers moving from ETH to EOS?

Race condition causing Scatter to never connect

When using the browser extension, if ScatterJS.scatter.connect is called after scatterLoaded would've been called then Scatter will never connect and timeout.

I think this code would replicate the issue (untested):

setTimeout(() => {
   ScatterJS.scatter.connect("testing").then(connected => console.log(connected));
}, 10000);

The fix would be for the connect function to resolve immediately if Scatter has already been loaded/connected.

There is a problem with Path (Plugins -> plugins)

In the following two lines, plugins should be used instead of Plugins.

import Plugin from './Plugins/Plugin';
=> import Plugin from './plugins/Plugin';

import * as PluginTypes from './Plugins/PluginTypes';
=> import * as PluginTypes from './plugins/PluginTypes';

import Plugin from './Plugins/Plugin';

import * as PluginTypes from './Plugins/PluginTypes';

"npm install" returns error

When I run npm i scatter-js --save, it returns this error: Unexpected end of JSON input while parsing near '...},"modified":"2017-09', which causes I can't install the scatter-js.

I am using windows 8 and npm 5.6.0

getIdentity() returns empty accounts array

I'm trying to use scatter-js (2.5.1) with the Scatter Desktop application (8.7.0). In the Desktop application I've created an identity, imported an EOS private key (with the 'active' permission) and then linked myaccount@active (which is an existing account on the EOS mainnet).

Now, when I connect scatter-js with the Desktop application, I get the identity and can authorize myself, but I'm unable to retrieve my EOS account. This is my code:

import Eos from 'eosjs/lib/eos.js'
import ScatterJS from 'scatter-js/dist/scatter.esm'

const network = {
    blockchain: 'eos',
    host: 'nodes.get-scatter.com',
    port: 443,
    protocol: 'https',
    chainId: 'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906'
}

ScatterJS.scatter.connect('MyApp').then(connected => {
    ScatterJS.scatter.getIdentity({accounts: [network]}).then(identity => {
        console.log(identity)
           
         // ....
        
        }).catch(error => {
                console.log(error)
                ScatterJS.scatter.forgetIdentity()
        })
    }).catch(onrejected => {
           // ...
})

This is the log output of the identity object:

Object { hash: "redacted", publicKey: "EOSredacted", name: "myidentity", kyc: false, accounts: [] }

And if I try to execute an EOS action (for example voteproducer), I get this error:

Object { type: "account_missing", message: "You are trying to sign a request with an account that isn't currently linked or doesn't exist in the user's Scatter", code: 402, isError: true }

Is there anything I've missed?

TypeError: scatter.eosHook is not a function

throw error with code:

import ScatterJS from 'scatterjs-core'
import ScatterEOS from 'scatterjs-plugin-eosjs2'
ScatterJS.plugins(new ScatterEOS());

const eosjs = require('eosjs')
const fetch = require('node-fetch')            
const { TextDecoder, TextEncoder } = require('text-encoding')

async login ({commit, state, dispatch}) { 
      const connectionOptions = {initTimeout: 20000}
      const connected = ScatterJS.scatter.connect("xxxx", connectionOptions)
      if (!connected) throw new Error('no-scatter')
      const scatter = ScatterJS.scatter
      const network = {
        blockchain: 'eos',
        protocol: process.env.EOS_PROTOCOL,
        host: process.env.EOS_HOST,
        port: process.env.EOS_PORT,
        chainId: process.env.EOS_CHAINID
      }
      console.log(network)
      const requiredFields = { accounts: [network] }
      await scatter.getIdentity(requiredFields)
      const account = scatter.identity.accounts.find(x => x.blockchain === 'eos')
      const accountName = account.name
      console.log(accountName)
      commit('setScatter', scatter)


      rpc = new eosjs.Rpc.JsonRpc('http://127.0.0.1:8000', { fetch });
      api = new eosjs.Api({ rpc, signatureProvider:scatter.eosHook(network), textDecoder: new TextDecoder(), textEncoder: new TextEncoder() });
    
      // window.ScatterJS = null
      
}

Be friendly to the eos game?

Hello,

I try to create some kind game like space invaders, before starting, I play the demo on https://eosauthority.com/space/. And I find if the client sends request (move LEFT/RIGHT) to contract, the scatter pops up. Anyway to make scatter be friendly to the game? say auto-confirm the request?

Separate checking for Scatter from requesting connection to desktop

Right now using connect will actually request a user provides access to scatter, which is the only way to check if they have scatter desktop installed but isn't a great user-experience.

These two should be separated into two different pathways to provide applications a way to check if a user has scatter installed but only prompt for app permissions before they first request an api route

scatter-js - index.html configuration does not connect

Cannot connect:

Get error on console:
polling-xhr.js:265 GET http://127.0.0.1:50005/socket.io/?EIO=3&transport=polling&t=MLJl-ax 0 ()

If I replace:
var network = {blockchain:'eos', protocol:'http', host:'192.168.1.6', port:8888, chainId:'cf057bbfb72640471fd910bcb67639c22df9f92470936cddc1ade0e2f2e7dc4f'};

with: (public mainnet- entrypoint)
var network = {blockchain:'eos', protocol:'https', host:'eos.greymass.com', port:8888, chainId:'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906'};

and my eos-address:
scatter.linkAccount(publicKey, { name:'cryptobeings', authority:'active' },

also no connection

Is there an official developer Telegram-Group for Scatter?
Thank you very much!

Eosjs2 support

Once lerna extrapolation is implemented a provider for eosjs2 should be made to give devs multiple options of libraries when interacting with EOS blockchains

Abi 'xxxxxxxx' is not cached in action.data

When I used eosio.msig to call my own contract interface, this problem occurred. After a period of research, I found such a phenomenon, the fourth parameter of the proos interface of eosio.msig is called, if the content is eosio.token The interface is fine, but if it is a custom contract interface will report this error, what is the problem, please help me.
Below is the display code and call in my vue project.

`<script>

import ScatterJS from 'scatterjs-core';
import ScatterEOS from 'scatterjs-plugin-eosjs';
import Eos from 'eosjs'

export default {
name: "",
data() {
return {
roleType: "",
signData:''
};
},
methods: {
// 登录
async login() {
// alert('login')
let scatter, eos;

ScatterJS.plugins( new ScatterEOS() );
const network = ScatterJS.Network.fromJson({
blockchain:'eos',
chainId:'aca376f206b8fc25a6ed44dbdc66547c36c6c33e3a119ffbeaef943642f0e906',
host:'mainnet.eoscalgary.io',
port:80,
protocol:'http',
});
ScatterJS.scatter.connect('LernaVanillaTest').then(connected => {
if(!connected) return false;
scatter = ScatterJS.scatter;
console.log("scatter",scatter);
eos = scatter.eos(network, Eos);
scatter.suggestNetwork(network);
scatter.getIdentity({accounts:[network]})
let account = scatter.identity.accounts.find(x => x.blockchain ==='eos');
console.log("account",account);
const transactionOptions = { authorization:[${account.name}@${account.authority}]};

   eos.contract('liantongct11',{breakCache:true}).then(market => 
      {
    eos.contract('eosio.msig').then( msig =>
    {
      // {broadcast: true, sign: true},
        //transactionOptions
        market.issue('liantongvip2', '10.0000 CAT', 'issue1',60,0,'10.0000 CAT',2000,4,80,'10.0000 CAT'
        ,{broadcast: false, sign: false}).then(trade=>
        {
          trade.transaction.transaction.max_net_usage_words = 0;
          // console.log(' trade', trade)
          trade.transaction.transaction.max_net_usage_words = 0;
          trade.transaction.transaction.ref_block_num = 0;
          trade.transaction.transaction.ref_block_prefix = 0;
          
          trade.transaction.expiration = new Date(Date.parse(new Date()) + 1000 * 60 * 3);
          console.log(trade.transaction.transaction);
          msig.propose('liantongt','liantongta2',[
          {
              "actor": "liantongvip3",
              "permission": "active"
          },
          {
              "actor": "liantongvip1",
              "permission": "active"
          },
          {
              "actor": "liantongvip2",
              "permission": "active"
          }],
          trade.transaction.transaction,                                
          transactionOptions).then(
              (res,error)=>{
                console.log('res',res);
                console.log('error',error);
              }
            );
        });
        });
      });
});
 
},
logout() {
  scatter.forgetIdentity();
 
},
transfer() {
  alert('transfer')
 
},
contract() {
  alert('contract')
 
},
multi() {
  alert('contract')
 
},
fc() {
  alert('fc')
 
},
hookTransfer() {
  alert('hookTransfer')
 
},
donate() {
  donate('donate')
 
},
init(){
  
  
}

},

async mounted() {

},
}
</script>`

eosjs2 getting an update

2 helpful takeaways:

  • the default export is gone and exports are modified slightly (i.e. new eosjs.Rpc.JsonRpc is now just new JsonRpc)
  • JsonRpc now has getRawAbi which retrieves the rawCodeAndAbi.abi and does base64ToBinary, so you can remove your numeric import and use that call instead

Did Scatter-JS support mobile application such as iOS, Android?

Hi, My boss demand us to integrate Scatter-JS In our app mobile application such as iOS, Android . But we can't find any document or demo to show the user how to implement this . If Scatter-JS support this , give me any information such as demo ,or any OpenSource app on github. Thank you very much!

Uncaught (in promise) Error: No Identity

Since I use scatter-core with chrome scatter extension, an error occurs as the title shows when I tried to transfer.

let holder = new Holder(new Index());
if(typeof window !== 'undefined') {
    // Catching extension instead of Desktop
    if(typeof document !== 'undefined'){
        const bindScatterClassic = () => {
            holder.scatter = window.scatter;  // **here holder.scatter is overridden by window.scatter**
            holder.scatter.isExtension = true;
            holder.scatter.connect = () => new Promise(resolve => resolve(true));
        };

        if(typeof window.scatter !== 'undefined') bindScatterClassic();
        else document.addEventListener('scatterLoaded', () => bindScatterClassic());
    }
    window.ScatterJS = holder;
}
constructor(){
    this.isExtension = false;
    this.identity = null;
}

loadPlugin(plugin){
    const noIdFunc = () => {
        //**here 'this' refers to instance of Index **
        //** so when 'scatterjs-plugin-eosjs' executes 'throwIfNoIdentity()', 'this.identity' still equals 'null';**
        if(!this.identity) throw new Error('No Identity') 
    };
    if(!plugin.isValid()) throw new Error(`${plugin.name} doesn't seem to be a valid ScatterJS plugin.`);
    PluginRepository.loadPlugin(plugin);
    if(plugin.isSignatureProvider()){
        this[plugin.name] = plugin.signatureProvider(noIdFunc);
        this[plugin.name+'Hook'] = plugin.hookProvider;
    }
}

// **this function would not be called since the override
getIdentity(requiredFields){
    throwNoAuth();
    return SocketService.sendApiRequest({
        type:'getOrRequestIdentity',
        payload:{
            fields:requiredFields
        }
    }).then(id => {
        if(id) this.identity = id;
        return id;
    });
}

how to commit transaction via using native websocket

I read the document and find that the document just show me how to create transaction, but I could not get the transcation id from the response. So I think the api just just create transaction without commit ! So how to commit a transaction??
ps: I called create transaction api for my contract to call my function, is that anything wrong? this function has not params
image

account missing issue with Scatter-desktop and exist on Scatter-Extension with a same settings

I communicate with separate EOS-compatible network and contract on it. Settings in Scatter-Desktop and Scatter-Extension is a full same. Both Scatters have imported keys, networks and pulled identities.

When i pull transfer action with enabled Scatter-Ex and closed Scatter-D, transfer is success, Scatter-Ex sign transaction. When i disable Scatter-Ex and open Scatter-D for the same transfer action, after submit permission, i have error:

{ "type": "account_missing", "message": "You are trying to sign a request with an account that isn't currently linked or doesn't exist in the user's Scatter", "code": 402, "isError": true }

Identity does not contain a account for sign. But account installed same like in Scatter-Ex. How it can be solved for stable operation two applications?

I use this code:

ScatterJS.scatter.connect("travelchain").then(connected => {
        if(connected){
            this.scatter = ScatterJS.scatter;
            window.scatter = null;
        }
    });

..............

scatter.getIdentity().then(identity => {
          const options = {
            authorization: this.username,
          }

          const eost = scatter.eos( network, Eos, options, 'https');
          eost.transfer(this.username, this.contract_name, amount, this.host_name).then(()=> {
            this.refresh_page()
            loading.close()
          }).catch(error => {
            this.throwBCError(error)
            loading.close()
          })
      })

a way to identify when user login to Scatter

Hello, I am building an Eos Dapp using Scatter, and when the app is loaded I check if the user is connected using this line:

const isConnected = await ScatterJS.scatter.connect('My App');

if the user is not connected, I show him a message that tells him to connect.

is there a way to auto detect when the user login? I tried running the above code in interval to check for updates, but it doesn't work so good.

scatter eos hook or proxy provider can not push action to nodeos

I am using eosjs2

const api = new Api({
        rpc,
        signatureProvider: scatter.eosHook(network),
        textDecoder: new TextDecoder(),
        textEncoder: new TextEncoder()
      });

and using api.transact to push an action to the nodeos, but nothing happend, no response, no error.

But If I use [email protected], and as follows of eosjs document, action can push to the nodeos.

does scatter supoorted eosjs2?

desktop response is different from chrome extension

for example
with chrome extension:

const eos = ScatterJS.scatter.eos(network, Eos);
eos.transfer.then((trx) => {
    const trxId = trx.transaction_id
)

with desktop version v9.5.0:

const eos = ScatterJS.scatter.eos(network, Eos);
eos.transfer.then((trx) => {
    // trx becomes 'Proxy'
    console.log(typeof trx.transaction_id) // 'function'
)

image

currently I have to get the id by Object.getOwnPropertyDescriptor(trx, 'transaction_id').value

am I missing something?

Improve "account not found" error messages when importing keys for EOS chain

IMHO it would be helpful to get a better error message when talking to networks. Right now, if you import your keys to the network and the account is set up but the chain is missing the history api plugin Scatter would state that the account was not found, but in fact the endpoint does not exist. Response from eos chain in such cases:
{"code":404,"message":"Not Found","error":{"code":0,"name":"exception","what":"unspecified","details":[{"message":"Unknown Endpoint","file":"http_plugin.cpp","line_number":244,"method":"handle_http_request"}]}}

Add a means to know when Scatter Desktop is locked or actually missing

With Scatter web when I do the routine to check for Scatter, it will return that Scatter is found if their wallet is locked.

With Scatter Desktop and scatter-js, when I do the following routine to check for Scatter, I find that if the user only has Scatter Desktop (no chrome extension), and their wallet is locked, then this routine returns as failed and I can't differentiate between if the user is missing the Scatter app, or if it's just locked.

    if (await ScatterJS.scatter.connect(`[APPNAME]`, { initTimeout: 5000 })) {
      this.setScatterInstance(ScatterJS.scatter)
      window.scatter = null;
    } else {
      console.log(`Did not find scatter instance on user's computer or browser`);
      this.setScatterState('missing');
    }

scatter.isInstalled() throw error

I am looking for a way to check if user installed Scatter Desktop/Extension, I couldn't find a way to do that in the docs, buy I did find, isInstalled method on Scatter object.
is this function reliable and can be used?

anyway, when trying to call it I get this Error:
image

HTTP/HTTPS mixed content

It seems firefox doesn't allow localhost http sockets to https websites citing mixed content.

It's possible that the user's Scatter can generate a self signed cert to use for https connections.

Use npm scoped packages for Scatter's family of libraries?

After seeing your @babel/runtime instruction in the latest readme, I learned about scoped packages in npm.

Scopes are a way of grouping related packages together, and also affect a few things about the way npm treats the package.

I wonder if this might be something you consider for Scatter, e.g. this feature:

Each npm user/organization has their own scope, and only you can add packages in your scope. This means you don't have to worry about someone taking your package name ahead of you. Thus it is also a good way to signal official packages for organizations.

Then the imports would look something like this potentially:

@scatter/core
@scatter/plugin-eosjs
@scatter/plugin-eosjs2
@scatter/plugin-web3
@scatter/plugin-tron

Obviously not a priority and managing backwards compatibility might be a bit painful, not sure. Just an idea for sometime in the future maybe.

Angular 6

Hi everyone,

I need help to use Scatter in an Angular 6 App.

I try to use Scatter:

import Eos from 'eosjs'
import ScatterJS from 'scatterjs-core';
import ScatterEOS from 'scatterjs-plugin-eosjs'

@Component({
    selector: 'app-some',
    templateUrl: './some.component.html',
    styleUrls: ['./some.component.scss']
})
export class SomeComponent implements OnInit {
    private network: Object = {
        blockchain:'eos',
        chainId:'038f4b0fc8ff18a4f0842a8f0564611f6e96e8535901dd45e43ac8691a1c4dca',
        host:'dev.cryptolions.io',
        port:18888,
        protocol:'http'
    };

    private scatter: any = null;

    ngOnInit() {
        ScatterJS.plugins(new ScatterEOS());
        ScatterJS.scatter.connect('Worbli').then(connected => {
            if(!connected)
                return false;

            this.scatter = ScatterJS.scatter;
        });
    }

    public login() {
        this.scatter.getIdentity({accounts:[this.network]}).then(id => {
            console.log('id', id);
        })

    }
}

but I have the error:

ERROR in ./node_modules/scatterjs-core/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/asyncToGenerator' in '/project/front/node_modules/scatterjs-core/dist'
ERROR in ./node_modules/scatterjs-core/dist/plugins/PluginRepository.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/asyncToGenerator' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-plugin-eosjs/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/asyncToGenerator' in '/project/front/node_modules/scatterjs-plugin-eosjs/dist'
ERROR in ./node_modules/scatterjs-core/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' in '/project/front/node_modules/scatterjs-core/dist'
ERROR in ./node_modules/scatterjs-core/dist/models/Network.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' in '/project/front/node_modules/scatterjs-core/dist/models'
ERROR in ./node_modules/scatterjs-core/dist/plugins/PluginRepository.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-core/dist/plugins/Plugin.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-core/dist/services/StorageService.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' in '/project/front/node_modules/scatterjs-core/dist/services'
ERROR in ./node_modules/scatterjs-core/dist/services/SocketService.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' in '/project/front/node_modules/scatterjs-core/dist/services'
ERROR in ./node_modules/scatterjs-plugin-eosjs/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/classCallCheck' in '/project/front/node_modules/scatterjs-plugin-eosjs/dist'
ERROR in ./node_modules/scatterjs-core/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/createClass' in '/project/front/node_modules/scatterjs-core/dist'
ERROR in ./node_modules/scatterjs-core/dist/models/Network.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/createClass' in '/project/front/node_modules/scatterjs-core/dist/models'
ERROR in ./node_modules/scatterjs-core/dist/plugins/PluginRepository.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/createClass' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-core/dist/plugins/Plugin.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/createClass' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-core/dist/services/StorageService.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/createClass' in '/project/front/node_modules/scatterjs-core/dist/services'
ERROR in ./node_modules/scatterjs-core/dist/services/SocketService.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/createClass' in '/project/front/node_modules/scatterjs-core/dist/services'
ERROR in ./node_modules/scatterjs-plugin-eosjs/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/createClass' in '/project/front/node_modules/scatterjs-plugin-eosjs/dist'
ERROR in ./node_modules/scatterjs-plugin-eosjs/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/getPrototypeOf' in '/project/front/node_modules/scatterjs-plugin-eosjs/dist'
ERROR in ./node_modules/scatterjs-plugin-eosjs/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/inherits' in '/project/front/node_modules/scatterjs-plugin-eosjs/dist'
ERROR in ./node_modules/scatterjs-core/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireDefault' in '/project/front/node_modules/scatterjs-core/dist'
ERROR in ./node_modules/scatterjs-core/dist/models/Network.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireDefault' in '/project/front/node_modules/scatterjs-core/dist/models'
ERROR in ./node_modules/scatterjs-core/dist/plugins/PluginRepository.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireDefault' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-core/dist/plugins/Plugin.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireDefault' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-core/dist/services/SocketService.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireDefault' in '/project/front/node_modules/scatterjs-core/dist/services'
ERROR in ./node_modules/scatterjs-core/dist/services/StorageService.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireDefault' in '/project/front/node_modules/scatterjs-core/dist/services'
ERROR in ./node_modules/scatterjs-plugin-eosjs/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireDefault' in '/project/front/node_modules/scatterjs-plugin-eosjs/dist'
ERROR in ./node_modules/scatterjs-core/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireWildcard' in '/project/front/node_modules/scatterjs-core/dist'
ERROR in ./node_modules/scatterjs-core/dist/plugins/Plugin.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireWildcard' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-core/dist/plugins/PluginRepository.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/interopRequireWildcard' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-plugin-eosjs/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/possibleConstructorReturn' in '/project/front/node_modules/scatterjs-plugin-eosjs/dist'
ERROR in ./node_modules/scatterjs-core/dist/services/SocketService.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/slicedToArray' in '/project/front/node_modules/scatterjs-core/dist/services'
ERROR in ./node_modules/scatterjs-core/dist/services/SocketService.js
Module not found: Error: Can't resolve '@babel/runtime/helpers/typeof' in '/project/front/node_modules/scatterjs-core/dist/services'
ERROR in ./node_modules/scatterjs-core/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/regenerator' in '/project/front/node_modules/scatterjs-core/dist'
ERROR in ./node_modules/scatterjs-core/dist/plugins/PluginRepository.js
Module not found: Error: Can't resolve '@babel/runtime/regenerator' in '/project/front/node_modules/scatterjs-core/dist/plugins'
ERROR in ./node_modules/scatterjs-plugin-eosjs/dist/index.js
Module not found: Error: Can't resolve '@babel/runtime/regenerator' in '/project/front/node_modules/scatterjs-plugin-eosjs/dist'
ERROR in ./node_modules/cipher-base/index.js
Module not found: Error: Can't resolve 'stream' in '/project/front/node_modules/cipher-base'
ERROR in ./node_modules/hash-base/index.js
Module not found: Error: Can't resolve 'stream' in '/project/front/node_modules/hash-base'

Publish package pre-compiled

I want to use the library with create-react-app and it fails to compile. Please publish the package pre-compiled so we can circumvent this issue (link).

module parse fails

I get this error:

bildschirmfoto 2018-09-20 um 17 22 50

in line 346 is a async function and I tried many solutions to support async functions but none of them worked yet.

my .babelrc file:
bildschirmfoto 2018-09-20 um 17 27 57

my webpack.config.js:
bildschirmfoto 2018-09-20 um 17 29 30

getIdentity returns null.

Hello!

Scatter Desktop 8.7.0

Scatter-js 2.5.1

Yesterday my Scatter Desktop and scatter-js worked fine but today I receive null identities.
I run Scatter Desktop. So basically, my websocket connects fine but ScatterDesktop doesn't pop any window in which I can choose my identity. It sends over a null identity and the getIdentity promise get resolved.

I don't know if the issue is at the Scatter Desktop level or scatter-js, on which side of the websockets there is an issue

Scatter ledger nano s issue after fairy wallet integration

want to make a transaction with Scatter but I'm stuck.... due to permission changes I can login in Scatter but I am not able to claim, airgrab, make transaction...

code: 402
isError: true
message: "Signature missing error... 

Please help!

Error compiling with CreateReactApp: 'minification failed' on scatter-js. Workaround: transpile with 'babel-preset-2015'

Using create react app and scatter-js, the build process fails on production builds when it attempts to minify/uglify the build.

Here is the documentation snippet from Facebook on the matter:
https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#npm-run-build-fails-to-minify

npm run build fails to minify
Some third-party packages don't compile their code to ES5 before publishing to npm. This often causes problems in the ecosystem because neither browsers (except for most modern versions) nor some tools currently support all ES6 features. We recommend to publish code on npm as ES5 at least for a few more years.

To resolve this:
Open an issue on the dependency's issue tracker and ask that the package be published pre-compiled.
Note: Create React App can consume both CommonJS and ES modules. For Node.js compatibility, it is recommended that the main entry point is CommonJS. However, they can optionally provide an ES module entry point with the module field in package.json. Note that even if a library provides an ES Modules version, it should still precompile other ES6 features to ES5 if it intends to support older browsers.
Fork the package and publish a corrected version yourself.

If the dependency is small enough, copy it to your src/ folder and treat it as application code.

In the future, we might start automatically compiling incompatible third-party modules, but it is not currently supported. This approach would also slow down the production builds.

For other developers / information purposes, the workaround that ended up working for me is the following:

There are 3 packages we need to transpile using babel-preset-2015:

  • scatter-js
  • web3-provider-engine
  • eth-block-tracker

Resolution Steps

  • npm install --save babel-preset-es2015
  • Add the following additional entries in /config/paths.js in the module exports:
module.exports = {
...
  scatterSrc: resolveApp('node_modules/scatter-js'),
  web3Src: resolveApp('node_modules/web3-provider-engine'),
  ethBlockTrackerSrc: resolveApp('node_modules/eth-block-tracker'),
};
  • Open /config/webpack.config.prod.js, find this section:
...
      {
        // "oneOf" will traverse all following loaders until one will
        // match the requirements. When no loader matches it will fall
        // back to the "file" loader at the end of the loader list.
        oneOf: [
...

Add a new babel loader entry for the paths we created:

          {
            test: /\.(js|jsx|mjs)$/,
            include: [
              paths.scatterSrc,
              paths.web3Src,
              paths.ethBlockTrackerSrc
            ],
            loader: require.resolve('babel-loader'),
            query: {
              presets: ['babel-preset-es2015'],
            }
          },

After this you should be able to run npm run build without any more issues.

Does Scatter-Js Adaptive for Safari?

Hi, We've tested Scatter-Js on Safari . but find it couldn't support DApp which domain contains https . Is there any solution for this problem ? Thank you very much !

Better error message when importing keys for EOS

Right now, when you import keys for an identity and the account does exist but the endpoint does not (for example because the network you are talking to does not have the history api plugin enabled) the error message is: "Account not found" but instead it should be "Endpoint not found" like the response from the eos chain.

Can I use scatter to transfer own coins between test accounts within private chain ?

I create the test coin 'SYS' within private chain. I want to transfer some 'SYS' between the test accounts by use scatter api. I use transfer by this code:
transfer() {
const account = scatter.identity.accounts.find(x => x.blockchain === 'eos');
const opts = { authorization:[${account.name}@${account.authority}] };
eos.transfer(account.name, 'user1', '1.0000 SYS', '', opts).then(trx => {
console.log('trx', trx);
}).catch(err => {
console.error(err);
})
};

but it throw error with this:
apigen.js:107 POST http://192.168.1.107:8888/v1/chain/push_transaction 500 (Internal Server Error)
App.vue:154 trx-err {"code":500,"message":"Internal Service Error","error":{"code":3090003,"name":"unsatisfied_authorization","what":"Provided keys, permissions, and delays do not satisfy declared authorizations","details":[]}}

What's wrong with this code ? Can't scatter transfer private coins within private chain ? or other reason?

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.