Giter Club home page Giter Club logo

bitsharesjs's Introduction

BitsharesJS (bitsharesjs)

Pure JavaScript Bitshares library for node.js and browsers. Can be used to construct, sign and broadcast transactions in JavaScript, and to easily obtain data from the blockchain via public apis.

Most of this code was written by jcalfee, my work was mostly just repackaging to a discrete npm package.

npm version npm downloads

Setup

This library can be obtained through npm:

npm install bitsharesjs

Usage

Three sub-libraries are included: ECC, Chain and Serializer. Generally only the ECC and Chain libraries need to be used directly.

Chain

This library provides utility functions to handle blockchain state as well as a login class that can be used for simple login functionality using a specific key seed.

Login

The login class uses the following format for keys:

keySeed = accountName + role + password

Using this seed, private keys are generated for either the default roles active, owner, memo, or as specified. A minimum password length of 12 characters is enforced, but an even longer password is recommended. Three methods are provided:

generateKeys(account, password, [roles])
checkKeys(account, password, auths)
signTransaction(tr)

The auths object should contain the auth arrays from the account object. An example is this:

{
    active: [
        ["GPH5Abm5dCdy3hJ1C5ckXkqUH2Me7dXqi9Y7yjn9ACaiSJ9h8r8mL", 1]
    ]
}

If checkKeys is successful, you can use signTransaction to sign a TransactionBuilder transaction using the private keys for that account.

State container

The Chain library contains a complete state container called the ChainStore. The ChainStore will automatically configure the set_subscribe_callback and handle any incoming state changes appropriately. It uses Immutable.js for storing the state, so all objects are return as immutable objects. It has its own subscribe method that can be used to register a callback that will be called whenever a state change happens.

The ChainStore has several useful methods to retrieve, among other things, objects, assets and accounts using either object ids or asset/account names. These methods are synchronous and will return undefined to indicate fetching in progress, and null to indicate that the object does not exist.

import {Apis} from "bitsharesjs-ws";
var {ChainStore} = require("bitsharesjs");

Apis.instance("wss://eu.nodes.bitshares.ws", true).init_promise.then((res) => {
    console.log("connected to:", res[0].network);
    ChainStore.init().then(() => {
        ChainStore.subscribe(updateState);
    });
});

let dynamicGlobal = null;
function updateState(object) {
    dynamicGlobal = ChainStore.getObject("2.1.0");
    console.log("ChainStore object update\n", dynamicGlobal ? dynamicGlobal.toJS() : dynamicGlobal);
}

ECC

The ECC library contains all the crypto functions for private and public keys as well as transaction creation/signing.

Private keys

As a quick example, here's how to generate a new private key from a seed (a brainkey for example):

var {PrivateKey, key} = require("bitsharesjs");

let seed = "THIS IS A TERRIBLE BRAINKEY SEED WORD SEQUENCE";
let pkey = PrivateKey.fromSeed( key.normalize_brainKey(seed) );

console.log("\nPrivate key:", pkey.toWif());
console.log("Public key :", pkey.toPublicKey().toString(), "\n");

Transactions

TODO transaction signing example

ESDoc (beta)

npm i -g esdoc esdoc-es7-plugin
esdoc -c ./esdoc.json
open out/esdoc/index.html

Binaries / Browserified bundles

Please have a look here to find your desired release. If you want to build the binaries yourself you can clone this repository and run npm install. It will create

  • Browserified version build/bitsharesjs.js
  • Browserified and minified (babel) version build/bitsharesjs.min.js
  • CommonJS version using webpack build/bitsharesjs.cjs

bitsharesjs's People

Contributors

abitmore avatar ammaryousefm avatar clockworkgr avatar dependabot[bot] avatar destenson avatar dot5enko avatar fgdfkgndj avatar grctest avatar hldzlk avatar iobanker avatar ioxbank avatar lanhaoxiang avatar pluswave avatar ppitonak avatar runestone0 avatar sschiessl-bcp avatar startailcoon avatar svk31 avatar verevkinalexander avatar vikramrajkumar avatar xeroc avatar xiangxn 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

Watchers

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

bitsharesjs's Issues

Function `to_long()` returns unexpected value when input is float with decimals

As mentioned in bitshares/bitshares-ui#3545 (comment), the function to_long() in SerializerValidation.js may return unexpected result if the input is a float with decimals (E.G. 12.999999999999998). Code:

to_long(value, field_name = "", unsigned = false) {
if (this.is_empty(value)) {
return value;
}
if (Long.isLong(value)) {
return value;
}
this.no_overflow64(value, field_name, unsigned);
if (typeof value === "number") {
value = "" + value;
}
return Long.fromString(value, unsigned);
},

> parseFloat("0.00013")*100000
12.999999999999998
> Long.fromString(""+parseFloat("0.00013")*100000)
Long { low: 1150981118, high: 30, unsigned: false }
> Long.fromString(""+parseFloat("0.00013")*100000).toString()
129999999998

To fix this, IMHO, as a library, we shouldn't change user input, but we should require the input to be valid.

Create a new release?

It has been more than a year since last release (6.0.0), and there are quite a few changes merged into in develop branch. I think it is about time to create a new release.

trailing zero different from js serilization and backend.

while broadcast the following transaction :

{"ref_block_num":44955,"ref_block_prefix":3677548938,"expiration":"2018-01-02T08:05:39","operations":[[0,{"fee":{"amount":"17246","asset_id":"1.3.113"},"from":"1.2.546038","to":"1.2.543188","amount":{"amount":"396000000","asset_id":"1.3.113"},"memo":{"from":"BTS67cQbPKZ6hiv9ALqyidDYqsVpjCVrC1uxEvSehE9BGiZ99q38N","to":"BTS6ZKYgqnkecVZLuMydtPSWw7NeiPtho22sED615uvxeTRMSawR2","nonce":"387809362826033","message":"a4470c032d27cd5d164f027d821f04914c5ec1f394169f386f6ad37969c05bad"},"extensions":[]}]],"extensions":[],"signatures":["2035795735adbe1a67d175782740ae0990c2340b98142fdfc9fe69156354b2863a50c7abb0e5365e3ffdd62a7d80c57e4101ad29b1b327dc4be1eaed9a97491389"]}

get "missing authority" failed, then I compared the transaction hash from backend and js lib, I found that the backend reports one more byte (0x00).

Here is the hash from backend (removed signatures key from the object):

9baf8af132db533d4b5a01005e4300000000000071f6a921d49321007b9a1700000000710102a17d86d0296a08424cc1cc70a012bd2325ab6a5133d5eeb016d938f6481cc21e02dbddcfffe7d63200f63494c205438253decc7b895c3119ae7c85aff7bccf0a0531d34fe7b560010020a4470c032d27cd5d164f027d821f04914c5ec1f394169f386f6ad37969c05bad000000

hash from js lib:

9baf8af132db533d4b5a01005e4300000000000071f6a921d49321007b9a1700000000710102a17d86d0296a08424cc1cc70a012bd2325ab6a5133d5eeb016d938f6481cc21e02dbddcfffe7d63200f63494c205438253decc7b895c3119ae7c85aff7bccf0a0531d34fe7b560010020a4470c032d27cd5d164f027d821f04914c5ec1f394169f386f6ad37969c05bad0000

I have no idea if it is a backend(seems like fc lib) or js lib issue, just report it here first.

To select WSS node with lowest latency

I am using BitsharesJS WS library to connect the Bitshare server. I wanted to use one or multi node server to connect Bitshare server with low latency.
I am not sure how to get available public WS nodes? and how to find the low latency among the public WS nodes?
Please suggest.

public/un-encrypted memo

If @ref from == @ref to and @ref from == 0 then no encryption is used, the memo is public.

https://github.com/bitshares/bitshares-core/blob/master/libraries/chain/include/graphene/chain/protocol/memo.hpp#L36

However, Im not able to set these params to null or undefined (void 0).
https://github.com/bitshares/bitsharesjs/blob/master/lib/serializer/src/operations.js#L393

BTW, I can still set the message to clear text as a workaround.

Is is a bug or I am missing anything?
Thank you,

Wrong prefix during transaction validation.

When I try to create an account_update transaction using a bitShares public key (example: BTS7yXA4684QDr9Rhz8JfTQEwcu8n8DJE4Z9WJ42GjpufCMVpfs6h), I get this error:

account_update.owner	 cause: authority.key_auths	 cause: Expecting key to begin with GPH, instead got B

How do I change the prefix check to BTS instead?

Beet - importing cloud account encounters 'digest method not supported'

BlockchainAPI.js:334 Error: Digest method not supported
at new Hash (node:internal/crypto/hash:67:19)
at createHash (node:crypto:130:10)
at ripemd160 (C:\Users\username\Desktop\git\beet\node_modules\bitsharesjs\dist\ecc\src\hash.js:47:37)
at PublicKey.toPublicKeyString (C:\Users\username\Desktop\git\beet\node_modules\bitsharesjs\dist\ecc\src\PublicKey.js:96:40)
at PublicKey.toString (C:\Users\username\Desktop\git\beet\node_modules\bitsharesjs\dist\ecc\src\PublicKey.js:82:17)
at BitShares.getPublicKey (BitShares.js:205:14)
at BlockchainAPI.js:332:38
at Array.forEach ()
at BitShares._callee$ (BlockchainAPI.js:322:31)
at tryCatch (C:\Users\username\Desktop\git\beet\node_modules\regenerator-runtime\runtime.js:63:40)
ImportCloudPass.vue:69

{key: 'invalid_key_error'}

Have newer versions of node dropped support for ripemd160?

Missing Fee for Proposed OP

The OP fee within a proposed operation is zero.

{
  "ref_block_num": 0,
  "ref_block_prefix": 0,
  "expiration": "1970-01-01T00:00:00",
  "operations": [
    [
      22,
      {
        "fee": {
          "amount": "88137",
          "asset_id": "1.3.0"
        },
        "fee_paying_account": "1.2.x",
        "expiration_time": "2018-12-03T17:29:30",
        "proposed_ops": [
          {
            "op": [
              0,
              {
                "fee": {
                  "amount": "0",
                  "asset_id": "1.3.0"
                },
                "from": "1.2.x",
                "to": "1.2.x",
                "amount": {
                  "amount": "100000",
                  "asset_id": "1.3.0"
                },
                "extensions": []
              }
            ]
          }
        ],
        "extensions": []
      }
    ]
  ],
  "extensions": [],
  "signatures": []
}

generateKeys() returns public keys with incorrect prefix if same account-password combination was already processed with it using another prefix

const bts = require('bitsharesjs');
undefined
bts.Login.generateKeys("randomaccount-777", "thisisafakepassword", ['active', 'owner', 'memo'], 'FAKEPREFIX').pubKeys
{ active: 'FAKEPREFIX6jhmykDHAfUyCLVBkjzYN2jdhdcNtXv3BrBr1u3byz2wphSBNh',
owner: 'FAKEPREFIX6xKHNcqgJnEdMETPcxxAaPZwfjiqgXPn7NHsCGMxTqcqb3HwNd',
memo: 'FAKEPREFIX5uUuJNu7i1F6Q9ZrFAhuVPnG5f8UcMoTdtjy3CRJxRQszkNA4U' }
bts.Login.generateKeys("randomaccount-777", "thisisafakepassword", ['active', 'owner', 'memo'], 'BTS').pubKeys
{ active: 'FAKEPREFIX6jhmykDHAfUyCLVBkjzYN2jdhdcNtXv3BrBr1u3byz2wphSBNh',
owner: 'FAKEPREFIX6xKHNcqgJnEdMETPcxxAaPZwfjiqgXPn7NHsCGMxTqcqb3HwNd',
memo: 'FAKEPREFIX5uUuJNu7i1F6Q9ZrFAhuVPnG5f8UcMoTdtjy3CRJxRQszkNA4U' }

Undefined instance shortly after initialization?

I'm suddenly getting the following error and I'm struggling to debug it, anyone run into this before?

TypeError: Cannot read properties of undefined (reading 'exec')
    at TransactionBuilder2.update_head_block (TransactionBuilder.js:318:48)

Triggering from: https://github.com/BTS-CM/airdrop_tool/blob/develop/src/pages/Create.jsx#LL101C29-L101C30

Fails here: https://github.com/BTS-CM/airdrop_tool/blob/develop/src/lib/generate.js#L53

example generate deeplink inputs:

{
    "chain": "BTS",
    "node": "wss://node.xbts.io/ws",
    "opType": "ticket_create",
    "opContents": {
        "account": "1.2.5",
        "target_type": 1,
        "amount": {
            "amount": 100000,
            "asset_id": "1.3.0"
        },
        "extensions": [],
        "fee": {
            "amount": 0,
            "asset_id": 0
        }
    }
}

Works here: https://github.com/BTS-CM/airdrop_tool/blob/main/src/pages/Create.jsx#L131 (Main branch)

Also works here: https://github.com/BTS-CM/beet-deeplinks/blob/main/examples/BTS/057_ticket_create.js

Would appreciate any help on this, once this error is resolved I'll be translating the locale strings and creating a new release with new features and additional locales. I wasn't expecting this to stop working..

Failed to sync with the API server Please verify that your computer clock is correct, gives error in ChainStore.js file

I am having error when in ChanStore.js file when i try to connect my own Witness node to the wallet by runing following command

./programs/witness_node/witness_node --rpc-endpoint="0.0.0.0:8090"

it gives following error , but it shows latency which means my Wallet is connected to Node but clock issue is there:

screenshclockot

and this is the error i am able to see in ChainStore.js file as follows:

screenshot from 2019-01-09 13-51-28

Note: i want to connect my own node to wallet, not anyothers nodes.
i have to connect only my specific node only.

I use 'get_trade_history', but get empty data, why?

Hi,

I use 'get_trade_history', but get empty data, why?

............................
 await tradeHistory("BTC", "BTS", "2018-04-01T01:00:00", "2018-04-30T01:00:00", 100).then((dict) => {
        console.log(dict);
    })
}

async function tradeHistory(base, quote, date_start, date_stop, limit) {
 
    return Apis.instance().db_api().exec("get_trade_history", [

                base, quote, date_start, date_stop, limit
        
            ]).then(dict => {
                return dict;
            }).catch(err => {
        
                console.log("err:", err);
        
    })
} 

Thanks

example request: how to get transaction id from processed transaction?

With the following example how do I get transaction hash of transaction returned from 'get_transaction' call?

import {Apis} from "bitsharesjs-ws";
import {ChainStore, FetchChain, PrivateKey, TransactionHelper, Aes, TransactionBuilder} from "bitsharesjs";

Apis.instance("wss://node.testnet.bitshares.eu/", true)
    .init_promise.then((res) => {
        console.log("connected to:", res[0].network_name, "network")

        return Apis.instance().db_api().exec( "get_transaction", [103,0] )
    }).then((res) => {
        // how do I get transaction hash here?
        console.log(res)
    });

How to import this library in an Angular App?

  1. I install the BitsharesJS and BitsharesJS-WS in my angular app
  2. Include bitsharesjs.js and bitshresjs-ws.js in angular.json of the app under "scripts"
  3. Include a custom JS file custom-ws.js in asset and include the same in angular.json
  4. In my custom-ws.js I am able to connect testnet server and can write methods to use db_api, history_api
  5. BUT I am not able to import bitsharesjs, to use account_create class for creating new user account.

Please help me to use classes in bitsharesjs in the custom js file / directly use the class in Angular component,

Can't decode memo.

When I try and decode a memo, I get:

/Users/username/Desktop/MD/node_modules/bitsharesjs/dist/ecc/src/PrivateKey.js:130
        var KB = public_key.toUncompressed().toBuffer();
                            ^

TypeError: Cannot read property 'toUncompressed' of null
    at PrivateKey.get_shared_secret (/Users/username/Desktop/MD/node_modules/bitsharesjs/dist/ecc/src/PrivateKey.js:130:29)
    at Function.decrypt_with_checksum (/Users/username/Desktop/MD/node_modules/bitsharesjs/dist/ecc/src/aes.js:97:29)
    at Object.<anonymous> (/Users/username/Desktop/MD/index.js:50:13)
    at Module._compile (module.js:660:30)
    at Object.Module._extensions..js (module.js:671:10)
    at Module.load (module.js:573:32)
    at tryModuleLoad (module.js:513:12)
    at Function.Module._load (module.js:505:3)
    at Function.Module.runMain (module.js:701:10)
    at startup (bootstrap_node.js:194:16)
    at bootstrap_node.js:618:3

the code is:

var a = Aes.decrypt_with_checksum(PrivateKey.fromWif("PRIVATEKEYHERE"),PublicKey.fromPublicKeyString("BTS7caZZCa1Eh6FU1eFbPa5t99Coa2xAsLB69KCr7MviwZU6jNgSa"),"392417103062207", "3cfd11f58f9c674d60fd7eb4e16b9a1d",false).toString("utf-8")
console.log(a)

Edit: If I pass in the Public Key as a raw sting, I get:

  throw new errors.AssertionError({
  ^

AssertionError [ERR_ASSERTION]: Expecting key to begin with GPH, instead got BTS
    at Function.fromStringOrThrow (/Users/username/Desktop/MD/node_modules/bitsharesjs/dist/ecc/src/PublicKey.js:132:26)

ESDOC geneterate fails:

Firstly esdoc-title isnt needed causes compile to fail.

Second compile fails with stack heap:::

==== JS stack trace =========================================

Security context: 0x295cf68cfb39
1: DoJoin(aka DoJoin) [native array.js:~129] [pc=0x2b374224ccbd] (this=0x295cf6804381 ,w=0xb50f3498c89 <JS Array[7]>,x=7,N=0x295cf68043c1 ,J=0xb50f347b8d1 <String[4]: ,\n >,I=0x295cf68b46c9 <JS Function ConvertToString (SharedFunctionInfo 0x295cf6852dc9)>)
2: Join(aka Join) [native array.js:180] [pc=0x2b3741b18032] (this=0x295cf6804381 ,w=0xb50f3498c89 <JS ...

FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
1: node::Abort() [node]
2: 0x109b7ac [node]
3: v8::Utils::ReportApiFailure(char const*, char const*) [node]
4: v8::internal::V8::FatalProcessOutOfMemory(char const*, bool) [node]
5: v8::internal::Factory::NewRawTwoByteString(int, v8::internal::PretenureFlag) [node]
6: v8::internal::Runtime_StringBuilderJoin(int, v8::internal::Object**, v8::internal::Isolate*) [node]
7: 0x2b3741a092a7
Aborted (core dumped)

Terminating a ws connection takes forever, why?

I am testing new reconnection strategy for UI and I found that it takes forever when ChainWebSocket recognizes that connection is dead until the rpc_connection_status in BlockchainStore is updated.

Why is that @svk31 ? You can test it by simply opening the UI and disabling the internet connection after connection has been established. Are there any timeouts involved that are possibly to high?

image

Cannot be used in "react native", will appear ”Unable to resolve module `stream`” and “can't find variable Buffer”

I'm working on a phone app to make "bitshares" available on the phone, but when I execute "npm install bitsharesjs," the program crashes every time I use "import {PublicKey} from / bitbitshares / s / es'".I think it may be that the "react native" running environment is inconsistent with the browser, resulting in incompatibility, which is my personal view, I hope the author can answer my question, thank you very much.

ConnectionManager

connectionManager.checkConnections()

Connection manager seems to produce inaccurate numbers when pinging multiple nodes at same time

Allow to load a raw transaction into a Transaction builder

I want to be able to load a raw transaction into a transaction builder process (the tx is constructed elsewhere).

What needs to be done:

function load_tx(tx) {
   var txbuilder = bitshares_js.TransactionBuilder;
   var ops = bitshares_js.serializer.ops

   var tr = new txbuilder()
   // I need to do this manually, this is usually done in `finalize` but then it replaces the expiration, and ref_block_* parameters, which i want to pass over manually!!!
   tr.tr_buffer = ops.transaction.toBuffer(tx);

   // load stuff outside operations
   tr.expiration = tx.expiration;
   tr.ref_block_num = tx.ref_block_num;
   tr.ref_block_prefix = tx.ref_block_prefix;

   //load operations
   for (var i=0; i< tx.operations.length; ++i) {
    tr.add_operation(tx.operations[i]);
   }

   return tx
}

Memo decrypt: TypeError: private_key.get_shared_secret is not a function

node -v 8.11.1

get the transaction history:

{ 
       from: '<BTS Address>',
       to: '<BTS Address>',
       nonce: '<random>',
       message: '<encrypted message>' 
}

What sequence of steps is needed to perform the decryption?

by doing:

let memo_text = Aes.decrypt_with_checksum(
          private_key,
          public_key,
          memo.nonce,
          memo.message
        ).toString("utf-8");

console.log(memo_text);

getting an error: ...
TypeError: private_key.get_shared_secret is not a function.
at Function.decrypt_with_checksum node_modules\bitsharesjs\dist\ecc\src\aes.js:97

Has anyone encountered a similar problem?

Tutorial regarding transaction?

  1. Is there any tutorial?
  2. What I am missing in the examples is how to create an account for a user.
    3.Is it production ready? Someone used the java script library?
  3. Cant find 'FetchChain' in documentation.

a special public key can't be in key_auths array: Missing Active Authority

The following public key can't be in key_auths array: (I generated with uptick randomwif)

BTS6agpGeRkc1zHD9MTbHaK9CKR1Pt8aU4v2GTxF6tRtf3ZC3TnU6

It is very strange that I tested the api for account_update with multi-signature, but if the above public key is in any key_auths array (either owner or active ) it will report the following error:

missing required active authority: Missing Active Authority 

Tested in node and browser , one account each. you can create a new account without asset, then add above active key. Normally it will report fee insufficient issue, but it reports the above issue.

I just posted this issue to wrong repo. bitshares/bitshares-js#94

AES Encrypt

aes.encryptToHex(encryption_buffer)
AES encryption results are 96 bits。
How to do at iOS or Objective-C?

Multipackage repo for all bitshares JS?

The JavaScript packages in the bitshares org https://github.com/bitshares might be better organized, easier to understand, more cohesive and easier to publish as a monorepo using tools like yarn workspaces and lerna. Is there a document that explains how bitshares-ui, bitsharesjs, bitsharesjs-ws, bitshares-js, bitshares-ui-api, perfect-scrollbar, reconnecting-websocket, etc are related to eachother. As a newbie, I'm having a hard time understanding what is what.

I'm looking to get a little bit of data from the blockchain. I think this (bitshares/bitsharesjs) is the package I care about at the moment. But, I look at all the nice modules in bitshares-ui https://github.com/bitshares/bitshares-ui/tree/staging/app/components and can't help but think that some might be able to be released to npm as separate modules... The only way this would be practical is if a tool like lerna is used to publish.

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.