# Get Account History Source: https://docs.adamik.io/api-reference/account/get-account-history https://api.adamik.io/openapi.json get /api/{chainId}/account/{accountId}/history Returns the history of a specified account identifier (address or xpub) and chain ID, primarily focusing on past transactions. # Get Account State (Balances) Source: https://docs.adamik.io/api-reference/account/get-account-state-balances https://api.adamik.io/openapi.json get /api/{chainId}/account/{accountId}/state Returns the state of a specified account identifier (address or xpub) and chain ID, focusing on balance information. The response includes details on native asset balances, token balances, and staking balances. This endpoint supports optional filters to refine the results, making it essential for wallet applications to display accurate and tailored account information. # Get Account Tokens (paginated) Source: https://docs.adamik.io/api-reference/account/get-account-tokens-paginated https://api.adamik.io/openapi.json get /api/{chainId}/account/{accountId}/state/tokens Returns the tokens (amount and details) held by a specified account identifier and chain ID. This endpoint allows for pagination over the returned tokens. # Get Chain Details Source: https://docs.adamik.io/api-reference/chain/get-chain-details https://api.adamik.io/openapi.json get /api/chains/{chainId} Retrieves detailed information about a specific blockchain network identified by chain ID. # Get Chain Validators Source: https://docs.adamik.io/api-reference/chain/get-chain-validators https://api.adamik.io/openapi.json get /api/{chainId}/validators Lists validators for a specified chain ID, including their operational status and commission rates. Useful for delegation operations on proof-of-stake blockchains. # Get Supported Chains Source: https://docs.adamik.io/api-reference/chain/get-supported-chains https://api.adamik.io/openapi.json get /api/chains Retrieves a list of all supported blockchain networks with their detailed information. # Get Token Details Source: https://docs.adamik.io/api-reference/chain/get-token-details https://api.adamik.io/openapi.json get /api/{chainId}/token/{tokenId} Retrieves detailed information about a specific token for a blockchain network, identified by chain ID and token ID. # Open API Specification Source: https://docs.adamik.io/api-reference/open-api-specification https://api.adamik.io/openapi.json get /api Provides the Open API specification of the Adamik API # Broadcast Raw Transaction Source: https://docs.adamik.io/api-reference/transaction/broadcast-raw-transaction https://api.adamik.io/openapi.json post /api/{chainId}/transaction/broadcast/raw Broadcasts a signed transaction to the blockchain in raw format. Unlike the standard broadcast, which builds the broadcast payload for you, this endpoint requires the final payload, ready for submission. Returns the transaction receipt (hash) or error details in case of failure. # Broadcast Transaction Source: https://docs.adamik.io/api-reference/transaction/broadcast-transaction https://api.adamik.io/openapi.json post /api/{chainId}/transaction/broadcast Broadcasts a signed transaction to the blockchain, crucial for submitting transactions like transfers, delegations, or reward claims. Returns a transaction receipt (hash) or error details. Note: the exact same 'data' and 'encoded' fields that were retrieved with the /transaction/encode endpoint, must be provided here. # Encode a Transaction Source: https://docs.adamik.io/api-reference/transaction/encode-a-transaction https://api.adamik.io/openapi.json post /api/{chainId}/transaction/encode Encodes transaction data into a format suitable for broadcasting. This endpoint is pivotal for creating transactions that comply with the specific requirements of different blockchains. It performs several important functions: 1. **Validates** the transaction data against chain-specific rules 2. **Computes and adds** necessary transaction parameters (fees, gas, nonce) 3. **Calculates** the maximum spendable amount when requested 4. **Returns** the raw data and transaction hash in the appropriate format for signing The response includes both the transaction hash (which needs to be signed) and the raw transaction data in a chain-specific format. # Get Transaction Details Source: https://docs.adamik.io/api-reference/transaction/get-transaction-details https://api.adamik.io/openapi.json get /api/{chainId}/transaction/{transactionId} Retrieves detailed information about a specific transaction for a blockchain network, identified by chain ID and transaction ID. # Validate Transaction Source: https://docs.adamik.io/api-reference/transaction/validate-transaction https://api.adamik.io/openapi.json post /api/{chainId}/transaction/validate Validates a transaction's format and checks it against the blockchain's current state for potential errors or warnings. This pre-validation is critical for ensuring transaction success rates and for debugging transaction issues. # Pubkey to Address Source: https://docs.adamik.io/api-reference/utils/pubkey-to-address https://api.adamik.io/openapi.json post /api/{chainId}/address/encode Encodes the provided public key to one or multiple addresses, for the given chain ID. Each address is labeled with a type, which may be "default" when there is only one address. # Validate Address Source: https://docs.adamik.io/api-reference/utils/validate-address https://api.adamik.io/openapi.json post /api/{chainId}/address/validate Validates the specified address for the given chain ID, returning true if the address is valid, otherwise false. # null Source: https://docs.adamik.io/api_overview/introduction The Adamik API adheres to RPC principles, providing streamlined and predictable interactions for blockchain integration in cryptocurrency applications. It features resource-oriented URLs, accepts and returns JSON-encoded data, and uses standard HTTP methods and response codes. ## Chain-Agnostic Philosophy The Adamik API is designed with a chain-agnostic approach, ensuring that developers do not need to handle specific blockchain logic within their codebase. This means that the API avoids endpoints tied exclusively to particular blockchain types or families. The focus is on delivering a unified interface that abstracts away the complexities of individual blockchains, enabling seamless integration across various chains without requiring chain-specific adaptations. ## Focused Functionality Each API request processes single objects to ensure precise updates, supporting clear and straightforward blockchain interactions. This precision aligns with our goal of maintaining simplicity and clarity in blockchain integrations. ## Authentication Access to the Adamik API requires an API key to authenticate requests. Include your API key in the Authorization header of each request using the following format: ``` Authorization: ``` You can generate and manage your API key through the [Adamik Dashboard](https://dashboard.adamik.io). ## Error Handling The API uses standard HTTP response codes to reflect the outcome of each request: * **2xx** — Success * **4xx** — Client-side errors (e.g., missing parameters, validation errors) * **5xx** — Server-side errors (rare, but indicate an issue with Adamik’s system) Error responses include clear messages and may provide error codes to aid debugging. ## OpenAPI Specification Explore the complete API structure using the OpenAPI Specification (OAS). The OAS provides a comprehensive reference for all endpoints, parameters, and response formats. Access it via the [OpenAPI endpoint](../api-reference). ## Versioning The Adamik API is continuously evolving. Our chain-agnostic approach ensures updates are compatible across all blockchain ecosystems, supporting flexible, scalable integrations. # Read API Overview Source: https://docs.adamik.io/api_overview/read_API_overview_and_interaction_flow The **Read API** provides endpoints to retrieve blockchain data across multiple categories. These endpoints deliver standardized responses across all supported networks. ## API Categories ### Chain Information * **Get Supported Chains** (`GET /api/chains`): List all supported blockchain networks and their features * **Get Chain Info** (`GET /api/chain/{chainId}`): Detailed information about a specific blockchain * **Get Validators** (`GET /api/{chainId}/validators`): List of validators and their details * **Get Transaction Details** (`GET /api/{chainId}/transaction/{transactionId}`): Detailed transaction information ### Account Operations * **Get Account State** (`GET /api/{chainId}/account/{accountId}/state`): Comprehensive account information including balances * **Get Account Tokens** (`GET /api/{chainId}/account/{accountId}/state/tokens`): List of tokens owned by an account * **Get Account History** (`GET /api/{chainId}/account/{accountId}/history`): Transaction history for an account ### Utilities * **Encode Address** (`POST /api/{chainId}/address/encode`): Convert public key to chain-specific address format * **Validate Address** (`POST /api/{chainId}/address/validate`): Verify address format for a specific chain ## Interaction Flow ```mermaid theme={null} sequenceDiagram participant USER as End-User participant APP as Client App participant ADAMIK as Adamik API Note over USER,ADAMIK: Chain Information USER->>APP: Query chain data APP->>ADAMIK: /api/chains ADAMIK->>APP: Supported chains & features USER->>APP: Get validators APP->>ADAMIK: /api/{chainId}/validators ADAMIK->>APP: Validator list & details Note over USER,ADAMIK: Account Operations USER->>APP: View account details APP->>ADAMIK: /api/{chainId}/account/{accountId}/state ADAMIK->>APP: Account state & balances APP->>ADAMIK: /api/{chainId}/account/{accountId}/state/tokens ADAMIK->>APP: Token balances APP->>ADAMIK: /api/{chainId}/account/{accountId}/history ADAMIK->>APP: Transaction history Note over USER,ADAMIK: Transaction Details USER->>APP: View transaction APP->>ADAMIK: /api/{chainId}/transaction/{transactionId} ADAMIK->>APP: Transaction details ``` **Note**: All Read API endpoints are stateless and return standardized responses across different blockchain networks. Pagination is supported where applicable using the `nextPage` parameter. ## Chain-Specific Features The Read API adapts to each blockchain's capabilities: ```json theme={null} { "read": { "token": true, // Token information support "validators": true, // Validator queries support "transaction": { "native": true, // Native transaction queries "tokens": true, // Token transaction queries "staking": true // Staking transaction queries }, "account": { "balances": { "native": true, // Native balance queries "tokens": true, // Token balance queries "staking": true // Staking position queries }, "transactions": { "native": true, // Native transaction history "tokens": true, // Token transaction history "staking": true // Staking transaction history } } } } ``` ## Response Standardization The API provides consistent response formats across all chains: * Transaction states are normalized (`pending`, `unconfirmed`, `confirmed`, `failed`, `unknown`) * Transaction types are standardized (`transfer`, `transferToken`, `delegate`, `redelegate`, `undelegate`, `claimRewards`) * Optional `include` parameters allow requesting additional data (e.g., `parsed` and `raw` transaction details) For implementation details, refer to: * [Get Chain Details](../api-reference/chain/get-chain-details) * [Get Account State](../api-reference/account/get-account-state-balances) * [Get Transaction Details](../api-reference/transaction/get-transaction-details) # Write API Overview Source: https://docs.adamik.io/api_overview/write_API_overview_and_interaction_flow The Write API provides endpoints for managing blockchain transactions. These endpoints handle transaction encoding, validation, and broadcasting across all supported networks. ## Transaction Lifecycle ### 1. Transaction Encoding The `/api/transaction/encode` endpoint streamlines transaction creation by: * Validating input parameters * Calculating fees and gas estimates * Applying chain-specific rules * Preparing the transaction for signing ### 2. Transaction Validation The validation endpoint helps verify transactions before broadcasting: * Checks transaction structure * Validates sender's balance * Verifies chain-specific requirements ### 3. Transaction Broadcasting Two options for broadcasting transactions: * **Standard Broadcast** (`POST /api/transaction/broadcast`): For regular signed transactions * **Raw Broadcast** (`POST /api/transaction/broadcast/raw`): For pre-formatted transaction payloads ```mermaid theme={null} sequenceDiagram participant USER as End-User participant CLIENT as Client-App participant ADAMIK as Adamik API Note over USER,ADAMIK: 1. Transaction Construction USER->>CLIENT: Set transaction data CLIENT->>ADAMIK: POST /api/transaction/encode ADAMIK->>CLIENT: Return encoded transaction CLIENT->>ADAMIK: POST /api/transaction/validate ADAMIK->>CLIENT: Return validation result Note over USER,ADAMIK: 2. Transaction Signature CLIENT->>USER: Request signature USER->>CLIENT: Sign transaction Note over USER,ADAMIK: 3. Transaction Broadcast CLIENT->>ADAMIK: POST /api/transaction/broadcast ADAMIK->>CLIENT: Return transaction hash ``` ## Supported Transaction Types The API supports various transaction types across chains: * **Native Transfers**: Send native blockchain currency * **Token Transfers**: Handle ERC20 and other token standards * **Staking Operations**: Delegate, redelegate, undelegate, and claim rewards Each chain may support different transaction types. Use the `/api/chains` endpoint to check supported features for any chains. ## Chain-Specific Features The Write API adapts to each blockchain's capabilities: ```json theme={null} { "write": { "transaction": { "type": { "native": true, // Native currency transfers "tokens": true, // Token operations "staking": true // Staking operations }, "field": { "memo": true // Optional transaction memo support } } } } ``` ## Error Handling The API provides detailed error feedback: * Pre-broadcast validation errors * Chain-specific rejection reasons * Broadcasting status and confirmation details For implementation details, refer to: * [Encode a Transaction](../api-reference/transaction/encode-a-transaction) * [Validate Transaction](../api-reference/transaction/validate-transaction) * [Broadcast Transaction](../api-reference/transaction/broadcast-transaction) # In-House Blockchain Support: Is It Worth It? Source: https://docs.adamik.io/get_started/Build-VS-Buy You’ve decided to add a crypto section to your app—congratulations! This could be the spark that ignites a wave of innovation and user engagement. However, like fireworks, blockchain integration demands precision and expertise. Without it, you risk more than just missing out; you could face significant setbacks. As a development leader or product manager, you recognize blockchain’s potential. But navigating this complex landscape requires careful planning and deep technical understanding, as even the most seasoned developers can find it challenging to master. ## The Blockchain Integration Challenge: More Than Just Another API At first glance, adding blockchain functionality might seem like just another API integration. But as many teams have discovered, it's a landscape filled with unique challenges: 1. **Protocol Diversity**: Each blockchain network—be it Ethereum, Bitcoin, or The Open Network (TON)—operates with its own set of rules, transaction structures, and consensus mechanisms. This diversity necessitates a deep understanding of each protocol you intend to support. 2. **Rapid Evolution**: The blockchain space is in constant flux. New updates, forks, and protocols emerge frequently, requiring continuous adaptation of your integration code. 3. **Security Risks**: Improper transaction construction or inaccurate fee estimation can lead to significant financial losses. As blockchain ecosystems multiply, staying informed on all transaction formats and security best practices becomes increasingly challenging. 4. **Scalability Hurdles**: Managing multiple blockchain infrastructures to handle high transaction volumes is resource-intensive and can stretch your team thin. 5. **Data Privacy Concerns**: Balancing blockchain's inherent transparency with data protection regulations like GDPR and CCPA presents a unique set of challenges. Let's delve deeper into these challenges and explore how they impact your development process. ## The Intricacies of Blockchain Technology Imagine you're tasked with integrating support for Ethereum, Bitcoin, and The Open Network (TON) into your application. Each of these networks has its own nuances: * **Ethereum** uses an account-based model and requires management of nonces for transaction ordering. * **Bitcoin** uses a UTXO (Unspent Transaction Output) model, which requires a different approach to balance calculation and transaction construction. * **The Open Network (TON)** uses smart contract wallets where each wallet is a contract deployed on the blockchain, introducing unique requirements for transaction construction and signing. Keeping up with these differences is just the tip of the iceberg. As blockchain technology evolves, your team must continuously adapt your application to remain compatible. This constant state of change demands substantial resources and adds a layer of unpredictability to your development efforts. ## Build vs. Buy: A Technical Perspective When faced with blockchain integration, development teams often grapple with the decision to build their own solution or leverage existing tools. Let's compare these approaches:
Aspect Building Your Own Integration Leveraging a Adamik Unified API
Development Time Longer - requires building separate clients for each blockchain Shorter - single API for multiple blockchains
Protocol Handling Manual implementation of protocol-specific details Automatic handling of protocol-specific nuances
Maintenance Regular updates needed to keep pace with protocol changes Automatic updates to support new protocols and features
Security Custom security measures required for each blockchain Built-in security measures and best practices
Error Handling Custom error handling for each blockchain Simplified, unified error handling
Scalability Can be challenging as new blockchains are added Easily scalable to support new blockchains
Control Full control over implementation details Less control, but more standardized approach
Expertise Required Deep knowledge of multiple blockchain protocols Focus on application logic rather than blockchain specifics
Resource Allocation Significant developer resources needed for blockchain-specific work More resources available for core application development
While building your own integration offers full control, it comes with significant challenges. Leveraging a Adamik unified API reduces these burdens, allowing your team to focus on core application features. For teams looking to rapidly integrate blockchain functionality or work with multiple blockchains, a unified API solution can offer substantial benefits in development speed, maintenance, and scalability. The choice ultimately depends on your team's specific needs, expertise, and resources. ## The Bigger Picture: Impact on Your Product and Team While the technical aspects are crucial, it's equally important to consider the broader implications of blockchain integration on your product and team: 1. **Time to Market**: In the fast-paced world of blockchain, timing is critical. A unified API solution can significantly reduce development time, allowing you to capitalize on market opportunities faster. 2. **Resource Allocation**: Building and maintaining blockchain integrations in-house requires a team with specialized knowledge. This can be a significant investment, especially for smaller companies or those new to the blockchain space. 3. **User Experience**: The fragmented nature of blockchain networks can make it challenging to provide a consistent user experience. A unified solution can help streamline your UX across different blockchain functionalities. 4. **Scalability**: As your user base grows, can your blockchain integration handle increased transaction volumes? A robust, pre-built solution is often better equipped to handle scaling challenges. 5. **Future-Proofing**: With the rapid evolution of blockchain technology, how will you ensure your integration remains up-to-date? A dedicated solution provider can take this burden off your team's shoulders. ## Turning Complexity into Competitive Advantage Blockchain integration presents a unique set of challenges, but it also offers immense potential for innovation and growth. The key lies in approaching these challenges strategically: * For developers, it means focusing on creating value within your application rather than getting bogged down in the intricacies of multiple blockchain protocols. * For technical managers, it's about efficiently allocating resources and ensuring your team can move quickly without compromising on security or scalability. * For product managers, it's an opportunity to enhance your product offering and tap into new markets, without letting technical complexities slow down your roadmap. By carefully considering your team's capabilities, your product's needs, and your long-term goals, you can turn the challenge of blockchain integration into a significant competitive advantage. Ready to explore how a unified blockchain API can accelerate your development process? [Get your free Adamik API key](https://dashboard.adamik.io/) and start building today. # null Source: https://docs.adamik.io/get_started/overview Before exploring the detailed specifications and API references, review these high-level principles for an overview of the API's capabilities and workflow. ## API Categories The Adamik API is organized into four main categories: * **Chain**: Query blockchain network information and validators * **Account**: Retrieve account states, balances, and history * **Transaction**: Manage transaction lifecycle from encoding to broadcasting * **Utils**: Handle utility operations and helper functions ```mermaid theme={null} sequenceDiagram participant CLIENT as Client App participant ADAMIK as Adamik API %% Chain & Network Info %% Note right of CLIENT: Chain Information CLIENT->>ADAMIK: Query chain details/validators ADAMIK->>CLIENT: Return chain data %% Account Operations %% Note right of CLIENT: Account Operations CLIENT->>ADAMIK: Get account state/tokens/history ADAMIK->>CLIENT: Return account information %% Transaction Lifecycle %% Note right of CLIENT: Transaction Lifecycle CLIENT->>ADAMIK: Encode transaction ADAMIK->>CLIENT: Return encoded transaction CLIENT->>ADAMIK: Broadcast transaction ADAMIK->>CLIENT: Return transaction result ``` Read operations: Query network information and account states Write operations: Manage transaction lifecycle Utility functions and helper operations Note that our APIs are fully stateless and do not require access to private keys. # null Source: https://docs.adamik.io/get_started/pricing_plans We offer flexible plans for wallets, exchanges, and custodians
\$0 /month
Get started for free.
Perfect for solo builders & early prototyping
  • ✓ 5,000 API calls per month
  • ✓ Access to all supported blockchains
  • ✓ Discord support
  • ✓ Ideal for hackathons, testing, and MVPs
Get Started for Free
{" "}
\$250 /month
Pay-as-you-go. Ideal for scaling teams & production use
  • ✓ 10,000 API calls per month
  • ✓ Usage-based billing beyond 10k
  • ✓ Access to all supported blockchains
  • ✓ Priority Slack support
Talk to Us →
Custom
Ideal for high-throughput enterprises
  • ✓ Unlimited Calls
  • ✓ Access to all supported blockchains
  • ✓ Custom Rate Limits
  • ✓ White-glove Pilot
  • ✓ Premium Support
Talk to Us →
## How It Works 1. **Free Plan**: The Free Plan gives you 5,000 API calls per month with access to all supported blockchains. It's perfect for non-production use, offering basic rate limits and access to community support. No payment information is required to get started. 2. **Growth Plan**: This plan is designed for production environments. For \$250 per month, you get 10,000 API calls included, premium support, and increased rate limits for higher-volume use. After the first 10,000 API calls, additional calls are charged according to the dynamic pricing tiers below, which scale based on your usage. 3. **Enterprise Plan**: For businesses with high volume needs. This plan offers custom pricing, dedicated support, and tailored features for high-throughput enterprises. ## Pricing Tiers for Pay-As-You-Go Plan Your cost is recalculated immediately after each API call based on a rolling 30-day total, with prices dynamically adjusting to match the appropriate tier.
Tier API Calls Price per Call
1 10,001 - 500,000 \$0.00071
2 500,001 - 1,000,000 \$0.00064
3 1,000,001 - 5,000,000 \$0.00057
4 5,000,001 - 15,000,000 \$0.00050
5 15,000,001 - 50,000,000 \$0.00029
6 50,000,001 - 100,000,000 \$0.00023
7 >100,000,000 \$0.00011
## Example: Monthly Cost Calculation **Example Scenario:** * **Plan**: Growth Plan * **Total API Calls**: 1,200,000 (monthly) ### Calculation: 1. **API Call Charges**: * First 10,000 calls:\ Included in the monthly fee of \$250 * Next 490,000 calls (Tier 1):\ `490,000 × 0.00071 = $347.90` * Next 500,000 calls (Tier 2):\ `500,000 × 0.00064 = $320.00` * Remaining 200,000 calls (Tier 3):\ `200,000 × 0.00057 = $114.00` * **Total API Call Cost**:\ `$347.90 + $320.00 + $114.00 = $781.90` 2. **Total Monthly Cost**:\ `$781.90 (API Call Cost) + $250 (Flat Fee) = $1,031.90` ## Need More Features? We value your feedback. [Contact us](https://adamik.io/contact) to discuss upgrades. # null Source: https://docs.adamik.io/get_started/quick_start ## Get your API key 🔑 Start your Adamik journey by generating your personal API key. It's your ticket to the Multichain universe. [Sign up here](https://dashboard.adamik.io). ## Create your first read request 🔍 Dive into blockchain data with your first read request. Fetch data seamlessly with our API by trying the request below. ```cURL Get Available Balance theme={null} curl --request GET \ --url https://api.adamik.io/api/ethereum/account/0xfc43f5f9dd45258b3aff31bdbe6561d97e8b71de/state \ --header 'Authorization: ' ``` ```cURL Get Balance Bitcoin theme={null} curl --request GET \ --url https://api.adamik.io/api/bitcoin/account/bc1qekphvuz20qvdhkzywfe29r9vvtwxrszvaxzmqm/state \ --header 'Authorization: ' ``` ```cURL Get Balance Tron theme={null} curl --request GET \ --url https://api.adamik.io/api/tron/account/TVKG4gUar24bpAVrDv4GSzyDRtPkjPkogL/state \ --header 'Authorization: ' ``` ## Create your first write request 🖊️ Make your mark on the blockchain. Learn to submit write requests for seamless transaction handling. Whether transferring on Ethereum or Bitcoin, delegating on Cosmos, or claiming rewards on dYdX, the Adamik API simplifies crafting your transactions. ```cURL Transfer Ethereum theme={null} curl --request POST \ --url https://api.adamik.io/api/ethereum/transaction/encode \ --header 'Authorization: ' \ --data '{ "transaction": { "data": { "mode": "transfer", "senderAddress": "0x3f5CE5FBFe3E9af3971dD833D26bA9b5C936f0bE", "recipientAddress": "0xd8da6bf26964af9d7eed9e03e53415d37aa96045", "amount": "12345600000" } } }' ``` ```cURL Transfer Bitcoin theme={null} curl --request POST \ --url https://api.adamik.io/api/bitcoin/transaction/encode \ --header 'Authorization: ' \ --data '{ "transaction": { "data": { "mode": "transfer", "senderAddress": "bc1pdvagvvtvs3k35zxq7hp86x6cgp5kl6np786y50p7dj2m394rhrwq236ryc", "recipientAddress": "bc1qekphvuz20qvdhkzywfe29r9vvtwxrszvaxzmqm", "amount": "1" } } }' ``` ```cURL Delegate Cosmos theme={null} curl --request POST \ --url https://api.adamik.io/api/cosmoshub/transaction/encode \ --header 'Authorization: ' \ --data '{ "transaction": { "data": { "mode": "stake", "senderAddress": "cosmos1g84934jpu3v5de5yqukkkhxmcvsw3u2ajxvpdl", "recipientAddress": "", "targetValidatorAddress": "cosmosvaloper1clpqr4nrk4khgkxj78fcwwh6dl3uw4epsluffn", "amount": "123" } } }' ``` ```cURL Claim Rewards Dydx theme={null} curl --request POST \ --url https://api.adamik.io/api/dydx/transaction/encode \ --header 'Authorization: ' \ --data '{ "transaction": { "data": { "mode": "claimRewards", "sender": "dydx1yvuhqg73fdzxvam9sj7mazfa38gpn7uleyzn78", "recipient": "dydx1yvuhqg73fdzxvam9sj7mazfa38gpn7uleyzn78", "validatorAddress": "dydxvaloper1mwhwf9rqh64ktr8t8xnz37nhg7vvy42ec56jwe", "useMaxAmount": true } } }' ``` ## Fork the Adamik App and deep-dive into Adamik's API Explore Adamik's capabilities hands-on. Fork the [Adamik App](https://github.com/AdamikHQ/adamik-app) and build your own multichain application. Dive deeper into our [API Documentation](../api-reference) and unlock your project's potential. # Supported Chains Source: https://docs.adamik.io/get_started/supported_chains List of blockchains supported in the Adamik API with their respective features. You will get the same info using the [chain endpoint](../api-reference/chain/get-supported-chains) of the Adamik API. We're excited to announce upcoming support for the following blockchains: * 🐻 Berachain * ⚡ Polkadot * 🌐 Ethereum (Staking) * 🌊 Sui * 🌐 Stellar ## Exotic Layer 1s
Blockchain Name Network Identifier Native Balance Token Balance Native Transfer Token Transfer Staking and Rewards Transaction History
Algorand algorand ✅ ✅ ✅ ✅ ❌ ✅
Aptos aptos ✅ ✅ ✅ ✅ ✅ ✅
Babylon Testnet babylon ✅ ✅ ✅ ✅ ✅ ✅
StarkNet starknet ✅ ✅ ✅ ✅ Coming Soon ✅
Tron tron ✅ ✅ ✅ ✅ Coming Soon ✅
TON ton ✅ ✅ ✅ ✅ Coming Soon Coming Soon
Solana ton ✅ ✅ ✅ ✅ ✅ ✅
## Cosmos Ecosystem Chains
Blockchain Name Network Identifier Native Balance Token Balance Native Transfer Token Transfer Staking and Rewards Transaction History
Akash akash ✅ ✅ ✅ ❌ ✅ ✅
Axelar axelar ✅ ✅ ✅ ❌ ✅ ✅
Band Protocol band ✅ ✅ ✅ ❌ ✅ ❌
Celestia celestia ✅ ✅ ✅ ❌ ✅ ✅
Cosmos Hub cosmos ✅ ✅ ✅ ❌ ✅ ✅
Dydx dydx ✅ ✅ ✅ ❌ ✅ ✅
Evmos evmos ✅ ✅ ✅ ❌ ✅ ✅
Fetch.ai fetchai ✅ ✅ ✅ ❌ ✅ ❌
Humans.ai humans ✅ ✅ ✅ ❌ ✅ ❌
Injective injective ✅ ✅ ✅ ❌ ✅ ✅
IRISnet iris ✅ ✅ ✅ ❌ ✅ ❌
Juno juno ✅ ✅ ✅ ❌ ✅ ❌
Ki Chain ki ✅ ✅ ✅ ❌ ✅ ❌
KYVE kyve ✅ ✅ ✅ ❌ ✅ ❌
Lum Network lum ✅ ✅ ✅ ❌ ✅ ❌
MediBloc medibloc ✅ ✅ ✅ ❌ ✅ ❌
OmniFlix omniflix ✅ ✅ ✅ ❌ ✅ ❌
Osmosis osmosis ✅ ✅ ✅ ❌ ✅ ✅
Persistence persistence ✅ ✅ ✅ ❌ ✅ ❌
Quicksilver quicksilver ✅ ✅ ✅ ❌ ✅ ❌
Regen Network regen ✅ ✅ ✅ ❌ ✅ ❌
Secret Network secret ✅ ✅ ✅ ❌ ✅ ❌
Sei sei ✅ ✅ ✅ ❌ ✅ ❌
Stargaze stargaze ✅ ✅ ✅ ❌ ✅ ❌
Stride stride ✅ ✅ ✅ ❌ ✅ ❌
Terra terra ✅ ✅ ✅ ❌ ✅ ❌
## UTXO Chains
Blockchain Name Network Identifier Native Balance Token Balance Native Transfer Token Transfer Staking and Rewards Transaction History
Bitcoin bitcoin, bitcoin-testnet ✅ ❌ ✅ ❌ ✅ ❌
Dogecoin dogecoin ✅ ❌ ✅ ❌ ❌ ❌
Litecoin litecoin ✅ ❌ ✅ ❌ ❌ ❌
## EVM Chains
Blockchain Name Network Identifier Native Balance Token Balance Native Transfer Token Transfer Staking and Rewards Transaction History
Arbitrum One arbitrum-one ✅ ✅ ✅ ✅ ❌ ✅
Avalanche avalanche-c ✅ ✅ ✅ ✅ ❌ ✅
Base base ✅ ✅ ✅ ✅ ❌ ✅
Binance Smart Chain bsc ✅ ✅ ✅ ✅ ❌ ✅
Chiliz Chain chiliz ✅ ✅ ✅ ✅ ❌ ✅
Ethereum ethereum, ethereum-goerli ✅ ✅ ✅ ✅ COMING SOON ✅
Fantom fantom ✅ ✅ ✅ ✅ ❌ ✅
Gnosis gnosis ✅ ✅ ✅ ✅ ❌ ✅
Kava kava ✅ ✅ ✅ ❌ ✅ ✅
Linea linea ✅ ✅ ✅ ✅ ❌ ✅
Mantle Network mantle ✅ ✅ ✅ ✅ ❌ ✅
Moonbeam moonbeam ✅ ✅ ✅ ✅ ❌ ✅
Moonriver moonriver ✅ ✅ ✅ ✅ ❌ ✅
Optimism optimism ✅ ✅ ✅ ✅ ❌ ✅
Polygon polygon ✅ ✅ ✅ ✅ ❌ ✅
ZkSync zksync ✅ ✅ ✅ ✅ ❌ ✅
Injective EVM Testnet injective-evm-testnet ✅ ✅ ✅ ✅ ❌ ✅
RootStock rootstock, rootstock-testnet ✅ ❌ ❌ ❌ ❌ ❌
# Welcome to Adamik! Source: https://docs.adamik.io/get_started/welcome Everything you need to start building with Adamik, all in one place. Adamik Intro Adamik offers API tools designed to simplify blockchain integration, providing a faster and more reliable alternative to traditional methods. This portal is your complete guide to using Adamik. It contains all the tools and information you need to navigate the realm of multichain capabilities effectively. ### Key Features * **Multichain Support**: Seamlessly interact with multiple blockchain networks. * **Unified API**: Simplifies data retrieval and transaction management. * **Non Custodial**: You maintain control over your private keys and transactions. ### Why Build with Adamik APIs? Integrating blockchain functionality can be complex, with challenges such as protocol diversity, infrastructure overhead, and the need for continuous updates. By leveraging Adamik's unified API, you can significantly reduce development time and resource allocation while ensuring robust security measures are in place. For a deeper understanding of why building on Adamik is advantageous compared to creating your own in-house solution, check out our [Build vs. Buy](./Build-VS-Buy) guide. > **🛡 You stay in control 🛡** > > Self-custody and user autonomy are paramount at Adamik. We don't handle your private keys or digital signatures directly. Instead, every transaction requires your explicit approval, maintaining your control over all blockchain operations. ### Next Steps Get your [free API key](https://dashboard.adamik.io)🔑 and make your first request. Take a look at [Adamik's API overview](./overview) to get familiar with the main modules the API offers. Check out our [API Reference](../api-reference) to explore the functionalities of the Adamik API. ### Get in Touch Connect with us through our [Discord Server](https://discord.gg/gsZJR2JfMR) or directly through [GitHub](https://github.com/AdamikHQ). We're here to support you at every step of your journey. Let's embark on this exciting venture together! 🚀 # Whitelabelled Staking API Source: https://docs.adamik.io/get_started/whitelabelled-staking-api ## Overview The Adamik Staking White-Labeled API is a fully integrated, non-custodial solution designed specifically for staking providers. This API enables staking providers to seamlessly provide staking functionalities to Enterprise and Institutional clients. ## Why Staking Providers Need a Staking API Staking providers need to reach users where they already are: on wallets, exchanges, custodians, and institutional platforms. However, infrastructure excellence is sometimes not sufficient to reach these players. Staking providers need to solve their clients' problems by facilitating the technical integration of the underlying protocols they operate on. Many staking providers have understood this and have spent tens of thousands in development resources to build their own staking API solutions. Adamik's white-labeled staking API allows staking providers to release their own Staking API in a matter of days, at a fraction of the cost, and without dealing with maintenance or support. ## Product Description Adamik White-Labeled Staking API offers powerful API tools designed to simplify staking across multiple blockchain networks, providing a faster and more reliable alternative to building everything in-house.
Feature Description
Data Retrieval Provides real-time and historical blockchain data, including balances, validator information, and transaction history.
Basic Transaction Management Facilitates seamless interaction with blockchain networks by enabling end clients to create and broadcast basic transaction transactions such as main currency and token transfers.
Staking and Delegation Offers a simplified way for end clients to delegate and manage staking positions across multiple PoS networks. Through the staking provider's platform, clients can initiate delegations, redelegate between validators, and undelegate programmatically without handling complex blockchain interactions themselves.
Technical Support Direct support on Discord for end clients or Slack to ensure smooth integration and usability.
Custom Documentation Adamik creates a custom developer portal to be integrated into the staking provider's website (see example:{" "} here)
## Pricing Book a call with our team to learn more about our Whitelabelled Staking API # null Source: https://docs.adamik.io/guides/e2e-examples/using-Adamik-API-with-Bitcoin This guide demonstrates how to create, sign, and broadcast a transaction using the Adamik API along with the common Bitcoin library, `bitcoinjs-lib`. This tutorial is perfect for developers who want to integrate Adamik's features into their Bitcoin workflows, ensuring secure and efficient transaction management. ## Prerequisites * **Node.js** and **npm** installed * Basic understanding of Bitcoin and transaction workflows * Familiarity with the `bitcoinjs` library ## Step-by-Step Guide ### 1. Setting Up the Environment Ensure you have the `bitcoinjs` library installed in your project: ```bash theme={null} npm install bitcoinjs-lib ``` In this example, we'll start with just the mnemonic and derive a typical HD wallet. For that, we'll require bip32 and bip39 libraries: ```bash theme={null} npm install bip32 bip39 ``` Finally, because we'll be using deriving a Taproot account for this example, you'll also need a elyptic curve cryptographiy library (ECC): ```bash theme={null} npm install @bitcoinerlab/secp256k1 ``` ### 2. Writing the Script [https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki](https://github.com/bitcoin/bips/blob/master/bip-0086.mediawiki) Below is the script that handles the full transaction flow, from creating a wallet to broadcasting the signed transaction. You can find the complete code example in the [Adamik GitHub repository](https://github.com/AdamikHQ/adamik-link/blob/main/test/docs/bitcoin.spec.ts). ```javascript theme={null} import * as ecc from "@bitcoinerlab/secp256k1"; import BIP32Factory from "bip32"; import * as bip39 from "bip39"; import * as bitcoin from "bitcoinjs-lib"; import { toXOnly } from "bitcoinjs-lib/src/psbt/bip371"; bitcoin.initEccLib(ecc); const bip32 = BIP32Factory(ecc); // Replace with your wallet's mnemonic phrase const mnemonic = "your mnemonic phrase here"; // Fill in your derivation path for Taproot (BIP-86) // This script is setup as if this account has 1 simple UTXO of more than 100000 sats const derivationPath = `m/86'/0'/0'/0/0`; // Replace with recipient address or leave empty for self-transfer const recipientAddress = ""; // Replace with your Adamik API key from https://dashboard.adamik.io const ADAMIK_API_KEY = "your-adamik-api-key"; async function main() { try { // Create wallet using mnemonic phrase const seed = await bip39.mnemonicToSeed(mnemonic); const rootKey = bip32.fromSeed(seed); const childNode = rootKey.derivePath(derivationPath); const internalPubkey = toXOnly(Buffer.from(childNode.publicKey)); const { address } = bitcoin.payments.p2tr({ internalPubkey, }); console.log("Public address of sender:", address); // Prepare the transaction request const requestBody = { transaction: { data: { chainId: "bitcoin", // Target Bitcoin mode: "transfer", // Simple tx senderAddress: address, recipientAddress: recipientAddress || address, amount: "10", // Transaction amount in satoshis }, }, }; console.log("Encoding transaction..."); // Encode the transaction with Adamik API const responseEncode = await fetch( "https://api.adamik.io/api/bitcoin/transaction/encode", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify(requestBody), } ); const encodedData = await responseEncode.json(); console.log( "Encoded transaction data:", JSON.stringify(encodedData, null, 2) ); const rawtx = encodedData.transaction.encoded; console.log("Signing transaction..."); // Create and sign the PSBT (Partially Signed Bitcoin Transaction) const psbt = bitcoin.Psbt.fromHex(rawtx); psbt.updateInput(0, { tapInternalKey: internalPubkey, }); const tweakedChildNode = childNode.tweak( bitcoin.crypto.taggedHash("TapTweak", internalPubkey) ); psbt.signTaprootInput(0, tweakedChildNode); psbt.finalizeAllInputs(); const signedTransaction = psbt.extractTransaction().toHex(); console.log("Transaction signed"); // Prepare to broadcast the signed transaction const sendTransactionBody = { transaction: { data: encodedData.transaction.data, encoded: encodedData.transaction.encoded, signature: signedTransaction, }, }; console.log("Broadcasting transaction..."); // Broadcast the transaction using Adamik API const responseBroadcast = await fetch( "https://api.adamik.io/api/bitcoin/transaction/broadcast", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify(sendTransactionBody), } ); const responseData = await responseBroadcast.json(); console.log("Transaction Result:", JSON.stringify(responseData, null, 2)); console.log("Transaction hash:", responseData.hash); } catch (error) { console.error("Error:", error); } } main(); ``` ### 3. Explanation * **Wallet Creation**: The script begins by creating a wallet using a mnemonic phrase, which is crucial for managing private keys. Please note Adamik API doesn't have the custody of the assets. * **Transaction Encoding**: The transaction details are passed to the Adamik API, which translates them into a raw transaction to be signed. * **Signing and Broadcasting**: The transaction is then signed with the wallet's private key and finally broadcast to the Bitcoin network using the Adamik API. ### 4. Troubleshooting * **Invalid API Key**: Ensure your Adamik API key is correct. * **Network Issues**: Verify network availability and Adamik API status. * **Security Note**: Never hardcode sensitive information like mnemonic phrases in your production environment. ### 5. Get in Touch Connect with us through our [Discord Server](https://discord.gg/gsZJR2JfMR) or directly through [GitHub](https://github.com/AdamikHQ). # null Source: https://docs.adamik.io/guides/e2e-examples/using-Adamik-API-with-Ethereum This guide demonstrates how to create, sign, and broadcast a transaction using the Adamik API along with a common Ethereum library, `ethers.js`. This tutorial is perfect for developers who want to integrate Adamik's features into their Ethereum workflows, ensuring secure and efficient transaction management. ## Prerequisites * **Node.js** and **npm** installed * Basic understanding of Ethereum and transaction workflows * Familiarity with the `ethers.js` library ## Step-by-Step Guide ### 1. Setting Up the Environment Ensure you have the `ethers` library installed in your project: ```bash theme={null} npm install ethers ``` ### 2. Writing the Script Below is the script that handles the full transaction flow, from creating a wallet to broadcasting the signed transaction. You can find the complete code example in the [Adamik GitHub repository](https://github.com/AdamikHQ/adamik-link/blob/main/test/docs/ethereum.spec.ts). ```javascript theme={null} import { Wallet } from "ethers"; // Replace with your wallet's mnemonic phrase const walletPhrase = "your mnemonic phrase here"; // Replace with your Adamik API key from https://dashboard.adamik.io const ADAMIK_API_KEY = "your-adamik-api-key"; // Replace with the recipient's address or leave empty for self-transfer const recipientAddress = "0xeD35957be660cf9A2C768fDB52eC4D9D19eEB80F"; async function main() { try { console.log("Creating wallet..."); const wallet = Wallet.fromPhrase(walletPhrase); console.log("Wallet created"); console.log("Sender address:", wallet.address); const requestBody = { transaction: { data: { chainId: "sepolia", // Target Ethereum testnet chain mode: "transfer", senderAddress: wallet.address, recipientAddress: recipientAddress || wallet.address, // Self-send if no recipient amount: "10000", // Transaction amount useMaxAmount: false, fees: "0", gas: "0", memo: "", format: "json", validatorAddress: "", params: { pubKey: wallet.publicKey, // Public key of the wallet }, }, }, }; console.log("Encoding transaction..."); // Encode the transaction with Adamik API const responseEncode = await fetch( "https://api.adamik.io/api/sepolia/transaction/encode", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify(requestBody), } ); const encodedData = await responseEncode.json(); console.log( "Encoded transaction data:", JSON.stringify(encodedData, null, 2) ); // Sign the encoded transaction const tx = encodedData.transaction.encoded; console.log("Signing transaction..."); const signature = await wallet.signTransaction(tx); console.log("Transaction signed"); // Prepare to broadcast the signed transaction const sendTransactionBody = { transaction: { data: encodedData.transaction.data, encoded: tx, signature: signature, }, }; console.log("Broadcasting transaction..."); // Broadcast the transaction using Adamik API const responseBroadcast = await fetch( "https://api.adamik.io/api/sepolia/transaction/broadcast", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify(sendTransactionBody), } ); const responseData = await responseBroadcast.json(); console.log("Transaction Result:", JSON.stringify(responseData, null, 2)); console.log("Transaction hash:", responseData.hash); } catch (error) { console.error("Error:", error); } } main(); ``` ### 3. Explanation * **Wallet Creation**: The script begins by creating a wallet using a mnemonic phrase, which is crucial for managing private keys. Please note Adamik API doesn't have the custody of the assets. * **Transaction Encoding**: The transaction details are passed to the Adamik API, which translates them into a raw transaction to be signed. * **Signing and Broadcasting**: The transaction is then signed with the wallet's private key and finally broadcast to the Ethereum network using the Adamik API. ### 4. Troubleshooting * **Invalid API Key**: Ensure your Adamik API key is correct. * **Network Issues**: Verify network availability and Adamik API status. * **Security Note**: Never hardcode sensitive information like mnemonic phrases in your production environment. ### 5. Get in Touch Connect with us through our [Discord Server](https://discord.gg/gsZJR2JfMR) or directly through [GitHub](https://github.com/AdamikHQ). # null Source: https://docs.adamik.io/guides/e2e-examples/using-Adamik-API-with-StarkNet This guide demonstrates how to create, sign, and broadcast a transaction using the Adamik API with StarkNet. This tutorial is perfect for developers who want to leverage Adamik to power their StarkNet workflow, ensuring secure and efficient transaction management. ## Prerequisites * **Node.js** and **npm** installed * Basic understanding of StarkNet blockchain and transaction workflows * Familiarity with StarkNet libraries ## Step-by-Step Guide ### 1. Setting Up the Environment Install the required dependencies: ```bash theme={null} npm install starknet ``` ### 2. Writing the Script Below is the script that handles StarkNet transactions, including wallet deployment and transfers: You can find the complete code example in the [Adamik GitHub repository](https://github.com/AdamikHQ/adamik-link/blob/main/test/docs/starknet.spec.ts). ```javascript theme={null} import { ec } from "starknet"; // Replace with your StarkNet private key const walletPrivateKey = "your-starknet-private-key"; // Replace with your Adamik API key from https://dashboard.adamik.io const ADAMIK_API_KEY = "your-adamik-api-key"; async function main() { try { console.log("Creating wallet..."); const pubKey = ec.starkCurve.getStarkKey(walletPrivateKey); // First, let's get our wallet address const requestBodyAddressEncode = { pubkey: pubKey, }; // Fetch the wallet address from Adamik API const responseAddressEncode = await fetch( "https://api.adamik.io/api/starknet/address/encode", { method: "POST", headers: { "Content-Type": "application/json", Authorization: ADAMIK_API_KEY, }, body: JSON.stringify(requestBodyAddressEncode), } ); const addressEncode = await responseAddressEncode.json(); // Get the ArgentX wallet address const senderAddress = addressEncode.addresses.find( (address) => address.type === "argentx" ).address; console.log("Sender address:", senderAddress); // Prepare the transfer transaction const requestBody = { transaction: { data: { mode: "transfer", // Transaction type senderAddress, // Our wallet address recipientAddress: senderAddress, // Where we're sending to (self-transfer in this example) amount: "20000000000", // Amount in wei (0.00002 STRK in this example) }, }, }; console.log("Encoding transaction..."); const response = await fetch( "https://api.adamik.io/api/starknet/transaction/encode", { method: "POST", headers: { "Content-Type": "application/json", Authorization: ADAMIK_API_KEY, }, body: JSON.stringify(requestBody), } ); let encodedData = await response.json(); // Check for encoding errors if ( encodedData.status && encodedData.status.errors && encodedData.status.errors.length > 0 ) { if ( encodedData.status.errors[0].message === "Sender account does not exist" ) { console.log( "Account never deployed... Creating deployment transaction" ); // We need to deploy the account because it hasn't been deployed yet const requestBodyDeploy = { transaction: { data: { mode: "deployAccount", // Transaction type senderPubKey: pubKey, type: "argentx", }, }, }; console.log("Encoding deployment transaction..."); const responseDeploy = await fetch( "https://api.adamik.io/api/starknet/transaction/encode", { method: "POST", headers: { "Content-Type": "application/json", Authorization: ADAMIK_API_KEY, }, body: JSON.stringify(requestBodyDeploy), } ); encodedData = await responseDeploy.json(); console.log( "Deployment transaction encoded:", JSON.stringify(encodedData, null, 2) ); } else { throw new Error(encodedData.status.errors[0].message); } } console.log("Signing transaction..."); // Sign the encoded transaction using StarkNet curve const signature = ec.starkCurve.sign( encodedData.transaction.encoded, walletPrivateKey ); const signatureHex = signature.toDERHex(); console.log("Transaction signed"); // Prepare the broadcast request const broadcastTransactionBody = { transaction: { ...encodedData.transaction, signature: signatureHex, }, }; console.log("Broadcasting transaction..."); // Broadcast the signed transaction const broadcastResponse = await fetch( "https://api.adamik.io/api/starknet/transaction/broadcast", { method: "POST", headers: { "Content-Type": "application/json", Authorization: ADAMIK_API_KEY, }, body: JSON.stringify(broadcastTransactionBody), } ); const responseData = await broadcastResponse.json(); console.log("Transaction Result:", JSON.stringify(responseData, null, 2)); console.log("Transaction hash:", responseData.hash); } catch (error) { console.error("Error:", error); } } main(); ``` ### 3. Explanation * **Key Generation**: The script uses the StarkNet curve to generate a public key from your private key. * **Address Encoding**: Before making a transfer, we need to get our wallet address using the Adamik API's address encode endpoint. * **Transaction Encoding**: The transaction details are passed to the Adamik API, which encodes the transaction specifically for StarkNet. * **Signing**: The encoded transaction is signed using StarkNet's signature scheme. * **Broadcasting**: The signed transaction is broadcast to the StarkNet network via the Adamik API. * **Account Deployment**: The script also handles the case where the account hasn't been deployed yet, automatically creating a deployment transaction if needed. ### 4. Troubleshooting * **Invalid Signature**: Ensure you're using the correct private key and StarkNet curve for signing. * **Gas Fees**: Make sure your wallet has enough funds to cover gas fees. ### 5. Get in Touch Connect with us through our [Discord Server](https://discord.gg/gsZJR2JfMR) or directly through [GitHub](https://github.com/AdamikHQ). # null Source: https://docs.adamik.io/guides/e2e-examples/using-Adamik-API-with-Stellar This guide demonstrates how to create, sign, and broadcast a transaction using the Adamik API along with the Stellar SDK for JavaScript. This tutorial is perfect for developers who want to integrate Adamik's features into their Stellar workflows, ensuring secure and efficient transaction management. ## Prerequisites * **Node.js** and **npm** installed * Basic understanding of Stellar and transaction workflows * Familiarity with the Stellar SDK ## Step-by-Step Guide ### 1. Setting Up the Environment Ensure you have the Stellar SDK installed in your project: ```bash theme={null} npm install @stellar/stellar-sdk ``` ### 2. Writing the Script Below is the script that handles the full transaction flow, from creating a wallet to broadcasting the signed transaction. You can find the complete code example in the [Adamik GitHub repository](https://github.com/AdamikHQ/adamik-link/blob/main/test/docs/stellar.spec.ts). ```javascript theme={null} const { Keypair } = require("@stellar/stellar-sdk"); // Replace with your wallet's secret key const secretKey = "your-stellar-secret-key-here"; // Replace with your Adamik API key from https://dashboard.adamik.io const ADAMIK_API_KEY = "your-adamik-api-key"; // Replace with the recipient's address const recipientAddress = "GCKFBEIYV2U22IO2BJ4KVJOIP7XPWQGQFKKWXR6DOSJBV7STMAQSMTMA"; async function main() { try { // Create wallet from secret key const sourceKeypair = Keypair.fromSecret(secretKey); const sourcePublicKey = sourceKeypair.publicKey(); // Prepare the transaction request for Adamik API const requestBody = { transaction: { data: { chainId: "stellar", // Target Stellar mainnet (use "stellar-testnet" for testnet) mode: "transfer", senderAddress: sourcePublicKey, recipientAddress: recipientAddress || sourcePublicKey, // Self-send if no recipient amount: "10000000", // Transaction amount in stroops (1 XLM = 10^7 stroops) useMaxAmount: false, fees: "0", gas: "0", memo: "Adamik Transfer", format: "json", validatorAddress: "", }, }, }; // Encode the transaction with Adamik API const responseEncode = await fetch( "https://api.adamik.io/api/stellar/transaction/encode", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify(requestBody), } ); const encodedData = await responseEncode.json(); if (!responseEncode.ok) { console.error("Encode failed:", encodedData); return; } // Sign the transaction hash const hashToSign = encodedData.transaction.encoded[0].hash.value; const hashBuffer = Buffer.from(hashToSign, 'hex'); const signature = sourceKeypair.sign(hashBuffer); const signatureHex = signature.toString('hex'); // Prepare to broadcast the signed transaction const sendTransactionBody = { transaction: { data: encodedData.transaction.data, encoded: encodedData.transaction.encoded, signature: signatureHex, }, }; // Broadcast the transaction using Adamik API const responseBroadcast = await fetch( "https://api.adamik.io/api/stellar/transaction/broadcast", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify(sendTransactionBody), } ); const responseData = await responseBroadcast.json(); console.log("Transaction hash:", responseData.hash); } catch (error) { console.error("Error:", error); } } main(); ``` ### 3. Explanation * **Wallet Creation**: The script begins by creating a wallet using a Stellar secret key, which is crucial for managing private keys. Please note Adamik API doesn't have the custody of the assets. * **Transaction Encoding**: The transaction details are passed to the Adamik API, which returns an encoded transaction with its hash. Note that amounts are in stroops (1 XLM = 10,000,000 stroops). * **Signing**: The transaction hash is signed directly using the Stellar Keypair's sign method, producing a hex signature. * **Broadcasting**: The signed transaction is broadcast to the Stellar network using the Adamik API with the signature attached. ### 4. Troubleshooting * **Invalid API Key**: Ensure your Adamik API key is correct. * **Network Issues**: Verify network availability and Adamik API status. * **Insufficient Balance**: Ensure your account has enough XLM to cover the transaction amount plus fees. * **Security Note**: Never hardcode sensitive information like secret keys in your production environment. ### 5. Get in Touch Connect with us through our [Discord Server](https://discord.gg/gsZJR2JfMR) or directly through [GitHub](https://github.com/AdamikHQ). # null Source: https://docs.adamik.io/guides/e2e-examples/using-Adamik-API-with-TON This guide demonstrates how to create, sign, and broadcast a transaction using the Adamik API along with a TON signer. This tutorial is perfect for developers who want to leverage Adamikto power their TON workflow, ensuring secure and efficient transaction management. ## Prerequisites * **Node.js** and **npm** installed * Basic understanding of TON blockchain and transaction workflows * Familiarity with the TON libraries (`@ton/crypto`, `@ton/ton`) ## Step-by-Step Guide ### 1. Setting Up the Environment Ensure you have the required TON libraries installed in your project: ```bash theme={null} npm install @ton/crypto @ton/ton node-fetch ``` ### 2. Writing the Script Below is the script that handles the full transaction flow, from creating a wallet to broadcasting the signed transaction. You can find the complete code example in the [Adamik GitHub repository](https://github.com/AdamikHQ/adamik-link/blob/main/test/docs/ton.spec.ts). ```javascript theme={null} import { mnemonicToPrivateKey, sign } from "@ton/crypto"; import { WalletContractV4 } from "@ton/ton"; // Replace with your wallet's mnemonic phrase const walletPhrase = "your mnemonic phrase here"; // Replace with your Adamik API key from https://dashboard.adamik.io const ADAMIK_API_KEY = "your-adamik-api-key"; // Replace with recipient address or leave empty for self-transfer const recipientAddress = ""; async function main() { try { console.log("Creating wallet..."); const keyPair = await mnemonicToPrivateKey(walletPhrase.split(" ")); // Define the workchain and create a wallet contract let workchain = 0; let wallet = WalletContractV4.create({ workchain, publicKey: keyPair.publicKey, }); const address = wallet.address.toString(); console.log("Wallet created: ", address); // Prepare the transaction request const requestBody = { transaction: { data: { chainId: "ton", // TON blockchain mode: "transfer", senderAddress: address, recipientAddress: recipientAddress || address, amount: "10000", useMaxAmount: false, fees: "0", // Set fees to 0 for now gas: "0", // Gas is not required on TON memo: "", // Optionally, add a memo format: "hex", validatorAddress: "", params: { pubKey: keyPair.publicKey.toString("hex"), }, }, }, }; console.log("Encoding transaction..."); // Encode the transaction with Adamik API const responseEncode = await fetch( "https://api.adamik.io/api/ton/transaction/encode", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify(requestBody), } ); const encodedData = await responseEncode.json(); console.log( "Encoded transaction data:", JSON.stringify(encodedData, null, 2) ); // Sign the encoded transaction const tx = encodedData.transaction.encoded; console.log("Signing transaction..."); // Sign the encoded transaction const signature = sign( Buffer.from(encodedData.transaction.encoded, "hex"), keyPair.secretKey ).toString("hex"); console.log("Transaction signed"); // Prepare to broadcast the signed transaction const sendTransactionBody = { transaction: { data: encodedData.transaction.data, encoded: tx, signature: signature, }, }; console.log("Broadcasting transaction..."); // Broadcast the transaction using Adamik API const responseBroadcast = await fetch( "https://api.adamik.io/api/ton/transaction/broadcast", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify(sendTransactionBody), } ); const responseData = await responseBroadcast.json(); console.log("Transaction Result:", JSON.stringify(responseData, null, 2)); console.log("Transaction hash:", responseData.hash); } catch (error) { console.error("Error:", error); } } main(); ``` ### 3. Explanation * **Key Pair Generation**: The script generates a key pair from a mnemonic phrase using the `@ton/crypto` library, which is helpful for managing private keys and signing transactions on TON. Please note Adamik API doesn't have the custody of the assets. * **Transaction Encoding**: The transaction details, such as sender, recipient, and amount, are passed to the Adamik API, which encodes the transaction for signing. * **Signing and Broadcasting**: The encoded transaction is signed using the private key, and the signed transaction is then broadcast to the TON blockchain via the Adamik API. ### 4. Troubleshooting * **Invalid API Key**: Ensure your Adamik API key is correct and up to date. * **Network Issues**: Verify network availability and Adamik API status. * **Security Note**: Never hardcode sensitive information such as mnemonic phrases or private keys in your production environment. ### 5. Get in Touch Connect with us through our [Discord Server](https://discord.gg/gsZJR2JfMR) or directly through [GitHub](https://github.com/AdamikHQ). # Integrating Sodot MPC with Adamik API Source: https://docs.adamik.io/guides/signers/integrating-sodot-mpc This guide demonstrates how to integrate Sodot's secure Multi-Party Computation (MPC) technology with the Adamik API, based on our [live demo application](https://sodot-multichain.adamik.io). By following this implementation, you can leverage a single MPC infrastructure to sign transactions across all Adamik-supported blockchains. ## Overview The [sodot-multichain demo](https://sodot-multichain.adamik.io) showcases how Sodot MPC technology can be combined with Adamik API to: * Generate cryptographic keys securely using MPC across multiple parties * Sign transactions for 60+ blockchains without exposing private keys * Provide institutional-grade security for blockchain operations The complete source code for this implementation is available in our [GitHub repository](https://github.com/AdamikHQ/adamik-tutorial/tree/sodot-signer). ## Implementation Architecture The integration consists of three main components: 1. **Sodot MPC Signer**: Handles key generation and transaction signing 2. **Adamik API Client**: Manages blockchain interactions (encoding addresses, preparing and broadcasting transactions) 3. **Application Logic**: Connects these components in a seamless workflow ## Implementing the Sodot Signer The core of the integration is the `SodotSigner` class, which implements the `BaseSigner` interface: ```typescript theme={null} // Based on src/signers/types.ts export interface BaseSigner { signerSpec: AdamikSignerSpec; signerName: string; chainId: string; getPubkey(): Promise; signTransaction(encodedMessage: string): Promise; } ``` Here's a simplified implementation based on our demo application: ```typescript theme={null} // Based on src/signers/Sodot.ts export class SodotSigner implements BaseSigner { public chainId: string; public signerSpec: AdamikSignerSpec; public signerName = "SODOT"; private SODOT_VERTICES = [ "https://sodot-vertex-1.example.com", "https://sodot-vertex-2.example.com", "https://sodot-vertex-3.example.com", ]; private n = 3; // Number of parties private t = 2; // Threshold (minimum parties needed) private keyIds: string[] = []; constructor(chainId: string, signerSpec: AdamikSignerSpec) { this.chainId = chainId; this.signerSpec = signerSpec; } // Check if Sodot configuration is valid static isConfigValid(): boolean { // Verify environment variables and configuration return true; // Simplified for this example } // Get or generate public key public async getPubkey(): Promise { // If keys don't exist, generate them if (this.keyIds.length === 0) { await this.keygenVertex( this.adamikCurveToSodotCurve(this.signerSpec.curve) ); } // Derive public key using the first vertex const pubkeyResponse = await this.derivePubkeyWithVertex( 0, this.keyIds[0], [44, Number(this.signerSpec.coinType), 0, 0, 0], this.adamikCurveToSodotCurve(this.signerSpec.curve) ); return pubkeyResponse.pubkey; } // Sign a transaction public async signTransaction(encodedMessage: string): Promise { // Determine hash method based on chain const hashMethod = this.adamikHashFunctionToSodotHashMethod( this.signerSpec.hashFunction, this.signerSpec.curve ); // Sign the transaction const signature = await this.sign( encodedMessage, this.keyIds, [44, Number(this.signerSpec.coinType), 0, 0, 0], this.signerSpec.curve, hashMethod ); return signature; } // Helper methods (simplified) private adamikCurveToSodotCurve( adamikCurve: AdamikCurve ): "ecdsa" | "ed25519" { return adamikCurve === AdamikCurve.SECP256K1 ? "ecdsa" : "ed25519"; } private adamikHashFunctionToSodotHashMethod( hashAlgo: AdamikHashFunction, curve: AdamikCurve ): "sha256" | "keccak256" | undefined { // Map Adamik hash functions to Sodot hash methods if (hashAlgo === AdamikHashFunction.SHA256) return "sha256"; if (hashAlgo === AdamikHashFunction.KECCAK256) return "keccak256"; return undefined; } // Additional methods for key generation, signing, etc. // See the full implementation in the GitHub repository } ``` ## Integration Workflow The demo application follows this workflow: 1. **Initialize the Signer**: Create a `SodotSigner` instance for the selected blockchain 2. **Generate Public Key**: Call `getPubkey()` to generate or retrieve the MPC key 3. **Encode Address**: Use Adamik API to convert the public key to a blockchain address 4. **Prepare Transaction**: Use Adamik API to encode a transaction 5. **Sign Transaction**: Use the `SodotSigner` to sign the encoded transaction 6. **Broadcast Transaction**: Send the signed transaction to the network via Adamik API Here's how this workflow is implemented in the demo application: ```typescript theme={null} // Example from src/utils/terminalCommands.tsx (simplified) async function executeChainSelection(chainId: string) { // Get chain information from Adamik API const chain = await adamikGetChain(chainId); // Create SodotSigner instance const signer = new SodotSigner(chainId, chain.signerSpec); // Generate public key const pubkey = await signer.getPubkey(); // Convert public key to address using Adamik API const { address } = await encodePubKeyToAddress(pubkey, chainId); // Store for later use workflowState.selectedChain = chainId; workflowState.pubkey = pubkey; workflowState.address = address; return { success: true, address, pubkey }; } async function executeSignTransaction() { const { selectedChain, encodedTransaction } = workflowState; // Recreate signer with the same chain and signer spec const chain = await adamikGetChain(selectedChain); const signer = new SodotSigner(selectedChain, chain.signerSpec); // Sign the transaction const signature = await signer.signTransaction(encodedTransaction); // Store signature for broadcasting workflowState.signature = signature; return { success: true, signature }; } async function executeBroadcastTransaction() { const { selectedChain, encodedTransaction, signature } = workflowState; // Broadcast the transaction using Adamik API const result = await broadcastTransaction( selectedChain, encodedTransaction, signature ); // Store transaction hash workflowState.txHash = result.hash; return { success: true, hash: result.hash }; } ``` ## Adamik API Integration The demo application uses a set of utility functions to interact with the Adamik API. These functions are located in the `src/adamik` directory: * `encodePubkeyToAddress.ts`: Converts a public key to a blockchain address * `encodeTransaction.ts`: Prepares a transaction for signing * `broadcastTransaction.ts`: Broadcasts a signed transaction to the network These functions handle the API calls, error handling, and logging, making it easy to integrate with the Sodot MPC signer. ## Security Considerations This demo application uses the Sodot Demo API for demonstration purposes only. For production deployments, it is critical to: 1. **Use Official Sodot Setup**: Always work with Sodot through official channels to set up your production MPC infrastructure 2. **Never Use Demo API in Production**: The Demo API is for testing and educational purposes only 3. **Follow Security Best Practices**: * Distributed Key Generation: Keys are generated across multiple parties (vertices) * Threshold Signing: Requires multiple parties to collaborate for signing * No Private Key Exposure: Private key material is never combined or exposed * API Logging: All API calls are logged for audit purposes ## Testing the Integration You can test this integration by: 1. Visiting the [live demo](https://sodot-multichain.adamik.io) 2. Cloning the [GitHub repository](https://github.com/AdamikHQ/adamik-tutorial/tree/sodot-signer) 3. Setting up your own environment with Sodot MPC and Adamik API ## Conclusion The integration of Sodot MPC with Adamik API provides a powerful solution for secure multi-chain applications. By following the implementation in our demo application, you can leverage this integration to build your own secure blockchain applications. For more details, explore the full source code in our [GitHub repository](https://github.com/AdamikHQ/adamik-tutorial/tree/sodot-signer), particularly the `src/signers/Sodot.ts` file for the MPC implementation and the `src/adamik` directory for the API integration. # Integrating Turnkey with Adamik API Source: https://docs.adamik.io/guides/signers/integrating-turnkey This guide demonstrates how to integrate Turnkey's secure signing infrastructure with the Adamik API. By following this implementation, you can leverage Turnkey's institutional-grade key management system to sign transactions across all Adamik-supported blockchains. ## Overview The integration showcases how Turnkey can be combined with Adamik API to: * Securely manage cryptographic keys in a custodial environment * Sign transactions for 60+ blockchains with enterprise-grade security * Automatically handle different signature formats and curves across chains The complete source code for this implementation is available in our [GitHub repository](https://github.com/AdamikHQ/adamik-tutorial). ## Prerequisites To use Turnkey with Adamik API, you'll need: * A Turnkey account with API credentials (you can create one [here](https://app.turnkey.com/dashboard/auth/initial)) * A wallet created in the Turnkey interface (required to obtain your wallet ID) * Environment variables properly set up (see below) ### Environment Setup Depending on your project structure, you'll need to set up environment variables slightly differently: **For frontend projects (like [adamik-tutorial](https://github.com/AdamikHQ/adamik-tutorial/tree/signer-turnkey)):** ```env theme={null} # These variables need the VITE_ prefix for client-side access VITE_TURNKEY_BASE_URL="https://api.turnkey.com" VITE_TURNKEY_API_PUBLIC_KEY="your-api-public-key" VITE_TURNKEY_API_PRIVATE_KEY="your-api-private-key" VITE_TURNKEY_ORGANIZATION_ID="your-organization-id" VITE_TURNKEY_WALLET_ID="your-wallet-id" ``` **For backend/Node.js projects (like [adamik-link](https://github.com/AdamikHQ/adamik-link)):** ```env theme={null} # No VITE_ prefix needed for server-side code TURNKEY_BASE_URL="https://api.turnkey.com" TURNKEY_API_PUBLIC_KEY="your-api-public-key" TURNKEY_API_PRIVATE_KEY="your-api-private-key" TURNKEY_ORGANIZATION_ID="your-organization-id" TURNKEY_WALLET_ID="your-wallet-id" ``` ## Implementing the Turnkey Signer The core of the integration is the `TurnkeySigner` class, which implements the `BaseSigner` interface: ```typescript theme={null} // Based on src/signers/types.ts export interface BaseSigner { signerSpec: AdamikSignerSpec; signerName: string; chainId: string; getPubkey(): Promise; signTransaction(encodedMessage: string): Promise; } ``` Here's a complete implementation: ```typescript theme={null} import { Turnkey } from "@turnkey/sdk-server"; import { AdamikCurve, AdamikHashFunction, AdamikSignerSpec, } from "../adamik/types"; export class TurnkeySigner implements BaseSigner { private turnkeyClient: Turnkey; public chainId: string; public signerSpec: AdamikSignerSpec; public signerName = "TURNKEY"; private pubKey: string | undefined; constructor(chainId: string, signerSpec: AdamikSignerSpec) { this.chainId = chainId; this.signerSpec = signerSpec; // Access environment variables based on your project setup const baseUrl = process.env.TURNKEY_BASE_URL || import.meta.env?.VITE_TURNKEY_BASE_URL; const apiPublicKey = process.env.TURNKEY_API_PUBLIC_KEY || import.meta.env?.VITE_TURNKEY_API_PUBLIC_KEY; const apiPrivateKey = process.env.TURNKEY_API_PRIVATE_KEY || import.meta.env?.VITE_TURNKEY_API_PRIVATE_KEY; const organizationId = process.env.TURNKEY_ORGANIZATION_ID || import.meta.env?.VITE_TURNKEY_ORGANIZATION_ID; this.turnkeyClient = new Turnkey({ apiBaseUrl: baseUrl, apiPublicKey: apiPublicKey, apiPrivateKey: apiPrivateKey, defaultOrganizationId: organizationId, }); } private convertAdamikCurveToTurnkeyCurve( curve: AdamikCurve ): "CURVE_SECP256K1" | "CURVE_ED25519" { switch (curve) { case AdamikCurve.SECP256K1: return "CURVE_SECP256K1"; case AdamikCurve.ED25519: return "CURVE_ED25519"; default: throw new Error(`Unsupported curve: ${curve}`); } } private convertHashFunctionToTurnkeyHashFunction( hashFunction: AdamikHashFunction, curve: AdamikCurve ) { if (curve === AdamikCurve.ED25519) { return "HASH_FUNCTION_NOT_APPLICABLE"; } switch (hashFunction) { case AdamikHashFunction.SHA256: return "HASH_FUNCTION_SHA256"; case AdamikHashFunction.KECCAK256: return "HASH_FUNCTION_KECCAK256"; default: return "HASH_FUNCTION_NOT_APPLICABLE"; } } async getPubkey(): Promise { try { const walletId = process.env.TURNKEY_WALLET_ID || import.meta.env?.VITE_TURNKEY_WALLET_ID; const { accounts } = await this.turnkeyClient .apiClient() .getWalletAccounts({ walletId, paginationOptions: { limit: "100", }, }); const accountCompressed = accounts.find( (account) => account.curve === this.convertAdamikCurveToTurnkeyCurve(this.signerSpec.curve) && getCoinTypeFromDerivationPath(account.path) === Number(this.signerSpec.coinType) && account.addressFormat === "ADDRESS_FORMAT_COMPRESSED" ); if (accountCompressed) { this.pubKey = accountCompressed.address; return accountCompressed.address; } // Create account if not found try { const createAccount = await this.turnkeyClient .apiClient() .createWalletAccounts({ walletId, accounts: [ { curve: this.convertAdamikCurveToTurnkeyCurve( this.signerSpec.curve ), path: `m/44'/${this.signerSpec.coinType}'/0'/0/0`, pathFormat: "PATH_FORMAT_BIP32", addressFormat: "ADDRESS_FORMAT_COMPRESSED", }, ], }); this.pubKey = createAccount.addresses[0]; return createAccount.addresses[0]; } catch (error) { // Handle case where account creation fails but account exists if ( error.message?.includes( "wallet account corresponding to path already exists" ) ) { // Retry fetching accounts const { accounts } = await this.turnkeyClient .apiClient() .getWalletAccounts({ walletId, }); const existingAccount = accounts.find( (account) => account.curve === this.convertAdamikCurveToTurnkeyCurve(this.signerSpec.curve) && getCoinTypeFromDerivationPath(account.path) === Number(this.signerSpec.coinType) ); if (existingAccount) { this.pubKey = existingAccount.address; return existingAccount.address; } } throw error; } } catch (error) { console.error("Error in Turnkey getPubkey:", error); throw error; } } async signTransaction(encodedMessage: string): Promise { if (!this.pubKey) { this.pubKey = await this.getPubkey(); } try { const txSignResult = await this.turnkeyClient.apiClient().signRawPayload({ signWith: this.pubKey, payload: encodedMessage, encoding: "PAYLOAD_ENCODING_HEXADECIMAL", hashFunction: this.convertHashFunctionToTurnkeyHashFunction( this.signerSpec.hashFunction, this.signerSpec.curve ), }); return extractSignature(this.signerSpec.signatureFormat, txSignResult); } catch (error) { console.error("Error in Turnkey signTransaction:", error); throw error; } } } // Helper functions function getCoinTypeFromDerivationPath(path: string): number { const parts = path.split("/"); // Handle format like m/44'/60'/0'/0/0 for (let i = 0; i < parts.length; i++) { if (parts[i].includes("44'") && i + 1 < parts.length) { const nextPart = parts[i + 1]; return parseInt(nextPart.replace("'", "")); } } return 0; } function extractSignature(signatureFormat: string, signResult: any): string { // Implementation depends on your specific needs for different chains // This is a placeholder that should be replaced with actual implementation // based on signature format requirements for each blockchain return signResult.r + signResult.s + (signResult.v ? signResult.v : ""); } ``` ## Integration Workflow The typical workflow for using Turnkey with Adamik API follows these steps: 1. **Initialize the Signer**: ```typescript theme={null} const chain = await adamikGetChain(chainId); const signer = new TurnkeySigner(chainId, chain.signerSpec); ``` 2. **Generate/Retrieve Public Key**: ```typescript theme={null} const pubkey = await signer.getPubkey(); ``` 3. **Convert to Address** (using Adamik API): ```typescript theme={null} const { address } = await encodePubKeyToAddress(pubkey, chainId); ``` 4. **Prepare a Transaction** (using Adamik API): ```typescript theme={null} const { encodedTransaction } = await encodeTransaction(chainId, { senderAddress: address, recipientAddress: destinationAddress, amount: "0.001", // other parameters depending on chain }); ``` 5. **Sign Transaction**: ```typescript theme={null} const signature = await signer.signTransaction(encodedTransaction); ``` 6. **Broadcast Transaction** (using Adamik API): ```typescript theme={null} const result = await broadcastTransaction( chainId, encodedTransaction, signature ); ``` ## Key Features ### Automatic Account Creation The Turnkey signer automatically creates accounts with the correct derivation paths and address formats based on the blockchain requirements. If an account already exists, it retrieves it: ```typescript theme={null} // If account not found, create it if (!accountCompressed) { const createAccount = await this.turnkeyClient .apiClient() .createWalletAccounts({ walletId, accounts: [ { curve: this.convertAdamikCurveToTurnkeyCurve(this.signerSpec.curve), path: `m/44'/${this.signerSpec.coinType}'/0'/0/0`, pathFormat: "PATH_FORMAT_BIP32", addressFormat: "ADDRESS_FORMAT_COMPRESSED", }, ], }); this.pubKey = createAccount.addresses[0]; return createAccount.addresses[0]; } ``` ### Multi-Curve Support The signer handles different cryptographic curves required by various blockchains: ```typescript theme={null} private convertAdamikCurveToTurnkeyCurve( curve: AdamikCurve ): "CURVE_SECP256K1" | "CURVE_ED25519" { switch (curve) { case AdamikCurve.SECP256K1: return "CURVE_SECP256K1"; case AdamikCurve.ED25519: return "CURVE_ED25519"; default: throw new Error(`Unsupported curve: ${curve}`); } } ``` ### Error Handling The implementation includes proper error handling for common scenarios, including the case where an account exists but wasn't found in the initial lookup: ```typescript theme={null} try { // Create account code... } catch (error) { // If account creation fails but account exists if ( error.message?.includes( "wallet account corresponding to path already exists" ) ) { // Retry fetching accounts const { accounts } = await this.turnkeyClient .apiClient() .getWalletAccounts({ walletId, }); // Find existing account... } throw error; } ``` ## Troubleshooting Common Issues ### "Wallet account corresponding to path already exists" This error occurs when trying to create an account that already exists. The signer implementation handles this by: 1. Catching the error 2. Fetching the accounts again 3. Finding the existing account with the matching path ### Missing Environment Variables If you encounter errors related to missing environment variables, check: * For frontend projects: Ensure variables start with `VITE_` * For backend projects: No prefix needed * Verify all required variables are defined in your `.env` file * Restart your application after updating environment variables ### Authentication Issues If you experience authentication problems: 1. Verify your API keys are correct 2. Ensure your organization ID and wallet ID are properly set 3. Check that your Turnkey account has necessary permissions ## Security Considerations When implementing Turnkey with Adamik API, consider these security best practices: 1. **Environment Variables**: Never hardcode API credentials 2. **Error Handling**: Implement proper error handling for API responses 3. **Key Management**: Use appropriate key derivation paths for each blockchain 4. **Logging**: Implement comprehensive logging for audit purposes, but avoid logging sensitive information ## Testing the Integration To test this integration: 1. Clone the [GitHub repository](https://github.com/AdamikHQ/adamik-tutorial/tree/signer-turnkey) 2. Create a `.env.local` file based on the `.env.local.example` 3. Set up your Turnkey environment variables 4. Run the example code to test transactions on different chains ## Conclusion The integration of Turnkey with Adamik API provides a secure and scalable solution for multi-chain applications. By following this implementation guide, you can leverage Turnkey's institutional-grade security while maintaining the flexibility to operate across multiple blockchains through a single interface. For more details, explore the full source code in our [GitHub repository](https://github.com/AdamikHQ/adamik-tutorial/tree/signer-turnkey), particularly the `src/signers/Turnkey.ts` file for the implementation details. # How to Craft a Bitcoin Transaction with Adamik Source: https://docs.adamik.io/guides/tutorials/Bitcoin-Transaction-Crafting This guide provides step-by-step instructions for leveraging the Adamik API to construct Bitcoin transactions. Bitcoin utilizes the UTXO (Unspent Transaction Output) model, where multiple UTXOs may need to be aggregated to satisfy the desired transaction amount. In the example below, we use a single address as the sender, which contains multiple UTXOs. For scenarios involving wallets with multiple addresses, the Adamik API also supports extended public keys (xpub). This feature enables seamless handling of UTXOs across various addresses within the same wallet, offering enhanced flexibility for more complex transaction workflows. Please note the following addresses are used for the example purpose only. ### Step 1: Prepare Your Request To initiate the transaction, use the `/api/transaction/encode` endpoint with the following payload: ```json theme={null} { "transaction": { "data": { "chainId": "bitcoin", "mode": "transfer", "senderAddress": "bc1qekphvuz20qvdhkzywfe29r9vvtwxrszvaxzmqm", "recipientAddress": "bc1q2e00eecxtjlvuzf6dpm4leqjd2pem0xkfggw8j", "amount": "90000" } } } ``` ### Step 2: Response The API will respond with a hex-encoded PSBT (Partially Signed Bitcoin Transaction). Example: ```plaintext theme={null} 70736274ff0100710200000001df3efc2277171e2181372f26be8b49d1bb98f0c7e5d617aac53e7e4bdac086cf0100000000fdffffff02905f010000000000160014565efce7065cbece093a68775fe4126a839dbcd69f19000000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c000000000001011ff37a010000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c000000 ``` ### Step 3: Analyze the PSBT The PSBT contains details about the inputs and outputs used in the transaction. #### Inputs: ```json theme={null} { "vin": [ { "txid": "cf86c0da4b7e3ec5aa17d6e5c7f098bbd1498bbe262f3781211e177722fc3edf", "vout": 1, "scriptSig": { "asm": "", "hex": "" }, "sequence": 4294967293 } ] } ``` #### Outputs: ```json theme={null} { "vout": [ { "value": 0.0009, "n": 0, "scriptPubKey": { "asm": "0 565efce7065cbece093a68775fe4126a839dbcd6", "desc": "addr(bc1q2e00eecxtjlvuzf6dpm4leqjd2pem0xkfggw8j)#c5pa6kvw", "hex": "0014565efce7065cbece093a68775fe4126a839dbcd6", "address": "bc1q2e00eecxtjlvuzf6dpm4leqjd2pem0xkfggw8j", "type": "witness_v0_keyhash" } }, { "value": 6.559e-5, "n": 1, "scriptPubKey": { "asm": "0 cd8376704a7818dbd8447272a28cac62dc61c04c", "desc": "addr(bc1qekphvuz20qvdhkzywfe29r9vvtwxrszvaxzmqm)#yxdkvw7j", "hex": "0014cd8376704a7818dbd8447272a28cac62dc61c04c", "address": "bc1qekphvuz20qvdhkzywfe29r9vvtwxrszvaxzmqm", "type": "witness_v0_keyhash" } } ] } ``` ### Step 4: Signing the Transaction The PSBT provided by Adamik API must be signed with a compatible Bitcoin signer. Example of a signed transaction (hex-encoded): ```plaintext theme={null} 70736274ff01009a020000000221f8c3f9a2e6db8c5273e67031d846ca77a9154c382521e541436bbaa67e601d0100000000fdffffff84beb7db39234cd25d33e0c664e6d4566c34b35c06f470ec9368adf0412e9a740000000000fdffffff02107a070000000000160014cd8376704a7818dbd8447272a28cac62dc61c04cbb07000000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c000000000001011fff7d040000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c01086b0247304402205f706f0eb2c89be45308cfd558dc1ee9694ba5f85f9ecb7b9dc8d36fffa284b30220182893f9479927ffa6100adfd648c145fc4be9a07523bbc6fd9c9c42889ae549012103d14c088f9a2f63f02173be720c7ced7f0cc254d7dea3d5bb4cef1d8ccc6103080001011f1a0b030000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c01086c02483045022100e04d73abc886ecee4e0a7318cd730de745421c184ad89aeca5ea33d9cba471130220760e892cd78f190d18ae6d18d4e9f65865a0f1a6652229324f2c631d6a7afd63012103d14c088f9a2f63f02173be720c7ced7f0cc254d7dea3d5bb4cef1d8ccc610308000000 ``` Please note that the signed transaction is the same as the PSBT, but with the signature added. Different signers may use different formats, so please refer to the documentation of the signer you are using. ### Step 5: Finalize and Broadcast After signing, submit the transaction using the `/api/transaction/broadcast` endpoint. * Submit the original transaction intent. * Input the hex-encoded PSBT. * Add the signed BTC transaction in the signature field of the broadcast endpoint Example of a broadcast request: ```json theme={null} { "transaction": { "data": { "chainId": "bitcoin", "mode": "transfer", "senderAddress": "bc1qekphvuz20qvdhkzywfe29r9vvtwxrszvaxzmqm", "recipientAddress": "bc1q2e00eecxtjlvuzf6dpm4leqjd2pem0xkfggw8j", "amount": "90000" }, "encoded": "70736274ff01009a020000000221f8c3f9a2e6db8c5273e67031d846ca77a9154c382521e541436bbaa67e601d0100000000fdffffff84beb7db39234cd25d33e0c664e6d4566c34b35c06f470ec9368adf0412e9a740000000000fdffffff02107a070000000000160014cd8376704a7818dbd8447272a28cac62dc61c04cbb07000000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c000000000001011fff7d040000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c01086b0247304402205f706f0eb2c89be45308cfd558dc1ee9694ba5f85f9ecb7b9dc8d36fffa284b30220182893f9479927ffa6100adfd648c145fc4be9a07523bbc6fd9c9c42889ae549012103d14c088f9a2f63f02173be720c7ced7f0cc254d7dea3d5bb4cef1d8ccc6103080001011f1a0b030000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c01086c02483045022100e04d73abc886ecee4e0a7318cd730de745421c184ad89aeca5ea33d9cba471130220760e892cd78f190d18ae6d18d4e9f65865a0f1a6652229324f2c631d6a7afd63012103d14c088f9a2f63f02173be720c7ced7f0cc254d7dea3d5bb4cef1d8ccc610308000000", "signature": "70736274ff01009a020000000221f8c3f9a2e6db8c5273e67031d846ca77a9154c382521e541436bbaa67e601d0100000000fdffffff84beb7db39234cd25d33e0c664e6d4566c34b35c06f470ec9368adf0412e9a740000000000fdffffff02107a070000000000160014cd8376704a7818dbd8447272a28cac62dc61c04cbb07000000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c000000000001011fff7d040000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c01086b0247304402205f706f0eb2c89be45308cfd558dc1ee9694ba5f85f9ecb7b9dc8d36fffa284b30220182893f9479927ffa6100adfd648c145fc4be9a07523bbc6fd9c9c42889ae549012103d14c088f9a2f63f02173be720c7ced7f0cc254d7dea3d5bb4cef1d8ccc6103080001011f1a0b030000000000160014cd8376704a7818dbd8447272a28cac62dc61c04c01086c02483045022100e04d73abc886ecee4e0a7318cd730de745421c184ad89aeca5ea33d9cba471130220760e892cd78f190d18ae6d18d4e9f65865a0f1a6652229324f2c631d6a7afd63012103d14c088f9a2f63f02173be720c7ced7f0cc254d7dea3d5bb4cef1d8ccc610308000000" } } ``` Example of a broadcast response: ```json theme={null} { "hash": "019eec21c164a4181d9a57854ff16b39d2331ded50b749683d057778f618b891", "transaction": { "data": { "chainId": "bitcoin", "senderAddress": "bc1qekphvuz20qvdhkzywfe29r9vvtwxrszvaxzmqm", "recipientAddress": "bc1q2e00eecxtjlvuzf6dpm4leqjd2pem0xkfggw8j", "useMaxAmount": false, "mode": "transfer", "amount": "90000" } }, "status": { "errors": [], "warnings": [] } } ``` ### Summary * **Transaction Intent**: Specify sender, recipient, and amount. * **PSBT Generation**: The Adamik API will generate the PSBT and automatically select the UTXOs for the transaction, as well as calculate the fees. * **Sign the PSBT**: Employ a compatible signer. * **Broadcast**: Submit the signed transaction back to the Adamik API, which will broadcast the transaction to the Bitcoin network. In case of any issues, please connect with us through our [Discord Server](https://discord.gg/gsZJR2JfMR) or directly through [GitHub](https://github.com/AdamikHQ). # How to Enable Tokens (Trustlines) on Stellar with Adamik Source: https://docs.adamik.io/guides/tutorials/Stellar-Token-Enabling This guide provides step-by-step instructions for enabling tokens on Stellar using the Adamik API. On the Stellar network, before you can receive or hold custom assets (tokens), you must establish a trustline to the asset's issuer. This process is called "enabling a token" or "creating a trustline." Stellar requires users to explicitly opt-in to hold custom assets as a security measure. This prevents unwanted tokens from being sent to your account without your permission. ## Understanding Stellar Assets On Stellar, all assets except the native XLM are identified by: * **Asset Code**: A 1-12 character alphanumeric code (e.g., "USDC", "EURC") * **Issuer Address**: The Stellar account that created and issued the asset Together, these form a unique identifier for each asset on the network. ## Prerequisites Before enabling a token, ensure you have: 1. A funded Stellar account (minimum 1 XLM for base reserve) 2. Your account's secret key for signing transactions 3. The asset code and issuer address of the token you want to enable 4. An Adamik API key from [dashboard.adamik.io](https://dashboard.adamik.io) Each trustline requires 0.5 XLM to be locked as a base reserve. This XLM becomes available again if you remove the trustline. ## Step-by-Step Tutorial ### Step 1: Prepare Your Request To enable a token, use the `/api/stellar-testnet/transaction/encode` endpoint with the `enable_token` mode: ```json theme={null} { "transaction": { "data": { "chainId": "stellar-testnet", "mode": "enable_token", "tokenId": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "senderAddress": "GCZ2GEDRGWOB42FGJM3UVW2PQPOTKAUD5TFYUIVTJZR3ROCBJATPGB4R", "format": "json" } } } ``` The `tokenId` field follows the format: `ASSET_CODE:ISSUER_ADDRESS` ### Step 2: API Response The API returns an encoded transaction ready for signing: ```json theme={null} { "chainId": "stellar-testnet", "transaction": { "data": { "mode": "enable_token", "senderAddress": "GCZ2GEDRGWOB42FGJM3UVW2PQPOTKAUD5TFYUIVTJZR3ROCBJATPGB4R", "tokenId": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "fees": "100" }, "encoded": [ { "raw": { "format": "XDR", "value": "cee0302d59844d32bdca915c8203dd44b33fbb7edc19051ea37abedf28ecd472..." }, "hash": { "format": "sha256", "value": "a1b2c3d4e5f6..." } } ] } } ``` ### Step 3: Sign the Transaction For Stellar, you must sign the transaction **hash** (not the raw transaction): ```javascript theme={null} const { Keypair } = require("@stellar/stellar-sdk"); // Your wallet's secret key const secretKey = "SBFZCHU5645DOKRWYBXVOXY2ELGJKFRX6VGGPRYUWHQ7PMXXJNDZFMKD"; const keypair = Keypair.fromSecret(secretKey); // Extract and sign the hash const hashToSign = encodedData.transaction.encoded[0].hash.value; const hashBuffer = Buffer.from(hashToSign, 'hex'); const signature = keypair.sign(hashBuffer); const signatureHex = signature.toString('hex'); ``` ### Step 4: Broadcast the Signed Transaction Send the signed transaction back to Adamik for broadcasting: ```json theme={null} { "transaction": { "data": { "mode": "enable_token", "senderAddress": "GCZ2GEDRGWOB42FGJM3UVW2PQPOTKAUD5TFYUIVTJZR3ROCBJATPGB4R", "tokenId": "USDC:GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5", "fees": "100" }, "encoded": [...], "signature": "5a3e0ec98d7475332f09900cd6f2ef6e266fdb4f95b2800ee9c0244a6dba70cf..." } } ``` Use the `/api/stellar-testnet/transaction/broadcast` endpoint to broadcast. ### Step 5: Verify the Transaction Upon successful broadcast, you'll receive a transaction hash: ```json theme={null} { "hash": "7f8e9d0c1b2a3..." } ``` You can view the transaction on Stellar Expert: ``` https://stellar.expert/explorer/testnet/tx/{hash} ``` ## Complete Code Example Here's a complete Node.js example for enabling a token on Stellar testnet: ```javascript theme={null} const { Keypair } = require("@stellar/stellar-sdk"); async function enableStellarToken() { // Configuration const ADAMIK_API_KEY = "your-adamik-api-key"; const secretKey = "your-stellar-secret-key"; const assetCode = "USDC"; const issuerAddress = "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5"; // Create keypair const keypair = Keypair.fromSecret(secretKey); const senderAddress = keypair.publicKey(); // Step 1: Encode the enable_token transaction const encodeResponse = await fetch( "https://api.adamik.io/api/stellar-testnet/transaction/encode", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ transaction: { data: { chainId: "stellar-testnet", mode: "enable_token", tokenId: `${assetCode}:${issuerAddress}`, senderAddress: senderAddress, format: "json", }, }, }), } ); const encodedData = await encodeResponse.json(); if (!encodeResponse.ok) { console.error("Failed to encode:", encodedData); return; } console.log("Trustline transaction encoded successfully"); // Step 2: Sign the transaction hash const hashToSign = encodedData.transaction.encoded[0].hash.value; const hashBuffer = Buffer.from(hashToSign, 'hex'); const signature = keypair.sign(hashBuffer); const signatureHex = signature.toString('hex'); // Step 3: Broadcast the signed transaction const broadcastResponse = await fetch( "https://api.adamik.io/api/stellar-testnet/transaction/broadcast", { method: "POST", headers: { Authorization: ADAMIK_API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ transaction: { data: encodedData.transaction.data, encoded: encodedData.transaction.encoded, signature: signatureHex, }, }), } ); const result = await broadcastResponse.json(); if (broadcastResponse.ok && result.hash) { console.log(`✅ Token enabled successfully!`); console.log(`Transaction hash: ${result.hash}`); console.log(`View on explorer: https://stellar.expert/explorer/testnet/tx/${result.hash}`); } else { console.error("Broadcast failed:", result); } } enableStellarToken().catch(console.error); ``` ## Common Testnet Tokens Here are some commonly used tokens on Stellar testnet for testing: | Asset Code | Issuer | Description | | ---------- | -------------------------------------------------------- | ----------------------- | | USDC | GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5 | USD Coin Test | | SRT | GCDNJUBQSX7AJWLJACMJ7I4BC3Z47BQUTMHEICZLE6MU4KQBRYG5JY6B | Stellar Reference Token | | EURC | GB3Q6QDZYTHWT7E5PVS3W7FUT5GVAFC5KSZFFLPU25GO7VTC3NM2ZTVO | Euro Coin Test | ## Troubleshooting ### Common Errors and Solutions | Error | Cause | Solution | | -------------------------- | ----------------------------- | ------------------------------------------------------------------------ | | "Balance is too low" | Insufficient XLM for reserves | Ensure account has at least 1.5 XLM (1 XLM base + 0.5 XLM per trustline) | | "Asset issuer not found" | Invalid issuer address | Verify the issuer address is correct and active | | "Trustline already exists" | Token already enabled | The token is already enabled for your account | | "Invalid asset code" | Malformed asset code | Asset codes must be 1-12 alphanumeric characters | ### Important Considerations 1. **Reserve Requirements**: Each trustline locks 0.5 XLM as a base reserve 2. **Trust Limits**: You can optionally set a maximum amount you're willing to hold of an asset 3. **Asset Freezing**: Some issuers can freeze assets - research issuers before trusting 4. **Removing Trustlines**: You can only remove a trustline if your balance of that asset is zero ## Next Steps After enabling a token, you can: * Receive the token from other accounts * Trade the token on Stellar DEX * Send the token to other accounts that have also enabled it * Set up path payments using the token For more information on Stellar assets and trustlines, visit the [Stellar documentation](https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-data-structures/assets). ## Get Support Need help? Connect with us: * [Discord Server](https://discord.gg/gsZJR2JfMR) * [GitHub Issues](https://github.com/AdamikHQ) * [Adamik Dashboard](https://dashboard.adamik.io) # Babylon BTC Staking using the Adamik API Source: https://docs.adamik.io/guides/tutorials/babylon-with-adamik Babylon allows Bitcoin holders to participate in staking, earning rewards while maintaining their BTC holdings. This guide walks through the process of staking Bitcoin using the Adamik API, including transaction creation, signing, and broadcasting. ## I - Stake Bitcoins ### Notes * The duration of a Bitcoin staking position is 64000 blocks (\~444 days). It will naturally end after this period. However the Babylon protocol also allows to manually end the staking position in advance (see part III - [Unstake Bitcoins](/guides/tutorials/babylon-with-adamik#iii-unstake-bitcoins)). * Babylon offers two registration methods: **pre-stake** and post-stake. This guide implements the more user-friendly **pre-stake registration** flow. Refer to [Babylon's documentation](https://github.com/babylonlabs-io/babylon/blob/main/docs/register-bitcoin-stake.md#2-bitcoin-stake-registration-methods) for details. * The examples are targeting Bitcoin Signet and Babylon Testnet networks. To target the mainnets, simply replace `"bitcoin-signet"` with `"bitcoin"` and `"babylon-testnet"` with `"babylon"` in API calls. * The example data shown is for demonstration purposes. While encoded payloads are valid for signing, they may not match the provided examples exactly. ### Overview Babylon API Pre-Stake Registration Flow ### 1. Collect Required Information #### Retrieve Bitcoin Validators First, fetch the list of available Bitcoin "finality providers" (validators): ```http Request theme={null} GET /api/bitcoin-signet/validators ``` ```json Response theme={null} { "chainId": "bitcoin-signet", "validators": [ { "address": "d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76", "name": "Babylon Foundation 0", "commission": 0.1, "stakedAmount": "18881117815" }, { "address": "e4889630fa8695dae630c41cd9b85ef165ccc2dc5e5935d5a24393a9defee9ef", "name": "Babylon Foundation 1", "commission": 0.07, "stakedAmount": "11305179705" }, ... ] } ``` #### User Inputs You'll need to collect: * Chosen validator * Staking amount * Bitcoin address and Bitcoin public key (**NOT** the xpub) ### 2. Create Bitcoin Staking Transaction Generate the Bitcoin transaction payloads to sign, using transaction mode `stake`: ```json Request theme={null} POST /api/bitcoin-signet/transaction/encode { "transaction": { "data": { "mode": "stake", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "targetValidatorAddress": "ee9da95e9fecbb2191943c56a109d1dc81787a77994ad9ef89278850a58e4876", "amount": "1000" } } } ``` ```json Response theme={null} { "chainId": "bitcoin-signet", "transaction": { "data": { "mode": "stake", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "targetValidatorAddress": "ee9da95e9fecbb2191943c56a109d1dc81787a77994ad9ef89278850a58e4876", "amount": "1000", "fees": "1896", "params": { "stakingPsbt": "70736274ff010089020000000144a549ead63ac9c6987b90669208ece5e93f28de4b1f97b5e4036c995f47b3d50100000000ffffffff0250c3000000000000225120a80fe5278c52cab2e0a0c9702713f61fe8f2f248346a6d7dcc1245338c14ec1609dd06000000000022512074aa0a4aeefc052d0e63edda5a5f9cd4a9a6b245fad33ea29408c130e2916041000000000001012b31a507000000000022512074aa0a4aeefc052d0e63edda5a5f9cd4a9a6b245fad33ea29408c130e2916041011720bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c000000", "slashingPsbt": "70736274ff01007d02000000017b3897f29ddb41a6c5f304ac8a078b6575fb6d0584a50f8bb9c8f8f046b1bf520000000000ffffffff02c4090000000000001600145be12624d08a2b424095d7c07221c33450d14bf104a60000000000002251208d50aed5bc9d2e62d65e27af2bc7a424ac1906dd2dc7a29b3d88b8c7bd5026e0000000000001012b50c3000000000000225120a80fe5278c52cab2e0a0c9702713f61fe8f2f248346a6d7dcc1245338c14ec164215c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0089a5f44e98c08db22bb0f07e05678d015b479990161599e05c331363c9c67fefd790120bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499cad20d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76ad200aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25ac20113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0ba2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ba203bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899cba2040afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092dfba2079a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0ba20d21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36ba20f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8eba20fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737ba569cc001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0000000", "unbondingSlashingPsbt": "70736274ff01007d02000000017b7b276f516e307c2684b9b52ee7ef476bc1f52170b02fa1df0dda39b60d51a50000000000ffffffff0260090000000000001600145be12624d08a2b424095d7c07221c33450d14bf1989e0000000000002251208d50aed5bc9d2e62d65e27af2bc7a424ac1906dd2dc7a29b3d88b8c7bd5026e0000000000001012b80bb000000000000225120925f6e5d2f54928dbbf7c7b989e2d0e8b6023baece6b7ae6efed0c4f548919994215c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac08418260aca037f78aa845243f0e2e4c201f3360266f71c130a21535e670351f9fd790120bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499cad20d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76ad200aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25ac20113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0ba2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ba203bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899cba2040afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092dfba2079a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0ba20d21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36ba20f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8eba20fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737ba569cc001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0000000", "unbondingTransaction": "70736274ff01005e020000000173379dc78521b8e15c4dd5a0cf547d9f22e520a068de93101220c9ae6b34177f0000000000ffffffff0180bb0000000000002251207d1d0a7c9548850f5b2a9f33b4ab156c71ac395546559ced78224850a844ab2f000000000001012b50c30000000000002251205cd5dc2f87756eaab10fbd8a248fdb52e8df067d2c4e555786e1710ada78e3416215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac049e7cd04d69e4ace167fbea710b5ca53bfd0a36278f15223c7b309ebf8668a4a3c56a81fd2fcade9658a84b61afce956d368491ecedcfa5e8fa40b4b7fb20944fd570120bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499cad200aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25ac20113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0ba2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ba203bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899cba2040afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092dfba2079a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0ba20d21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36ba20f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8eba20fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737ba539cc001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00000" } }, // (staking psbt, duplicated for convenience and consistency) "encoded": "70736274ff010089020000000144a549ead63ac9c6987b90669208ece5e93f28de4b1f97b5e4036c995f47b3d50100000000ffffffff0250c3000000000000225120a80fe5278c52cab2e0a0c9702713f61fe8f2f248346a6d7dcc1245338c14ec1609dd06000000000022512074aa0a4aeefc052d0e63edda5a5f9cd4a9a6b245fad33ea29408c130e2916041000000000001012b31a507000000000022512074aa0a4aeefc052d0e63edda5a5f9cd4a9a6b245fad33ea29408c130e2916041011720bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c000000" }, "status": { "errors": [], "warnings": [] } } ``` ### 3. Sign Bitcoin Transactions Sign the following payloads with a compatible Bitcoin signer: * **Staking PSBT**: The main transaction for staking * **Slashing PSBT**: Required for the slashing mechanism * **Unbonding Slashing PSBT**: For slashing during unbonding * **Babylon Address**: Sign with Bitcoin signer: `[ECDSA or BIP322](hex(bech32Address))` > ℹ️ The unbonding PSBT does not need to be signed at this stage, but must be included in the registration transaction, see below. ### 4. Register with Babylon Blockchain Create the Babylon **registration** transaction: ```json Request theme={null} POST /api/babylon/transaction/encode { "transaction": { "data": { "mode": "registerStake", // User's Babylon address "senderAddress": "xxxxxxxxxxxxxxxxxx", // User's Babylon public key "senderPubKey": "xxxxxxxxxxxxxxxxxx", // User's Bitcoin public key in hexadecimal format "senderForeignPubKey": "xxxxxxxxxxxxxxxxxx", // User's Babylon address, signed with Bitcoin signer (hex) "proofOfPossession": "xxxxxxxxxxxxxxxxxx", "amount": "1234", // Bitcoin finality provider's public key (hex) "validatorPubKey": "xxxxxxxxxxxxxxxxxx", // The unbonding PSBT, exactly as provided in the response of the Bitcoin encode "unsignedUnbondingTransaction": "xxxxxxxxxxxxxxxxxx", // Staking transaction, signed from the provided PSBT (hex) "signedStakingTransaction": "xxxxxxxxxxxxxxxxxx", // Slashing transaction, signed from the provided PSBT (hex) "signedSlashingTransaction": "xxxxxxxxxxxxxxxxxx", // Unbonding slashing transaction, signed from the provided PSBT (hex) "signedUnbondingSlashingTransaction": "xxxxxxxxxxxxxxxxxx" } } } ``` ```json Response theme={null} { "chainId": "babylon", "transaction": { "data": { "mode": "registerStake", "senderAddress": "xxxxxxxxxxxxxxxxxx", "senderPubKey": "xxxxxxxxxxxxxxxxxx", "senderForeignPubKey": "xxxxxxxxxxxxxxxxxx", "proofOfPossession": "xxxxxxxxxxxxxxxxxx", "amount": "1234", "validatorPubKey": "xxxxxxxxxxxxxxxxxx", "unsignedUnbondingTransaction": "xxxxxxxxxxxxxxxxxx", "signedStakingTransaction": "xxxxxxxxxxxxxxxxxx", "signedSlashingTransaction": "xxxxxxxxxxxxxxxxxx", "signedUnbondingSlashingTransaction": "xxxxxxxxxxxxxxxxxx", "fees": "12432", "gas": "1775858" }, "encoded": "0a330a310a2d2f626162796c6f6e2e6274637374616b696e672e76312e4d736743726561746542544344656c65676174696f6e120012650a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103833d5aebe72ca68e3816c4a466d395280929f07ccf5e75dc4e2d71c2c92da45812040a020801180712110a0b0a047562626e120337303010a08d061a0a62626e2d746573742d3520eac404" }, "status": { "errors": [], "warnings": [] } } ``` > ℹ️ The returned encoded transaction is in Cosmos' protobuf format, serialized as hex. ### 5. Sign Babylon Transaction Sign the encoded Babylon transaction using a Babylon-compatible wallet. ### 6. Broadcast Babylon Registration Transaction ```json Request theme={null} POST /api/babylon/transaction/broadcast { "transaction": { "data": { "mode": "registerStake", "senderAddress": "xxxxxxxxxxxxxxxxxx", "senderPubKey": "xxxxxxxxxxxxxxxxxx", "senderForeignPubKey": "xxxxxxxxxxxxxxxxxx", "proofOfPossession": "xxxxxxxxxxxxxxxxxx", "amount": "1234", "validatorPubKey": "xxxxxxxxxxxxxxxxxx", "unsignedUnbondingTransaction": "xxxxxxxxxxxxxxxxxx", "signedStakingTransaction": "xxxxxxxxxxxxxxxxxx", "signedSlashingTransaction": "xxxxxxxxxxxxxxxxxx", "signedUnbondingSlashingTransaction": "xxxxxxxxxxxxxxxxxx", "fees": "12432", "gas": "1775858" }, "encoded": "0a330a310a2d2f626162796c6f6e2e6274637374616b696e672e76312e4d736743726561746542544344656c65676174696f6e120012650a500a460a1f2f636f736d6f732e63727970746f2e736563703235366b312e5075624b657912230a2103833d5aebe72ca68e3816c4a466d395280929f07ccf5e75dc4e2d71c2c92da45812040a020801180712110a0b0a047562626e120337303010a08d061a0a62626e2d746573742d3520eac404", "signature": "xxxxxxxxxxxxxxxxxx" } } ``` ```json Response theme={null} { "chainId": "babylon", "hash": "E66FD5957527263056AB39308DA9D5AAB984AF25D38067248156339C7DDE9899" } ``` ### 7. Wait for Confirmation Monitor the transaction status until it's confirmed: ```http GET Request theme={null} GET /api/babylon/transaction/{hash} ``` ```json Response theme={null} { "transaction": { "parsed": { "id": "C5D2C6EF1092369AD9F7D8302C5F2AADDED7CC9EB43BF445D0E33D3C6A957FA3", "mode": "unknown", "state": "confirmed", "blockHeight": "288089", "timestamp": "1739465632000", "fees": { "amount": "12397", "ticker": "ubbn" }, "gas": "1770929" } }, "status": { "errors": [], "warnings": [] } } ``` > ⚠️ **Important**: Wait for `transaction.parsed.state` to be `confirmed` before proceeding to the next step. ### 8. Broadcast Bitcoin Staking Transaction Once the Babylon registration is confirmed, broadcast the signed Bitcoin staking transaction: ```json Request theme={null} POST /api/bitcoin-signet/transaction/broadcast { "transaction": { "data": { "mode": "stake", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "targetValidatorAddress": "ee9da95e9fecbb2191943c56a109d1dc81787a77994ad9ef89278850a58e4876", "amount": "1000", "fees": "1896" }, "encoded": "70736274ff010089020000000144a549ead63ac9c6987b90669208ece5e93f28de4b1f97b5e4036c995f47b3d50100000000ffffffff0250c3000000000000225120a80fe5278c52cab2e0a0c9702713f61fe8f2f248346a6d7dcc1245338c14ec1609dd06000000000022512074aa0a4aeefc052d0e63edda5a5f9cd4a9a6b245fad33ea29408c130e2916041000000000001012b31a507000000000022512074aa0a4aeefc052d0e63edda5a5f9cd4a9a6b245fad33ea29408c130e2916041011720bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c000000", "signature": "xxxxxxxxxxxxxxxxxx" } } ``` ```json Response theme={null} { "chainId": "bitcoin-signet", "hash": "5a2d155884d3021f5c9a9437d6b9411003a8c7fdc6d94d47c9e9723d82a9353a" } ``` ## II - Manage Staking Positions ### View Bitcoin Staking Positions Retrieve all staking positions for a Bitcoin public key: ```http GET Request theme={null} GET /api/bitcoin-signet/account/state/{address}?pubkey={publicKey} ``` ```json Response theme={null} { "chainId": "bitcoin-signet", "accountId": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "balances": { "native": { "available": "466250", "unconfirmed": "0", "total": "466250" }, "staking": { "total": "80000", "locked": "50000", "unlocking": "20000", "unlocked": "10000", "positions": [ { "stakeId": "e6dd797fe3ced5a30f1d89c911f593f099bf9e018d3968498ba12cc8b2ea8532", "validatorAddresses": [ "143a1961c97682d59b5f48d5b469ac74ac45273245947865e3c4ad575e4fa646" ], "amount": "50000", "status": "pending" }, { "stakeId": "52bfb146f0f8c8b98b0fa584056dfb75658b078aac04f3c5a641db9df297387b", "validatorAddresses": [ "d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76" ], "amount": "50000", "status": "locked", "completionDate": "1745382554000" }, { "stakeId": "d5b3475f996c03e4b5971f4bde283fe9e5ec089266907b98c6c93ad6ea49a544", "validatorAddresses": [ "d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76" ], "amount": "20000", "status": "unlocking", "completionDate": "1738746956000" }, { "stakeId": "943b38b6e1d6ffe0194f93dbfbe36499d1eaa625867aae17a59aff2825d42109", "validatorAddresses": [ "143a1961c97682d59b5f48d5b469ac74ac45273245947865e3c4ad575e4fa646" ], "amount": "10000", "status": "unlocked" } ], // Rewards unsupported yet, will come at a later step "rewards": { "native": [], "tokens": [] } } } } ``` > ℹ️ The stakeId is the hash of the Bitcoin staking transaction ## III - Unstake Bitcoins The Babylon protocol allows to end an active Bitcoin staking position in advance, i.e before the end of the default staking period of 64000 blocks. This is done by sending a dedicated bitcoin transaction, that is a request for unbonding, after which there is an unbonding period of 7 days. When the unbonding duration is complete, users must then send a withdrawal transaction to retrieve their bitcoins and make them spendable again (see part IV - [Withdraw Bitcoins](/guides/tutorials/babylon-with-adamik#iv-withdraw-bitcoins)). ### 1. Create Bitcoin Transaction Generate the Bitcoin transaction payload to sign, using transaction mode `unstake`: ```json Request theme={null} POST /api/bitcoin-signet/transaction/encode { "transaction": { "data": { "mode": "unstake", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "validatorAddress": "d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76", "stakeId": "52bfb146f0f8c8b98b0fa584056dfb75658b078aac04f3c5a641db9df297387b" } } } ``` ```json Response theme={null} { "chainId": "bitcoin-signet", "transaction": { "data": { "mode": "unstake", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "validatorAddress": "d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76", "stakeId": "52bfb146f0f8c8b98b0fa584056dfb75658b078aac04f3c5a641db9df297387b", "useMaxAmount": false, "recipientAddress": "", "fees": "2000" }, "encoded": "70736274ff01005e02000000017b3897f29ddb41a6c5f304ac8a078b6575fb6d0584a50f8bb9c8f8f046b1bf520000000000ffffffff0180bb000000000000225120925f6e5d2f54928dbbf7c7b989e2d0e8b6023baece6b7ae6efed0c4f54891999000000000001012b50c3000000000000225120a80fe5278c52cab2e0a0c9702713f61fe8f2f248346a6d7dcc1245338c14ec166215c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac08b47c4bf56db05be7cc5f84b03d14987e05392d76b88d6875136d66d34db31d697cb47898d4200f9dbfb360a7dc2402178e9acd31f8c1167ae9afec71b8c34b4fd570120bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499cad200aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25ac20113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0ba2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ba203bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899cba2040afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092dfba2079a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0ba20d21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36ba20f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8eba20fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737ba569cc001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00000" }, "status": { "errors": [], "warnings": [] } } ``` ### 2. Sign Bitcoin Transaction Sign the `encoded` payload with a compatible Bitcoin signer. ### 3. Broadcast Bitcoin Transaction Broadcast the signed Bitcoin staking transaction: ```json Request theme={null} POST /api/bitcoin-signet/transaction/broadcast { "transaction": { "data": { "mode": "unstake", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "validatorAddress": "d23c2c25e1fcf8fd1c21b9a402c19e2e309e531e45e92fb1e9805b6056b0cc76", "stakeId": "52bfb146f0f8c8b98b0fa584056dfb75658b078aac04f3c5a641db9df297387b", "useMaxAmount": false, "recipientAddress": "", "fees": "2000" }, "encoded": "70736274ff01005e02000000017b3897f29ddb41a6c5f304ac8a078b6575fb6d0584a50f8bb9c8f8f046b1bf520000000000ffffffff0180bb000000000000225120925f6e5d2f54928dbbf7c7b989e2d0e8b6023baece6b7ae6efed0c4f54891999000000000001012b50c3000000000000225120a80fe5278c52cab2e0a0c9702713f61fe8f2f248346a6d7dcc1245338c14ec166215c050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac08b47c4bf56db05be7cc5f84b03d14987e05392d76b88d6875136d66d34db31d697cb47898d4200f9dbfb360a7dc2402178e9acd31f8c1167ae9afec71b8c34b4fd570120bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499cad200aee0509b16db71c999238a4827db945526859b13c95487ab46725357c9a9f25ac20113c3a32a9d320b72190a04a020a0db3976ef36972673258e9a38a364f3dc3b0ba2017921cf156ccb4e73d428f996ed11b245313e37e27c978ac4d2cc21eca4672e4ba203bb93dfc8b61887d771f3630e9a63e97cbafcfcc78556a474df83a31a0ef899cba2040afaf47c4ffa56de86410d8e47baa2bb6f04b604f4ea24323737ddc3fe092dfba2079a71ffd71c503ef2e2f91bccfc8fcda7946f4653cef0d9f3dde20795ef3b9f0ba20d21faf78c6751a0d38e6bd8028b907ff07e9a869a43fc837d6b3f8dff6119a36ba20f5199efae3f28bb82476163a7e458c7ad445d9bffb0682d10d3bdb2cb41f8e8eba20fa9d882d45f4060bdb8042183828cd87544f1ea997380e586cab77d5fd698737ba569cc001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00000" } } ``` ```json Response theme={null} { "chainId": "bitcoin-signet", "hash": "ab9df0f871b9b6e4302b77b0d940434aa30b89b3d7f55255918aec98fafb7f85" } ``` ## IV - Withdraw Bitcoins After a staking position has ended, users have to send a withdrawal transaction before being able to spend their bitcoins again. This transaction is mandatory whether the position has ended naturally after the default staking duration or after the manual unbonding period has eneded. ### 1. Create Bitcoin Transaction Generate the Bitcoin transaction payload to sign, using transaction mode `withdraw`: ```json Request theme={null} POST /api/bitcoin-signet/transaction/encode { "transaction": { "data": { "mode": "withdraw", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "recipientAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "validatorAddress": "d66124f8f42fd83e4c901a100ae3b5d706ef6cfd217b04bc64152e739a30c41e", "stakeId": "943b38b6e1d6ffe0194f93dbfbe36499d1eaa625867aae17a59aff2825d42109" } } } ``` ```json Response theme={null} { "chainId": "bitcoin-signet", "transaction": { "data": { "mode": "withdraw", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "validatorAddress": "d66124f8f42fd83e4c901a100ae3b5d706ef6cfd217b04bc64152e739a30c41e", "stakeId": "943b38b6e1d6ffe0194f93dbfbe36499d1eaa625867aae17a59aff2825d42109", "recipientAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "fees": "159" }, "encoded": "70736274ff01005e0200000001fd2f56d383b71a98d0f86780aa591f1eca05c44e581d47e1e3838b05df259a3b0000000000f003000001e1ba00000000000022512074aa0a4aeefc052d0e63edda5a5f9cd4a9a6b245fad33ea29408c130e2916041000000000001012b80bb0000000000002251206f5554b3505cbccc88c8e86541dbac87e53f962c18b953780ccde2e4d5969d3c4215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac099c5eb18cdfad5d84d849d1aa9e883c313b19b2a89726b534534dd064587eb512720bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499cad02f003b2c001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00000" }, "status": { "errors": [], "warnings": [] } } ``` ### 2. Sign Bitcoin Transaction Sign the `encoded` payload with a compatible Bitcoin signer. ### 3. Broadcast Bitcoin Transaction Broadcast the signed Bitcoin staking transaction: ```json Request theme={null} POST /api/bitcoin-signet/transaction/broadcast { "transaction": { "data": { "mode": "withdraw", "senderPubKey": "02bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499c", "validatorAddress": "d66124f8f42fd83e4c901a100ae3b5d706ef6cfd217b04bc64152e739a30c41e", "stakeId": "943b38b6e1d6ffe0194f93dbfbe36499d1eaa625867aae17a59aff2825d42109", "recipientAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "senderAddress": "tb1pwj4q5jhwlszj6rnrahd95huu6j56dvj9ltfnag55prqnpc53vpqsxh76tx", "fees": "159" }, "encoded": "70736274ff01005e0200000001fd2f56d383b71a98d0f86780aa591f1eca05c44e581d47e1e3838b05df259a3b0000000000f003000001e1ba00000000000022512074aa0a4aeefc052d0e63edda5a5f9cd4a9a6b245fad33ea29408c130e2916041000000000001012b80bb0000000000002251206f5554b3505cbccc88c8e86541dbac87e53f962c18b953780ccde2e4d5969d3c4215c150929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac099c5eb18cdfad5d84d849d1aa9e883c313b19b2a89726b534534dd064587eb512720bd2eb288281a9e7a15ec81b8b593f243b96fbcd2b16a1a509c1b87df95fc499cad02f003b2c001172050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac00000" } } ``` ```json Response theme={null} { "chainId": "bitcoin-signet", "hash": "34b7f4ff29240eabaca4bc981205335306f51a0afc697cab4b5ad2586e480dfd" } ``` ## V. Claim Rewards on secured chains The reward claiming process for Babylon staking will be documented soon.