Giter Club home page Giter Club logo

mpl-candy-machine's People

Contributors

azerpas avatar danenbm avatar febo avatar github-actions[bot] avatar lorisleiva avatar marksackerberg avatar sohrab- 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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

mpl-candy-machine's Issues

Question - rate limit guard?

Is there a plan for rate limiting guard?

Not sure if needed , since the bot tax has been quite successful in reducing spam.

If it's needed , I can open a PR.
Plan is, having a PDA used as a mini blockchain.

As in, client reads PDA data and pass that to minting instruction.

The program will compare PDA data to client input and hash this data with a nonce from client or clock time, and update the PDA.

This means that only one can mint until the network propagates the new state and clients can pass the correct PDA info again.

Can also be expanded to store an array of size X if a higher throughput is desired.

resolved

Hello,

I'm encountering a persistent issue when trying to initialize a candy machine using the create function provided by '@metaplex-foundation/mpl-candy-machine'. Despite ensuring that all objects (signers, public keys, etc.) are properly initialized and logged (see attached logs), I receive a TypeError indicating an undefined publicKey.

Here are the details of my setup:

  • Library version: @metaplex-foundation/[email protected]
  • Code snippet causing the error:
import {
      mplTokenMetadata,
      mplCandyMachine,
      create as candyMachineCreate,
      route,
      getMerkleProof,
      getMerkleRoot,
      mintV2
        } from '@metaplex-foundation/mpl-candy-machine'
        
        useEffect(() => {
  async function initializeCandyMachine() {
    if (!umi) {
      console.error('UMI client not initialized');
      return;
    }

    if (!projectOwnerSigner || !projectOwnerSigner.publicKey) {
      console.error('Project owner signer is not properly initialized.');
      return;
    }

    try {
      console.log('Initializing signer identity...');
      umi.use(signerIdentity(projectOwnerSigner));
    } catch (error) {
      console.error('Error initializing signer identity:', error);
      return;
    }

    try {
      console.log('Attempting to use public keys...');
      const solTreasuryPublicKey = new PublicKey(solTreasury);
      const projectOwnerSignerPublicKey = new PublicKey(projectOwnerSigner.publicKey);

      console.log('Treasury Public Key:', solTreasuryPublicKey.toString());
      console.log('Owner Signer Public Key:', projectOwnerSignerPublicKey.toString());

      console.log('Project Owner Signer:', projectOwnerSigner);
      console.log('UMI Configuration:', umi);

      try {
        console.log('Creating Candy Machine...');
        const result = await candyMachineCreate(umi, {
          guards: {
            botTax: some({ lamports: sol(0.05), lastInstruction: true }),
            solPayment: some({ lamports: sol(0.05), destination: solTreasuryPublicKey }),
          },
        });

        console.log("Candy Machine initialization successful", result);
        setMintProgressStep(MintingStep.Success);
      } catch (internalError) {
        console.error("Error during Candy Machine creation:", internalError);
        setMintProgressStep(MintingStep.Error);
      }
    } catch (error) {
      console.error("Error preparing or using public keys:", error);
      setMintProgressStep(MintingStep.Error);
    }
  }

  initializeCandyMachine();
}, [umi, projectOwnerSigner]);
  • My console log:
BUNDLE  ./index.js 
LOG  projectOwnerSigner initialized {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}
LOG  Initializing signer identity...
LOG  Treasury Public Key: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
LOG  Owner Signer Public Key: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
LOG  Fetching balance for: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
ERROR  Error during Candy Machine creation: [TypeError: Cannot read property 'publicKey' of undefined]
LOG  Balance fetched: 13889948440
LOG  projectOwnerSigner initialized {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}
LOG  Initializing signer identity...
LOG  Attempting to use public keys...
LOG  Treasury Public Key: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
LOG  Owner Signer Public Key: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
LOG  Project Owner Signer: {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}
LOG  UMI Configuration: {"downloader": {"download": [Function download], "downloadJson": [Function downloadJson]}, "eddsa": {"createKeypairFromSecretKey": [Function createKeypairFromSecretKey], "createKeypairFromSeed": [Function createKeypairFromSeed], "findPda": [Function findPda], "generateKeypair": [Function generateKeypair], "isOnCurve": [Function isOnCurve], "sign": [Function sign], "verify": [Function verify]}, "guards": {"manifests": Map {"botTax" => [Object], "solPayment" => [Object], "tokenPayment" => [Object], "startDate" => [Object], "thirdPartySigner" => [Object], "tokenGate" => [Object], "gatekeeper" => [Object], "endDate" => [Object], "allowList" => [Object], "mintLimit" => [Object], "nftPayment" => [Object], "redeemedAmount" => [Object], "addressGate" => [Object], "nftGate" => [Object], "nftBurn" => [Object], "tokenBurn" => [Object], "freezeSolPayment" => [Object], "freezeTokenPayment" => [Object], "programGate" => [Object], "allocation" => [Object], "token2022Payment" => [Object]}}, "http": {"send": [Function send]}, "identity": {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}, "payer": {"publicKey": "CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm", "signAllTransactions": [Function signAllTransactions], "signMessage": [Function signMessage], "signTransaction": [Function signTransaction]}, "programs": {"add": [Function add], "all": [Function all], "bind": [Function bind], "clone": [Function clone], "get": [Function get], "getPublicKey": [Function getPublicKey], "has": [Function has], "resolveError": [Function resolveError], "unbind": [Function unbind]}, "rpc": {"accountExists": [Function accountExists], "airdrop": [Function airdrop], "call": [Function call], "confirmTransaction": [Function confirmTransaction], "connection": {"_blockhashInfo": [Object], "_commitment": undefined, "_confirmTransactionInitialTimeout": undefined, "_disableBlockhashCaching": false, "_nextClientSubscriptionId": 0, "_pollingBlockhash": false, "_rpcBatchRequest": [Function anonymous], "_rpcClient": [ClientBrowser], "_rpcEndpoint": "https://api.devnet.solana.com", "_rpcRequest": [Function anonymous], "_rpcWebSocket": [RpcWebSocketClient], "_rpcWebSocketConnected": false, "_rpcWebSocketGeneration": 0, "_rpcWebSocketHeartbeat": null, "_rpcWebSocketIdleTimeout": null, "_rpcWsEndpoint": "wss://api.devnet.solana.com", "_subscriptionCallbacksByServerSubscriptionId": [Object], "_subscriptionDisposeFunctionsByClientSubscriptionId": [Object], "_subscriptionHashByClientSubscriptionId": [Object], "_subscriptionStateChangeCallbacksByHash": [Object], "_subscriptionsAutoDisposedByRpc": [Set], "_subscriptionsByHash": [Object], "getBlockHeight": [Function anonymous]}, "getAccount": [Function getAccount], "getAccounts": [Function getAccounts], "getBalance": [Function getBalance], "getBlockTime": [Function getBlockTime], "getCluster": [Function getCluster], "getEndpoint": [Function getEndpoint], "getLatestBlockhash": [Function getLatestBlockhash], "getProgramAccounts": [Function getProgramAccounts], "getRent": [Function getRent], "getSignatureStatuses": [Function getSignatureStatuses], "getSlot": [Function getSlot], "getTransaction": [Function getTransaction], "sendTransaction": [Function sendTransaction]}, "serializer": {"array": [Function array], "bool": [Function bool], "bytes": [Function bytes], "dataEnum": [Function dataEnum], "enum": [Function scalarEnum], "f32": [Function f32], "f64": [Function f64], "i128": [Function i128], "i16": [Function i16], "i32": [Function i32], "i64": [Function i64], "i8": [Function i8], "map": [Function map], "nullable": [Function nullable], "option": [Function option], "publicKey": [Function publicKey], "set": [Function set], "string": [Function string], "struct": [Function struct], "tuple": [Function tuple], "u128": [Function u128], "u16": [Function u16], "u32": [Function u32], "u64": [Function u64], "u8": [Function u8], "unit": [Function unit]}, "transactions": {"create": [Function create], "deserialize": [Function deserialize], "deserializeMessage": [Function deserializeMessage], "serialize": [Function serialize], "serializeMessage": [Function serializeMessage]}, "uploader": {"getUploadPrice": [Function errorHandler], "upload": [Function errorHandler], "uploadJson": [Function errorHandler]}, "use": [Function use]}
LOG  Creating Candy Machine...
LOG  Fetching balance for: CaBdCcUPdDTzzLRxCxv1QPhsYzQRCYao6Dxeazkdp9Gm
ERROR  Error during Candy Machine creation: [TypeError: Cannot read property 'publicKey' of undefined]
LOG  Balance fetched: 13889948440

Why do I keep failing to execute sugar withdraw? This is my candy machine id: J3RZuYxgsGeZmwqrafb9ghYDtmqXAMWz6DHDANxyDw7j

πŸ›‘ Error running command (re-run needed): unable to confirm transaction. This can happen in situations such as transaction expiration and insufficient fee-payer funds % sugar withdraw --candy-machine J3RZuYxgsGeZmwqrafb9ghYDtmqXAMWz6DHDANxyDw7j --keypair /Users/jiawababa/keys___/id.json
[1/2] πŸ–₯ Initializing connection
β–ͺβ–ͺβ–ͺβ–ͺβ–ͺ Connected

[2/2] 🏧 Retrieving funds

πŸ›‘ Error running command (re-run needed): unable to confirm transaction. This can happen in situations such as transaction expiration and insufficient fee-payer funds
getRent % sugar withdraw --candy-machine J3RZuYxgsGeZmwqrafb9ghYDtmqXAMWz6DHDANxyDw7j --keypair /Users/jiawababa/keys___/id.json
[1/2] πŸ–₯ Initializing connection
β–ͺβ–ͺβ–ͺβ–ͺβ–ͺ Connected

[2/2] 🏧 Retrieving funds

πŸ›‘ Error running command (re-run needed): unable to confirm transaction. This can happen in situations such as transaction expiration and insufficient fee-payer funds
getRent % sugar withdraw --candy-machine J3RZuYxgsGeZmwqrafb9ghYDtmqXAMWz6DHDANxyDw7j --keypair /Users/jiawababa/keys___/id.json
[1/2] πŸ–₯ Initializing connection
β–ͺβ–ͺβ–ͺβ–ͺβ–ͺ Connected

[2/2] 🏧 Retrieving funds

πŸ›‘ Error running command (re-run needed): unable to confirm transaction. This can happen in situations such as transaction expiration and insufficient fee-payer funds
getRent %

safeFetchCandyGuard throws errors on missing

My understanding of safe* functions was that they return null when the account does not exist. However, it actually throws an UnexpectedAccountError on the empty buffer.

UnexpectedAccountError: The account at the provided address [3ix9kizh1uKa7PEYhWUHLseMRVMtqgu5eSUTZ6LT3Ezt] is not of the expected type [CandyGuard].

Source: SDK

Caused By: DeserializingEmptyBufferError: Serializer [i8] cannot deserialize empty buffers.

    at deserializeAccount (Account.ts:63:11)
    at deserializeCandyGuard (candyGuard.ts:90:10)
    at safeFetchCandyGuard (candyGuard.ts:125:7)

@metaplex-foundation/mpl-candy-machine v6.0.0

Update `anchor_lang` from 0.26.0 to 0.27.0

Getting compatibility errors when using anchor_lang = "0.27.0" and mpl-candy-machine-core = {version = "1.0.2", features = ["no-entrypoint"]} which use anchor_lang = "0.26.0"

[...]
   |     pub candy_machine: Account<'info, CandyMachine>,
   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `anchor_lang::AccountDeserialize` is not implemented for `CandyMachine`
   |
help: trait impl with same name found
   = note: perhaps two different versions of crate `anchor_lang` are being used?
   = help: the following other types implement trait `anchor_lang::AccountDeserialize`:
[...]

Downgrading to anchor_lang = "0.26.0" temporarily bypass the issue

Unable to use mpl-candy-machine in React

Hi!
I was hoping to make a feature for updating spl-token metadata on frontend. I'm using the latest version of packages. But as soon as i import them I start receiving this error:

Class extends value undefined is not a constructor or null
TypeError: Class extends value undefined is not a constructor or null

my imports:

import { percentAmount, generateSigner, signerIdentity, createSignerFromKeypair } from '@metaplex-foundation/umi';
import { createAndMint, TokenStandard } from '@metaplex-foundation/mpl-token-metadata';
import { createUmi } from '@metaplex-foundation/umi-bundle-defaults';
import { mplCandyMachine } from '@metaplex-foundation/mpl-candy-machine'; 

image

Please let me know if it's possible to fix if someone knows. Thank you

Create Time-Lock token with candy machine

how can i add a small time-lock customisation when minting spl tokens with candy machine?

I would like to lock tokens of new holders for 1 day as an experiment. please guide me. let me know the best way to achieve this. or if it is not possible.

limitation on number of groups in candy guard

I want to limit the number of mint per wallet which can be dynamic.
e.g. wallet1 has 5, wallet2 has 7, wallet3 has 10

to achieve this scenario, I have left the default guard empty and set 3 groups with the following settings.

groups

  • label: 0, address gate = wallet1, mint limit = ld:0, limit 5
  • label: 1, address gate = wallet2, mint limit = id:1, limit 7
  • label: 2, address gate = wallet2, mint limit = id:2, limit 10

which works just fine.

the problem starts when I specify 50 groups, the length of the transaction would be ~2500 bytes, which exceeded the hard limit of 1232 bytes. and I can not do a partial update, as it needs all data to update Candy Guard.

Is there any trick that executes this transaction OR is there any other combination of guards that can achieve the above scenario

Error Class extends value undefined is not a constructor or null

Hi! I am following this guide, adding the code to my create-react-app project:

https://docs.metaplex.com/programs/candy-machine/getting-started

But as soon as I include mpl-candy-machine I get the following runtime error from its depencency mpl-token-metadata:

ERROR Class extends value undefined is not a constructor or null TypeError: Class extends value undefined is not a constructor or null at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/errors.js (http://localhost:3000/static/js/bundle.js:8513:40) at options.factory (http://localhost:3000/static/js/bundle.js:110628:31) at __webpack_require__ (http://localhost:3000/static/js/bundle.js:110051:33) at fn (http://localhost:3000/static/js/bundle.js:110285:21) at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/hooked/metadataDelegateRoleSeed.js (http://localhost:3000/static/js/bundle.js:22151:18) at options.factory (http://localhost:3000/static/js/bundle.js:110628:31) at __webpack_require__ (http://localhost:3000/static/js/bundle.js:110051:33) at fn (http://localhost:3000/static/js/bundle.js:110285:21) at ./node_modules/@metaplex-foundation/mpl-token-metadata/dist/src/hooked/index.js (http://localhost:3000/static/js/bundle.js:22132:14) at options.factory (http://localhost:3000/static/js/bundle.js:110628:31)

I have checked the errors.js file of mpl-token-metadata and it is extending the UmiError class that is indeed being exported from the umi interface, so I'm not sure what is wrong here:

   "use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TokenMetadataError = void 0;
const {UmiError} = require("@metaplex-foundation/umi");
class TokenMetadataError extends umi_1.UmiError {
    constructor(message, cause) {
        super(message, 'plugin', 'Token Metadata', cause);
        this.name = 'TokenMetadataError';
    }
}
exports.TokenMetadataError = TokenMetadataError;
//# sourceMappingURL=errors.js.map

Followed the docs tutorial but still getting this error (Incorrect account owner)

'Program 11111111111111111111111111111111 invoke [1]', 'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR invoke [1]', 'Program log: Instruction: InitializeV2', 'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s invoke [2]', 'Program log: IX: Delegate', 'Program log: Incorrect account owner', 'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s consumed 8216 of 774536 compute units', 'Program metaqbxxUerdq28cj1RbAWkYQm3ybzjb6a8bt518x1s failed: custom program error: 0x39', 'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR consumed 33530 of 799850 compute units', 'Program CndyV3LdqHUfDLmE5naZjVN8rBZz4tqhdefbAnjHG3JR failed: custom program error: 0x39'

/// Author: Oguntunde Caleb Fiyinfoluwa <[email protected]>

import {
  addConfigLines,
  CandyGuard,
  CandyMachine,
  ConfigLine,
  updateCandyGuard,
  DefaultGuardSetArgs,
} from "@metaplex-foundation/mpl-candy-machine";

import {
  createNft,
  TokenStandard,
} from "@metaplex-foundation/mpl-token-metadata";
import { create } from "@metaplex-foundation/mpl-candy-machine";
import { generateSigner, some } from "@metaplex-foundation/umi";
import { publicKey } from "@metaplex-foundation/umi";

import BaseDaddyInuImpl from "./impl";

type NFTInput = Omit<Parameters<typeof createNft>[1], "mint" | "authority">;
type CreateInput = Omit<
  Parameters<typeof create>[1],
  | "candyMachine"
  | "collectionMint"
  | "tokenStandard"
  | "collectionUpdateAuthority"
>;

export default class DaddyInu extends BaseDaddyInuImpl {
  async createNFT(nftInput: NFTInput) {
    const mint = generateSigner(this.umi);
    const authority = generateSigner(this.umi);

    await createNft(this.umi, {
      mint,
      authority,
      ...nftInput,
    }).sendAndConfirm(this.umi);

    return [mint, authority];
  }

  async createCandyMachine(
    [mint, authority]: Awaited<ReturnType<typeof this.createNFT>>,
    createInput: CreateInput
  ) {
    const candyMachine = generateSigner(this.umi);
    await (
      await create(this.umi, {
        candyMachine,
        collectionMint: mint.publicKey,
        collectionUpdateAuthority: authority,
        tokenStandard: TokenStandard.NonFungible,
        ...createInput,
        creators: [
          {
            address: this.umi.identity.publicKey,
            verified: true,
            percentageShare: 10,
          },
          ...createInput.creators,
        ],
        configLineSettings: some({
          prefixName: "",
          prefixUri: "",
          nameLength: 8,
          uriLength: 32,
          isSequential: true,
          ...createInput.configLineSettings,
        }),
      })
    )
    .sendAndConfirm(this.umi);

    return candyMachine;
  }

  insertNFTItems(
    candyMachine: CandyMachine,
    items: ConfigLine[],
    index?: number
  ) {
    return addConfigLines(this.umi, {
      candyMachine: publicKey(candyMachine.publicKey),
      index: index ?? candyMachine.itemsLoaded,
      configLines: items,
    }).sendAndConfirm(this.umi);
  }

  updateCandyGuards(
    candyGuard: CandyGuard,
    guards: Partial<DefaultGuardSetArgs>
  ) {
    return updateCandyGuard(this.umi, {
      candyGuard: candyGuard.publicKey,
      guards: {
        ...candyGuard.guards,
        ...guards,
      },
      groups: candyGuard.groups,
    });
  }
}
import { createUmi } from "@metaplex-foundation/umi-bundle-defaults";
import { publicKey, Umi } from "@metaplex-foundation/umi";
import {
  fetchCandyMachine,
  fetchCandyGuard,
  mplCandyMachine,
  CandyGuard,
  CandyMachine,
} from "@metaplex-foundation/mpl-candy-machine";

export default class BaseDaddyInuImpl {
  public readonly umi: Umi;

  constructor(endpoint: string | Umi) {
    if (typeof endpoint === "string") this.umi = createUmi(endpoint);
    else this.umi = endpoint;

    this.umi.use(mplCandyMachine()).use(mplCandyMachine());
  }

  async fetchCandyMachineAndGuard(
    candyMachineAddress: string
  ): Promise<[CandyMachine, CandyGuard]> {
    const candyMachine = await fetchCandyMachine(
      this.umi,
      publicKey(candyMachineAddress)
    );

    const candyGuard = await fetchCandyGuard(
      this.umi,
      candyMachine.mintAuthority
    );

    return [candyMachine, candyGuard];
  }
}
import { percentAmount, keypairIdentity, some } from "@metaplex-foundation/umi";

import secret from "./keypair.json";
import DaddyInu from "../src/daddy_inu";

export default async function main() {
  const daddyInu = new DaddyInu("https://api.devnet.solana.com");
  const keypair = daddyInu.umi.eddsa.createKeypairFromSecretKey(
    Uint8Array.from(secret)
  );

  daddyInu.umi.use(keypairIdentity(keypair));

  const signers = await daddyInu.createNFT({
    name: "Big Daddy Pass",
    symbol: "BDP",
    uri: "https://www.daddyinu.com/pass/dinu.jpg",
    sellerFeeBasisPoints: percentAmount(10),
    isCollection: true,
  });

  const nftAddress = signers.map((signer) => signer.publicKey);
  console.log(`Mint & Authority: ${nftAddress.join(", ")}`);

  const [mintAddress, _authorityAddress] = nftAddress;

  console.log(
    `https://explorer.solana.com/address/${mintAddress}?cluster=devnet`
  );

  await sleep(5);

  const candyMachine = await daddyInu.createCandyMachine(signers, {
    creators: [],
    symbol: "BDB",
    sellerFeeBasisPoints: percentAmount(10),
    itemsAvailable: 5000,
  });

  console.log(`Candy Machine: ${candyMachine.publicKey}`);
}

main().catch((error) => {
  console.log(error);
});

async function sleep(seconds: number) {
  return new Promise((resolve) => {
    setTimeout(() => {
      return resolve(void 0);
    }, seconds * 1000);
  });
}

[Feature]: Allow multiple nftPayments / nftBurns per mint.

Feature

Allow multiple nftPayments / nftBurns per mint.

Standard Change?

No

Ideal solution or implementation

Simple solution is to extend the current gates to allow an "amount" as a part of the configuration. Then during the mint process it burns/ transfers multiple NFTs at once from the given collection.

Alternative solutions or implementations

No response

Other context

No response

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.