Code Monkey home page Code Monkey logo

nem-apps-lib's Introduction

NEM Apps Library

Java API library for NEM.io blockchain platform. This directly calls the https://github.com/NEMModules/nem.core that then calls the endpoints based on https://bob.nem.ninja/docs/

Library has the following features/functionalities

  • Initiate a transfer transactoin (including mosaic)
  • Initiate a multisig transaction (including mosaic)
  • Cosign a multisig transaction
  • Configurable Custom Fee Calculation
  • Get All Transaction (Confirmed/Unconfirmed/Incoming/Outgoing) for an Account
  • Get All Owned Mosaics of an Account
  • Get Block and Chain Info
  • Node Information and Check Node Heartbeats
  • Transaction Monitoring (using nem-transaction-monitor)

Technology Stack

  • Java 1.8
  • nem.core

How to build

Make sure to clone NEMModules fork of nem.core and build.
git clone https://github.com/NEMPH/nem.core.git
cd nem.core
mvn clean install

build the nem-apps-lib after.

git clone https://github.com/NEMPH/nem-apps-lib.git
cd nem-apps-lib
mvn clean install

Import it as a maven dependency

<dependency>
    <groupId>io.nem.apps</groupId>
    <artifactId>nem-apps-lib</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

Configuration Setup

Before starting, make sure you have the node endpoint is all set. Note that this should only be called once.

ConfigurationBuilder.nodeNetworkName("<network name>")
    .nodeNetworkProtocol("http")
    .nodeNetworkUri("<node url>")
    .nodeNetworkPort("7895")
    .setup();
    

You can also change the node endpoint on the fly.

Globals.setNodeEndpoint(new NodeEndpoint("http","<node url>",7895));

Transactions

Use the following set of builders to create transactions.

Transfer Transaction

TransferTransactionBuilder.sender(new Account(this.senderPrivateKeyPair))
    .recipient(new Account(this.recipientPublicKeyPair))
    .amount(0l)
    .buildAndSendTransaction();

Multisig Transaction

TransferTransaction transaction = TransferTransactionBuilder
    .sender(new Account(this.senderPrivateKeyPair)) // multisig account
    .recipient(new Account(this.recipientPublicKeyPair)) 
    .amount(0l)
    .buildTransaction();
    
MultisigTransactionBuilder.sender(this.senderPrivateAccount) // co-signer as sender
    .otherTransaction(transaction)
    .buildAndSendMultisigTransaction();
	

MultisigSignature Transaction

Single Signer

MultisigSignatureTransactionBuilder.multisig(this.multisigPublicAccount) // multisig account
    .signer(this.senderPrivateAccount) // signer
    .otherTransaction(Hash.fromHexString("hash")) // hash
    .buildMultisigSignatureTransaction();

Multiple Signer

MultisigSignatureTransactionBuilder.multisig(this.multisigPublicAccount) // multisig
		.startAssignSigners()
			.addSigner(this.senderPrivateAccount1) // signer 1
			.addSigner(this.senderPrivateAccount2) // signer 2
		.endAssignSigners()
	.otherTransaction(Hash.fromHexString("hash"))
	.coSign();

Transaction Callbacks

Developers can catch callbacks before and after a transaction is made. All the developer needs to do is define a Callback class and use it either on per Transaction or for All Transaction.

Fee Calculation

Fees can be calculated either on a Global level or per transaction.

Global Level Fees

Fees can also be configurable. With the API, the developers can put in their own Fee Calculation on either per Transaction or for All Transaction.

ConfigurationBuilder.nodeNetworkName("<network name>").nodeNetworkProtocol("http")
	.nodeNetworkUri("<node url>").nodeNetworkPort("7895")
	.transactionFee(new TransactionFeeCalculatorAfterFork()) // global
	.setup();

Transaction Level Fees

Fee on the Transaction

fee can also be set on the transaction level via the fee() method.

TransferTransactionBuilder
    .sender(new Account(this.senderPrivateKeyPair))
    .recipient(new Account(this.recipientPublicKeyPair))
    .amount(0l)
    .fee(Amount.fromMicroNem(0l)) // fee
    .buildAndSendTransaction();

Fee Calculation via Fee Calculation Object

fee calculation can also be set on the transaction level using the feeCalculator() method.

TransferTransactionBuilder
    .sender(new Account(this.senderPrivateKeyPair))
    .recipient(new Account(this.recipientPublicKeyPair))
    .amount(0l)
    .feeCalculator(new TransactionFeeCalculatorAfterForkForApp()) // custom fee calculator
    .buildAndSendTransaction();

Decode/Encode Secure Message/Payload

Use the following static methods to encode and decode Secure Message Payloads.

Encode

SecureMessageEncoder.encode(Account senderPrivateKey, Account recipientPublicKey, String message) 
//or 
SecureMessageEncoder.encode(String senderPrivateKey, String recipientPublicKey, String message) 

Decode

SecureMessageDecoder.decode(Account recipientPrivateKey, Account senderPublicKey, String encryptedPayload) SecureMessageDecoder.decode(Account recipientPrivateKey, Account senderPublicKey, byte[] encryptedPayload) 
//or 
SecureMessageDecoder.decode(String recipientPrivateKey, String senderPublicKey, String encryptedPayload)
SecureMessageDecoder.decode(String recipientPrivateKey, String senderPublicKey, byte[] encryptedPayload) 

Data Encryption (Encrypt/Decrypt) from nem.core

CryptoEngine engine = CryptoEngines.ed25519Engine();

//encrypt
byte[] encrypted = engine
		.createBlockCipher(
				new KeyPair(PrivateKey.fromHexString(xPvkey), engine),
				new KeyPair(PublicKey.fromHexString(xPubkey), engine))
		.encrypt("hello".getBytes());

// decrypt
byte[] decrypted = engine
		.createBlockCipher(
				new KeyPair(PublicKey.fromHexString(xPubkey), engine),
				new KeyPair(PrivateKey.fromHexString(xPvkey), engine)).decrypt(encrypted);

Accounts

Generate a new Account

GeneratedAccount AccountApi.generateAccount()

Get Account Info using Address

AccountMetaDataPair AccountApi.getAccountByAddress(String address) 

Get All Transactions for an Account

List<TransactionMetaDataPair> AccountApi.getAllTransactions(String address)

Get All Confirmed Transactions for an Account

List<TransactionMetaDataPair> AccountApi.getAllConfirmedTransactions(String address)

Get All Unconfirmed Transactions for an Account

List<TransactionMetaDataPair> AccountApi.getAllUnconfirmedTransactions(String address)

Get All Incoming Transactions for an Account

List<TransactionMetaDataPair> AccountApi.getIncomingTransactions(String address)

Get All Outgoing Transactions for an Account

List<TransactionMetaDataPair> AccountApi.getOutgoingTransactions(String address)

Get All Mosaics for an Account

List<Mosaic> AccountApi.getAccountOwnedMosaic(String address)

Blocks

Get Block by Block Height

Block BlockApi.getBlockByHeight(int blockHeight)

Get Block After Given Block Height

Block getBlockAfterGivenBlockHeight(int height) 

Chains

Get Chain Height

Block ChainApi.getChainHeight()

Get Chain Last Score

Block ChainApi.getChainScore()

Get Chain Last Block

Block ChainApi.getChainLastBlock()

Validations

Validate if Address is Valid

boolean ValidationApi.isAddressValid(String address)
boolean ValidationApi.isAddressValid(String address, NodeEndpoint nodeEndpoint)
boolean ValidationApi.isAddressValid(String address, String protocol, String host, int port)
boolean ValidationApi.isAddressPatternValid(String address)

Nodes

Check Node Info

Node NodeApi.getNodeInfo()

Check Node Extenteded Info

NisNodeInfo NodeApi.getNodeExtendedInfo()

Check Nem Node Heartbeat

NemRequestResult NodeApi.getNemNodeHeartBeat()

Incorporating Transaction Monitor

You can incorporate the nem-transaction-monitor library to monitor the transactions that's coming in.
git clone https://github.com/NEMPH/nem-transaction-monitor.git
cd nem-transaction-monitor
mvn clean install

Import maven dependency

<dependency>
    <groupId>io.nem.apps</groupId>
    <artifactId>nem-transaction-monitor</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>
WsNemTransactionMonitor.init().host("<node url>").port("7895").wsPort("7778")
	.addressToMonitor("MDYSYWVWGC6JDD7BGE4JBZMUEM5KXDZ7J77U4X2Y") // address to monitor
	.subscribe(io.nem.utils.Constants.URL_WS_TRANSACTIONS, new TransactionMonitor()) // multiple subscription and a handler
	.subscribe(io.nem.utils.Constants.URL_WS_UNCONFIRMED, new UnconfirmedTransactionMonitor())
	.monitor(); // trigger the monitoring process

Custom Transaction Monitor

You can create your own handler to handle the incoming payload.
public class CustomTransactionMonitor implements TransactionMonitorHandler {
	@Override
	public Type getPayloadType(StompHeaders headers) {
		return String.class;
	}
	@Override
	public void handleFrame(StompHeaders headers, Object payload) {
		System.out.println(payload.toString()); // handle the payload.
	}
}

Support

Need help integration your Java Application with NEM.io Platform? I can definitely help you with that, send me a message via

telegram

Tips are appreciated but not required. :bowtie: ๐Ÿ’ช ๐Ÿค˜
XEM: NA6IT2-ZSTQLT-YO223Z-ZMH2J7-2GVG7G-ZY72FN-47IF
BTC: 3JYAYPxN9RL4UvbxMd1svbQynMpFbf5ehy

Copyright (c) 2017

nem-apps-lib's People

Contributors

kilerixs avatar

Stargazers

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

Watchers

 avatar  avatar

nem-apps-lib's Issues

One Primary account

Can i create one primary wallet and then create its sub address in nem blockchain ? So that all balance can be consolidate in one account ?

Send failed for NEW Address

Hi,
My user can add his other NEM wallet's address which can be new, so below code is not working since not able to get public key using KeyConvertor.getPublicKeyFromAddress().

		NemAnnounceResult result = TransferTransactionBuilder
			    .sender(new Account(new KeyPair(PrivateKey.fromHexString("---private key----")))) 
			    .recipient(new Account(new KeyPair(PublicKey.fromHexString(**KeyConvertor.getPublicKeyFromAddress**("TCX3DLZ4YEJF2YRPXFG3VN6R2Y5ZEFUH32VADHXH")))))
			    .amount(Amount.fromMicroNem( amount.multiply(BigDecimal.valueOf(MICRONEMS_IN_NEM)).longValue()))
			    .fee(Amount.fromMicroNem( fee.multiply(BigDecimal.valueOf(MICRONEMS_IN_NEM)).longValue()) )
			    .buildAndSendTransaction();

How to send coins in above case ?
Please help me.
Thanks.

java.lang.IllegalArgumentException: trying to add a signature with an unexpected debtor

when i use 'BlockApi.getBlockByHeight()' to get block 1711952, nothing wrong, but block 1711953, this error happened... , can you help me ???

java.lang.IllegalArgumentException: trying to add a signature with an unexpected debtor
	at org.nem.core.model.MultisigTransaction.addSignature(MultisigTransaction.java:82)
	at org.nem.core.model.MultisigTransaction.lambda$new$0(MultisigTransaction.java:50)
	at java.util.ArrayList.forEach(ArrayList.java:1257)
	at org.nem.core.model.MultisigTransaction.<init>(MultisigTransaction.java:50)
	at org.nem.core.model.TransactionFactory.deserialize(TransactionFactory.java:72)
	at org.nem.core.model.TransactionFactory.lambda$static$0(TransactionFactory.java:17)
	at org.nem.core.serialization.JsonDeserializer.deserializeObject(JsonDeserializer.java:147)
	at org.nem.core.serialization.JsonDeserializer.readOptionalObjectArray(JsonDeserializer.java:139)
	at org.nem.core.serialization.Deserializer.readObjectArray(Deserializer.java:279)
	at org.nem.core.model.Block.<init>(Block.java:79)

Balance not reflected in Nem block chain

I'm transferring Nem of First user to Second nem user by using TransferTransactionBuilder. it will create the hash for me. but balance not reflect in Second user account

TransferTransactionBuilder
.sender(new Account(privatekeyPair))
.recipient(new Account(publicKeyPair))
.amount(Amount.fromMicroNem(actualtransferAmount))
.buildAndSendTransaction().getTransactionHash().toString();

Can't not create mutiple client in multiple thread

Hi,
I gona write a web server application that handle large number of requests to 2 NodeEndpoints ( Eg.
http://NODE1:7895 and http://NODE2:7895 ) . I found that there is only one option for node endpoint in Global variable which can not be applied in multiple-thread environment.

Globals.setNodeEndpoint(new NodeEndpoint("http","NODE1",7895));

What's should I do?
Thanks

mvn compilation error

hi, I issued mvn install, and hit errors as following, could you help:
[ERROR] /v:/git_github/nem-apps-lib/src/main/java/io/nem/apps/api/NamespaceMosaicsApi.java:[37,88] cannot find symbol
[ERROR] symbol: variable NIS_REST_NAMESPACE_ROOT_PAGE
[ERROR] location: class org.nem.core.connect.client.NisApiId
[ERROR] /v:/git_github/nem-apps-lib/src/main/java/io/nem/apps/api/NamespaceMosaicsApi.java:[60,88] cannot find symbol
[ERROR] symbol: variable NIS_REST_NAMESPACE_MOSAIC_DEFINITION_PAGE
[ERROR] location: class org.nem.core.connect.client.NisApiId
[ERROR] /v:/git_github/nem-apps-lib/src/main/java/io/nem/apps/api/NamespaceMosaicsApi.java:[89,88] cannot find symbol
[ERROR] symbol: variable NIS_REST_NAMESPACE_ROOT_PAGE
[ERROR] location: class org.nem.core.connect.client.NisApiId
[ERROR] /v:/git_github/nem-apps-lib/src/main/java/io/nem/apps/api/NamespaceMosaicsApi.java:[113,41] cannot find symbol
[ERROR] symbol: variable NIS_REST_NAMESPACE_ROOT_PAGE
[ERROR] location: class org.nem.core.connect.client.NisApiId
[ERROR] /v:/git_github/nem-apps-lib/src/main/java/io/nem/apps/api/NamespaceMosaicsApi.java:[134,88] cannot find symbol
[ERROR] symbol: variable NIS_REST_NAMESPACE
[ERROR] location: class org.nem.core.connect.client.NisApiId
[ERROR] /v:/git_github/nem-apps-lib/src/main/java/io/nem/apps/api/NamespaceMosaicsApi.java:[160,41] cannot find symbol
[ERROR] symbol: variable NIS_REST_NAMESPACE_MOSAIC_DEFINITION_PAGE
[ERROR] location: class org.nem.core.connect.client.NisApiId
[ERROR] /v:/git_github/nem-apps-lib/src/main/java/io/nem/apps/api/NamespaceMosaicsApi.java:[209,41] cannot find symbol
[ERROR] symbol: variable NIS_REST_NAMESPACE_MOSAIC_DEFINITION_PAGE
[ERROR] location: class org.nem.core.connect.client.NisApiId
[ERROR] /v:/git_github/nem-apps-lib/src/main/java/io/nem/apps/api/NamespaceMosaicsApi.java:[236,88] cannot find symbol
[ERROR] symbol: variable NIS_REST_NAMESPACE_MOSAIC_DEFINITION_PAGE
[ERROR] location: class org.nem.core.connect.client.NisApiId

Pad block corrupted

I had follow these steps:
git clone https://github.com/NEMPH/nem.core.git
cd nem.core
mvn clean install

org.bouncycastle.crypto.InvalidCipherTextException: pad block corrupted
at org.bouncycastle.crypto.paddings.PKCS7Padding.padCount(Unknown Source)
at org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher.doFinal(Unknown Source)
at org.nem.core.crypto.ed25519.Ed25519BlockCipher.transform(Ed25519BlockCipher.java:84)
at org.nem.core.crypto.ed25519.Ed25519BlockCipher.decrypt(Ed25519BlockCipher.java:77)
at org.nem.core.crypto.BlockCipherStressITCase.stressCipherSingleIteration(BlockCipherStressITCase.java:50)
at org.nem.core.crypto.BlockCipherStressITCase.stressCipher(BlockCipherStressITCase.java:26)
at org.nem.core.crypto.BlockCipherStressITCase.ed25519EngineCipherCannotBeCracked(BlockCipherStressITCase.java:12)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:264)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:153)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:124)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:200)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:153)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)

Failed to build

when try to build it give below errors:

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 0.407 s
[INFO] Finished at: 2018-04-04T16:59:14+05:30
[INFO] Final Memory: 8M/303M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal on project nem-apps-lib: Could not resolve dependencies for project io.nem.apps:nem-apps-lib:jar:0.0.1-SNAPSHOT: The following artifacts could not be resolved: org.nem.core:nem-core:jar:0.6.93-BETA, org.nem.core:nem-core:jar:tests:0.6.93-BETA: Failure to find org.nem.core:nem-core:jar:0.6.93-BETA in https://repo.maven.apache.org/maven2 was cached in the local repository, resolution will not be reattempted until the update interval of central has elapsed or updates are forced -> [Help 1]

Failed to build

After I builded nem.core then i build nem-apps-lib failed error log detail below :

Test set: io.nem.apps.main.Ed25519CryptoEngineTest

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.003 sec <<< FAILURE!
testSign(io.nem.apps.main.Ed25519CryptoEngineTest) Time elapsed: 0.003 sec <<< ERROR!
java.io.FileNotFoundException: File 'D:\Projects\eworkspace\proximaxsdks\xpx-java-sdk\git_push.sh' does not exist
at org.apache.commons.io.FileUtils.openInputStream(FileUtils.java:299)
at org.apache.commons.io.FileUtils.readFileToByteArray(FileUtils.java:1763)
at io.nem.apps.main.Ed25519CryptoEngineTest.testSign(Ed25519CryptoEngineTest.java:28)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:44)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:180)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:41)
at org.junit.runners.ParentRunner$1.evaluate(ParentRunner.java:173)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.run(ParentRunner.java:220)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:252)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:141)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:112)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.apache.maven.surefire.util.ReflectionUtils.invokeMethodWithArray(ReflectionUtils.java:189)
at org.apache.maven.surefire.booter.ProviderFactory$ProviderProxy.invoke(ProviderFactory.java:165)
at org.apache.maven.surefire.booter.ProviderFactory.invokeProvider(ProviderFactory.java:85)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:115)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:75)

Please show me how to fix this error thanks alots

BUILD FAILURE

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 3.162 s
[INFO] Finished at: 2018-06-14T11:50:20+05:00
[INFO] Final Memory: 22M/324M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12.4:test (default-test) on project nem-apps-lib: There are test failures.
[ERROR]
[ERROR] Please refer to /home/dokotov/nem-apps-lib/target/surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

help

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.