stacks.js

repository·main·Indexed 21 days ago

https://github.com/stx-labs/stacks.js

A comprehensive suite of JavaScript and TypeScript libraries for building applications on the Stacks blockchain. It includes packages for API interaction (@stacks/api), authentication and session management (@stacks/auth), PoX-5 paired-BTC bond staking (@stacks/bitcoin-staking), Blockchain Naming System interaction (@stacks/bns), and a command line interface (@stacks/cli) for managing transactions, balances, and smart contract calls.

Tokens
123.2K
Snippets
465
Records
541
Agent score
76%

What's inside stacks.js

  1. Overview of Stacks.js packages

    main

    Stacks.js is a collection of JavaScript/TypeScript packages designed to provide the essential building blocks for interacting with the Stacks blockchain. The repository is organized into several functional modules:

    Connecting Wallets

    • @stacks/connect: Used to connect web applications to Stacks wallet browser extensions (maintained in a separate repository).

    Stacks Primitives

    • @stacks/transactions: For constructing and decoding transactions and working with Clarity smart contracts.
    • @stacks/wallet-sdk: For building wallets, managing accounts, and handling keys.
    • @stacks/storage: For storing and fetching files using Gaia (decentralized storage).
    • @stacks/encryption: Provides encryption functions used across the Stacks.js ecosystem.
    • @stacks/auth: For constructing and decoding authentication requests.
    • @stacks/profile: For manipulating user profiles.
    • @stacks/network: A library for interacting with Stacks blockchain nodes and APIs.
    • @stacks/common: Shared utilities used by other packages.

    Native Smart Contract Interaction

    • @stacks/bns: For interacting with the BNS (Bitcoin Name System) contract.
    • @stacks/stacking: For interacting with Proof-of-Transfer (PoX) stacking.

    Utilities and CLI

    • @stacks/cli: A command-line interface for interacting with auth, storage, and Stacks transactions.

    Note: @stacks/keychain is deprecated and has been replaced by @stacks/wallet-sdk.

  2. How delegated stacking works

    main

    Delegated stacking allows a user (the "stacker") to delegate their STX funds to a pool operator. The pool operator then locks these funds on the blockchain and commits to stacking participation for reward cycles. This process involves three main steps:

    1. Delegation: The user sends a delegateStx transaction to the pool's STX address.
    2. Locking: The pool operator sends a delegateStackStx transaction to lock the delegated funds.
    3. Committing: The pool operator sends a stackAggregationCommit transaction to participate in reward cycles.

    This model allows individuals to benefit from pool-based stacking without managing the technical complexities of cycle commitments themselves.

    sequenceDiagram
      User->>Stacks Blockchain: tx: `delegateStx`<br>Delegate funds to pool,<br>by pool's STX address
      Stacks Blockchain-->Pool Operator: Monitored by
      Pool Operator->>Stacks Blockchain: tx: `delegateStackStx`<br>Lock delegated funds
      Pool Operator->>Stacks Blockchain: tx: `stackAggregationCommit`<br>Commit stacking for each cycle
  3. Update derivation methods for @stacks/wallet-sdk (v5.0.0)

    main
    As of version 5.0.0, compatibility with the bip32 package in @stacks/wallet-sdk has been removed. All derivation methods now rely exclusively on HDKey from @scure/bip32. Developers using custom derivation logic should ensure their implementation is compatible with @scure/bip32.
  4. How Secret Keys, Wallets, and Accounts work together

    main

    The @stacks/wallet-sdk uses a hierarchical structure to manage identity and assets:

    1. Secret Key: A BIP-39 compliant mnemonic phrase (12 or 24 words). It is the root of all identity; using the same Secret Key will always generate the same addresses.
    2. Wallet: A collection of private keys for a user. A wallet contains multiple accounts and can be encrypted with a password.
    3. Account: A specific identity within a wallet. Each account has its own unique Stacks address, balance, and state. Accounts allow users to segregate assets and data. External parties cannot determine if different accounts belong to the same wallet.

    Derivation Path: Private keys follow BIP32/BIP44 standards with the Stacks coin type 5757. The path for an account at index n is m/44'/5757'/0'/0/n.

  5. How post conditions work in @stacks/bitcoin-staking

    main

    Builders in this package do not automatically attach post conditions. Transactions default to Deny mode. If a transaction moves an asset without a matching post condition, it will abort with abort_by_post_condition.

    You must either:

    1. Attach the matching post conditions to the transaction.
    2. Set postConditionMode: 'allow' to bypass strict checking.
  6. Handle an authentication response payload

    main

    After a user authenticates via a redirect, check if a sign-in is pending using userSession.isSignInPending(). If true, call userSession.handlePendingSignIn() to process the response. This method returns a userData object containing the user's identity, BNS username, and profile information.

    if (userSession.isSignInPending()) {
      userSession.handlePendingSignIn().then(userData => {
        // Do something with userData
      });
    }
  7. How to initiate a @stacks/storage client

    main

    To use storage, a user must first be authenticated. The storage client requires an active UserSession (typically from @stacks/auth) where userSession.isUserSignedIn() returns true.

    When initializing the Storage client, you pass the existing userSession object. If you are manually setting up a session for testing or specific workflows, ensure the userData contains the necessary appPrivateKey.

    import { UserSession, AppConfig } from '@stacks/auth';
    import { Storage } from '@stacks/storage';
    
    const privateKey = '896adae13a1bf88db0b2ec94339b62382ec6f34cd7e2ff8abae7ec271e05f9d8';
    const appConfig = new AppConfig();
    const userSession = new UserSession({ appConfig });
    
    // Manually setting session data for demonstration
    userSession.store.getSessionData().userData = <any> {
      appPrivateKey: privateKey,
    };
    
    const storage = new Storage({ userSession });