Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Dag4.js Javascript API
The dag4.js typescript library provides secure wallet functionality in javascript and convenient wrappers for interacting with Constellation Network APIs. The library is platform agnostic and can be used to build apps in browsers, NodeJS, or React Native.
View Dag4.js on Github
You can find the dag4 repo and additional documentation on Github.
npm install @stardust-collective/dag4
yarn add @stardust-collective/dag4
const { dag4 } = require('@stardust-collective/dag4');
import { dag4 } from '@stardust-collective/dag4';
In order to make the most of Constellation Network APIs, a brief understanding of the architecture of the network is useful. The Hypergraph consists of multiple layers of networks of individual responsibility through which transactions flow. Each of the major network layers has REST API endpoints available with distinct functionality. Transactions are sent to the outermost layer, labeled as L1 networks in the graphic, before being processed into a state snapshot in an L0 layer.
DAG transactions are sent to the DAG L1 network which bundles the transactions into blocks and sends them to the Global L0 for inclusion into global snapshots. Snapshots are then indexed by the Block Explorer via a snapshot streaming service that processes them.
Metagraph token transactions flow in a similar way from the metagraph currency L1 where they're received, bundled into blocks, and then passed to the currency L0 layer to be included in metagraph snapshots. The metagraph snapshots are then submitted to the Global L0 to be included in global snapshots and eventually indexed into the Block Explorer via the snapshot streaming service.
The APIs for each of the L1 and L0 layers is nearly identical with a few minor differences, namely endpoint naming of /dag
for DAG endpoints and /currency
for currency endpoints. You can explore the API specs for each in the sections below.
In summary, the functionalities of the different APIs for DAG and metagraph tokens are as follows:
DAG transactions are sent to this API via the /transactions
POST endpoint.
Pending transactions can be queried through this API via the /transactions/:hash
endpoint.
The address lastRef
for an address can be queried here as well.
Query global snaphots
Query DAG supply and address balances
Submit metagraph (state channel) snapshots
DAG transactions are sent to this API via the /transactions
POST endpoint.
Pending transactions can be queried through this API via the /transactions/:hash
endpoint.
The address lastRef
for an address can be queried here as well.
Query metagraph snapshots
Query metagraph token supply and address balances
Submit metagraph (state channel) snapshots
A wallet consists of a private key, a public key, and an address. You can create a new private key like this.
Before accessing methods on dag4.account specific to a wallet, you'll need to log in with a private key or seed phrase.
If you already have a pneumonic phrase generated by a web wallet or somewhere else you can log in with that as well.
The dag4.js typescript library provides secure wallet functionality in javascript and convenient wrappers for interacting with Constellation Network APIs. The library is platform agnostic and can be used to build apps in browsers, NodeJS, or React Native.
View Dag4.js on Github
You can find the dag4 repo and additional documentation on .
NPM
or Yarn
Node
ES6
npm install @stardust-collective/dag4
yarn add @stardust-collective/dag4
const { dag4 } = require('@stardust-collective/dag4');
import { dag4 } from '@stardust-collective/dag4';
const pk = dag4.keyStore.generatePrivateKey();
dag4.account.loginPrivateKey(pk);
dag4.account.loginSeedPhrase('disco foxtrot calm appleseed trinity organ putter waldorf ordinary shatter green portion');
const address = dag4.account.address;
dag4.account.publicKey;
Constellation provides developers with a full featured IntegrationNet to test applications and metagraphs before they're ready for the production environment. The IntegrationNet has all of the same features as MainNet and can therefore be used to validate application integrations in a realistic way.
Developing a Metagraph Metagraph developers may use IntegrationNet as they're nearing production readiness. See .
The following urls can used to access IntegrationNet:
Block Explorer API: https://be-integrationnet.constellationnetwork.io
Global L0 API: https://l0-lb-integrationnet.constellationnetwork.io
Constellation hosts a IntegrationNet faucet which distributes IntegrationNet DAG for testing purposes. This coin has no value and can only be used on IntegrationNet. The faucet provides small amounts of DAG at each request with rate limiting to prevent depletion of its DAG reserves.
The faucet can be accessed at:
GET https://faucet.constellationnetwork.io/integrationnet/faucet/<YOUR WALLET ADDRESS>
const { dag4 } = require('@stardust-collective/dag4');
dag4.account.connect({
networkVersion: '2.0',
testnet: true
});
dag4.account.loginPrivateKey('MY-PRIVATE-KEY');
const toAddress = 'DAGabc123...';
const amount = 25.551;
const fee = 0;
await dag4.account.transferDag(toAddress, amount, fee);
// Get last ref online, or else fetch from an offline data store
const lastRef = await dag4.network.getAddressLastAcceptedTransactionRef('DAGWalletSendingAddress');
// Get signed transaction (offline)
const txn = await dag4.account.generateSignedTransaction('DAGabc123...', 25.551, 0, lastRef);
// Send transaction (online)
await dag4.network.postTransaction(txn);
// Get last ref online, or else fetch from an offline data store
let lastRef = await dag4.network.getAddressLastAcceptedTransactionRef('DAGWalletSendingAddress');
// Generate txns offline
const txn_data = [
{to: 'DAGabc123...', amount: 10, fee: 0},
{to: 'DAGxyz987...', amount: 25.01, fee: 0},
{to: 'DAGzzz555...', amount: 1.01, fee: 0},
{to: 'DAGwww988...', amount: 0.00000001, fee: 0},
];
const hashes = await dag4.account.transferDagBatch(txn_data, lastRef);
// console.log(hashes)
Choosing a Transaction Fee
Transactions without a fee are processed at a maximum of one transaction per global snapshot, or roughly 1 transaction every 5 seconds. In practice this means that almost all transactions do not require a fee unless you need to send a large number of transactions in a short period of time. To send more transactions per snapshot, include a small fee of 0.00000001 DAG with each transaction. Up to 100 transactions per snapshot will be processed if a fee is included.
When a transaction is sent to the network and is accepted, the response will return a hash that can be used to monitor the status of the transaction.
The transaction will initially be in a "waiting" state before it's included in a block and sent to a snapshot. While in this state you can check its status with the L1 API. Once processed by the network, the transaction will no longer be found via the L1 API and will be found in the block explorer API. At this point the transaction is considered final.
The following process can be used to confirm a transaction has been processed and reached a successful final state.
// Send transaction
const hash = await dag4.network.postTransaction(txn);
// Keep checking the transaction status until this returns null
const pendingTx = await dag4.network.getPendingTransaction(txHash);
// Check the block explore API
if (pendingTx === null) {
const confirmedTx = await dag4.network.getTransaction(txHash);
if (confirmedTx) {
// Txn is confirmed - from this point the state cannot be changed
console.log('Transaction confirmed');
} else {
// The txn cannot be found on block explorer. It's a good idea to wait several seconds and try again to confirm the txn has actually been dropped
console.log('Transaction dropped - not confirmed');
}
}
Metagraph APIs are hosted on any metagraph that adheres to the Metagraph Token Standard or implements a custom data endpoint. The APIs described here are very similar to the Hypergraph APIs described in the previous section. The metagraph APIs consist of the Currency L0 API, Currency L1 API, and the Data L1 API. These APIs are hosted on individual metagraphs which may have their own rate limits or specific configurations required.
The Currency L0 API can be used to fetch metagraph snapshot chain information, view token supply and address balances, and submit metagraph snapshots.
You can connect directly to a network node by IP address and port, or by an endpoint provided to you by the metagraph network.
API Spec
The Currency L1 API is used primarily for sending metagraph token transactions which are then processed through the Global L0, Currency L0, and Global L0.
You can connect directly to a network node by IP address and port, or by an endpoint provided to you by the metagraph network.
API Spec
Base urls
Base urls or ip addresses will be provided by the metagraph network you wish to connect to.
The Global L0 API can be used to fetch global snapshot information, view DAG supply and address balances, and submit metagraph (state channel) snapshots.
You can connect directly to a network node by IP address and port, or by an endpoint provided to you by the metagraph network.
API Spec
Base urls
Base urls or ip addresses will be provided by the metagraph network you wish to connect to.
An off-network API offering indexed and searchable transactions, snapshots, and block information.
API Spec
Base urls:
IntegrationNet: https://be-integrationnet.constellationnetwork.io
See dag4.js used in production open source codebases.
Want to see your open source project featured here? Submit your project for consideration.
Dag4.js provides reasonable configuration values by default for accessing Constellation Network versions 1.0 and 2.0.
You can provide custom values for each the three network API endpoints to set up a custom connection.
The following endpoints are used by default by Dag4.
IntegrationNet
Block Explorer API:
L0 API:
L1 API:
MainNet
Block Explorer API:
L0 API:
L1 API:
TestNet usage is not recommended as it is expected to be unstable. Use IntegrationNet as the preferred testnet.
TestNet
Block Explorer API:
L0 API:
L1 API:
Metagraph tokens work in much the same way as DAG. They share a common transaction format and API interface. Both DAG and metagraph tokens use DAG addresses for their balance maps so a single public/private keypair can control DAG and metagraph token accounts.
Minimum Version
You will need version 2.1.1 or higher in order to interact with metagraph token networks.
In order to interact with a metagraph token you will need to first need to create a connection to the Hypergraph, then create a metagraph client instance to connect to the metagraph and send transactions.
The example below connects to IntegrationNet. Fill in :metagraph-l0-endpoint
, :metagraph-currency-l1-endpoint
, and :metagraph-id
in the code below with the correct details for the metagraph you are connecting to.
A list of existing metagraphs can be found on the . On each metagraph's page you'll find the Metagraph ID, as well as L0 and currency L1 endpoints, which are necessary for configuring your metagraph client to connect to a specific metagraph network.
The metagraph client has all the same methods as dag4.account
except transferDag
becomes transfer
and transferDagBatch
becomes transferBatch
.
Transaction Fees
Note that transaction fees on metagraph networks are paid in the network's metagraph token, not in DAG.
The Hypergraph APIs are the public HTTP APIs hosted on Global L0 and the DAG L1 network nodes. Below you'll find an OpenAPI spec for each of the public network environments. In general, TestNet has the bleeding edge features, IntegrationNet has stable new features, and MainNet has fully released features.
The DAG L1 API is used primarily for sending DAG transactions which are then processed through the Global L0 and are eventually visible on the Block Explorer API after reaching finality.
You can use one of the load balancer endpoints below or connect directly to a network node by IP address and port. You can use the load balancer /cluster/info endpoint to find an active network node to connect to. Connect to the node using http and the configured port, ex:
API Spec
Base urls:
TestNet:
IntegrationNet:
MainNet:
The Global L0 API can be used to fetch global snapshot information, view DAG supply and address balances, and submit metagraph snapshots.
You can use one of the load balancer endpoints below or connect directly to a network node by IP address and port. You can use the load balancer /cluster/info endpoint to find a network node. Connect using http and the configured port, ex: .
API Spec
Base urls:
TestNet:
IntegrationNet:
MainNet:
dag4.account.connect({
networkVersion: '2.0',
testnet: true
});
dag4.account.connect({
networkVersion: '2.0',
beUrl: 'https://be-mainnet.constellationnetwork.io/',
l0Url: 'http://13.52.246.74:9000',
l1Url: 'http://13.52.246.74:9010'
});
dag4.account.connect({
id: 'integration2',
networkVersion: '2.0',
beUrl: 'https://be-integrationnet.constellationnetwork.io',
l0Url: 'https://l0-lb-integrationnet.constellationnetwork.io',
l1Url: 'https://l1-lb-integrationnet.constellationnetwork.io'
}, false);
dag4.account.connect({
networkVersion: '2.0',
testnet: false
});
dag4.account.connect({
networkVersion: '2.0',
testnet: true
});
const { dag4 } = require('@stardust-collective/dag4');
// Connect to Hypergraph on IntegrationNet or MainNet
dag4.account.connect({
networkVersion: '2.0',
beUrl: "https://be-integrationnet.constellationnetwork.io",
l0Url: "https://l0-lb-integrationnet.constellationnetwork.io",
l1Url: "https://l1-lb-integrationnet.constellationnetwork.io",
});
dag4.account.loginPrivateKey('MY-PRIVATE-KEY');
// Create a metagraphClient instance to connect to a specific metagraph
const metagraphClient = dag4.account.createMetagraphTokenClient({
beUrl: "https://be-integrationnet.constellationnetwork.io",
l0Url: ':metagraph-l0-endpoint',
l1Url: ':metagraph-currency-l1-endpoint',
metagraphId: ':metagraph-id'
});
// Make calls directly to the metagraph (check balance, send transactions, etc.)
await metagraphClient.getBalance();
// 100000
// connect as shown above
const toAddress = 'DAGabc123...';
const amount = 25.551;
const fee = 0;
await metagraphClient.transfer(toAddress, amount, fee);
// Get last ref online, or else fetch from an offline data store
let lastRef = await metagraphClient.getAddressLastAcceptedTransactionRef('DAGWalletSendingAddress');
// Generate txns offline
const txn_data = [
{to: 'DAGabc123...', amount: 10, fee: 0},
{to: 'DAGxyz987...', amount: 25.01, fee: 0},
{to: 'DAGzzz555...', amount: 1.01, fee: 0},
{to: 'DAGwww988...', amount: 0.00000001, fee: 0},
];
const hashes = await metagraphClient.transferBatch(txn_data, lastRef);
// console.log(hashes)
Stargazer Wallet
Stargazer Wallet is a cross-chain wallet supporting Constellation Network and Ethereum ecosystems. It is available as a Chrome extension and as a mobile app for iOS and Android.
Telegram Tip Bot
The Telegram Tip Bot is a small cloud application integrated with Telegram that allows users to send DAG to each other with TG commands. Because transactions on the Hypergraph are free, all tip transactions are able to be processed on-chain.
Metagraph Examples Constellation maintains a repo with metagraph implementation examples, including several that demonstrate usage of dag4.js in combination with a metagraph codebase.
This document describes how to manually sign transactions on the Constellation Network. Understanding the transaction signing process is crucial for developers implementing custom signing solutions in various programming languages or integrating with the Constellation Network.
Constellation Network supports two distinct methods for transaction signing:
DAG/L0 Token Transactions: Uses Kryo serialization without compression
Other Transaction Types: Uses Brotli compression for serialization (TokenLock, AllowSpend, DelegatedStake, etc.)
In the long term, DAG and L0 token transactions will likely be migrated to use the same brotli compression as the newer transaction types but for now, the Kryo serialization method is maintained for backwards compatibility.
All transactions in the Constellation Network, regardless of type, are submitted to the network using a standard format:
{
"value": {
// Transaction body containing all transaction details
},
"proofs": [
{
"id": "<signer public key>",
"signature": "<signature of transaction body>"
}
]
}
Key components of this format:
value: Contains the transaction body with all relevant transaction details
proofs: An array of signatures that validate the transaction
Currently, all transactions require exactly one proof in the array
The array structure supports future multi-signature functionality
Each proof contains:
id: The public key of the signer
signature: The signature of the transaction body, created using the corresponding private key
The different transaction signing methods described in this document ultimately produce transaction data in this standard format, though the specific contents of the value
field and the method of generating the signature in the proofs
array will differ based on the transaction type.
To sign transactions, you need:
A private key
A public key
Transaction details to be signed
Understanding of cryptographic operations: SHA-256, SHA-512, and secp256k1 ECDSA signing
DAG or L0 token transactions follow this signing process:
For token transactions, the following fields are required:
source
: Sender address
destination
: Recipient address
amount
: Transaction amount (in smallest unit, e.g., 1 DAG = 100,000,000 units)
fee
: Transaction fee (in smallest unit)
parent
: Last transaction reference (hash and ordinal)
salt
: Random value to ensure unique transaction hashes
Create a transaction object with the required fields
Format the transaction according to the network's expected structure (v2 format)
Encode the transaction into a specific format that concatenates fields with their lengths
The encoded transaction is serialized using Kryo serialization, which follows these steps:
Create a prefix using the format: 03
(fixed) + UTF-8 encoded length
Convert the encoded transaction to UTF-8 bytes
Convert the UTF-8 bytes to hexadecimal format
Concatenate the prefix with the hexadecimal transaction
Example pseudo-code for Kryo serialization:
function kryoSerialize(encodedTransaction):
prefix = "03" + utf8EncodedLength(encodedTransaction.length + 1)
hexTransaction = hexEncode(utf8Encode(encodedTransaction))
return prefix + hexTransaction
The UTF-8 encoded length is variable-length encoded with specific bit patterns:
Bit 8 denotes UTF-8
Bit 7 denotes if another byte is present
Compute the SHA-256 hash of the Kryo-serialized transaction bytes:
transactionHash = sha256(Buffer.from(serializedTransaction, 'hex'))
Sign the hash using ECDSA with the secp256k1 curve and the private key:
Compute SHA-512 hash of the transaction hash
Sign the SHA-512 hash with the private key using secp256k1 ECDSA
Format the signature according to the expected format (often DER encoded and converted to hexadecimal)
sha512Hash = sha512(transactionHash)
signature = secp256k1Sign(sha512Hash, privateKey)
hexSignature = signature.toHex()
To verify the signature:
Use the public key to verify the signature against the same SHA-512 hash
Ensure the signature verification passes
isValid = secp256k1Verify(signature, sha512Hash, publicKey)
For other transaction types, the signing process uses Brotli compression:
Before serialization, normalize the transaction object:
Sort object keys alphabetically
Remove null/undefined values
Convert the object to a consistent format
normalizedBody = normalizeObject(transactionBody)
Serialize the normalized transaction using Brotli compression:
Convert the normalized JSON to a string
Encode the string as UTF-8 bytes
Compress the bytes using Brotli compression (typically with compression level 2)
normalizedJson = JSON.stringify(normalizedBody)
utf8Bytes = utf8Encode(normalizedJson)
compressedData = brotliCompress(utf8Bytes, compressionLevel=2)
Compute the SHA-256 hash of the Brotli-compressed data:
messageHash = sha256(compressedData)
Sign the hash with the private key:
Compute SHA-512 hash of the message hash
Sign the SHA-512 hash with the private key using secp256k1 ECDSA
Format the signature according to the expected format
sha512Hash = sha512(messageHash)
signature = secp256k1Sign(sha512Hash, privateKey)
hexSignature = signature.toHex()
The final result should be structured as:
{
"value": normalizedBody,
"proofs": [
{
"id": publicKey,
"signature": hexSignature
}
]
}
Private keys should be in hexadecimal format without the "0x" prefix
Public keys for verification can be in compressed or uncompressed format
When using uncompressed public keys, they may need the "04" prefix
Transaction amounts and fees should be represented in the smallest unit (datum)
Example: 1 DAG = 100,000,000 datum (8 decimal places)
Amounts should be integers after being multiplied by 10^8
SHA-256 and SHA-512 implementations should follow the standard specifications
Input to hash functions should be byte arrays, not hexadecimal strings
Use secp256k1 curve for ECDSA signing
Sign the SHA-512 hash of the message, not the message directly
DER encoding is commonly used for the signature format
This feature is currently available on IntegrationNet only.
This guide walks you through integrating with Constellation Network’s Delegated Staking system, including how to create, update, and withdraw delegated stakes for users that want to automate this process through the network APIs.
Delegated staking allows users to lock their tokens on the network and delegate them to a node operator, receiving a share of the validator’s rewards in return. The process relies on TokenLocks and is managed via the Global L0 (gL0) and DAG L1 (dagL1) APIs.
Manual staking using Stargazer Wallet is supported through the DAG Explorer website.
For node operators looking for information on how to participate in Delegated Staking and how to attract delegators to their nodes, see .
Before getting started, familiarize yourself with the following endpoints. Note that you'll be interacting with API endpoints on both the DAG L1 and Global L0 APIs.
/token-locks
POST
Submit a TokenLock.
/token-locks/:address/last-reference
GET
Get the latest transaction reference for use in a TokenLock.
/delegated-stakes/:address/info
GET
Fetch current delegated stake positions for an address.
/delegated-stakes
POST
Create or update a delegated stake position.
/delegated-stakes
PUT
Withdraw a delegated stake position.
/node-params
GET
Fetch node metadata including node IDs and reward settings.
All POST
and PUT
requests below follow the brotli compressed signing scheme described in Transaction Signing. If using a library like dag4.js to generate and send requests to the network, serialization and signing will be handled for you automatically. If sending requests directly to the REST APIs without using a library, you will need to generate the signatures manually.
To create a delegated stake, follow these steps:
Use the following API call to list the nodes currently accepting delegated stakes:
curl -X GET "{GL0_API}/node-params" -H "Content-Type: application/json"
Each node record includes:
nodeId
: used to delegate
name
: name provided by the operator
description
: description provided by the operator
rewardFraction
: the validator's share of rewards
You’ll use the nodeId
from this list when creating your stake.
Before creating a TokenLock, you need the last reference for your wallet address:
curl -X GET "{DAGL1_API}/token-locks/{address}/last-reference" -H "Content-Type: application/json"
This step can be skipped w/dag4.js. The parent reference will be fetched automatically when creating the TokenLock.
This value will be used as the parentReference
in your new TokenLock transaction.
Submit a TokenLock to lock your tokens:
curl -X POST "{DAGL1_API}/token-locks" -H "Content-Type: application/json" -d '{
"value": {
"source": "DAG4xPWQj3BpAg2YKg3kbdW2AJcMfZz2SUKqYb1t",
"amount": 100000000,
"fee": 0,
"parent": {YOUR_PARENT_REFERENCE},
"currencyId": null,
"unlockEpoch": null
},
"proofs":[{
"id": "c7f9a08bdea7ff5f51c8af16e223a1d751bac9c541125d9aef5658e9b7597aee8cba374119ebe83fb9edd8c0b4654af273f2d052e2d7dd5c6160b6d6c284a17c",
"signature": "3045022017607e6f32295b0ba73b372e31780bd373322b6342c3d234b77bea46adc78dde022100e6ffe2bca011f4850b7c76d549f6768b88d0f4c09745c6567bbbe45983a28bf1"
}]
}'
import { dag4 } from '@stardust-collective/dag4'
dag4.account.loginSeedPhrase(YOUR_SEED_PHRASE)
dag4.account.connect({
networkVersion: '2.0',
l0Url: {GL0_API},
l1Url: {DAGL1_API}
})
await dag4.account.postTokenLock({
source: dag4.account.address,
amount: 500000000000,
fee: 0,
tokenL1Url: {DAGL1_API},
unlockEpoch: null,
currencyId: null,
})
source
: set to the address of the wallet sending the request
amount
: number of tokens to lock (in smallest unit, i.e., datum)
fee
: set to zero
currencyId
: set to null
unlockEpoch
: set to null
— this ensures only the network can unlock the tokens upon withdrawal
parent
: from previous step
Now fetch your DelegatedStake's last reference:
curl -X GET "{GL0_API}/delegated-stakes/{address}/info" -H "Content-Type: application/json"
This step can be skipped w/dag4.js. The parent reference will be fetched automatically when creating the DelegatedStake.
Use the returned value as parent
when submitting the new stake.
Now that you have your tokenLockRef
and parent reference, submit the stake:
curl -X POST "{GL0_API}/delegated-stakes" -H "Content-Type: application/json" -d '{
"value": {
"source": "{SENDER_ADDRESS}",
"nodeId": "{NODE_ID}",
"amount": 100000000,
"fee": 0,
"tokenLockRef": {TOKEN_LOCK_REF},
"parent": {PARENT_REFERENCE}
},
"proofs":[{
"id": "c7f9a08bdea7ff5f51c8af16e223a1d751bac9c541125d9aef5658e9b7597aee8cba374119ebe83fb9edd8c0b4654af273f2d052e2d7dd5c6160b6d6c284a17c",
"signature": "3045022017607e6f32295b0ba73b372e31780bd373322b6342c3d234b77bea46adc78dde022100e6ffe2bca011f4850b7c76d549f6768b88d0f4c09745c6567bbbe45983a28bf1"
}]
}'
import { dag4 } from '@stardust-collective/dag4'
dag4.account.loginSeedPhrase(YOUR_SEED_PHRASE)
dag4.account.connect({
networkVersion: '2.0',
l0Url: {GL0_API},
l1Url: {DAGL1_API}
})
await dag4.account.postDelegatedStake({
source: dag4.account.address,
nodeId: "{NODE_ID}",
amount: 500000000000,
fee: 0,
tokenLockRef: "{TOKEN_LOCK_REF}"
})
Request body includes:
nodeId
: from /node-params
amount
: must exactly match the amount of the TokenLock referenced
fee
: should be zero
tokenLockRef
: from TokenLock response
parent
: from /delegated-stakes/:address/info
If successful, a hash
of the DelegatedStake record will be returned.
Use:
curl -X GET "{GL0_API}/delegated-stakes/{address}/info" -H "Content-Type: application/json"
Check that your stake is listed in the activeDelegatedStakes
array, and that rewardsAmount
is increasing.
Delegated stakes can be redirected to a new node without withdrawal or penalty.
Re-run:
curl -X GET "{GL0_API}/node-params" -H "Content-Type: application/json"
Choose a new node ID to delegate to.
Use the same tokenLockRef
and stake amount, but change the nodeId
.
curl -X POST "{GL0_API}/delegated-stakes" -H "Content-Type: application/json" -d '{
"value": {
"source": "{SENDER_ADDRESS}",
"nodeId": "{NEW_NODE_ID}",
"amount": 100000000,
"fee": 0,
"tokenLockRef": {TOKEN_LOCK_REF},
"parent": {PARENT_REFERENCE}
},
"proofs":[{
"id": "c7f9a08bdea7ff5f51c8af16e223a1d751bac9c541125d9aef5658e9b7597aee8cba374119ebe83fb9edd8c0b4654af273f2d052e2d7dd5c6160b6d6c284a17c",
"signature": "3045022017607e6f32295b0ba73b372e31780bd373322b6342c3d234b77bea46adc78dde022100e6ffe2bca011f4850b7c76d549f6768b88d0f4c09745c6567bbbe45983a28bf1"
}]
}'
import { dag4 } from '@stardust-collective/dag4'
dag4.account.loginSeedPhrase(YOUR_SEED_PHRASE)
dag4.account.connect({
networkVersion: '2.0',
l0Url: {GL0_API},
l1Url: {DAGL1_API}
})
await dag4.account.postDelegatedStake({
source: dag4.account.address,
nodeId: "{NEW_NODE_ID}",
amount: 500000000000,
fee: 0,
tokenLockRef: "{TOKEN_LOCK_REF}"
})
This will update the position to the new node without incurring a withdrawal penalty. All fields other than nodeId
must remain the same as the original request.
Use:
curl -X GET "{GL0_API}/delegated-stakes/{address}/info" -H "Content-Type: application/json"
Ensure the nodeId
has updated and rewardAmount
continues to increase.
To withdraw a delegated stake (unlock your tokens and receive rewards), follow this process:
curl -X PUT "{GL0_API}/delegated-stakes" -H "Content-Type: application/json" -d '{
"source": "{SENDER_ADDRESS}",
"stakeRef": "{DELEGATED_STAKE_REFERENCE}"
}'
dag4.account.loginSeedPhrase(YOUR_SEED_PHRASE)
dag4.account.connect({
networkVersion: '2.0',
l0Url: {GL0_API},
l1Url: {DAGL1_API}
})
await dag4.account.putWithdrawDelegatedStake({
source: dag4.account.address,
stakeRef: "{DELEGATED_STAKE_REFERENCE}"
})
You’ll need:
Reference to the original DelegatedStake position
This will start the 21-day unbonding period.
After submitting, verify the stake has moved to pendingWithdrawals
:
curl -X GET "{GL0_API}/delegated-stakes/{address}/info" -H "Content-Type: application/json"
During this time:
The position no longer accrues rewards
Tokens remain locked
After ~21 days (estimated in network epochProgress
), check your wallet:
TokenLock should be removed
Rewards should be distributed in a reward transaction
The dag4-keystore package can be used to sign messages using a private key. Messages are signed using secp256k1 which generates a deterministic and canonical ECDSA signature that can be verified with a public key. This example code is not intended to be used to sign transactions.
const privKey = dag4.keyStore.generatePrivateKey();
const pubKey = dag4.keyStore.getPublicKeyFromPrivate(privateKey);
const signature = await dag4.keyStore.sign(privKey, message);
const verified = dag4.keyStore.verify(pubKey, message, signature);
if (verified) {
console.log('Signature verified');
} else {
console.log('Signature invalid');
}