Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6993ef0dc8 | |||
| 0e53562ce2 | |||
| c1acef9bc8 | |||
| d67a968e76 | |||
| 8ad641f8f8 | |||
| b45bb9e7e9 | |||
| cab072f2d0 | |||
| c389f43dd0 | |||
| 71c24d8c81 | |||
| e336e02df2 | |||
| 74db9be819 | |||
| 77c4acf602 | |||
| f4d0ac855c | |||
| eb1c7d649e | |||
| 75f34ef51b | |||
| 4f7fa557d5 | |||
| a96fb098c2 | |||
| ad5c6ab829 | |||
| b3d07e8832 | |||
| e761255174 | |||
| e4a20f9cf5 | |||
| 1eefe8a579 | |||
| e9dc848950 | |||
| 81162fba7e | |||
| be36da68b1 | |||
| 21a56e307f | |||
| bd966383be | |||
| 7626785ce4 | |||
| 6f79d39d48 | |||
| 014b5f767a | |||
| e0966565e6 | |||
| c6aec663b7 | |||
| 7d041ddd44 | |||
| 5d8bdc6570 | |||
| 06c412b3ba | |||
| 356cf00106 | |||
| 58493a69aa | |||
| e881da834b | |||
| eee9d8ab0c | |||
| 09026307f4 | |||
| 507ddf246c | |||
| 8d8ce29113 | |||
| 3be9e06bef | |||
| 770078a9ed | |||
| fcffebfe45 | |||
| 9c7d79683b | |||
| c7f34d04c0 | |||
| 9a62581272 | |||
| ebb8e4ef19 | |||
| a0057eb223 | |||
| 39195d79f5 | |||
| ede5ffaffc | |||
| ed16505137 | |||
| 03bec90b83 | |||
| add57b2c14 |
+1
-11
@@ -14,7 +14,6 @@
|
||||
# contracts
|
||||
/contracts/mixnet @durch @jstuczyn
|
||||
/contracts/vesting @durch @jstuczyn
|
||||
/contracts/service-provider-directory @octol
|
||||
|
||||
# crypto code
|
||||
/common/crypto/ @jstuczyn
|
||||
@@ -22,14 +21,5 @@
|
||||
/common/dkg/ @jstuczyn
|
||||
/common/nymsphinx/ @jstuczyn
|
||||
|
||||
# rust sdk
|
||||
/sdk/rust/ @octol
|
||||
|
||||
# nym-connect (rust)
|
||||
/nym-connect/desktop/src-tauri/ @octol
|
||||
|
||||
# nym-wallet (rust)
|
||||
/nym-wallet/src-tauri/ @octol
|
||||
|
||||
# documentation
|
||||
/documentation @mfahampshire
|
||||
/documentation @mfahampshire
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
name: Build and upload Nym APU container to harbor.nymte.ch
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
WORKING_DIRECTORY: "."
|
||||
CONTAINER_NAME: "nym-api"
|
||||
|
||||
jobs:
|
||||
build-container:
|
||||
runs-on: arc-ubuntu-22.04-dind
|
||||
steps:
|
||||
- name: Login to Harbor
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: harbor.nymte.ch
|
||||
username: ${{ secrets.HARBOR_ROBOT_USERNAME }}
|
||||
password: ${{ secrets.HARBOR_ROBOT_SECRET }}
|
||||
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Configure git identity
|
||||
run: |
|
||||
git config --global user.email "lawrence@nymtech.net"
|
||||
git config --global user.name "Lawrence Stalder"
|
||||
|
||||
- name: Get version from cargo.toml
|
||||
uses: mikefarah/yq@v4.45.4
|
||||
id: get_version
|
||||
with:
|
||||
cmd: yq -oy '.package.version' ${{ env.WORKING_DIRECTORY }}/nym-api/Cargo.toml
|
||||
|
||||
- name: Remove existing tag if exists
|
||||
run: |
|
||||
echo "Checking if tag ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }} exists..."
|
||||
if git rev-parse ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }} >/dev/null 2>&1; then
|
||||
echo "Tag ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }} already exists"
|
||||
git push --delete origin ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }}
|
||||
git tag -d ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }}
|
||||
fi
|
||||
|
||||
- name: Create tag
|
||||
run: |
|
||||
git tag -a ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }} -m "Version ${{ steps.get_version.outputs.result }}"
|
||||
git push origin ${{ env.CONTAINER_NAME }}-${{ steps.get_version.outputs.result }}
|
||||
|
||||
- name: BuildAndPushImageOnHarbor
|
||||
run: |
|
||||
docker build -f nym-api.dockerfile ${{ env.WORKING_DIRECTORY }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:${{ steps.get_version.outputs.result }} -t harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }}:latest
|
||||
docker push harbor.nymte.ch/nym/${{ env.CONTAINER_NAME }} --all-tags
|
||||
@@ -62,3 +62,4 @@ nym-api/redocly/formatted-openapi.json
|
||||
|
||||
**/settings.sql
|
||||
**/enter_db.sh
|
||||
CLAUDE.md
|
||||
Generated
+795
-798
File diff suppressed because it is too large
Load Diff
@@ -36,6 +36,9 @@ pub trait GatewayTransceiver: GatewaySender + GatewayReceiver {
|
||||
&mut self,
|
||||
message: ClientRequest,
|
||||
) -> Result<(), GatewayClientError>;
|
||||
|
||||
/// Check if the websocket connection to the gateway is alive
|
||||
fn is_connection_alive(&self) -> bool;
|
||||
}
|
||||
|
||||
/// This trait defines the functionality of sending `MixPacket` into the mixnet,
|
||||
@@ -90,6 +93,11 @@ impl<G: GatewayTransceiver + ?Sized + Send> GatewayTransceiver for Box<G> {
|
||||
log::debug!("Sent client request: {:?}", message);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn is_connection_alive(&self) -> bool {
|
||||
(**self).is_connection_alive()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||
@@ -147,6 +155,10 @@ where
|
||||
) -> Result<(), GatewayClientError> {
|
||||
self.gateway_client.send_client_request(message).await
|
||||
}
|
||||
|
||||
fn is_connection_alive(&self) -> bool {
|
||||
self.gateway_client.is_connection_alive()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(target_arch = "wasm32", async_trait(?Send))]
|
||||
@@ -234,6 +246,11 @@ mod nonwasm_sealed {
|
||||
) -> Result<(), GatewayClientError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_connection_alive(&self) -> bool {
|
||||
// LocalGateway is always "connected" since it's in-process
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -316,4 +333,9 @@ impl GatewayTransceiver for MockGateway {
|
||||
) -> Result<(), GatewayClientError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn is_connection_alive(&self) -> bool {
|
||||
// MockGateway is always "connected" for testing purposes
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -166,6 +166,9 @@ pub enum ClientCoreError {
|
||||
#[error("there are no gateways supporting the wss protocol available")]
|
||||
NoWssGateways,
|
||||
|
||||
#[error("there are no gateways with compatible protocol versions available")]
|
||||
NoGatewaysWithCompatibleProtocol,
|
||||
|
||||
#[error("the specified gateway '{gateway}' does not support the wss protocol")]
|
||||
UnsupportedWssProtocol { gateway: String },
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ use futures::{SinkExt, StreamExt};
|
||||
use log::{debug, info, trace, warn};
|
||||
use nym_crypto::asymmetric::ed25519;
|
||||
use nym_gateway_client::GatewayClient;
|
||||
use nym_gateway_requests::{ClientControlRequest, ServerResponse, CURRENT_PROTOCOL_VERSION};
|
||||
use nym_topology::node::RoutingNode;
|
||||
use nym_validator_client::client::IdentityKeyRef;
|
||||
use nym_validator_client::UserAgent;
|
||||
@@ -131,6 +132,63 @@ pub async fn gateways_for_init<R: Rng>(
|
||||
Ok(valid_gateways)
|
||||
}
|
||||
|
||||
pub async fn gateways_for_init_with_protocol_validation<R: Rng>(
|
||||
rng: &mut R,
|
||||
nym_apis: &[Url],
|
||||
user_agent: Option<UserAgent>,
|
||||
minimum_performance: u8,
|
||||
ignore_epoch_roles: bool,
|
||||
) -> Result<Vec<RoutingNode>, ClientCoreError> {
|
||||
// First get the initial list of gateways
|
||||
let gateways = gateways_for_init(
|
||||
rng,
|
||||
nym_apis,
|
||||
user_agent,
|
||||
minimum_performance,
|
||||
ignore_epoch_roles,
|
||||
)
|
||||
.await?;
|
||||
|
||||
info!(
|
||||
"Checking protocol compatibility for {} gateways...",
|
||||
gateways.len()
|
||||
);
|
||||
|
||||
// Filter out gateways with invalid protocols concurrently
|
||||
let validated_gateways = Arc::new(tokio::sync::Mutex::new(Vec::new()));
|
||||
|
||||
futures::stream::iter(&gateways)
|
||||
.for_each_concurrent(CONCURRENT_GATEWAYS_MEASURED, |gateway| async {
|
||||
let id = gateway.identity();
|
||||
trace!("validating protocol compatibility with {id}...");
|
||||
|
||||
match validate_gateway_protocol(gateway).await {
|
||||
Ok(()) => {
|
||||
debug!("{id}: protocol check successful");
|
||||
validated_gateways.lock().await.push(gateway.clone());
|
||||
}
|
||||
Err(err) => {
|
||||
warn!("failed to check protocol for {id}: {err}");
|
||||
}
|
||||
}
|
||||
})
|
||||
.await;
|
||||
|
||||
let validated_gateways = validated_gateways.lock().await;
|
||||
|
||||
info!(
|
||||
"Protocol check complete: {}/{} gateways responded successfully",
|
||||
validated_gateways.len(),
|
||||
gateways.len()
|
||||
);
|
||||
|
||||
if validated_gateways.is_empty() {
|
||||
return Err(ClientCoreError::NoGatewaysWithCompatibleProtocol);
|
||||
}
|
||||
|
||||
Ok(validated_gateways.clone())
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
async fn connect(endpoint: &str) -> Result<WsConn, ClientCoreError> {
|
||||
match tokio::time::timeout(CONN_TIMEOUT, connect_async(endpoint)).await {
|
||||
@@ -210,6 +268,132 @@ where
|
||||
Ok(GatewayWithLatency::new(gateway, avg))
|
||||
}
|
||||
|
||||
async fn validate_gateway_protocol<G>(gateway: &G) -> Result<(), ClientCoreError>
|
||||
where
|
||||
G: ConnectableGateway,
|
||||
{
|
||||
let Some(addr) = gateway.clients_address(false) else {
|
||||
return Err(ClientCoreError::UnsupportedEntry {
|
||||
id: gateway.node_id(),
|
||||
identity: gateway.identity().to_string(),
|
||||
});
|
||||
};
|
||||
|
||||
trace!(
|
||||
"validating protocol compatibility with {} ({addr})...",
|
||||
gateway.identity(),
|
||||
);
|
||||
|
||||
let mut stream = connect(&addr).await?;
|
||||
|
||||
// Send protocol version request
|
||||
let protocol_request = ClientControlRequest::SupportedProtocol {};
|
||||
|
||||
// Send the request as JSON text message
|
||||
stream.send(Message::from(protocol_request)).await?;
|
||||
|
||||
// Wait for response with timeout
|
||||
let protocol_timeout = Duration::from_millis(2000);
|
||||
let response_future = stream.next();
|
||||
|
||||
match tokio::time::timeout(protocol_timeout, response_future).await {
|
||||
Err(_) => {
|
||||
warn!("Gateway {} protocol check timed out", gateway.identity());
|
||||
Err(ClientCoreError::GatewayConnectionTimeout)
|
||||
}
|
||||
Ok(Some(Ok(Message::Text(response_text)))) => {
|
||||
// Try to deserialize the response
|
||||
let response = ServerResponse::try_from(response_text).map_err(|_| {
|
||||
ClientCoreError::GatewayClientError {
|
||||
gateway_id: gateway.identity().to_base58_string(),
|
||||
source: *Box::new(
|
||||
nym_gateway_client::error::GatewayClientError::MalformedResponse,
|
||||
),
|
||||
}
|
||||
})?;
|
||||
|
||||
match response {
|
||||
ServerResponse::SupportedProtocol { version } => {
|
||||
debug!(
|
||||
"Gateway {} supports protocol version {}, ours: {}",
|
||||
gateway.identity(),
|
||||
version,
|
||||
CURRENT_PROTOCOL_VERSION
|
||||
);
|
||||
|
||||
// Check protocol compatibility
|
||||
if version > CURRENT_PROTOCOL_VERSION {
|
||||
warn!(
|
||||
"Gateway {} uses newer protocol version {} (client supports {}). \
|
||||
Gateway should gracefully degrade, but consider updating your client.",
|
||||
gateway.identity(),
|
||||
version,
|
||||
CURRENT_PROTOCOL_VERSION
|
||||
);
|
||||
}
|
||||
|
||||
trace!(
|
||||
"Gateway {} protocol validation successful (gateway: v{}, client: v{})",
|
||||
gateway.identity(),
|
||||
version,
|
||||
CURRENT_PROTOCOL_VERSION
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
ServerResponse::Error { message } => {
|
||||
warn!(
|
||||
"Gateway {} returned error during protocol check: {}",
|
||||
gateway.identity(),
|
||||
message
|
||||
);
|
||||
Err(ClientCoreError::GatewayClientError {
|
||||
gateway_id: gateway.identity().to_base58_string(),
|
||||
source: *Box::new(
|
||||
nym_gateway_client::error::GatewayClientError::GatewayError(message),
|
||||
),
|
||||
})
|
||||
}
|
||||
_ => {
|
||||
warn!(
|
||||
"Gateway {} returned unexpected response during protocol check",
|
||||
gateway.identity()
|
||||
);
|
||||
Err(ClientCoreError::GatewayClientError {
|
||||
gateway_id: gateway.identity().to_base58_string(),
|
||||
source: *Box::new(
|
||||
nym_gateway_client::error::GatewayClientError::UnexpectedResponse {
|
||||
name: response.name().to_string(),
|
||||
},
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Some(Ok(_))) => {
|
||||
warn!(
|
||||
"Gateway {} sent non-text response during protocol check",
|
||||
gateway.identity()
|
||||
);
|
||||
Err(ClientCoreError::GatewayConnectionAbruptlyClosed)
|
||||
}
|
||||
Ok(Some(Err(e))) => {
|
||||
warn!(
|
||||
"WebSocket error during protocol check with {}: {}",
|
||||
gateway.identity(),
|
||||
e
|
||||
);
|
||||
Err(e.into())
|
||||
}
|
||||
Ok(None) => {
|
||||
warn!(
|
||||
"Gateway {} closed connection during protocol check",
|
||||
gateway.identity()
|
||||
);
|
||||
Err(ClientCoreError::GatewayConnectionAbruptlyClosed)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn choose_gateway_by_latency<R: Rng, G: ConnectableGateway + Clone>(
|
||||
rng: &mut R,
|
||||
gateways: &[G],
|
||||
|
||||
@@ -27,7 +27,6 @@ nym-credential-storage = { path = "../../credential-storage" }
|
||||
nym-credentials-interface = { path = "../../credentials-interface" }
|
||||
nym-crypto = { path = "../../crypto" }
|
||||
nym-gateway-requests = { path = "../../gateway-requests" }
|
||||
nym-http-api-client = { path = "../../http-api-client" }
|
||||
nym-network-defaults = { path = "../../network-defaults" }
|
||||
nym-sphinx = { path = "../../nymsphinx" }
|
||||
nym-statistics-common = { path = "../../statistics" }
|
||||
|
||||
@@ -165,6 +165,24 @@ impl<C, St> GatewayClient<C, St> {
|
||||
self.bandwidth.remaining()
|
||||
}
|
||||
|
||||
pub fn is_connection_established(&self) -> bool {
|
||||
self.connection.is_established()
|
||||
}
|
||||
|
||||
/// Check if the websocket connection is actually alive at the socket level
|
||||
pub fn is_connection_alive(&self) -> bool {
|
||||
// First check if we have an established connection
|
||||
if !self.connection.is_established() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the file descriptor and check if the socket is alive
|
||||
match self.ws_fd() {
|
||||
Some(fd) => socket_is_alive(fd),
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
async fn _close_connection(&mut self) -> Result<(), GatewayClientError> {
|
||||
match std::mem::replace(&mut self.connection, SocketState::NotConnected) {
|
||||
@@ -1128,3 +1146,49 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if a socket file descriptor is alive and responsive
|
||||
///
|
||||
/// This function performs socket-level checks to determine if the connection is actually alive.
|
||||
/// It's cross-platform compatible and works on both Unix and non-Unix systems.
|
||||
fn socket_is_alive(fd: RawFd) -> bool {
|
||||
#[cfg(unix)]
|
||||
{
|
||||
use std::io::ErrorKind;
|
||||
use std::net::TcpStream;
|
||||
use std::os::unix::io::FromRawFd;
|
||||
|
||||
unsafe {
|
||||
// Create a TcpStream from the raw fd to perform socket operations
|
||||
let stream = TcpStream::from_raw_fd(fd);
|
||||
|
||||
// Try to peek at the socket to see if it's still connected
|
||||
// We peek with a zero-length buffer to avoid consuming data
|
||||
let mut buf = [0u8; 0];
|
||||
let result = match stream.peek(&mut buf) {
|
||||
Ok(_) => true, // Socket is alive and readable
|
||||
Err(e) => match e.kind() {
|
||||
ErrorKind::WouldBlock => true, // Socket is alive but no data available
|
||||
ErrorKind::ConnectionReset
|
||||
| ErrorKind::ConnectionAborted
|
||||
| ErrorKind::BrokenPipe
|
||||
| ErrorKind::NotConnected => false, // Socket is clearly dead
|
||||
_ => true, // Other errors might be temporary, assume alive
|
||||
},
|
||||
};
|
||||
|
||||
// Prevent the TcpStream from closing the fd when it's dropped
|
||||
// since we don't own the fd
|
||||
std::mem::forget(stream);
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(unix))]
|
||||
{
|
||||
// On non-Unix systems, we can't easily check socket state
|
||||
// Fall back to assuming the connection is alive if we have an fd
|
||||
fd != 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::error::GatewayClientError;
|
||||
|
||||
use nym_http_api_client::HickoryDnsResolver;
|
||||
#[cfg(unix)]
|
||||
use std::{
|
||||
os::fd::{AsRawFd, RawFd},
|
||||
@@ -20,7 +19,6 @@ pub(crate) async fn connect_async(
|
||||
) -> Result<(WebSocketStream<MaybeTlsStream<TcpStream>>, Response), GatewayClientError> {
|
||||
use tokio::net::TcpSocket;
|
||||
|
||||
let resolver = HickoryDnsResolver::default();
|
||||
let uri =
|
||||
Url::parse(endpoint).map_err(|_| GatewayClientError::InvalidUrl(endpoint.to_owned()))?;
|
||||
let port: u16 = uri.port_or_known_default().unwrap_or(443);
|
||||
@@ -29,18 +27,18 @@ pub(crate) async fn connect_async(
|
||||
.host()
|
||||
.ok_or(GatewayClientError::InvalidUrl(endpoint.to_owned()))?;
|
||||
|
||||
// Get address for tcp connection, if a domain is provided use our preferred resolver rather than
|
||||
// the default std resolve
|
||||
// Get address for tcp connection, using system DNS resolver
|
||||
let sock_addrs: Vec<SocketAddr> = match host {
|
||||
Host::Ipv4(addr) => vec![SocketAddr::new(addr.into(), port)],
|
||||
Host::Ipv6(addr) => vec![SocketAddr::new(addr.into(), port)],
|
||||
Host::Domain(domain) => {
|
||||
// Do a DNS lookup for the domain using our custom DNS resolver
|
||||
resolver
|
||||
.resolve_str(domain)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|a| SocketAddr::new(a, port))
|
||||
// Do a DNS lookup for the domain using system DNS resolver
|
||||
tokio::net::lookup_host((domain, port))
|
||||
.await
|
||||
.map_err(|err| GatewayClientError::NetworkConnectionFailed {
|
||||
address: endpoint.to_owned(),
|
||||
source: err.into(),
|
||||
})?
|
||||
.collect()
|
||||
}
|
||||
};
|
||||
|
||||
@@ -49,10 +49,6 @@ pub enum GatewayClientError {
|
||||
#[error("Invalid URL: {0}")]
|
||||
InvalidUrl(String),
|
||||
|
||||
#[cfg(not(target_arch = "wasm32"))]
|
||||
#[error("resolution failed: {0}")]
|
||||
ResolutionFailed(#[from] nym_http_api_client::HickoryDnsError),
|
||||
|
||||
#[error("No shared key was provided or obtained")]
|
||||
NoSharedKeyAvailable,
|
||||
|
||||
|
||||
@@ -73,6 +73,7 @@ pub const STAKE_SATURATION: &str = "stake-saturation";
|
||||
pub const INCLUSION_CHANCE: &str = "inclusion-probability";
|
||||
pub const SUBMIT_GATEWAY: &str = "submit-gateway-monitoring-results";
|
||||
pub const SUBMIT_NODE: &str = "submit-node-monitoring-results";
|
||||
pub const SUBMIT_ROUTE: &str = "submit-route-monitoring-results";
|
||||
|
||||
pub const SERVICE_PROVIDERS: &str = "services";
|
||||
|
||||
|
||||
@@ -98,11 +98,10 @@ impl SqliteEcashTicketbookManager {
|
||||
pub(crate) async fn contains_ticketbook_data(&self, data: &[u8]) -> Result<bool, sqlx::Error> {
|
||||
let exists = sqlx::query(
|
||||
r#"
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM ecash_ticketbook
|
||||
WHERE ticketbook_data = ?
|
||||
)
|
||||
SELECT 1
|
||||
FROM ecash_ticketbook
|
||||
WHERE ticketbook_data = ?
|
||||
|
||||
"#,
|
||||
)
|
||||
.bind(data)
|
||||
|
||||
@@ -124,7 +124,7 @@ impl ReconstructionBuffer {
|
||||
// TODO: what to do in that case? give up on the message? overwrite it? panic?
|
||||
// it *might* be due to lock ack-packet, but let's keep the `warn` level in case
|
||||
// it could be somehow exploited
|
||||
warn!(
|
||||
debug!(
|
||||
"duplicate fragment received! - frag - {} (set id: {})",
|
||||
fragment.current_fragment(),
|
||||
fragment.id()
|
||||
|
||||
@@ -224,6 +224,10 @@ impl NymTopology {
|
||||
serde_json::from_reader(file).map_err(Into::into)
|
||||
}
|
||||
|
||||
pub fn node_details(&self) -> &HashMap<NodeId, RoutingNode> {
|
||||
&self.node_details
|
||||
}
|
||||
|
||||
pub fn add_skimmed_nodes(&mut self, nodes: &[SkimmedNode]) {
|
||||
self.add_additional_nodes(nodes.iter())
|
||||
}
|
||||
|
||||
@@ -11,6 +11,27 @@ static NETWORK_MONITORS: LazyLock<HashSet<String>> = LazyLock::new(|| {
|
||||
nm
|
||||
});
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, ToSchema)]
|
||||
pub struct RouteResult {
|
||||
pub layer1: u32,
|
||||
pub layer2: u32,
|
||||
pub layer3: u32,
|
||||
pub gw: u32,
|
||||
pub success: bool,
|
||||
}
|
||||
|
||||
impl RouteResult {
|
||||
pub fn new(layer1: u32, layer2: u32, layer3: u32, gw: u32, success: bool) -> Self {
|
||||
RouteResult {
|
||||
layer1,
|
||||
layer2,
|
||||
layer3,
|
||||
gw,
|
||||
success,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, JsonSchema, Clone, ToSchema)]
|
||||
pub struct NodeResult {
|
||||
#[schema(value_type = u32)]
|
||||
@@ -29,23 +50,23 @@ impl NodeResult {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, JsonSchema)]
|
||||
#[derive(Serialize, Deserialize, JsonSchema, ToSchema)]
|
||||
#[serde(untagged)]
|
||||
pub enum MonitorResults {
|
||||
Mixnode(Vec<NodeResult>),
|
||||
Gateway(Vec<NodeResult>),
|
||||
Node(Vec<NodeResult>),
|
||||
Route(Vec<RouteResult>),
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, JsonSchema, ToSchema)]
|
||||
pub struct MonitorMessage {
|
||||
results: Vec<NodeResult>,
|
||||
results: MonitorResults,
|
||||
signature: String,
|
||||
signer: String,
|
||||
timestamp: i64,
|
||||
}
|
||||
|
||||
impl MonitorMessage {
|
||||
fn message_to_sign(results: &[NodeResult], timestamp: i64) -> Vec<u8> {
|
||||
fn message_to_sign(results: &MonitorResults, timestamp: i64) -> Vec<u8> {
|
||||
let mut msg = serde_json::to_vec(results).unwrap_or_default();
|
||||
msg.extend_from_slice(×tamp.to_le_bytes());
|
||||
msg
|
||||
@@ -60,7 +81,7 @@ impl MonitorMessage {
|
||||
now - self.timestamp < 5
|
||||
}
|
||||
|
||||
pub fn new(results: Vec<NodeResult>, private_key: &PrivateKey) -> Self {
|
||||
pub fn new(results: MonitorResults, private_key: &PrivateKey) -> Self {
|
||||
let timestamp = SystemTime::now()
|
||||
.duration_since(SystemTime::UNIX_EPOCH)
|
||||
.expect("Time went backwards")
|
||||
@@ -82,7 +103,7 @@ impl MonitorMessage {
|
||||
NETWORK_MONITORS.contains(&self.signer)
|
||||
}
|
||||
|
||||
pub fn results(&self) -> &[NodeResult] {
|
||||
pub fn results(&self) -> &MonitorResults {
|
||||
&self.results
|
||||
}
|
||||
|
||||
|
||||
+14
-5
@@ -1,17 +1,27 @@
|
||||
import React, { useState } from 'react'
|
||||
import CirculatingSupply from 'components/outputs/api-scraping-outputs/circulating-supply.json'
|
||||
import RewardParams from 'components/outputs/api-scraping-outputs/reward-params.json'
|
||||
|
||||
|
||||
export default function RewardsCalculator() {
|
||||
const [a, setA] = useState(0)
|
||||
const [a, setA] = useState(
|
||||
Number(
|
||||
(Number(RewardParams.interval.epoch_reward_budget) / 1_000_000).toFixed(6)
|
||||
)
|
||||
)
|
||||
const [b, setB] = useState(0)
|
||||
const [c, setC] = useState(0)
|
||||
const [d, setD] = useState(0)
|
||||
const [e, setE] = useState(0)
|
||||
|
||||
const [e, setE] = useState(
|
||||
Number(
|
||||
(Number(RewardParams.interval.stake_saturation_point) / 1_000_000).toFixed(6)
|
||||
)
|
||||
)
|
||||
const result =
|
||||
e !== 0
|
||||
? `${(
|
||||
a * b * c * ((1 / 240) + 0.3 * ((d / e) / 240)) * 1 / (1 + 0.3)
|
||||
).toFixed(4)} NYM`
|
||||
).toFixed(6)} NYM`
|
||||
: '—'
|
||||
|
||||
return (
|
||||
@@ -117,4 +127,3 @@ export default function RewardsCalculator() {
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"total_supply": {
|
||||
"denom": "unym",
|
||||
"amount": "1000000000000000"
|
||||
},
|
||||
"mixmining_reserve": {
|
||||
"denom": "unym",
|
||||
"amount": "188691142067690"
|
||||
},
|
||||
"vesting_tokens": {
|
||||
"denom": "unym",
|
||||
"amount": "0"
|
||||
},
|
||||
"circulating_supply": {
|
||||
"denom": "unym",
|
||||
"amount": "811308857932310"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"interval": {
|
||||
"reward_pool": "188691142067690.265566584946684804",
|
||||
"staking_supply": "248179643769563.241524591796100959",
|
||||
"staking_supply_scale_factor": "0.5",
|
||||
"epoch_reward_budget": "5241420612.991396265738470741",
|
||||
"stake_saturation_point": "1034081849039.84683968579915042",
|
||||
"sybil_resistance": "0.3",
|
||||
"active_set_work_factor": "10",
|
||||
"interval_pool_emission": "0.02"
|
||||
},
|
||||
"rewarded_set": {
|
||||
"entry_gateways": 50,
|
||||
"exit_gateways": 70,
|
||||
"mixnodes": 120,
|
||||
"standby": 0
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
Monday, May 19th 2025, 09:30:50 UTC
|
||||
Wednesday, May 21st 2025, 13:50:05 UTC
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# Introduction
|
||||
The Rust SDK allows developers building applications in Rust to import and interact with Nym clients as they would any other dependency, instead of running the client as a separate process on their machine.
|
||||
|
||||
Check the [development status](./rust/development-status) page to see the various modules that make up the SDK, and the [FFI](./rust/ffi) page for Go/C++ developers.
|
||||
@@ -0,0 +1,16 @@
|
||||
# Introduction
|
||||
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
The Rust SDK allows developers building applications in Rust to import and interact with Nym clients as they would any other dependency, instead of running the client as a separate process on their machine.
|
||||
|
||||
Check the [development status](./rust/development-status) page to see the various modules that make up the SDK, and the [FFI](./rust/ffi) page for Go/C++ developers.
|
||||
@@ -4,6 +4,5 @@
|
||||
"mixnet": "Mixnet Module",
|
||||
"tcpproxy": "TcpProxy Module",
|
||||
"client-pool": "Client Pool",
|
||||
"ffi": "FFI",
|
||||
"tutorials": "Tutorials (Coming Soon)"
|
||||
"ffi": "FFI"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
# Client Pool
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
We have a configurable-size Client Pool for processes that require multiple clients in quick succession (this is used by default by the [`TcpProxyClient`](./tcpproxy) for instance)
|
||||
|
||||
This will be useful for developers looking to build connection logic, or just are using raw SDK clients in a sitatuation where there are multiple connections with a lot of churn.
|
||||
|
||||
@@ -1,5 +1,17 @@
|
||||
# Client Pool Architecture
|
||||
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
|
||||
## Motivations
|
||||
In situations where multiple connections are expected, and the number of connections can vary greatly, the Client Pool reduces time spent waiting for the creation of a Mixnet Client blocking your code sending traffic through the Mixnet. Instead, a configurable number of Clients can be generated and run in the background which can be very quickly grabbed, used, and disconnected.
|
||||
|
||||
|
||||
+10
@@ -1,5 +1,15 @@
|
||||
# Client Pool Example
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
> You can find this code [here](https://github.com/nymtech/nym/blob/develop/sdk/rust/nym-sdk/examples/client_pool.rs)
|
||||
|
||||
```rust
|
||||
+12
@@ -1,4 +1,16 @@
|
||||
# Development status
|
||||
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
The SDK is still somewhat a work in progress: interfaces are fairly stable but still may change in subsequent releases.
|
||||
|
||||
In the future the SDK will be made up of several modules, each of which will allow developers to interact with different parts of Nym infrastructure.
|
||||
@@ -1,7 +1,14 @@
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
# FFI Bindings
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
We are working on the intitial versions of the FFI code to allow developers to experiment and get feedback. Please get in touch if you think the FFI bindings are lacking certain functionality.
|
||||
</Callout>
|
||||
|
||||
+10
@@ -1,4 +1,14 @@
|
||||
# Installation
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
The `nym-sdk` crate is **not yet available via [crates.io](https://crates.io)**. As such, in order to import the crate you must specify the Nym monorepo in your `Cargo.toml` file. Since the `HEAD` of `master` is always the most recent release, we recommend developers use that for their imports, unless they have a reason to pull in a specific historic version of the code.
|
||||
|
||||
```toml
|
||||
@@ -1,4 +1,13 @@
|
||||
# Mixnet Module
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
This module exposes the logic of creating and interacting with clients and Mixnet messages. This is recommended for those wanting to either start playing around with the Mixnet and how it works, or build connection logic.
|
||||
|
||||
|
||||
+10
@@ -1,5 +1,15 @@
|
||||
# Examples
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
All the following examples can be found in the `nym-sdk` [examples directory](https://github.com/nymtech/nym/tree/master/sdk/rust/nym-sdk/examples) in the monorepo. Just navigate to `nym/sdk/rust/nym-sdk/examples/` and run the files from there with:
|
||||
|
||||
```sh
|
||||
@@ -1,3 +0,0 @@
|
||||
# Builder Patterns
|
||||
|
||||
Since there are two ways of creating an SDK client - ephemeral and with-storage - then there are two ways of applying the Builder Pattern to client creation.
|
||||
@@ -0,0 +1,11 @@
|
||||
# Builder Patterns
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
Since there are two ways of creating an SDK client - ephemeral and with-storage - then there are two ways of applying the Builder Pattern to client creation.
|
||||
+8
@@ -1,5 +1,13 @@
|
||||
# Mixnet Client Builder with Storage
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
The previous example involves ephemeral keys - if we want to create and then maintain a client identity over time, our code becomes a little more complex as we need to create, store, and conditionally load these keys.
|
||||
|
||||
> You can find this code [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/examples/builder_with_storage.rs).
|
||||
+8
@@ -1,5 +1,13 @@
|
||||
# Mixnet Client Builder
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
You can spin up an ephemeral client like so. This client will not have a persistent identity and its keys will be dropped on restart. Since there is currently no way of reconnecting a client that has been disconnected after use, then treat disconnecting a client the same as dropping its keys entirely.
|
||||
|
||||
> You can find this code [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/examples/builder.rs).
|
||||
@@ -2,6 +2,14 @@
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
<Callout type="warning" emoji="⚠️">
|
||||
These examples are **not** the same as using a configurable network: these functions define a subset of nodes to use on a given network, whereas the [testnet](./testnet) example is an example of switching to use a different network entirely. The two can be combined, but if you are looking for how to connect your client to a testnet, see the `testnet` file.
|
||||
</Callout>
|
||||
|
||||
+8
@@ -1,5 +1,13 @@
|
||||
# Custom Topology Provider
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
If you are also running a Validator and Nym API for your network, you can specify that endpoint as such and interact with it as clients usually do (under the hood).
|
||||
|
||||
> You can find this code [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/examples/custom_topology_provider.rs)
|
||||
+8
@@ -1,5 +1,13 @@
|
||||
# Manually Overwrite Topology
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
If you aren't running a Validator and Nym API, and just want to import a specific sub-set of mix nodes, you can simply overwrite the grabbed topology manually.
|
||||
|
||||
> You can find this code [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/examples/manually_overwrite_topology.rs)
|
||||
+10
@@ -1,4 +1,14 @@
|
||||
# Simple Send
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
Lets look at a very simple example of how you can import and use the websocket client in a piece of Rust code.
|
||||
|
||||
Simply importing the `nym_sdk` crate into your project allows you to create a client and send traffic through the mixnet.
|
||||
+9
@@ -1,5 +1,14 @@
|
||||
# Socks Proxy
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
If you are looking at implementing Nym as a transport layer for a crypto wallet or desktop app, this is probably the best place to start if they can speak SOCKS5, 4a, or 4.
|
||||
|
||||
> You can find this code [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/examples/socks5.rs)
|
||||
+10
@@ -1,4 +1,14 @@
|
||||
# Send and Receive in Different Tasks
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
If you need to split the different actions of your client across different tasks, you can do so like this. You can think of this analogously to spliting a Tcp Stream into read/write. This functionality is also useful for embedding a sending and receiving client into different tasks.
|
||||
|
||||
> You can find this code [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/examples/parallel_sending_and_receiving.rs)
|
||||
+10
@@ -1,4 +1,14 @@
|
||||
# Manually Handle Storage
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
If you're integrating mixnet functionality into an existing app and want to integrate saving client configs and keys into your existing storage logic, you can manually perform these actions.
|
||||
|
||||
> You can find this code [here](https://github.com/nymtech/nym/blob/master/sdk/rust/nym-sdk/examples/manually_handle_storage.rs)
|
||||
+10
@@ -1,4 +1,14 @@
|
||||
# Anonymous Replies with SURBs (Single Use Reply Blocks)
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
Both functions used to send messages through the mixnet (`send_message` and `send_plain_message`) send a pre-determined number of SURBs along with their messages by default.
|
||||
|
||||
You can read more about how SURBs function under the hood [here](../../../../network/traffic/anonymous-replies).
|
||||
@@ -1,5 +1,13 @@
|
||||
# Configurable Network
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
If you want to connect your Mixnet client to a different network than Mainnet, simply pull in a file from [`nym/envs`](https://github.com/nymtech/nym/tree/master/envs) as such:
|
||||
|
||||
```rust
|
||||
|
||||
+10
@@ -1,5 +1,15 @@
|
||||
# Message Helpers
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
## Handling incoming messages
|
||||
When listening out for a response to a sent message (e.g. if you have sent a request to a service, and are awaiting the response) you will want to await [non-empty messages (if you don't know why, read the info on this here)](./troubleshooting#client-receives-empty-messages-when-listening-for-response). This can be done with something like the helper functions here:
|
||||
|
||||
+10
@@ -1,5 +1,15 @@
|
||||
# Message Types
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
There are several functions used to send outgoing messages through the Mixnet, each with a different level of customisation:
|
||||
|
||||
- `send(&self, message: InputMessage) -> Result<()>`
|
||||
+13
@@ -1,4 +1,17 @@
|
||||
# Troubleshooting
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
|
||||
Below are several common issues or questions you may have.
|
||||
|
||||
If you come across something that isn't explained here, [PRs are welcome](https://github.com/nymtech/nym/issues/new/choose).
|
||||
@@ -1,5 +1,13 @@
|
||||
# TcpProxy Module
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
This module exposes the `TcpProxyClient` and the `TcpProxyServer` which can be used to proxy traffic through the Mixnet in a way that is more familiar to developers than the methods exposed by the [`Mixnet` module](./mixnet).
|
||||
|
||||
Both `Client` and `Server` are intended to be initialised and then run in a background thread, exposing a configurable `localhost` socket which developers can read/write/stream to without having to worry about the [message-based](../concepts/messages) nature of sending and receiving traffic to/from the Mixnet.
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
# Architecture
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
|
||||
## Motivations
|
||||
The motivation behind the creation of the `TcpProxy` module is to allow developers to interact with the Mixnet in a way that is far more familiar to them: simply setting up a connection with a transport, being returned a socket, and then being able to stream data to/from it, similar to something like the Tor [`arti`](https://gitlab.torproject.org/tpo/core/arti/-/tree/main/crates/arti-client) client.
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Multi Connection Example
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
This example starts off several Tcp connections on a loop to a remote endpoint: in this case the `TcpListener` behind the `NymProxyServer` instance on the echo server found in
|
||||
[`nym/tools/echo-server/`](https://github.com/nymtech/nym/tree/develop/tools/echo-server). It pipes a few messages to it, logs the replies, and keeps track of the number of replies received per connection.
|
||||
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# Single Connection Example
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
This is a basic example which opens a single TCP connection and writes a bunch of messages between a client and some 'echo server' logic, so only uses a single session under the hood and doesn't really show off the message ordering capabilities; this is mainly just a quick introductory illustration on how:
|
||||
- the mixnet does message ordering
|
||||
- the NymProxyClient and NymProxyServer can be hooked into and used to communicate between two otherwise pretty vanilla TcpStreams
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
# Troubleshooting
|
||||
|
||||
## Lots of `duplicate fragment received` messages
|
||||
You might see a lot of `WARN` level logs about duplicate fragments in your logs, depending on the log level you're using. This occurs when a packet is retransmitted somewhere in the Mixnet, but then the original makes it to the destination client as well. This is not something to do with your client logic, but instead the state of the Mixnet.
|
||||
@@ -0,0 +1,12 @@
|
||||
# Troubleshooting
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
There will be a breaking SDK upgrade in the coming months. This upgrade will make the SDK a lot easier to build with.
|
||||
|
||||
This upgrade will affect the interface of the SDK dramatically, and will be coupled with a protocol change - stay tuned for information on early access to the new protocol testnet.
|
||||
|
||||
It will also be coupled with the documentation of the SDK on [crates.io](https://crates.io/).
|
||||
</Callout>
|
||||
## Lots of `duplicate fragment received` messages
|
||||
You might see a lot of `WARN` level logs about duplicate fragments in your logs, depending on the log level you're using. This occurs when a packet is retransmitted somewhere in the Mixnet, but then the original makes it to the destination client as well. This is not something to do with your client logic, but instead the state of the Mixnet.
|
||||
@@ -1,5 +1,16 @@
|
||||
|
||||
# Introduction
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
Welcome to the documentation for Nym's TypeScript SDK!
|
||||
|
||||
This comprehensive guide contains information about the various TypeScript SDK modules that facilitate interaction with different components of the Nym stack, including the Nym mixnet, the Nyx blockchain, and Coconut credentials.
|
||||
This guide contains information about the various TypeScript SDK modules that facilitate interaction with different components of the Nym stack, including the Nym mixnet, the Nyx blockchain, and Coconut credentials.
|
||||
|
||||
@@ -1,4 +1,13 @@
|
||||
# TS SDK FAQ
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
## Why and when does the mixnet client complain about insufficient topology?
|
||||
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
# Troubleshooting bundling
|
||||
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
You might need some help bundling packages from the Nym Typescript SDK into your package.
|
||||
|
||||
Here are some things that could go wrong:
|
||||
|
||||
@@ -2,6 +2,14 @@ import { Callout } from 'nextra/components';
|
||||
|
||||
# Troubleshooting bundling with ESbuild
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
If you've been following the steps outlined in the Examples section, your development environment should be configured as follows:
|
||||
|
||||
#### Environment Setup
|
||||
@@ -14,7 +22,7 @@ npm create vite@latest
|
||||
During the environment setup, choose React and subsequently opt for Typescript if you want your application to function smoothly following this tutorial. Next, navigate to your application directory and run the following commands:
|
||||
```bash
|
||||
cd < YOUR_APP >
|
||||
npm i
|
||||
npm i
|
||||
npm run dev
|
||||
```
|
||||
|
||||
@@ -29,4 +37,3 @@ npm install @nymproject/< PACKAGE_NAME >
|
||||
</Callout>
|
||||
|
||||
By implementing the provided code for the various components in the step-by-step examples section, you should be able to set-up and run your application without encountering any bundling challenges!
|
||||
|
||||
|
||||
@@ -2,6 +2,15 @@ import { Callout } from 'nextra/components';
|
||||
|
||||
# Troubleshooting bundling with Webpack
|
||||
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
## Webpack > 5 ESM
|
||||
|
||||
For any project using Webpack, you´ll need the following rule in your `webpack.config.js` above version 5:
|
||||
@@ -24,7 +33,7 @@ If you wish to use Webpack for your app with the code provided in the step-by-st
|
||||
npx create-react-app nymapp --template typescript
|
||||
cd nymapp
|
||||
```
|
||||
You'll then need to install the needed dependencies, head to your app's `App.tsx` file and paste the code provided in the step-by-step section.
|
||||
You'll then need to install the needed dependencies, head to your app's `App.tsx` file and paste the code provided in the step-by-step section.
|
||||
|
||||
#### Contract client
|
||||
|
||||
@@ -34,7 +43,7 @@ You'll then need to install the needed dependencies, head to your app's `App.tsx
|
||||
|
||||
##### Install contract-clients dependencies
|
||||
```bash
|
||||
npm install @nymproject/contract-clients @cosmjs/cosmwasm-stargate @cosmjs/proto-signing
|
||||
npm install @nymproject/contract-clients @cosmjs/cosmwasm-stargate @cosmjs/proto-signing
|
||||
```
|
||||
|
||||
Head to you app's `App.tsx` file and replace the code by the one provided in the step-by-step examples section.
|
||||
@@ -76,7 +85,7 @@ module.exports = function override(config) {
|
||||
}
|
||||
}
|
||||
])
|
||||
return config;
|
||||
return config;
|
||||
}
|
||||
EOF
|
||||
```
|
||||
@@ -90,4 +99,4 @@ EOF
|
||||
"test": "react-app-rewired test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
```
|
||||
```
|
||||
|
||||
@@ -2,8 +2,12 @@ import { Callout } from 'nextra/components'
|
||||
|
||||
# Cosmos Kit
|
||||
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
The wonderful people of Cosmology have made some [fantastic components](https://cosmoskit.com/) that can be used with
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
import { Callout } from 'nextra/components';
|
||||
|
||||
# `mixFetch`
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
An easy way to secure parts or all of your web app is to replace calls to [`fetch`](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch) with `mixFetch`:
|
||||
|
||||
MixFetch works the same as vanilla `fetch` as it's a proxied wrapper around the original function.
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
# Mixnet Client
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
As you know by now, in order to send or receive messages over the mixnet, you'll need to use the [`SDK Client`](https://www.npmjs.com/package/@nymproject/sdk), which will allow you to create apps that can use the Nym mixnet and Coconut credentials.
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
# Nym Smart Contract Clients
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
As previously mentioned, to query or execute on any of the Nym contracts, you'll need to use one of the [`Contract Clients`](https://www.npmjs.com/package/@nymproject/contract-clients), which contains read-only query and signing clients for all of Nym's smart contracts.
|
||||
|
||||
|
||||
@@ -4,6 +4,14 @@ import { Callout } from 'nextra/components'
|
||||
|
||||
The different modules in the Typescript SDK allow developers to start building browser-based applications quickly. Simply import the SDK module of your choice – depending on the component from the Nym architecture you want to use – into your code via NPM, as you would any other TypeScript library.
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
Other than the `Contract Clients`, SDK modules come in four different flavours (ESM, CJS and full-fat for ESM and CJS).
|
||||
This documentation focuses on examples using the `full-fat` versions.
|
||||
|
||||
@@ -3,6 +3,16 @@ import { TableContainer, Table, TableBody, TableCell, TableRow, Paper } from '@m
|
||||
import { NPMLink } from '../../../components/npm';
|
||||
|
||||
## SDK overview
|
||||
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
The Typescript SDK allows developers to start building browser-based Nym-based applications quickly, by simply importing the SDK modules into their code via NPM as they would any other Typescript library.
|
||||
|
||||
Currently developers can use different packages from the Typescript SDK to run the following entirely in browser:
|
||||
|
||||
@@ -6,8 +6,12 @@ import FormattedCosmoskitExampleCode from '../../../../code-examples/sdk/typescr
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
Below is an example that uses [CosmosKit](https://cosmoskit.com/) to connect and sign a fake transaction with your [Keplr wallet](https://www.keplr.app/) or
|
||||
|
||||
@@ -5,23 +5,16 @@ import Box from '@mui/material/Box';
|
||||
import FormattedMixFetchExampleCode from '../../../../code-examples/sdk/typescript/mixfetch-example-code.mdx';
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
<Callout type="info" emoji="ℹ️">
|
||||
Right now Gateways are not required to run a Secure Websocket (WSS) listener, so only a subset of nodes running in Gateway mode have configured their nodes to do so.
|
||||
|
||||
For the moment you have to select a Gateway that has WSS enabled from [this list](https://harbourmaster.nymtech.net/v1/services?wss=true).
|
||||
|
||||
You can also find WSS-enabled nodes by querying the `gateways/described` endpoint on the Nym API and filtering for `wss_port`, either via the [Swagger webpage](https://validator.nymtech.net/api/swagger/index.html) or with `curl`:
|
||||
|
||||
```
|
||||
curl -X 'GET' \
|
||||
'https://validator.nymtech.net/api/v1/gateways/described' \
|
||||
-H 'accept: application/json'
|
||||
```
|
||||
</Callout>
|
||||
|
||||
|
||||
<MixFetch />
|
||||
|
||||
@@ -5,8 +5,14 @@ import Box from '@mui/material/Box';
|
||||
import FormattedExampleCode from '../../../../code-examples/sdk/typescript/mixnodes-example-code.mdx';
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
The Nym Mixnet contract keeps a directory of all mixnodes that can be used to mix traffic.
|
||||
|
||||
@@ -4,10 +4,14 @@ import { Traffic } from '../../../../components/traffic';
|
||||
import Box from '@mui/material/Box';
|
||||
import FormattedTrafficExampleCode from '../../../../code-examples/sdk/typescript/traffic-example-code.mdx';
|
||||
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
</Callout>
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
Use this tool to experiment with the mixnet: send and receive messages!
|
||||
|
||||
<Traffic />
|
||||
|
||||
@@ -13,8 +13,12 @@ import FormattedWalletDelegationsCode from '../../../../code-examples/sdk/typesc
|
||||
|
||||
import { Callout } from 'nextra/components'
|
||||
|
||||
<Callout type="warning">
|
||||
The Typescript SDK is currently undergoing maintenance: a network upgrade elsewhere has temporarily caused a problem. These docs are likely to change after we upgrade the SDK.
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
Here's a small wallet example using testnet for you to test out!
|
||||
|
||||
@@ -3,6 +3,14 @@ import { Callout } from 'nextra/components'
|
||||
|
||||
## MixFetch
|
||||
|
||||
<Callout type="error">
|
||||
The TypeScript SDK is currently not avaliable to use: a network upgrade elsewhere has caused a problem which is not currently fixed. TS SDK Clients are not able to connect to the network.
|
||||
|
||||
When the issue is resolved, this will be reflected in the documentation.
|
||||
|
||||
Thanks for your patience!
|
||||
</Callout>
|
||||
|
||||
Use the [`mixFetch`](https://www.npmjs.com/package/@nymproject/mix-fetch) package as a drop-in replacement for `fetch`to send HTTP requests over the Nym mixnet:
|
||||
|
||||
```ts
|
||||
|
||||
@@ -29,6 +29,10 @@ python api_targets.py time_now > ../../docs/components/outputs/api-scraping-outp
|
||||
|
||||
python api_targets.py calculate --staking_target --separator _ > ../../docs/components/outputs/api-scraping-outputs/nyx-outputs/staking-target.md &&
|
||||
|
||||
curl -L https://validator.nymtech.net/api/v1/circulating-supply | jq > ../../docs/components/outputs/api-scraping-outputs/circulating-supply.json &&
|
||||
|
||||
curl -L https://validator.nymtech.net/api/v1/epoch/reward_params | jq > ../../docs/components/outputs/api-scraping-outputs/reward-params.json &&
|
||||
|
||||
cd ../../../scripts &&
|
||||
echo '```python' > ../documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md &&
|
||||
python node_api_check.py query_stats --help >> ../documentation/docs/components/outputs/command-outputs/node-api-check-query-help.md &&
|
||||
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT epoch_id as \"epoch_id: u32\", serialised_signatures, serialization_revision as \"serialization_revision: u8\"\n FROM expiration_date_signatures\n WHERE expiration_date = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "epoch_id: u32",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "serialised_signatures",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "serialization_revision: u8",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "00d857b624e7edab1198114b17cbad1e16988a3f9989d135840500e1143ce5e5"
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT epoch_id as \"epoch_id: u32\", serialised_key, serialization_revision as \"serialization_revision: u8\"\n FROM master_verification_key WHERE epoch_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "epoch_id: u32",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "serialised_key",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "serialization_revision: u8",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "0112296b190328a3856d1adf51aafa2525da6c0b871633aad80ad555db9cf47c"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT COUNT(*) as count FROM simulated_node_performance WHERE simulated_epoch_id = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "count",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "0557e64c547e147ef7eef713b49c62afde62b3b04ff817ae372ffe9fbeaee6b8"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT COUNT(*) as count FROM simulated_reward_epochs",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "count",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 0
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "1411660a6456f6f5ca141db10d9a54857fc8b4a661e09ae6719d84ac2e77cf6d"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT OR IGNORE INTO expiration_date_signatures(expiration_date, epoch_id, serialised_signatures, serialization_revision)\n VALUES (?, ?, ?, ?);\n UPDATE expiration_date_signatures\n SET\n serialised_signatures = ?,\n serialization_revision = ?\n WHERE expiration_date = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 7
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "16d10f0ac0ed9ce4239937f46df3797a6a9ee7db2aab9f1b5e55f7c13c53bcc1"
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id as \"id!\", epoch_id as \"epoch_id!: u32\", calculation_method as \"calculation_method!\", \n start_timestamp as \"start_timestamp!\", end_timestamp as \"end_timestamp!\", \n description, created_at as \"created_at!\"\n FROM simulated_reward_epochs\n WHERE id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "epoch_id!: u32",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "start_timestamp!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "end_timestamp!",
|
||||
"ordinal": 4,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "description",
|
||||
"ordinal": 5,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "created_at!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "1e4daea4d5f87938cf98cb2b6facc5802e79b06f3d0d41f6467844265b26d0f7"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO ecash_ticketbook\n (serialization_revision, ticketbook_data, expiration_date, ticketbook_type, epoch_id, total_tickets, used_tickets)\n VALUES (?, ?, ?, ?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 7
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "284b3ceae42f9320c30323dde47765854899103fd3c0fa670eb6809492270e02"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO simulated_reward_epochs \n (epoch_id, calculation_method, start_timestamp, end_timestamp, description)\n VALUES (?, ?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 5
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "2bb062a25129bfc6b060f68592e74aa91d8c82b8b912009fce14f9c19fd4464c"
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id as \"id!\", simulated_epoch_id as \"simulated_epoch_id!\", \n node_id as \"node_id!: NodeId\", calculation_method as \"calculation_method!\", \n performance_rank as \"performance_rank!\", performance_percentile as \"performance_percentile!\",\n calculated_at as \"calculated_at!\"\n FROM simulated_performance_rankings\n WHERE simulated_epoch_id = ? AND calculation_method = ?\n ORDER BY performance_rank\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "simulated_epoch_id!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_id!: NodeId",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "performance_rank!",
|
||||
"ordinal": 4,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "performance_percentile!",
|
||||
"ordinal": 5,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "calculated_at!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "3024d5e589b1f50f95f5e7bf09e31161beca74e137e340d2a6a02a589ad251cb"
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id as \"id!\", simulated_epoch_id as \"simulated_epoch_id!\", \n node_id as \"node_id!: NodeId\", calculation_method as \"calculation_method!\", \n performance_rank as \"performance_rank!\", performance_percentile as \"performance_percentile!\",\n calculated_at as \"calculated_at!\"\n FROM simulated_performance_rankings\n WHERE simulated_epoch_id = ?\n ORDER BY calculation_method, performance_rank\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "simulated_epoch_id!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_id!: NodeId",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "performance_rank!",
|
||||
"ordinal": 4,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "performance_percentile!",
|
||||
"ordinal": 5,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "calculated_at!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "33108405de0328977ac5d05d89f484bdb127f9cba0ba5370c931e1225983d74a"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "DELETE FROM ecash_ticketbook WHERE expiration_date <= ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "37f82c9ec26b53d01601a2d6df82038a77ec37cca9f9aef18008dcd03030c2c4"
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT sra.id as \"id!\", sra.simulated_epoch_id as \"simulated_epoch_id!\", \n sra.calculation_method as \"calculation_method!\", sra.total_routes_analyzed as \"total_routes_analyzed!: u32\", \n sra.successful_routes as \"successful_routes!: u32\", sra.failed_routes as \"failed_routes!: u32\", \n sra.average_route_reliability, sra.time_window_hours as \"time_window_hours!: u32\", \n sra.analysis_parameters, sra.calculated_at as \"calculated_at!\"\n FROM simulated_route_analysis sra\n JOIN simulated_reward_epochs sre ON sra.simulated_epoch_id = sre.id\n WHERE sre.epoch_id = ? AND sra.calculation_method = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "simulated_epoch_id!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "total_routes_analyzed!: u32",
|
||||
"ordinal": 3,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "successful_routes!: u32",
|
||||
"ordinal": 4,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "failed_routes!: u32",
|
||||
"ordinal": 5,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "average_route_reliability",
|
||||
"ordinal": 6,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "time_window_hours!: u32",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "analysis_parameters",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "calculated_at!",
|
||||
"ordinal": 9,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "4e2338362058e4356ac639fdf806e827761f879cab723cb2a649bc76b176fdad"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "DELETE FROM pending_issuance WHERE deposit_id = ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "5c5d4bfabf18bc6fa56e76a9b98e38b7f6ceb8e9191a7b9201922efcf6b07966"
|
||||
}
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT OR IGNORE INTO routes (layer1, layer2, layer3, gw, success) VALUES (?, ?, ?, ?, ?);\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 5
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "66109c1d856e1ca2b5126e4bf4c58c7a27b8c303bfa079cf74909354202dcc49"
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n d.node_id as \"node_id: NodeId\",\n CASE WHEN count(*) > 3 THEN AVG(reliability) ELSE 100 END as \"value: f32\"\n FROM\n gateway_details d\n JOIN\n gateway_status s on d.id = s.gateway_details_id\n WHERE\n timestamp >= ? AND\n timestamp <= ?\n GROUP BY 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "node_id: NodeId",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "value: f32",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "676299beb2004ab89f7b38cf21ffb84ab5e7d7435297573523e2532560c2e302"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id as \"id!\", simulated_epoch_id as \"simulated_epoch_id!\", node_id as \"node_id!: NodeId\", \n node_type as \"node_type!\", performance_score as \"performance_score!\", \n work_factor as \"work_factor!\", calculation_method as \"calculation_method!\", \n positive_samples as \"positive_samples?\", negative_samples as \"negative_samples?\",\n route_success_rate as \"route_success_rate?\", calculated_at as \"calculated_at!\"\n FROM simulated_performance_comparisons\n WHERE simulated_epoch_id = ?\n ORDER BY calculation_method, node_id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "simulated_epoch_id!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_id!: NodeId",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_type!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "performance_score!",
|
||||
"ordinal": 4,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "work_factor!",
|
||||
"ordinal": 5,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 6,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "positive_samples?",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "negative_samples?",
|
||||
"ordinal": 8,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "route_success_rate?",
|
||||
"ordinal": 9,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "calculated_at!",
|
||||
"ordinal": 10,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
true,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "6a7b25d2c580298bd44fcf74e4d2c550537c64dbfb2c17a6c91bd5345b9a3e6a"
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n layer1 as \"layer1\",\n layer2 as \"layer2\",\n layer3 as \"layer3\",\n gw as \"gw\",\n success\n FROM routes\n WHERE timestamp >= ? AND timestamp <= ?\n ORDER BY timestamp ASC\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "layer1",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "layer2",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "layer3",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "gw",
|
||||
"ordinal": 3,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "success",
|
||||
"ordinal": 4,
|
||||
"type_info": "Bool"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "6b2479c02cf1ef5ae674ce0ab4d027595b91739f3579e1f289b0c722ea91bbcc"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT snp.id as \"id!\", snp.simulated_epoch_id as \"simulated_epoch_id!\", \n snp.node_id as \"node_id!: NodeId\", snp.node_type as \"node_type!\", \n snp.identity_key, snp.reliability_score as \"reliability_score!\", \n snp.positive_samples as \"positive_samples!: u32\", snp.negative_samples as \"negative_samples!: u32\", \n snp.work_factor, snp.calculation_method as \"calculation_method!\", snp.calculated_at as \"calculated_at!\"\n FROM simulated_node_performance snp\n JOIN simulated_reward_epochs sre ON snp.simulated_epoch_id = sre.id\n WHERE snp.node_id = ?\n ORDER BY sre.epoch_id DESC, snp.calculation_method\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "simulated_epoch_id!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_id!: NodeId",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_type!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "identity_key",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "reliability_score!",
|
||||
"ordinal": 5,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "positive_samples!: u32",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "negative_samples!: u32",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "work_factor",
|
||||
"ordinal": 8,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "calculated_at!",
|
||||
"ordinal": 10,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "6fa6967e77886b69b049c68b664cdf8f4b97daa3734036db16e49915fd89073a"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT INTO pending_issuance\n (deposit_id, serialization_revision, pending_ticketbook_data, expiration_date)\n VALUES (?, ?, ?, ?)\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 4
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "81a12a8a419c88b1c28a5533fde4d63462e9ea0049e2edafea1dc3f8476b33e4"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "UPDATE ecash_ticketbook SET used_tickets = used_tickets + ? WHERE id = ?",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "84cad8b1078a4000830835e6349de3eb76fed954b7336530401db72cd008aff3"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT OR IGNORE INTO master_verification_key(epoch_id, serialised_key, serialization_revision) VALUES (?, ?, ?);\n UPDATE master_verification_key\n SET\n serialised_key = ?,\n serialization_revision = ?\n WHERE epoch_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 6
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "a5b18e66d77ff802e274623605e15dcfcffb502ba8398caefd56c481f44eb84e"
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT epoch_id as \"epoch_id: u32\", serialised_signatures, serialization_revision as \"serialization_revision: u8\"\n FROM coin_indices_signatures WHERE epoch_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "epoch_id: u32",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "serialised_signatures",
|
||||
"ordinal": 1,
|
||||
"type_info": "Blob"
|
||||
},
|
||||
{
|
||||
"name": "serialization_revision: u8",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "ba96344db31b0f2155e2af53eaaeafc9b5f64061b6c9a829e2912945b6cffc82"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n UPDATE ecash_ticketbook\n SET used_tickets = used_tickets - ?\n WHERE id = ?\n AND used_tickets = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 3
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "bc823c54143e2dc590b91347cd089dde284b38a3a4960afed758206d03ca1cf4"
|
||||
}
|
||||
-12
@@ -1,12 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n INSERT OR IGNORE INTO coin_indices_signatures(epoch_id, serialised_signatures, serialization_revision) VALUES (?, ?, ?);\n UPDATE coin_indices_signatures\n SET\n serialised_signatures = ?,\n serialization_revision = ?\n WHERE epoch_id = ?\n ",
|
||||
"describe": {
|
||||
"columns": [],
|
||||
"parameters": {
|
||||
"Right": 6
|
||||
},
|
||||
"nullable": []
|
||||
},
|
||||
"hash": "bd1973696121b6128bd75ae80fab253c071e04eb853d4b0f3b21782ea57c2f68"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id as \"id!\", simulated_epoch_id as \"simulated_epoch_id!\", node_id as \"node_id!: NodeId\", \n node_type as \"node_type!\", identity_key, reliability_score as \"reliability_score!\", \n positive_samples as \"positive_samples!: u32\", negative_samples as \"negative_samples!: u32\", \n work_factor, calculation_method as \"calculation_method!\", calculated_at as \"calculated_at!\"\n FROM simulated_node_performance\n WHERE simulated_epoch_id = ?\n ORDER BY calculation_method, node_id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "simulated_epoch_id!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_id!: NodeId",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_type!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "identity_key",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "reliability_score!",
|
||||
"ordinal": 5,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "positive_samples!: u32",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "negative_samples!: u32",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "work_factor",
|
||||
"ordinal": 8,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "calculated_at!",
|
||||
"ordinal": 10,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "c04c33631eea6959267dd441f50c2bd876ba951e32e8b8bee398cf98fec5e7bf"
|
||||
}
|
||||
-26
@@ -1,26 +0,0 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT\n d.mix_id as \"mix_id: NodeId\",\n AVG(s.reliability) as \"value: f32\"\n FROM\n mixnode_details d\n JOIN\n mixnode_status s on d.id = s.mixnode_details_id\n WHERE\n timestamp >= ? AND\n timestamp <= ?\n GROUP BY 1\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "mix_id: NodeId",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "value: f32",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
false,
|
||||
true
|
||||
]
|
||||
},
|
||||
"hash": "c19e1b3768bf2929407599e6e8783ead09f4d7319b7997fa2a9bb628f9404166"
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "SELECT DISTINCT calculation_method FROM simulated_reward_epochs WHERE epoch_id = ?",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "calculation_method",
|
||||
"ordinal": 0,
|
||||
"type_info": "Text"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "c9796e61c49a29ebd42dec46fb047f7a7e2f80aa4db4f963146cf56864a62347"
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id as \"id!\", simulated_epoch_id as \"simulated_epoch_id!\", node_id as \"node_id!: NodeId\", \n node_type as \"node_type!\", identity_key, reliability_score as \"reliability_score!\", \n positive_samples as \"positive_samples!: u32\", negative_samples as \"negative_samples!: u32\", \n work_factor, calculation_method as \"calculation_method!\", calculated_at as \"calculated_at!\"\n FROM simulated_node_performance\n WHERE simulated_epoch_id = ? AND calculation_method = ?\n ORDER BY node_id\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "simulated_epoch_id!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_id!: NodeId",
|
||||
"ordinal": 2,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "node_type!",
|
||||
"ordinal": 3,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "identity_key",
|
||||
"ordinal": 4,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "reliability_score!",
|
||||
"ordinal": 5,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "positive_samples!: u32",
|
||||
"ordinal": 6,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "negative_samples!: u32",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "work_factor",
|
||||
"ordinal": 8,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 9,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "calculated_at!",
|
||||
"ordinal": 10,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 2
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "d76e131fff79978284f31509e70d42d20ea2e95e5a2f2d574d33ad8d2a7f2a19"
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
{
|
||||
"db_name": "SQLite",
|
||||
"query": "\n SELECT id as \"id!\", simulated_epoch_id as \"simulated_epoch_id!\", \n calculation_method as \"calculation_method!\", total_routes_analyzed as \"total_routes_analyzed!: u32\", \n successful_routes as \"successful_routes!: u32\", failed_routes as \"failed_routes!: u32\", \n average_route_reliability, time_window_hours as \"time_window_hours!: u32\", \n analysis_parameters, calculated_at as \"calculated_at!\"\n FROM simulated_route_analysis\n WHERE simulated_epoch_id = ?\n ORDER BY calculation_method\n ",
|
||||
"describe": {
|
||||
"columns": [
|
||||
{
|
||||
"name": "id!",
|
||||
"ordinal": 0,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "simulated_epoch_id!",
|
||||
"ordinal": 1,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "calculation_method!",
|
||||
"ordinal": 2,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "total_routes_analyzed!: u32",
|
||||
"ordinal": 3,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "successful_routes!: u32",
|
||||
"ordinal": 4,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "failed_routes!: u32",
|
||||
"ordinal": 5,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "average_route_reliability",
|
||||
"ordinal": 6,
|
||||
"type_info": "Float"
|
||||
},
|
||||
{
|
||||
"name": "time_window_hours!: u32",
|
||||
"ordinal": 7,
|
||||
"type_info": "Int64"
|
||||
},
|
||||
{
|
||||
"name": "analysis_parameters",
|
||||
"ordinal": 8,
|
||||
"type_info": "Text"
|
||||
},
|
||||
{
|
||||
"name": "calculated_at!",
|
||||
"ordinal": 9,
|
||||
"type_info": "Int64"
|
||||
}
|
||||
],
|
||||
"parameters": {
|
||||
"Right": 1
|
||||
},
|
||||
"nullable": [
|
||||
true,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
true,
|
||||
false
|
||||
]
|
||||
},
|
||||
"hash": "db2b71d1dd33022d5c960053d6a0f5d7ccf52de6775d4f57744d1401d44fee62"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user