Code Monkey home page Code Monkey logo

unity-solana-wallet's Introduction

Unity-Solana Wallet

The First Open-Source Unity-Solana Wallet with NFT support

The Unity-Solana Wallet is an essential bridge connecting game developers and the Solana blockchain. With Solana’s quick and low-cost transactions, games can start using blockchain technology like never before - in real-time. Thousands of developers will bring millions of players into the Solana ecosystem. This will, in turn, make the Solana projects benefit from an increased number of participants, and cross-protocol interoperability in games will take us beyond the current understanding of DeFi.

Unity-Solana Wallet uses Solnet's implementation .NET SDK, but we had to modify the library to make it Unity compatible with .NET Standard 2.0 and .NET 4.x. Solnet is Solana's .NET SDK to integrate with the .NET ecosystem. Solnet.

Features

  • Create/Backup wallet with mnemonic phrase
  • Account handling
  • Transaction building
  • SOL balance
  • SPL-token balances
  • SPL-token transfers
  • Basic UI examples
  • WebSocket subscription
  • Save and load mnemonics from local txt file
  • Save private key in txt file

Dependencies

  • Newtonsoft.Json
  • Chaos.NaCl.Standard
  • Portable.BouncyCastle
  • Zxing

External packages

  • Native File Picker
  • Standalone File Browser

Roadmap

  • Multiple wallet accounts
  • Camera support with QR code scanning for token transfers
  • Improved UI for in-game easy integration
  • Metaplex NFT / NFT-PRO support with GameObjects
  • Token swaps
  • NFT swaps
  • One-click in-game currency creator
  • Themed UI support
  • Metaplex auctions for in-game store items

Installation

  1. Clone this repository outside of the main Unity project
  2. Go to Package Manager in your project
  3. Click on the plus in the top left corner and select "Add package from disk"
  4. Select package.json file from a cloned dir
  5. Once the package is installed, in the Package Manager inspector you will have Samples. Click on Import

Step-by-step instructions

  1. If you have an older version of Unity that doesn't have imported Newtonsoft.Json just import it.
  2. After importing the wallet Unity will throw unity-plastic error. Just restart Unity.
  3. Create a new scene.
  4. Import WalletController prefab into your scene.
  5. Set Client Source (Mainnet/Testnet/Devnet/Custom uri) and Storage Method (Json/Simple txt) on SimpleWallet script in WalletController prefab.
  6. If you use custom URI be careful to use WS/WSS instead of HTTP/HTTPS because WebSocket does not work with HTTP / HTTPS.
  7. To save mnemonics in JSON format, select the JSON storage method, and if you want to save it as a regular string, select Simple Txt.
  8. If you want to use mnemonics saved in JSON format, you must deserialize it first. You have an example in ReGenerateAccountScreen.cs in the ResolveMnemonicsByType method.
  9. Create new Canvas
  10. Import WalletHolder prefab into the Canvas or if you want your design just import wallet prefab and customize the scene like we did with WalletHolder.

Functionalities description

Login Screen

  • If you have already logged in to your wallet, then your mnemonics are stored and encrypted in memory with your password and you can log in with that password. Otherwise you have to create or restore a wallet.

Create Wallet Screen

  • You now have automatically generated mnemonics and to successfully create a wallet you must enter a password with which the mnemonics will be encrypted. I recommend that you use the Save Mnemonics option and save them to a text file. Then press create button to create a wallet.

Regenerate Wallet Screen

  • If you have saved mnemonics and want to recreate a wallet with it, load them by pressing Load Mnemonics button and generate the password again. Now your wallet is regenerated and the amount of SOL and NFT will be reloaded.

Wallet Screen

  • After you successfully logged in / generated / regenerated a wallet you will automatically be transferred to the wallet screen. Now you are shown SOL balance and your NFT's and you are automatically subscribed to the account via the websocket. This allows you to track changes in your account (automatic refreshing of SOL balance when a balance changes, etc..).

Recieve Screen

  • To facilitate testing, there is an Airdrop option in the Recieve section. Click on the Airdrop button, return to the Wallet Screen and wait a few seconds to see the change in SOL balance.

Transfer Screen

  • To complete the transaction enter the wallet pubkey and the amount you want to send. Then return to the wallet screen and wait a few seconds for the SOL Balance to refresh.

Introduction to WalletBaseComponent.cs

  • This class is located at Packages -> Solana Wallet -> Runtime -> codebase -> WalletBaseComponent.cs

Create account

public async void CreateAccount(Account account, string toPublicKey = "", long ammount = 1000)
  • First create keypair(private key and public key),
  • Then create blockHash from activeRpcClient,
  • Initialize transaction
  • Send transaction

Start connection

public SolanaRpcClient StartConnection(EClientUrlSource clientUrlSource, string customUrl = "")
  • For starting RPC connection call StartConnection and forward clientSource.
  • Function returns new connected RPC client.
  • Call example
StartConnection(clientSource);

Generate wallet with mnemonics

 public Wallet GenerateWalletWithMenmonic(string mnemonics)
  • First check forwarded mnemonics validity.
  • Encrypt mnemonics with password
  • Create new wallet from mnemonics
  • Subscribe to WebSocket
  • Save mnemonics and encrypted mnemonics in memory
  • Call example
SimpleWallet.instance.GenerateWalletWithMenmonic(_simpleWallet.LoadPlayerPrefs(_simpleWallet.MnemonicsKey));

Login check with mnemonics and password

 public bool LoginCheckMnemonicAndPassword(string password)
  • Try to encrypt decrypted mnemonics with typed password.
  • Return true or false
  • Call example
private void LoginChecker()
{
    if (_simpleWallet.LoginCheckMnemonicAndPassword(_passwordInputField.text))
    {
        SimpleWallet.instance.GenerateWalletWithMenmonic(_simpleWallet.LoadPlayerPrefs(_simpleWallet.MnemonicsKey));
        MainThreadDispatcher.Instance().Enqueue(() => { _simpleWallet.StartWebSocketConnection(); }); 
        manager.ShowScreen(this, "wallet_screen");
        this.gameObject.SetActive(false);
    }
    else
    {
        SwitchButtons("TryAgain");
    }
}

Get sol amount

public async Task<double> GetSolAmmount(Account account)
  • Returns sol amount of forwarded account
  • Call example
double sol = await SimpleWallet.instance.GetSolAmmount(SimpleWallet.instance.wallet.GetAccount(0));

Transfer sol

public async Task<RequestResult<string>> TransferSol(string toPublicKey, long ammount = 10000000)
  • Executes sol transaction from one account to another one for forwarded amount.
  • Call example
private async void TransferSol()
{
    RequestResult<string> result = await SimpleWallet.instance.TransferSol(toPublic_txt.text, long.Parse(ammount_txt.text));
    HandleResponse(result);
}

Transfer token

public async Task<RequestResult<string>> TransferToken(string sourceTokenAccount, string toWalletAccount, Account sourceAccountOwner, string tokenMint, long ammount = 1)
  • Executes SOL transaction from one account to another one
  • Call example
private async void TransferToken()
{
    RequestResult<string> result = await SimpleWallet.instance.TransferToken(
                        transferTokenAccount.pubkey,
                        toPublic_txt.text,
                        SimpleWallet.instance.wallet.GetAccount(0),
                        transferTokenAccount.Account.Data.Parsed.Info.Mint,
                        long.Parse(ammount_txt.text));

    HandleResponse(result);
}

Request airdrop

public async Task<string> RequestAirdrop(Account account, ulong ammount = 1000000000)
  • Send 1 sol to our wallet (this is for testing).
  • Call example
airdrop_btn.onClick.AddListener(async () => {
            await SimpleWallet.instance.RequestAirdrop(SimpleWallet.instance.wallet.GetAccount(0));
        });

Get owned token accounts

public async Task<TokenAccount[]> GetOwnedTokenAccounts(Account account)
  • Returns array of tokens on the account
  • Call example
TokenAccount[] result = await SimpleWallet.instance.GetOwnedTokenAccounts(SimpleWallet.instance.wallet.GetAccount(0));

Delete wallet and clear key

public void DeleteWalletAndClearKey()
  • Unsubscribe from WebSocket events
  • Delete used wallet

Start WebSocket connection

public void StartWebSocketConnection()
  • Starts WebSocket connection when user is logged in.

Introduction to WebsocketService.cs

  • This class is located at Packages -> Solana Wallet -> Runtime -> UnityWebSocket -> WebSocketService.cs

Start connection

public void StartConnection(string address)
  • For WebSocket to work we must first create a connection calling StartConnection from WebSocketService.cs and forward address
  • In this function we create new WebSocket, then subscribe to events and open WebSocket connection.
  • Call example
 webSocketService.StartConnection(GetWebsocketConnectionURL(clientSource));

Subscribe to wallet account events

 public void SubscribeToWalletAccountEvents(string pubKey)
  • To subscribe Account on WebSocket events call function SubscribeToWalletAccountEvents and forward Wallet Pub key
  • First set subscriptionTypeReference to know which event we are processing (in this case it is accountSubscribe).
  • Then call SendParameter and forward parameter for account subscription.
  • Call example
 webSocketService.SubscribeToWalletAccountEvents(wallet.Account.GetPublicKey);

Unsubscribe to wallet account events

 public void UnSubscribeToWalletAccountEvents()
  • To unsubscribe Account from WebSocket events call function UnsubscribeToWalletAccountEvents
  • First set subscriptionTypeReference to know which event we are processing (in this case it is accountUnsubscribe).
  • Then call SendParameter and forward parameter for account unsubscription.
  • Call example
public void StartWebSocketConnection()
{
    if (webSocketService.Socket != null) return;

    webSocketService.StartConnection(GetWebsocketConnectionURL(clientSource));
}

On Message

private void OnMessage(object sender, MessageEventArgs e)
  • To respond to websocket events we use WebSocket actions that we call in OnMessage function
  • Depending on the SubscriptionTypeReference, we deserialize the message into a model.
  • Invoke WebSocketAction
  • Then subscribe the desired functionality to the action
 WebSocketActions.WebSocketAccountSubscriptionAction += CheckSubscription;

Close connection

 public void CloseConnection()
 {
     if (_socket == null) return;

     _socket.CloseAsync();
 }

-To close WebSocket connection call CloseConnection from WebSocketService.cs

Introduction to Nft.cs

  • This class is located at Packages -> Solana Wallet -> Runtime -> codebase -> nft -> Nft.cs

Try get nft data

public static async Task<Nft> TryGetNftData(string mint, SolanaRpcClient connection, bool tryUseLocalContent = true)
  • Returns all data for one NFT and save file to persistance data path
  • Call example
Nft.Nft nft = await Nft.Nft.TryGetNftData(item.Account.Data.Parsed.Info.Mint, SimpleWallet.instance.activeRpcClient, true);

Try load nft from local

public static Nft TryLoadNftFromLocal(string mint)
  • Returns nft data from local machine if it exists.
  • Call example
if (tryUseLocalContent)
{ 
    Nft nft = TryLoadNftFromLocal(mint);
    if (nft != null)
    {
        return nft;
    }
}

Create address

public static Solnet.Wallet.PublicKey CreateAddress(List<byte[]> seed, string programId)
  • Create NFT's public key from seed and programId
  • Call example
try
{
     seeds[3] = new[] { (byte)nonce };
     publicKey = CreateAddress(seeds, programId);
     return publicKey;
}

Find program address

public static Solnet.Wallet.PublicKey FindProgramAddress(string mintPublicKey, string programId = "metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s")
  • Returns metaplex data pubkey from mint pubkey and programId
  • Call example
Solnet.Wallet.PublicKey metaplexDataPubKey = FindProgramAddress(mint);

Get metaplex Json data

public static async Task<T> GetMetaplexJsonData<T>(string jsonUrl)
  • Returns metaplex json data from forwarded jsonUrl

Resize

private static Texture2D Resize(Texture2D texture2D, int targetX, int targetY)
  • Compress nft image to target height and width.
  • Call example
Texture2D compressedTexture = Resize(texture, 75, 75);

License

This project is licensed under the MIT License - see the LICENSE file for details

unity-solana-wallet's People

Contributors

berial42 avatar vuckovic95 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

unity-solana-wallet's Issues

save mnemonics Unable to save

when I try to save mnemonics it doesn't let me save, instead, it's looking for a file to open? Does anyone have that issue with the latest sdk?

Error right after importing package - Multiple precompiled assemblies with the same name Newtonsoft.Json.dll included or the current platform. Only one assembly with the same name is allowed per platform. (C:/Users/37067/Desktop/New Unity Project/Library/PackageCache/[email protected]/Runtime/Newtonsoft.Json.dll)

Error right after importing package - Multiple precompiled assemblies with the same name Newtonsoft.Json.dll included or the current platform. Only one assembly with the same name is allowed per platform. (C:/Users/37067/Desktop/New Unity Project/Library/PackageCache/[email protected]/Runtime/Newtonsoft.Json.dll)

Mint NFT

Is it possible to mint an NFT here?

Errors: The modifier 'public' is not valid for this item

unity-solana-wallet-main\Runtime\codebase\nft\nft_interfaces\iNftFile.cs(4,23): error CS0106: The modifier 'public' is not valid for this item
unity-solana-wallet-main\Runtime\codebase\nft\nft_interfaces\iNftFile.cs(5,23): error CS0106: The modifier 'public' is not valid for this item
unity-solana-wallet-main\Runtime\codebase\nft\nft_interfaces\iNftFile.cs(6,23): error CS0106: The modifier 'public' is not valid for this item
unity-solana-wallet-main\Runtime\codebase\nft\nft_interfaces\iNftFile.cs(7,18): error CS0106: The modifier 'public' is not valid for this item

Insecure WebSocket connection Fix

If you upload the game on the web hosting and try to play you will get to see a error of insecure WebSocket connection.

DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.

You can solve it by replacing ws with wss in the WalletBaseComponent.cs.

Example:

Before:-
public static string webSocketMainNetAdress = "ws://api.mainnet-beta.solana.com";

After:-
public static string webSocketMainNetAdress = "wss://api.mainnet-beta.solana.com";

can I access my phantom wallet with my mnemonic recovery phrase?

Hello,

I'm trying to use your unity wallet system to work directly with my phantom wallet. is it possible to load my phantom wallet directly into unity using the new Solnet.Wallet.Wallet(mnemonicWords, BIP39Wordlist.English); function? Am I forced to create a new wallet and transfer my spl-tokens from phantom to unity?

Samples folder has a '~' after it causing errors

There is a '~' symbol after the Samples folder which causes an error when you try to import the Simple Wallet sample from the package manager. Removing it on my local fixed it and I was able to import Simple Wallet successfully.

The refrence scripts with most of the gameObjects are missing

When I import the plugins and rest of the code into my unity project, almost all the scripts are gone and it says the scripts are missing. I'm not able to integrate Solana Wallet with my unity. Also there's no video or proper tutorial regarding the integration of this project with Unity. You're doing an exceptional thing because there's nobody else doing this kinda thing. Please post a proper tutorial so we get proper advantage from this project

SimpleWallet script does not contain setClientSource method.

"5) Set Client Source (Mainnet/Testnet/Devnet/Custom uri) and Storage Method (Json/Simple txt) on SimpleWallet script in WalletController prefab."

I can't find the method to which you're referring. Should I write it? Is the sentence wording off? Or am I missing a piece of understanding?

I would appreciate your insight. Thank you in advance.

Unity Build error

Unity is failed to create build while creating with il2cpp. Error are as follows:

Building Library\Bee\artifacts\Android\iz17e\libil2cpp.so failed with output:
D:/GAMEOVERDREAMS/DemiGodZ/Library/Bee/artifacts/Android/il2cppOutput/cpp/Assembly-CSharp.cpp:0: error: undefined reference to 'DownloadFile'
D:/GAMEOVERDREAMS/DemiGodZ/Library/Bee/artifacts/Android/il2cppOutput/cpp/Assembly-CSharp.cpp:7793: error: undefined reference to 'DownloadFile'
D:/GAMEOVERDREAMS/DemiGodZ/Library/Bee/artifacts/Android/il2cppOutput/cpp/Assembly-CSharp.cpp:8425: error: undefined reference to 'UploadFile'
D:/GAMEOVERDREAMS/DemiGodZ/Library/Bee/artifacts/Android/il2cppOutput/cpp/Assembly-CSharp.cpp:9206: error: undefined reference to 'UploadFile'
D:/GAMEOVERDREAMS/DemiGodZ/Library/Bee/artifacts/Android/il2cppOutput/cpp/Assembly-CSharp.cpp:11902: error: undefined reference to 'DownloadFile'
D:/GAMEOVERDREAMS/DemiGodZ/Library/Bee/artifacts/Android/il2cppOutput/cpp/Assembly-CSharp.cpp:11902: error: undefined reference to 'DownloadFile'
D:/GAMEOVERDREAMS/DemiGodZ/Library/Bee/artifacts/Android/il2cppOutput/cpp/Assembly-CSharp.cpp:14003: error: undefined reference to 'UploadFile'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
UnityEngine.GUIUtility:ProcessEvent (int,intptr,bool&)

License

Hi,
what is the license of this repo? Can you please add one?

Add mint function

Hello,
we are trying to add Minting functionality to the SDK. The solnet version in the allart sdk doesn’t include the AssociatedTokenAccountProgram, which is needed to implement the mint. What changes have you made to make solnet Unity-compatible. Do you have any plan to add the functionality or to update the solnet version?

[You are trying to create a MonoBehaviour using the 'new' keyword]

I have done the "Step-by-step instructions" and I got those warnings.
I can run it but when I click the wallet icon nothing happened.
image

These are the warning description:

You are trying to create a MonoBehaviour using the 'new' keyword. This is not allowed. MonoBehaviours can only be added using AddComponent(). Alternatively, your script can inherit from ScriptableObject or no base class at all
UnityEngine.MonoBehaviour:.ctor ()
WebSocketService:.ctor ()
AllArt.Solana.WalletBaseComponent:Awake () (at D:/Unity/libs/unity-solana-wallet/Runtime/codebase/WalletBaseComponent.cs:57)
AllArt.Solana.Example.SimpleWallet:Awake () (at Assets/Samples/Solana Wallet/1.0.0/Simple Wallet/Solana Wallet/1.0.0/Simple Wallet/script/example/SimpleWallet.cs:18)

No mainnet support

I can only get to the dev net and get myself airdrops.
How can I get to mainnet where players can actually do transfers of tokens?

Correct me if I am wrong or maybe I don't understand.
TIA_

Phantom Wallet

This might sound stupid but I see it as the major elephant in the room, I notice that this requires the user to either create a new wallet or divulge their mnemonic to authenticate, this is incredibly scary for the end user. Is there any plan to integrate some kind of intermediary authority i.e. Phantom Wallet. I think pazerdogs have the right approach in their web based app https://www.panzerdogs.io/. Can we hope to see some kind of Phantom / Sollet integration?

Can i build for webgl?

I get these errors :

crypto.loader.js:1 wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
printErr @ crypto.loader.js:1
crypto.loader.js:1 falling back to ArrayBuffer instantiation

crypto.framework.js:2 MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "dotnetstandard-bip39.Resources.resources" was correctly embedded or linked into assembly "dotnetstandard-bip39" at compile time, or that all the satellite assemblies required are loadable and fully signed.
at System.Resources.ManifestBasedResourceGroveler.HandleResourceStreamMissing (System.String fileName) [0x00000] in <00000000000000000000000000000000>:0

Fetch nft

How can i fetch nft after connecting to wallet ?
Nft.cs script can fetch but its not inside sample folder .

Can't find a way to alter the derivation_path

I'm trying to connect my Phantom account but it won't fetch the right wallet.
I think it's because you're using Solana-cli derivation_path and not phantom.

Could you please show me where could I alter this to check my theory?

1 SOL = 1000000000 ? How to make 1SOL = 1 and add decimal numbers ?

Hey there,

I have played with transactions and I thought it is not working but later actually realized that 1SOL = 1000000000.
How to make it more natural I mean like 1SOL = 1 and if I want to send less it would be nice to use decimals as well so 0.25SOL = 0.25 etc. At this moment decimals are not accepted.

image

Thanks in advance for help !

JSON Exeption on GetOwnedTokenAccounts()

public class Test : MonoBehaviour {
    [SerializeField] WalletBaseComponent Wallet_Base;

    void Start() {
        GetData();
    }

    async void GetData() {
        string pubkey = "9UeHg5HvpK1GeRbTWLK1uuW2Wjk6x3reeqWMBQWAh7Pq";
        TokenAccount[] owned_tokens = await Wallet_Base.GetOwnedTokenAccounts( pubkey, "", TokenProgram.ProgramId );
        Debug.Log( owned_tokens.Length );
    }
}

JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.UInt64' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly.
To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'result.value[0].account.data.parsed.info.delegatedAmount.amount', line 1, position 189.

Newtonsoft.Json.dll compilation errors during package import

I got this error when I imported the package.json file through package manager.

Multiple precompiled assemblies with the same name Newtonsoft.Json.dll included or the current platform. Only one assembly with the same name is allowed per platform.

I tried to rename the file from the project directory (Library/PackageCache/[email protected]/Runtime/Newtonsoft.Json.dll) - wouldn't work, compilation failed and it rebuilt itself with the original name.

Tried to rename the file in this package (unity-solana-wallet/Runtime/Plugins/Newtonsoft.Json.dll) - showed the import in the package manager but got another compilation error:
C:\Users\crypt\Developer\unity-solana-wallet\Runtime\codebase\utility\ObjectToByte.cs(101,38): error CS0433: The type 'JToken' exists in both 'Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed' and 'Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=null'

Any idea how to resolve this please? Thanks

not support on unity 2020

I try this repo out on unity 2020, but it told me this is built on a version before unity 5.
and when I try to force upgrade it to unity 2020, all those scene folders disappear...

is there any way I can work around this?

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.