Only this pageAll pages
Powered by GitBook
1 of 73

Threshold Network Docs

Loading...

Applications

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Governance

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Staking & Running a Node

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

App Development

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Extras

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Installation

A tBTC v2 node can be set up using either a docker or binary installation.

Initial Protocol Loan

The Initial Protocol Loan (IPL) is a debt issued against the protocol itself in order to fund the stability pool. Even though it's technically debt, it does not in itself make the protocol a fractional reserve because all funds are accounted for.

How it works

thUSD is minted by the PCV and deposited into the stability pool. A freeze on withdraw is initiated until debt is fully repaid. At any time, the Threshold DAO can initiate a withdraw, which will destruct the debt and withdraw exceeds. If the PCV for some reason has less than the debt available, withdraw is denied.

Profits from usage of the protocol (loan interest, redemption fee, etc) accrues into the PCV, so in an event where there are less funds than debt the protocol first has to earn back the missing funds.

Benefits of the hybrid PCV + IPL model:

  • Bootstrap stability pool for free

  • No need for LQTY token = all profits accrue directly to the PCV

  • Immediate surplus on first loan drawn / liquidation

  • Predictability and (once debt is repaid) high resilience against Black Swans

  • No idle capital (it doesn't "really" exist)

Disadvantages

  • Higher risk of under-collateralization during the initial stages

  • Poor management of PCV could result in not enough funds in the stability pool

Each liquidation that occurs will draw against the stability pool and result in ~10% profit to the stability pool. This also means that the price can drop up to 10% after a liquidation before the stability pool is at risk of losing money on the liquidation. Our integration with ensures that liquidated tBTC is automatically converted back to thUSD and re-deposited into the stability pool. Under normal circumstances and without other factors, it is expected that the balance of thUSD in the pool will grow over time.

But there can be Black Swan events, large drops in the price of BTC in a short period of time or liquidity issues that results in a loss, even at ~10% profit. This is a risk of the protocol becoming undercollateralized, but the same issue would apply even without debt (stability pool not being profitable). The protocol is created to be sustainable, so these types of rare events will be averaged out. In addition, all income streams from Threshold USD also ends up in the PCV which further decrease the risk of undercollaterization.

The undercollaterialization is mostly a concern during the initial bootstrapping phase. As interest accrue and repay the initial debt, the funds in the stability pool will be replaced by fully owned PVC, thus eliminating this disadvantage.

Upgrade NU & KEEP to T

NU and KEEP tokens can be upgraded to T tokens via the Vending Machine contracts. As decided by the NU and KEEP communities in the final merge proposal, the conversion ratio for each token is based on the total supply rather than price. The final total supply of NU is ~1,380,688,920 and the total supply of KEEP is ~940,795,010.

As a result, the token factors are:

  • 1 NU: ~3.26 T

  • 1 KEEP: ~4.78 T

Token upgrades can be performed via the Threshold Dashboard which interfaces directly with the Vending Machine smart contracts.

Staked Token Delegation

How to delegate staked T tokens

Stakers on Threshold can delegate their stake weights to themselves or a third party for voting on governance proposals.

1. Go to

2. Connect your wallet

3. Enter the delegate address - once an address is entered, a “Delegate” button will appear

4. Click "Delegate" and sign the transaction.

Self-Managed

nucypher-ops is an ansible script that automates setup and configuration of a PRE node.

A guide for to setup and configure the tBTC v2 client.

PRE node setup with nucypher-ops

nucypher-ops setup guide

tBTC v2 Client Setup

tBTC v2 Client Setup

About the risk

B.Protocol
NU->T Upgrade
Keep->T Upgrade

Delegation is accomplished via an on-chain transaction which costs ETH gas.

https://stake.nucypher.network/manage/delegate
Enter Delegate Address
Delegate Button

Conditions-Based Decryption (CBD)

Threshold Application – underlying technology

Conditions-Based Decryption (CBD) is one of two technologies underpinning the Threshold Access Control service, the other being Proxy Re-Encryption. The vast majority of developers will only require CBD technology to provably protect their users' data, and we recommend that all developers start here – by familiarizing themselves with CBD.

In broad terms, CBD enables the users of adopting applications to specify conditions for accessing their encrypted data. If those conditions are not fulfilled – which means formal verification by a cohort of nodes from the Threshold network – then the data remain entirely unreadable to anyone besides the original data owner/encryptor. However, if the predefined conditions are provably satisfied, then the data requester gains decryption rights.

Threshold Decryption

Under the hood, CBD involves splitting a joint secret – a decryption key – into multiples shares and distributing those among authorized and collateralized node operators (stakers in the Threshold network). A minimum number – a threshold – of those operators holding the key shares must be online and actively participate in partial decryptions. These are subsequently combined on the requester's client to reconstruct the original plaintext data.

Conditionality

A range of access condition types can be defined by the data owner. For example:

  • EVM-based e.g. Does the requester own a given NFT?

  • RPC-driven e.g. Does the requester have at least X amount of a given token in their wallet?

  • Time-based e.g. Has a predefined period elapsed, after which requests will be ignored?

These conditions are also composable and can be combined in any logical sequence or decision tree.

Conditions are 'attached' on a per-ciphertext basis. In other words, each and every payload, message or bit can be access-restricted by a unique set of specified conditions. In most situations, condition sets will be automatically reused until the end-user proactively configures them – for example, in order to remove an address from continuing to access the messages in a group chat.

Conditions Verification

Currently, requesters prove their association with condition fulfillment – i.e. their right to receive a threshold number of decrypting shares – by signing a transaction that verifies their ownership of a given Ethereum wallet. That wallet is checked for fulfillment of the specific condition – e.g. owning an NFT in order to access a DAO's knowledge base.

This signature can be cached by the application for a use case-appropriate period of time, such that the user does not have to repeatedly re-sign for access later. However, verification still takes place in the background – for example, if a wallet address is removed from an NFT-gated group-chat by dint of changing the access-granting NFT, they will immediately be unable to see new messages. The cached signature will not give them access any longer than is specified by the data owner/encryptor.

Network Parameterization

CBD is fully decentralized. Therefore, developers have the option to tweak certain network parameters, which affect the collusion-resistance, redundancy, latency and (in future versions) cost of using CBD. For example:

  • The number of decrypting shares n

  • The frequency and/or prompt for resampling a new cohort from the node array

  • The 'hard-coded' node address that always feature in the cohort

This optionality can also be surfaced for end-users – for example, in the form of 'packages' that they might choose between, accommodating their risk and cost preferences . A guide on best practices for choosing/surfacing network parameters will be released soon.

Vote Delegation

To participate in DAO governance, stakers or token holders must set a governance delegate address. Vote delegation is the process of granting a delegate the power to vote on your behalf, using your voting weight, on DAO governance issues. The delegate can be yourself (self-delegation) or a third party. A configured delegate can be changed or revoked at any time.

Delegation never involves the transfer of custody of assets but rather just the vote weight those assets represent in the Threshold DAO.

Third-Party Delegation

Third-party delegates are volunteers who actively participate in Threshold governance and wish to grow their influence over critical DAO decisions. Delegates provide ETH addresses to which other Threshold token holders and Threshold stakers can delegate their vote weight. Third-party delegates are subsequently responsible for voting on Threshold governance proposals with this vote weight that others have assigned to them.

Community members who are unsure or uninterested in governance and do not want to actively participate in proposals, discussions, and voting, can instead delegate to active DAO members who have demonstrated a commitment to Threshold. Delegating their vote allows token holders and stakers to have an indirect say in the DAO without being involved in day-to-day governance activities.

Community members interested in serving as delegates can self-nominate here.

There is no compensation for third-party delegate contribution to governance.

The process for delegating liquid tokens and delegating staked tokens is distinct, and each are explained in the following subsections. It's not currently possible to delegate tokens deposited as LP in AMM pools (e.g. Curve), although this is an area for future improvement.

Running a Node

Get involved in staking the Threshold Network

Have what it takes to run a node of your own?

Click here for a guide on how to setup your own PRE node.

Click here to learn how to setup a tBTC v2 node.

Please be aware that running a node is not an easy task and requires technical skill and commitment to maintaining node uptime and availability.

Prefer staking with Professional Staking Providers instead?

Click here to see a list of professional grade staking providers.

Staking Providers have not been vetted or endorsed by Threshold. Use your judgement when selecting a provider.

Contribution

How to make edits

Refer to the following documentation here: https://docs.gitbook.com/

To contribute to Threshold documentation, the best place to start is to join the Discord. You can ask questions there and help contribute to documentation. Join here: http://discord.gg/threshold

CBD References

Trust Packages

This page is under construction.

PRE Mainnet Version

This page is under construction.

Operator Account

Prepare your machine to install the tBTC v2 staking client

The client requires an Ethereum Key File of an Operator Account to connect to the Ethereum chain. This account is created in a subsequent step using Geth (GoEthereum).

The Ethereum Key File is expected to be encrypted with a password. The password has to be provided in a prompt after the client starts or configured as a KEEP_ETHEREUM_PASSWORD environment variable.

The Operator Account has to maintain a positive Ether balance at all times. We strongly advise you monitor the account and top-up when its balance gets below 0,5 Ether.

Please do NOT reuse an operator account that is being used for PRE or other applications.

Install Geth (GoEthereum)

To create a new Ethereum account, install Geth (GoEthereum) and create a new account using the command below. This account will subsequently be referred to as the Operator Account.

When prompted, provide a password to protect the operator key file.

Use a password manager to generate a strong password and store it safely. It will be needed again during setup.

Avoid passwords that contain the following characters: ', ", `, $ These characters may be interpreted as part of the configuration which can lead to undesirable outcomes that may be extremely time intensive to correct.

Once the process completes, your public key will be displayed. Take note of your Operator Account public key.

DO NOT LOSE THE PASSWORD TO THE OPERATOR ACCOUNT.

Funding your Operator Account

Your Operator Account will need to maintain a positive ETH balance at all times to ensure proper operation and availability of your tBTC v2 node.

Frequently Asked Questions

Find answers to some of the most commonly asked questions here.

Errors in Logs or Console

Certain errors may be reported by your node during the early stages of Chaosnet and the tBTC 2 launch. See a sample below:

2022-10-10T18:30:42.571Z    WARN    keep-beacon    beacon/node.go:78    selecting group not possible: [cannot select group in the sortition pool: [got error [execution reverted: Sortition pool unlocked] while resolving original error [execution reverted: Sortition pool unlocked]]]    {"seed": "0x29c60250c292e108e6abf4dcc76cb161d8ae8e803c4d4419eaff6e97f514b080"}

This warning is normal and may happen on chaosnet. It will disappear and reappear periodically.

This is expected during this stage of the chaosnet. When the pool is locked, new operators cannot join but sortition (selecting operators from the pool) is possible. When the pool is unlocked, new operators can join but the sortition is not possible. Once the first set of beta operators is registered, the pool will get locked for some time to allow the sortition. After some time, when another set of beta operators are added, the pool will be unlocked again.

geth account new --keystore ./operator-key

B. Protocol

B. Protocol is a third-party decentralized backstop liquidity protocol aiming to make lending platforms more stable.

The problem

In Liquity Protocol there's a concept called "Stability Pool". The purpose of the stability pool is to purchase liquidated collateral (tBTC) at a discount by using Threshold USD (thUSD) as payment.

Users deposits thUSD into the stability pool and their funds are pooled with other depositors. If a pool consist of 900,000 thUSD and a user deposits 100,000 thUSD, that user is entitled to 10% of the collateral seized.

The issue with stability pool is that as liquidations occurs, thUSD is traded to tBTC, but never back to thUSD. If left untouched, the pool will eventually only consist of tBTC and no further liquidations can take place against the pool. Furthermore, by acquiring tBTC collateral, the value for depositors in the pool becomes subject to the price of BTC.

Users are therefore incentivized to quickly sell of the tBTC for thUSD to avoid taking on price risk, but in Liquity, this process is manual. Users have to manually open the UI and withdraw tBTC, sell it for thUSD and then re-deposit the thUSD. This is both a time consuming and gas costly operation, best suited for whales and users with their own bots.

Even worse, a DAO cannot realistically operate in the current stability pool model because voting to move and sell funds becomes impractical, costly and slow.

In order to establish a non-human, algorithmic, fully automated solution to compound profits we look to B.Protocol.

Instead of depositing directly into the stability pool, we can use B.Protocol's wrapping smart contract interface, which deposits the thUSD to the stability pool on behalf of all users (and the PCV).

Once liquidation happens, the discounted tBTC is automatically offered for sale by B.Protocol’s Backstop AMM (B.AMM). This is done according to a deterministic formula, which takes into account the current tBTC and thUSD inventory, and the current BTC-USD market price (which is taken from Chainlink). Whenever the sale occurs, the smart contract deposits the returned thUSD back to the stability pool.

If there are no takers for the offer on the B.AMM, Gelato Keepers will arbitrage through popular DEX pairs to fulfill the order.

This way the PCV becomes self-sufficient and able to operate indefinitely without outside interference.

B.Protocol Team will deploy a non-upgradeable pool that is Threshold USD compatible.

The pool will be using Chainlink BTC/USD oracle (same as Threshold USD).

The pool will not deploy idle funds in any yield farming applications.

Threshold USD PCV will whitelist the smart contract for the B.Protocol pool and the Threshold Network DAO (T DAO) will vote to initiate a deposit of thUSD to the B.Protocol pool. The deposit is moved from the PCV smart contract to B.Protocol and can be moved back to the PCV at any time, without limitation, as long as the T DAO votes to do so. If there is tBTC in the pool at the time of withdraw, the tBTC may also be transferred back to the PCV.

The B.AMM contract's "A" parameter ("A" is amplification factor​​​, higher value means less slippage) is operated through a co-ownership between T DAO and B.Protocol, where B.Protocol propose "A" value and T DAO can approve or reject.

The discount rate is set to 4% on deployment, but the max rate should be configurable up to 10% in a joint governance mechanism between T DAO & B.Protocol.

All profits from liquidations will auto-compound within the B. Protocol pool.

Keeper

As a backup mechanism, B. Protocol will deploy that can route.

Example:​

tBTC -> WBTC -> USDC -> thUSD

In this example funds could be routed through Curve Finance pools (both stablecoin and wrapped bitcoin pools).

In addition, funds could be routed through uniswap (v2 or v3) WBTC or USDC paired pools.

Other routes could be:

tBTC -> WBTC -> DAI -> thUSD tBTC -> WBTC -> USDT -> thUSD

The keeper is funded by the DAO and any profit it makes is distributed back to the PCV.

​

Governance Process

Lifecycle of a successful proposal

  1. Forum discussion: A Threshold community member posts a potential proposal on the Threshold governance forums. Community members who post the initial proposal are encouraged to get active in Meta governance discussions within the community on forums and in Discord to earn support for the proposal. There is no minimum token threshold required to create a new proposal on the forums. Community mods reserve the right to moderate spam proposals during this stage by deleting the proposal from the forums.

  2. Temperature Check: Once a potential proposal has enough traction and discussion within the community, it can proceed for a temperature check via an off-chain snapshot. If a proposal receives majority support during the temperature check, it is eligible to move onto the next step.

  3. Proposal Creation: A community member holding enough vote weight (at least 0.25% of T total supply) submits the proposal on-chain. The proposal enters a 2-day delay period before voting officially begins.

  4. Vote Period: Proposal voting remains open for 10 days. If the proposal passes with enough quorum (at least 1.5% of T total supply), it moves onto the next step; if the proposal fails, it is canceled. Creators and supporters of the proposal may bring a modified proposal forward again but it must be sufficiently different and pass requirements outlined in previous steps.

  5. Timelock Period: Once a proposal is approved, the Governor Bravo smart contracts include an additional timelock delay of 2 days. Anyone can interact with the Governor Bravo smart contracts to queue an approved proposal into the Timelock contract.

  6. Execution: After the timelock delay, anyone can execute an approved proposal.

  • Council vetos: During the on-chain phase, the Elected Council can veto any proposal. This is intended to be an extra security mechanism in the event that a dangerous proposal passes.

  • Late quorum prevention: The 10-days voting period is automatically extended when quorum is reached late, to prevent governance attacks that try to reach quorum at the last minute; in case a proposal reaches quorum less than 2 days before the deadline, the proposal deadline is extended for 2 more days from the moment the quorum was reached.

  • Off-chain proposals: Some proposals to not imply any on-chain action (e.g. Council and Guild elections). In these cases, there is only a Snapshot vote, with no associated on-chain proposal).

Threshold Access Control

Trust-minimized Access Control

Threshold Access Control enables end-to-end encrypted data sharing and communication without the need to trust a centralized authority. It is the only access control layer available to Web3 developers that has already achieved true decentralization through a live and well-collateralized network, with sensitive cryptographic operations disassembled and distributed across ~250 independently operated servers.

End-users of applications which have integrated Threshold Access Control enjoy the following features & benefits:

  • End-to-end encryption for everything. Built on the privacy-for-everyone principles of popular end-to-end encrypted messengers but applicable to a far wider set of use cases, including private NFTs, connected vehicles, DBaaS, live-streaming, private DAO group chats, and much more.

  • Trust-minimization via cryptography and true decentralization. Key management, condition verification and ciphertext re-encryption are operationally distributed across a geographically diverse array of machines/servers, operated by economically independent individuals and commercial entities.

  • Powerful, per-ciphertext conditionality. Future access to data can be contingent on the fulfillment of nearly any predefined condition, and those conditions attached to any granularity of data payload (e.g. a single message or an entire table).

  • Flexible condition composability. Conditions of all types can be mixed-and-matched using logical operators and flexible prefix notation into virtually any desired combination.

  • Tunable collusion-resistance, redundancy & latency. Developers have full control over the cohort(s) of node operators which manage access to a given data payload, user base or entire application. These security parameters can also be packaged into simpler user-facing optionality for custom risk preferences.

  • Highly incentivized uptime. Threshold Network's multi-app model strongly incentivizes node operators to provision service to tBTC, and its strict availability requirements. Threshold Access Control 'piggybacks' on tBTC uptime, reliability and technical competence.

  • Optional: keypair-only decryption. If even stricter security guarantees are required, and data recipients' public keys are known in advance, developers may opt for end-user data to be re-encrypted by node operators such that they are only decryptable by pre-designated clients.

The Threshold Access Control service is built on two distinct but interwoven technologies; Conditions-Based Decryption (CBD) and Proxy Re-Encryption (PRE). Both offer trust-minimized end-to-end encryption and access control is executed by the same decentralized array of nodes. There are some trade-offs between (explicit) security and access condition customization, which are explored in the section.

Note for Threshold stakers: the up-and-running 'PRE app' will eventually be renamed to encompass the broader Threshold Access Control service, and will also acquire new functionality via the addition of CBD technology. This will require a DAO-driven upgrade but will not fundamentally change the operational requirements or compensation.

Liquid Token Delegation

How to delegate liquid T tokens

Liquid T holders who aren't staking on Threshold can delegate their token weights to themselves or a third party for voting on governance proposals.

Delegation is accomplished via an on-chain transaction which costs ETH gas.

1. Go to https://boardroom.io/threshold

2. Connect your wallet

3. Click "Set Up Delegation"

Set Up Delegation

4. Select your "Delegation Type" - either to yourself or a third party.

Choose Delegation Type

5. Enter "Delegate Address" and click on "Delegate Votes"

Delegate Votes

6. Sign the transaction

CLI Options

Review available CLI Options below.

$ keep-client start --help
Starts the Keep Client in the foreground

Usage:
  keep-client start [flags]

Flags:
      --ethereum.url string                        WS connection URL for Ethereum client.
      --ethereum.keyFile string                    The local filesystem path to Keep operator account keyfile.
      --ethereum.miningCheckInterval duration      The time interval in seconds in which transaction mining status is checked. If the transaction is not mined within this time, the gas price is increased and transaction is resubmitted. (default 1m0s)
      --ethereum.maxGasFeeCap wei                  The maximum gas fee the client is willing to pay for the transaction to be mined. If reached, no resubmission attempts are performed. (default 500 gwei)
      --ethereum.requestPerSecondLimit int         Request per second limit for all types of Ethereum client requests. (default 150)
      --ethereum.concurrencyLimit int              The maximum number of concurrent requests which can be executed against Ethereum client. (default 30)
      --ethereum.balanceAlertThreshold wei         The minimum balance of operator account below which client starts reporting errors in logs. (default 500000000 gwei)
      --network.bootstrap                          Run the client in bootstrap mode.
      --network.peers strings                      Addresses of the network bootstrap nodes.
  -p, --network.port int                           Keep client listening port. (default 3919)
      --network.announcedAddresses strings         Overwrites the default Keep client address announced in the network. Should be used for NAT or when more advanced firewall rules are applied.
      --network.disseminationTime int              Specifies courtesy message dissemination time in seconds for topics the node is not subscribed to. Should be used only on selected bootstrap nodes. (0 = none)
      --storage.dir string                         Location to store the Keep client key shares and other sensitive data.
      --clientInfo.port int                        Client Info HTTP server listening port. (default 9601)
      --clientInfo.networkMetricsTick duration     Client Info network metrics check tick in seconds. (default 1m0s)
      --clientInfo.ethereumMetricsTick duration    Client info Ethereum metrics check tick in seconds. (default 10m0s)
      --tbtc.preParamsPoolSize int                 tECDSA pre-parameters pool size. (default 1000)
      --tbtc.preParamsGenerationTimeout duration   tECDSA pre-parameters generation timeout. (default 2m0s)
      --tbtc.preParamsGenerationDelay duration     tECDSA pre-parameters generation delay. (default 10s)
      --tbtc.preParamsGenerationConcurrency int    tECDSA pre-parameters generation concurrency. (default 1)
      --tbtc.keyGenerationConcurrency int          tECDSA key generation concurrency. (default number of cores)
      --developer.bridgeAddress string             Address of the Bridge smart contract
      --developer.randomBeaconAddress string       Address of the RandomBeacon smart contract
      --developer.tokenStakingAddress string       Address of the TokenStaking smart contract
      --developer.walletRegistryAddress string     Address of the WalletRegistry smart contract

Global Flags:
  -c, --config string   Path to the configuration file. Supported formats: TOML, YAML, JSON.
      --developer       Developer network
      --goerli          Görli network
      --mainnet         Mainnet network

Environment variables:
    KEEP_ETHEREUM_PASSWORD    Password for Keep operator account keyfile decryption.
    LOG_LEVEL                 Space-delimited set of log level directives; set to "help" for help.

Advanced Options

Advanced configuration options and tBTC v2 staking client options

Configuration options for logging

Alternative application authorization methods to using the Threshold Dashboard.

Application configuration can be stored in a file and passed to the application with the --config flag.

Client information exposed by the tBTC v2 staking client.

Goerli Testnet

Here you'll find the Goerli testnet version of the Threshold dapp.

Goerli Testnet - Threshold Dashboard

The Path to Permissionlessness

The system was designed from the outset to be fully permissionless - anyone with the minimum amount of T stake, could run a node and have a of being a custodian.

In order to effectively ship the product, we launched with a permissioned set of Signers, as well as permissioned sets of Guardians and Minters. This document will explain the ideas behind those changes and what we're doing about it going forward.

  • We will make the Signer set permissionless after we have solved some technical obstacles.

  • Minters and Guardians are here to stay, but will not be the only way to mint.

🙋♀ 🙋♀ Guilds

Additionally to the DAO governance bodies, there are three community-led guilds with different focus areas: the Marketing Guild, the Integrations Guild, and the Treasury Guild. Each guild is managed by an elected committee and holds regular, rotating elections.

Join a guild (via 's #dao-contribute channel) and work together with other Threshold DAO members based on your interests and expertise!

The is responsible for effectively managing the Threshold DAO treasury. This includes growing Protocol Owned Liquidity (POL), researching / implementing best practice treasury management strategies, executing ecosystem liquidity incentives, diversifying the treasury, etc.

The core mission of the is to build successful, synergistic and long-lasting relationships with other protocols, DAOs and external organizations.

The is responsible for general Threshold marketing, growing our network of contributors, onboarding new members to the Threshold DAO, educating people about the Threshold’s value, services and use cases, and more.

Trust Assumptions

As the only genuinely decentralized access control service on the market, Threshold Access Control may also claim to be the most 'trustless' solution available to Web3 app buidlers – or indeed, available to any developer seeking an unambiguous departure from the exploitative Web 2.0 trust paradigm.

Nevertheless, there is no such thing as a third-party integration that imposes zero additional trust burden onto an application's end-users. Rather, when choosing infrastructural technology, it is the nature and texture of the trust burden(s) – or the 'trust assumptions' – that truly matter.

In the case of Threshold Access Control, the trust assumptions are: non-binary – i.e. not reducible to 'trustless' or 'trustful'.

non-static – i.e. they evolve over time based on in-protocol features and exogeneous phenomena. tunable – i.e. adopting developers may select from a range of explicit trust assumptions on behalf of their user base, and/or surface that optionality for end-users to choose themselves.

This section serves to explain the implicit and explicit trust assumptions that are baked into Threshold Access Control, for the and versions. These assumptions are synthesized and exposed to the vast majority of adopting developers in the form of pre-configured

Cohort

When creating a new cohort, the configuration must include threshold, shares, and porterUri. We also make available the parameters include and exclude which can be used to filter particular Nodes.

A cohort can be serialized to a JSON object so that it can be stored and re-used at a later time.

Similarly, we can read in a valid JSON object to build a new Cohort.

Glossary

Threshold Network Lingo

Term
Definition

CBD Proof-of-Concept Version

The Proof-of-Concept version exists to help developers familiarize themselves with the SDK, API and other architectural/design choices, ahead of the Mainnet version release in Q2 2023.. It is not intended to be utilized as a trust-minimized service. Hence, the trust assumptions are strictly worse than the Mainnet version. One can consider the following limitations to be appended on top of the Mainnet trust :

  1. In the absence of a DKG component, the encryptor (or 'Alice') retains permanent decryption power, regardless of their condition fulfillment later – e.g. transferring the corresponding NFT out of their wallet.

  2. Conditions can technically be 'stripped' from ciphertexts by a sophisticated user, which would enable them to maliciously gain decryption rights by presenting a ciphertext with no attached access conditionality.

Threshold Access Control

Use Threshold Access Control for end-to-end encrypted, end-to-end decentralized data sharing and communication.

-> See in the Fundamentals section for an overview of the over-arching concepts and value propositions.

There are multiple products and versions under the umbrella of 'Threshold Access Control':

  • Conditions-Based Decryption, Proof-of-Concept Use this version to familiarize yourself with the SDK, API and developer-facing configuration/parametrization. Get started .

Get Started (PRE Mainnet)

External documentation and examples

trust assumptions
Logging
Alternatives to Dashboard
Config File
CLI Options
Client Info

Treasury Guild

Integrations Guild

Marketing Guild

Discord
Threshold Treasury Guild
Threshold Integrations Guild
Threshold Marketing Guild

The node array managing decryption fragments – and validating condition (non/)fulfillment – are running on testnet, are operated primarily by NuCypher team-members, and are not subject to a cryptoeconomic protocol or a requirement to deposit/risk collateral.

Note that these three limitations will be addressed in the CBD Mainnet version. Upgrading from this version to the Mainnet version involves entirely replacing the underlying cryptosystem, which means all data encrypted via the Proof-of-Concept will have to be (downloaded and) encrypted again from plaintext utilizing the new cryptography.

model
Conditions-Based Decryption, Mainnet version This version is under intense development and will be released in early Q2 2022. Learn about the vision for the product here and underlying trust model here.
  • Proxy Re-encryption, Mainnet version This product and version is currently live on the Threshold Mainnet and has been battle-tested for over 2 years. Learn the fundamentals of the PRE offering here and get started building with PRE here.

  • Threshold Access Control
    here

    This page is under construction. In the meantime use the Read-The-Docs and Github Documentation linked below.

    https://github.com/nucypher/nucypher-ts
    https://github.com/nucypher/nucypher-ts-demo
    https://docs.nucypher.com/en/latest/application_development/getting_started.html#

    B.Protocol to the rescue

    Integration details

    Gelato keepers

    Deviations in the proposal lifecycle

    The lifecycle of a successful proposal

    Authorizer

    An ethereum address appointed by an owner to authorize applications on behalf of the owner. An application must be approved by the authorizer before the staking provider is eligible to participate.

    Beneficiary

    An ethereum address where the rewards for participation are sent, earned by the staking provider, on behalf of the owner. A beneficiary doesn’t sign or publish any protocol-relevant transactions, but any currency or tokens earned by the staking provider will be transferred to the beneficiary.

    Delegated stake

    An owner’s staked tokens, delegated to the staking provider by the owner. Delegation enables token owners to have their wallets offline and their stake operated by staking providers on their behalf.

    Application

    An external smart contract or a set of smart contracts utilizing functionalities offered by Threshold Network. Example applications are: random beacon, proxy re-encryption, and tBTC. Applications authorized for the given staking provider are eligible to slash the stake delegated to that staking provider.

    Threshold Cryptography

    Threshold cryptography is a revolutionary technology that distributes sensitive operations across multiple independent entities – like nodes in a network – and requires a threshold, or minimum number of those entities to cooperate for the operation to be successful.

    Staking Provider

    An ethereum address of a party authorized to operate in the network on behalf of a given owner. The staking provider handles the everyday operations on the delegated stake without actually owning the staked tokens. A staking provider can not simply transfer away delegated tokens, however, it should be noted that the staking provider’s misbehavior may result in slashing tokens and thus the entire staked amount is indeed at stake.

    .

    Note that many projects in the Web3 infrastructure space seek to obscure this reality by loosely labelling their solution as 'decentralized', but fail to explain precisely what the trust implications are in practice. Beware of ambiguity!

    Mainnet
    Proof-of-Concept
    Trust Packages

    Cohort.create

    Cohort.toJSON

    Cohort.fromJSON

    Implementing Revocation via Smart Contract

    It is possible to implement Revocation using Conditions that rely on a function call to a Custom Smart Contract. This allows the handling of revocation to be decentralized and transparent. Here is an example of a smart contract (not suitable for production):

    pragma solidity 0.8.7;
    
    contract Revocation {
    
        mapping(address => bool) public isRevoked;
    
        function revoke(address user) public {
            isRevoked[user] = true;
        }
    
        function unRevoke(address user) public {
            isRevoked[user] = false;
        }
    }

    And the associated Condition:

    const revocationCondition = {
      contractAddress: 'DEPLOYED_CONTRACT_ADDRESS',
      method: 'isRevoked',
      parameters: [':userAddress'],
      functionAbi: {
        inputs: [
          {
            internalType: 'address',
            name: '',
            type: 'address',
          },
        ],
        name: 'isRevoked',
        outputs: [
          {
            internalType: 'bool',
            name: '',
            type: 'bool',
          },
        ],
        stateMutability: 'view',
        type: 'function',
      },
      chain: 'ethereum',
      returnValueTest: {
        comparator: '==',
        value: false,
      },
    };

    The condition we have defined calls the isRevoked function of the smart contract and passes the user's address. If the call returns false (not revoked, i.e. granted), then decryption will occur. If the call returns true (is revoked), then decryption will fail.

    const config = {
      threshold: 3,
      shares: 5,
      porterUri: 'https://porter-ibex.nucypher.community',
    };
    const newCohort = await Cohort.create(config, (include = []), (exclude = []));
    const cohortJSON = newCohort.toJSON();
    console.log(cohortJSON);
    // {
    //     "ursulaAddresses": [
    //         "0x5cf1703a1c99a4b42eb056535840e93118177232",
    //         "0x7fff551249d223f723557a96a0e1a469c79cc934",
    //         "0x9c7c824239d3159327024459ad69bb215859bd25"
    //     ],
    //     "threshold": 2,
    //     "shares": 3,
    //     "porterUri": "https://porter-ibex.nucypher.community"
    // }
    const importedCohort = Cohort.fromJSON(cohortJSON);
    console.log(importedCohort);
    // Cohort {
    //     ursulaAddresses: [
    //     '0x5cf1703a1c99a4b42eb056535840e93118177232',
    //     '0x7fff551249d223f723557a96a0e1a469c79cc934',
    //     '0x9c7c824239d3159327024459ad69bb215859bd25'
    //     ],
    //     configuration: {
    //     threshold: 2,
    //     shares: 3,
    //     porterUri: 'https://porter-ibex.nucypher.community'
    //     }
    // }
    To select the 100 Signers for a wallet, we choose from the list of Beta Stakers instead of all Stakers. This decision was made for several reasons:
    1. During the early days of the system; the testnet and chaosnet phases, it is important to ensure that the Stakers are available to help test changes and quickly respond to critical bugs. Having direct access to individuals known to the development team is critical in this context.

    2. The underlying signature algorithm, GG18, cannot identify misbehaving signers.

    The point about GG18 is crucial. Without being able to identify misbehaving Stakers, a small, sophisticated, malicious minority can make it difficult to sign Bitcoin transactions in a timely manner. If we were able to identify the misbehaving signers, we could exclude them directly from the signing process.

    Although alternative algorithms exist for identifying misbehaving signers, they are not yet viable for production use for one or more of the following reasons:

    • They are not yet production-ready codebases.

    • They are not open source.

    • They exist only as whitepapers.

    To address this issue, we have been developing a proof-of-concept for CGGMP and exploring FROST. Once we are confident in these areas, we will open up Custodianship to any staker running a node and staking the minimum amount of T. This will create a permissionless alternative to Optimistic Minting through the Guardians and Minters, albeit slightly slower.

    Optimistic Minting diagram for minting tBTC

    Guardians and Minters will remain permissioned indefinitely, as they are a set of high-trust public operators with their reputations on the line. If we were to make these lists permissionless, a malicious Minter could flood the system with fake minting requests for the Guardians to deal with, or a malicious Guardian could veto every proposed mint to halt growth.

    If a Guardian or Minter misbehaves, the Threshold DAO can vote to remove them.

    Sweeping option for minting tBTC

    Once sweeping is enabled and the Signers are permissionless, any deposit that all Minters refuse to approve or that a Guardian refuses to accept can still be minted every eight hours by the Signers. This ensures that the system remains resilient and able to handle situations in which a malicious actor attempts to disrupt the minting process.

    TL;DR

    Permissionless Custodianship

    proportional chance

    Guardians and Minters

    tBTC v2 Node Setup

    This document explains the basic installation and configuration for the tBTC v2 staking client.

    This document is intended for members of the community who would like to run their own tBTC v2 node.

    Please be aware that running a node is not an easy task and requires technical skill and commitment to maintaining node uptime and availability.

    Please review this document in its entirety prior to beginning setup of your node to familiarize yourself with the general setup process.

    Important Considerations

    The Threshold Network expects certain capabilities for each node running on the network. To help attain these capabilities consider the following criteria:

    • It is paramount that tBTC v2 nodes remain available to the Network. We strongly encourage a stable and redundant internet connection.

    • Equally important is machine uptime and reliability. A VPS is strongly recommended.

    • A connection to a production grade self-hosted or third party Ethereum node deployment.

    • Persistent and redundant storage that will survive a VM or container rotation, and a disk failure.

    • Each node running on the network requires a unique Ethereum Operator Account. The account has to maintain a positive Ether balance at all times.

    • Each node running on the network requires a unique IP address or a unique application port running under the same IP.

    Your operating environment will ultimately dictate what machine type to go with. This is particularly relevant if you’re running a containerized solution where multiple applications are sharing VM resources. The below types are sufficient for running one instance of the tBTC v2 Node.

    The preferred OS is Ubuntu.

    VPS Provider
    VPS Type

    A Keep Node requires a connection to a WebSocket Ethereum API. You should obtain a WS API URL from a service provider (e.g. , , ) or run your own Ethereum node (e.g. ).

    The client expects configuration options to be passed as CLI flags or specified in a . If you specify an option by using a parameter on the command line, it will override the value read from the configuration file.

    Client Info

    Client information exposed by the tBTC v2 staking client.

    The client exposes metrics and diagnostics on a configurable port (default: 9601) under /metrics and /diagnostics resources.

    The data can be consumed by Prometheus to monitor the state of a node.

    Metrics

    The client exposes the following metrics:

    • connected peers count,

    • connected bootstraps count,

    • Ethereum client connectivity status (if a simple read-only CALL can be executed).

    Metrics are enabled once the client starts. It is possible to customize the port at which metrics endpoint is exposed as well as the frequency with which the metrics are collected.

    Exposed metrics contain the value and timestamp at which they were collected.

    Example metrics endpoint call result:

    The client exposes the following diagnostics:

    • list of connected peers along with their network id and Ethereum operator address,

    • information about the client’s network id and Ethereum operator address.

    Diagnostics are enabled once the client starts. It is possible to customize the port at which diagnostics endpoint is exposed.

    Example diagnostics endpoint call result:

    Wallet Generation

    Wallets are created periodically based on governance. changes the time between wallets and reads it. The time between new wallets is held in walletCreationPeriod in number of seconds, so the current value of 1209600 represents 14 days. In order for the wallet to move funds, it produces signatures using a , requiring 51-of-100 Signers to cooperate.

    The 100 signers on each wallet are chosen with our , and the randomness is provided by the .

    The probability that a is chosen to be a Signer is equal to their percentage of the total TBTC Stake. Each Signer is chosen independently. The same Staker can be a signer on the same wallet multiple times. The same Staker can be a Signer on multiple wallets simultaneously.

    For simplicity, say there are only three Stakers: Alice, Bob, and Carol. Alice has 250M T, Bob has 400M T, and Carol has 350M T staked, so they own 25%, 40% and 35% of the stake respectively. That means, Alice has a 25% chance to be a Signer, Bob has a 40% chance, and Carol has a 35% chance. Each Signer is selected independently.

    Binary Installation

    This page will guide you through Binary setup steps.

    Download the client binary file, make sure you are in the correct directory.

    After the download completes, use the command below to display the contents of the folder:

    Extract the compressed file:

    To launch the tBTC v2 client, several configuration flags and environmental values need to be set. For simplicity, a bash script can be used rather than typing or pasting all the flags into the console.

    The following flags must be set at minimum:

    For a complete list of client commands and flags, see .

    To launch the client, execute the following:

    If everything is configured correctly, the client will request the password for the Operator Account. Supply the password and press Enter.

    n2-highcpu-2

    Self-hosted

    2 vCPU / 2 GB RAM / 1 GiB Persistent Storage

    AWS

    c5.large

    Azure

    F2s v2

    Recommended Machine Types

    While it is possible to run the client on a local machine, this is not recommended.

    Ethereum API

    Configuration

    Alchemy
    Infura
    Ankr
    Geth
    config file

    Google Cloud

    Diagnostics

    You should see the following shortly:

    Congratulations, your node is up and running.

    Choose either Docker installation OR Binary installation.

    Download the Binary

    You can save some time and prevent misspelling a file name by typing the first few letter of the file name and pressing the Tab key. This will autocomplete the file name. Be sure to verify the file name prior to pressing the enter key.

    Configure tBTC v2 Client

    CLI Options
    $ curl localhost:9601/metrics
    # TYPE connected_peers_count gauge
    connected_peers_count 108 1623235129569
    
    # TYPE connected_bootstrap_count gauge
    connected_bootstrap_count 10 1623235129569
    
    # TYPE eth_connectivity gauge
    eth_connectivity 1 1623235129789
    $ curl localhost:9601/diagnostics
    {
      "client_info" {
       "ethereum_address":"0xDcd4199e22d09248cA2583cBDD2759b2acD22381",
       "network_id":"16Uiu2HAkzYFHsqbwt64ZztWWK1hyeLntRNqWMYFiZjaKu1PZgikN"
      },
      "connected_peers": [
        {"ethereum_address":"0x3712C6fED51CECA83cA953f6FF3458f2339436b4","network_id":"16Uiu2HAkyYtzNoWuF3ULaA7RMfVAxvfQQ9YRvRT3TK4tXmuZtaWi"},
        {"ethereum_address":"0x4bFa10B1538E8E765E995688D8EEc39C717B6797","network_id":"16Uiu2HAm9d4MG4LNrwkFmugD2pX7frm6ZmA4vE3EFAEjk7yaoeLd"},
        {"ethereum_address":"0x650A9eD18Df873cad98C88dcaC8170531cAD2399","network_id":"16Uiu2HAkvjVWogUk2gq6VTNLQdFoSHXYpobJdZyuAYeoWD66e8BD"},
        ...
      ]
    }
    cd /home/keep
    wget https://github.com/keep-network/keep-core/releases/download/v2.0.0-m2/keep-client-mainnet-v2.0.0-m2-linux-amd64.tar.gz
    ls -la
    tar xzvf downloaded-file-name-here.tar.gz
    --ethereum.url "wss://mainnet-ETH-enpoint-here"
    --mainnet
    --storage.dir "/home/keep/storage"
    --ethereum.keyFile "/home/keep/config/UTC--Your-Operator-Key-Name"
    # to configure your node to use your machine's public IP
    --network.announcedAddresses "/ip4/your.ipv4.address.here/tcp/3919"
    # to configure your node to use DNS, provide your DNS in the following
    # format
    # /dns4/bootstrap-1.test.keep.network/tcp/3919
    
    ./keep-client start --ethereum.url "wss://mainnet-ETH-enpoint-here" --mainnet --storage.dir "/home/keep/storage" --ethereum.keyFile "/home/keep/config/UTC--Your-Operator-Key-Name" --network.announcedAddresses "/ip4/your.ipv4.address.here/tcp/3919"
    
    ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
    ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
      ▓▓▓▓▓▓    ▓▓▓▓▓▓▓▀    ▐▓▓▓▓▓▓    ▐▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
      ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀      ▐▓▓▓▓▓▓▄▄▄▄         ▓▓▓▓▓▓▄▄▄▄         ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
      ▓▓▓▓▓▓▓▓▓▓▓▓▓▀        ▐▓▓▓▓▓▓▓▓▓▓         ▓▓▓▓▓▓▓▓▓▓▌        ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
      ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄       ▐▓▓▓▓▓▓▀▀▀▀         ▓▓▓▓▓▓▀▀▀▀         ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
      ▓▓▓▓▓▓   ▀▓▓▓▓▓▓▄     ▐▓▓▓▓▓▓     ▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌
    ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓
    ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓
    
    Trust math, not hardware.
    	
    -----------------------------------------------------------------------------------
    | Keep Client Node                                                                |
    |                                                                                 |
    | Version: Version: v2.0.0-m1 (4d745f6d0)                                         |
    |                                                                                 |
    | Operator: 0x_your_operator_address                                              |
    |                                                                                 |
    | Port: 3919                                                                      |
    | IPs : /ip4/111.222.333.444/tcp/3919/ipfs/redacted                               |
    |                                                                                 |
    | Contracts:                                                                      |
    | RandomBeacon   : 0x5499f54b4A1CB4816eefCf78962040461be3D80b                     |
    | WalletRegistry : 0x46d52E41C2F300BC82217Ce22b920c34995204eb                     |
    | TokenStaking   : 0x01B67b1194C75264d06F808A921228a95C765dd7                     |
    -----------------------------------------------------------------------------------
    The Sortition Pool is more complex (because of heavy gas optimization), but reasoning about it could look like this: For each Signer, we're going to generate a random number between 1 and 100. Alice is the Signer if the number is in [1, 25]. Bob is the Signer if the number is in [26, 65]. Carol is the Signer if the number is in [66, 100]. For example, if our first random number is 33, our first Signer would be Bob. We can generate 100 random numbers: (75, 51, 13, 48, 36, 62, 46, 65, 97, 67...), and then use that to determine Signers: (Carol, Bob, Alice, Bob, Bob, Bob, Bob, Bob, Carol, Carol...). This example illustrates a few properties mentioned earlier:
    • Each Signer is selected independently. Whether or not Carol is the first signer has no influence on Carol being the second Signer.

    • The chance that you become a particular Signer is equal to your share of the Stake.

    If Carol has a 35% chance of being a particular Signer, what are chances that Carol has at least 51 of the 100 seats (and could control the wallet by herself)?

    The number of Signers that Carol controls on a wallet is modeled by the Binomial Distribution. From wikipedia:

    A Binomial distribution with parameters n and p is the discrete probability distribution of the number of successes in a sequence of n independent experiments, each asking a yes–no question, and each with its own Boolean-valued outcome: success (with probability p) or failure (with probability 1−p).

    This is exactly our situation! From Carol's perspective, there will be n=100 independent experiments, each asking a yes-no question (does this Signer belong to Carol), each with a 35% probability.

    That means we can use a Binomial Probability Calculator to answer our question:

    It's the last figure: "Cumulative probability: P(X>51)" that's relevant. That says there is a ~0.074% chance that Carol would have a controlling Share of any particular wallet.

    The next important question is "The probability that Carol controls a Wallet is low, but it only needs to happen once for things to be bad. What is the probability that she controls any wallet in the next 2 years?"

    A wallet is generated every 14 days, so over the next 2 years, the system would generate ~52 wallets. Each wallet has a 1 - 0.00074 = .99926 or 99.926% chance of not being controlled by Carol. That means we can exponentiate:

    Carol would have a ~3.8% chance of getting control of a wallet in 2 years. That's with her owning 35% of the total Stake! Alice has a much lower chance. She has a 0.0002131% chance of controlling a wallet, which means that over the course of 52 wallets, she has a 0.02131% chance of controlling any wallet in 2 years.

    As of writing, the *largest* Staker controls ~8.83% of the Stake.

    The only thing that a Staker accomplishes by splitting up their Stake into multiple identities is making the system appear to be more diverse.

    For example, say that Alice split up her Stake equally into 5 accounts: Alice1, Alice2, Alice3, Alice4, and Alice5. Now, rather than Alice having a 25% chance to be a Signer, each account has a 5% chance which collectively add up to 25%.

    To use the example from earlier: Alice has 250M T, Bob has 400M T, and Carol has 350M T staked. Alice has her T split into 50M for each identity. Alice1 would own 50M/1000M = 5%. Keeping with the simplification of assigning numbers from 1 to 100 to identities, Alice1 would get [1, 5], Alice2 gets [6, 10], Alice3 gets [11, 15], Alice4 gets [16, 20], Alice5 gets [21, 25], Bob gets [26, 65], Carol gets [66, 100]. If we use the same random numbers as before, (75, 51, 13, 48, 36, 62, 46, 65, 97, 67...), then we make the assignments as (Carol, Bob, Alice3, Bob, Bob, Bob, Bob, Bob, Carol, Carol...). Nothing has effectively changed!

    Examples

    updateWalletParameters
    walletParameters
    Threshold Elliptic Curve Digital Signature Algorithm
    Sortition Pool
    Random Beacon
    Staker
    0.9992652=.96220.99926^{52} = .96220.9992652=.9622

    Statistics

    Sybil Resistance

    tBTC Minting Walkthrough

    Follow along with this guide and leverage your Bitcoin by minting tBTC.

    Before you start

    Here are some things you will need before you start the minting process:

    ✅ Bitcoin (BTC)

    ✅ Ethereum (ETH) for Ethereum transaction gas costs

    ✅ Bitcoin compatible wallet

    ✅ Ethereum compatible wallet

    If you don't already have one, you'll need to set up a Bitcoin wallet. A solid option to use is Green Wallet. You can download it here:

    After you've created your wallet, select Bitcoin as your network.

    🎉 You're ready to mint! Go to the tBTC dapp here:

    1. Connect your preferred Ethereum wallet to the tBTC dapp by selecting Connect Wallet.

    1. Navigate to the . This is represented in the lefthand navigation by the tBTC icon.

    1. Enter a Bitcoin wallet address as the BTC Recovery Address. Click Generate Deposit Address to create your unique deposit address.

    1. Make sure to download the JSON file by clicking Download. The JSON file contains a wallet public key, a refund public key, and a refund lock time. You need to keep this JSON file until you receive your tBTC tokens.

    1. In your Bitcoin wallet, take a picture of the QR code of the generated Deposit Address in the tBTC dapp. It will look something like this:

    2. Send your BTC deposit to this Deposit Address from your Bitcoin wallet. The minimum deposit is 0.01 BTC.

    3. Return to the tBTC dapp. After your funds are sent, the screen will automatically advance to Step 3.

    1. To initiate minting, click on Confirm deposit & mint.

    1. Sign the transaction in your Ethereum wallet.

    1. Your mint is now in progress! You don't need to remain in the dapp to wait for your tBTC tokens to mint. You can see the status of your mint in the dapp. The first stage requires 1 confirmation on the Bitcoin Network before advancing to the next step.

    1. Now you will see the following while waiting for a Minter to assess the minting initialization:

    1. Next, you will see the following while waiting for a Guardian to examine the minting request:

    1. Success! You can see all transaction links on this screen.

    1. Make sure to add the tBTC token address to your Ethereum wallet by clicking token address.

    🎉 You've successfully minted tBTC! 🎉

    Strategy

    A Strategy combines all possible configuration parameters for using CBD. It takes the following parameters:

    • cohort - a Cohort object

    • conditionSet? - an optional ConditionSet. If used, all encryptions made via this strategy have a default Condition Set assigned

    • aliceSecretKey? - an optional Secret Key for the encrypter

    • bobSecretKey? - an optional SecretKey for decrypter

    If the optional secret keys are not provided, new ones will be generated instead.

    Assuming we have a Cohort already defined, we can construct a Strategy:

    Before we can encrypt/decrypt, the Threshold network needs to be made aware of our Strategy. We do this by deploying:

    Strategy.deploy takes 2 parameters:

    • label - this is a string that the network uses to identify the strategy

    • provider - deploying a Strategy requires writing to the smart contract, so a connection to a wallet is required via a Web3 provider

    Deploying a strategy returns a new DeployedStrategy object. This object grants us access to the encrypter and decrypter which can then be used throughout an application.

    Strategies can be exported allowing them to be reused easily. The syntax is the same whether the strategy has been deployed or not.

    Similarly, we can import and export the decrypter objects to JSON. This allows us to rebuild the decrypter on a client facing application:

    CBD Mainnet Version

    CBD allows adopting developers to pull a range of 'trust levers' in order to satisfy and assuage the trust, risk, cost, redundancy and latency preferences of their end-users. However, correctly selecting individual parameters across each and every trust/risk dimension requires a deep understanding of the underlying mechanisms and cryptology. Moreover, these parameters must be combined into a coherent bundle that, as a whole, aligns with the risk aversion and trust-minimization desiderata of end-users. Hence, to avoid burdening developers with onerous analysis, the Threshold team has constructed a set of pre-configured 'trust packages'. They are introduced and detailed .

    The context for configuring the trust packages follows below.

    The foundation of the Threshold Access Control trust model (and indeed, threshold cryptography in general) is the concept of a Cohort; a group of Threshold nodes temporarily employed to either:

    1. Collectively generate and manage part of a public key that can be used to encrypt one or more data payloads.

    Start minting tBTC

    If you have questions about terminology, you can toggle over to the How it Works page in the dapp to learn more. You can also dive into documentation on wallet generation and bridge permissionlessness in the docs.

    STEP 1: Generate a deposit address

    STEP 2: Make BTC Deposit

    STEP 3: Initiate Minting

    STEP 4: tBTC Minting

    Congrats — you minted!

    Apple store download
    Google store download
    https://dashboard.threshold.network/tBTC/mint
    tBTC Bridge page

    Collectively manage a decryption fragment associated with a single data payload and provide the fragment to requesters who fulfill pre-specified conditions.

    All Cohorts are parametrized on formation, including the Cohort size (n) and Cohort threshold (m). These parameters are the inputs for the following core trust assumptions: The first is the orderly threshold assumption, wherein the protocol relies on a minimum number – the threshold – of node operators within each Cohort to follow the protocol correctly. For example, a 16-of-32 cohort would require at least 16 nodes to be online, responsive and (ideally) run an up-to-date version of CBD software. If any fewer than 16 are online, data requesters will be unable to retrieve decryption fragments. The second is the honest threshold assumption, the protocol's most fundamental form of collusion-resistance – that is, protection against deliberate, unlawful attempts to access private data. In this case, the protocol relies on a minimum number of operators to be ‘honest’ – i.e. not susceptible to bribery, coercion or other attempts to maliciously collude. This minimum is calculated as the threshold node count (m) subtracted from the total cohort size, plus one (n - m + 1). Using the same example as before, a 16-of-32 Cohort would require a minimum of 32 - 16 + 1 = 17 honest operators. In other words, if at least 17 individual operators refuse to collude, there is nothing the remaining 15 operators can do, regardless of their war chest or aggregate stake power.

    Note that the orderly threshold and honest threshold assumptions are conceptually similar to the more common honest majority assumption. However, they are more flexible than simply requiring those who control 50% of the staked tokens to be honest. Unlike most BFT or pBFT-based protocols, the honest threshold can be partially decoupled from the operators’ stake weights, depending on the cohort sampling parameters specified by the developer or end-user.

    Some example cohort size and threshold configurations can be seen in Create Security Optionality With Reusable Cohorts

    The orderly threshold and honest threshold trust assumptions above treat each Cohort as an isolated group, where the chosen parameters (m-of-n) determine the group’s redundancy, latency and collusion resistance. However, the reality is that each Cohort is selected from a larger sample of Threshold nodes, which is far larger than the typical/optimal size of each cohort – there is not necessarily much overlap between Cohorts. Therefore, the mechanisms through which nodes are selected to form Cohorts carry their own trust assumptions. More specifically, the sampling parameters impact the security and collusion-resistance of a given data sharing flow. Sampling parametrization can be divided into; (1) those relating to frequency and prompting of (re-)sampling, and (2) compositional requirements to form a Cohort, besides the top-level m & n parameters.

    Members of a Cohort can be replaced as frequently as is practical, with the main constraint being the bandwidth overhead of key discovery. A more regular re-sampling of Cohort members provides a form of increased collusion-resistance, as an attacker would have less time to discover, contact and bribe/coerce the requisite threshold of operators in order to access sensitive material.

    The logic which prompts the refreshing of Cohort members is also customizable. For example, a group chat application might include the option to mark a conversation as 'sensitive', in which case messages sent within this conversation will be assigned to and managed by fresh Cohorts with a greater frequency (or randomness) than regular messages.

    Developers may also toggle certain Cohort characteristics via the sampling mechanism. For example, they might force a percentage of Cohort positions to be filled exclusively by:

    • Node operators who have staked a minimum (or maximum) sum of T tokens.

    • Specific Ethereum addresses (e.g. nodes operated by the adopting developer themselves, or their partners).

    • Node operators who have not initiated stake unbonding in the past X months.

    • Node operators who also (or do not) provision service to other Threshold applications, such as tBTCv2.

    • Node operators who have a minimum historical availability (for example, as measured via their verifiable tBTCv2 activity).

    The protocol is also permissionless and psuedonymous (Ethereum addresses), which means the total population of node operators will expand, contract and change its composition over time, and that change will not be perfectly discernible.

    The node population is also non-uniform; rather, it is comprised of a heterogeneous set of operators, ranging from the hobbyist to institutional stakers. Although there is a degree of standardization with respect to requisite machine memory, CPU power, latency and availability, the actual underlying servers are only observable anecdotally – i.e. this cannot yet be verified on-chain. However, this anecdotal, informal insight into the node population can be supplemented and corroborated with conclusions drawn from on-chain activity, such as slashing or unbonding events.

    
Note that the CBD Mainnet version remains under development and is planned for release in Q2 2023. However, for developers considering integrating Conditions-Based Decryption into their application, it is worthwhile familiarizing oneself with the underlying trust model.

    Trust Packages

    Cohort-based trust assumptions

    here

    Sampling-based trust assumptions

    (1) Cohort refresh

    It could be argued that with very frequent Cohort refresh, a wily attacker could simply wait until a subset of operators they control happens to satisfy the threshold, however briefly that may be. However, this attack strategy would be of little value in most contexts, since it would be almost impossible to predict which encrypted message would coincide with the malicious subset-in-waiting. For example, an attacker seeking illicit access to market sensitive information (from a private DAO group chat) would be extraordinarily fortunate to temporarily control the requisite decryption fragments in the exact window that a market-moving message was shared.

    It’s worth noting that the refreshing of Cohort members is unavoidable, regardless of the frequency or prompts chosen by a developer or end-user. This is because node operators will naturally wind down their operations and commitment to the network ('unbonding') over time. Although there are staker-facing protocol mechanisms in place to minimize the probability of a disorderly exodus, the proactive refreshing of Cohorts can also mitigate against abandonment of duties, for example by preemptively replacing operators with pending stake withdrawals (i.e. those who have initiated unbonding) with those with a longer-term economic commitment to the network (i.e. no unbonding initiated, or some longer token lock-up period).

    (2) Cohort composition beyond m & n

    Population-based trust assumptions

    This section is under construction.

    Infrastructure-based trust assumptions

    This section is under construction.

    Create a Strategy

    Deploy a Strategy

    Import and Export Strategies

    import { Cohort, Strategy } from '@nucypher/nucypher-ts';
    
    const config = {
      threshold: 3,
      shares: 5,
      porterUri: 'https://porter-ibex.nucypher.community',
    };
    const newCohort = await Cohort.create(config);
    
    const newStrategy = Strategy.create(
      newCohort
    );
    import detectEthereumProvider from '@metamask/detect-provider';
    import providers from 'ethers';
    
    const MMprovider = await detectEthereumProvider();
    const mumbai = providers.providers.getNetwork(80001);
    
    if (MMprovider) {
      const web3Provider = new providers.providers.Web3Provider(
        MMprovider,
        mumbai
      );
      const newDeployed = await newStrategy.deploy('test', web3Provider);
    }
    const encrypter = newDeployed.encrypter;
    const decrypter = newDeployed.decrypter;
    
    const plaintext = 'this is a secret';
    const encryptedMessageKit = encrypter.encryptMessage(plaintext);
    
    const decryptedMessage = await decrypter.retrieveAndDecrypt([
      encryptedMessageKit,
    ]);
    import { DeployedStrategy } from '@nucypher/nucypher-ts';
    
    const configJSON = newDeployed.toJSON();
    console.log(configJSON);
    /*
    LARGE JSON OBJECT
    */
    const importedStrategy = DeployedStrategy.fromJSON(configJSON);
    import { DeployedStrategy } from '@nucypher/nucypher-ts';
    
    const decrypter = newDeployed.decrypter;
    const decrypterJSON = decrypter.toJSON();
    // save this JSON are send it over a side channel to a client facing app
    
    // on the client app
    import { tDecDecrypter } from '@nucypher/nucypher-ts';
    const newDecrypter = tDecDecrypter.fromJSON(decrypterJSON);

    Ethereum Mainnet

    Threshold Contracts

    Delivered in @threshold-network/[email protected] package.

    Contract
    Address

    T Token

    Contract
    Address

    Delivered in @keep-network/[email protected] and @keep-network/[email protected] packages.

    Contract
    Address
    Contract
    Address
    Contract
    Address

    Delivered in @keep-network/[email protected] package.

    Contract
    Address

    Docker Installation

    This page will guide you through Docker setup steps.

    Install or update Docker to the latest version. Visit the for detailed instructions. Use the command below to find your installed version if needed:

    General best practices recommend against running the tBTC v2 client as the root user as a security precaution. One security-minded approach is to (Rootless mode).

    Next, choose ONE of the following options. The tBTC v2 Service option configures the client to run as a service in order to ensure that the client is restarted automatically, should your machine reboot. The Docker Launch Script is faster to setup, but won't start the client if your machine reboots.

    Create the tbtcv2.service file:

    Paste the following in the tbtcv2.service file:

    Get Started (CBD Proof-of-Concept)

    This tutorial is a quick way for developers to learn about the Threshold Access Control service by building with the Proof-of-Concept (PoC) version of .

    Note that the underlying vary between versions and technologies; these are explained in detail for the , , and versions.

    To begin, we need to install the nucypher-ts library:

    One of the nucypher-ts dependencies takes advantage of . In order to run nucypher-ts in the browser, we have to from the source files. This process is mostly automated by the wrapper generated by .

    Replace the placeholders inside the <> brackets, remove the <> brackets but be sure to not edit anything further.

    When done, save and close the file.

    Next, test to make sure your configuration works:

    There will be no console output because it will be running in the background. Use systemctl to get the status of the service:

    If the service failed, go back and double check your configuration.

    Another option is to see if the Docker container is running:

    If everything is running as intended, enable the service:

    Now, with the service running, you should make sure that your configuration will tolerate a reboot and start up again automatically.

    Log back in to your machine and check that the service is running. If it is, you're done. If not, go back and review your work.

    Docker Launch Script

    To launch the tBTC v2 client, several configuration flags and environmental values need to be set. For simplicity, a bash script can be used rather than typing or pasting all the flags into the console.

    Create the launch script:

    And paste the following:

    Save and close the file, and make it executable:

    To launch the tBTC v2 client, execute:

    The --detach property will prevent the status messages from the client to be printed to the console. Review the Docker logs for detailed status information.

    Unless the --detach flag was removed from the startup script, there will be no console output. In order to check your node, retrieve the Docker logs.

    First, find your Docker instance identification, it'll be a random combination of words, e.g. stinky_brownie:

    Use your specific identification and substitute:

    Scroll down about half a page, and you should see the following:

    Congratulations, your node is up and running.

    Install Docker

    Docker and Security Best Practices

    Official Docker website
    Run the Docker daemon as a non-root user
    cd /etc/systemd/system/
    nano tbtcv2.service
    [Unit]
    Description=tBTC v2 client
    After=network.target
    Wants=network.target
    
    [Service]
    Environment="ETHEREUM_WS_URL=<Ethereum API WS URL>"
    Environment="OPERATOR_KEY_FILE_NAME=<Operator Account keyfile name>"
    Environment="OPERATOR_KEY_FILE_PASSWORD=<Operator Account keyfile password>"
    Environment="PUBLIC_IP=/dns4/<PUBLIC_IP_OF_MACHINE>/tcp/3919"
    Environment="CONFIG_DIR=/home/<user name>/keep/config"
    Environment="STORAGE_DIR=/home/<user name>/keep/storage"
    
    # These items only apply if you setup rootless-mode.
    # Do not enable unless using rootless mode. Don't forget to adjust user UID.
    #Environment="XDG_RUNTIME_DIR=/run/<user name>/<user UID>/"
    #Environment="DOCKER_HOST=unix:///run/<user name>/<user UID>/docker.sock"
    
    Type=simple
    WorkingDirectory=/home/<user>
    
    ExecStart=/usr/bin/docker run \
        --volume ${CONFIG_DIR}:/mnt/keep/config \
        --volume ${STORAGE_DIR}:/mnt/keep/storage \
        --env KEEP_ETHEREUM_PASSWORD=${OPERATOR_KEY_FILE_PASSWORD} \
        --env LOG_LEVEL=info \
        --log-opt max-size=100m \
        --log-opt max-file=3 \
        -p 3919:3919 \
        -p 9601:9601 \
        keepnetwork/keep-client:latest \
        start \
        --ethereum.url ${ETHEREUM_WS_URL} \
        --ethereum.keyFile /mnt/keep/config/${OPERATOR_KEY_FILE_NAME} \
        --storage.dir /mnt/keep/storage \
        --network.announcedAddresses $PUBLIC_IP
    
    Restart=always
    RestartSec=15s
    
    [Install]
    WantedBy=default.target
    

    The path shown in the example configuration will differ from yours. Make sure it is configured correctly.

    Client Startup

    nano keep.sh
    # Keep tBTC v2 Client
    #
    # Ethereum endpoint WebSocket URL
    # This can be a provider such as Infura, Alchemy, Ankr, etc or your own Geth Nodeq
    # ETHEREUM_WS_URL="wss://mainnet.infura.io/ws/v3/redacted_credentials"
    # note: only replace characters inside the " ". The Quotation marks must be retained
    ETHEREUM_WS_URL="<Ethereum API WS URL>"
    
    # copied to home/keep/config earlier
    OPERATOR_KEY_FILE_NAME="<Operator Account keyfile name>"
    
    # password set during Operator Account Address creation
    OPERATOR_KEY_FILE_PASSWORD="<Operator Account keyfile password>"
    
    # To configure your node with a Public IP, enter it below.
    PUBLIC_IP="<PUBLIC_IP_OF_MACHINE>"
    # Alternatively, you can use DNS.
    # To configure DNS, modify the last line of the script
    # and add your DNS in the following format:
    # /dns4/bootstrap-1.test.keep.network/tcp/3919
    
    # Setup configuration and storage directories
    # THESE MUST BE PERSISTENT STORAGE
    CONFIG_DIR="/home/keep/config"
    STORAGE_DIR="/home/keep/storage"
    
    docker run \
        --detach \
        --restart on-failure \
        --volume $CONFIG_DIR:/mnt/keep/config \
        --volume $STORAGE_DIR:/mnt/keep/storage \
        --env KEEP_ETHEREUM_PASSWORD=$OPERATOR_KEY_FILE_PASSWORD \
        --env LOG_LEVEL=info \
        --log-opt max-size=100m \
        --log-opt max-file=3 \
        -p 3919:3919 \
        -p 9601:9601 \
        keepnetwork/keep-client:latest \
        start \
        --ethereum.url $ETHEREUM_WS_URL \
        --ethereum.keyFile /mnt/keep/config/$OPERATOR_KEY_FILE_NAME \
        --storage.dir /mnt/keep/storage \
        --network.announcedAddresses /ip4/$PUBLIC_IP/tcp/3919
    
    sudo chmod +x keep.sh
    sudo bash keep.sh
    docker --version
    sudo systemctl start tbtcv2
    sudo systemctl status tbtcv2
    docker ps
    systemctl enable tbtcv2
    reboot now
    sudo docker ps
    sudo docker logs stinky_brownie >& /path/to/output/file
    
    ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
    ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
      ▓▓▓▓▓▓    ▓▓▓▓▓▓▓▀    ▐▓▓▓▓▓▓    ▐▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
      ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀      ▐▓▓▓▓▓▓▄▄▄▄         ▓▓▓▓▓▓▄▄▄▄         ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
      ▓▓▓▓▓▓▓▓▓▓▓▓▓▀        ▐▓▓▓▓▓▓▓▓▓▓         ▓▓▓▓▓▓▓▓▓▓▌        ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
      ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄       ▐▓▓▓▓▓▓▀▀▀▀         ▓▓▓▓▓▓▀▀▀▀         ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
      ▓▓▓▓▓▓   ▀▓▓▓▓▓▓▄     ▐▓▓▓▓▓▓     ▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌
    ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓
    ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓
    
    Trust math, not hardware.
    	
    -----------------------------------------------------------------------------------
    | Keep Client Node                                                                |
    |                                                                                 |
    | Version: Version: v2.0.0-m1 (4d745f6d0)                                         |
    |                                                                                 |
    | Operator: 0x_your_operator_address                                              |
    |                                                                                 |
    | Port: 3919                                                                      |
    | IPs : /ip4/111.222.333.444/tcp/3919/ipfs/redacted                               |
    |                                                                                 |
    | Contracts:                                                                      |
    | RandomBeacon   : 0x5499f54b4A1CB4816eefCf78962040461be3D80b                     |
    | WalletRegistry : 0x46d52E41C2F300BC82217Ce22b920c34995204eb                     |
    | TokenStaking   : 0x01B67b1194C75264d06F808A921228a95C765dd7                     |
    -----------------------------------------------------------------------------------

    Integrations Guild Multisig

    Marketing Guild Multisig

    TBTC

    TBTCVault

    VendingMachine

    WalletRegistry

    CoveragePool

    TokenStaking

    0x01b67b1194c75264d06f808a921228a95c765dd7

    KeepStake

    0x10DE37cF84202A20cae61069C617B3Aa874aF8b4

    NU<>T Vending Machine

    0x1CCA7E410eE41739792eA0A24e00349Dd247680e

    KEEP<>T Vending Machine

    0xE47c80e8c23f6B4A1aE41c34837a0599D5D16bb0

    GovernorBravo TimelockController

    0x87F005317692D05BAA4193AB0c961c69e175f45f

    Council Multisig

    0x9F6e831c8F8939DC0C830C6e492e7cEf4f9C2F5f

    Bridge

    0x5e4861a80B55f035D899f66772117F00FA0E8e7B

    RandomBeacon

    0x5499f54b4A1CB4816eefCf78962040461be3D80b

    PRE Application

    0x7E01c9c03FD3737294dbD7630a34845B0F70E5Dd

    SubscriptionManager (Polygon-mainnet)

    0xB0194073421192F6Cf38d72c791Be8729721A0b3

    NU Token

    0x4fE83213D56308330EC302a8BD641f1d0113A4Cc

    StakingEscrow

    0xbbD3C0C794F40c4f993B03F65343aCC6fcfCb2e2

    KEEP Token

    0x85Eee30c52B0b379b046Fb0F85F4f3Dc3009aFEC

    TokenStaking

    0x1293a54e160D1cd7075487898d65266081A15458

    Threshold DAO Contracts

    TBTC Application Contracts

    PRE Application Contracts

    Legacy NU Contracts

    Legacy Keep Contracts

    0xCdF7028ceAB81fA0C6971208e83fa7872994beE5

    Treasury Guild Multisig

    WorkLock

    For this tutorial we'll need a few extra packages:

    Visit nucypher-ts/examples for more information on using nucypher-ts in your web application.

    Next, we will create a Cohort based on our risk preferences. A Cohort is a group of nodes that work together to control access to data. Threshold and Shares are two parameters used to create a Cohort. For example, a 3-of-5 Cohort needs at least 3 of the 5 members to provide shares to access the original data.

    To create a Cohort, use the following code:

    Notice that we provided a porterUri parameter. Porter is a web-based service that interacts with nodes on the network on behalf of applications. It acts as an "Infura for Threshold Access Control". In this example, we used a Porter endpoint for the tapir testnet.

    Conditions are the requirements for a data requester or recipient to access the plaintext data – i.e. what they will need to prove later to gain decryption rights.

    The ERC721Ownership condition checks the owner of a given token ID. It can be customized by using the ownerOf contract method and comparing it with the requestor's signature. For more information, see the References section.

    We will now specify the conditions that must be met to access the data. In this tutorial, we will require that the requester owns an ERC721 token with a token ID of 5954.

    We will now combine the Cohort, ConditionSet, and any other necessary parameters into a Strategy. Strategies are a convenient way to bundle together frequently used configurations, including specific combinations of network parameters and conditionality.

    Next, we will deploy this Strategy to the Threshold Network. To do that, we're going to transact on Polygon Mumbai:

    For more information about customizing and reusing Cohort, Condition, and Strategy objects, see the References page in the documentation.

    We can now encrypt data using the newly deployed Strategy. At this point, we can also specify new conditions on which data access will be predicated. These will take a higher precedence and override the default conditions contained in the Strategy. For this example, let's make it so the overriding requirement is that the requester's wallet hold a minimum number (three) of NFTs. The NFTs are from the same collection that we specified in Step 3. Note that Threshold nodes will check this new condition using the balanceOf method.

    To encrypt the plaintext:

    The resulting encryptedMessageKit contains the encrypted data and associated condition(s).

    Finally, we will test the conditional access control service by requesting decryption rights:

    At decryption time, the requester will be asked to verify their address by signing a message in MetaMask. This is where conditionContext comes into play – if the requester's address controls the minimum number (or greater) of the specified NFT, they are eligible to receive the requisite number of decryption fragments. By assembling these fragments, they are able to decrypt and view the plaintext encrypted in the previous step.

    The following samples showcase integrations with React-based web apps, and serve as an 'end-to-end' reference for creating conditions-based encryption & decryption:

    • nucypher/tdec-sandbox

    • nucypher/tdec-nft-example

    • nucypher/alpha-leaks-demo

    yarn add @nucypher/nucypher-ts

    Update (04.14.23) The Proof-of-Concept version is compatible with condition evaluation on Mumbai (Polygon testnet) via the Threshold node-facing Tapir testnet.

    An additional node-facing testnet (Oryx) now points to Polygon mainnet. This means access conditions can be checked and verified by Threshold nodes if they pertain to state on either of the Polygon networks. Note that it is not possible to evaluate conditions on both Mumbai and Polygon mainnet in a single runtime, because pre-configuration requires choosing between Tapir and Oryx.

    1. Install nucypher-ts

    nucypher-ts is under active development.

    Conditions-Based Decryption
    trust assumptions
    CBD Proof-of-Concept
    CBD Mainnet
    PRE Mainnet
    WASM
    load WASM
    wasm-pack
    yarn add ethers @metamask/detect-provider
    import { Cohort } from '@nucypher/nucypher-ts';
    
    const config = {
      threshold: 3,
      shares: 5,
      porterUri: 'https://porter-tapir.nucypher.community',
    };
    const newCohort = await Cohort.create(config);
    import { Conditions } from '@nucypher/nucypher-ts';
    
    const NFTOwnership = new Conditions.ERC721Ownership({
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
      chain: 5, // Tapir network uses Görli testnet
      parameters: [5954],
    });
    import { Conditions, ConditionSet } from '@nucypher/nucypher-ts';
    
    const conditions = new ConditionSet([
      NFTOwnership,
      // Other conditions can be added here
    ]);
    import { Strategy } from '@nucypher/nucypher-ts';
    
    const newStrategy = Strategy.create(newCohort, conditions);
    import detectEthereumProvider from '@metamask/detect-provider';
    import { providers } from 'ethers';
    
    const MMprovider = await detectEthereumProvider();
    const mumbai = providers.getNetwork(80001);
    
    const web3Provider = new providers.Web3Provider(MMprovider, mumbai);
    const newDeployed = await newStrategy.deploy('test', web3Provider);
    const NFTBalanceConfig = {
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
      standardContractType: 'ERC721',
      chain: 5,
      method: 'balanceOf',
      parameters: [':userAddress'],
      returnValueTest: {
        comparator: '>=',
        value: 3,
      },
    };
    const NFTBalance = new Conditions.Condition(NFTBalanceConfig);
    
    const encrypter = newDeployed.encrypter;
    
    const plaintext = 'this is a secret';
    const encryptedMessageKit = encrypter.encryptMessage(
      plaintext,
      new ConditionSet([NFTBalance])
    );
    const decrypter = newDeployed.decrypter;
    
    const conditionContext = conditions.buildContext(web3Provider);
    const decryptedMessage = await decrypter.retrieveAndDecrypt(
      [encryptedMessageKit],
      conditionContext
    );

    2. Build a Cohort

    3. Specify default Conditions

    CBD allows developers to enforce conditional access at various runtime stages, depending on what makes the most sense for the use case. At this point, we will add the default Conditions, which will only gate-keep access if no other conditions are included later at encryption time. This is explained further in .

    There are multiple and it is possible to combine multiple conditions into a .

    4. Build a Strategy

    Deploying a Strategy requires writing to the blockchain. This requires a wallet funded with testnet MATIC and connection to the blockchain via a provider(e.g. MetaMask).

    5. Encrypt the plaintext & update Conditions

    6. Request decryption rights

    Note that the requester does not need to manually sign the next time they seek access to the data, as their client can temporarily cache their signature. Fresh plaintexts encrypted under any conditions involving the same wallet address are automatically accessible to any requester who has signed at least once, provided they still fulfill the (new) conditions, and the cached signature has not expired.

    Example applications

    0x71E47a4429d35827e0312AA13162197C23287546
    0x2ff7aB212cD6FEaE21bAc5300465E149FB6b85a9
    0xd55c4261145EA1752662faA0485AfBC8C431b0CA
    0x18084fbA666a33d37592fA2633fD49a74DD93a88
    0x9C070027cdC9dc8F82416B2e5314E11DFb4FE3CD
    0x6590DFF6abEd7C077839E8227A4f12Ec90E6D85F
    0x46d52E41C2F300BC82217Ce22b920c34995204eb
    0x7D7B622C07f216d99eFc3EfB9Cf71872F46D811A
    0xe9778e69a961e64d3cdbb34cf6778281d34667c2
    Condition Hierarchies
    Condition types
    ConditionSet

    Bootstrapping

    A Bitcoin-backed Stablecoin

    A certain network effect is required for a stablecoin to function well. Bootstrapping is the process of ensuring the protocol has gained enough traction to become self-sufficient.

    In the past this was usually accomplished by being an early adopter of coins, such as buying Bitcoin early and benefiting from the lower price. DeFi revolutionized the bootstrapping concept by enabling the bootstrapping of capital through yield-farming (aka rented liquidity).

    Liquity Protocol (creators of the LUSD stablecoin) bootstrapped by issuing LQTY tokens to depositors in the stability pool. This incentivized people to take out loans and deposit to the stability pool.

    For normal, healthy operations of the protocol, it's vital that there is sufficient funds in the stability pool to cover all liquidations. However the LQTY incentive resulted in far more deposits than required, essentially creating wasted capital. Furthermore there are concerns on how sustainable Liquity will be after the initial 100 million LQTY has been issued and the pool is only sustained through liquidations rewards.

    How does Threshold USD approach this?

    In Threshold USD we take a different approach. A newer concept in DeFi known as Protocol Controlled Value (PCV) is the idea that the protocol itself can own liquidity and use that to improve the protocol. This is a new alternative to renting it elsewhere (aka yield-farming) and has the benefit of long-term sustainability.

    But the PCV has to come from somewhere. In thUSD we resolve this by issuing an to the PCV which then deposit these funds directly to the stability pool. Read more about this here:

    That lets us bootstrap the stability pool at zero cost to the protocol.

    But not only that, by eliminating the LQTY token, all profits (from interest, redemption fee, etc) will go directly into the PCV. Compared to Liquity, where profits are distributed among LQTY holders, we have eliminated a massive drain on the system, at no cost.

    Having the stability pool funded on its own is enough for the protocol to function, and we can expect some users that want to borrow against their tBTC to take part, but it's not going to create major adoption, and for thUSD to function well it needs to be stable at ~$1, that requires people to put up liquidity at decentralized exchanges.

    In order to draw in more users and create liquidity for thUSD, we will issue rewards to pools on other platforms (such as a thUSD stablecoin pool on Curve). This will incentivize users to take debt and deposit into Curve, with the added benefit of improved liquidity and resiliency.

    How fast we want to grow can be almost entirely adjusted by how much reward is sent to the pool.

    This part is indeed rented liquidity with all its drawbacks, but remember that Threshold USD profits are sent to the PCV instead of LQTY holders: as the protocol grows in popularity, profits from the protocol itself can be used to fund these rewards, thus creating a self-sustaining feedback loop.

    On top of that, Threshold DAO will store some of its reserves in stablecoins, so the Threshold DAO can initiate a PCV with deposits on Curve. That will result in more stability for thUSD which is important for adoption.

    Initial Protocol Loan
    Initial Protocol Loan

    Alternatives to Dashboard

    Alternative application authorization methods to using the Threshold Dashboard.

    An operator-registering transaction can be submitted with the Keep Client if the staking provider address key file is available.

    Authorizing Random Beacon via the Client (Docker)

    Authorizing TBTC application via the Client (Docker)

    Via Web Browser

    An operator-registering transactions can be submitted with Etherscan.

    For each of the RandomBeacon and WalletRegistry contracts perform the following steps:

    1. Find the address of the contract and open it on Etherscan (see below).

    2. Go to Contract → Write Contract tab.

    3. Connect your wallet with Connect to Web3 button.

    4. Submit the registerOperator function with your Operator address as an argument.

    export KEEP_CLIENT_CONFIG_DIR=$(pwd)/config
    
    export KEEP_CLIENT_ETHEREUM_WS_URL="<Ethereum API WS URL>"
    
    export STAKING_PROVIDER_KEY_FILE_PASSWORD="<Staking Provider Account Key File Password>"
    export STAKING_PROVIDER_KEY_FILE_NAME="<Staking Provider Account Key File Name>"
    export OPERATOR_ADDRESS="<Operator Account Address>"
    
    docker run \
        --volume $KEEP_CLIENT_CONFIG_DIR:/mnt/keep-client/config \
        --env KEEP_CLIENT_ETHEREUM_PASSWORD=$STAKING_PROVIDER_KEY_FILE_PASSWORD
        us-docker.pkg.dev/keep-test-f3e0/public/keep-client:latest \
        ethereum \
        --ethereum.url $KEEP_CLIENT_ETHEREUM_WS_URL \
        --ethereum.keyFile /mnt/keep-client/config/$STAKING_PROVIDER_KEY_FILE_NAME \
        beacon random-beacon register-operator --submit \
        $OPERATOR_ADDRESS
    export KEEP_CLIENT_CONFIG_DIR=$(pwd)/config
    
    export KEEP_CLIENT_ETHEREUM_WS_URL="<Ethereum API WS URL>"
    
    export STAKING_PROVIDER_KEY_FILE_PASSWORD="<Staking Provider Account Key File Password>"
    export STAKING_PROVIDER_KEY_FILE_NAME="<Staking Provider Account Key File Name>"
    export OPERATOR_ADDRESS="<Operator Account Address>"
    
    docker run \
        --volume $KEEP_CLIENT_CONFIG_DIR:/mnt/keep-client/config \
        --env KEEP_CLIENT_ETHEREUM_PASSWORD=$STAKING_PROVIDER_KEY_FILE_PASSWORD
        us-docker.pkg.dev/keep-test-f3e0/public/keep-client:latest \
        ethereum \
        --ethereum.url $KEEP_CLIENT_ETHEREUM_WS_URL \
        --ethereum.keyFile /mnt/keep-client/config/$STAKING_PROVIDER_KEY_FILE_NAME \
        ecdsa wallet-registry register-operator --submit
        $OPERATOR_ADDRESS

    Staking on Threshold

    Stakes on Threshold can take the following forms:

    • T stake using liquid T created on the Threshold Dashboard

    • Legacy NU stake migrated to T from the NuCypher Dashboard

    • Legacy KEEP stake migrated to T from the Keep Dashboard

    Here is a summary of the overall process:

    • Go to

    • Connect your wallet

    • Your T balance will be shown - click on "Stake"

    • There will be a pop-up describing the staking process; click the check-box to acknowledge you have read the requirements

    • Go to

    • Click "Stake NU on Threshold"

    • Authorize Threshold Staking for the Keep Network legacy stake -

    What is the Threshold Network?

    Getting Started

    Got 2 minutes? Check out an introduction video to the Threshold Network:

    Staking Guides: Jump right in

    Follow our handy guides to get started on staking basics as quickly as possible:

    Staking on Threshold

    Fundamentals: Dive a little deeper

    Learn the fundamentals of the Threshold Network to get a deeper understanding of our main features:

    tBTC Bitcoin BridgeThreshold Access Control

    Threshold USD

    A Bitcoin-backed Stablecoin

    Threshold USD (thUSD) is a stablecoin soft-pegged against USD and backed by ETH and tBTC as collaterals with a minimum collateral ratio of 110%.

    With either BTC or ETH as your collateral, you'll be able to borrow USD at low interest rate.

    Threshold USD is a modified fork of built to be self-sustained through a PCV ("Protocol Controlled Value"). There is no equivalent of LQTY token in Threshold USD. Instead all profits accrue into the PCV. Since there is no token, is completed through an .

    The result of protocol owning its own liquidity ("PCV") is a more predictable trajectory and sustainability long-term. The stability pool is funded by the PCV instead of user deposits. Thanks to this, no funds are wasted on rewards to passive LQTY stakers (rented liquidity) and those funds can instead by re-injected into the stability pool. As the protocol grows and accrue fees, the stability pool will be consistently topped up.

    Liquity is limited to ETH as the only type of collateral. Threshold USD expand to support BTC as collateral for loans through the decentralized BTC wrapper tBTC. In the future other types of collateral may be considered for on-boarding if they are sufficiently decentralized.

    Each collateral will be deployed with its own contracts and each new collateral will require a DAO vote with a lengthy time delay before deployment. By having each collateral be its own contract any collateral can easily be deprecated by disallowing minting on that specific contract.

    Multi-collateral

    Liquity Protocol
    Bootstrapping
    Initial Protocol Loan
  • Choose an amount of T to stake and confirm the transaction

  • Stake Liquid T

    Migrate Legacy NU Stake

    Migrate Legacy KEEP Stake

    https://dashboard.threshold.network/staking
    https://stake.nucypher.network/manage/stake
    https://dashboard.keep.network/applications/threshold
    Stake Creation
    Stake NU on Threshold
    Stake KEEP on Threshold

    Threshold DAO

    Threshold is community-driven and governed by an eponymous DAO that includes the constituencies of both the NuCypher and Keep networks. The Threshold DAO has two primary bodies: the Tokenholder DAO and the Elected Council. The goal of this two-pronged structure is to enhance representation while ensuring accountability. Each of these governance bodies holds the other accountable, similar to the system of checks and balances found in most constitutional governments. They also hold separate responsibilities that are embedded in the governance structure.

    From an implementation perspective, the Tokenholder DAO is based on the Governor Bravo governance model (in particular, using OpenZeppelin Governance). The Tokenholder DAO is on Ethereum Mainnet at 0xd101f2B25bCBF992BdF55dB67c104FE7646F5447. The Elected Council is implemented as a Gnosis Safe contract, with a 6-of-9 configuration, also deployed on Ethereum Mainnet, at 0x9F6e831c8F8939DC0C830C6e492e7cEf4f9C2F5f.

    A technical architecture diagram is show below.

    Threshold DAO Governance Architecture Diagram

    Staking Providers

    You can delegate running an application node to one of the node-as-a-service Staking Providers listed below.

    Staking Providers have not been vetted or endorsed by Threshold. Use your judgement when selecting a provider.

    Staking Provider
    Contact Information

    Condition Set

    Conditions can be combined into Condition Sets using AND and OR operators.

    The below example shows how to authenticate that a requester owns an NFT in one of two different collections.

    If we wanted to store this Condition Set for later use we could export it to JSON:

    And then easily import:

    Security

    Security Policies for Threshold Network

    If you identify vulnerabilities with any Threshold Network code, please email with relevant information to your findings. We will work with researchers to coordinate vulnerability disclosure between our stakers, partners, and users to ensure the successful mitigation of vulnerabilities.

    Throughout the reporting process, we expect researchers to honor an embargo period that may vary depending on the severity of the disclosure. This ensures that we have the opportunity to fix any issues, identify further issues (if any), and inform our users.

    Sometimes vulnerabilities are more sensitive in nature and require extra precautions. We are happy to work together to use a more secure medium, such as Signal. Email and we will coordinate a communication channel that we're both comfortable with.

    A great place to begin your research is by working on our testnet. Please see our to get started. We ask that you please respect network machines and their owners. If you find a vulnerability that you suspect has given you access to a machine against the owner's permission, stop what you're doing and immediately email .

    The Threshold team will make its best effort to respond to a new report within 48 hours

    DELIGHT

    [email protected]

    InfStones

    [email protected]

    P2P

    [email protected]

    Staked

    [email protected]

    Boar
    [email protected]
    const genuineUndead = new Conditions.ERC721Balance({
      contractAddress: '0x209e639a0EC166Ac7a1A4bA41968fa967dB30221',
    });
    const gnomePals = new Conditions.ERC721Balance({
      contractAddress: '0x5dB11d7356aa4C0E85Aa5b255eC2B5F81De6d4dA',
    });
    const NFTConditionSet = new ConditionSet([
      genuineUndead,
      Operator.OR(),
      gnomePals,
    ]);
    const NFTConditionSetJSON = NFTConditionSet.toJSON();
    console.log(NFTConditionSetJSON);
    // [
    //     {
    //         "chain": "ethereum",
    //         "method": "balanceOf",
    //         "parameters": [
    //             ":userAddress"
    //         ],
    //         "standardContractType": "ERC721",
    //         "returnValueTest": {
    //             "comparator": ">",
    //             "value": 0
    //         },
    //         "contractAddress": "0x209e639a0EC166Ac7a1A4bA41968fa967dB30221"
    //     },
    //     {
    //         "operator": "or"
    //     },
    //     {
    //         "chain": "ethereum",
    //         "method": "balanceOf",
    //         "parameters": [
    //             ":userAddress"
    //         ],
    //         "standardContractType": "ERC721",
    //         "returnValueTest": {
    //             "comparator": ">",
    //             "value": 0
    //         },
    //         "contractAddress": "0x5dB11d7356aa4C0E85Aa5b255eC2B5F81De6d4dA"
    //     }
    // ]
    const newConditionSet = ConditionSet.fromJSON(NFTConditionSetJSON);
    . This response may be a simple acknowledgment that the report was received or may be an initial assessment from the team. Unless the report is assessed as irrelevant or incorrect, this response will include expected next steps and communication time frames from the Threshold team.

    The Threshold team will try to make an initial assessment of a bug's relevance, severity, and exploitability, and communicate this back to the reporter.

    The Threshold DAO does have a bug bounty available, which is dispensed on a case-by-case basis.

    The following Bug Bounty amounts were approved by the DAO in the TIP-041 proposal:

    • Critical: Up to $500,000 in T tokens.

    • High: Up to $50,000 in T tokens.

    • Medium: Up to $5,000 in T tokens.

    • Low: Up to $500 in T tokens.

    The following attacks are excluded from the Bug Bounty program:

    • Attacks that the reporter has already exploited themselves, leading to damage.

    • Attacks requiring access to leaked keys/credentials.

    • Basic economic governance attacks (e.g. 51% attack).

    • Lack of liquidity.

    • Sybil attacks.

    The following activities are prohibited by this bug bounty program:

    • Any testing with mainnet or public testnet contracts; all testing should be done on private testnets.

    • Attempting phishing or other social engineering attacks against our contributors and/or users.

    • Any denial of service attacks.

    • Automated testing of services that generates significant amounts of traffic.

    • Public disclosure of an unpatched vulnerability in an embargoed bounty.

    Rewards are distributed according to the impact of the vulnerability based on the Immunefi Vulnerability Severity Classification System V2.2. This is a simplified 5-level scale, with separate scales for websites/apps, smart contracts, and blockchains/DLTs, focusing on the impact of the vulnerability reported.

    Threshold DAO is currently in the process of establishing a Bug Bounty program on Immunefi.

    [email protected]
    [email protected]
    [email protected]

    Bug Bounty Program

    Contribution Guide

    Download, install, build, and test with:

    Install git hooks

    Generate contract typings

    Prepare a new release

    To launch a local development version of the documentation:

    This will launch a local server, available at http://localhost:3000.

    To release a new version of the documentation:

    Publish a new release on NPM.

    Pay attention to the output of these commands and fix your release if needed.

    To build and publish a release, run

    Follow instructions from the command output to finalize the process.

    git clone https://github.com/nucypher/nucypher-ts
    cd nucypher-ts
    yarn install
    yarn build
    yarn test
    npx husky install
    yarn typechain
    yarn run prepare-release
    cd website
    yarn run start
    yarn run docusaurus docs:version 1.1.0

    Development

    Documentation

    Publishing

    Logging

    Optional logging configuration for the tBTC v2 staking client.

    Logging can be configured with environment variables. Please see sample settings:

    LOG_LEVEL=DEBUG
    IPFS_LOGGING_FMT=nocolor
    GOLOG_FILE=/var/log/keep/keep.log
    GOLOG_TRACING_FILE=/var/log/keep/trace.json

    Configuration

    LOG_LEVEL option DEBUG will generate extensive output. Consider INFO instead.

    If you want to share your LibP2P address with others you can get it from the startup log. When sharing remember to substitute the /ipv4/ address with the public facing IP of your client if you’re running on a private machine, or replace the entire /ipv4/ segment with a DNS entry if you’re using a hostname.

    yarn prepare-release
    # Or, to publish an alpha release
    yarn prepare-release:alpha

    CBD Advanced Usage

    Updating tBTC v2 Node

    Update procedure for the tBTC v2 client depends on installation method

    Docker Installation

    The following instructions assume your docker install followed these installation instructions.

    These steps are specific to the Client: v2.0.0-m2 (Mainnet) release and may change.

    The latest release is available on GitHub.

    Open the systemd service file created during the initial install.

    ~/etc/systemd/system/

    The install instructions named the service tbtcv2.service. Locate your service file and open it in your prefered editor. For simplicity we use nano here. You may need sudo.

    sudo nano tbtcv2.service

    The service should look like this:

    Locate the following line:

    Make the following change to this line only:

    Save and exit the service file.

    Reload the daemon and restart the service:

    Verify your client updated by visiting your status page:

    Look for :

    If you simply used the docker container launch script, the following change needs to be made to the script prior to relaunching the script.

    Open the launch script from your storage location

    Locate the following line:

    Make the following change to this line only:

    Save and exit the service file.

    Use the following to determine your docker container's name

    The ID of your tBTC v2 container will be shown, copy the container ID and paste it into the folowing:

    To launch the tBTC v2 client again, execute:

    This install method requires downloading the latest version of the binary. Follow the installation steps provided .

    keep-core/docs/resources/client-start-help at main · threshold-network/keep-coreGitHub

    Contract Addresses

    Click here to see the addresses of contracts deployed on Ethereum Mainnet.

    Click here to see the addresses of contracts deployed on Görli Testnet.

    https://www.youtube.com/watch?v=8MzE_FG67Z8www.youtube.com

    Please be aware that this method does NOT restart your node in case of a crash.

    here
    [Unit]
    Description=tBTC v2 client
    After=network.target
    Wants=network.target
    
    [Service]
    Environment="ETHEREUM_WS_URL=<Ethereum API WS URL>"
    Environment="OPERATOR_KEY_FILE_NAME=<Operator Account keyfile name>"
    Environment="OPERATOR_KEY_FILE_PASSWORD=<Operator Account keyfile password>"
    Environment="PUBLIC_IP=/dns4/<PUBLIC_IP_OF_MACHINE>/tcp/3919"
    Environment="CONFIG_DIR=/home/<user name>/keep/config"
    Environment="STORAGE_DIR=/home/<user name>/keep/storage"
    
    # These items only apply if you setup rootless-mode.
    # Do not enable unless using rootless mode. Don't forget to adjust user UID.
    #Environment="XDG_RUNTIME_DIR=/run/<user name>/<user UID>/"
    #Environment="DOCKER_HOST=unix:///run/<user name>/<user UID>/docker.sock"
    
    Type=simple
    WorkingDirectory=/home/<user>
    
    ExecStart=/usr/bin/docker run \
        --volume ${CONFIG_DIR}:/mnt/keep/config \
        --volume ${STORAGE_DIR}:/mnt/keep/storage \
        --env KEEP_ETHEREUM_PASSWORD=${OPERATOR_KEY_FILE_PASSWORD} \
        --env LOG_LEVEL=info \
        --log-opt max-size=100m \
        --log-opt max-file=3 \
        -p 3919:3919 \
        -p 9601:9601 \
        keepnetwork/keep-client:latest \
        start \
        --ethereum.url ${ETHEREUM_WS_URL} \
        --ethereum.keyFile /mnt/keep/config/${OPERATOR_KEY_FILE_NAME} \
        --storage.dir /mnt/keep/storage \
        --network.announcedAddresses $PUBLIC_IP
    
    Restart=always
    RestartSec=15s
    
    [Install]
    WantedBy=default.target
    

    Create Security Optionality With Reusable Cohorts

    Providing configurable security to end-users is easy with Reusable Cohorts. Below we define three cohorts: small, medium, and large.

    smallCohort, mediumCohort, and largeCohort can then be reused by multiple Strategies.

    const smallConfig = {
      threshold: 3,
      shares: 5,
      porterUri: 'https://porter-tapir.nucypher.community',
    };
    const mediumConfig = {
      threshold: 11,
      shares: 20,
      porterUri: 'https://porter-tapir.nucypher.community',
    };
    const largeConfig = {
      threshold: 51,
      shares: 100,
      porterUri: 'https://porter-tapir.nucypher.community',
    };
    const smallCohort = await Cohort.create(smallConfig);
    const mediumCohort = await Cohort.create(mediumConfig);
    const largeCohort = await Cohort.create(largeConfig);
    keepnetwork/keep-client:latest \
    keepnetwork/keep-client:v2.0.0-m2 \
     sudo systemctl daemon-reload
     sudo systemctl restart tbtcv2
    http://111.222.333.444:9601/metrics
    client_info{version="v2.0.0-m2"}
    nano keep.sh
    keepnetwork/keep-client:latest \
    keepnetwork/keep-client:v2.0.0-m2 \
    sudo docker ps
    sudo docker kill CONTAINER_ID
    sudo bash keep.sh

    tBTC Bitcoin Bridge

    A Decentralized, Permissionless Bitcoin Bridge to DeFi

    Existing solutions that bridge Bitcoin to Ethereum require users to send their Bitcoin to an intermediary, in exchange for an ERC-20 token that represents the original asset. This centralized model requires you to trust a third party and is susceptible to censorship, threatening the premise of Bitcoin as sovereign, secure, permissionless digital asset.

    The second generation of tBTC is a truly decentralized (and scalable) bridge between Bitcoin and Ethereum. It provides Bitcoin holders secure and open access to the broader DeFi ecosystem. tBTC v2 allows you to unlock your Bitcoin’s value to borrow and lend, mint stablecoins, provide liquidity, and much more.

    Instead of centralized intermediaries, tBTC uses a randomly selected group of operators running nodes on the Threshold Network to secure deposited Bitcoin through threshold cryptography. That means tBTC requires a threshold majority agreement before operators perform any action with your Bitcoin. By rotating the selection of operators weekly, tBTC protects against any individual or group of operators colluding to fraudulently seize the underlying deposits. By relying on an honest-majoriy-assumption, we can calculate the likelihood any wallet comprised of a quorum of dishonest operators (for a deeper discussion of the probability calculations, see here. An insurance backstop (the coverage pools), serves as an emergency fallback in the event a wallet is compromised.

    Unlike other solutions on the market, users of tBTC trust math, not hardware or people.

    Proxy Re-Encryption (PRE)

    Threshold application – underlying technology

    PRE is an end-to-end encryption protocol that is a more scalable, more flexible form of public-key encryption and enables a group of proxy entities to transform encrypted data from one public key to another, without the power to decrypt the data or gain access to any private keys. PRE equips developers, applications and end-users with secrets management and dynamic access control capabilities. The nodes on the Threshold Network act as these proxy entities and use threshold cryptography to securely and cooperatively re-encrypt data for recipients based on access conditions defined by the data owner.

    PRE is directly applicable to use cases that aim to maintain data ownership while facilitating data sharing capabilities such as paid subscriptions to encrypted content, or the transfer of data ownership for encrypted NFTs. Data, wherever stored, remains private and encrypted while data owners maintain the ability to share that data and cryptographically enforce access controls. Want to get started staking with Threshold and running a node for PRE? Follow this guide:

    PRE Node Setup

    Threshold Multisigs

    Compilation of current multisigs for the Threshold Council and Guilds

    Data Storage

    Setup persistent data directories for the client.

    The client requires two persistent directories. These directories will store configuration files and data generated and used by the client. It is highly recommended to create frequent backups of these directories. Loss of these data may be catastrophic and may lead to slashing.

    The tBTC v2 client will create two subdirectories within the storage directory: keystore and work. You do not need to create these.

    The keystore subdirectory contains sensitive key material data generated by the client. Loosing the keystore data is a serious protocol offense and leads to slashing and potentially losing funds.

    The work directory contains data generated by the client that should persist the client restarts or relocations. If the

    work
    data are lost the client will be able to recreate them, but it is inconvenient due to the time needed for the operation to complete and may lead to losing rewards.

    Assuming Geth was installed for the root user with the command provided in the Operator Account creation step, the operator-key file should be located in the ~/operator-key directory.

    Contained within the operator-key directory is the account key file (operator key file), its name will be similar to the following: UTC--2018-11-01T06-23-57.810787758Z--fa3da235947aab49d439f3bcb46effd1a7237e32

    copy (not move!) this account key file to the config directory created above

    It is crucial to ensure the data directory is persisted and backed up on a regular basis.

    Create folders for tBTC v2 client

    It is the operator’s responsibility to ensure the keystore data are not lost under any circumstances.

    Copy Operator keystore file

    cd /home
    mkdir keep
    cd keep
    mkdir storage config
    cd ~/operator-key
    ls -la
    cp name_of_account_key_file /home/keep/config/name_of_account_key_file

    Council Multisig

    The Threshold Council multisig is set to 6 of 9.

    Treasury Guild Multisig

    This multisig is currently set to 5 of 9.

    Integrations Guild Multisig

    This multisig is currently set to 3 of 5.

    Marketing Guild Multisig

    This multisig is currently set to 5 of 8.

    ESDM - Emergency Security Developer Multisig

    To be created

    Conditions

    This page focuses on Condition types and composition. To understand how Conditions are added and enforced with respect to runtime, check out the Condition Hierarchies page. Several distinct categories of access conditions can be specified and combined:

    • EVM - on-chain state, eg NFT ownership, ETH balance, tx status, contract function call

    • RPC - ethereum RPC calls as defined in the Official API

    • Timelock - time-based conditions, eg Block Height

    We provide many helper objects to streamline the creation of common conditions. An expressive API also allows much more granular control of conditions, and we will provide examples of both methods wherever possible.

    Conditions.ERC721Ownership is a shortcut for building conditions that test for ownership of a specific ERC721 token (NFT):

    If we want to be more verbose we can use Conditions.Condition. The above and below examples are completely equivalent:

    Conditions.ERC721Balance is a shortcut for building conditions that test for ownership of at least one ERC721 token (NFT) within a collection.

    Alternatively:

    Conditions.TimelockCondition is a shortcut for building conditions that test against block height.

    or:

    Conditions.RpcCondition is a shortcut for building conditions that test against standard .

    or:

    Conditions.Condition provides full control over the configuration of a Condition. It takes parameters:

    • contractAddress is the public address of the contract we'd like to query.

    • standardContractType can take values from ERC20 and ERC721. Alternatively, an ABI can be passed through if a non standard contract is being used.

    Here we're checking whether the user owns any T Threshold Network token:

    In this example, we will check that the user is able to vote in the T Threshold DAO. The Threshold staking contract is located at . The function we wish to call is getVotes which takes an address as its parameter. We need to provide the contractAddress, functionName, functionParams, and functionAbi when defining the condition.

    Network Configuration

    Required network configuration for the tBTC v2 staking client.

    Required Ports

    The node has to be accessible publicly to establish and maintain connections with bootstrap nodes and discovered peers. The node exposes metrics and diagnostics services for network health monitoring purposes. Update firewall rules as necessary, including application level firewalls for the following ports

    Purpose
    Config Property
    Protocol
    Default

    An Announced Address is a layered addressing information (multiaddress/multiaddr) announced to the Threshold Network that is used by peers to connect with your node, e.g.: /dns4/bootstrap-0.test.keep.network/tcp/3919 or /ip4/104.154.61.116/tcp/3919.

    If the machine you’re running your node is not exposing a public IP (e.g. it is behind NAT) you should set the network.AnnouncedAddresses (flag: --network.announcedAddresses) configuration property to addresses (ip4 or dns4) under which your node is reachable for the public.

    To read more about multiaddress see the .

    Condition Hierarchies

    Conditions can be attached at several steps in the TAC lifecycle, and they have a fixed hierarchy at runtime. This means default Conditions can be specified and subsequently overwritten later on in the process.

    Strategy Conditions

    Conditions can be attached directly to a Strategy. They have the lowest precedence and are a great place for including defaults or 'fall back' conditions.

    import { Cohort, Conditions, ConditionSet, Strategy } from '@nucypher/nucypher-ts';
    
    const config = {
      threshold: 3,
      shares: 5,
      porterUri: 'https://porter-tapir.nucypher.community',
    };
    const newCohort = await Cohort.create(config);
    
    const NFTOwnership = new Conditions.ERC721Ownership({
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
      chain: 5, // Tapir network uses Görli testnet
      parameters: [5954],
    })
    const conditions = new ConditionSet([NFTOwnership]);
    
    const newStrategy = Strategy.create(
      newCohort,
      conditions
    );

    All encrypter objects that a deployed Strategy produces will automatically have these conditions included. Therefore, all encrypted messages will require these conditions to be satisfied.

    Encrypter Conditions

    This is the next level of precedence in the hierarchy, where each encrypter object can have its own conditions. Assuming the above strategy has been deployed, we can attach conditions in the following way:

    const encrypter = deployedStrategy.encrypter;
    
    const newNFTOwnership = new Conditions.ERC721Ownership({
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
      chain: 5,
      parameters: [5000], // let's change the specific NFT
    })
    
    encrypter.conditions = new ConditionSet([newNFTOwnership])

    This will overwrite the Strategy conditions we defined above - only the new Conditions will be evaluated, not both. All messages encrypted with encrypter will require newNFTOwnership to be satisfied.

    This is the final, and highest priority, Condition type. When encrypting a message, Conditions can be added that apply only to this specific encryption. Again, they will overwrite any Conditions specified during Strategy creation or within the encrypter.

    Here we've actually made our Condition more relaxed, and only require a non-zero balance with the NFT contract.

    Application Authorization & Operator Registration

    The following demonstrates how to authorize applications for tBTC v2 and how to register your operator address via the Threshold Dashboard.

    One important step to get your node operating on the Threshold Network is proper application authorization as well as operator account registration. Applications need only be authorized once.

    It is CRITICALLY important that both the tBTC application as well as the Random Beacon applications are authorized. A node cannot be deployed without both applications being properly authorized.

    Please note: by authorizing these applications, an unbonding period of 45 days will go into effect on the T you stake for these applications. This cool-down period begins the day you submit an unstake request.

    Application Authorization

    To get started, visit the Threshold Dashboard and connect your wallet.

    Threshold Dashboard

    Click on "Configure Apps"

    Authorizing Threshold Applications

    Select BOTH tBTC and Random Beacon applications and enter your desired amount of T to stake per application. Note that the minimum is 40,000T.

    Authorizing Threshold Applications

    Operator Registration

    The operator account is the Ethereum account created on your node. In order for the network to associate your T stake with your node, you must register your Operator Address.

    An Operator for the Provider registration can be submitted just once. The Operator address assignment cannot be updated.

    After both applications have been authorized, click on "Start Mapping" to begin the Operator Registration process.

    Enter your Operator Address in the field provided and click on "Map Address."

    Once the steps above have been successfully completed, you are ready to move on to the next step in the node deployment process.

    Network

    network.port

    TCP

    3919

    Status

    clientInfo.port

    TCP

    9601

    The network port must be exposed publicly for peers to connect to your node.

    The status port must be exposed publicly for rewards allocation.

    Announced Addresses

    libp2p documentation

    Message Conditions

    const NFTBalance = new Conditions.ERC721Balance({
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
      chain: 5,
    });
    
    const plaintext = 'this is a secret';
    const encryptedMessageKit = encrypter.encryptMessage(plaintext, new ConditionSet([NFTBalance]));
    functionAbi is the ABI of the function we'd like to call. This is optional if the contract is a standard ERC20, ERC721 or ERC1155.
  • chain - currently only ethereum is supported, please if you require non-Ethereum based conditions.

  • method the contract method that will be called.

  • parameters are the parameters that will be passed to the contract's method.

  • returnValueTest defines how the return value of the contract call should be evaluated.

  • const NFTOwnership = new Conditions.ERC721Ownership({
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
      // check for ownership of NFT with token ID 5954
      parameters: [5954],
    });
    const NFTOwnershipConfig = {
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
      standardContractType: 'ERC721',
      chain: 1,
      method: 'ownerOf',
      parameters: [5954],
      returnValueTest: {
        comparator: '==',
        value: ':userAddress',
      },
    };
    const NFTOwnership = new Conditions.Condition(NFTOwnershipConfig);
    const NFTBalance = new Conditions.ERC721Balance({
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
    });
    const NFTBalanceConfig = {
      contractAddress: '0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D',
      standardContractType: 'ERC721',
      chain: 5,
      method: 'balanceOf',
      parameters: [':userAddress'],
      returnValueTest: {
        comparator: '>',
        value: 0,
      },
    };
    
    const NFTBalance = new Conditions.Condition(NFTBalanceConfig);
    const timelock = Conditions.TimelockCondition({
      returnValueTest: {
        comparator: '>',
        value: 100,
      },
    });
    const timelockConfig = {
      contractAddress: '',
      standardContractType: '',
      chain: 5,
      method: 'timelock',
      returnValueTest: {
        comparator: '>',
        value: 100,
      },
    };
    const timelock = Conditions.Condition(timelockConfig);
    const rpc = new Conditions.RpcCondition({
      chain: 1,
      method: 'eth_getBalance',
      parameters: [
          ":userAddress",
          "latest"
        ],
      returnValueTest: {
        comparator: ">=",
        value: 10000000000000
      }
    });
    const rpcConfig = {
      contractAddress: '',
      standardContractType: '',
      chain: 1,
      method: 'eth_getBalance',
      parameters: [':userAddress', 'latest'],
      returnValueTest: {
        comparator: '>=',
        value: 10000000000000,
      },
    };
    const rpc = Conditions.Condition(rpcConfig);
    const ERC20Conditions = {
      contractAddress: '0xCdF7028ceAB81fA0C6971208e83fa7872994beE5',
      standardContractType: 'ERC20',
      chain: 5,
      method: 'balanceOf',
      parameters: [':userAddress'],
      returnValueTest: {
        comparator: '>',
        value: 0,
      },
    };
    const customABICondition = {
      contractAddress: '0x01B67b1194C75264d06F808A921228a95C765dd7',
      method: 'getVotes',
      parameters: [':userAddress'],
      functionAbi: {
        inputs: [
          {
            internalType: 'address',
            name: 'account',
            type: 'address',
          },
        ],
        name: 'getVotes',
        outputs: [
          {
            internalType: 'uint96',
            name: '',
            type: 'uint96',
          },
        ],
        stateMutability: 'view',
        type: 'function',
      },
      chain: 1,
      returnValueTest: {
        comparator: '>',
        value: 0,
      },
    };

    Conditions.ERC721Ownership

    Conditions.ERC721Balance

    Conditions.TimelockCondition

    Conditions.RpcCondition

    Conditions.Condition

    Non Zero balance of ERC20 Token

    Function call of nonstandard Contract

    RPC calls
    0x01B67b1194C75264d06F808A921228a95C765dd7

    Don't forget: a tBTC v2 node will not be able to be deployed without successfully authorizing both the tBTC and Random Beacon applications, and registering the node's operator address FIRST.

    Registering Operator Address
    Registering Operator Address
    Contact Us

    Görli Testnet

    Threshold Contracts

    Delivered in @threshold-network/[email protected] NPM package.

    Contract
    Address

    T Token

    Contract
    Address

    Delivered in @keep-network/[email protected] NPM package.

    Contract
    Address
    Contract
    Address

    Delivered in @keep-network/[email protected], @keep-network/[email protected] and @keep-network/[email protected] NPM packages.

    Contract
    Address

    Config File

    Use a config file to store client configuration.

    Application configuration can be stored in a file and passed to the application with the --config flag.

    Example:

    Configuration files in formats TOML, YAML and JSON are supported.

    Sample configuration file:

    Logo
    ./keep-client --config /path/to/your/config.toml start
    # This is a sample TOML configuration file for the Keep client.
    
    [ethereum]
    URL = "ws://127.0.0.1:8546"
    KeyFile = "/Users/someuser/ethereum/data/keystore/UTC--2018-03-11T01-37-33.202765887Z--AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA8AAAAAAAAA"
    
    # Uncomment to override the defaults for transaction status monitoring.
    
    # MiningCheckInterval is the interval in which transaction
    # mining status is checked. If the transaction is not mined within this
    # time, the gas price is increased and transaction is resubmitted.
    #
    # MiningCheckInterval = 60  # 60 sec (default value)
    
    # MaxGasFeeCap specifies the maximum gas fee cap the client is
    # willing to pay for the transaction to be mined. The offered transaction
    # gas cost can not be higher than the max gas fee cap value. If the maximum
    # allowed gas fee cap is reached, no further resubmission attempts are
    # performed. This property should be set only for Ethereum. In case of
    # legacy non-EIP-1559 transactions, this field works in the same way as
    # `MaxGasPrice` property.
    #
    # MaxGasFeeCap = "500 Gwei" # 500 Gwei (default value)
    
    # Uncomment to enable Ethereum node rate limiting. Both properties can be
    # used together or separately.
    #
    # RequestsPerSecondLimit sets the maximum average number of requests
    # per second which can be executed against the Ethereum node.
    # All types of Ethereum node requests are rate-limited,
    # including view function calls.
    #
    # RequestsPerSecondLimit = 150
    
    # ConcurrencyLimit sets the maximum number of concurrent requests which
    # can be executed against the Ethereum node at the same time.
    # This limit affects all types of Ethereum node requests,
    # including view function calls.
    #
    # ConcurrencyLimit = 30
    
    # BalanceAlertThreshold defines a minimum value of the operator's account
    # balance below which the client will start reporting errors in logs.
    # A value can be provided in `wei`, `Gwei` or `ether`, e.g. `7.5 ether`,
    # `7500000000 Gwei`.
    #
    # BalanceAlertThreshold = "0.5 ether" # 0.5 ether (default value)
    
    [network]
    Bootstrap = false
    Peers = [
    	"/ip4/127.0.0.1/tcp/3919/ipfs/16Uiu2HAmFRJtCWfdXhZEZHWb4tUpH1QMMgzH1oiamCfUuK6NgqWX",
    ]
    Port = 3920
    
    # Uncomment to override the node's default addresses announced in the network
    # AnnouncedAddresses = ["/dns4/example.com/tcp/3919", "/ip4/80.70.60.50/tcp/3919"]
    
    # Uncomment to enable courtesy message dissemination for topics this node is
    # not subscribed to. Messages will be forwarded to peers for the duration
    # specified as a value in seconds.
    # Message dissemination is disabled by default and should be enabled only
    # on selected bootstrap nodes. It is not a good idea to enable dissemination
    # on non-bootstrap node as it may clutter communication and eventually lead
    # to blacklisting the node. The maximum allowed value is 90 seconds.
    #
    # DisseminationTime = 90
    
    [storage]
    Dir = "/my/secure/location"
    
    # ClientInfo exposes metrics and diagnostics modules.
    # 
    # Metrics collects and exposes information useful for external monitoring tools usually
    # operating on time series data.
    # All values exposed by metrics module are quantifiable or countable.
    #
    # The following metrics are available:
    # - connected peers count
    # - connected bootstraps count
    # - eth client connectivity status
    # 
    # Diagnostics module exposes the following information:
    # - list of connected peers along with their network id and ethereum operator address
    # - information about the client's network id and ethereum operator address
    [clientInfo]
    Port = 9601
    # NetworkMetricsTick = 60
    # EthereumMetricsTick = 600
    
    # Uncomment to overwrite default values for TBTC config.
    #
    # [tbtc]
    # PreParamsPoolSize = 3000
    # PreParamsGenerationTimeout = "2m"
    # PreParamsGenerationDelay = "10s"
    # PreParamsGenerationConcurrency = 1
    # KeyGenConcurrency = 1
    
    # Developer options to work with locally deployed contracts
    #
    # [developer]
    # TokenStakingAddress = "0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
    # RandomBeaconAddress = "0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
    # WalletRegistryAddress = "0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
    # BridgeAddress = "0xBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"

    TokenStaking

    KeepStake

    NU<>T Vending Machine

    KEEP<>T Vending Machine

    NU Token

    StakingEscrow (stub)

    KEEP Token

    TokenStaking

    Simple PRE Application (Tapir testnet)

    Bridge

    RandomBeacon

    Legacy NU Contracts

    Legacy Keep Contracts

    PRE Application Contracts

    TBTC Application Contracts

    0x3f16380656cAE45D3f80D8833682d2b606eD094A

    TBTC

    TBCTVault

    VendingMachine

    WalletRegistry

    0x1da5d88C26EA4f87b5e09C3452eE2384Ee20DC75
    0xC76796B031232976cb17521342B0d12283588E6F
    0x8D4Ccc04D17d055b88fbaB8634C7F0611d8Aa946
    0x8d1EDfee0510537E1081a28Fa4A94769Cfa3969a
    0x26bDc8Cb2D4F55Af3B43568069b65B435bCdc32c
    0xd696d5a9b083959587F30e487038529a876b08C2
    0x22647FfAe391540d584599818CA22fdF18890753
    0x73A63e2Be2D911dc7eFAc189Bfdf48FbB6532B5b
    0xaF96aa6000ec2B6CF0Fe6B505B6C33fa246967Ca
    0x0Cad3257C4B7ec6de1f6926Fbf5714255a6632c3
    0xF177CfA720ceC42841c04A458f6c68e1243C1b49
    0x679874fBE6D4E7Cc54A59e315FF1eB266686a937
    0x65eB0562FCe858f8328858c76E689aBedB78621F
    0x36B7383077a2CEeFd53e796512760a1888cEeb97
    0x0f0E2afF99A55B11026Fb270A05f04d37724dE86

    PRE Node Setup

    This document provides basic instructions for use of the nucypher-ops utility for setting up PRE nodes.

    This document will help you get a node running to which you can bond your stake. Please note that running a node is not a passive activity.

    Nucypher-ops is an ansible script that will setup and configure a PRE node for you. Currently, the script supports AWS and Digital Ocean. This document will guide you through the setup process using visuals from DigitalOcean.

    Local Machine Considerations

    Install Ubuntu 20.04.4 LTS through the Windows Store:

    WSL is the most convenient way to run nucypher-ops on a Windows based local machine

    To begin, update your local machine and install dependencies

    sudo apt update
    sudo apt
    

    Read prompts and respond appropriately. This will take a few minutes.

    Install Python and pip on your local machine, if you don't have it already:

    Python Website

    Visit the

    PyPA Website

    Visit the and follow the steps provided to make sure that you have a working Python with pip installed.

    To begin, update your local machine and install dependencies

    Read prompts and respond appropriately. This will take a few minutes.

    Generate an SSH key pair. We will need the public key.

    Visit the website to learn about OpenSSH.

    Copy the highlighted part

    In your Digital Ocean dashboard:

    Go to Settings > Security and click the Add SSH Key button.

    Paste the key into the box, give your key a name, and click the Add SSH Key button.

    Open a Text Document to make notes. Copy the SSH Fingerprint into this text file.

    While we're here, let's create an API key as well. Go to API > Tokens/Keys and click the Generate New Token button.

    Name your token and click the Generate New Token button.

    Copy the API Key into your Text file or password manager.

    The PRE application requires access to an Ethereum endpoint, as well as a Polygon endpoint. One solution is to use a provider such as , , or . Each has their own pros and cons. Review them carefully.

    Once you have made your decision(s) and signed up for an account, login to your account and setup an endpoint for Ethereum. The setup steps are very straightforward for each provider.

    Make sure you select Mainnet for each endpoint. You will receive what looks like a https web address, Infura calls it an Endpoint, Quicknode refers to it as a Web3 endpoint. Make sure that the endpoint you copy starts with https.

    Copy each of the endpoints to your text document or into your password manager. We will use them shortly.

    Let's review and make sure you have everything needed to be successful:

    • SSH key pair fingerprint

    • API Access token

    • Endpoint URL for Ethereum

    • Endpoint URL for Polygon

    These items should be kept readily available.

    This will download the utility, and install dependencies. This process will take several minutes.

    Execute the following and be ready to answer questions from the utility:

    This will connect to your Digital Ocean account, spin up a VPS, configure and secure it, and install all of the necessary software for you.

    The utility will ask which provider you are using. Answer accordingly and press ENTER.

    Provide your API Key and press ENTER.

    Provide your SSH Fingerprint and press ENTER.

    Then be patient.

    In a few minutes, you'll be ready to bond your stake.

    Provide your ETH endpoint when requested and press ENTER.

    Provide your Polygon endpoint when requested and press ENTER.

    Wait for it...

    The items at the bottom are your node's IP address and Operator address, to which you will need to bond your stake.

    To bond your stake to your new PRE node, click below:

    Nucypher-ops is a convenient tool for deploying a PRE node on the Threshold network. In case you need to make changes to the configuration of the utility on your local machine, these are the default directories where config files are stored locally:

    To find out about other features try

    if you need to update your node to a new version of NuCypher just execute

    upgrade
    sudo apt-get install libffi-dev python3-dev python3-pip python3-virtualenv build-essential libssl-dev
    sudo apt update
    sudo apt upgrade
    sudo apt-get install libffi-dev python3-dev python3-pip python3-virtualenv build-essential libssl-dev
    ssh-keygen -t rsa
     cat .ssh/id_rsa.pub
    pip install nucypher-ops
    nucypher-ops nodes create
    nucypher-ops ursula deploy
    ~/.local/share/nucypher-ops
    ~/Library/Application Support/nucypher-ops
    nucypher-ops --help
    nucypher-ops ursula update

    SSH Key

    Do not share the fingerprint with anyone. Save and store in a secure place such as a password manager.

    Unless you plan to periodically refresh this token yourself, you can set "Expiration" to NEVER

    L2 Providers

    Do NOT share your provider addresses with anyone.

    Checklist

    Installing nucypher-ops

    Creating Your Node

    Deploying Ursula

    Make sure you take note of your operator address.

    Nucypher-Ops Config File location

    Caution: Do not make changes to these files without making a backup of them first. Do not make changes to these files unless you know and understand what you are doing.

    Caution: Breaking these files may lead to your node becoming permanently inaccessible. Use extreme caution.

    Post Install

    Keep in mind staking is an active process, and that you are responsible for operational security, as well as backing up any relevant data. Carefully review your firewall rules and make necessary adjustments. nucypher-ops configures a PRE node, it does not setup security measures.

    Python.org Website
    pypa.io Website
    OpenSSH
    Infura
    Quicknode
    Alchemy
    Generating a new SSH Key
    New SSH Key
    Adding a new SSH Key
    Adding a new SSH Key
    SSH Fingerprint
    Generating an API Access Token
    Generating an API Access Token
    Generating an API Access Token
    Sample text file
    nucypher-ops installation
    Selecting VPS provider in nucypher-ops
    Providing API Key in nucypher-ops
    Providing SSH fingerprint in nucypher-ops
    Creating VPS instance & PRE node
    VPS instance & PRE node created
    Configuring and deploying Ursula
    PRE node ready to bond

    Testnet tBTC v2 node Setup

    This page will show you how to launch a tBTC v2 node on the testnet.

    This is a TESTNET guide document. Following this document will not result in a node enabling you to earn mainnet rewards.

    Recommended Machine Types

    While it is possible to run the client on a local machine, this is not recommended.

    Your operating environment will ultimately dictate what machine type to go with. This is particularly relevant if you’re running a containerized solution where multiple applications are sharing VM resources. The below types are sufficient for running one instance of the tBTC v2 Node.

    The preferred OS is Ubuntu.

    VPS Provider
    VPS Type

    AWS

    A Keep Node requires a connection to a WebSocket Ethereum API. You should obtain a WS API URL from a service provider (e.g. , , ) or run your own Ethereum node (e.g. ).

    The client requires an Ethereum Key File of an Operator Account to connect to the Ethereum chain. This account is created in a subsequent step using Geth (GoEthereum).

    The Ethereum Key File is expected to be encrypted with a password. The password has to be provided in a prompt after the client starts or configured as a KEEP_ETHEREUM_PASSWORD environment variable.

    The Operator Account has to maintain a positive Ether balance at all times.

    To create a new Ethereum account, (GoEthereum) and create a new account using the command below. This account will subsequently be referred to as the Operator Account.

    When prompted, provide a password to protect the operator key file.

    Once the process completes, your public key will be displayed. Take note of your Operator Account public key.

    Your Operator Account will need to be funded with goerli ETH and maintain a positive balance at all times to ensure proper operation and availability of your tBTC v2 node.

    The node has to be accessible publicly to establish and maintain connections with bootstrap nodes and discovered peers.

    The node exposes metrics and diagnostics services for monitoring. A network port has to be exposed publicly, so the peers can connect to your node. A Diagnostics Port has to be exposed publicly, for the rewards allocation.

    Purpose
    Config Property
    Protocol
    Default

    An Announced Address is a layered addressing information (multiaddress/multiaddr) announced to the Threshold Network that is used by peers to connect with your node, e.g.: /dns4/bootstrap-0.test.keep.network/tcp/3919 or /ip4/104.154.61.116/tcp/3919.

    If the machine you’re running your node is not exposing a public IP (e.g. it is behind NAT) you should set the network.AnnouncedAddresses (flag: --network.announcedAddresses) configuration property to an addresses (ip4 or dns4) under which your node is reachable for the public.

    To read more about multiaddress see the .

    One important step to get your node operating on the Threshold Network is proper application authorization as well as operator account registration. Applications need only be authorized once.

    To get started, visit the Threshold Dashboard and connect your wallet.

    Click on "Configure Apps"

    Select BOTH tBTC and Random Beacon applications and enter your desired amount of T to stake per application. Note that the minimum is 40,000T.

    The operator account is the Ethereum account created on your node. In order for the network to associate your T stake with your node, you must register your Operator Address.

    After both applications have been authorized, click on "Start Mapping" to begin the Operator Registration process.

    Enter your Operator Address in the field provided and click on "Map Address."

    Once the steps above have been successfully completed, you are ready to move on to the next step in the node deployment process.

    The client requires two persistent directories. These directories will store configuration files and data generated and used by the client. It is highly recommended to create frequent backups of these directories. Loss of these data may be catastrophic and may lead to slashing.

    The tBTC v2 client will create two subdirectories within the storage directory: keystore and work. You do not need to create these.

    The keystore subdirectory contains sensitive key material data generated by the client. Loosing the keystore data is a serious protocol offense and leads to slashing and potentially losing funds.

    The work directory contains data generated by the client that should persist the client restarts or relocations. If the work data are lost the client will be able to recreate them, but it is inconvenient due to the time needed for the operation to complete and may lead to losing rewards.

    Assuming for the root user with the command provided in the step, the operator-key file should be located in the ~/operator-key directory.

    Contained within the operator-key directory is the account key file (operator key file), its name will be similar to the following: UTC--2018-11-01T06-23-57.810787758Z--fa3da235947aab49d439f3bcb46effd1a7237e32

    copy (not move!) this account key file to the config directory created above

    Install or update Docker to the latest version. Visit the for detailed instructions. Use the command below to find your installed version if needed:

    To launch the tBTC v2 client, several configuration flags and environmental values need to be set. For simplicity, a bash script can be used rather than typing or pasting all the flags into the console.

    Create the launch script:

    And paste the following:

    Save and close the file, and make it executable:

    To launch the tBTC v2 client, execute:

    Unless the --detach flag was removed from the startup script, there will be no console output. In order to check your node, retrieve the Docker logs.

    First, find your Docker instance identification, it'll be a random combination of words, e.g. stinky_brownie:

    Use your specific identification and substitute:

    Scroll down about half a page, and you should see the following:

    Congratulations, your node is up and running.

    c5.large

    Azure

    F2s v2

    Google Cloud

    n2-highcpu-2

    Self-hosted

    2 vCPU / 2 GB RAM / 1 GiB Persistent Storage

    geth account new --keystore ./operator-key

    Network

    network.port

    TCP

    3919

    cd /home
    mkdir keep
    cd keep
    mkdir storage config
    cd ~/operator-key
    ls -la
    cp name_of_account_key_file /home/keep/config/name_of_account_key_file
    docker --version
    nano keep.sh
    # Keep Testnet tBTC v2 Client
    #
    # Ethereum endpoint WebSocket URL
    # This can be a provider such as Infura, Alchemy, Ankr, etc or your own Geth Nodeq
    # ETHEREUM_WS_URL="wss://goerli.infura.io/ws/v3/redacted_credentials"
    # note: only replace characters inside the " ". The Quotation marks must be retained
    ETHEREUM_WS_URL="<Ethereum API WS URL>"
    
    # copied to home/keep/config earlier
    OPERATOR_KEY_FILE_NAME="<Operator Account keyfile name>"
    
    # password set during Operator Account Address creation
    OPERATOR_KEY_FILE_PASSWORD="<Operator Account keyfile password>"
    
    # To configure your node with a Public IP, enter it below.
    PUBLIC_IP="<PUBLIC_IP_OF_MACHINE>"
    # Alternatively, you can use DNS.
    # To configure DNS, modify the last line of the script
    # and add your DNS in the following format:
    # /dns4/bootstrap-1.test.keep.network/tcp/3919
    
    # Setup configuration and storage directories
    # THESE MUST BE PERSISTENT STORAGE
    CONFIG_DIR="/home/keep/config"
    STORAGE_DIR="/home/keep/storage"
    
    docker run \
        --detach \
        --restart on-failure \
        --volume $CONFIG_DIR:/mnt/keep/config \
        --volume $STORAGE_DIR:/mnt/keep/storage \
        --env KEEP_ETHEREUM_PASSWORD=$OPERATOR_KEY_FILE_PASSWORD \
        --env LOG_LEVEL=info \
        --log-opt max-size=100m \
        --log-opt max-file=3 \
        -p 3919:3919 \
        -p 9601:9601 \
        us-docker.pkg.dev/keep-test-f3e0/public/keep-client \
        start \
        --goerli \
        --ethereum.url $ETHEREUM_WS_URL \
        --ethereum.keyFile /mnt/keep/config/$OPERATOR_KEY_FILE_NAME \
        --storage.dir /mnt/keep/storage \
        --network.announcedAddresses /ip4/$PUBLIC_IP/tcp/3919
    
    sudo chmod +x keep.sh
    sudo bash keep.sh
    sudo docker ps
    sudo docker logs stinky_brownie >& /path/to/output/file
    
    ▓▓▌ ▓▓ ▐▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▄
    ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▌▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
      ▓▓▓▓▓▓    ▓▓▓▓▓▓▓▀    ▐▓▓▓▓▓▓    ▐▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
      ▓▓▓▓▓▓▄▄▓▓▓▓▓▓▓▀      ▐▓▓▓▓▓▓▄▄▄▄         ▓▓▓▓▓▓▄▄▄▄         ▐▓▓▓▓▓▌   ▐▓▓▓▓▓▓
      ▓▓▓▓▓▓▓▓▓▓▓▓▓▀        ▐▓▓▓▓▓▓▓▓▓▓         ▓▓▓▓▓▓▓▓▓▓▌        ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
      ▓▓▓▓▓▓▀▀▓▓▓▓▓▓▄       ▐▓▓▓▓▓▓▀▀▀▀         ▓▓▓▓▓▓▀▀▀▀         ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▀
      ▓▓▓▓▓▓   ▀▓▓▓▓▓▓▄     ▐▓▓▓▓▓▓     ▓▓▓▓▓   ▓▓▓▓▓▓     ▓▓▓▓▓   ▐▓▓▓▓▓▌
    ▓▓▓▓▓▓▓▓▓▓ █▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓
    ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▐▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓  ▓▓▓▓▓▓▓▓▓▓
    
    Trust math, not hardware.
    	
    -----------------------------------------------------------------------------------
    | Keep Client Node                                                                |
    |                                                                                 |
    | Version: Version: v2.0.0-m1 (4d745f6d0)                                         |
    |                                                                                 |
    | Operator: 0x_your_operator_address                                              |
    |                                                                                 |
    | Port: 3919                                                                      |
    | IPs : /ip4/111.222.333.444/tcp/3919/ipfs/redacted                               |
    |                                                                                 |
    | Contracts:                                                                      |
    | RandomBeacon   : 0x2bA82903B635a96154A515488d2952E86D6adc3A                     |
    | WalletRegistry : 0x2363cc10b7680000C02E4a7067A68d1788ffc86F                     |
    | TokenStaking   : 0x69f962a0fbA5635e84eC94131f9072108E2E4F24                     |
    -----------------------------------------------------------------------------------

    Ethereum API

    Please do NOT reuse an operator account that is being used for PRE or other applications.

    Install Geth (GoEthereum)

    Use a password manager to generate a strong password and store it safely. It will be needed again during setup.

    Avoid passwords that contain the following characters: ', ", `, $ These characters may be interpreted as part of the configuration which can lead to undesirable outcomes that may be extremely time intensive to correct.

    DO NOT LOSE THE PASSWORD TO THE OPERATOR ACCOUNT.

    Funding your Operator Account

    Network Configuration

    Update firewall rules as necessary, including application level firewalls.

    A Diagnostics Port has to be exposed publicly, for the rewards allocation.

    Announced Addresses

    It is CRITICALLY important that both the tBTC application as well as the Random Beacon applications are authorized. A node cannot be deployed without both applications being properly authorized.

    Please note: by authorizing these applications, an unbonding period of 45 days will go into effect on the T you stake for these applications. This cool-down period begins the day you submit an unstake request.

    Application Authorization

    Operator Registration

    An Operator for the Provider registration can be submitted just once. The Operator address assignment cannot be updated.

    Don't forget: a tBTC v2 node will not be able to be deployed without successfully authorizing both the tBTC and Random Beacon applications, and registering the node's operator address FIRST.

    Create Folder Structure

    It is crucial to ensure the data directory is persisted and backed up on a regular basis.

    Create folders for tBTC v2 client

    It is the operator’s responsibility to ensure the keystore data are not lost under any circumstances.

    Copy Operator keystore file

    Install Docker

    Docker Launch Script

    The --detach property will prevent the status messages from the client to be printed to the console. Review the Docker logs for detailed status information.

    The path shown in the example configuration will differ from yours. Make sure it is configured correctly.

    Client Startup

    Alchemy
    Infura
    Ankr
    Geth
    install Geth
    libp2p docummentation
    Geth was installed
    Operator Account creation
    Official Docker website
    Threshold Dashboard
    Authorizing Threshold Applications
    Authorizing Threshold Applications
    Registering Operator Address
    Registering Operator Address

    Status

    clientInfo.port

    TCP

    9601

    documentation
    Safe{Wallet}safe
    Council Multisig on Safe
    Logo
    Safe{Wallet}safe
    Integrations Guild Multisig on Safe
    https://www.youtube.com/watch?t=10s&v=SXn1zShgVI8www.youtube.com
    Logo
    https://youtu.be/9jnDtNQ_GEcyoutu.be
    tBTC intro video
    Safe{Wallet}safe
    Marketing Guild Multisig on Safe
    Logo
    Safe{Wallet}safe
    Treasury Guild Multisig on Safe
    Logo
    https://stake.nucypher.network/manage/bondstake.nucypher.network
    Bonding UI link

    Links

    Resource
    Link

    Threshold Website

    Staking Dashboard

    PRE Application Dashboard

    Github(s)

    Discord

    Governance Forum

    Blog

    Twitter

    https://threshold.network
    https://dashboard.threshold.network
    https://stake.nucypher.network/manage/operator
    https://github.com/threshold-network
    https://github.com/nucypher/
    https://github.com/keep-network/
    https://github.com/threshold-usd
    https://discord.gg/threshold
    https://forum.threshold.network
    https://blog.threshold.network
    https://twitter.com/thetnetwork