From 497004798bcf7c04f378e73217bc1091e8f608db Mon Sep 17 00:00:00 2001 From: Percival Lucena Date: Sun, 23 Aug 2026 16:40:29 -0300 Subject: [PATCH 1/4] docs: add COTI ERC-7984 as a top-level product section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a new product section comparing COTI's Privacy on Demand pERC20 with FHE-based implementations of the ERC-7984 confidential-token standard. - coti-erc7984/README.md — overview, section nav, and summary table - Six sub-pages: precision and decimals, host-chain deployment, transaction economics, transfer semantics, concurrency, deployed contracts - Listed in SUMMARY.md after Privacy on Avalanche - Cross-linked from the Privacy Portal's privateerc20.sol.md Co-Authored-By: Claude Opus 5 --- SUMMARY.md | 7 +++++ coti-erc7984/README.md | 30 +++++++++++++++++++ coti-erc7984/concurrency.md | 7 +++++ coti-erc7984/deployed-contracts.md | 25 ++++++++++++++++ coti-erc7984/host-chain-deployment.md | 16 ++++++++++ coti-erc7984/precision-and-decimals.md | 15 ++++++++++ coti-erc7984/transaction-economics.md | 22 ++++++++++++++ coti-erc7984/transfer-semantics.md | 17 +++++++++++ .../developer-guide/privateerc20.sol.md | 2 ++ 9 files changed, 141 insertions(+) create mode 100644 coti-erc7984/README.md create mode 100644 coti-erc7984/concurrency.md create mode 100644 coti-erc7984/deployed-contracts.md create mode 100644 coti-erc7984/host-chain-deployment.md create mode 100644 coti-erc7984/precision-and-decimals.md create mode 100644 coti-erc7984/transaction-economics.md create mode 100644 coti-erc7984/transfer-semantics.md diff --git a/SUMMARY.md b/SUMMARY.md index 86a4d7b..815dd5a 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -152,6 +152,13 @@ * [Cookbook: private investor allocations with PoD](privacy-on-avalanche/cookbook-private-investor-allocations.md) * [Tutorial: private Adder on Avalanche Fuji](privacy-on-avalanche/tutorial-private-adder-fuji.md) * [Tutorial: custom privacy logic with PoD](privacy-on-avalanche/tutorial-custom-logic.md) +* [COTI ERC-7984](coti-erc7984/README.md) + * [Precision and decimals](coti-erc7984/precision-and-decimals.md) + * [Host-chain deployment](coti-erc7984/host-chain-deployment.md) + * [Transaction economics](coti-erc7984/transaction-economics.md) + * [Transfer semantics](coti-erc7984/transfer-semantics.md) + * [Concurrency](coti-erc7984/concurrency.md) + * [Deployed contracts](coti-erc7984/deployed-contracts.md) ## Security diff --git a/coti-erc7984/README.md b/coti-erc7984/README.md new file mode 100644 index 0000000..3efb585 --- /dev/null +++ b/coti-erc7984/README.md @@ -0,0 +1,30 @@ +# COTI ERC-7984 + +**Confidential tokens on the chains you already use.** + +Privacy on Demand brings encrypted balances and encrypted transfers to any EVM chain — no privacy-native L1, no specialised rollup, no migration. Live today on Avalanche Fuji and Ethereum Sepolia. + +COTI's implementation of the [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) confidential-token interface is the PoD ERC-7984: a 1:1 collateralised confidential wrapper deployed on the host chain, with the encrypted computation performed on COTI behind the scenes. It exposes ERC-7984 metadata and emits `ConfidentialTransfer` events, so explorers and integrators treat it as a first-class confidential token. + +This section compares that implementation against FHE-based implementations of the same standard, dimension by dimension. + +## In this section + +* [**Precision and decimals**](precision-and-decimals.md) — 256-bit values against the 64-bit ceiling, and why it decides whether a wrapper can mirror an 18-decimal asset. +* [**Host-chain deployment**](host-chain-deployment.md) — what the token requires of the chain it runs on, and what it requires of the user. +* [**Transaction economics**](transaction-economics.md) — encrypted-input size, on-chain footprint, and where the cryptographic work happens. +* [**Transfer semantics**](transfer-semantics.md) — encrypted allowances with standard `approve` / `transferFrom`, and failures that reveal nothing. +* [**Concurrency**](concurrency.md) — multiple in-flight requests per account, ordered by a monotonic nonce. +* [**Deployed contracts**](deployed-contracts.md) — the six pTokens live on Avalanche Fuji and Ethereum Sepolia, and how new ones are listed. + +## Why teams choose COTI ERC-7984 + +| | | +| :--------------------------- | :------------------------------------------------------------------------ | +| **Wrap real assets** | 18-decimal confidential WETH and WAVAX — out of reach for 64-bit designs | +| **Keep your chain** | Runs on any EVM chain; no privacy L1, no migration | +| **Full precision** | 256-bit values, no supply ceiling | +| **Small on-chain footprint** | ~192-byte inputs, 2-slot balances | +| **Instant for users** | No client-side proof generation | +| **Private allowances** | Exact encrypted amounts, not public blanket authority | +| **Ship fast** | Factory-deployed portal + token pair per asset | diff --git a/coti-erc7984/concurrency.md b/coti-erc7984/concurrency.md new file mode 100644 index 0000000..10dcbb4 --- /dev/null +++ b/coti-erc7984/concurrency.md @@ -0,0 +1,7 @@ +# Concurrency + +## Concurrency that keeps up with users + +Multiple transfers, mints, and burns from the same account can be in flight simultaneously. Each is tracked independently by request id, and a monotonic nonce guarantees results always apply in the correct order. **No queue, no serialisation, no waiting for one transfer to clear before starting the next.** + +For how asynchronous private operations settle in general, see [Async private operations](../privacy-on-demand/async-private-operations.md). diff --git a/coti-erc7984/deployed-contracts.md b/coti-erc7984/deployed-contracts.md new file mode 100644 index 0000000..3a507ce --- /dev/null +++ b/coti-erc7984/deployed-contracts.md @@ -0,0 +1,25 @@ +# Deployed contracts + +## Live on two public testnets + +Six confidential tokens, deployed and operating. + +**Avalanche Fuji** + + +| Token | Address | Decimals | +| :------- | :------------------------------------------- | :------: | +| `p.MTT` | `0x02f284a1968160E1d3e4bC2BA3261be49725E765` | 18 | +| `p.USDC` | `0x21576D8CCE47d044C5815bd59eca1F6DA94c65A5` | 6 | +| `p.AVAX` | `0x74d47cD68203066c97BA99787Fe1e0c68Ce42b04` | 18 | + +**Ethereum Sepolia** + + +| Token | Address | Decimals | +| :------- | :------------------------------------------- | :------: | +| `p.MTT` | `0x0510F0b32828D5fB472dE5A5bE30b370c5D1a056` | 18 | +| `p.USDC` | `0xD7B3D49F85000489708B7db5B0f1a8693Fc707f3` | 6 | +| `p.ETH` | `0xd33A363459c6Ee0C4F8504E380E8D3Aa4F209116` | 18 | + +Each pair is deployed by `PrivacyPortalFactory` as a minimal-proxy clone — **one portal and one pToken per asset**, so listing a new confidential token is a factory call, not an engineering project. diff --git a/coti-erc7984/host-chain-deployment.md b/coti-erc7984/host-chain-deployment.md new file mode 100644 index 0000000..c2dac66 --- /dev/null +++ b/coti-erc7984/host-chain-deployment.md @@ -0,0 +1,16 @@ +# Host-chain deployment + +## Deploy anywhere there is an Inbox + +Confidential tokens have historically meant moving to a privacy chain and asking your users to follow. PoD inverts that: the token lives on **your** chain, and the encrypted computation happens on COTI behind the scenes. + +| | | +| :----------------------------- | :-------------------------------------------------------------- | +| **Chains supported** | Any EVM chain with a PoD Inbox deployed | +| **Live today** | Avalanche Fuji, Ethereum Sepolia | +| **Required of the host chain** | Nothing — no FHE precompiles, no custom opcodes, no forked EVM | +| **Required of the user** | A standard wallet | + +Your liquidity, your users, and your existing integrations stay exactly where they are. + +For the components behind the Inbox, see [Architecture and main components](../privacy-on-demand/architecture-and-components.md) in the Privacy on Demand section. diff --git a/coti-erc7984/precision-and-decimals.md b/coti-erc7984/precision-and-decimals.md new file mode 100644 index 0000000..4fea43a --- /dev/null +++ b/coti-erc7984/precision-and-decimals.md @@ -0,0 +1,15 @@ +# Precision and decimals + +## Wrap the assets that actually exist + +PoD ERC-7984 is a 1:1 collateralised confidential wrapper. Lock WETH, get `p.ETH`. Lock USDC, get `p.USDC`. The private token mirrors the underlying exactly — same decimals, same supply, same value — and unwraps back on demand. + +That "same decimals" part is where PoD stands alone. + +**FHE-based confidential token standards store balances as 64-bit encrypted integers.** At 18 decimals, a 64-bit ceiling caps a token at roughly **18.4 whole units** before it overflows. A confidential 1:1 WETH wrapper is not difficult under that constraint — it is arithmetically impossible above ~18 ETH. + +PoD carries **full 256-bit precision** end to end: 18 decimals, `uint256` range, no ceiling worth naming. Four of the six pTokens live today are 18-decimal, including `p.ETH` and `p.AVAX`. + +> **If you want to wrap real liquidity confidentially, 256-bit is not a preference. It is the entry requirement.** + +The [deployed contracts](deployed-contracts.md) page lists the decimals of each live pToken. diff --git a/coti-erc7984/transaction-economics.md b/coti-erc7984/transaction-economics.md new file mode 100644 index 0000000..23e8e4b --- /dev/null +++ b/coti-erc7984/transaction-economics.md @@ -0,0 +1,22 @@ +# Transaction economics + +## Built for real transaction economics + +Confidentiality usually arrives with a size problem. FHE-based tokens attach a zero-knowledge input proof to every encrypted value — commonly **16–20 KB per input** — and offload multi-kilobyte ciphertext blobs off-chain. + +PoD's encrypted values are small enough to treat like ordinary transaction data. + +| | **PoD ERC-7984** | **FHE-based confidential tokens** | +| :--------------- | :------------------- | :--------------------------------------- | +| Encrypted input | **~192 bytes** | ~16,000–20,000 bytes | +| On-chain balance | **2 storage slots** | Handle on-chain, multi-KB blob offloaded | +| Client-side work | **Encrypt and sign** | Generate a ZK proof, per transaction | +| Numeric range | **256-bit** | 64-bit | + +**Roughly two orders of magnitude smaller on input.** Confidential transfers that fit comfortably inside normal block economics, on chains that were never designed for privacy. + +## No proving in the browser + +FHE inputs require the user's device to generate a zero-knowledge proof before a transaction can even be submitted — seconds of computation, and a frozen UI while it runs. + +PoD asks the client to **encrypt and sign**. That is it. The wallet does what wallets already do, and the transaction goes out immediately. On mobile, on low-end hardware, and at scale, that difference compounds. diff --git a/coti-erc7984/transfer-semantics.md b/coti-erc7984/transfer-semantics.md new file mode 100644 index 0000000..9b3fd3c --- /dev/null +++ b/coti-erc7984/transfer-semantics.md @@ -0,0 +1,17 @@ +# Transfer semantics + +## Precise, confidential approvals + +PoD keeps the allowance model developers already know — and encrypts it. + +- **Exact amounts.** Approve 50 tokens, not blanket authority over the balance. +- **Encrypted on-chain.** The allowance value is a ciphertext, readable only by the owner and the spender. +- **Standard semantics.** `approve` / `transferFrom`, the shape every integrator already knows. + +Blanket time-boxed operator models grant a spender full authority over a balance until expiry, and record that authority publicly. PoD grants a specific encrypted amount, and keeps the amount private. + +## Failure that reveals nothing + +When an encrypted transfer exceeds a balance, PoD resolves it inside the garbled circuit: the effective amount becomes zero and the request completes normally. **No revert, no error code, no observable difference** between a transfer that moved value and one that did not. + +Insufficient balances stay as private as sufficient ones. diff --git a/coti-privacy-portal/developer-guide/privateerc20.sol.md b/coti-privacy-portal/developer-guide/privateerc20.sol.md index 529360a..731aa42 100644 --- a/coti-privacy-portal/developer-guide/privateerc20.sol.md +++ b/coti-privacy-portal/developer-guide/privateerc20.sol.md @@ -39,6 +39,8 @@ PrivateERC20 follows the ERC20 interface, but changes how data is stored and exp | Supports plain uint256 operations | Yes | Yes | | Supports encrypted operations | No | Yes (`itUint256`, `gtUint256` variants) | +For a comparison against the [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) confidential-token standard — and how COTI's Privacy on Demand `pERC20` compares with FHE-based implementations on encrypted-input size, numeric range, and allowance semantics — see [COTI ERC-7984](../../coti-erc7984/README.md). + ### How it works #### Balances From df2c2c28c0a3f3817b2c7442f703aafceeb920e4 Mon Sep 17 00:00:00 2001 From: Naiem Date: Sun, 30 Aug 2026 10:13:06 +0000 Subject: [PATCH 2/4] docs: reframe coti-erc7984 as compatible alternative, not full ERC-7984 Rewrite the section as research positioning vs Zama/FHE: draft-standard stance, on-chain DA, decrypt trust model, and validateCiphertext vs ZK input proofs. Co-authored-by: Cursor --- SUMMARY.md | 6 +- coti-erc7984/README.md | 58 ++++++++---- coti-erc7984/compatibility-and-divergence.md | 52 +++++++++++ coti-erc7984/decryption-trust-model.md | 68 ++++++++++++++ coti-erc7984/deployed-contracts.md | 4 +- coti-erc7984/host-chain-deployment.md | 6 +- coti-erc7984/input-validation.md | 79 ++++++++++++++++ coti-erc7984/on-chain-data-availability.md | 89 +++++++++++++++++++ coti-erc7984/precision-and-decimals.md | 8 +- coti-erc7984/transaction-economics.md | 22 ++--- coti-erc7984/transfer-semantics.md | 8 +- .../developer-guide/privateerc20.sol.md | 2 +- 12 files changed, 359 insertions(+), 43 deletions(-) create mode 100644 coti-erc7984/compatibility-and-divergence.md create mode 100644 coti-erc7984/decryption-trust-model.md create mode 100644 coti-erc7984/input-validation.md create mode 100644 coti-erc7984/on-chain-data-availability.md diff --git a/SUMMARY.md b/SUMMARY.md index 815dd5a..9c0c3d3 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -152,7 +152,11 @@ * [Cookbook: private investor allocations with PoD](privacy-on-avalanche/cookbook-private-investor-allocations.md) * [Tutorial: private Adder on Avalanche Fuji](privacy-on-avalanche/tutorial-private-adder-fuji.md) * [Tutorial: custom privacy logic with PoD](privacy-on-avalanche/tutorial-custom-logic.md) -* [COTI ERC-7984](coti-erc7984/README.md) +* [COTI confidential tokens & ERC-7984 compatibility](coti-erc7984/README.md) + * [Compatibility and divergence](coti-erc7984/compatibility-and-divergence.md) + * [On-chain data availability](coti-erc7984/on-chain-data-availability.md) + * [Decryption trust model](coti-erc7984/decryption-trust-model.md) + * [Input validation](coti-erc7984/input-validation.md) * [Precision and decimals](coti-erc7984/precision-and-decimals.md) * [Host-chain deployment](coti-erc7984/host-chain-deployment.md) * [Transaction economics](coti-erc7984/transaction-economics.md) diff --git a/coti-erc7984/README.md b/coti-erc7984/README.md index 3efb585..e508bf1 100644 --- a/coti-erc7984/README.md +++ b/coti-erc7984/README.md @@ -1,30 +1,54 @@ -# COTI ERC-7984 +# COTI confidential tokens & ERC-7984 compatibility -**Confidential tokens on the chains you already use.** +**Confidential tokens with encrypted balances and transfers — without treating an unfinished standard as product identity.** -Privacy on Demand brings encrypted balances and encrypted transfers to any EVM chain — no privacy-native L1, no specialised rollup, no migration. Live today on Avalanche Fuji and Ethereum Sepolia. +[ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) describes a confidential fungible-token interface aimed at FHE-style stacks (notably Zama / OpenZeppelin confidential contracts). COTI does **not** implement ERC-7984 as a full standard. COTI provides a **confidential-token alternative** with selective compatibility where it helps explorers and integrators — and deliberate divergence where ERC-7984’s design fights COTI’s on-chain privacy model. -COTI's implementation of the [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) confidential-token interface is the PoD ERC-7984: a 1:1 collateralised confidential wrapper deployed on the host chain, with the encrypted computation performed on COTI behind the scenes. It exposes ERC-7984 metadata and emits `ConfidentialTransfer` events, so explorers and integrators treat it as a first-class confidential token. +This section is a research comparison: why the designs differ, what that unlocks on COTI, and how deployed PoD confidential wrappers fit in. -This section compares that implementation against FHE-based implementations of the same standard, dimension by dimension. +## Why COTI is not “an ERC-7984 implementation” + +| Reason | What it means | +| :----- | :------------ | +| **Draft standard** | ERC-7984 is incomplete; locking product identity to it is premature. | +| **Ciphertext format** | COTI `it*` / `gt*` / `ct*` is not Zama `euint*` / handles. Full drop-in interface compatibility is blocked by crypto, not only API taste. | +| **Allowances, not operators** | ERC-7984 replaces amount-bounded `approve` with time-boxed **unlimited** `setOperator`. COTI keeps encrypted allowances (ERC-20 / ERC-2612-like) because private state lives on-chain and can be compared. | + +Compatibility where useful: familiar transfer shapes, metadata, and explorer-facing confidential-transfer signals — **without** claiming full ERC-7984 compliance. + +## Comparison at a glance + +| Dimension | COTI confidential tokens | Zama / FHE ERC-7984-style | +| :-------- | :----------------------- | :------------------------ | +| Private state | Encrypted values **on-chain** (readable by contracts) | Handles on-chain; bulk ciphertext / execution often off-chain (DAL / coprocessor) | +| Delegation | Encrypted **amount-bounded** `approve` / `transferFrom` | Public **time-boxed operator** (any amount until expiry) | +| User decrypt | Client AES decrypt of on-chain `ct*` | Relayer HTTPS → Gateway/KMS re-encrypt → client | +| Input validity | On-chain `validateCiphertext` (precompile) | Client ZK input proof (`inputProof`), often multi-KB | +| Numeric range | **256-bit** | Typically **64-bit** (`euint64`) | +| Host deployment | Any EVM with a PoD Inbox (computation on COTI) | FHE-capable stack / coprocessor assumptions | ## In this section -* [**Precision and decimals**](precision-and-decimals.md) — 256-bit values against the 64-bit ceiling, and why it decides whether a wrapper can mirror an 18-decimal asset. -* [**Host-chain deployment**](host-chain-deployment.md) — what the token requires of the chain it runs on, and what it requires of the user. -* [**Transaction economics**](transaction-economics.md) — encrypted-input size, on-chain footprint, and where the cryptographic work happens. -* [**Transfer semantics**](transfer-semantics.md) — encrypted allowances with standard `approve` / `transferFrom`, and failures that reveal nothing. -* [**Concurrency**](concurrency.md) — multiple in-flight requests per account, ordered by a monotonic nonce. -* [**Deployed contracts**](deployed-contracts.md) — the six pTokens live on Avalanche Fuji and Ethereum Sepolia, and how new ones are listed. +1. [**Compatibility and divergence**](compatibility-and-divergence.md) — draft standard, format mismatch, operators vs allowances. +2. [**On-chain data availability**](on-chain-data-availability.md) — private state as contract state; vote → claim public ERC-20. +3. [**Decryption trust model**](decryption-trust-model.md) — client AES vs Relayer/KMS path (TypeScript). +4. [**Input validation**](input-validation.md) — `validateCiphertext` vs browser ZK proofs. +5. [**Precision and decimals**](precision-and-decimals.md) — 256-bit vs 64-bit ceiling. +6. [**Host-chain deployment**](host-chain-deployment.md) — PoD Inbox; token on your chain. +7. [**Transaction economics**](transaction-economics.md) — ciphertext size and on-chain footprint. +8. [**Transfer semantics**](transfer-semantics.md) — encrypted allowances and silent insufficient-balance handling. +9. [**Concurrency**](concurrency.md) — multiple in-flight requests per account. +10. [**Deployed contracts**](deployed-contracts.md) — live pTokens on Fuji and Sepolia. -## Why teams choose COTI ERC-7984 +## Why teams choose COTI’s model -| | | +| | | | :--------------------------- | :------------------------------------------------------------------------ | | **Wrap real assets** | 18-decimal confidential WETH and WAVAX — out of reach for 64-bit designs | -| **Keep your chain** | Runs on any EVM chain; no privacy L1, no migration | +| **On-chain private logic** | Private vars participate in contract control flow alongside public actions | +| **Keep your chain** | Runs on any EVM chain with a PoD Inbox; no privacy L1 migration | | **Full precision** | 256-bit values, no supply ceiling | | **Small on-chain footprint** | ~192-byte inputs, 2-slot balances | -| **Instant for users** | No client-side proof generation | -| **Private allowances** | Exact encrypted amounts, not public blanket authority | -| **Ship fast** | Factory-deployed portal + token pair per asset | +| **Instant for users** | Encrypt and sign — no client-side ZK input proof | +| **Private allowances** | Exact encrypted amounts, not public blanket operator authority | +| **Local decrypt** | User `ct*` decrypted with the account AES key on the client | diff --git a/coti-erc7984/compatibility-and-divergence.md b/coti-erc7984/compatibility-and-divergence.md new file mode 100644 index 0000000..72904d7 --- /dev/null +++ b/coti-erc7984/compatibility-and-divergence.md @@ -0,0 +1,52 @@ +# Compatibility and divergence + +COTI offers confidential fungible tokens. It does **not** ship a complete [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) implementation. This page explains the three reasons that matter for product and research decisions. + +## 1. ERC-7984 is not a finished standard + +ERC-7984 is a draft interface for confidential fungible tokens. The surface (operators, confidential transfer shapes, encrypted amount pointers) is still evolving in the EIP process and in reference stacks such as [OpenZeppelin confidential contracts](https://docs.openzeppelin.com/confidential-contracts/token). + +Treating “ERC-7984-compliant” as product identity is premature: the standard is incomplete, and implementations disagree on crypto formats and trust assumptions. COTI tracks the conversation and remains **selectively compatible** (familiar transfer ideas, metadata, explorer-facing signals) without locking the product to a draft. + +## 2. Encrypted data formats differ + +ERC-7984 leaves “pointer” resolution to the implementation. In practice, Zama / FHE stacks use encrypted handles (`euint*`, `externalEuint64` + `inputProof`, ACL). COTI uses a different type system: + +| Role | COTI | Zama / FHE ERC-7984-style | +| :--- | :--- | :------------------------ | +| User input to a contract | `it*` (ciphertext + signature) | `externalEuint*` + ZK `inputProof` | +| Network / MPC private state | `gt*` (garbled / network-key) | Handle to ciphertext managed with ACL + coprocessor | +| User-readable output | `ct*` (bound to the user’s AES key) | Handle; decrypt via Relayer / KMS path | + +Because the ciphertext formats are not interchangeable, a COTI confidential token cannot be a byte-compatible drop-in for a Zama ERC-7984 token. “Compatibility” here means product and integrator familiarity — not shared crypto. + +See [Input validation](input-validation.md) for how COTI verifies `it*` on-chain, and [Decryption trust model](decryption-trust-model.md) for how `ct*` is read on the client. + +## 3. Operators vs encrypted allowances + +ERC-7984 **drops amount-bounded allocation** from the ERC-20 model. Instead of `approve(spender, amount)`, the draft uses: + +```solidity +// ERC-7984-style: public relationship, unlimited amount until `until` +function setOperator(address operator, uint48 until) external; +function isOperator(address holder, address spender) external view returns (bool); +``` + +While approved, an operator may transfer **any amount** on behalf of the holder. The operator relationship and expiry are plaintext on-chain; only balances and transfer amounts stay encrypted. That design reduces FHE compare/branch complexity when encrypted allowance state is hard to keep on-chain — but it is a **dangerous trust model** for users: granting an operator is closer to handing the wallet’s token control to another address until expiry. + +COTI keeps **allocation functions similar to ERC-20 and ERC-2612**: + +- Exact encrypted amounts via `approve` / `transferFrom` (and related increase/decrease allowance flows where exposed). +- Allowance values stored as ciphertext, readable only by the parties that need them. +- No public “this address may spend everything until time T” grant as the primary delegation model. + +That is possible because COTI holds **encrypted state on-chain** and can compare against encrypted allowances inside private execution. It is not a missing ERC-7984 feature — it is a deliberate alternative enabled by [on-chain data availability](on-chain-data-availability.md). + +| | COTI | ERC-7984 / Zama-style | +| :- | :--- | :-------------------- | +| Delegation primitive | Encrypted amount-bounded allowance | Time-boxed unlimited operator | +| Amount visibility | Private | Operator may move any amount | +| Relationship visibility | Spender/owner ciphertexts; not a public blanket grant | `OperatorSet` / `isOperator` are public | +| Why | On-chain private state supports compare | Avoid FHE allowance compare / off-chain load | + +For transfer behaviour (silent insufficient balance, encrypted approve shape), see [Transfer semantics](transfer-semantics.md). For native COTI and PoD implementations, see the PrivateERC20 / pERC20 developer guides under COTI Privacy Portal and Build on COTI. diff --git a/coti-erc7984/decryption-trust-model.md b/coti-erc7984/decryption-trust-model.md new file mode 100644 index 0000000..90f0687 --- /dev/null +++ b/coti-erc7984/decryption-trust-model.md @@ -0,0 +1,68 @@ +# Decryption trust model + +Who can see plaintext when a user “decrypts” a confidential balance or result? + +On **COTI**, user-facing ciphertexts (`ct*`) are bound to the account AES key. Decryption happens **on the client**. No single server in the path holds the user’s decrypted value. + +On **Zama today**, user decrypt goes through a **Relayer over HTTPS** to the Gateway / threshold KMS. The KMS decrypts under the FHE network key and **re-encrypts** to the user’s transport public key; the app then recovers plaintext locally. The Relayer is documented as untrusted for plaintext, but a **networked decrypt/re-encrypt service still sits in the path**. That is an implementation architecture choice, not necessarily a permanent protocol law — document it as how the stack works today. + +## COTI: local AES decrypt + +Flow in short: + +1. Onboard → account AES key (e.g. `GetUserKey` / wallet plugin). +2. Contract returns or stores `ct*` for that user (`offBoardToUser`). +3. Client reads the ciphertext from chain and decrypts locally (AES + XOR; see [AES keys](../how-coti-works/advanced-topics/aes-keys.md)). + +```typescript +import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; + +// Ciphertext already on-chain (e.g. from balanceOf / offBoardToUser). +const ciphertextHex = await token.balanceOf(userAddress); // ct* as returned by the contract + +// Decrypt happens entirely in-process with the user's AES key. +// No HTTPS decrypt service is required to obtain plaintext. +const plain = CotiPodCrypto.decrypt( + ciphertextHex.toString(), + accountAesKey, // from onboarding — never leave the client + DataType.Uint256 +); + +console.log("balance", plain); +``` + +**Implementation note:** encryption of inputs may still use a PoD encryption helper over HTTP to produce `it*` + signature; **decrypt of user `ct*` does not** send ciphertext to a server for plaintext recovery. + +## Zama: Relayer HTTPS → KMS re-encrypt → client + +Typical TypeScript shape with the current Zama SDK ([encrypt & decrypt guide](https://docs.zama.org/protocol/sdk/guides/encrypt-decrypt)): + +```typescript +import { ZamaSDK } from "@zama-fhe/sdk"; + +// Encrypt (client WASM also builds a ZK input proof — see Input validation). +const { encryptedValues, inputProof } = await sdk.encrypt({ + values: [{ value: 1000n, type: "euint64" }], + contractAddress, + userAddress, +}); + +// User decrypt of a handle returned by the contract: +// This call goes Relayer HTTPS → Gateway / KMS. +// KMS decrypts under the FHE key and re-encrypts to the user's transport key; +// plaintext is recovered on the client only after that round trip. +const decrypted = await sdk.decryption.decryptValues([ + { encryptedValue: handleFromChain, contractAddress }, +]); +``` + +Legacy Relayer SDK examples use `userDecrypt` / `createEncryptedInput(...).encrypt()` with the same architectural split: **proof + encrypt on the client**, **decrypt coordination over the Relayer**. + +| | COTI | Zama (today) | +| :- | :--- | :----------- | +| Where user plaintext is recovered | Client, from on-chain `ct*` | Client, after Relayer/KMS re-encrypt hop | +| Server sees user plaintext? | No — AES key stays with the user | Relayer should not; KMS operates on FHE key material then re-encrypts | +| Dependency for decrypt | Chain read + local AES | HTTPS Relayer (API key / proxy on mainnet) + KMS | +| Protocol vs implementation | Local decrypt is the product model | Path can evolve; today’s apps depend on the Relayer | + +For input proving cost (separate from decrypt), see [Input validation](input-validation.md). diff --git a/coti-erc7984/deployed-contracts.md b/coti-erc7984/deployed-contracts.md index 3a507ce..29b218c 100644 --- a/coti-erc7984/deployed-contracts.md +++ b/coti-erc7984/deployed-contracts.md @@ -2,7 +2,7 @@ ## Live on two public testnets -Six confidential tokens, deployed and operating. +Six confidential tokens (PoD pTokens), deployed and operating. **Avalanche Fuji** @@ -23,3 +23,5 @@ Six confidential tokens, deployed and operating. | `p.ETH` | `0xd33A363459c6Ee0C4F8504E380E8D3Aa4F209116` | 18 | Each pair is deployed by `PrivacyPortalFactory` as a minimal-proxy clone — **one portal and one pToken per asset**, so listing a new confidential token is a factory call, not an engineering project. + +These are COTI confidential wrappers on the host chain — not ERC-7984 deployments. See [Compatibility and divergence](compatibility-and-divergence.md). diff --git a/coti-erc7984/host-chain-deployment.md b/coti-erc7984/host-chain-deployment.md index c2dac66..1b56c56 100644 --- a/coti-erc7984/host-chain-deployment.md +++ b/coti-erc7984/host-chain-deployment.md @@ -2,7 +2,9 @@ ## Deploy anywhere there is an Inbox -Confidential tokens have historically meant moving to a privacy chain and asking your users to follow. PoD inverts that: the token lives on **your** chain, and the encrypted computation happens on COTI behind the scenes. +Confidential tokens have historically meant moving to a privacy chain and asking your users to follow. Privacy on Demand inverts that: the **confidential wrapper lives on your chain**, and the encrypted computation happens on COTI behind the scenes. + +This is host-chain deployment of COTI confidential tokens — not a requirement that the host run FHE precompiles or adopt ERC-7984. | | | | :----------------------------- | :-------------------------------------------------------------- | @@ -13,4 +15,4 @@ Confidential tokens have historically meant moving to a privacy chain and asking Your liquidity, your users, and your existing integrations stay exactly where they are. -For the components behind the Inbox, see [Architecture and main components](../privacy-on-demand/architecture-and-components.md) in the Privacy on Demand section. +For the components behind the Inbox, see [Architecture and main components](../privacy-on-demand/architecture-and-components.md) in the Privacy on Demand section. For how COTI relates to ERC-7984, see [Compatibility and divergence](compatibility-and-divergence.md). diff --git a/coti-erc7984/input-validation.md b/coti-erc7984/input-validation.md new file mode 100644 index 0000000..6e7a641 --- /dev/null +++ b/coti-erc7984/input-validation.md @@ -0,0 +1,79 @@ +# Input validation + +Confidential transfers need a way to prove that an encrypted input is well-formed and bound to the caller. Zama’s FHE stack does that with a **client-generated zero-knowledge input proof**. COTI does it with an **on-chain precompile** that validates the ciphertext and signature — invalid inputs revert; the wallet never runs a heavy ZK prover. + +## Zama: ZK input proof in the browser + +Encryption and proof generation run in-client (WASM, often via a Web Worker). Multi-thread WASM needs `SharedArrayBuffer` and COOP/COEP headers; otherwise the SDK falls back to slower single-thread proving — painful on mobile browsers. + +Illustrative TypeScript ([Zama SDK encrypt guide](https://docs.zama.org/protocol/sdk/guides/encrypt-decrypt)): + +```typescript +import { ZamaSDK } from "@zama-fhe/sdk"; + +// Client must generate a ZK proof that the encryption is valid (ZKPoK). +// This is the expensive step on mobile / constrained browsers. +const { encryptedValues, inputProof } = await sdk.encrypt({ + values: [{ value: amount, type: "euint64" }], + contractAddress, + userAddress, +}); + +// Both ciphertext handle and inputProof are passed into the contract. +await token.confidentialTransfer(to, encryptedValues[0], inputProof); +``` + +Legacy pattern still common in examples: + +```typescript +const enc = await fhevm + .createEncryptedInput(contractAddress, userAddress) + .add64(amount) + .encrypt(); +// enc.handles[0], enc.inputProof — proof generated on the device before submit +``` + +Proof payloads are large (often **tens of kilobytes** per input), which also hurts transaction economics. See [Transaction economics](transaction-economics.md). + +## COTI: `validateCiphertext` on-chain + +The user encrypts with their AES key and signs the input (`it*`: ciphertext + signature). The contract (or PoD path into COTI) calls the MPC precompile. If the ciphertext or signature is invalid, the call **reverts**. There is no client ZK proof of encryption validity. + +Precompile address: `0x0000000000000000000000000000000000000064`. + +Solidity (via `MpcCore`): + +```solidity +import {MpcCore, itUint256, gtUint256} from "@coti-io/coti-contracts/contracts/utils/mpc/MpcCore.sol"; + +function transfer(address to, itUint256 calldata value) external { + // On-chain validation: bad ciphertext / signature → revert. + // No ZK input proof was generated in the browser. + gtUint256 gtValue = MpcCore.validateCiphertext(value); + _transfer(msg.sender, to, gtValue); +} +``` + +Conceptually the precompile is: + +```solidity +// ExtendedOperations at address 0x64 +function ValidateCiphertext( + bytes1 metaData, + uint256 ciphertextHigh, + uint256 ciphertextLow, + bytes calldata signature +) external returns (uint256 result); +``` + +**What the client does on COTI:** encrypt and sign, then submit. **What the chain does:** verify and either accept (`it*` → `gt*`) or revert. + +| | COTI | Zama / FHE | +| :- | :--- | :--------- | +| Who proves input validity | On-chain `validateCiphertext` | Client ZK `inputProof` | +| Client work | Encrypt + sign | Encrypt + prove (WASM) | +| Mobile / browser cost | Low | High (esp. without SharedArrayBuffer) | +| Failure mode | Transaction reverts | Proof never builds, or verify fails | +| Typical input size | ~192 bytes | Multi-KB with proof | + +Related: [Decryption trust model](decryption-trust-model.md), [Precompiles](../how-coti-works/advanced-topics/precompiles.md). diff --git a/coti-erc7984/on-chain-data-availability.md b/coti-erc7984/on-chain-data-availability.md new file mode 100644 index 0000000..d18a62f --- /dev/null +++ b/coti-erc7984/on-chain-data-availability.md @@ -0,0 +1,89 @@ +# On-chain data availability + +COTI is a privacy blockchain: **encrypted data lives on-chain** as first-class contract state. Contracts can read private variables, compute on them, and combine those results with public actions in the same control flow. + +Zama’s FHE model (as commonly deployed for confidential tokens) keeps **handles and execution traces** on-chain while bulk ciphertext and private execution sit with an off-chain privacy service / DAL (data availability layer) and coprocessor. What explorers see is often a log of requests — not private values the EVM contract can treat like ordinary readable state when deciding a public side effect. + +## Why it matters + +If private data cannot participate in on-chain decision-making alongside public state, many product patterns break: payouts gated on private tallies, private eligibility that triggers a public ERC-20 send, or any flow where the contract must **branch on a private result and then touch a public token**. + +| | COTI | Zama FHE pattern (typical) | +| :- | :--- | :------------------------- | +| Where ciphertext lives | On-chain private state (`gt*` / user `ct*`) | Handle on-chain; blob / DA off-chain | +| Contract reads private vars | Yes — native to the execution model | Handle ops via FHE API; not “plain” private storage for public branching the same way | +| Private → public in one flow | Supported (compute privately, then public call) | Public transfer gated on a private tally is not a natural same-tx pattern | + +```mermaid +flowchart LR + subgraph cotiModel [COTI] + PrivState[Encrypted state on-chain] + ContractLogic[Contract reads private vars] + PublicAction[Public ERC-20 transfer] + PrivState --> ContractLogic --> PublicAction + end + subgraph zamaModel [Zama_FHE_pattern] + Handles[Handles and event traces on-chain] + Offchain[Off-chain DAL / coprocessor] + Handles -.-> Offchain + end +``` + +## Example: private votes, public claim + +Users privately vote for candidates. A candidate later claims a public ERC-20 (e.g. EUDC) proportional to votes received. On COTI this is a normal pattern: the contract holds encrypted tallies and, on `claim`, uses the private result to drive a public transfer. + +Illustrative pseudo-code (not production): + +```solidity +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.19; + +interface IERC20 { + function transfer(address to, uint256 amount) external returns (bool); +} + +/// @notice Illustrative only — shows private state gating a public ERC-20 send. +contract PrivateVotePublicClaim { + IERC20 public immutable rewardToken; // e.g. EUDC + + // Encrypted tallies live as on-chain private state (COTI gt* / equivalent). + // mapping(candidate => encryptedVoteCount) + mapping(address => uint256 /* stand-in for gtUint256 */) private votes; + + mapping(address => bool) public claimed; + + constructor(IERC20 rewardToken_) { + rewardToken = rewardToken_; + } + + /// @dev User submits an encrypted ballot (it* validated on-chain on COTI). + function vote(address candidate, /* itUint256 */ uint256 encryptedOne) external { + // validateCiphertext(encryptedOne) → add into votes[candidate] + votes[candidate] = /* privateAdd(votes[candidate], validated) */; + } + + function claim() external { + require(!claimed[msg.sender], "already claimed"); + claimed[msg.sender] = true; + + // Private tally is readable to the contract's private execution. + uint256 amount = /* privateRevealOrUse(votes[msg.sender]) */; + // In a fully private design, amount may stay encrypted until a + // controlled reveal; the point is the contract can use the private + // result to size the public payout in this flow. + + // ★ This public ERC-20 send, gated on the private vote result, + // is natural on COTI. In the typical Zama handle / off-chain DAL + // model there is no equivalent synchronous private-state read + // that can gate a public ERC-20 transfer in the same on-chain + // control flow — the contract does not hold the private tally + // as ordinary on-chain private state for that decision. + require(rewardToken.transfer(msg.sender, amount), "transfer failed"); + } +} +``` + +**Highlight:** the `rewardToken.transfer(...)` line (marked ★) is the line that does not work in the usual Zama deployment pattern for this use case. There is no way for the contract to know the private vote results as on-chain private state and, in the same control flow, send a public ERC-20 reward sized by that result. COTI’s on-chain encrypted state makes that combined private→public decision a first-class pattern. + +Related reading: [Compatibility and divergence](compatibility-and-divergence.md), [Privacy on Demand architecture](../privacy-on-demand/architecture-and-components.md). diff --git a/coti-erc7984/precision-and-decimals.md b/coti-erc7984/precision-and-decimals.md index 4fea43a..04a510a 100644 --- a/coti-erc7984/precision-and-decimals.md +++ b/coti-erc7984/precision-and-decimals.md @@ -2,13 +2,13 @@ ## Wrap the assets that actually exist -PoD ERC-7984 is a 1:1 collateralised confidential wrapper. Lock WETH, get `p.ETH`. Lock USDC, get `p.USDC`. The private token mirrors the underlying exactly — same decimals, same supply, same value — and unwraps back on demand. +PoD confidential wrappers are 1:1 collateralised. Lock WETH, get `p.ETH`. Lock USDC, get `p.USDC`. The private token mirrors the underlying exactly — same decimals, same supply, same value — and unwraps back on demand. -That "same decimals" part is where PoD stands alone. +That "same decimals" part is where COTI’s model stands alone against typical FHE confidential-token designs. -**FHE-based confidential token standards store balances as 64-bit encrypted integers.** At 18 decimals, a 64-bit ceiling caps a token at roughly **18.4 whole units** before it overflows. A confidential 1:1 WETH wrapper is not difficult under that constraint — it is arithmetically impossible above ~18 ETH. +**Zama / FHE confidential token standards store balances as 64-bit encrypted integers** (e.g. `euint64` in ERC-7984-style interfaces). At 18 decimals, a 64-bit ceiling caps a token at roughly **18.4 whole units** before it overflows. A confidential 1:1 WETH wrapper is not difficult under that constraint — it is arithmetically impossible above ~18 ETH. -PoD carries **full 256-bit precision** end to end: 18 decimals, `uint256` range, no ceiling worth naming. Four of the six pTokens live today are 18-decimal, including `p.ETH` and `p.AVAX`. +COTI carries **full 256-bit precision** end to end: 18 decimals, `uint256` range, no ceiling worth naming. Four of the six pTokens live today are 18-decimal, including `p.ETH` and `p.AVAX`. > **If you want to wrap real liquidity confidentially, 256-bit is not a preference. It is the entry requirement.** diff --git a/coti-erc7984/transaction-economics.md b/coti-erc7984/transaction-economics.md index 23e8e4b..46428a7 100644 --- a/coti-erc7984/transaction-economics.md +++ b/coti-erc7984/transaction-economics.md @@ -2,21 +2,17 @@ ## Built for real transaction economics -Confidentiality usually arrives with a size problem. FHE-based tokens attach a zero-knowledge input proof to every encrypted value — commonly **16–20 KB per input** — and offload multi-kilobyte ciphertext blobs off-chain. +Confidentiality usually arrives with a size problem. Zama / FHE confidential tokens attach a zero-knowledge **input proof** to every encrypted value — commonly **16–20 KB per input** — and often keep multi-kilobyte ciphertext off-chain behind handles. -PoD's encrypted values are small enough to treat like ordinary transaction data. +COTI encrypted inputs are small enough to treat like ordinary transaction data. Validity is checked on-chain with [`validateCiphertext`](input-validation.md), not proven in the browser. -| | **PoD ERC-7984** | **FHE-based confidential tokens** | -| :--------------- | :------------------- | :--------------------------------------- | -| Encrypted input | **~192 bytes** | ~16,000–20,000 bytes | -| On-chain balance | **2 storage slots** | Handle on-chain, multi-KB blob offloaded | -| Client-side work | **Encrypt and sign** | Generate a ZK proof, per transaction | -| Numeric range | **256-bit** | 64-bit | +| | **COTI confidential tokens** | **Zama / FHE ERC-7984-style** | +| :--------------- | :--------------------------- | :--------------------------------------- | +| Encrypted input | **~192 bytes** | ~16,000–20,000 bytes (with `inputProof`) | +| On-chain balance | **2 storage slots** | Handle on-chain, multi-KB blob offloaded | +| Client-side work | **Encrypt and sign** | Generate a ZK proof, per transaction | +| Numeric range | **256-bit** | 64-bit | **Roughly two orders of magnitude smaller on input.** Confidential transfers that fit comfortably inside normal block economics, on chains that were never designed for privacy. -## No proving in the browser - -FHE inputs require the user's device to generate a zero-knowledge proof before a transaction can even be submitted — seconds of computation, and a frozen UI while it runs. - -PoD asks the client to **encrypt and sign**. That is it. The wallet does what wallets already do, and the transaction goes out immediately. On mobile, on low-end hardware, and at scale, that difference compounds. +For proving cost, WASM/mobile constraints, and Solidity `validateCiphertext` examples, see [Input validation](input-validation.md). diff --git a/coti-erc7984/transfer-semantics.md b/coti-erc7984/transfer-semantics.md index 9b3fd3c..0749d5a 100644 --- a/coti-erc7984/transfer-semantics.md +++ b/coti-erc7984/transfer-semantics.md @@ -2,16 +2,16 @@ ## Precise, confidential approvals -PoD keeps the allowance model developers already know — and encrypts it. +COTI keeps the allowance model developers already know from ERC-20 — and encrypts it. This is a deliberate alternative to ERC-7984’s time-boxed unlimited [operator model](compatibility-and-divergence.md). - **Exact amounts.** Approve 50 tokens, not blanket authority over the balance. - **Encrypted on-chain.** The allowance value is a ciphertext, readable only by the owner and the spender. -- **Standard semantics.** `approve` / `transferFrom`, the shape every integrator already knows. +- **Standard semantics.** `approve` / `transferFrom`, the shape every integrator already knows (including ERC-2612-style permit flows where exposed). -Blanket time-boxed operator models grant a spender full authority over a balance until expiry, and record that authority publicly. PoD grants a specific encrypted amount, and keeps the amount private. +Blanket time-boxed operator models grant a spender full authority over a balance until expiry, and record that authority publicly. COTI grants a specific encrypted amount, and keeps the amount private. ## Failure that reveals nothing -When an encrypted transfer exceeds a balance, PoD resolves it inside the garbled circuit: the effective amount becomes zero and the request completes normally. **No revert, no error code, no observable difference** between a transfer that moved value and one that did not. +When an encrypted transfer exceeds a balance, COTI resolves it inside the garbled circuit: the effective amount becomes zero and the request completes normally. **No revert, no error code, no observable difference** between a transfer that moved value and one that did not. Insufficient balances stay as private as sufficient ones. diff --git a/coti-privacy-portal/developer-guide/privateerc20.sol.md b/coti-privacy-portal/developer-guide/privateerc20.sol.md index 731aa42..10a3956 100644 --- a/coti-privacy-portal/developer-guide/privateerc20.sol.md +++ b/coti-privacy-portal/developer-guide/privateerc20.sol.md @@ -39,7 +39,7 @@ PrivateERC20 follows the ERC20 interface, but changes how data is stored and exp | Supports plain uint256 operations | Yes | Yes | | Supports encrypted operations | No | Yes (`itUint256`, `gtUint256` variants) | -For a comparison against the [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) confidential-token standard — and how COTI's Privacy on Demand `pERC20` compares with FHE-based implementations on encrypted-input size, numeric range, and allowance semantics — see [COTI ERC-7984](../../coti-erc7984/README.md). +For why COTI does not implement [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) as a full standard — and how Privacy on Demand `pERC20` compares with Zama / FHE designs on data availability, allowances vs operators, decrypt trust, and input validation — see [COTI confidential tokens & ERC-7984 compatibility](../../coti-erc7984/README.md). ### How it works From 08423fbdae16d83cfbaa2f78e5ae58b73d0306e9 Mon Sep 17 00:00:00 2001 From: Naiem Date: Sun, 6 Sep 2026 00:05:12 +0000 Subject: [PATCH 3/4] docs: correct ERC-7984 comparison with measured Zama proof sizes Stakeholder review: inputProof is coprocessor signatures (ZKPoK stays off-chain), euint64/6 decimals is a cost tradeoff not a hard cap, and the PoD encrypt helper receives plaintext. Replace 404 cotitech-io SDK links with GitBook pages and live coti-io repos. Co-authored-by: Cursor --- build-on-coti/quickstart.md | 4 +- build-on-coti/tools/remix-plugin.md | 2 +- coti-erc7984/README.md | 73 ++++++------ coti-erc7984/compatibility-and-divergence.md | 55 ++++----- coti-erc7984/concurrency.md | 20 +++- coti-erc7984/decryption-trust-model.md | 65 +++++------ coti-erc7984/deployed-contracts.md | 14 +-- coti-erc7984/host-chain-deployment.md | 22 ++-- coti-erc7984/input-validation.md | 75 ++++++++----- coti-erc7984/on-chain-data-availability.md | 104 +++++++----------- coti-erc7984/precision-and-decimals.md | 37 ++++++- coti-erc7984/transaction-economics.md | 29 +++-- coti-erc7984/transfer-semantics.md | 21 ++-- privacy-on-avalanche/README.md | 9 +- .../architecture-and-components.md | 12 +- .../async-private-operations.md | 2 +- .../cookbook-private-investor-allocations.md | 2 +- .../for-developers-mapping-to-the-sdk.md | 54 ++++----- privacy-on-avalanche/glossary.md | 2 +- ...ow-a-private-request-travels-end-to-end.md | 6 +- privacy-on-avalanche/how-poa-fees-work.md | 1 - privacy-on-avalanche/tutorial-custom-logic.md | 6 +- .../tutorial-private-adder-fuji.md | 19 ++-- .../tutorials-privacy-on-avalanche.md | 6 +- privacy-on-avalanche/typescript-pod-sdk.md | 2 - .../what-is-privacy-on-avalanche.md | 2 +- privacy-on-demand/README.md | 13 ++- .../architecture-and-components.md | 12 +- privacy-on-demand/async-private-operations.md | 2 +- .../cookbook-private-investor-allocations.md | 8 +- .../for-developers-mapping-to-the-sdk.md | 59 +++++----- privacy-on-demand/glossary.md | 2 +- ...ow-a-private-request-travels-end-to-end.md | 6 +- privacy-on-demand/how-poa-fees-work.md | 6 +- privacy-on-demand/networks/README.md | 2 +- privacy-on-demand/tutorial-custom-logic.md | 10 +- .../tutorial-private-adder-sepolia.md | 53 +++++---- .../tutorials-privacy-on-demand.md | 6 +- privacy-on-demand/typescript-pod-sdk.md | 8 +- .../what-is-privacy-on-demand.md | 4 +- 40 files changed, 430 insertions(+), 405 deletions(-) diff --git a/build-on-coti/quickstart.md b/build-on-coti/quickstart.md index a85b99a..281c49e 100644 --- a/build-on-coti/quickstart.md +++ b/build-on-coti/quickstart.md @@ -172,7 +172,7 @@ This guide will help you explore the basics of interacting with the COTI network ``` -2. Navigate to the [**coti-ethers**](https://github.com/coti-io/coti-typescript-examples/blob/main/coti-ethers/server/README.md) examples subdirectory in the newly cloned repository directory\ +2. Navigate to the [**coti-ethers**](https://github.com/coti-io/coti-typescript-examples/tree/main/coti-ethers/server) examples subdirectory in the newly cloned repository directory\ ```bash @@ -264,7 +264,7 @@ This guide will help you explore the basics of interacting with the COTI network ``` -2. Navigate to the [**coti-web3**](https://github.com/coti-io/coti-python-examples/blob/main/coti-web3/README.md) examples subdirectory in the newly cloned repository directory\ +2. Navigate to the [**coti-web3**](https://github.com/coti-io/coti-python-examples/tree/main/coti-web3) examples subdirectory in the newly cloned repository directory\ ```bash diff --git a/build-on-coti/tools/remix-plugin.md b/build-on-coti/tools/remix-plugin.md index b587f11..f25357c 100644 --- a/build-on-coti/tools/remix-plugin.md +++ b/build-on-coti/tools/remix-plugin.md @@ -51,7 +51,7 @@ The Onboard section of the plugin provides an easy way to generate an AES key. T If the account has already been onboarded and an AES key has already been created, the key will be displayed in this section. -The Onboard action makes use of the [**`AccountOnboard.sol`**](https://github.com/coti-io/confidentiality-contracts/blob/main/contracts/AccountOnboard/AccountOnboard.sol) smart contract via the Typescript SDK [**`onboard.ts`**](https://github.com/coti-io/coti-sdk-typescript/blob/main/src/account/onboard.ts) script. +The Onboard action uses the [`AccountOnboard.sol`](https://github.com/coti-io/coti-contracts/blob/main/contracts/onboard/AccountOnboard.sol) contract. The TypeScript SDK no longer ships a dedicated `onboard.ts` file. Once the `Onboard` button is clicked, the plugin will return data related to your AES key. You may clear this data by clicking on the `Clear AES Key` button. diff --git a/coti-erc7984/README.md b/coti-erc7984/README.md index e508bf1..ece1508 100644 --- a/coti-erc7984/README.md +++ b/coti-erc7984/README.md @@ -1,54 +1,59 @@ # COTI confidential tokens & ERC-7984 compatibility -**Confidential tokens with encrypted balances and transfers — without treating an unfinished standard as product identity.** +[ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) is a **Draft** ERC (created 3 July 2025) for confidential fungible tokens via `bytes32` pointers. The interface is technology-agnostic; the widely used reference stack is Zama FHEVM plus [OpenZeppelin confidential contracts](https://docs.openzeppelin.com/confidential-contracts/token). COTI does **not** implement ERC-7984 as a complete standard. It offers a confidential-token alternative with overlapping transfer shapes where that helps explorers and integrators, and a different ciphertext format, allowance model, and (on native COTI) decrypt path. -[ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) describes a confidential fungible-token interface aimed at FHE-style stacks (notably Zama / OpenZeppelin confidential contracts). COTI does **not** implement ERC-7984 as a full standard. COTI provides a **confidential-token alternative** with selective compatibility where it helps explorers and integrators — and deliberate divergence where ERC-7984’s design fights COTI’s on-chain privacy model. +This section compares ciphertext formats, input registration, decrypt paths, numeric range, and host-chain deployment. -This section is a research comparison: why the designs differ, what that unlocks on COTI, and how deployed PoD confidential wrappers fit in. +## Sources and versions + +Compared **6 September 2026** against: + +| Item | Version / status | +| :--- | :--------------- | +| ERC-7984 | Draft ([EIP-7984](https://eips.ethereum.org/EIPS/eip-7984)) | +| `@zama-fhe/sdk` | 3.5.1 (depends on `@fhevm/sdk` 0.13.2; TFHE WASM v1.6.2) | +| `@fhevm/solidity` | 0.13.3 | +| `@openzeppelin/confidential-contracts` | 0.5.3 (`ERC7984` stores `euint64`; `decimals()` returns `6`) | +| Zama Sepolia relayer | `https://relayer.testnet.zama.org` | +| Input-size measurement | Relayer `POST /v2/input-proof` plus live `confidentialTransfer` calldata on [cUSDCMock](https://sepolia.etherscan.io/address/0x7c5BF43B851c1dff1a4feE8dB225b87f2C223639) | + +Zama figures below are for that stack. Protocol details can change; re-check the pinned packages before treating a number as current. ## Why COTI is not “an ERC-7984 implementation” | Reason | What it means | | :----- | :------------ | -| **Draft standard** | ERC-7984 is incomplete; locking product identity to it is premature. | -| **Ciphertext format** | COTI `it*` / `gt*` / `ct*` is not Zama `euint*` / handles. Full drop-in interface compatibility is blocked by crypto, not only API taste. | +| **Draft standard** | ERC-7984 is still a Draft ERC. Implementations already disagree on crypto formats and trust assumptions. | +| **Ciphertext format** | COTI `it*` / `gt*` / `ct*` is not Zama `euint*` / handles. Drop-in interface compatibility is blocked by crypto, not only API taste. | | **Allowances, not operators** | ERC-7984 replaces amount-bounded `approve` with time-boxed **unlimited** `setOperator`. COTI keeps encrypted allowances (ERC-20 / ERC-2612-like) because private state lives on-chain and can be compared. | Compatibility where useful: familiar transfer shapes, metadata, and explorer-facing confidential-transfer signals — **without** claiming full ERC-7984 compliance. -## Comparison at a glance - -| Dimension | COTI confidential tokens | Zama / FHE ERC-7984-style | -| :-------- | :----------------------- | :------------------------ | -| Private state | Encrypted values **on-chain** (readable by contracts) | Handles on-chain; bulk ciphertext / execution often off-chain (DAL / coprocessor) | -| Delegation | Encrypted **amount-bounded** `approve` / `transferFrom` | Public **time-boxed operator** (any amount until expiry) | -| User decrypt | Client AES decrypt of on-chain `ct*` | Relayer HTTPS → Gateway/KMS re-encrypt → client | -| Input validity | On-chain `validateCiphertext` (precompile) | Client ZK input proof (`inputProof`), often multi-KB | -| Numeric range | **256-bit** | Typically **64-bit** (`euint64`) | -| Host deployment | Any EVM with a PoD Inbox (computation on COTI) | FHE-capable stack / coprocessor assumptions | +## Comparison + +| Dimension | COTI confidential tokens | Zama / FHE ERC-7984-style (pinned stack) | +| :-------- | :----------------------- | :---------------------------------------- | +| Private state | Encrypted values **on-chain** (`gt*` / user `ct*`) | 32-byte handles on-chain; ciphertext held by coprocessors | +| Delegation | Encrypted **amount-bounded** `approve` / `transferFrom` | Public **time-boxed operator** (any amount until `until`) | +| User decrypt | Client AES decrypt of on-chain `ct*` | Relayer HTTPS → Gateway / threshold KMS re-encrypt → client | +| Contract decrypt → public logic | Native COTI: [synchronous decrypt](../how-coti-works/advanced-topics/coti-vs-others.md#advantages-over-fhe) in the same call. PoD host-chain apps: [async request/callback](../privacy-on-demand/async-private-operations.md) | Encrypted branching via `FHE.select` in the same tx. Public branching needs a **later** tx with KMS signatures ([Zama branching](https://docs.zama.org/protocol/solidity-guides/smart-contract/logics/conditions)) | +| Input validity | On-chain `validateCiphertext` (precompile `0x64`) | Client ZKPoK sent to the Relayer; coprocessors verify; host chain checks **signed handles** | +| Typical encrypted input on the host chain | `itUint256`: two 32-byte limbs + ~65-byte signature (**~192 bytes** payload) | `externalEuint64` handle (32 bytes) + `inputProof` attestation (**230 bytes** for 1 handle / 3 signers) | +| Off-chain input blob | None for native encrypt; PoD HTTP encrypt is a separate helper | Packed ciphertext + ZKPoK to Relayer: **18,794 bytes** in this measurement | +| Numeric type in the token reference | **256-bit** (`itUint256` / `gtUint256`) | **`euint64`** in OpenZeppelin `ERC7984`; `decimals()` = **6**. `euint128` has the same arithmetic ops at higher [HCU](https://docs.zama.org/protocol/solidity-guides/development-guide/hcu); `euint256` has **no** add/mul | +| Trust | MPC / garbled-circuit network (threshold network key); user AES key on the client; PoD encryption HTTP helper **does** receive plaintext | Threshold coprocessors (InputVerifier signatures); threshold KMS; Relayer is a liveness path (documented as untrusted for plaintext) | +| Host deployment | Any EVM with a PoD Inbox (computation on COTI) | FHEVM host contracts + coprocessor / Gateway assumptions | +| Concurrency | PoD: multiple in-flight requests per account, applied by request id / nonce | Host txs follow ordinary EVM account nonces; overlapping writes to the same handle are ordered by coprocessor execution of host events. Unwrap is two host txs | ## In this section 1. [**Compatibility and divergence**](compatibility-and-divergence.md) — draft standard, format mismatch, operators vs allowances. -2. [**On-chain data availability**](on-chain-data-availability.md) — private state as contract state; vote → claim public ERC-20. -3. [**Decryption trust model**](decryption-trust-model.md) — client AES vs Relayer/KMS path (TypeScript). -4. [**Input validation**](input-validation.md) — `validateCiphertext` vs browser ZK proofs. -5. [**Precision and decimals**](precision-and-decimals.md) — 256-bit vs 64-bit ceiling. +2. [**On-chain data availability**](on-chain-data-availability.md) — private state as contract state; private → public control flow. +3. [**Decryption trust model**](decryption-trust-model.md) — client AES vs Relayer/KMS; encryption helper plaintext. +4. [**Input validation**](input-validation.md) — `validateCiphertext` vs Relayer ZKPoK + on-chain signatures. +5. [**Precision and decimals**](precision-and-decimals.md) — 256-bit vs `euint64` / 6 decimals / `euint128` cost. 6. [**Host-chain deployment**](host-chain-deployment.md) — PoD Inbox; token on your chain. -7. [**Transaction economics**](transaction-economics.md) — ciphertext size and on-chain footprint. +7. [**Transaction economics**](transaction-economics.md) — measured calldata vs off-chain proof size. 8. [**Transfer semantics**](transfer-semantics.md) — encrypted allowances and silent insufficient-balance handling. -9. [**Concurrency**](concurrency.md) — multiple in-flight requests per account. +9. [**Concurrency**](concurrency.md) — in-flight PoD requests vs Zama handle updates. 10. [**Deployed contracts**](deployed-contracts.md) — live pTokens on Fuji and Sepolia. - -## Why teams choose COTI’s model - -| | | -| :--------------------------- | :------------------------------------------------------------------------ | -| **Wrap real assets** | 18-decimal confidential WETH and WAVAX — out of reach for 64-bit designs | -| **On-chain private logic** | Private vars participate in contract control flow alongside public actions | -| **Keep your chain** | Runs on any EVM chain with a PoD Inbox; no privacy L1 migration | -| **Full precision** | 256-bit values, no supply ceiling | -| **Small on-chain footprint** | ~192-byte inputs, 2-slot balances | -| **Instant for users** | Encrypt and sign — no client-side ZK input proof | -| **Private allowances** | Exact encrypted amounts, not public blanket operator authority | -| **Local decrypt** | User `ct*` decrypted with the account AES key on the client | diff --git a/coti-erc7984/compatibility-and-divergence.md b/coti-erc7984/compatibility-and-divergence.md index 72904d7..c4621d8 100644 --- a/coti-erc7984/compatibility-and-divergence.md +++ b/coti-erc7984/compatibility-and-divergence.md @@ -1,52 +1,43 @@ # Compatibility and divergence -COTI offers confidential fungible tokens. It does **not** ship a complete [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) implementation. This page explains the three reasons that matter for product and research decisions. +COTI offers confidential fungible tokens. It does **not** ship a complete [ERC-7984](https://eips.ethereum.org/EIPS/eip-7984) implementation. ERC-7984 is a **Draft** ERC (created 3 July 2025; citation still `[DRAFT]` as of 6 September 2026). -## 1. ERC-7984 is not a finished standard +## 1. Draft interface, multiple cryptosystems -ERC-7984 is a draft interface for confidential fungible tokens. The surface (operators, confidential transfer shapes, encrypted amount pointers) is still evolving in the EIP process and in reference stacks such as [OpenZeppelin confidential contracts](https://docs.openzeppelin.com/confidential-contracts/token). +ERC-7984 standardises names and `bytes32` **pointers**. Pointer resolution, ciphertext format, and trust assumptions are implementation-specific. The common reference is [OpenZeppelin confidential contracts](https://docs.openzeppelin.com/confidential-contracts/token) on Zama FHEVM (`@openzeppelin/confidential-contracts` 0.5.3, balances as `euint64`). -Treating “ERC-7984-compliant” as product identity is premature: the standard is incomplete, and implementations disagree on crypto formats and trust assumptions. COTI tracks the conversation and remains **selectively compatible** (familiar transfer ideas, metadata, explorer-facing signals) without locking the product to a draft. +COTI uses a different crypto (`it*` / `gt*` / `ct*`). Selective compatibility (transfer shapes, metadata, explorer-facing confidential-transfer signals) is not byte-compatible ERC-7984. -## 2. Encrypted data formats differ +## 2. Encrypted data formats -ERC-7984 leaves “pointer” resolution to the implementation. In practice, Zama / FHE stacks use encrypted handles (`euint*`, `externalEuint64` + `inputProof`, ACL). COTI uses a different type system: - -| Role | COTI | Zama / FHE ERC-7984-style | -| :--- | :--- | :------------------------ | -| User input to a contract | `it*` (ciphertext + signature) | `externalEuint*` + ZK `inputProof` | -| Network / MPC private state | `gt*` (garbled / network-key) | Handle to ciphertext managed with ACL + coprocessor | -| User-readable output | `ct*` (bound to the user’s AES key) | Handle; decrypt via Relayer / KMS path | - -Because the ciphertext formats are not interchangeable, a COTI confidential token cannot be a byte-compatible drop-in for a Zama ERC-7984 token. “Compatibility” here means product and integrator familiarity — not shared crypto. - -See [Input validation](input-validation.md) for how COTI verifies `it*` on-chain, and [Decryption trust model](decryption-trust-model.md) for how `ct*` is read on the client. +| Role | COTI | Zama / FHE ERC-7984-style (pinned stack) | +| :--- | :--- | :---------------------------------------- | +| User input | `it*` (ciphertext + signature) | `externalEuint*` handle + `inputProof` (**coprocessor signatures**, not the ZKPoK — [Input validation](input-validation.md)) | +| Network private state | `gt*` (network-key / garbled) | Handle; ciphertext with coprocessors; ACL | +| User-readable output | `ct*` (account AES key) | Handle; decrypt via Relayer / KMS ([Decryption trust model](decryption-trust-model.md)) | ## 3. Operators vs encrypted allowances -ERC-7984 **drops amount-bounded allocation** from the ERC-20 model. Instead of `approve(spender, amount)`, the draft uses: +ERC-7984 replaces amount-bounded `approve` with: ```solidity -// ERC-7984-style: public relationship, unlimited amount until `until` +// Public relationship. Operator may transfer any amount until `until`. function setOperator(address operator, uint48 until) external; function isOperator(address holder, address spender) external view returns (bool); ``` -While approved, an operator may transfer **any amount** on behalf of the holder. The operator relationship and expiry are plaintext on-chain; only balances and transfer amounts stay encrypted. That design reduces FHE compare/branch complexity when encrypted allowance state is hard to keep on-chain — but it is a **dangerous trust model** for users: granting an operator is closer to handing the wallet’s token control to another address until expiry. - -COTI keeps **allocation functions similar to ERC-20 and ERC-2612**: +While the grant is live, the operator can move **any** amount of the holder’s token. `OperatorSet` / `isOperator` are **plaintext**. Balances and transfer amounts stay encrypted. The EIP rationale is to avoid tracking encrypted approval amounts on the external system. -- Exact encrypted amounts via `approve` / `transferFrom` (and related increase/decrease allowance flows where exposed). -- Allowance values stored as ciphertext, readable only by the parties that need them. -- No public “this address may spend everything until time T” grant as the primary delegation model. +COTI keeps **encrypted, amount-bounded** allowances (ERC-20 / ERC-2612-like `approve` / `transferFrom`): -That is possible because COTI holds **encrypted state on-chain** and can compare against encrypted allowances inside private execution. It is not a missing ERC-7984 feature — it is a deliberate alternative enabled by [on-chain data availability](on-chain-data-availability.md). +- Allowance values are ciphertext. +- Compare-and-subtract runs in private execution ([on-chain data availability](on-chain-data-availability.md)). +- There is no public “unlimited until time T” grant as the primary delegation model. -| | COTI | ERC-7984 / Zama-style | -| :- | :--- | :-------------------- | -| Delegation primitive | Encrypted amount-bounded allowance | Time-boxed unlimited operator | -| Amount visibility | Private | Operator may move any amount | -| Relationship visibility | Spender/owner ciphertexts; not a public blanket grant | `OperatorSet` / `isOperator` are public | -| Why | On-chain private state supports compare | Avoid FHE allowance compare / off-chain load | +| | COTI | ERC-7984 / OpenZeppelin `ERC7984` | +| :- | :--- | :-------------------------------- | +| Delegation | Encrypted amount-bounded allowance | Time-boxed operator | +| Amount the delegate may spend | The approved encrypted amount | Any amount until `until` | +| Relationship on-chain | Allowance ciphertext | Public `isOperator` / `OperatorSet` | -For transfer behaviour (silent insufficient balance, encrypted approve shape), see [Transfer semantics](transfer-semantics.md). For native COTI and PoD implementations, see the PrivateERC20 / pERC20 developer guides under COTI Privacy Portal and Build on COTI. +[Transfer semantics](transfer-semantics.md) covers silent insufficient-balance handling. Native PrivateERC20 and PoD pERC20 developer guides live under COTI Privacy Portal and Build on COTI. diff --git a/coti-erc7984/concurrency.md b/coti-erc7984/concurrency.md index 10dcbb4..c35156d 100644 --- a/coti-erc7984/concurrency.md +++ b/coti-erc7984/concurrency.md @@ -1,7 +1,21 @@ # Concurrency -## Concurrency that keeps up with users +How overlapping confidential transfers are ordered. -Multiple transfers, mints, and burns from the same account can be in flight simultaneously. Each is tracked independently by request id, and a monotonic nonce guarantees results always apply in the correct order. **No queue, no serialisation, no waiting for one transfer to clear before starting the next.** +## COTI PoD (host-chain pTokens) -For how asynchronous private operations settle in general, see [Async private operations](../privacy-on-demand/async-private-operations.md). +A user can submit **multiple** Inbox requests while earlier ones are still in flight. Each request has a **request id**. A **monotonic nonce** on the COTI-side token applies results in order so two in-flight transfers from the same account do not clobber each other. + +The host-chain mental model is still **async**: submit → wait → callback. See [Async private operations](../privacy-on-demand/async-private-operations.md). + +## Zama / FHEVM ERC-7984-style tokens + +Host-chain transactions follow the ordinary **EVM account nonce**. One account cannot have two pending host txs mined out of nonce order. + +Coprocessors execute FHE ops in the order of host events for a given handle. There is no PoD-style in-flight **request queue** on the token: a `confidentialTransfer` that already passed Relayer input registration is a single host transaction. + +Flows that need a **public** result take **two host transactions** (for example `unwrap` then `finalizeUnwrap`). Those two txs are sequenced by the EVM nonce and by waiting for KMS signatures in between — not by a PoD request id. + +## Transfer semantics + +Silent insufficient-balance handling (encrypted amount → effective zero) is independent of this queueing model. See [Transfer semantics](transfer-semantics.md). diff --git a/coti-erc7984/decryption-trust-model.md b/coti-erc7984/decryption-trust-model.md index 90f0687..cd52f82 100644 --- a/coti-erc7984/decryption-trust-model.md +++ b/coti-erc7984/decryption-trust-model.md @@ -1,68 +1,69 @@ # Decryption trust model -Who can see plaintext when a user “decrypts” a confidential balance or result? +Who can see plaintext, and which services sit on the path? -On **COTI**, user-facing ciphertexts (`ct*`) are bound to the account AES key. Decryption happens **on the client**. No single server in the path holds the user’s decrypted value. +**Decrypt of user `ct*` on COTI is local:** the client reads ciphertext from chain and AES-decrypts with the account key. That step does not send ciphertext to a server for plaintext recovery. -On **Zama today**, user decrypt goes through a **Relayer over HTTPS** to the Gateway / threshold KMS. The KMS decrypts under the FHE network key and **re-encrypts** to the user’s transport public key; the app then recovers plaintext locally. The Relayer is documented as untrusted for plaintext, but a **networked decrypt/re-encrypt service still sits in the path**. That is an implementation architecture choice, not necessarily a permanent protocol law — document it as how the stack works today. +**Encrypt is a separate path.** Native COTI SDKs can encrypt locally with the same AES key. PoD dApps that call `CotiPodCrypto.encrypt` **POST the plaintext** to the PoD encryption HTTP service (`buildEncryptedInputs`). That helper **does receive plaintext**. Do not treat “client-side decrypt” as “no server ever sees the value.” -## COTI: local AES decrypt +Zama user decrypt goes Relayer HTTPS → Gateway / threshold KMS (re-encrypt to the user’s transport key) → client. The Relayer is documented as untrusted for plaintext; the KMS and coprocessors are the cryptographic trust base. + +## Trust assumptions -Flow in short: +| | COTI | Zama / FHEVM (pinned stack, 6 Sep 2026) | +| :- | :--- | :-------------------------------------- | +| Who holds the network key | MPC / garbled-circuit nodes hold **threshold shares** of the network AES key. No single node is documented as able to reconstruct it ([AES keys](../how-coti-works/advanced-topics/aes-keys.md)). | Threshold **coprocessors** attest inputs (`InputVerifier` signatures). Threshold **KMS** decrypts under the FHE network key. | +| User key | Account AES key from onboarding (`GetUserKey` / wallet plugin). The client must store it; loss means those `ct*` values cannot be decrypted. | User transport key for KMS re-encrypt. ACL on handles controls who may request decrypt. | +| Encrypt-time plaintext | **PoD:** encryption HTTP service reads the plaintext. **Native COTI:** `encryptValue` can stay on the client. | Client WASM encrypts under the FHE public key. Relayer sees packed ciphertext + ZKPoK, not the plaintext. | +| Decrypt-time plaintext | Client AES on `ct*`. No Relayer decrypt hop. | Client recovers plaintext after KMS re-encrypt. Relayer/Gateway are on the path (liveness). | +| Liveness | PoD also depends on Inbox / relayer for **request and callback**. Native COTI decrypt does not. | Relayer + Gateway for **input registration and decrypt**. Failure can happen before a host tx exists ([Input validation](input-validation.md)). | -1. Onboard → account AES key (e.g. `GetUserKey` / wallet plugin). -2. Contract returns or stores `ct*` for that user (`offBoardToUser`). -3. Client reads the ciphertext from chain and decrypts locally (AES + XOR; see [AES keys](../how-coti-works/advanced-topics/aes-keys.md)). +## COTI: local AES decrypt + +1. Onboard → account AES key. +2. Contract returns or stores `ct*` for that user (`offBoardToUser` / PoD callback). +3. Client reads the ciphertext from chain and decrypts locally (AES + XOR). ```typescript -import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; // Ciphertext already on-chain (e.g. from balanceOf / offBoardToUser). -const ciphertextHex = await token.balanceOf(userAddress); // ct* as returned by the contract +const ciphertextHex = await token.balanceOf(userAddress); -// Decrypt happens entirely in-process with the user's AES key. -// No HTTPS decrypt service is required to obtain plaintext. +// Decrypt is in-process with the user's AES key. const plain = CotiPodCrypto.decrypt( ciphertextHex.toString(), - accountAesKey, // from onboarding — never leave the client + accountAesKey, DataType.Uint256 ); - -console.log("balance", plain); ``` -**Implementation note:** encryption of inputs may still use a PoD encryption helper over HTTP to produce `it*` + signature; **decrypt of user `ct*` does not** send ciphertext to a server for plaintext recovery. +```typescript +// PoD encrypt: plaintext is in the HTTP body. The encryption service reads it. +const enc = await CotiPodCrypto.encrypt( + "1000", + "testnet", + DataType.itUint256 +); +``` ## Zama: Relayer HTTPS → KMS re-encrypt → client -Typical TypeScript shape with the current Zama SDK ([encrypt & decrypt guide](https://docs.zama.org/protocol/sdk/guides/encrypt-decrypt)): +Typical TypeScript ([Zama encrypt & decrypt](https://docs.zama.org/protocol/sdk/guides/encrypt-decrypt)): ```typescript import { ZamaSDK } from "@zama-fhe/sdk"; -// Encrypt (client WASM also builds a ZK input proof — see Input validation). const { encryptedValues, inputProof } = await sdk.encrypt({ values: [{ value: 1000n, type: "euint64" }], contractAddress, userAddress, }); -// User decrypt of a handle returned by the contract: -// This call goes Relayer HTTPS → Gateway / KMS. -// KMS decrypts under the FHE key and re-encrypts to the user's transport key; -// plaintext is recovered on the client only after that round trip. +// User decrypt of a handle: Relayer HTTPS → Gateway / KMS re-encrypt. const decrypted = await sdk.decryption.decryptValues([ { encryptedValue: handleFromChain, contractAddress }, ]); ``` -Legacy Relayer SDK examples use `userDecrypt` / `createEncryptedInput(...).encrypt()` with the same architectural split: **proof + encrypt on the client**, **decrypt coordination over the Relayer**. - -| | COTI | Zama (today) | -| :- | :--- | :----------- | -| Where user plaintext is recovered | Client, from on-chain `ct*` | Client, after Relayer/KMS re-encrypt hop | -| Server sees user plaintext? | No — AES key stays with the user | Relayer should not; KMS operates on FHE key material then re-encrypts | -| Dependency for decrypt | Chain read + local AES | HTTPS Relayer (API key / proxy on mainnet) + KMS | -| Protocol vs implementation | Local decrypt is the product model | Path can evolve; today’s apps depend on the Relayer | - -For input proving cost (separate from decrypt), see [Input validation](input-validation.md). +**Public** decrypt (plaintext that a contract can `require` on) is a different flow: off-chain KMS signatures, then a **later** host transaction. See [On-chain data availability](on-chain-data-availability.md) and COTI native [synchronous decrypt](../how-coti-works/advanced-topics/coti-vs-others.md#advantages-over-fhe). diff --git a/coti-erc7984/deployed-contracts.md b/coti-erc7984/deployed-contracts.md index 29b218c..2417359 100644 --- a/coti-erc7984/deployed-contracts.md +++ b/coti-erc7984/deployed-contracts.md @@ -1,27 +1,21 @@ # Deployed contracts -## Live on two public testnets - -Six confidential tokens (PoD pTokens), deployed and operating. +Six PoD pTokens on public testnets (addresses as of this documentation; redeploys can change them). These are **COTI confidential wrappers**, not ERC-7984 deployments. **Avalanche Fuji** - | Token | Address | Decimals | | :------- | :------------------------------------------- | :------: | | `p.MTT` | `0x02f284a1968160E1d3e4bC2BA3261be49725E765` | 18 | -| `p.USDC` | `0x21576D8CCE47d044C5815bd59eca1F6DA94c65A5` | 6 | +| `p.USDC` | `0x21576D8CCE47d044C5815bd59eca1F6DA94c65A5` | 6 | | `p.AVAX` | `0x74d47cD68203066c97BA99787Fe1e0c68Ce42b04` | 18 | **Ethereum Sepolia** - | Token | Address | Decimals | | :------- | :------------------------------------------- | :------: | | `p.MTT` | `0x0510F0b32828D5fB472dE5A5bE30b370c5D1a056` | 18 | -| `p.USDC` | `0xD7B3D49F85000489708B7db5B0f1a8693Fc707f3` | 6 | +| `p.USDC` | `0xD7B3D49F85000489708B7db5B0f1a8693Fc707f3` | 6 | | `p.ETH` | `0xd33A363459c6Ee0C4F8504E380E8D3Aa4F209116` | 18 | -Each pair is deployed by `PrivacyPortalFactory` as a minimal-proxy clone — **one portal and one pToken per asset**, so listing a new confidential token is a factory call, not an engineering project. - -These are COTI confidential wrappers on the host chain — not ERC-7984 deployments. See [Compatibility and divergence](compatibility-and-divergence.md). +Each pair is a `PrivacyPortalFactory` minimal-proxy clone: one portal and one pToken per asset. Decimals match the underlying (see [Precision and decimals](precision-and-decimals.md)). diff --git a/coti-erc7984/host-chain-deployment.md b/coti-erc7984/host-chain-deployment.md index 1b56c56..fdecd2b 100644 --- a/coti-erc7984/host-chain-deployment.md +++ b/coti-erc7984/host-chain-deployment.md @@ -1,18 +1,14 @@ # Host-chain deployment -## Deploy anywhere there is an Inbox +Privacy on Demand puts the **confidential wrapper on the host chain**. Encrypted computation runs on COTI. The host does not need FHE precompiles, a forked EVM, or an ERC-7984 stack. -Confidential tokens have historically meant moving to a privacy chain and asking your users to follow. Privacy on Demand inverts that: the **confidential wrapper lives on your chain**, and the encrypted computation happens on COTI behind the scenes. +| | | +| :--- | :--- | +| Host requirement | An EVM chain with a PoD Inbox | +| Live testnets (6 Sep 2026) | Avalanche Fuji, Ethereum Sepolia | +| Token contract | Ordinary host-chain bytecode (portal + pToken clone) | +| Private execution | COTI MPC / garbled-circuit path, via Inbox request/callback | -This is host-chain deployment of COTI confidential tokens — not a requirement that the host run FHE precompiles or adopt ERC-7984. +Zama FHEVM confidential tokens instead assume FHEVM host contracts, Relayer/Gateway, and coprocessors on that host. -| | | -| :----------------------------- | :-------------------------------------------------------------- | -| **Chains supported** | Any EVM chain with a PoD Inbox deployed | -| **Live today** | Avalanche Fuji, Ethereum Sepolia | -| **Required of the host chain** | Nothing — no FHE precompiles, no custom opcodes, no forked EVM | -| **Required of the user** | A standard wallet | - -Your liquidity, your users, and your existing integrations stay exactly where they are. - -For the components behind the Inbox, see [Architecture and main components](../privacy-on-demand/architecture-and-components.md) in the Privacy on Demand section. For how COTI relates to ERC-7984, see [Compatibility and divergence](compatibility-and-divergence.md). +Inbox and executor roles: [Architecture and main components](../privacy-on-demand/architecture-and-components.md). Live addresses: [Deployed contracts](deployed-contracts.md). ERC-7984 relationship: [Compatibility and divergence](compatibility-and-divergence.md). diff --git a/coti-erc7984/input-validation.md b/coti-erc7984/input-validation.md index 6e7a641..36fa529 100644 --- a/coti-erc7984/input-validation.md +++ b/coti-erc7984/input-validation.md @@ -1,43 +1,60 @@ # Input validation -Confidential transfers need a way to prove that an encrypted input is well-formed and bound to the caller. Zama’s FHE stack does that with a **client-generated zero-knowledge input proof**. COTI does it with an **on-chain precompile** that validates the ciphertext and signature — invalid inputs revert; the wallet never runs a heavy ZK prover. +Confidential transfers need a way to prove that an encrypted input is well-formed and bound to the caller. The stacks do that in different places. -## Zama: ZK input proof in the browser +On **COTI**, the contract (or the PoD path into COTI) calls an **on-chain precompile**. Invalid ciphertext or signature reverts in that transaction. -Encryption and proof generation run in-client (WASM, often via a Web Worker). Multi-thread WASM needs `SharedArrayBuffer` and COOP/COEP headers; otherwise the SDK falls back to slower single-thread proving — painful on mobile browsers. +On **Zama FHEVM**, the client builds a zero-knowledge proof of knowledge (ZKPoK) locally, but **that proof is not the host-chain calldata**. The client sends the packed ciphertext and ZKPoK to the **Relayer**. Coprocessors verify it on the Gateway path and return **ECDSA-signed handles**. The contract’s `inputProof` argument is those signatures, checked by `InputVerifier`. -Illustrative TypeScript ([Zama SDK encrypt guide](https://docs.zama.org/protocol/sdk/guides/encrypt-decrypt)): +The practical consequences are Relayer/Gateway dependency, ZKPoK verification cost, and failures that can happen **before** any host-chain transaction is sent — not a multi-kilobyte ZK proof sitting in L1 calldata. + +## Zama: ZKPoK off-chain, signed handles on-chain + +Flow (current protocol, measured 6 September 2026): + +1. The client encrypts under the FHE public key and produces a ZKPoK (WASM; `@zama-fhe/sdk` 3.5.1 / TFHE WASM v1.6.2). Multi-thread WASM needs `SharedArrayBuffer` and COOP/COEP; otherwise the SDK falls back to single-thread proving. +2. The SDK `POST`s the blob to the Relayer (`/v2/input-proof`). Coprocessors verify the ZKPoK and store the ciphertext. +3. The Relayer returns handles plus coprocessor signatures. That byte string is what Solidity calls `inputProof`. +4. The user (or the SDK) sends the host-chain transaction. `FHE.fromExternal(handle, inputProof)` checks signatures against a threshold in `InputVerifier`. Comments in that contract state the layout: `numHandles + numSigners + handles + coprocessorSignatures` (+ `extraData`). + +If Relayer or coprocessor verification fails, **no host transaction is submitted**. Users still pay for ZKPoK verification on the Gateway path (Relayer-coordinated). Both **input registration** and **decryption** depend on that Relayer / Gateway / KMS flow. + +### What we measured + +Encrypting one `euint64` for Sepolia [cUSDCMock](https://sepolia.etherscan.io/address/0x7c5BF43B851c1dff1a4feE8dB225b87f2C223639) via `https://relayer.testnet.zama.org`: + +| Object | Size | What it is | +| :----- | ---: | :--------- | +| Relayer field `ciphertextWithInputVerification` | **18,794 bytes** | Packed ciphertext + ZKPoK (hex payload, no `0x` prefix; 37,588 hex chars) | +| Host-chain `inputProof` returned by `sdk.encrypt` | **230 bytes** | `0x01` handles, `0x03` signers, 32-byte handle, 3 × 65-byte signatures, 1-byte `extraData` | +| Live `confidentialTransfer` calldata (9 txs, 5 Sep 2026) | **452 bytes** typical | Selector + `address` + handle + ABI-encoded 230-byte `inputProof` | + +Example host transaction: [`0x1a8b317a…d2976b`](https://sepolia.etherscan.io/tx/0x1a8b317ad2593aacad3ad1a9344482e7eeac2cea6d288729fcef02052ad2976b) (`inputProof` length 230, gas used 1,464,996). + +`InputVerifier` documents the same split: the off-chain bundle is `compressedPackedCT+ZKPOK`; the handle is derived from it; calldata is handles and coprocessor signatures. + +Illustrative TypeScript ([Zama encrypt & decrypt](https://docs.zama.org/protocol/sdk/guides/encrypt-decrypt)): ```typescript import { ZamaSDK } from "@zama-fhe/sdk"; -// Client must generate a ZK proof that the encryption is valid (ZKPoK). -// This is the expensive step on mobile / constrained browsers. +// Client WASM builds a ZKPoK. sdk.encrypt() sends it to the Relayer and +// waits for coprocessor signatures. Failures here happen before any host tx. const { encryptedValues, inputProof } = await sdk.encrypt({ values: [{ value: amount, type: "euint64" }], contractAddress, userAddress, }); -// Both ciphertext handle and inputProof are passed into the contract. +// inputProof is signed handles, not the ZKPoK. await token.confidentialTransfer(to, encryptedValues[0], inputProof); ``` -Legacy pattern still common in examples: - -```typescript -const enc = await fhevm - .createEncryptedInput(contractAddress, userAddress) - .add64(amount) - .encrypt(); -// enc.handles[0], enc.inputProof — proof generated on the device before submit -``` - -Proof payloads are large (often **tens of kilobytes** per input), which also hurts transaction economics. See [Transaction economics](transaction-economics.md). +Legacy Hardhat plugin shape (`createEncryptedInput(...).encrypt()`) is the same architecture: prove locally, register via Relayer/Gateway, pass attestations on-chain. ## COTI: `validateCiphertext` on-chain -The user encrypts with their AES key and signs the input (`it*`: ciphertext + signature). The contract (or PoD path into COTI) calls the MPC precompile. If the ciphertext or signature is invalid, the call **reverts**. There is no client ZK proof of encryption validity. +The user encrypts with their AES key and signs the input (`it*`: ciphertext + signature). The contract (or PoD path into COTI) calls the MPC precompile. If the ciphertext or signature is invalid, the call **reverts**. There is no client ZK proof of encryption validity and no Relayer registration step before the host transaction. Precompile address: `0x0000000000000000000000000000000000000064`. @@ -48,7 +65,6 @@ import {MpcCore, itUint256, gtUint256} from "@coti-io/coti-contracts/contracts/u function transfer(address to, itUint256 calldata value) external { // On-chain validation: bad ciphertext / signature → revert. - // No ZK input proof was generated in the browser. gtUint256 gtValue = MpcCore.validateCiphertext(value); _transfer(msg.sender, to, gtValue); } @@ -68,12 +84,15 @@ function ValidateCiphertext( **What the client does on COTI:** encrypt and sign, then submit. **What the chain does:** verify and either accept (`it*` → `gt*`) or revert. -| | COTI | Zama / FHE | -| :- | :--- | :--------- | -| Who proves input validity | On-chain `validateCiphertext` | Client ZK `inputProof` | -| Client work | Encrypt + sign | Encrypt + prove (WASM) | -| Mobile / browser cost | Low | High (esp. without SharedArrayBuffer) | -| Failure mode | Transaction reverts | Proof never builds, or verify fails | -| Typical input size | ~192 bytes | Multi-KB with proof | +Native COTI SDKs can encrypt locally with the account AES key. PoD dApps often call an HTTP encryption helper instead; that helper receives plaintext (see [Decryption trust model](decryption-trust-model.md)). + +| | COTI | Zama / FHE (pinned stack) | +| :- | :--- | :------------------------ | +| Who verifies well-formed encryption | On-chain `validateCiphertext` | Coprocessors verify ZKPoK; host chain verifies coprocessor signatures | +| Client work | Encrypt + sign | Encrypt + prove (WASM), then Relayer round-trip | +| Host-chain encrypted input | ~192-byte `itUint256` | 32-byte handle + **230-byte** attestation (1 input, 3 signers) | +| Off-chain proof blob | None | **~18.8 KB** to Relayer | +| Failure before the host tx | No Relayer gate | Relayer / coprocessor / Gateway can reject the ZKPoK first | +| Failure in the host tx | Precompile revert | `InputVerifier` revert (bad signatures, threshold, binding) | -Related: [Decryption trust model](decryption-trust-model.md), [Precompiles](../how-coti-works/advanced-topics/precompiles.md). +Related: [Decryption trust model](decryption-trust-model.md), [Transaction economics](transaction-economics.md), [Precompiles](../how-coti-works/advanced-topics/precompiles.md). diff --git a/coti-erc7984/on-chain-data-availability.md b/coti-erc7984/on-chain-data-availability.md index d18a62f..02ab5aa 100644 --- a/coti-erc7984/on-chain-data-availability.md +++ b/coti-erc7984/on-chain-data-availability.md @@ -1,89 +1,61 @@ # On-chain data availability -COTI is a privacy blockchain: **encrypted data lives on-chain** as first-class contract state. Contracts can read private variables, compute on them, and combine those results with public actions in the same control flow. +Encrypted **balances** are contract state on both stacks. What differs is **where the bulk ciphertext lives**, and whether a contract can turn a **private** predicate into a **public** `if` in the **same** transaction. -Zama’s FHE model (as commonly deployed for confidential tokens) keeps **handles and execution traces** on-chain while bulk ciphertext and private execution sit with an off-chain privacy service / DAL (data availability layer) and coprocessor. What explorers see is often a log of requests — not private values the EVM contract can treat like ordinary readable state when deciding a public side effect. +## Where private data lives -## Why it matters - -If private data cannot participate in on-chain decision-making alongside public state, many product patterns break: payouts gated on private tallies, private eligibility that triggers a public ERC-20 send, or any flow where the contract must **branch on a private result and then touch a public token**. - -| | COTI | Zama FHE pattern (typical) | -| :- | :--- | :------------------------- | -| Where ciphertext lives | On-chain private state (`gt*` / user `ct*`) | Handle on-chain; blob / DA off-chain | -| Contract reads private vars | Yes — native to the execution model | Handle ops via FHE API; not “plain” private storage for public branching the same way | -| Private → public in one flow | Supported (compute privately, then public call) | Public transfer gated on a private tally is not a natural same-tx pattern | +| | COTI | Zama / FHEVM (pinned stack) | +| :- | :--- | :-------------------------- | +| What explorers see | Encrypted `gt*` / `ct*` words in storage (two 32-byte limbs for `ctUint256`) | 32-byte **handles**; ciphertext with coprocessors | +| Contract math on private values | MPC precompiles on `gt*` | FHE ops on handles (`FHE.add`, `FHE.select`, …) | +| User-readable ciphertext | `ct*` on-chain, AES-decrypt on the client | Handle on-chain; user decrypt via Relayer / KMS | ```mermaid flowchart LR subgraph cotiModel [COTI] - PrivState[Encrypted state on-chain] - ContractLogic[Contract reads private vars] - PublicAction[Public ERC-20 transfer] - PrivState --> ContractLogic --> PublicAction + PrivState[Encrypted gt or ct in storage] + Mpc[MPC precompile] + PrivState --> Mpc end - subgraph zamaModel [Zama_FHE_pattern] - Handles[Handles and event traces on-chain] - Offchain[Off-chain DAL / coprocessor] - Handles -.-> Offchain + subgraph zamaModel [Zama_FHEVM] + Handles[Handles in storage] + Coproc[Coprocessor ciphertext] + Handles -.-> Coproc end ``` -## Example: private votes, public claim - -Users privately vote for candidates. A candidate later claims a public ERC-20 (e.g. EUDC) proportional to votes received. On COTI this is a normal pattern: the contract holds encrypted tallies and, on `claim`, uses the private result to drive a public transfer. +## Private vs public control flow -Illustrative pseudo-code (not production): +Three different questions: -```solidity -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.19; - -interface IERC20 { - function transfer(address to, uint256 amount) external returns (bool); -} +1. **Encrypted branching** — pick ciphertext A or B without revealing the bit (`mux` / `FHE.select`). Both stacks do this in the transaction that runs the FHE/MPC op. +2. **Public branching** — a plaintext `if`, a public ERC-20 `transfer`, an event that discloses an amount. That needs a **plaintext**. +3. **When the plaintext exists** — same transaction, or a later one. -/// @notice Illustrative only — shows private state gating a public ERC-20 send. -contract PrivateVotePublicClaim { - IERC20 public immutable rewardToken; // e.g. EUDC +| Path | Same transaction as the private compute? | Notes | +| :--- | :--- | :---- | +| **Native COTI** (gcEVM) | Yes | Contract can decrypt inside the call (`SetPublic` / garbled-circuit reveal) and then branch or send a public token. See [Advantages over FHE](../how-coti-works/advanced-topics/coti-vs-others.md#advantages-over-fhe). | +| **PoD host-chain tokens** | No | Private work runs on COTI. The host contract sees the result in an **Inbox callback** ([Async private operations](../privacy-on-demand/async-private-operations.md)). | +| **Zama FHEVM** | Encrypted: yes (`FHE.select`). Public: no | [Zama branching](https://docs.zama.org/protocol/solidity-guides/smart-contract/logics/conditions): moving from an encrypted condition to non-encrypted logic **requires off-chain public decryption**, then a **later** host tx (`FHE.checkSignatures` / `finalizeUnwrap`-style callbacks). | - // Encrypted tallies live as on-chain private state (COTI gt* / equivalent). - // mapping(candidate => encryptedVoteCount) - mapping(address => uint256 /* stand-in for gtUint256 */) private votes; +OpenZeppelin confidential wrappers follow that two-transaction public path (for example `unwrap` then `finalizeUnwrap`; swap then `finalizeSwap`). - mapping(address => bool) public claimed; +## Example: private tally, public payout - constructor(IERC20 rewardToken_) { - rewardToken = rewardToken_; - } +On **native COTI**, a contract can hold encrypted tallies and, in `claim`, decrypt (or mux) and send a public ERC-20 in the **same** call. - /// @dev User submits an encrypted ballot (it* validated on-chain on COTI). - function vote(address candidate, /* itUint256 */ uint256 encryptedOne) external { - // validateCiphertext(encryptedOne) → add into votes[candidate] - votes[candidate] = /* privateAdd(votes[candidate], validated) */; - } - - function claim() external { - require(!claimed[msg.sender], "already claimed"); - claimed[msg.sender] = true; - - // Private tally is readable to the contract's private execution. - uint256 amount = /* privateRevealOrUse(votes[msg.sender]) */; - // In a fully private design, amount may stay encrypted until a - // controlled reveal; the point is the contract can use the private - // result to size the public payout in this flow. - - // ★ This public ERC-20 send, gated on the private vote result, - // is natural on COTI. In the typical Zama handle / off-chain DAL - // model there is no equivalent synchronous private-state read - // that can gate a public ERC-20 transfer in the same on-chain - // control flow — the contract does not hold the private tally - // as ordinary on-chain private state for that decision. - require(rewardToken.transfer(msg.sender, amount), "transfer failed"); - } +```solidity +function claim() external { + require(!claimed[msg.sender], "already claimed"); + claimed[msg.sender] = true; + // Native COTI: private result can become public in this call. + uint256 amount = /* decrypt or controlled reveal of votes[msg.sender] */; + require(rewardToken.transfer(msg.sender, amount), "transfer failed"); } ``` -**Highlight:** the `rewardToken.transfer(...)` line (marked ★) is the line that does not work in the usual Zama deployment pattern for this use case. There is no way for the contract to know the private vote results as on-chain private state and, in the same control flow, send a public ERC-20 reward sized by that result. COTI’s on-chain encrypted state makes that combined private→public decision a first-class pattern. +On **Zama**, the auction/prize pattern in the FHEVM docs is: encrypted bids with `FHE.select` during the sale, then `makePubliclyDecryptable` / off-chain decrypt, then a **second** function that verifies KMS signatures and transfers the prize. + +On **PoD**, a host-chain pToken transfer is already request → COTI → callback. A public ERC-20 send gated on a private host-chain tally uses that same two-step Inbox path, not a native same-tx decrypt. -Related reading: [Compatibility and divergence](compatibility-and-divergence.md), [Privacy on Demand architecture](../privacy-on-demand/architecture-and-components.md). +Related: [Compatibility and divergence](compatibility-and-divergence.md), [Concurrency](concurrency.md), [Privacy on Demand architecture](../privacy-on-demand/architecture-and-components.md). diff --git a/coti-erc7984/precision-and-decimals.md b/coti-erc7984/precision-and-decimals.md index 04a510a..93dc1f3 100644 --- a/coti-erc7984/precision-and-decimals.md +++ b/coti-erc7984/precision-and-decimals.md @@ -1,15 +1,40 @@ # Precision and decimals -## Wrap the assets that actually exist +PoD confidential wrappers are 1:1 collateralised. Lock WETH, get `p.ETH`. Lock USDC, get `p.USDC`. The private token mirrors the underlying — same decimals, same supply, same value — and unwraps back on demand. -PoD confidential wrappers are 1:1 collateralised. Lock WETH, get `p.ETH`. Lock USDC, get `p.USDC`. The private token mirrors the underlying exactly — same decimals, same supply, same value — and unwraps back on demand. +That is a **precision vs FHE-cost** choice on Zama, not a hard platform bit-width ceiling. -That "same decimals" part is where COTI’s model stands alone against typical FHE confidential-token designs. +## What the Zama token reference actually uses -**Zama / FHE confidential token standards store balances as 64-bit encrypted integers** (e.g. `euint64` in ERC-7984-style interfaces). At 18 decimals, a 64-bit ceiling caps a token at roughly **18.4 whole units** before it overflows. A confidential 1:1 WETH wrapper is not difficult under that constraint — it is arithmetically impossible above ~18 ETH. +OpenZeppelin [`ERC7984`](https://docs.openzeppelin.com/confidential-contracts/token) (`@openzeppelin/confidential-contracts` 0.5.3) stores balances as **`euint64`** and implements `decimals()` as **`6`**. ERC-7984 itself only requires a plaintext `decimals()`; it does not mandate 64-bit math. `euint64` is the reference-design type. -COTI carries **full 256-bit precision** end to end: 18 decimals, `uint256` range, no ceiling worth naming. Four of the six pTokens live today are 18-decimal, including `p.ETH` and `p.AVAX`. +`uint64` max is \(2^{64}-1\) ≈ \(1.84 \times 10^{19}\): -> **If you want to wrap real liquidity confidentially, 256-bit is not a preference. It is the entry requirement.** +| Decimals | Max whole tokens in `euint64` | Fit with 18-decimal collateral | +| -------: | ----------------------------: | :----------------------------- | +| 18 | ≈ **18.45** | Does not fit a 1:1 WETH wrapper above ~18 ETH | +| 6 | ≈ **18.45 trillion** | Fits large supplies; **12 digits of token precision are dropped** vs 18-decimal ERC-20 math | + +Zama confidential wrappers for 18-decimal underlyings scale into 6 decimals (for example \(10^{12}\) on mock WETH). Arithmetic on 6-decimal amounts does not match 18-decimal ERC-20 rounding and dust behaviour. + +## `euint128` and `euint256` are not a silent 64-bit wall + +[FHEVM types](https://docs.zama.org/protocol/solidity-guides/smart-contract/types) (`@fhevm/solidity` 0.13.3): + +- **`euint64`** and **`euint128`** support the main arithmetic operators (add, sub, mul, comparisons, `select`, …). +- **`euint256`** supports bitwise ops, equality, `select`, and rand — **not** add/mul. It is not a drop-in confidential `uint256` balance type. + +[HCU](https://docs.zama.org/protocol/solidity-guides/development-guide/hcu) for non-scalar ops (higher = more coprocessor work): + +| Op | `euint64` | `euint128` | +| :- | --------: | ---------: | +| `add` | 162,000 | 259,000 | +| `mul` | 596,000 | 1,686,000 | + +A confidential 18-decimal WETH-style balance **can** be represented in `euint128` (\(2^{128}-1 / 10^{18}\) is far above any realistic ETH supply). The reference ERC-7984 token does not do that: it keeps `euint64` and 6 decimals so FHE cost stays lower. The tradeoff is **precision (and ERC-20 decimal compatibility) versus FHE cost**, not “the platform cannot exceed ~18 ETH.” + +## COTI + +COTI carries **256-bit** encrypted integers end to end (`itUint256` / `gtUint256` / `ctUint256`). PoD wrappers keep the underlying’s decimals. Four of the six live pTokens are 18-decimal, including `p.ETH` and `p.AVAX`. The [deployed contracts](deployed-contracts.md) page lists the decimals of each live pToken. diff --git a/coti-erc7984/transaction-economics.md b/coti-erc7984/transaction-economics.md index 46428a7..2a04ef5 100644 --- a/coti-erc7984/transaction-economics.md +++ b/coti-erc7984/transaction-economics.md @@ -1,18 +1,25 @@ # Transaction economics -## Built for real transaction economics +Confidentiality has a size and a **path** cost. On Zama FHEVM the client ZKPoK is sent to the Relayer. The host chain receives a short coprocessor attestation, not that proof. -Confidentiality usually arrives with a size problem. Zama / FHE confidential tokens attach a zero-knowledge **input proof** to every encrypted value — commonly **16–20 KB per input** — and often keep multi-kilobyte ciphertext off-chain behind handles. +Measured **6 September 2026** (`@zama-fhe/sdk` 3.5.1, Sepolia cUSDCMock): -COTI encrypted inputs are small enough to treat like ordinary transaction data. Validity is checked on-chain with [`validateCiphertext`](input-validation.md), not proven in the browser. +| | **COTI confidential tokens** | **Zama / FHE ERC-7984-style** | +| :--------------- | :--------------------------- | :---------------------------- | +| Encrypted input on the host chain | **`itUint256` ~192-byte payload** (two 32-byte limbs + ~65-byte signature) | 32-byte handle + **230-byte** `inputProof` (1 handle, 3 signers) | +| Typical `confidentialTransfer` calldata | Same order of magnitude as a signed `it*` transfer | **452 bytes** in 8 of 9 sampled txs | +| Packed ciphertext + ZKPoK | Not used | **18,794 bytes** in Relayer `ciphertextWithInputVerification` | +| Where validity is checked | `validateCiphertext` in the same host/COTI call | Relayer / coprocessors first; `InputVerifier` signatures on-chain | +| Client-side work | Encrypt and sign (WASM ZK proving not required) | Generate ZKPoK (WASM), wait for Relayer | +| Numeric type in the token reference | 256-bit | `euint64` + 6 decimals in OpenZeppelin `ERC7984` | -| | **COTI confidential tokens** | **Zama / FHE ERC-7984-style** | -| :--------------- | :--------------------------- | :--------------------------------------- | -| Encrypted input | **~192 bytes** | ~16,000–20,000 bytes (with `inputProof`) | -| On-chain balance | **2 storage slots** | Handle on-chain, multi-KB blob offloaded | -| Client-side work | **Encrypt and sign** | Generate a ZK proof, per transaction | -| Numeric range | **256-bit** | 64-bit | +On-chain encrypted-amount size is hundreds of bytes on both stacks. What differs: -**Roughly two orders of magnitude smaller on input.** Confidential transfers that fit comfortably inside normal block economics, on chains that were never designed for privacy. +- Users pay for **ZKPoK verification** on the Gateway path even though the ZK proof never appears in host calldata. +- Input registration and decryption **depend on the Relayer**. A Relayer or coprocessor failure aborts **before** the host transaction exists. +- Host `confidentialTransfer` gas on the sampled Sepolia txs was about **0.96M–1.85M**. +- FHE arithmetic is metered in [HCU](https://docs.zama.org/protocol/solidity-guides/development-guide/hcu) on the coprocessor, separate from calldata. -For proving cost, WASM/mobile constraints, and Solidity `validateCiphertext` examples, see [Input validation](input-validation.md). +COTI balances that are `ctUint256` occupy two ciphertext limbs (see [On-chain data availability](on-chain-data-availability.md)). Zama balances are 32-byte handles; the ciphertext lives with the coprocessors. + +For the Relayer flow, `InputVerifier` layout, and Solidity `validateCiphertext` examples, see [Input validation](input-validation.md). diff --git a/coti-erc7984/transfer-semantics.md b/coti-erc7984/transfer-semantics.md index 0749d5a..960d3cc 100644 --- a/coti-erc7984/transfer-semantics.md +++ b/coti-erc7984/transfer-semantics.md @@ -1,17 +1,20 @@ # Transfer semantics -## Precise, confidential approvals +## Allowances vs operators -COTI keeps the allowance model developers already know from ERC-20 — and encrypts it. This is a deliberate alternative to ERC-7984’s time-boxed unlimited [operator model](compatibility-and-divergence.md). +COTI confidential tokens keep **amount-bounded** `approve` / `transferFrom` (and ERC-2612-style permit where exposed). The allowance is an on-chain ciphertext. See [Compatibility and divergence](compatibility-and-divergence.md) for ERC-7984 `setOperator` (public, unlimited until `until`). -- **Exact amounts.** Approve 50 tokens, not blanket authority over the balance. -- **Encrypted on-chain.** The allowance value is a ciphertext, readable only by the owner and the spender. -- **Standard semantics.** `approve` / `transferFrom`, the shape every integrator already knows (including ERC-2612-style permit flows where exposed). +## Insufficient encrypted balance -Blanket time-boxed operator models grant a spender full authority over a balance until expiry, and record that authority publicly. COTI grants a specific encrypted amount, and keeps the amount private. +When the transfer **amount is encrypted**, both stacks avoid reverting on insolvency so observers cannot distinguish “not enough” from a successful private transfer. -## Failure that reveals nothing +| Stack | Mechanism | Host-visible result | +| :---- | :-------- | :------------------ | +| COTI PoD pToken (encrypted amount) | COTI-side `mux` of the effective amount to zero; callback **Success** | Request completes; balances unchanged if insolvent | +| OpenZeppelin `ERC7984` | `FHESafeMath.tryDecrease` + `FHE.select(success, amount, 0)` | Transaction succeeds; `ConfidentialTransfer` amount is an encrypted zero | -When an encrypted transfer exceeds a balance, COTI resolves it inside the garbled circuit: the effective amount becomes zero and the request completes normally. **No revert, no error code, no observable difference** between a transfer that moved value and one that did not. +COTI **public** amounts (for example portal withdraw where fail vs success must be real) take the other branch: decrypt the comparison and return **Failure** instead of mux-to-zero. -Insufficient balances stay as private as sufficient ones. +Encrypted-path “success with zero moved” is therefore a **confidentiality** choice on both designs, not a COTI-only behaviour. + +Overlapping transfers: [Concurrency](concurrency.md). diff --git a/privacy-on-avalanche/README.md b/privacy-on-avalanche/README.md index 3db3997..68326d5 100644 --- a/privacy-on-avalanche/README.md +++ b/privacy-on-avalanche/README.md @@ -22,7 +22,7 @@ Fees on the host side are paid in **AVAX**. Private execution still happens on C

Further resources

- **[Examples](https://github.com/coti-io/coti-contracts/tree/main/contracts/pod/examples)** — Contract examples in `@coti-io/coti-contracts`. -- **[PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs)** — Full SDK docs on GitHub. +- **[`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod)** — TypeScript SDK. - **[General Privacy on Demand section](../privacy-on-demand/README.md)** — Multi-host PoD overview (not Avalanche-only). @@ -72,7 +72,7 @@ Full tables: [Avalanche Fuji](networks/fuji.md). 7. [Async private operations (why it is not instant)](async-private-operations.md) — What “pending” means and why UX must reflect it. 8. [How do PoA fees work?](how-poa-fees-work.md) — Two-way Inbox budgets in AVAX, oracle conversion, and a worked gas-unit example. -9. [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) — Checklists and links to the [PoD SDK documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). +9. [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) — Checklists and links to source files. ### Tutorials (hands-on) @@ -84,6 +84,7 @@ Full tables: [Avalanche Fuji](networks/fuji.md). ## Official technical reference -The machine-readable contracts, types, and APIs live in the open-source SDK. Treat this book chapter as the **human-oriented companion**; treat the repository as the **source of truth** for signatures, fees, and network constants: +Machine-readable contracts, types, and APIs live in the open-source packages. This GitBook section is the human-oriented companion; pin package versions for signatures, fees, and network constants: -- [COTI PoD SDK — documentation index](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) +- [`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod) — TypeScript +- [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts/tree/main/contracts/pod) — Solidity (`PodLib`, Inbox, examples) diff --git a/privacy-on-avalanche/architecture-and-components.md b/privacy-on-avalanche/architecture-and-components.md index 6d95c9c..e57b7a9 100644 --- a/privacy-on-avalanche/architecture-and-components.md +++ b/privacy-on-avalanche/architecture-and-components.md @@ -45,7 +45,7 @@ flowchart TB ### MPC executor (COTI) -- **What it is**: The **COTI-side contract address** your dApp is configured to call for a given deployment. The SDK’s network presets expose this as a constant you set during construction (for example `MPC_EXECUTOR_ADDRESS` alongside `COTI_CHAIN_ID` in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md)). +- **What it is**: The **COTI-side contract address** your dApp is configured to call for a given deployment. The SDK’s network presets expose this as a constant you set during construction (for example `MPC_EXECUTOR_ADDRESS` alongside `COTI_CHAIN_ID` in [Getting started](tutorial-private-adder-fuji.md)). - **Why it matters**: It anchors **where** private execution is invoked in the COTI environment for **library-style** flows. ### PodUser @@ -55,8 +55,8 @@ flowchart TB ### PodLib -- **What it is**: **High-level helpers** for **common private operations** (for example comparisons and arithmetic at fixed bit widths—see the SDK [features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md) table). -- **Why it matters**: Faster path than writing a **custom** COTI contract for every operation. If you outgrow it, you move to **custom** encoding and COTI-side contracts using `MpcAbiCodec`, described in the SDK’s [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md). +- **What it is**: **High-level helpers** for **common private operations** (comparisons and arithmetic at fixed bit widths). +- **Why it matters**: Faster path than writing a **custom** COTI contract for every operation. If you outgrow it, you move to **custom** encoding and COTI-side contracts using `MpcAbiCodec` ([Tutorial: custom privacy logic](tutorial-custom-logic.md)). ## Data shapes: a non-developer mental model @@ -68,13 +68,11 @@ Engineers talk about **`it*`**, **`gt*`**, and **`ct*`**. At a high level: | **`gt*`** | **Private compute representation** during the operation | **Inside COTI** private execution | | **`ct*`** | **Encrypted output** you can **store on your chain** and **decrypt client-side** | **Returned** to your contract, **read** by the user’s app | -A fuller table lives in the SDK’s [data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md) page. - ## Trust and security highlights (for architects) -- **Callback authentication**: Your contract should only accept **Inbox-originated** callbacks for private results—otherwise anyone could try to spoof answers. The SDK’s `onlyInbox` pattern exists for this boundary ([features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md)). +- **Callback authentication**: Your contract should only accept **Inbox-originated** callbacks for private results—otherwise anyone could try to spoof answers. The `onlyInbox` pattern on `InboxUser` exists for this boundary. - **Request correlation**: Private work completes **later**; your system must track **request IDs** and statuses honestly in UX and backends ([Async private operations](async-private-operations.md)). -- **Key stewardship**: Client-side AES material is powerful; treat it like **credentials**, not analytics metadata ([TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md)). +- **Key stewardship**: Client-side AES material is powerful; treat it like **credentials**, not analytics metadata ([TypeScript PoD SDK](typescript-pod-sdk.md)). ## Next steps diff --git a/privacy-on-avalanche/async-private-operations.md b/privacy-on-avalanche/async-private-operations.md index 1a7e05b..c4a1196 100644 --- a/privacy-on-avalanche/async-private-operations.md +++ b/privacy-on-avalanche/async-private-operations.md @@ -18,7 +18,7 @@ So the user’s mental model should be closer to **“I submitted a job”** tha Private execution happens **outside** your chain’s normal synchronous EVM frame. The **Inbox** pattern exists precisely to **carry a message out** and **bring a response back** through a **controlled channel**. -The SDK’s [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) page lists the canonical lifecycle and common mistakes (wrong decode shape, missing `onlyInbox`, expecting same-block completion). +Common mistakes: wrong callback decode shape, missing `onlyInbox`, and expecting the private result in the same block as the request. ## What product and support teams should plan for diff --git a/privacy-on-avalanche/cookbook-private-investor-allocations.md b/privacy-on-avalanche/cookbook-private-investor-allocations.md index e9e0fee..17681bc 100644 --- a/privacy-on-avalanche/cookbook-private-investor-allocations.md +++ b/privacy-on-avalanche/cookbook-private-investor-allocations.md @@ -583,4 +583,4 @@ Before adapting this cookbook for a real launch, add: - [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) - [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) - [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) -- [PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) +- [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) diff --git a/privacy-on-avalanche/for-developers-mapping-to-the-sdk.md b/privacy-on-avalanche/for-developers-mapping-to-the-sdk.md index a8293b7..c066d7e 100644 --- a/privacy-on-avalanche/for-developers-mapping-to-the-sdk.md +++ b/privacy-on-avalanche/for-developers-mapping-to-the-sdk.md @@ -1,52 +1,52 @@ # For developers: mapping concepts to the SDK -This page is the **bridge** from [Architecture and main components](architecture-and-components.md) to the canonical [PoD SDK documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). It repeats a few facts on purpose so engineers can verify mental models quickly. +This page maps [Architecture and main components](architecture-and-components.md) to the packages you install: -For a guided first implementation, read **[Tutorials: building Privacy on Avalanche (PoD) dApps](tutorials-privacy-on-avalanche.md)** to pick the integration model, then follow [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) for a **primitive-only** Solidity + TypeScript walkthrough (Avalanche Fuji presets). +- TypeScript: [`@coti-io/pod-sdk`](https://www.npmjs.com/package/@coti-io/pod-sdk) ([GitHub](https://github.com/coti-io/coti-sdk-pod)) +- Solidity: [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts) (`contracts/pod/`) -## Official reading order (SDK) +For a guided first implementation, read **[Tutorials: building Privacy on Avalanche (PoD) dApps](tutorials-privacy-on-avalanche.md)**, then [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md). -The upstream docs recommend: +## Reading order -1. [Privacy dApps on any EVM chain with COTI PoD](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/01-privacy-decentralized-apps-on-any-evm-chain-with-coti-pod.md) -2. [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) -3. [Writing privacy contracts on Ethereum](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) -4. [TypeScript integration (UX development)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) +1. [What is Privacy on Avalanche?](what-is-privacy-on-avalanche.md) +2. [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) +3. [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) +4. [TypeScript PoD SDK](typescript-pod-sdk.md) -Then deep dives: +Then: -- [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) -- [MPC library (PodLib)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md) -- [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) -- Contract references: [Data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md), [Patterns and checklist](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/02-contract-patterns-and-checklist.md), [Request builder and remote calls](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md), [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) +- [Async private operations](async-private-operations.md) +- [Architecture and main components](architecture-and-components.md) (PodLib, types) +- [Tutorials index](tutorials-privacy-on-avalanche.md) +- [How a private request travels end to end](how-a-private-request-travels-end-to-end.md) +- [How do PoA fees work?](how-poa-fees-work.md) ## Component → source file map -| Concept (this book) | Where it lives in the SDK docs / repo | +| Concept (this book) | Where it lives | | --- | --- | -| **Inbox** | [IInbox.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/IInbox.sol) and cross-domain flow in the [domain model](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/01-privacy-decentralized-apps-on-any-evm-chain-with-coti-pod.md) diagram. | -| **Callback guard** | [InboxUser.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/InboxUser.sol) (`onlyInbox`) — see [Features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md). | -| **PodLib** | [PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol) and width-specific libraries (`PodLib64`, `PodLib128`, `PodLib256`). | -| **PodUser / presets** | [PodUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUser.sol), network mixins such as [PodUserFuji.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUserFuji.sol). | -| **Types (`it*`, `ct*`, `gt*`)** | [MpcCore.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/utils/mpc/MpcCore.sol) and [Data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md). | -| **Custom COTI calls** | [MpcAbiCodec.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpccodec/MpcAbiCodec.sol) and the **custom mode** section of [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md). | -| **Client crypto** | [coti-pod-crypto.ts](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) via `CotiPodCrypto` ([TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md)). | +| **Inbox** | [IInbox.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/IInbox.sol) | +| **Callback guard** | [InboxUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/InboxUser.sol) (`onlyInbox`) | +| **PodLib** | [PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol) and width-specific libraries (`PodLib64`, `PodLib128`, `PodLib256`) | +| **PodUser / presets** | [PodUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUser.sol), [PodUserFuji.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUserFuji.sol) | +| **Types (`it*`, `ct*`, `gt*`)** | [MpcCore.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/utils/mpc/MpcCore.sol) — see also [data shapes](architecture-and-components.md) | +| **Custom COTI calls** | [MpcAbiCodec.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpccodec/MpcAbiCodec.sol) and [custom tutorial](tutorial-custom-logic.md) | +| **Client crypto** | [coti-pod-crypto.ts](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) (`CotiPodCrypto`) | -## Implementation checklist (condensed) - -Derived from the SDK’s [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) and [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md): +## Implementation checklist 1. **Classify data** — public metadata vs `it*` inputs vs `ct*` outputs vs internal `gt*` (COTI-only). 2. **Pick integration mode** — `PodLib` helpers vs custom `MpcAbiCodec` + COTI contract. 3. **Model async state** — persist `requestId`, track pending/completed/failed. 4. **Harden callbacks** — `onlyInbox`, correct `abi.decode` tuple, validate peer context when applicable. 5. **Configure routing safely** — gated `configure` / `configureCoti` / inbox updates. -6. **Budget fees** — understand `msg.value` and `callbackFeeLocalWei`; use Inbox fee views where available ([Fees doc](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md)). -7. **Test failure paths** — spoofed callback must revert, error callbacks must mark failures, decrypt integration must match widths. +6. **Budget fees** — `msg.value` and `callbackFeeLocalWei`; Inbox fee views ([How do PoA fees work?](how-poa-fees-work.md)). +7. **Test failure paths** — spoofed callback must revert, error callbacks must mark failures, decrypt widths must match. ## Relationship to native COTI “build” documentation -If you build **directly on COTI V2** with precompiles and private types, start from **[Build on COTI](../build-on-coti/README.md)**. PoD adds the **Inbox-mediated cross-chain** angle; many **cryptographic ideas rhyme**, but **deployment and UX** differ. +If you build **directly on COTI V2** with precompiles and private types, start from **[Build on COTI](../build-on-coti/README.md)**. PoD adds the Inbox-mediated cross-chain path; cryptographic types rhyme, but deployment and UX differ. ## Package install diff --git a/privacy-on-avalanche/glossary.md b/privacy-on-avalanche/glossary.md index ad54ea1..9c35a9b 100644 --- a/privacy-on-avalanche/glossary.md +++ b/privacy-on-avalanche/glossary.md @@ -1,6 +1,6 @@ # Glossary -Short definitions for **Privacy on Demand** readers. Precise Solidity definitions and type tables are in the [PoD SDK contract types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md) document. +Short definitions for **Privacy on Demand** readers. Type roles (`it*`, `gt*`, `ct*`) are summarized in [Architecture and main components](architecture-and-components.md). Solidity structs live in [MpcCore.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/utils/mpc/MpcCore.sol). | Term | Meaning | | --- | --- | diff --git a/privacy-on-avalanche/how-a-private-request-travels-end-to-end.md b/privacy-on-avalanche/how-a-private-request-travels-end-to-end.md index 8450226..c54acf4 100644 --- a/privacy-on-avalanche/how-a-private-request-travels-end-to-end.md +++ b/privacy-on-avalanche/how-a-private-request-travels-end-to-end.md @@ -1,6 +1,6 @@ # How a private request travels end to end -This page describes **one full cycle** of Privacy on Demand **without assuming Solidity knowledge**. Names match what you will see in the [PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). +This page describes **one full cycle** of Privacy on Demand **without assuming Solidity knowledge**. Names match [Architecture and main components](architecture-and-components.md). ## Cast of roles @@ -12,7 +12,7 @@ This page describes **one full cycle** of Privacy on Demand **without assuming S | **Inbox (EVM)** | On-chain **messaging hub** on **your chain** that **forwards** jobs to the **Inbox (COTI)** and **calls back** into your contract when the answer is ready. | | **Inbox (COTI)** | The **COTI-side Inbox contract**—the **counterpart** to the host Inbox. It receives cross-domain messages and routes work to the MPC Executor. | | **COTI private execution** | The environment that performs **private computation** on **compute-domain values** (`gt*` in developer docs). | -| **MPC Executor** | The **COTI-side contract** your integration targets for a given network (see SDK presets such as `PodUserFuji` in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md)). The **Inbox (COTI)** invokes it; it is **not** the same contract as either Inbox. | +| **MPC Executor** | The **COTI-side contract** your integration targets for a given network (see SDK presets such as `PodUserFuji` in [Getting started](tutorial-private-adder-fuji.md)). The **Inbox (COTI)** invokes it; it is **not** the same contract as either Inbox. | ## The journey in seven steps @@ -79,7 +79,7 @@ sequenceDiagram ## Fees and gas -Private jobs that cross from your chain to COTI and back incur **network and execution costs**. Integrations typically attach **native token value** on the request and split it between **remote execution** and the **callback** leg. Operators configure **fee parameters** and **oracle** behavior on supporting contracts (see the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) page). +Private jobs that cross from your chain to COTI and back incur **network and execution costs**. Integrations typically attach **native token value** on the request and split it between **remote execution** and the **callback** leg. Operators configure **fee parameters** and **oracle** behavior on supporting contracts (see [How do PoA fees work?](how-poa-fees-work.md)). ## Next steps diff --git a/privacy-on-avalanche/how-poa-fees-work.md b/privacy-on-avalanche/how-poa-fees-work.md index a41c3d6..6976b84 100644 --- a/privacy-on-avalanche/how-poa-fees-work.md +++ b/privacy-on-avalanche/how-poa-fees-work.md @@ -141,7 +141,6 @@ const fee = await pod.estimateFee("add", podArgs, { - Payable **`add`** (or other `PodLib` helpers) with **`msg.value`** and **`callbackFeeLocalWei`** — see [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md). - Integration model context: [Tutorials overview](tutorials-privacy-on-avalanche.md). -- Contract-level detail: SDK [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md). ## Disclaimer diff --git a/privacy-on-avalanche/tutorial-custom-logic.md b/privacy-on-avalanche/tutorial-custom-logic.md index afae6e2..49b98c9 100644 --- a/privacy-on-avalanche/tutorial-custom-logic.md +++ b/privacy-on-avalanche/tutorial-custom-logic.md @@ -58,7 +58,7 @@ Paths like `../InboxUser.sol` assume you follow the SDK’s example layout; adju The Fuji contract **inherits `PodUserFuji`** (or your network’s `PodUser` preset), tracks the **COTI peer address**, and: -1. **`sendMessage`** — Wraps encrypted input (`itString`) and public addresses in an **`IInbox.MpcMethodCall`** built with **`MpcAbiCodec`** (see the SDK’s [Request builder and remote calls](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md)). It sends a **two-way** message so the result comes back asynchronously. +1. **`sendMessage`** — Wraps encrypted input (`itString`) and public addresses in an **`IInbox.MpcMethodCall`** built with **`MpcAbiCodec`** (see [How a private request travels end to end](how-a-private-request-travels-end-to-end.md)). It sends a **two-way** message so the result comes back asynchronously. 2. **`onMessageReceived`** — Decodes the tuple produced on COTI, **re-checks `inboxMsgSender()`**, and stores **`ctString`** keyed by conversation participants (or whatever your product needs). The Solidity below is **structurally** correct; wire **`MpcAbiCodec`**’s `create` / `addArgument` / `build` steps exactly as in your installed `@coti-io/coti-contracts` version (argument order and `gt`/`it` interface types **must** match the COTI method signature). @@ -135,8 +135,8 @@ This chapter stops at **Solidity** to highlight the **chain split**. For **encry - [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) — includes **`PodContract`**, **`encryptAndCallMethod`**, **`estimateFee`**, and **`extractRequestIds`** so you can copy the same client pattern to **`sendMessage`** (build **`PodMethodArgument[]`** with types that match your ABI: **`itString`** for the ciphertext argument, plain types for addresses and the callback-fee slot, **`isCallBackFee: true`** on the fee parameter). - [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) — short reference for **`CotiPodCrypto`** and **`PodContract`** with links to [`coti-pod-crypto.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts). -- [TypeScript integration — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) -- [Writing privacy contracts on Ethereum — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) (custom mode) +- [TypeScript PoD SDK](typescript-pod-sdk.md) +- [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) — custom COTI-side pattern. After **`encryptAndCallMethod("sendMessage", args, feeCfg)`** (or a raw **`ethers.Contract`** send), use **`await pod.extractRequestIds(receipt.hash)`** on the same **`PodContract`** instance so your UI stores the **`requestId`** emitted in the Inbox **`MessageSent`** logs—same helper as in the adder walkthrough. diff --git a/privacy-on-avalanche/tutorial-private-adder-fuji.md b/privacy-on-avalanche/tutorial-private-adder-fuji.md index 0c5e03d..64a1bff 100644 --- a/privacy-on-avalanche/tutorial-private-adder-fuji.md +++ b/privacy-on-avalanche/tutorial-private-adder-fuji.md @@ -2,9 +2,9 @@ This walkthrough is the **primitive-only** path: your host-chain contract calls **`PodLib`** helpers (the SDK surface for **MpcLib**-style primitives) and never deploys custom Solidity on COTI. If you are unsure whether that is enough for your product, read **[Tutorials: building Privacy on Avalanche (PoD) dApps](tutorials-privacy-on-avalanche.md)** first. -This guide shows how to build a minimal **Privacy on Demand** dApp that **adds two encrypted integers** on COTI and stores the **encrypted sum** on your EVM contract. It follows the same ideas as the SDK’s [MpcAdder.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/examples/MpcAdder.sol) example, extended with **Avalanche Fuji routing presets** and **request correlation** suitable for a real UI. +This guide shows how to build a minimal **Privacy on Demand** dApp that **adds two encrypted integers** on COTI and stores the **encrypted sum** on your EVM contract. It follows the same ideas as the SDK’s [MpcAdder.sol](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) example, extended with **Avalanche Fuji routing presets** and **request correlation** suitable for a real UI. -For background on async flows and fees, see [Async private operations](async-private-operations.md), [How do PoA fees work?](how-poa-fees-work.md), and the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) page. +For background on async flows and fees, see [Async private operations](async-private-operations.md) and [How do PoA fees work?](how-poa-fees-work.md). ## Writing a PoD example @@ -15,7 +15,7 @@ In this example we will do the following: 3. **Implement a success callback** that decodes `abi.encode(ctUint256)` and stores the ciphertext. 4. **Wire `onDefaultMpcError.selector`** so failed remote runs surface through the SDK’s default error path (and emit `ErrorRemoteCall` from `PodUser`). -After that works, you harden for production: per-user request ownership, explicit `pending / completed / failed` state, fee estimation via the Inbox, and tests for under-funded sends. The SDK’s [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) lists what the shipped `MpcAdder` omits on purpose. +After that works, you harden for production: per-user request ownership, explicit `pending / completed / failed` state, fee estimation via the Inbox, and tests for under-funded sends. The [tutorials index](tutorials-privacy-on-avalanche.md) lists what a minimal adder omits on purpose. ## Prerequisites @@ -24,7 +24,7 @@ Complete **[Getting started on Avalanche Fuji (Day 0)](getting-started-fuji.md)* - **Solidity toolchain** (Foundry or Hardhat) targeting **Avalanche Fuji C-Chain** (where the SDK’s `PodUserFuji` Inbox is deployed). - **Node.js 18+** for scripts and `fetch` used by encryption helpers. - **Fuji AVAX** for deployment and for **`msg.value`** on each `add` call (plus gas). -- **User onboarding** so your client can obtain an **account AES key** for decryption (see the SDK’s [TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) and [Onboarding / account AES key](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06c-onboarding-account-account-aes-key.md) docs). +- **User onboarding** so your client can obtain an **account AES key** for decryption (see the SDK’s [TypeScript integration](typescript-pod-sdk.md) and [Onboarding / account AES key](../how-coti-works/advanced-topics/aes-keys.md) docs). Always confirm **Inbox**, **COTI chain id**, and **MPC executor** against `PodUserFuji.sol` / `PodNetworkConstants.sol` in your installed `@coti-io/coti-contracts` package; constants can change between releases. @@ -46,7 +46,7 @@ Save as `PrivateAdder.sol`. The contract: - Inherits **`PodLib`** and **`PodUserFuji`** (Fuji Inbox + COTI Testnet routing are set in the `PodUserFuji` constructor — do not call `setInbox` / `configureCoti` again). - Calls **`add256`** with the caller’s encrypted inputs and your callback selector. -- Resolves **`requestId`** in the callback the same way as the SDK’s [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) example. +- Resolves **`requestId`** in the callback the same way as the [PrivateAdder](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) example. ```solidity // SPDX-License-Identifier: UNLICENSED @@ -240,15 +240,14 @@ console.log("sum (plaintext string):", decryptedString); - **Callback decode** must stay **`(ctUint256)`** — changing the executor op or COTI-side behavior without updating the decode tuple will corrupt storage reads. - **Type lane** — This contract uses **`add256`** with **`itUint256`** / **`ctUint256`** on chain. **`CotiPodCrypto.decrypt`** still takes a **`DataType`** for the scalar decode; keep **`DataType.Uint64`** (or **`Uint256`**, etc.) aligned with how your app and onboarding produce the ciphertext for this flow, per your installed SDK. -- **Production**: add tests for non-Inbox callers on `addCallback`, under-funded `msg.value`, and decrypt failures; follow the [first production checklist](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) in Getting started. +- **Production**: add tests for non-Inbox callers on `addCallback`, under-funded `msg.value`, and decrypt failures; follow the [first production checklist](tutorial-private-adder-fuji.md) in Getting started. ## Reference links - [`pod-method-call.ts` (`PodContract`, fees, `extractRequestIds`)](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts) -- [MpcAdder.sol (minimal repo example)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/examples/MpcAdder.sol) -- [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) -- [Getting started (PodUserFuji pattern)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) -- [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) +- [PrivateAdder.sol (repo example)](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) +- [Tutorials index](tutorials-privacy-on-avalanche.md) +- [Async private operations](async-private-operations.md)
diff --git a/privacy-on-avalanche/tutorials-privacy-on-avalanche.md b/privacy-on-avalanche/tutorials-privacy-on-avalanche.md index d371bcd..a639b4a 100644 --- a/privacy-on-avalanche/tutorials-privacy-on-avalanche.md +++ b/privacy-on-avalanche/tutorials-privacy-on-avalanche.md @@ -26,7 +26,7 @@ For **64-, 128-, and 256-bit** lanes, the library surface includes (names may be **Randomness:** `randBoundedBits` -For the authoritative list, signatures, and gas notes, use the SDK’s **[MPC library (PodLib)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md)** and **[PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol)** in your installed `@coti-io/coti-contracts` package. +For the authoritative list, signatures, and gas notes, use **[PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol)** in your installed `@coti-io/coti-contracts` package. ### Example tutorial (simple PoD dApp) @@ -138,9 +138,9 @@ flowchart LR | Your situation | Start here | | --- | --- | -| Logic fits the primitive list and a small number of MPC steps | [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md), [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md), then [MPC library (PodLib) — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md) | +| Logic fits the primitive list and a small number of MPC steps | [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md), [TypeScript PoD SDK](typescript-pod-sdk.md), [PodLib](architecture-and-components.md) | | You want a business-oriented public-to-private migration | [Cookbook: private investor allocations with PoD](cookbook-private-investor-allocations.md), then [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) | -| Logic needs custom COTI processing, `gt*` handling, or richer state | [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md), then [Writing privacy contracts on Ethereum — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) and [Request builder and remote calls — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md) | +| Logic needs custom COTI processing, `gt*` handling, or richer state | [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md), [How a private request travels end to end](how-a-private-request-travels-end-to-end.md) | | Fees, async UX, and components | [How do PoA fees work?](how-poa-fees-work.md), [Async private operations](async-private-operations.md), [Architecture and main components](architecture-and-components.md) | Return to the [Privacy on Avalanche section index](README.md). diff --git a/privacy-on-avalanche/typescript-pod-sdk.md b/privacy-on-avalanche/typescript-pod-sdk.md index 37769f9..1edc0d9 100644 --- a/privacy-on-avalanche/typescript-pod-sdk.md +++ b/privacy-on-avalanche/typescript-pod-sdk.md @@ -83,5 +83,3 @@ const requestIds = receipt?.hash ? await pod.extractRequestIds(receipt.hash) : [ - [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) — full walkthrough including `PodContract` and `extractRequestIds`. - [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) — custom COTI-side pattern. -- [TypeScript integration (SDK docs)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) -- [PoD SDK docs index](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) diff --git a/privacy-on-avalanche/what-is-privacy-on-avalanche.md b/privacy-on-avalanche/what-is-privacy-on-avalanche.md index d752cec..b400575 100644 --- a/privacy-on-avalanche/what-is-privacy-on-avalanche.md +++ b/privacy-on-avalanche/what-is-privacy-on-avalanche.md @@ -35,7 +35,7 @@ The **COTI PoD stack** provides the pattern: TypeScript helpers in [`@coti-io/po - **User experience** for onboarding, showing **pending / completed / failed** private operations, and **safe key handling**. - **Operations**: monitoring, indexing, or internal tools for stuck requests and AVAX fee configuration, as appropriate for your deployment. -The SDK’s own [documentation README](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/README.md) states scope clearly: it does not replace deployment scripts, indexers, or backend services for you. +Those packages do not replace your deployment scripts, indexers, or backend services. ## Next steps diff --git a/privacy-on-demand/README.md b/privacy-on-demand/README.md index 57c028c..6f792a3 100644 --- a/privacy-on-demand/README.md +++ b/privacy-on-demand/README.md @@ -17,8 +17,8 @@ Privacy on Demand lets applications use **strong privacy for data and computatio

Further resources

-- **[Examples](https://github.com/cotitech-io/coti-pod-sdk/tree/main/contracts/examples)** — Contract examples in the PoD SDK repo. -- **[PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs)** — Full SDK docs on GitHub. +- **[Examples](https://github.com/coti-io/coti-sdk-pod/tree/main/examples/private-adder-e2e)** — TypeScript e2e adder in [`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod). +- **[Solidity (`PodLib`, Inbox)](https://github.com/coti-io/coti-contracts/tree/main/contracts/pod)** — contracts in [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts). The same **Quick Access** and **Further resources** blocks appear on the [docs homepage](../README.md). @@ -26,7 +26,7 @@ The same **Quick Access** and **Further resources** blocks appear on the [docs h --- -This section explains **what PoD is**, **how it feels to users and operators**, and **how the main pieces fit together**. For step-by-step integration with the **COTI PoD SDK**, use the [npm package](https://www.npmjs.com/package/@coti/pod-sdk), the [documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs), and the links below. +This section explains **what PoD is**, **how it feels to users and operators**, and **how the main pieces fit together**. For integration, use [`@coti-io/pod-sdk`](https://www.npmjs.com/package/@coti-io/pod-sdk) (TypeScript) and [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts) (Solidity), plus the links below. ## Who this documentation is for @@ -50,7 +50,7 @@ This section explains **what PoD is**, **how it feels to users and operators**, 6. [Async private operations (why it is not instant)](async-private-operations.md) — What “pending” means and why UX must reflect it. 7. [How do PoA fees work?](how-poa-fees-work.md) — Two-way Inbox budgets, oracle conversion, and step-by-step gas-unit consumption (worked example). -8. [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) — Checklists and links to the [PoD SDK documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). +8. [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) — Checklists and links to source files. ### Tutorials (hands-on) @@ -62,6 +62,7 @@ This section explains **what PoD is**, **how it feels to users and operators**, ## Official technical reference -The machine-readable contracts, types, and APIs live in the open-source SDK. Treat this book chapter as the **human-oriented companion**; treat the repository as the **source of truth** for signatures, fees, and network constants: +Machine-readable contracts, types, and APIs live in the open-source packages. This GitBook section is the human-oriented companion; pin package versions for signatures, fees, and network constants: -- [COTI PoD SDK — documentation index](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) +- [`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod) — TypeScript +- [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts/tree/main/contracts/pod) — Solidity (`PodLib`, Inbox, examples) diff --git a/privacy-on-demand/architecture-and-components.md b/privacy-on-demand/architecture-and-components.md index 788dbf7..8714707 100644 --- a/privacy-on-demand/architecture-and-components.md +++ b/privacy-on-demand/architecture-and-components.md @@ -45,7 +45,7 @@ flowchart TB ### MPC executor (COTI) -- **What it is**: The **COTI-side contract address** your dApp is configured to call for a given deployment. The SDK’s network presets expose this as a constant you set during construction (for example `MPC_EXECUTOR_ADDRESS` alongside `COTI_CHAIN_ID` in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md)). +- **What it is**: The **COTI-side contract address** your dApp is configured to call for a given deployment. The SDK’s network presets expose this as a constant you set during construction (for example `MPC_EXECUTOR_ADDRESS` alongside `COTI_CHAIN_ID` in [Getting started](tutorial-private-adder-sepolia.md)). - **Why it matters**: It anchors **where** private execution is invoked in the COTI environment for **library-style** flows. ### PodUser @@ -55,8 +55,8 @@ flowchart TB ### PodLib -- **What it is**: **High-level helpers** for **common private operations** (for example comparisons and arithmetic at fixed bit widths—see the SDK [features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md) table). -- **Why it matters**: Faster path than writing a **custom** COTI contract for every operation. If you outgrow it, you move to **custom** encoding and COTI-side contracts using `MpcAbiCodec`, described in the SDK’s [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md). +- **What it is**: **High-level helpers** for **common private operations** (comparisons and arithmetic at fixed bit widths). +- **Why it matters**: Faster path than writing a **custom** COTI contract for every operation. If you outgrow it, you move to **custom** encoding and COTI-side contracts using `MpcAbiCodec` ([Tutorial: custom privacy logic](tutorial-custom-logic.md)). ## Data shapes: a non-developer mental model @@ -68,13 +68,11 @@ Engineers talk about **`it*`**, **`gt*`**, and **`ct*`**. At a high level: | **`gt*`** | **Private compute representation** during the operation | **Inside COTI** private execution | | **`ct*`** | **Encrypted output** you can **store on your chain** and **decrypt client-side** | **Returned** to your contract, **read** by the user’s app | -A fuller table lives in the SDK’s [data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md) page. - ## Trust and security highlights (for architects) -- **Callback authentication**: Your contract should only accept **Inbox-originated** callbacks for private results—otherwise anyone could try to spoof answers. The SDK’s `onlyInbox` pattern exists for this boundary ([features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md)). +- **Callback authentication**: Your contract should only accept **Inbox-originated** callbacks for private results—otherwise anyone could try to spoof answers. The `onlyInbox` pattern on `InboxUser` exists for this boundary. - **Request correlation**: Private work completes **later**; your system must track **request IDs** and statuses honestly in UX and backends ([Async private operations](async-private-operations.md)). -- **Key stewardship**: Client-side AES material is powerful; treat it like **credentials**, not analytics metadata ([TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md)). +- **Key stewardship**: Client-side AES material is powerful; treat it like **credentials**, not analytics metadata ([TypeScript PoD SDK](typescript-pod-sdk.md)). ## Next steps diff --git a/privacy-on-demand/async-private-operations.md b/privacy-on-demand/async-private-operations.md index 1a7e05b..c4a1196 100644 --- a/privacy-on-demand/async-private-operations.md +++ b/privacy-on-demand/async-private-operations.md @@ -18,7 +18,7 @@ So the user’s mental model should be closer to **“I submitted a job”** tha Private execution happens **outside** your chain’s normal synchronous EVM frame. The **Inbox** pattern exists precisely to **carry a message out** and **bring a response back** through a **controlled channel**. -The SDK’s [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) page lists the canonical lifecycle and common mistakes (wrong decode shape, missing `onlyInbox`, expecting same-block completion). +Common mistakes: wrong callback decode shape, missing `onlyInbox`, and expecting the private result in the same block as the request. ## What product and support teams should plan for diff --git a/privacy-on-demand/cookbook-private-investor-allocations.md b/privacy-on-demand/cookbook-private-investor-allocations.md index 91b774e..301afcc 100644 --- a/privacy-on-demand/cookbook-private-investor-allocations.md +++ b/privacy-on-demand/cookbook-private-investor-allocations.md @@ -40,7 +40,7 @@ The public version is useful because it gives you a known baseline: owner assign - A Solidity toolchain such as Hardhat or Foundry. - A Sepolia wallet with test ETH for deploys, transactions, and PoD request fees. - Node.js 18+ for scripts. -- The PoD SDK package: `npm install "@coti/pod-sdk"`. +- The PoD SDK package: `npm install "@coti-io/pod-sdk"`. - A way for users to complete PoD onboarding and obtain their account AES key for local decryption. Before implementing the private version, read: @@ -373,7 +373,7 @@ import { PodContract, type PodFeeEstimationConfig, type PodMethodArgument, -} from "@coti/pod-sdk"; +} from "@coti-io/pod-sdk"; const args: PodMethodArgument[] = [ { type: DataType.Address, value: investorAddress, isCallBackFee: false }, @@ -400,7 +400,7 @@ Tune `forwardGasLimit`, `callBackGasLimit`, and `callBackDataSize` from real mea The project owner encrypts allocation amounts before submitting them to the private flow. ```typescript -import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; const encryptedAllocation = await CotiPodCrypto.encrypt( ethers.parseUnits("1000", 18).toString(), @@ -583,4 +583,4 @@ Before adapting this cookbook for a real launch, add: - [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) - [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) - [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) -- [PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) +- [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) diff --git a/privacy-on-demand/for-developers-mapping-to-the-sdk.md b/privacy-on-demand/for-developers-mapping-to-the-sdk.md index 96750f6..64c9895 100644 --- a/privacy-on-demand/for-developers-mapping-to-the-sdk.md +++ b/privacy-on-demand/for-developers-mapping-to-the-sdk.md @@ -1,57 +1,58 @@ # For developers: mapping concepts to the SDK -This page is the **bridge** from [Architecture and main components](architecture-and-components.md) to the canonical [PoD SDK documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). It repeats a few facts on purpose so engineers can verify mental models quickly. +This page maps [Architecture and main components](architecture-and-components.md) to the packages you install: -For a guided first implementation, read **[Tutorials: building Privacy on Demand (PoD) dApps](tutorials-privacy-on-demand.md)** to pick the integration model, then follow [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) for a **primitive-only** Solidity + TypeScript walkthrough (Sepolia presets). +- TypeScript: [`@coti-io/pod-sdk`](https://www.npmjs.com/package/@coti-io/pod-sdk) ([GitHub](https://github.com/coti-io/coti-sdk-pod)) +- Solidity: [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts) (`contracts/pod/`) -## Official reading order (SDK) +For a guided first implementation, read **[Tutorials: building Privacy on Demand (PoD) dApps](tutorials-privacy-on-demand.md)**, then [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md). -The upstream docs recommend: +## Reading order -1. [Privacy dApps on any EVM chain with COTI PoD](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/01-privacy-decentralized-apps-on-any-evm-chain-with-coti-pod.md) -2. [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) -3. [Writing privacy contracts on Ethereum](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) -4. [TypeScript integration (UX development)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) +1. [What is Privacy on Demand?](what-is-privacy-on-demand.md) +2. [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) +3. [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) +4. [TypeScript PoD SDK](typescript-pod-sdk.md) -Then deep dives: +Then: -- [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) -- [MPC library (PodLib)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md) -- [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) -- Contract references: [Data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md), [Patterns and checklist](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/02-contract-patterns-and-checklist.md), [Request builder and remote calls](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md), [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) +- [Async private operations](async-private-operations.md) +- [Architecture and main components](architecture-and-components.md) (PodLib, types) +- [Tutorials index](tutorials-privacy-on-demand.md) +- [How a private request travels end to end](how-a-private-request-travels-end-to-end.md) +- [How do PoA fees work?](how-poa-fees-work.md) ## Component → source file map -| Concept (this book) | Where it lives in the SDK docs / repo | +| Concept (this book) | Where it lives | | --- | --- | -| **Inbox** | [IInbox.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/IInbox.sol) and cross-domain flow in the [domain model](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/01-privacy-decentralized-apps-on-any-evm-chain-with-coti-pod.md) diagram. | -| **Callback guard** | [InboxUser.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/InboxUser.sol) (`onlyInbox`) — see [Features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md). | -| **PodLib** | [PodLib.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpc/PodLib.sol) and width-specific libraries (`PodLib64`, `PodLib128`, `PodLib256`). | -| **PodUser / presets** | [PodUser.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpc/PodUser.sol), network mixins such as [PodUserSepolia.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpc/PodUserSepolia.sol) in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md). | -| **Types (`it*`, `ct*`, `gt*`)** | [MpcCore.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/utils/mpc/MpcCore.sol) and [Data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md). | -| **Custom COTI calls** | [MpcAbiCodec.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpccodec/MpcAbiCodec.sol) and the **custom mode** section of [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md). | -| **Client crypto** | [coti-pod-crypto.ts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts) via `CotiPodCrypto` ([TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md)). | +| **Inbox** | [IInbox.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/IInbox.sol) | +| **Callback guard** | [InboxUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/InboxUser.sol) (`onlyInbox`) | +| **PodLib** | [PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol) and width-specific libraries (`PodLib64`, `PodLib128`, `PodLib256`) | +| **PodUser / presets** | [PodUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUser.sol), [PodUserSepolia.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUserSepolia.sol) | +| **Types (`it*`, `ct*`, `gt*`)** | [MpcCore.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/utils/mpc/MpcCore.sol) — see also [data shapes](architecture-and-components.md) | +| **Custom COTI calls** | [MpcAbiCodec.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpccodec/MpcAbiCodec.sol) and [custom tutorial](tutorial-custom-logic.md) | +| **Client crypto** | [coti-pod-crypto.ts](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) (`CotiPodCrypto`) | -## Implementation checklist (condensed) - -Derived from the SDK’s [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) and [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md): +## Implementation checklist 1. **Classify data** — public metadata vs `it*` inputs vs `ct*` outputs vs internal `gt*` (COTI-only). 2. **Pick integration mode** — `PodLib` helpers vs custom `MpcAbiCodec` + COTI contract. 3. **Model async state** — persist `requestId`, track pending/completed/failed. 4. **Harden callbacks** — `onlyInbox`, correct `abi.decode` tuple, validate peer context when applicable. 5. **Configure routing safely** — gated `configure` / `configureCoti` / inbox updates. -6. **Budget fees** — understand `msg.value` and `callbackFeeLocalWei`; use Inbox fee views where available ([Fees doc](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md)). -7. **Test failure paths** — spoofed callback must revert, error callbacks must mark failures, decrypt integration must match widths. +6. **Budget fees** — `msg.value` and `callbackFeeLocalWei`; Inbox fee views ([How do PoA fees work?](how-poa-fees-work.md)). +7. **Test failure paths** — spoofed callback must revert, error callbacks must mark failures, decrypt widths must match. ## Relationship to native COTI “build” documentation -If you build **directly on COTI V2** with precompiles and private types, start from **[Build on COTI](../build-on-coti/README.md)**. PoD adds the **Inbox-mediated cross-chain** angle; many **cryptographic ideas rhyme**, but **deployment and UX** differ. +If you build **directly on COTI V2** with precompiles and private types, start from **[Build on COTI](../build-on-coti/README.md)**. PoD adds the Inbox-mediated cross-chain path; cryptographic types rhyme, but deployment and UX differ. ## Package install ```bash -npm install "@coti/pod-sdk" +npm install @coti-io/pod-sdk ethers +npm install github:coti-io/coti-contracts#main ``` -See [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) for Solidity imports and the `contract MyApp is PodLib, PodUserSepolia` pattern. +Solidity imports use `@coti-io/coti-contracts/contracts/pod/mpc/...`. The npm TypeScript package does not ship contract sources. diff --git a/privacy-on-demand/glossary.md b/privacy-on-demand/glossary.md index cbf6577..fb965b4 100644 --- a/privacy-on-demand/glossary.md +++ b/privacy-on-demand/glossary.md @@ -1,6 +1,6 @@ # Glossary -Short definitions for **Privacy on Demand** readers. Precise Solidity definitions and type tables are in the [PoD SDK contract types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md) document. +Short definitions for **Privacy on Demand** readers. Type roles (`it*`, `gt*`, `ct*`) are summarized in [Architecture and main components](architecture-and-components.md). Solidity structs live in [MpcCore.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/utils/mpc/MpcCore.sol). | Term | Meaning | | --- | --- | diff --git a/privacy-on-demand/how-a-private-request-travels-end-to-end.md b/privacy-on-demand/how-a-private-request-travels-end-to-end.md index 5008a90..e122f62 100644 --- a/privacy-on-demand/how-a-private-request-travels-end-to-end.md +++ b/privacy-on-demand/how-a-private-request-travels-end-to-end.md @@ -1,6 +1,6 @@ # How a private request travels end to end -This page describes **one full cycle** of Privacy on Demand **without assuming Solidity knowledge**. Names match what you will see in the [PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). +This page describes **one full cycle** of Privacy on Demand **without assuming Solidity knowledge**. Names match [Architecture and main components](architecture-and-components.md). ## Cast of roles @@ -12,7 +12,7 @@ This page describes **one full cycle** of Privacy on Demand **without assuming S | **Inbox (EVM)** | On-chain **messaging hub** on **your chain** that **forwards** jobs to the **Inbox (COTI)** and **calls back** into your contract when the answer is ready. | | **Inbox (COTI)** | The **COTI-side Inbox contract**—the **counterpart** to the host Inbox. It receives cross-domain messages and routes work to the MPC Executor. | | **COTI private execution** | The environment that performs **private computation** on **compute-domain values** (`gt*` in developer docs). | -| **MPC Executor** | The **COTI-side contract** your integration targets for a given network (see SDK presets such as `PodUserSepolia` in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md)). The **Inbox (COTI)** invokes it; it is **not** the same contract as either Inbox. | +| **MPC Executor** | The **COTI-side contract** your integration targets for a given network (see SDK presets such as `PodUserSepolia` in [Getting started](tutorial-private-adder-sepolia.md)). The **Inbox (COTI)** invokes it; it is **not** the same contract as either Inbox. | ## The journey in seven steps @@ -79,7 +79,7 @@ sequenceDiagram ## Fees and gas -Private jobs that cross from your chain to COTI and back incur **network and execution costs**. Integrations typically attach **native token value** on the request and split it between **remote execution** and the **callback** leg. Operators configure **fee parameters** and **oracle** behavior on supporting contracts (see the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) page). +Private jobs that cross from your chain to COTI and back incur **network and execution costs**. Integrations typically attach **native token value** on the request and split it between **remote execution** and the **callback** leg. Operators configure **fee parameters** and **oracle** behavior on supporting contracts (see [How do PoA fees work?](how-poa-fees-work.md)). ## Next steps diff --git a/privacy-on-demand/how-poa-fees-work.md b/privacy-on-demand/how-poa-fees-work.md index 9a0f9b9..0851c3d 100644 --- a/privacy-on-demand/how-poa-fees-work.md +++ b/privacy-on-demand/how-poa-fees-work.md @@ -4,7 +4,7 @@ This page explains how that payment is **split**, converted (via **oracles**) into **execution budgets** on each side—often described as **gas units**—and **consumed** step by step. -The numbers below are a **single worked example** so you can follow the arithmetic. Live networks use **oracle and Inbox policy** to set conversion rates and minimums; use your deployment’s **views** (for example `calculateTwoWayFeeRequiredInLocalToken`) and the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) reference for production. +The numbers below are a **single worked example** so you can follow the arithmetic. Live networks use **oracle and Inbox policy** to set conversion rates and minimums; use your deployment’s **views** (for example `calculateTwoWayFeeRequiredInLocalToken`) for production. ## Example call @@ -38,7 +38,7 @@ Solidity shape (conceptually): ## Walkthrough -Read the **first table top to bottom:** user ETH is split by leg, oracles supply **COTI** and **ETH** prices, the COTI leg is expressed as **quote → COTI tokens**, then policy turns each leg into **gas-unit budgets**. The **second table** spends **COTI** first, then **Sepolia** after the result exists. Underspend remains are illustrative; production behavior depends on **InboxMiner** / **InboxFeeManager** and operator policy (see the SDK [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) doc). +Read the **first table top to bottom:** user ETH is split by leg, oracles supply **COTI** and **ETH** prices, the COTI leg is expressed as **quote → COTI tokens**, then policy turns each leg into **gas-unit budgets**. The **second table** spends **COTI** first, then **Sepolia** after the result exists. Underspend remains are illustrative; production behavior depends on **InboxMiner** / **InboxFeeManager** and operator policy. ## Why this matters for `add(a, b) → ctUint64 c` @@ -49,7 +49,7 @@ Read the **first table top to bottom:** user ETH is split by leg, oracles supply ## Where to implement this in code - Solidity: payable **`add`** with **`msg.value`** and **`callbackFeeLocalWei`**, as in [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) (see [Tutorials overview](tutorials-privacy-on-demand.md) for how this fits the **primitive-only** model). -- Estimation: Inbox **`calculateTwoWayFeeRequiredInLocalToken`** and the [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) document in the PoD SDK repo. +- Estimation: Inbox **`calculateTwoWayFeeRequiredInLocalToken`**. ## Disclaimer diff --git a/privacy-on-demand/networks/README.md b/privacy-on-demand/networks/README.md index 763a20d..4646a0f 100644 --- a/privacy-on-demand/networks/README.md +++ b/privacy-on-demand/networks/README.md @@ -5,7 +5,7 @@ Privacy on Demand spans **two domains**: 1. **Host chain** — where your dApp contracts, assets, and the local **Inbox** live (for example Avalanche Fuji). 2. **COTI** — where private computation runs via the **MPC executor** and the COTI-side **Inbox**. -The pages below list network parameters and deployed contract addresses for current test environments. Addresses can change after redeploys; treat the [PoD SDK](https://github.com/cotitech-io/coti-pod-sdk) and your environment config as the live source of truth when building against a specific release. +The pages below list network parameters and deployed contract addresses for current test environments. Addresses can change after redeploys; treat [`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod), [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts), and your environment config as the live source of truth when building against a specific release. | Network | Chain ID | Role in PoD | | --- | --- | --- | diff --git a/privacy-on-demand/tutorial-custom-logic.md b/privacy-on-demand/tutorial-custom-logic.md index 15fd783..8178bf5 100644 --- a/privacy-on-demand/tutorial-custom-logic.md +++ b/privacy-on-demand/tutorial-custom-logic.md @@ -58,10 +58,10 @@ Paths like `../InboxUser.sol` assume you follow the SDK’s example layout; adju The Sepolia contract **inherits `PodUserSepolia`** (or your network’s `PodUser` preset), tracks the **COTI peer address**, and: -1. **`sendMessage`** — Wraps encrypted input (`itString`) and public addresses in an **`IInbox.MpcMethodCall`** built with **`MpcAbiCodec`** (see the SDK’s [Request builder and remote calls](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md)). It sends a **two-way** message so the result comes back asynchronously. +1. **`sendMessage`** — Wraps encrypted input (`itString`) and public addresses in an **`IInbox.MpcMethodCall`** built with **`MpcAbiCodec`** (see [How a private request travels end to end](how-a-private-request-travels-end-to-end.md)). It sends a **two-way** message so the result comes back asynchronously. 2. **`onMessageReceived`** — Decodes the tuple produced on COTI, **re-checks `inboxMsgSender()`**, and stores **`ctString`** keyed by conversation participants (or whatever your product needs). -The Solidity below is **structurally** correct; wire **`MpcAbiCodec`**’s `create` / `addArgument` / `build` steps exactly as in your installed `@coti/pod-sdk` version (argument order and `gt`/`it` interface types **must** match the COTI method signature). +The Solidity below is **structurally** correct; wire **`MpcAbiCodec`**’s `create` / `addArgument` / `build` steps exactly as in your installed `@coti-io/pod-sdk` version (argument order and `gt`/`it` interface types **must** match the COTI method signature). ```solidity // SPDX-License-Identifier: MIT @@ -134,9 +134,9 @@ contract DirectMessageEvm is PodUserSepolia { This chapter stops at **Solidity** to highlight the **chain split**. For **encryption**, **Inbox fee estimation**, and **client-side decryption** of `ctString`, continue with: - [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) — includes **`PodContract`**, **`encryptAndCallMethod`**, **`estimateFee`**, and **`extractRequestIds`** so you can copy the same client pattern to **`sendMessage`** (build **`PodMethodArgument[]`** with types that match your ABI: **`itString`** for the ciphertext argument, plain types for addresses and the callback-fee slot, **`isCallBackFee: true`** on the fee parameter). -- [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) — short reference for **`CotiPodCrypto`** and **`PodContract`** with links to [`coti-pod-crypto.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/pod-method-call.ts). -- [TypeScript integration — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) -- [Writing privacy contracts on Ethereum — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) (custom mode) +- [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) — short reference for **`CotiPodCrypto`** and **`PodContract`** with links to [`coti-pod-crypto.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts). +- [TypeScript PoD SDK](typescript-pod-sdk.md) +- [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) — custom COTI-side pattern. After **`encryptAndCallMethod("sendMessage", args, feeCfg)`** (or a raw **`ethers.Contract`** send), use **`await pod.extractRequestIds(receipt.hash)`** on the same **`PodContract`** instance so your UI stores the **`requestId`** emitted in the Inbox **`MessageSent`** logs—same helper as in the adder walkthrough. diff --git a/privacy-on-demand/tutorial-private-adder-sepolia.md b/privacy-on-demand/tutorial-private-adder-sepolia.md index 04bb85b..45c60ec 100644 --- a/privacy-on-demand/tutorial-private-adder-sepolia.md +++ b/privacy-on-demand/tutorial-private-adder-sepolia.md @@ -2,9 +2,9 @@ This walkthrough is the **primitive-only** path: your host-chain contract calls **`PodLib`** helpers (the SDK surface for **MpcLib**-style primitives) and never deploys custom Solidity on COTI. If you are unsure whether that is enough for your product, read **[Tutorials: building Privacy on Demand (PoD) dApps](tutorials-privacy-on-demand.md)** first. -This guide shows how to build a minimal **Privacy on Demand** dApp that **adds two encrypted integers** on COTI and stores the **encrypted sum** on your EVM contract. It follows the same ideas as the SDK’s [MpcAdder.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/examples/MpcAdder.sol) example, extended with **Sepolia routing presets** and **request correlation** suitable for a real UI. +This guide shows how to build a minimal **Privacy on Demand** dApp that **adds two encrypted integers** on COTI and stores the **encrypted sum** on your EVM contract. It follows the same ideas as the SDK’s [MpcAdder.sol](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) example, extended with **Sepolia routing presets** and **request correlation** suitable for a real UI. -For background on async flows and fees, see [Async private operations](async-private-operations.md), [How do PoA fees work?](how-poa-fees-work.md), and the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) page. +For background on async flows and fees, see [Async private operations](async-private-operations.md) and [How do PoA fees work?](how-poa-fees-work.md). ## Writing a PoD example @@ -15,38 +15,44 @@ In this example we will do the following: 3. **Implement a success callback** that decodes `abi.encode(ctUint256)` and stores the ciphertext. 4. **Wire `onDefaultMpcError.selector`** so failed remote runs surface through the SDK’s default error path (and emit `ErrorRemoteCall` from `PodUser`). -After that works, you harden for production: per-user request ownership, explicit `pending / completed / failed` state, fee estimation via the Inbox, and tests for under-funded sends. The SDK’s [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) lists what the shipped `MpcAdder` omits on purpose. +After that works, you harden for production: per-user request ownership, explicit `pending / completed / failed` state, fee estimation via the Inbox, and tests for under-funded sends. The [tutorials index](tutorials-privacy-on-demand.md) lists what a minimal adder omits on purpose. ## Prerequisites - **Solidity toolchain** (Foundry or Hardhat) targeting **Ethereum Sepolia** (where the SDK’s `PodUserSepolia` Inbox is deployed). - **Node.js 18+** for scripts and `fetch` used by encryption helpers. - **Sepolia ETH** for deployment and for **`msg.value`** on each `add` call (plus gas). -- **User onboarding** so your client can obtain an **account AES key** for decryption (see the SDK’s [TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) and [Onboarding / account AES key](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06c-onboarding-account-account-aes-key.md) docs). +- **User onboarding** so your client can obtain an **account AES key** for decryption (see the SDK’s [TypeScript integration](typescript-pod-sdk.md) and [Onboarding / account AES key](../how-coti-works/advanced-topics/aes-keys.md) docs). -Always confirm **Inbox**, **COTI chain id**, and **MPC executor** against the version of `PodUserSepolia.sol` in your installed `@coti/pod-sdk` package; constants can change between releases. +Always confirm **Inbox**, **COTI chain id**, and **MPC executor** against `PodUserSepolia.sol` / `PodNetworkConstants.sol` in your installed `@coti-io/coti-contracts` package; constants can change between releases. -## Step 1: Install the SDK +## Step 1: Install packages ```bash -npm install "@coti/pod-sdk" +# TypeScript helpers (encrypt / fees / send) +npm install @coti-io/pod-sdk ethers + +# Solidity (PodLib, PodUserSepolia, MpcCore) — currently install from GitHub main +npm install github:coti-io/coti-contracts#main ``` +`@coti-io/pod-sdk` is **TypeScript only**. Solidity imports come from `@coti-io/coti-contracts`. + ## Step 2: Create the `PrivateAdder` contract Save as `PrivateAdder.sol`. The contract: - Inherits **`PodLib`** and **`PodUserSepolia`** (Sepolia defaults for Inbox and COTI routing). - Calls **`add256`** with the caller’s encrypted inputs and your callback selector. -- Resolves **`requestId`** in the callback the same way as the SDK’s [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) example. +- Resolves **`requestId`** in the callback the same way as the [PrivateAdder](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) example. ```solidity // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.26; -import "@coti/pod-sdk/contracts/mpc/PodLib.sol"; -import "@coti/pod-sdk/contracts/mpc/PodUserSepolia.sol"; -import "@coti/pod-sdk/contracts/utils/mpc/MpcCore.sol"; +import "@coti-io/coti-contracts/contracts/pod/mpc/PodLib.sol"; +import "@coti-io/coti-contracts/contracts/pod/mpc/PodUserSepolia.sol"; +import "@coti-io/coti-contracts/contracts/utils/mpc/MpcCore.sol"; /// @title PrivateAdder /// @notice Adds two encrypted uint64 values via PoD on Sepolia (SDK preset addresses). @@ -108,7 +114,7 @@ contract PrivateAdder is PodLib, PodUserSepolia { ## Step 3: Compile and deploy on Sepolia -Configure remappings so `@coti/pod-sdk` resolves (Hardhat `paths`, Foundry `remappings.txt`, etc.), then compile and deploy `PrivateAdder` to **Ethereum Sepolia**. Record the deployed address for scripts. +Configure remappings so `@coti-io/pod-sdk` resolves (Hardhat `paths`, Foundry `remappings.txt`, etc.), then compile and deploy `PrivateAdder` to **Ethereum Sepolia**. Record the deployed address for scripts. ## Step 4: Budget `msg.value` and `callbackFeeLocalWei` @@ -116,12 +122,12 @@ Two-way Inbox traffic needs enough native token to cover **outbound execution** ## Step 5: Encrypt the two summands (TypeScript) -`CotiPodCrypto.encrypt` calls the PoD encryption service. For Sepolia-style test usage, pass **`"testnet"`** as the network key (see [`coti-pod-crypto.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts) in the SDK: `testnet` maps to the COTI testnet encryption endpoint). +`CotiPodCrypto.encrypt` calls the PoD encryption service. For Sepolia-style test usage, pass **`"testnet"`** as the network key (see [`coti-pod-crypto.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) in the SDK: `testnet` maps to the COTI testnet encryption endpoint). Use **`DataType.itUint256`** when you build **`itUint256`** calldata yourself (for example with **`ethers.Contract`**). If you use **`PodContract.encryptAndCallMethod`** in the next step, you can skip manual encryption: pass **plaintext numeric strings** and **`DataType.itUint256`** in each `PodMethodArgument`, and the SDK encrypts before encoding the transaction. ```typescript -import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; const plainA = "10"; const plainB = "20"; @@ -133,7 +139,7 @@ const encB = await CotiPodCrypto.encrypt(plainB, "testnet", DataType.itUint256); ## Step 6: Submit the `add` transaction (`PodContract`, fees, `extractRequestIds`) -[`PodContract`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/pod-method-call.ts) wraps your **`ethers.Contract`**: it **`estimateFee`**s against the Inbox, maps **`PodMethodArgument`** values (including **`encryptAndCallMethod`** encryption for **`it*`** types), injects the **`callBackFee`** into the slot marked **`isCallBackFee: true`**, sends **`value: totalFee`** on payable functions, and exposes **`extractRequestIds(txHash)`** to read **`requestId`** values from **`MessageSent`** logs on the Inbox (reliable across layouts where parsing logs from the app contract alone is brittle). +[`PodContract`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts) wraps your **`ethers.Contract`**: it **`estimateFee`**s against the Inbox, maps **`PodMethodArgument`** values (including **`encryptAndCallMethod`** encryption for **`it*`** types), injects the **`callBackFee`** into the slot marked **`isCallBackFee: true`**, sends **`value: totalFee`** on payable functions, and exposes **`extractRequestIds(txHash)`** to read **`requestId`** values from **`MessageSent`** logs on the Inbox (reliable across layouts where parsing logs from the app contract alone is brittle). ```typescript import { @@ -141,7 +147,7 @@ import { DataType, type PodFeeEstimationConfig, type PodMethodArgument, -} from "@coti/pod-sdk"; +} from "@coti-io/pod-sdk"; import { ethers } from "ethers"; // Minimal ABI fragment — prefer the full artifact from your build (Hardhat / Foundry). @@ -209,7 +215,7 @@ Private addition is **asynchronous**: the sum appears only after the Inbox invok After status is **Completed**, read **`sumByRequest(requestId)`**. The value is **`ctUint256`** (ciphertext), not plaintext. ```typescript -import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; // accountAesKey: hex string from your app’s COTI onboarding flow (never log it) @@ -229,21 +235,20 @@ console.log("sum (plaintext string):", decryptedString); // Expect "30" for plainA=10 and plainB=20 ``` -`CotiPodCrypto.decrypt` delegates to `@coti-io/coti-sdk-typescript` and expects a **scalar ciphertext** as a **hex string** for `Uint64`, plus the user’s **AES key** (see SDK source [coti-pod-crypto.ts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts)). +`CotiPodCrypto.decrypt` delegates to `@coti-io/coti-sdk-typescript` and expects a **scalar ciphertext** as a **hex string** for `Uint64`, plus the user’s **AES key** (see SDK source [coti-pod-crypto.ts](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts)). ## Step 8: Sanity checks and next steps - **Callback decode** must stay **`(ctUint256)`** — changing the executor op or COTI-side behavior without updating the decode tuple will corrupt storage reads. - **Type lane** — This contract uses **`add256`** with **`itUint256`** / **`ctUint256`** on chain. **`CotiPodCrypto.decrypt`** still takes a **`DataType`** for the scalar decode; keep **`DataType.Uint64`** (or **`Uint256`**, etc.) aligned with how your app and onboarding produce the ciphertext for this flow, per your installed SDK. -- **Production**: add tests for non-Inbox callers on `addCallback`, under-funded `msg.value`, and decrypt failures; follow the [first production checklist](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) in Getting started. +- **Production**: add tests for non-Inbox callers on `addCallback`, under-funded `msg.value`, and decrypt failures; follow the [first production checklist](tutorial-private-adder-sepolia.md) in Getting started. ## Reference links -- [`pod-method-call.ts` (`PodContract`, fees, `extractRequestIds`)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/pod-method-call.ts) -- [MpcAdder.sol (minimal repo example)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/examples/MpcAdder.sol) -- [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) -- [Getting started (PodUserSepolia pattern)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) -- [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) +- [`pod-method-call.ts` (`PodContract`, fees, `extractRequestIds`)](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts) +- [PrivateAdder.sol (repo example)](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) +- [Tutorials index](tutorials-privacy-on-demand.md) +- [Async private operations](async-private-operations.md)
diff --git a/privacy-on-demand/tutorials-privacy-on-demand.md b/privacy-on-demand/tutorials-privacy-on-demand.md index e19f720..002ac9d 100644 --- a/privacy-on-demand/tutorials-privacy-on-demand.md +++ b/privacy-on-demand/tutorials-privacy-on-demand.md @@ -26,7 +26,7 @@ For **64-, 128-, and 256-bit** lanes, the library surface includes (names may be **Randomness:** `randBoundedBits` -For the authoritative list, signatures, and gas notes, use the SDK’s **[MPC library (PodLib)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md)** and **[PodLib.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpc/PodLib.sol)** in your installed `@coti/pod-sdk` version. +For the authoritative list, signatures, and gas notes, use **[PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol)** in your installed `@coti-io/coti-contracts` package. ### Example tutorial (simple PoD dApp) @@ -138,9 +138,9 @@ flowchart LR | Your situation | Start here | | --- | --- | -| Logic fits the primitive list and a small number of MPC steps | [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md), [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md), then [MPC library (PodLib) — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md) | +| Logic fits the primitive list and a small number of MPC steps | [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md), [TypeScript PoD SDK](typescript-pod-sdk.md), [PodLib](architecture-and-components.md) | | You want a business-oriented public-to-private migration | [Cookbook: private investor allocations with PoD](cookbook-private-investor-allocations.md), then [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) | -| Logic needs custom COTI processing, `gt*` handling, or richer state | [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md), then [Writing privacy contracts on Ethereum — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) and [Request builder and remote calls — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md) | +| Logic needs custom COTI processing, `gt*` handling, or richer state | [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md), [How a private request travels end to end](how-a-private-request-travels-end-to-end.md) | | Fees, async UX, and components | [How do PoA fees work?](how-poa-fees-work.md), [Async private operations](async-private-operations.md), [Architecture and main components](architecture-and-components.md) | Return to the [Privacy on Demand section index](README.md). diff --git a/privacy-on-demand/typescript-pod-sdk.md b/privacy-on-demand/typescript-pod-sdk.md index 5a2f4af..ce747a0 100644 --- a/privacy-on-demand/typescript-pod-sdk.md +++ b/privacy-on-demand/typescript-pod-sdk.md @@ -1,6 +1,6 @@ # TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`) -The npm package **`@coti/pod-sdk`** ships TypeScript helpers for **encrypting and decrypting** PoD payloads and for **encoding, fee estimation, and sending** calls against your host-chain contract through [`coti-pod-crypto.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/pod-method-call.ts). +The npm package **`@coti-io/pod-sdk`** ships TypeScript helpers for **encrypting and decrypting** PoD payloads and for **encoding, fee estimation, and sending** calls against your host-chain contract through [`coti-pod-crypto.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts). Solidity (`PodLib`, `PodUserSepolia`) lives in **`@coti-io/coti-contracts`**, not in this package. Use these helpers from a wallet script, backend service, or dApp frontend once you have a **`Signer`** (or **`Provider`** for read-only helpers) and your contract **ABI**. @@ -15,7 +15,7 @@ Use these helpers from a wallet script, backend service, or dApp frontend once y `CotiPodCrypto.decrypt` uses the user's **account AES key** and `@coti-io/coti-sdk-typescript` under the hood. ```typescript -import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; // Encrypt plaintext for Solidity itUint256 parameters const enc = await CotiPodCrypto.encrypt("42", "testnet", DataType.itUint256); @@ -39,7 +39,7 @@ import { DataType, type PodFeeEstimationConfig, type PodMethodArgument, -} from "@coti/pod-sdk"; +} from "@coti-io/pod-sdk"; import { ethers } from "ethers"; const pod = new PodContract(contractAddress, abi, signer, { @@ -83,5 +83,3 @@ const requestIds = receipt?.hash ? await pod.extractRequestIds(receipt.hash) : [ - [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) — full walkthrough including `PodContract` and `extractRequestIds`. - [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) — custom COTI-side pattern. -- [TypeScript integration (SDK docs)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) -- [PoD SDK docs index](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) diff --git a/privacy-on-demand/what-is-privacy-on-demand.md b/privacy-on-demand/what-is-privacy-on-demand.md index dc230ac..0204c72 100644 --- a/privacy-on-demand/what-is-privacy-on-demand.md +++ b/privacy-on-demand/what-is-privacy-on-demand.md @@ -29,13 +29,13 @@ What PoD does **not** automatically guarantee by itself: ## What ships in the SDK versus what your team builds -The **COTI PoD SDK** ([GitHub](https://github.com/cotitech-io/coti-pod-sdk), [npm](https://www.npmjs.com/package/@coti/pod-sdk)) provides **contracts and TypeScript helpers** for the PoD pattern. Your project still typically supplies: +The **COTI PoD stack** provides the pattern: TypeScript helpers in [`@coti-io/pod-sdk`](https://www.npmjs.com/package/@coti-io/pod-sdk) ([GitHub](https://github.com/coti-io/coti-sdk-pod)), and Solidity (`PodLib`, **`PodUserSepolia`**, …) in [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts). Your project still typically supplies: - **Application-specific** EVM contracts and state machines. - **User experience** for onboarding, showing **pending / completed / failed** private operations, and **safe key handling**. - **Operations**: monitoring, indexing, or internal tools for stuck requests and fee configuration, as appropriate for your deployment. -The SDK’s own [documentation README](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/README.md) states scope clearly: it does not replace deployment scripts, indexers, or backend services for you. +Those packages do not replace your deployment scripts, indexers, or backend services. ## Next steps From 59b1486da2c5276aeb69724fe9df6bd205c295e0 Mon Sep 17 00:00:00 2001 From: Naiem Date: Sun, 6 Sep 2026 00:31:32 +0000 Subject: [PATCH 4/4] docs: keep ERC-7984 comparison changes in coti-erc7984 only Revert PoD, Privacy on Avalanche, and Build on COTI edits so this PR stays scoped to the comparison section. Co-authored-by: Cursor --- build-on-coti/quickstart.md | 4 +- build-on-coti/tools/remix-plugin.md | 2 +- privacy-on-avalanche/README.md | 9 ++- .../architecture-and-components.md | 12 ++-- .../async-private-operations.md | 2 +- .../cookbook-private-investor-allocations.md | 2 +- .../for-developers-mapping-to-the-sdk.md | 54 ++++++++--------- privacy-on-avalanche/glossary.md | 2 +- ...ow-a-private-request-travels-end-to-end.md | 6 +- privacy-on-avalanche/how-poa-fees-work.md | 1 + privacy-on-avalanche/tutorial-custom-logic.md | 6 +- .../tutorial-private-adder-fuji.md | 19 +++--- .../tutorials-privacy-on-avalanche.md | 6 +- privacy-on-avalanche/typescript-pod-sdk.md | 2 + .../what-is-privacy-on-avalanche.md | 2 +- privacy-on-demand/README.md | 13 ++-- .../architecture-and-components.md | 12 ++-- privacy-on-demand/async-private-operations.md | 2 +- .../cookbook-private-investor-allocations.md | 8 +-- .../for-developers-mapping-to-the-sdk.md | 59 +++++++++---------- privacy-on-demand/glossary.md | 2 +- ...ow-a-private-request-travels-end-to-end.md | 6 +- privacy-on-demand/how-poa-fees-work.md | 6 +- privacy-on-demand/networks/README.md | 2 +- privacy-on-demand/tutorial-custom-logic.md | 10 ++-- .../tutorial-private-adder-sepolia.md | 53 ++++++++--------- .../tutorials-privacy-on-demand.md | 6 +- privacy-on-demand/typescript-pod-sdk.md | 8 ++- .../what-is-privacy-on-demand.md | 4 +- 29 files changed, 161 insertions(+), 159 deletions(-) diff --git a/build-on-coti/quickstart.md b/build-on-coti/quickstart.md index 281c49e..a85b99a 100644 --- a/build-on-coti/quickstart.md +++ b/build-on-coti/quickstart.md @@ -172,7 +172,7 @@ This guide will help you explore the basics of interacting with the COTI network ``` -2. Navigate to the [**coti-ethers**](https://github.com/coti-io/coti-typescript-examples/tree/main/coti-ethers/server) examples subdirectory in the newly cloned repository directory\ +2. Navigate to the [**coti-ethers**](https://github.com/coti-io/coti-typescript-examples/blob/main/coti-ethers/server/README.md) examples subdirectory in the newly cloned repository directory\ ```bash @@ -264,7 +264,7 @@ This guide will help you explore the basics of interacting with the COTI network ``` -2. Navigate to the [**coti-web3**](https://github.com/coti-io/coti-python-examples/tree/main/coti-web3) examples subdirectory in the newly cloned repository directory\ +2. Navigate to the [**coti-web3**](https://github.com/coti-io/coti-python-examples/blob/main/coti-web3/README.md) examples subdirectory in the newly cloned repository directory\ ```bash diff --git a/build-on-coti/tools/remix-plugin.md b/build-on-coti/tools/remix-plugin.md index f25357c..b587f11 100644 --- a/build-on-coti/tools/remix-plugin.md +++ b/build-on-coti/tools/remix-plugin.md @@ -51,7 +51,7 @@ The Onboard section of the plugin provides an easy way to generate an AES key. T If the account has already been onboarded and an AES key has already been created, the key will be displayed in this section. -The Onboard action uses the [`AccountOnboard.sol`](https://github.com/coti-io/coti-contracts/blob/main/contracts/onboard/AccountOnboard.sol) contract. The TypeScript SDK no longer ships a dedicated `onboard.ts` file. +The Onboard action makes use of the [**`AccountOnboard.sol`**](https://github.com/coti-io/confidentiality-contracts/blob/main/contracts/AccountOnboard/AccountOnboard.sol) smart contract via the Typescript SDK [**`onboard.ts`**](https://github.com/coti-io/coti-sdk-typescript/blob/main/src/account/onboard.ts) script. Once the `Onboard` button is clicked, the plugin will return data related to your AES key. You may clear this data by clicking on the `Clear AES Key` button. diff --git a/privacy-on-avalanche/README.md b/privacy-on-avalanche/README.md index 68326d5..3db3997 100644 --- a/privacy-on-avalanche/README.md +++ b/privacy-on-avalanche/README.md @@ -22,7 +22,7 @@ Fees on the host side are paid in **AVAX**. Private execution still happens on C

Further resources

- **[Examples](https://github.com/coti-io/coti-contracts/tree/main/contracts/pod/examples)** — Contract examples in `@coti-io/coti-contracts`. -- **[`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod)** — TypeScript SDK. +- **[PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs)** — Full SDK docs on GitHub. - **[General Privacy on Demand section](../privacy-on-demand/README.md)** — Multi-host PoD overview (not Avalanche-only).
@@ -72,7 +72,7 @@ Full tables: [Avalanche Fuji](networks/fuji.md). 7. [Async private operations (why it is not instant)](async-private-operations.md) — What “pending” means and why UX must reflect it. 8. [How do PoA fees work?](how-poa-fees-work.md) — Two-way Inbox budgets in AVAX, oracle conversion, and a worked gas-unit example. -9. [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) — Checklists and links to source files. +9. [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) — Checklists and links to the [PoD SDK documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). ### Tutorials (hands-on) @@ -84,7 +84,6 @@ Full tables: [Avalanche Fuji](networks/fuji.md). ## Official technical reference -Machine-readable contracts, types, and APIs live in the open-source packages. This GitBook section is the human-oriented companion; pin package versions for signatures, fees, and network constants: +The machine-readable contracts, types, and APIs live in the open-source SDK. Treat this book chapter as the **human-oriented companion**; treat the repository as the **source of truth** for signatures, fees, and network constants: -- [`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod) — TypeScript -- [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts/tree/main/contracts/pod) — Solidity (`PodLib`, Inbox, examples) +- [COTI PoD SDK — documentation index](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) diff --git a/privacy-on-avalanche/architecture-and-components.md b/privacy-on-avalanche/architecture-and-components.md index e57b7a9..6d95c9c 100644 --- a/privacy-on-avalanche/architecture-and-components.md +++ b/privacy-on-avalanche/architecture-and-components.md @@ -45,7 +45,7 @@ flowchart TB ### MPC executor (COTI) -- **What it is**: The **COTI-side contract address** your dApp is configured to call for a given deployment. The SDK’s network presets expose this as a constant you set during construction (for example `MPC_EXECUTOR_ADDRESS` alongside `COTI_CHAIN_ID` in [Getting started](tutorial-private-adder-fuji.md)). +- **What it is**: The **COTI-side contract address** your dApp is configured to call for a given deployment. The SDK’s network presets expose this as a constant you set during construction (for example `MPC_EXECUTOR_ADDRESS` alongside `COTI_CHAIN_ID` in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md)). - **Why it matters**: It anchors **where** private execution is invoked in the COTI environment for **library-style** flows. ### PodUser @@ -55,8 +55,8 @@ flowchart TB ### PodLib -- **What it is**: **High-level helpers** for **common private operations** (comparisons and arithmetic at fixed bit widths). -- **Why it matters**: Faster path than writing a **custom** COTI contract for every operation. If you outgrow it, you move to **custom** encoding and COTI-side contracts using `MpcAbiCodec` ([Tutorial: custom privacy logic](tutorial-custom-logic.md)). +- **What it is**: **High-level helpers** for **common private operations** (for example comparisons and arithmetic at fixed bit widths—see the SDK [features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md) table). +- **Why it matters**: Faster path than writing a **custom** COTI contract for every operation. If you outgrow it, you move to **custom** encoding and COTI-side contracts using `MpcAbiCodec`, described in the SDK’s [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md). ## Data shapes: a non-developer mental model @@ -68,11 +68,13 @@ Engineers talk about **`it*`**, **`gt*`**, and **`ct*`**. At a high level: | **`gt*`** | **Private compute representation** during the operation | **Inside COTI** private execution | | **`ct*`** | **Encrypted output** you can **store on your chain** and **decrypt client-side** | **Returned** to your contract, **read** by the user’s app | +A fuller table lives in the SDK’s [data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md) page. + ## Trust and security highlights (for architects) -- **Callback authentication**: Your contract should only accept **Inbox-originated** callbacks for private results—otherwise anyone could try to spoof answers. The `onlyInbox` pattern on `InboxUser` exists for this boundary. +- **Callback authentication**: Your contract should only accept **Inbox-originated** callbacks for private results—otherwise anyone could try to spoof answers. The SDK’s `onlyInbox` pattern exists for this boundary ([features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md)). - **Request correlation**: Private work completes **later**; your system must track **request IDs** and statuses honestly in UX and backends ([Async private operations](async-private-operations.md)). -- **Key stewardship**: Client-side AES material is powerful; treat it like **credentials**, not analytics metadata ([TypeScript PoD SDK](typescript-pod-sdk.md)). +- **Key stewardship**: Client-side AES material is powerful; treat it like **credentials**, not analytics metadata ([TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md)). ## Next steps diff --git a/privacy-on-avalanche/async-private-operations.md b/privacy-on-avalanche/async-private-operations.md index c4a1196..1a7e05b 100644 --- a/privacy-on-avalanche/async-private-operations.md +++ b/privacy-on-avalanche/async-private-operations.md @@ -18,7 +18,7 @@ So the user’s mental model should be closer to **“I submitted a job”** tha Private execution happens **outside** your chain’s normal synchronous EVM frame. The **Inbox** pattern exists precisely to **carry a message out** and **bring a response back** through a **controlled channel**. -Common mistakes: wrong callback decode shape, missing `onlyInbox`, and expecting the private result in the same block as the request. +The SDK’s [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) page lists the canonical lifecycle and common mistakes (wrong decode shape, missing `onlyInbox`, expecting same-block completion). ## What product and support teams should plan for diff --git a/privacy-on-avalanche/cookbook-private-investor-allocations.md b/privacy-on-avalanche/cookbook-private-investor-allocations.md index 17681bc..e9e0fee 100644 --- a/privacy-on-avalanche/cookbook-private-investor-allocations.md +++ b/privacy-on-avalanche/cookbook-private-investor-allocations.md @@ -583,4 +583,4 @@ Before adapting this cookbook for a real launch, add: - [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) - [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) - [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) -- [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) +- [PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) diff --git a/privacy-on-avalanche/for-developers-mapping-to-the-sdk.md b/privacy-on-avalanche/for-developers-mapping-to-the-sdk.md index c066d7e..a8293b7 100644 --- a/privacy-on-avalanche/for-developers-mapping-to-the-sdk.md +++ b/privacy-on-avalanche/for-developers-mapping-to-the-sdk.md @@ -1,52 +1,52 @@ # For developers: mapping concepts to the SDK -This page maps [Architecture and main components](architecture-and-components.md) to the packages you install: +This page is the **bridge** from [Architecture and main components](architecture-and-components.md) to the canonical [PoD SDK documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). It repeats a few facts on purpose so engineers can verify mental models quickly. -- TypeScript: [`@coti-io/pod-sdk`](https://www.npmjs.com/package/@coti-io/pod-sdk) ([GitHub](https://github.com/coti-io/coti-sdk-pod)) -- Solidity: [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts) (`contracts/pod/`) +For a guided first implementation, read **[Tutorials: building Privacy on Avalanche (PoD) dApps](tutorials-privacy-on-avalanche.md)** to pick the integration model, then follow [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) for a **primitive-only** Solidity + TypeScript walkthrough (Avalanche Fuji presets). -For a guided first implementation, read **[Tutorials: building Privacy on Avalanche (PoD) dApps](tutorials-privacy-on-avalanche.md)**, then [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md). +## Official reading order (SDK) -## Reading order +The upstream docs recommend: -1. [What is Privacy on Avalanche?](what-is-privacy-on-avalanche.md) -2. [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) -3. [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) -4. [TypeScript PoD SDK](typescript-pod-sdk.md) +1. [Privacy dApps on any EVM chain with COTI PoD](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/01-privacy-decentralized-apps-on-any-evm-chain-with-coti-pod.md) +2. [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) +3. [Writing privacy contracts on Ethereum](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) +4. [TypeScript integration (UX development)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) -Then: +Then deep dives: -- [Async private operations](async-private-operations.md) -- [Architecture and main components](architecture-and-components.md) (PodLib, types) -- [Tutorials index](tutorials-privacy-on-avalanche.md) -- [How a private request travels end to end](how-a-private-request-travels-end-to-end.md) -- [How do PoA fees work?](how-poa-fees-work.md) +- [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) +- [MPC library (PodLib)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md) +- [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) +- Contract references: [Data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md), [Patterns and checklist](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/02-contract-patterns-and-checklist.md), [Request builder and remote calls](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md), [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) ## Component → source file map -| Concept (this book) | Where it lives | +| Concept (this book) | Where it lives in the SDK docs / repo | | --- | --- | -| **Inbox** | [IInbox.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/IInbox.sol) | -| **Callback guard** | [InboxUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/InboxUser.sol) (`onlyInbox`) | -| **PodLib** | [PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol) and width-specific libraries (`PodLib64`, `PodLib128`, `PodLib256`) | -| **PodUser / presets** | [PodUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUser.sol), [PodUserFuji.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUserFuji.sol) | -| **Types (`it*`, `ct*`, `gt*`)** | [MpcCore.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/utils/mpc/MpcCore.sol) — see also [data shapes](architecture-and-components.md) | -| **Custom COTI calls** | [MpcAbiCodec.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpccodec/MpcAbiCodec.sol) and [custom tutorial](tutorial-custom-logic.md) | -| **Client crypto** | [coti-pod-crypto.ts](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) (`CotiPodCrypto`) | +| **Inbox** | [IInbox.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/IInbox.sol) and cross-domain flow in the [domain model](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/01-privacy-decentralized-apps-on-any-evm-chain-with-coti-pod.md) diagram. | +| **Callback guard** | [InboxUser.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/InboxUser.sol) (`onlyInbox`) — see [Features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md). | +| **PodLib** | [PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol) and width-specific libraries (`PodLib64`, `PodLib128`, `PodLib256`). | +| **PodUser / presets** | [PodUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUser.sol), network mixins such as [PodUserFuji.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUserFuji.sol). | +| **Types (`it*`, `ct*`, `gt*`)** | [MpcCore.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/utils/mpc/MpcCore.sol) and [Data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md). | +| **Custom COTI calls** | [MpcAbiCodec.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpccodec/MpcAbiCodec.sol) and the **custom mode** section of [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md). | +| **Client crypto** | [coti-pod-crypto.ts](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) via `CotiPodCrypto` ([TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md)). | -## Implementation checklist +## Implementation checklist (condensed) + +Derived from the SDK’s [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) and [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md): 1. **Classify data** — public metadata vs `it*` inputs vs `ct*` outputs vs internal `gt*` (COTI-only). 2. **Pick integration mode** — `PodLib` helpers vs custom `MpcAbiCodec` + COTI contract. 3. **Model async state** — persist `requestId`, track pending/completed/failed. 4. **Harden callbacks** — `onlyInbox`, correct `abi.decode` tuple, validate peer context when applicable. 5. **Configure routing safely** — gated `configure` / `configureCoti` / inbox updates. -6. **Budget fees** — `msg.value` and `callbackFeeLocalWei`; Inbox fee views ([How do PoA fees work?](how-poa-fees-work.md)). -7. **Test failure paths** — spoofed callback must revert, error callbacks must mark failures, decrypt widths must match. +6. **Budget fees** — understand `msg.value` and `callbackFeeLocalWei`; use Inbox fee views where available ([Fees doc](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md)). +7. **Test failure paths** — spoofed callback must revert, error callbacks must mark failures, decrypt integration must match widths. ## Relationship to native COTI “build” documentation -If you build **directly on COTI V2** with precompiles and private types, start from **[Build on COTI](../build-on-coti/README.md)**. PoD adds the Inbox-mediated cross-chain path; cryptographic types rhyme, but deployment and UX differ. +If you build **directly on COTI V2** with precompiles and private types, start from **[Build on COTI](../build-on-coti/README.md)**. PoD adds the **Inbox-mediated cross-chain** angle; many **cryptographic ideas rhyme**, but **deployment and UX** differ. ## Package install diff --git a/privacy-on-avalanche/glossary.md b/privacy-on-avalanche/glossary.md index 9c35a9b..ad54ea1 100644 --- a/privacy-on-avalanche/glossary.md +++ b/privacy-on-avalanche/glossary.md @@ -1,6 +1,6 @@ # Glossary -Short definitions for **Privacy on Demand** readers. Type roles (`it*`, `gt*`, `ct*`) are summarized in [Architecture and main components](architecture-and-components.md). Solidity structs live in [MpcCore.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/utils/mpc/MpcCore.sol). +Short definitions for **Privacy on Demand** readers. Precise Solidity definitions and type tables are in the [PoD SDK contract types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md) document. | Term | Meaning | | --- | --- | diff --git a/privacy-on-avalanche/how-a-private-request-travels-end-to-end.md b/privacy-on-avalanche/how-a-private-request-travels-end-to-end.md index c54acf4..8450226 100644 --- a/privacy-on-avalanche/how-a-private-request-travels-end-to-end.md +++ b/privacy-on-avalanche/how-a-private-request-travels-end-to-end.md @@ -1,6 +1,6 @@ # How a private request travels end to end -This page describes **one full cycle** of Privacy on Demand **without assuming Solidity knowledge**. Names match [Architecture and main components](architecture-and-components.md). +This page describes **one full cycle** of Privacy on Demand **without assuming Solidity knowledge**. Names match what you will see in the [PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). ## Cast of roles @@ -12,7 +12,7 @@ This page describes **one full cycle** of Privacy on Demand **without assuming S | **Inbox (EVM)** | On-chain **messaging hub** on **your chain** that **forwards** jobs to the **Inbox (COTI)** and **calls back** into your contract when the answer is ready. | | **Inbox (COTI)** | The **COTI-side Inbox contract**—the **counterpart** to the host Inbox. It receives cross-domain messages and routes work to the MPC Executor. | | **COTI private execution** | The environment that performs **private computation** on **compute-domain values** (`gt*` in developer docs). | -| **MPC Executor** | The **COTI-side contract** your integration targets for a given network (see SDK presets such as `PodUserFuji` in [Getting started](tutorial-private-adder-fuji.md)). The **Inbox (COTI)** invokes it; it is **not** the same contract as either Inbox. | +| **MPC Executor** | The **COTI-side contract** your integration targets for a given network (see SDK presets such as `PodUserFuji` in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md)). The **Inbox (COTI)** invokes it; it is **not** the same contract as either Inbox. | ## The journey in seven steps @@ -79,7 +79,7 @@ sequenceDiagram ## Fees and gas -Private jobs that cross from your chain to COTI and back incur **network and execution costs**. Integrations typically attach **native token value** on the request and split it between **remote execution** and the **callback** leg. Operators configure **fee parameters** and **oracle** behavior on supporting contracts (see [How do PoA fees work?](how-poa-fees-work.md)). +Private jobs that cross from your chain to COTI and back incur **network and execution costs**. Integrations typically attach **native token value** on the request and split it between **remote execution** and the **callback** leg. Operators configure **fee parameters** and **oracle** behavior on supporting contracts (see the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) page). ## Next steps diff --git a/privacy-on-avalanche/how-poa-fees-work.md b/privacy-on-avalanche/how-poa-fees-work.md index 6976b84..a41c3d6 100644 --- a/privacy-on-avalanche/how-poa-fees-work.md +++ b/privacy-on-avalanche/how-poa-fees-work.md @@ -141,6 +141,7 @@ const fee = await pod.estimateFee("add", podArgs, { - Payable **`add`** (or other `PodLib` helpers) with **`msg.value`** and **`callbackFeeLocalWei`** — see [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md). - Integration model context: [Tutorials overview](tutorials-privacy-on-avalanche.md). +- Contract-level detail: SDK [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md). ## Disclaimer diff --git a/privacy-on-avalanche/tutorial-custom-logic.md b/privacy-on-avalanche/tutorial-custom-logic.md index 49b98c9..afae6e2 100644 --- a/privacy-on-avalanche/tutorial-custom-logic.md +++ b/privacy-on-avalanche/tutorial-custom-logic.md @@ -58,7 +58,7 @@ Paths like `../InboxUser.sol` assume you follow the SDK’s example layout; adju The Fuji contract **inherits `PodUserFuji`** (or your network’s `PodUser` preset), tracks the **COTI peer address**, and: -1. **`sendMessage`** — Wraps encrypted input (`itString`) and public addresses in an **`IInbox.MpcMethodCall`** built with **`MpcAbiCodec`** (see [How a private request travels end to end](how-a-private-request-travels-end-to-end.md)). It sends a **two-way** message so the result comes back asynchronously. +1. **`sendMessage`** — Wraps encrypted input (`itString`) and public addresses in an **`IInbox.MpcMethodCall`** built with **`MpcAbiCodec`** (see the SDK’s [Request builder and remote calls](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md)). It sends a **two-way** message so the result comes back asynchronously. 2. **`onMessageReceived`** — Decodes the tuple produced on COTI, **re-checks `inboxMsgSender()`**, and stores **`ctString`** keyed by conversation participants (or whatever your product needs). The Solidity below is **structurally** correct; wire **`MpcAbiCodec`**’s `create` / `addArgument` / `build` steps exactly as in your installed `@coti-io/coti-contracts` version (argument order and `gt`/`it` interface types **must** match the COTI method signature). @@ -135,8 +135,8 @@ This chapter stops at **Solidity** to highlight the **chain split**. For **encry - [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) — includes **`PodContract`**, **`encryptAndCallMethod`**, **`estimateFee`**, and **`extractRequestIds`** so you can copy the same client pattern to **`sendMessage`** (build **`PodMethodArgument[]`** with types that match your ABI: **`itString`** for the ciphertext argument, plain types for addresses and the callback-fee slot, **`isCallBackFee: true`** on the fee parameter). - [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) — short reference for **`CotiPodCrypto`** and **`PodContract`** with links to [`coti-pod-crypto.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts). -- [TypeScript PoD SDK](typescript-pod-sdk.md) -- [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) — custom COTI-side pattern. +- [TypeScript integration — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) +- [Writing privacy contracts on Ethereum — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) (custom mode) After **`encryptAndCallMethod("sendMessage", args, feeCfg)`** (or a raw **`ethers.Contract`** send), use **`await pod.extractRequestIds(receipt.hash)`** on the same **`PodContract`** instance so your UI stores the **`requestId`** emitted in the Inbox **`MessageSent`** logs—same helper as in the adder walkthrough. diff --git a/privacy-on-avalanche/tutorial-private-adder-fuji.md b/privacy-on-avalanche/tutorial-private-adder-fuji.md index 64a1bff..0c5e03d 100644 --- a/privacy-on-avalanche/tutorial-private-adder-fuji.md +++ b/privacy-on-avalanche/tutorial-private-adder-fuji.md @@ -2,9 +2,9 @@ This walkthrough is the **primitive-only** path: your host-chain contract calls **`PodLib`** helpers (the SDK surface for **MpcLib**-style primitives) and never deploys custom Solidity on COTI. If you are unsure whether that is enough for your product, read **[Tutorials: building Privacy on Avalanche (PoD) dApps](tutorials-privacy-on-avalanche.md)** first. -This guide shows how to build a minimal **Privacy on Demand** dApp that **adds two encrypted integers** on COTI and stores the **encrypted sum** on your EVM contract. It follows the same ideas as the SDK’s [MpcAdder.sol](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) example, extended with **Avalanche Fuji routing presets** and **request correlation** suitable for a real UI. +This guide shows how to build a minimal **Privacy on Demand** dApp that **adds two encrypted integers** on COTI and stores the **encrypted sum** on your EVM contract. It follows the same ideas as the SDK’s [MpcAdder.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/examples/MpcAdder.sol) example, extended with **Avalanche Fuji routing presets** and **request correlation** suitable for a real UI. -For background on async flows and fees, see [Async private operations](async-private-operations.md) and [How do PoA fees work?](how-poa-fees-work.md). +For background on async flows and fees, see [Async private operations](async-private-operations.md), [How do PoA fees work?](how-poa-fees-work.md), and the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) page. ## Writing a PoD example @@ -15,7 +15,7 @@ In this example we will do the following: 3. **Implement a success callback** that decodes `abi.encode(ctUint256)` and stores the ciphertext. 4. **Wire `onDefaultMpcError.selector`** so failed remote runs surface through the SDK’s default error path (and emit `ErrorRemoteCall` from `PodUser`). -After that works, you harden for production: per-user request ownership, explicit `pending / completed / failed` state, fee estimation via the Inbox, and tests for under-funded sends. The [tutorials index](tutorials-privacy-on-avalanche.md) lists what a minimal adder omits on purpose. +After that works, you harden for production: per-user request ownership, explicit `pending / completed / failed` state, fee estimation via the Inbox, and tests for under-funded sends. The SDK’s [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) lists what the shipped `MpcAdder` omits on purpose. ## Prerequisites @@ -24,7 +24,7 @@ Complete **[Getting started on Avalanche Fuji (Day 0)](getting-started-fuji.md)* - **Solidity toolchain** (Foundry or Hardhat) targeting **Avalanche Fuji C-Chain** (where the SDK’s `PodUserFuji` Inbox is deployed). - **Node.js 18+** for scripts and `fetch` used by encryption helpers. - **Fuji AVAX** for deployment and for **`msg.value`** on each `add` call (plus gas). -- **User onboarding** so your client can obtain an **account AES key** for decryption (see the SDK’s [TypeScript integration](typescript-pod-sdk.md) and [Onboarding / account AES key](../how-coti-works/advanced-topics/aes-keys.md) docs). +- **User onboarding** so your client can obtain an **account AES key** for decryption (see the SDK’s [TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) and [Onboarding / account AES key](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06c-onboarding-account-account-aes-key.md) docs). Always confirm **Inbox**, **COTI chain id**, and **MPC executor** against `PodUserFuji.sol` / `PodNetworkConstants.sol` in your installed `@coti-io/coti-contracts` package; constants can change between releases. @@ -46,7 +46,7 @@ Save as `PrivateAdder.sol`. The contract: - Inherits **`PodLib`** and **`PodUserFuji`** (Fuji Inbox + COTI Testnet routing are set in the `PodUserFuji` constructor — do not call `setInbox` / `configureCoti` again). - Calls **`add256`** with the caller’s encrypted inputs and your callback selector. -- Resolves **`requestId`** in the callback the same way as the [PrivateAdder](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) example. +- Resolves **`requestId`** in the callback the same way as the SDK’s [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) example. ```solidity // SPDX-License-Identifier: UNLICENSED @@ -240,14 +240,15 @@ console.log("sum (plaintext string):", decryptedString); - **Callback decode** must stay **`(ctUint256)`** — changing the executor op or COTI-side behavior without updating the decode tuple will corrupt storage reads. - **Type lane** — This contract uses **`add256`** with **`itUint256`** / **`ctUint256`** on chain. **`CotiPodCrypto.decrypt`** still takes a **`DataType`** for the scalar decode; keep **`DataType.Uint64`** (or **`Uint256`**, etc.) aligned with how your app and onboarding produce the ciphertext for this flow, per your installed SDK. -- **Production**: add tests for non-Inbox callers on `addCallback`, under-funded `msg.value`, and decrypt failures; follow the [first production checklist](tutorial-private-adder-fuji.md) in Getting started. +- **Production**: add tests for non-Inbox callers on `addCallback`, under-funded `msg.value`, and decrypt failures; follow the [first production checklist](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) in Getting started. ## Reference links - [`pod-method-call.ts` (`PodContract`, fees, `extractRequestIds`)](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts) -- [PrivateAdder.sol (repo example)](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) -- [Tutorials index](tutorials-privacy-on-avalanche.md) -- [Async private operations](async-private-operations.md) +- [MpcAdder.sol (minimal repo example)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/examples/MpcAdder.sol) +- [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) +- [Getting started (PodUserFuji pattern)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) +- [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md)
diff --git a/privacy-on-avalanche/tutorials-privacy-on-avalanche.md b/privacy-on-avalanche/tutorials-privacy-on-avalanche.md index a639b4a..d371bcd 100644 --- a/privacy-on-avalanche/tutorials-privacy-on-avalanche.md +++ b/privacy-on-avalanche/tutorials-privacy-on-avalanche.md @@ -26,7 +26,7 @@ For **64-, 128-, and 256-bit** lanes, the library surface includes (names may be **Randomness:** `randBoundedBits` -For the authoritative list, signatures, and gas notes, use **[PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol)** in your installed `@coti-io/coti-contracts` package. +For the authoritative list, signatures, and gas notes, use the SDK’s **[MPC library (PodLib)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md)** and **[PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol)** in your installed `@coti-io/coti-contracts` package. ### Example tutorial (simple PoD dApp) @@ -138,9 +138,9 @@ flowchart LR | Your situation | Start here | | --- | --- | -| Logic fits the primitive list and a small number of MPC steps | [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md), [TypeScript PoD SDK](typescript-pod-sdk.md), [PodLib](architecture-and-components.md) | +| Logic fits the primitive list and a small number of MPC steps | [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md), [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md), then [MPC library (PodLib) — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md) | | You want a business-oriented public-to-private migration | [Cookbook: private investor allocations with PoD](cookbook-private-investor-allocations.md), then [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) | -| Logic needs custom COTI processing, `gt*` handling, or richer state | [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md), [How a private request travels end to end](how-a-private-request-travels-end-to-end.md) | +| Logic needs custom COTI processing, `gt*` handling, or richer state | [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md), then [Writing privacy contracts on Ethereum — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) and [Request builder and remote calls — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md) | | Fees, async UX, and components | [How do PoA fees work?](how-poa-fees-work.md), [Async private operations](async-private-operations.md), [Architecture and main components](architecture-and-components.md) | Return to the [Privacy on Avalanche section index](README.md). diff --git a/privacy-on-avalanche/typescript-pod-sdk.md b/privacy-on-avalanche/typescript-pod-sdk.md index 1edc0d9..37769f9 100644 --- a/privacy-on-avalanche/typescript-pod-sdk.md +++ b/privacy-on-avalanche/typescript-pod-sdk.md @@ -83,3 +83,5 @@ const requestIds = receipt?.hash ? await pod.extractRequestIds(receipt.hash) : [ - [Tutorial: private Adder on Avalanche Fuji](tutorial-private-adder-fuji.md) — full walkthrough including `PodContract` and `extractRequestIds`. - [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) — custom COTI-side pattern. +- [TypeScript integration (SDK docs)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) +- [PoD SDK docs index](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) diff --git a/privacy-on-avalanche/what-is-privacy-on-avalanche.md b/privacy-on-avalanche/what-is-privacy-on-avalanche.md index b400575..d752cec 100644 --- a/privacy-on-avalanche/what-is-privacy-on-avalanche.md +++ b/privacy-on-avalanche/what-is-privacy-on-avalanche.md @@ -35,7 +35,7 @@ The **COTI PoD stack** provides the pattern: TypeScript helpers in [`@coti-io/po - **User experience** for onboarding, showing **pending / completed / failed** private operations, and **safe key handling**. - **Operations**: monitoring, indexing, or internal tools for stuck requests and AVAX fee configuration, as appropriate for your deployment. -Those packages do not replace your deployment scripts, indexers, or backend services. +The SDK’s own [documentation README](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/README.md) states scope clearly: it does not replace deployment scripts, indexers, or backend services for you. ## Next steps diff --git a/privacy-on-demand/README.md b/privacy-on-demand/README.md index 6f792a3..57c028c 100644 --- a/privacy-on-demand/README.md +++ b/privacy-on-demand/README.md @@ -17,8 +17,8 @@ Privacy on Demand lets applications use **strong privacy for data and computatio

Further resources

-- **[Examples](https://github.com/coti-io/coti-sdk-pod/tree/main/examples/private-adder-e2e)** — TypeScript e2e adder in [`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod). -- **[Solidity (`PodLib`, Inbox)](https://github.com/coti-io/coti-contracts/tree/main/contracts/pod)** — contracts in [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts). +- **[Examples](https://github.com/cotitech-io/coti-pod-sdk/tree/main/contracts/examples)** — Contract examples in the PoD SDK repo. +- **[PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs)** — Full SDK docs on GitHub. The same **Quick Access** and **Further resources** blocks appear on the [docs homepage](../README.md). @@ -26,7 +26,7 @@ The same **Quick Access** and **Further resources** blocks appear on the [docs h --- -This section explains **what PoD is**, **how it feels to users and operators**, and **how the main pieces fit together**. For integration, use [`@coti-io/pod-sdk`](https://www.npmjs.com/package/@coti-io/pod-sdk) (TypeScript) and [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts) (Solidity), plus the links below. +This section explains **what PoD is**, **how it feels to users and operators**, and **how the main pieces fit together**. For step-by-step integration with the **COTI PoD SDK**, use the [npm package](https://www.npmjs.com/package/@coti/pod-sdk), the [documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs), and the links below. ## Who this documentation is for @@ -50,7 +50,7 @@ This section explains **what PoD is**, **how it feels to users and operators**, 6. [Async private operations (why it is not instant)](async-private-operations.md) — What “pending” means and why UX must reflect it. 7. [How do PoA fees work?](how-poa-fees-work.md) — Two-way Inbox budgets, oracle conversion, and step-by-step gas-unit consumption (worked example). -8. [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) — Checklists and links to source files. +8. [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) — Checklists and links to the [PoD SDK documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). ### Tutorials (hands-on) @@ -62,7 +62,6 @@ This section explains **what PoD is**, **how it feels to users and operators**, ## Official technical reference -Machine-readable contracts, types, and APIs live in the open-source packages. This GitBook section is the human-oriented companion; pin package versions for signatures, fees, and network constants: +The machine-readable contracts, types, and APIs live in the open-source SDK. Treat this book chapter as the **human-oriented companion**; treat the repository as the **source of truth** for signatures, fees, and network constants: -- [`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod) — TypeScript -- [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts/tree/main/contracts/pod) — Solidity (`PodLib`, Inbox, examples) +- [COTI PoD SDK — documentation index](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) diff --git a/privacy-on-demand/architecture-and-components.md b/privacy-on-demand/architecture-and-components.md index 8714707..788dbf7 100644 --- a/privacy-on-demand/architecture-and-components.md +++ b/privacy-on-demand/architecture-and-components.md @@ -45,7 +45,7 @@ flowchart TB ### MPC executor (COTI) -- **What it is**: The **COTI-side contract address** your dApp is configured to call for a given deployment. The SDK’s network presets expose this as a constant you set during construction (for example `MPC_EXECUTOR_ADDRESS` alongside `COTI_CHAIN_ID` in [Getting started](tutorial-private-adder-sepolia.md)). +- **What it is**: The **COTI-side contract address** your dApp is configured to call for a given deployment. The SDK’s network presets expose this as a constant you set during construction (for example `MPC_EXECUTOR_ADDRESS` alongside `COTI_CHAIN_ID` in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md)). - **Why it matters**: It anchors **where** private execution is invoked in the COTI environment for **library-style** flows. ### PodUser @@ -55,8 +55,8 @@ flowchart TB ### PodLib -- **What it is**: **High-level helpers** for **common private operations** (comparisons and arithmetic at fixed bit widths). -- **Why it matters**: Faster path than writing a **custom** COTI contract for every operation. If you outgrow it, you move to **custom** encoding and COTI-side contracts using `MpcAbiCodec` ([Tutorial: custom privacy logic](tutorial-custom-logic.md)). +- **What it is**: **High-level helpers** for **common private operations** (for example comparisons and arithmetic at fixed bit widths—see the SDK [features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md) table). +- **Why it matters**: Faster path than writing a **custom** COTI contract for every operation. If you outgrow it, you move to **custom** encoding and COTI-side contracts using `MpcAbiCodec`, described in the SDK’s [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md). ## Data shapes: a non-developer mental model @@ -68,11 +68,13 @@ Engineers talk about **`it*`**, **`gt*`**, and **`ct*`**. At a high level: | **`gt*`** | **Private compute representation** during the operation | **Inside COTI** private execution | | **`ct*`** | **Encrypted output** you can **store on your chain** and **decrypt client-side** | **Returned** to your contract, **read** by the user’s app | +A fuller table lives in the SDK’s [data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md) page. + ## Trust and security highlights (for architects) -- **Callback authentication**: Your contract should only accept **Inbox-originated** callbacks for private results—otherwise anyone could try to spoof answers. The `onlyInbox` pattern on `InboxUser` exists for this boundary. +- **Callback authentication**: Your contract should only accept **Inbox-originated** callbacks for private results—otherwise anyone could try to spoof answers. The SDK’s `onlyInbox` pattern exists for this boundary ([features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md)). - **Request correlation**: Private work completes **later**; your system must track **request IDs** and statuses honestly in UX and backends ([Async private operations](async-private-operations.md)). -- **Key stewardship**: Client-side AES material is powerful; treat it like **credentials**, not analytics metadata ([TypeScript PoD SDK](typescript-pod-sdk.md)). +- **Key stewardship**: Client-side AES material is powerful; treat it like **credentials**, not analytics metadata ([TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md)). ## Next steps diff --git a/privacy-on-demand/async-private-operations.md b/privacy-on-demand/async-private-operations.md index c4a1196..1a7e05b 100644 --- a/privacy-on-demand/async-private-operations.md +++ b/privacy-on-demand/async-private-operations.md @@ -18,7 +18,7 @@ So the user’s mental model should be closer to **“I submitted a job”** tha Private execution happens **outside** your chain’s normal synchronous EVM frame. The **Inbox** pattern exists precisely to **carry a message out** and **bring a response back** through a **controlled channel**. -Common mistakes: wrong callback decode shape, missing `onlyInbox`, and expecting the private result in the same block as the request. +The SDK’s [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) page lists the canonical lifecycle and common mistakes (wrong decode shape, missing `onlyInbox`, expecting same-block completion). ## What product and support teams should plan for diff --git a/privacy-on-demand/cookbook-private-investor-allocations.md b/privacy-on-demand/cookbook-private-investor-allocations.md index 301afcc..91b774e 100644 --- a/privacy-on-demand/cookbook-private-investor-allocations.md +++ b/privacy-on-demand/cookbook-private-investor-allocations.md @@ -40,7 +40,7 @@ The public version is useful because it gives you a known baseline: owner assign - A Solidity toolchain such as Hardhat or Foundry. - A Sepolia wallet with test ETH for deploys, transactions, and PoD request fees. - Node.js 18+ for scripts. -- The PoD SDK package: `npm install "@coti-io/pod-sdk"`. +- The PoD SDK package: `npm install "@coti/pod-sdk"`. - A way for users to complete PoD onboarding and obtain their account AES key for local decryption. Before implementing the private version, read: @@ -373,7 +373,7 @@ import { PodContract, type PodFeeEstimationConfig, type PodMethodArgument, -} from "@coti-io/pod-sdk"; +} from "@coti/pod-sdk"; const args: PodMethodArgument[] = [ { type: DataType.Address, value: investorAddress, isCallBackFee: false }, @@ -400,7 +400,7 @@ Tune `forwardGasLimit`, `callBackGasLimit`, and `callBackDataSize` from real mea The project owner encrypts allocation amounts before submitting them to the private flow. ```typescript -import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; const encryptedAllocation = await CotiPodCrypto.encrypt( ethers.parseUnits("1000", 18).toString(), @@ -583,4 +583,4 @@ Before adapting this cookbook for a real launch, add: - [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) - [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) - [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) -- [For developers: mapping concepts to the SDK](for-developers-mapping-to-the-sdk.md) +- [PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) diff --git a/privacy-on-demand/for-developers-mapping-to-the-sdk.md b/privacy-on-demand/for-developers-mapping-to-the-sdk.md index 64c9895..96750f6 100644 --- a/privacy-on-demand/for-developers-mapping-to-the-sdk.md +++ b/privacy-on-demand/for-developers-mapping-to-the-sdk.md @@ -1,58 +1,57 @@ # For developers: mapping concepts to the SDK -This page maps [Architecture and main components](architecture-and-components.md) to the packages you install: +This page is the **bridge** from [Architecture and main components](architecture-and-components.md) to the canonical [PoD SDK documentation on GitHub](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). It repeats a few facts on purpose so engineers can verify mental models quickly. -- TypeScript: [`@coti-io/pod-sdk`](https://www.npmjs.com/package/@coti-io/pod-sdk) ([GitHub](https://github.com/coti-io/coti-sdk-pod)) -- Solidity: [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts) (`contracts/pod/`) +For a guided first implementation, read **[Tutorials: building Privacy on Demand (PoD) dApps](tutorials-privacy-on-demand.md)** to pick the integration model, then follow [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) for a **primitive-only** Solidity + TypeScript walkthrough (Sepolia presets). -For a guided first implementation, read **[Tutorials: building Privacy on Demand (PoD) dApps](tutorials-privacy-on-demand.md)**, then [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md). +## Official reading order (SDK) -## Reading order +The upstream docs recommend: -1. [What is Privacy on Demand?](what-is-privacy-on-demand.md) -2. [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) -3. [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) -4. [TypeScript PoD SDK](typescript-pod-sdk.md) +1. [Privacy dApps on any EVM chain with COTI PoD](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/01-privacy-decentralized-apps-on-any-evm-chain-with-coti-pod.md) +2. [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) +3. [Writing privacy contracts on Ethereum](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) +4. [TypeScript integration (UX development)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) -Then: +Then deep dives: -- [Async private operations](async-private-operations.md) -- [Architecture and main components](architecture-and-components.md) (PodLib, types) -- [Tutorials index](tutorials-privacy-on-demand.md) -- [How a private request travels end to end](how-a-private-request-travels-end-to-end.md) -- [How do PoA fees work?](how-poa-fees-work.md) +- [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md) +- [MPC library (PodLib)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md) +- [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) +- Contract references: [Data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md), [Patterns and checklist](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/02-contract-patterns-and-checklist.md), [Request builder and remote calls](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md), [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) ## Component → source file map -| Concept (this book) | Where it lives | +| Concept (this book) | Where it lives in the SDK docs / repo | | --- | --- | -| **Inbox** | [IInbox.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/IInbox.sol) | -| **Callback guard** | [InboxUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/InboxUser.sol) (`onlyInbox`) | -| **PodLib** | [PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol) and width-specific libraries (`PodLib64`, `PodLib128`, `PodLib256`) | -| **PodUser / presets** | [PodUser.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUser.sol), [PodUserSepolia.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodUserSepolia.sol) | -| **Types (`it*`, `ct*`, `gt*`)** | [MpcCore.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/utils/mpc/MpcCore.sol) — see also [data shapes](architecture-and-components.md) | -| **Custom COTI calls** | [MpcAbiCodec.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpccodec/MpcAbiCodec.sol) and [custom tutorial](tutorial-custom-logic.md) | -| **Client crypto** | [coti-pod-crypto.ts](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) (`CotiPodCrypto`) | +| **Inbox** | [IInbox.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/IInbox.sol) and cross-domain flow in the [domain model](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/01-privacy-decentralized-apps-on-any-evm-chain-with-coti-pod.md) diagram. | +| **Callback guard** | [InboxUser.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/InboxUser.sol) (`onlyInbox`) — see [Features](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/03-features.md). | +| **PodLib** | [PodLib.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpc/PodLib.sol) and width-specific libraries (`PodLib64`, `PodLib128`, `PodLib256`). | +| **PodUser / presets** | [PodUser.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpc/PodUser.sol), network mixins such as [PodUserSepolia.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpc/PodUserSepolia.sol) in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md). | +| **Types (`it*`, `ct*`, `gt*`)** | [MpcCore.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/utils/mpc/MpcCore.sol) and [Data types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md). | +| **Custom COTI calls** | [MpcAbiCodec.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpccodec/MpcAbiCodec.sol) and the **custom mode** section of [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md). | +| **Client crypto** | [coti-pod-crypto.ts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts) via `CotiPodCrypto` ([TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md)). | -## Implementation checklist +## Implementation checklist (condensed) + +Derived from the SDK’s [Writing privacy contracts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) and [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md): 1. **Classify data** — public metadata vs `it*` inputs vs `ct*` outputs vs internal `gt*` (COTI-only). 2. **Pick integration mode** — `PodLib` helpers vs custom `MpcAbiCodec` + COTI contract. 3. **Model async state** — persist `requestId`, track pending/completed/failed. 4. **Harden callbacks** — `onlyInbox`, correct `abi.decode` tuple, validate peer context when applicable. 5. **Configure routing safely** — gated `configure` / `configureCoti` / inbox updates. -6. **Budget fees** — `msg.value` and `callbackFeeLocalWei`; Inbox fee views ([How do PoA fees work?](how-poa-fees-work.md)). -7. **Test failure paths** — spoofed callback must revert, error callbacks must mark failures, decrypt widths must match. +6. **Budget fees** — understand `msg.value` and `callbackFeeLocalWei`; use Inbox fee views where available ([Fees doc](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md)). +7. **Test failure paths** — spoofed callback must revert, error callbacks must mark failures, decrypt integration must match widths. ## Relationship to native COTI “build” documentation -If you build **directly on COTI V2** with precompiles and private types, start from **[Build on COTI](../build-on-coti/README.md)**. PoD adds the Inbox-mediated cross-chain path; cryptographic types rhyme, but deployment and UX differ. +If you build **directly on COTI V2** with precompiles and private types, start from **[Build on COTI](../build-on-coti/README.md)**. PoD adds the **Inbox-mediated cross-chain** angle; many **cryptographic ideas rhyme**, but **deployment and UX** differ. ## Package install ```bash -npm install @coti-io/pod-sdk ethers -npm install github:coti-io/coti-contracts#main +npm install "@coti/pod-sdk" ``` -Solidity imports use `@coti-io/coti-contracts/contracts/pod/mpc/...`. The npm TypeScript package does not ship contract sources. +See [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) for Solidity imports and the `contract MyApp is PodLib, PodUserSepolia` pattern. diff --git a/privacy-on-demand/glossary.md b/privacy-on-demand/glossary.md index fb965b4..cbf6577 100644 --- a/privacy-on-demand/glossary.md +++ b/privacy-on-demand/glossary.md @@ -1,6 +1,6 @@ # Glossary -Short definitions for **Privacy on Demand** readers. Type roles (`it*`, `gt*`, `ct*`) are summarized in [Architecture and main components](architecture-and-components.md). Solidity structs live in [MpcCore.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/utils/mpc/MpcCore.sol). +Short definitions for **Privacy on Demand** readers. Precise Solidity definitions and type tables are in the [PoD SDK contract types](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/01-it-ct-gt-data-types.md) document. | Term | Meaning | | --- | --- | diff --git a/privacy-on-demand/how-a-private-request-travels-end-to-end.md b/privacy-on-demand/how-a-private-request-travels-end-to-end.md index e122f62..5008a90 100644 --- a/privacy-on-demand/how-a-private-request-travels-end-to-end.md +++ b/privacy-on-demand/how-a-private-request-travels-end-to-end.md @@ -1,6 +1,6 @@ # How a private request travels end to end -This page describes **one full cycle** of Privacy on Demand **without assuming Solidity knowledge**. Names match [Architecture and main components](architecture-and-components.md). +This page describes **one full cycle** of Privacy on Demand **without assuming Solidity knowledge**. Names match what you will see in the [PoD SDK documentation](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs). ## Cast of roles @@ -12,7 +12,7 @@ This page describes **one full cycle** of Privacy on Demand **without assuming S | **Inbox (EVM)** | On-chain **messaging hub** on **your chain** that **forwards** jobs to the **Inbox (COTI)** and **calls back** into your contract when the answer is ready. | | **Inbox (COTI)** | The **COTI-side Inbox contract**—the **counterpart** to the host Inbox. It receives cross-domain messages and routes work to the MPC Executor. | | **COTI private execution** | The environment that performs **private computation** on **compute-domain values** (`gt*` in developer docs). | -| **MPC Executor** | The **COTI-side contract** your integration targets for a given network (see SDK presets such as `PodUserSepolia` in [Getting started](tutorial-private-adder-sepolia.md)). The **Inbox (COTI)** invokes it; it is **not** the same contract as either Inbox. | +| **MPC Executor** | The **COTI-side contract** your integration targets for a given network (see SDK presets such as `PodUserSepolia` in [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md)). The **Inbox (COTI)** invokes it; it is **not** the same contract as either Inbox. | ## The journey in seven steps @@ -79,7 +79,7 @@ sequenceDiagram ## Fees and gas -Private jobs that cross from your chain to COTI and back incur **network and execution costs**. Integrations typically attach **native token value** on the request and split it between **remote execution** and the **callback** leg. Operators configure **fee parameters** and **oracle** behavior on supporting contracts (see [How do PoA fees work?](how-poa-fees-work.md)). +Private jobs that cross from your chain to COTI and back incur **network and execution costs**. Integrations typically attach **native token value** on the request and split it between **remote execution** and the **callback** leg. Operators configure **fee parameters** and **oracle** behavior on supporting contracts (see the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) page). ## Next steps diff --git a/privacy-on-demand/how-poa-fees-work.md b/privacy-on-demand/how-poa-fees-work.md index 0851c3d..9a0f9b9 100644 --- a/privacy-on-demand/how-poa-fees-work.md +++ b/privacy-on-demand/how-poa-fees-work.md @@ -4,7 +4,7 @@ This page explains how that payment is **split**, converted (via **oracles**) into **execution budgets** on each side—often described as **gas units**—and **consumed** step by step. -The numbers below are a **single worked example** so you can follow the arithmetic. Live networks use **oracle and Inbox policy** to set conversion rates and minimums; use your deployment’s **views** (for example `calculateTwoWayFeeRequiredInLocalToken`) for production. +The numbers below are a **single worked example** so you can follow the arithmetic. Live networks use **oracle and Inbox policy** to set conversion rates and minimums; use your deployment’s **views** (for example `calculateTwoWayFeeRequiredInLocalToken`) and the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) reference for production. ## Example call @@ -38,7 +38,7 @@ Solidity shape (conceptually): ## Walkthrough -Read the **first table top to bottom:** user ETH is split by leg, oracles supply **COTI** and **ETH** prices, the COTI leg is expressed as **quote → COTI tokens**, then policy turns each leg into **gas-unit budgets**. The **second table** spends **COTI** first, then **Sepolia** after the result exists. Underspend remains are illustrative; production behavior depends on **InboxMiner** / **InboxFeeManager** and operator policy. +Read the **first table top to bottom:** user ETH is split by leg, oracles supply **COTI** and **ETH** prices, the COTI leg is expressed as **quote → COTI tokens**, then policy turns each leg into **gas-unit budgets**. The **second table** spends **COTI** first, then **Sepolia** after the result exists. Underspend remains are illustrative; production behavior depends on **InboxMiner** / **InboxFeeManager** and operator policy (see the SDK [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) doc). ## Why this matters for `add(a, b) → ctUint64 c` @@ -49,7 +49,7 @@ Read the **first table top to bottom:** user ETH is split by leg, oracles supply ## Where to implement this in code - Solidity: payable **`add`** with **`msg.value`** and **`callbackFeeLocalWei`**, as in [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) (see [Tutorials overview](tutorials-privacy-on-demand.md) for how this fits the **primitive-only** model). -- Estimation: Inbox **`calculateTwoWayFeeRequiredInLocalToken`**. +- Estimation: Inbox **`calculateTwoWayFeeRequiredInLocalToken`** and the [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) document in the PoD SDK repo. ## Disclaimer diff --git a/privacy-on-demand/networks/README.md b/privacy-on-demand/networks/README.md index 4646a0f..763a20d 100644 --- a/privacy-on-demand/networks/README.md +++ b/privacy-on-demand/networks/README.md @@ -5,7 +5,7 @@ Privacy on Demand spans **two domains**: 1. **Host chain** — where your dApp contracts, assets, and the local **Inbox** live (for example Avalanche Fuji). 2. **COTI** — where private computation runs via the **MPC executor** and the COTI-side **Inbox**. -The pages below list network parameters and deployed contract addresses for current test environments. Addresses can change after redeploys; treat [`@coti-io/pod-sdk`](https://github.com/coti-io/coti-sdk-pod), [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts), and your environment config as the live source of truth when building against a specific release. +The pages below list network parameters and deployed contract addresses for current test environments. Addresses can change after redeploys; treat the [PoD SDK](https://github.com/cotitech-io/coti-pod-sdk) and your environment config as the live source of truth when building against a specific release. | Network | Chain ID | Role in PoD | | --- | --- | --- | diff --git a/privacy-on-demand/tutorial-custom-logic.md b/privacy-on-demand/tutorial-custom-logic.md index 8178bf5..15fd783 100644 --- a/privacy-on-demand/tutorial-custom-logic.md +++ b/privacy-on-demand/tutorial-custom-logic.md @@ -58,10 +58,10 @@ Paths like `../InboxUser.sol` assume you follow the SDK’s example layout; adju The Sepolia contract **inherits `PodUserSepolia`** (or your network’s `PodUser` preset), tracks the **COTI peer address**, and: -1. **`sendMessage`** — Wraps encrypted input (`itString`) and public addresses in an **`IInbox.MpcMethodCall`** built with **`MpcAbiCodec`** (see [How a private request travels end to end](how-a-private-request-travels-end-to-end.md)). It sends a **two-way** message so the result comes back asynchronously. +1. **`sendMessage`** — Wraps encrypted input (`itString`) and public addresses in an **`IInbox.MpcMethodCall`** built with **`MpcAbiCodec`** (see the SDK’s [Request builder and remote calls](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md)). It sends a **two-way** message so the result comes back asynchronously. 2. **`onMessageReceived`** — Decodes the tuple produced on COTI, **re-checks `inboxMsgSender()`**, and stores **`ctString`** keyed by conversation participants (or whatever your product needs). -The Solidity below is **structurally** correct; wire **`MpcAbiCodec`**’s `create` / `addArgument` / `build` steps exactly as in your installed `@coti-io/pod-sdk` version (argument order and `gt`/`it` interface types **must** match the COTI method signature). +The Solidity below is **structurally** correct; wire **`MpcAbiCodec`**’s `create` / `addArgument` / `build` steps exactly as in your installed `@coti/pod-sdk` version (argument order and `gt`/`it` interface types **must** match the COTI method signature). ```solidity // SPDX-License-Identifier: MIT @@ -134,9 +134,9 @@ contract DirectMessageEvm is PodUserSepolia { This chapter stops at **Solidity** to highlight the **chain split**. For **encryption**, **Inbox fee estimation**, and **client-side decryption** of `ctString`, continue with: - [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) — includes **`PodContract`**, **`encryptAndCallMethod`**, **`estimateFee`**, and **`extractRequestIds`** so you can copy the same client pattern to **`sendMessage`** (build **`PodMethodArgument[]`** with types that match your ABI: **`itString`** for the ciphertext argument, plain types for addresses and the callback-fee slot, **`isCallBackFee: true`** on the fee parameter). -- [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) — short reference for **`CotiPodCrypto`** and **`PodContract`** with links to [`coti-pod-crypto.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts). -- [TypeScript PoD SDK](typescript-pod-sdk.md) -- [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) — custom COTI-side pattern. +- [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md) — short reference for **`CotiPodCrypto`** and **`PodContract`** with links to [`coti-pod-crypto.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/pod-method-call.ts). +- [TypeScript integration — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) +- [Writing privacy contracts on Ethereum — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) (custom mode) After **`encryptAndCallMethod("sendMessage", args, feeCfg)`** (or a raw **`ethers.Contract`** send), use **`await pod.extractRequestIds(receipt.hash)`** on the same **`PodContract`** instance so your UI stores the **`requestId`** emitted in the Inbox **`MessageSent`** logs—same helper as in the adder walkthrough. diff --git a/privacy-on-demand/tutorial-private-adder-sepolia.md b/privacy-on-demand/tutorial-private-adder-sepolia.md index 45c60ec..04bb85b 100644 --- a/privacy-on-demand/tutorial-private-adder-sepolia.md +++ b/privacy-on-demand/tutorial-private-adder-sepolia.md @@ -2,9 +2,9 @@ This walkthrough is the **primitive-only** path: your host-chain contract calls **`PodLib`** helpers (the SDK surface for **MpcLib**-style primitives) and never deploys custom Solidity on COTI. If you are unsure whether that is enough for your product, read **[Tutorials: building Privacy on Demand (PoD) dApps](tutorials-privacy-on-demand.md)** first. -This guide shows how to build a minimal **Privacy on Demand** dApp that **adds two encrypted integers** on COTI and stores the **encrypted sum** on your EVM contract. It follows the same ideas as the SDK’s [MpcAdder.sol](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) example, extended with **Sepolia routing presets** and **request correlation** suitable for a real UI. +This guide shows how to build a minimal **Privacy on Demand** dApp that **adds two encrypted integers** on COTI and stores the **encrypted sum** on your EVM contract. It follows the same ideas as the SDK’s [MpcAdder.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/examples/MpcAdder.sol) example, extended with **Sepolia routing presets** and **request correlation** suitable for a real UI. -For background on async flows and fees, see [Async private operations](async-private-operations.md) and [How do PoA fees work?](how-poa-fees-work.md). +For background on async flows and fees, see [Async private operations](async-private-operations.md), [How do PoA fees work?](how-poa-fees-work.md), and the SDK’s [Fees, gas, and oracle](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/04-fees-gas-and-oracle.md) page. ## Writing a PoD example @@ -15,44 +15,38 @@ In this example we will do the following: 3. **Implement a success callback** that decodes `abi.encode(ctUint256)` and stores the ciphertext. 4. **Wire `onDefaultMpcError.selector`** so failed remote runs surface through the SDK’s default error path (and emit `ErrorRemoteCall` from `PodUser`). -After that works, you harden for production: per-user request ownership, explicit `pending / completed / failed` state, fee estimation via the Inbox, and tests for under-funded sends. The [tutorials index](tutorials-privacy-on-demand.md) lists what a minimal adder omits on purpose. +After that works, you harden for production: per-user request ownership, explicit `pending / completed / failed` state, fee estimation via the Inbox, and tests for under-funded sends. The SDK’s [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) lists what the shipped `MpcAdder` omits on purpose. ## Prerequisites - **Solidity toolchain** (Foundry or Hardhat) targeting **Ethereum Sepolia** (where the SDK’s `PodUserSepolia` Inbox is deployed). - **Node.js 18+** for scripts and `fetch` used by encryption helpers. - **Sepolia ETH** for deployment and for **`msg.value`** on each `add` call (plus gas). -- **User onboarding** so your client can obtain an **account AES key** for decryption (see the SDK’s [TypeScript integration](typescript-pod-sdk.md) and [Onboarding / account AES key](../how-coti-works/advanced-topics/aes-keys.md) docs). +- **User onboarding** so your client can obtain an **account AES key** for decryption (see the SDK’s [TypeScript integration](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) and [Onboarding / account AES key](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06c-onboarding-account-account-aes-key.md) docs). -Always confirm **Inbox**, **COTI chain id**, and **MPC executor** against `PodUserSepolia.sol` / `PodNetworkConstants.sol` in your installed `@coti-io/coti-contracts` package; constants can change between releases. +Always confirm **Inbox**, **COTI chain id**, and **MPC executor** against the version of `PodUserSepolia.sol` in your installed `@coti/pod-sdk` package; constants can change between releases. -## Step 1: Install packages +## Step 1: Install the SDK ```bash -# TypeScript helpers (encrypt / fees / send) -npm install @coti-io/pod-sdk ethers - -# Solidity (PodLib, PodUserSepolia, MpcCore) — currently install from GitHub main -npm install github:coti-io/coti-contracts#main +npm install "@coti/pod-sdk" ``` -`@coti-io/pod-sdk` is **TypeScript only**. Solidity imports come from `@coti-io/coti-contracts`. - ## Step 2: Create the `PrivateAdder` contract Save as `PrivateAdder.sol`. The contract: - Inherits **`PodLib`** and **`PodUserSepolia`** (Sepolia defaults for Inbox and COTI routing). - Calls **`add256`** with the caller’s encrypted inputs and your callback selector. -- Resolves **`requestId`** in the callback the same way as the [PrivateAdder](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) example. +- Resolves **`requestId`** in the callback the same way as the SDK’s [Getting started](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) example. ```solidity // SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.26; -import "@coti-io/coti-contracts/contracts/pod/mpc/PodLib.sol"; -import "@coti-io/coti-contracts/contracts/pod/mpc/PodUserSepolia.sol"; -import "@coti-io/coti-contracts/contracts/utils/mpc/MpcCore.sol"; +import "@coti/pod-sdk/contracts/mpc/PodLib.sol"; +import "@coti/pod-sdk/contracts/mpc/PodUserSepolia.sol"; +import "@coti/pod-sdk/contracts/utils/mpc/MpcCore.sol"; /// @title PrivateAdder /// @notice Adds two encrypted uint64 values via PoD on Sepolia (SDK preset addresses). @@ -114,7 +108,7 @@ contract PrivateAdder is PodLib, PodUserSepolia { ## Step 3: Compile and deploy on Sepolia -Configure remappings so `@coti-io/pod-sdk` resolves (Hardhat `paths`, Foundry `remappings.txt`, etc.), then compile and deploy `PrivateAdder` to **Ethereum Sepolia**. Record the deployed address for scripts. +Configure remappings so `@coti/pod-sdk` resolves (Hardhat `paths`, Foundry `remappings.txt`, etc.), then compile and deploy `PrivateAdder` to **Ethereum Sepolia**. Record the deployed address for scripts. ## Step 4: Budget `msg.value` and `callbackFeeLocalWei` @@ -122,12 +116,12 @@ Two-way Inbox traffic needs enough native token to cover **outbound execution** ## Step 5: Encrypt the two summands (TypeScript) -`CotiPodCrypto.encrypt` calls the PoD encryption service. For Sepolia-style test usage, pass **`"testnet"`** as the network key (see [`coti-pod-crypto.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) in the SDK: `testnet` maps to the COTI testnet encryption endpoint). +`CotiPodCrypto.encrypt` calls the PoD encryption service. For Sepolia-style test usage, pass **`"testnet"`** as the network key (see [`coti-pod-crypto.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts) in the SDK: `testnet` maps to the COTI testnet encryption endpoint). Use **`DataType.itUint256`** when you build **`itUint256`** calldata yourself (for example with **`ethers.Contract`**). If you use **`PodContract.encryptAndCallMethod`** in the next step, you can skip manual encryption: pass **plaintext numeric strings** and **`DataType.itUint256`** in each `PodMethodArgument`, and the SDK encrypts before encoding the transaction. ```typescript -import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; const plainA = "10"; const plainB = "20"; @@ -139,7 +133,7 @@ const encB = await CotiPodCrypto.encrypt(plainB, "testnet", DataType.itUint256); ## Step 6: Submit the `add` transaction (`PodContract`, fees, `extractRequestIds`) -[`PodContract`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts) wraps your **`ethers.Contract`**: it **`estimateFee`**s against the Inbox, maps **`PodMethodArgument`** values (including **`encryptAndCallMethod`** encryption for **`it*`** types), injects the **`callBackFee`** into the slot marked **`isCallBackFee: true`**, sends **`value: totalFee`** on payable functions, and exposes **`extractRequestIds(txHash)`** to read **`requestId`** values from **`MessageSent`** logs on the Inbox (reliable across layouts where parsing logs from the app contract alone is brittle). +[`PodContract`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/pod-method-call.ts) wraps your **`ethers.Contract`**: it **`estimateFee`**s against the Inbox, maps **`PodMethodArgument`** values (including **`encryptAndCallMethod`** encryption for **`it*`** types), injects the **`callBackFee`** into the slot marked **`isCallBackFee: true`**, sends **`value: totalFee`** on payable functions, and exposes **`extractRequestIds(txHash)`** to read **`requestId`** values from **`MessageSent`** logs on the Inbox (reliable across layouts where parsing logs from the app contract alone is brittle). ```typescript import { @@ -147,7 +141,7 @@ import { DataType, type PodFeeEstimationConfig, type PodMethodArgument, -} from "@coti-io/pod-sdk"; +} from "@coti/pod-sdk"; import { ethers } from "ethers"; // Minimal ABI fragment — prefer the full artifact from your build (Hardhat / Foundry). @@ -215,7 +209,7 @@ Private addition is **asynchronous**: the sum appears only after the Inbox invok After status is **Completed**, read **`sumByRequest(requestId)`**. The value is **`ctUint256`** (ciphertext), not plaintext. ```typescript -import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; // accountAesKey: hex string from your app’s COTI onboarding flow (never log it) @@ -235,20 +229,21 @@ console.log("sum (plaintext string):", decryptedString); // Expect "30" for plainA=10 and plainB=20 ``` -`CotiPodCrypto.decrypt` delegates to `@coti-io/coti-sdk-typescript` and expects a **scalar ciphertext** as a **hex string** for `Uint64`, plus the user’s **AES key** (see SDK source [coti-pod-crypto.ts](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts)). +`CotiPodCrypto.decrypt` delegates to `@coti-io/coti-sdk-typescript` and expects a **scalar ciphertext** as a **hex string** for `Uint64`, plus the user’s **AES key** (see SDK source [coti-pod-crypto.ts](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts)). ## Step 8: Sanity checks and next steps - **Callback decode** must stay **`(ctUint256)`** — changing the executor op or COTI-side behavior without updating the decode tuple will corrupt storage reads. - **Type lane** — This contract uses **`add256`** with **`itUint256`** / **`ctUint256`** on chain. **`CotiPodCrypto.decrypt`** still takes a **`DataType`** for the scalar decode; keep **`DataType.Uint64`** (or **`Uint256`**, etc.) aligned with how your app and onboarding produce the ciphertext for this flow, per your installed SDK. -- **Production**: add tests for non-Inbox callers on `addCallback`, under-funded `msg.value`, and decrypt failures; follow the [first production checklist](tutorial-private-adder-sepolia.md) in Getting started. +- **Production**: add tests for non-Inbox callers on `addCallback`, under-funded `msg.value`, and decrypt failures; follow the [first production checklist](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) in Getting started. ## Reference links -- [`pod-method-call.ts` (`PodContract`, fees, `extractRequestIds`)](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts) -- [PrivateAdder.sol (repo example)](https://github.com/coti-io/coti-sdk-pod/blob/main/examples/private-adder-e2e/contracts/PrivateAdder.sol) -- [Tutorials index](tutorials-privacy-on-demand.md) -- [Async private operations](async-private-operations.md) +- [`pod-method-call.ts` (`PodContract`, fees, `extractRequestIds`)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/pod-method-call.ts) +- [MpcAdder.sol (minimal repo example)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/examples/MpcAdder.sol) +- [Examples with description](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05c-examples-with-description.md) +- [Getting started (PodUserSepolia pattern)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/04-getting-started.md) +- [Async execution](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05a-async-execution.md)
diff --git a/privacy-on-demand/tutorials-privacy-on-demand.md b/privacy-on-demand/tutorials-privacy-on-demand.md index 002ac9d..e19f720 100644 --- a/privacy-on-demand/tutorials-privacy-on-demand.md +++ b/privacy-on-demand/tutorials-privacy-on-demand.md @@ -26,7 +26,7 @@ For **64-, 128-, and 256-bit** lanes, the library surface includes (names may be **Randomness:** `randBoundedBits` -For the authoritative list, signatures, and gas notes, use **[PodLib.sol](https://github.com/coti-io/coti-contracts/blob/main/contracts/pod/mpc/PodLib.sol)** in your installed `@coti-io/coti-contracts` package. +For the authoritative list, signatures, and gas notes, use the SDK’s **[MPC library (PodLib)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md)** and **[PodLib.sol](https://github.com/cotitech-io/coti-pod-sdk/blob/main/contracts/mpc/PodLib.sol)** in your installed `@coti/pod-sdk` version. ### Example tutorial (simple PoD dApp) @@ -138,9 +138,9 @@ flowchart LR | Your situation | Start here | | --- | --- | -| Logic fits the primitive list and a small number of MPC steps | [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md), [TypeScript PoD SDK](typescript-pod-sdk.md), [PodLib](architecture-and-components.md) | +| Logic fits the primitive list and a small number of MPC steps | [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md), [TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`)](typescript-pod-sdk.md), then [MPC library (PodLib) — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05b-multi-party-computing-library-mpclib.md) | | You want a business-oriented public-to-private migration | [Cookbook: private investor allocations with PoD](cookbook-private-investor-allocations.md), then [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) | -| Logic needs custom COTI processing, `gt*` handling, or richer state | [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md), [How a private request travels end to end](how-a-private-request-travels-end-to-end.md) | +| Logic needs custom COTI processing, `gt*` handling, or richer state | [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md), then [Writing privacy contracts on Ethereum — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/05-writing-privacy-contracts-on-ethereum.md) and [Request builder and remote calls — SDK](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/contracts/03-request-builder-and-remote-calls.md) | | Fees, async UX, and components | [How do PoA fees work?](how-poa-fees-work.md), [Async private operations](async-private-operations.md), [Architecture and main components](architecture-and-components.md) | Return to the [Privacy on Demand section index](README.md). diff --git a/privacy-on-demand/typescript-pod-sdk.md b/privacy-on-demand/typescript-pod-sdk.md index ce747a0..5a2f4af 100644 --- a/privacy-on-demand/typescript-pod-sdk.md +++ b/privacy-on-demand/typescript-pod-sdk.md @@ -1,6 +1,6 @@ # TypeScript PoD SDK (`CotiPodCrypto`, `PodContract`) -The npm package **`@coti-io/pod-sdk`** ships TypeScript helpers for **encrypting and decrypting** PoD payloads and for **encoding, fee estimation, and sending** calls against your host-chain contract through [`coti-pod-crypto.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/coti-io/coti-sdk-pod/blob/main/src/pod-method-call.ts). Solidity (`PodLib`, `PodUserSepolia`) lives in **`@coti-io/coti-contracts`**, not in this package. +The npm package **`@coti/pod-sdk`** ships TypeScript helpers for **encrypting and decrypting** PoD payloads and for **encoding, fee estimation, and sending** calls against your host-chain contract through [`coti-pod-crypto.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/coti-pod-crypto.ts) and [`pod-method-call.ts`](https://github.com/cotitech-io/coti-pod-sdk/blob/main/src/pod-method-call.ts). Use these helpers from a wallet script, backend service, or dApp frontend once you have a **`Signer`** (or **`Provider`** for read-only helpers) and your contract **ABI**. @@ -15,7 +15,7 @@ Use these helpers from a wallet script, backend service, or dApp frontend once y `CotiPodCrypto.decrypt` uses the user's **account AES key** and `@coti-io/coti-sdk-typescript` under the hood. ```typescript -import { CotiPodCrypto, DataType } from "@coti-io/pod-sdk"; +import { CotiPodCrypto, DataType } from "@coti/pod-sdk"; // Encrypt plaintext for Solidity itUint256 parameters const enc = await CotiPodCrypto.encrypt("42", "testnet", DataType.itUint256); @@ -39,7 +39,7 @@ import { DataType, type PodFeeEstimationConfig, type PodMethodArgument, -} from "@coti-io/pod-sdk"; +} from "@coti/pod-sdk"; import { ethers } from "ethers"; const pod = new PodContract(contractAddress, abi, signer, { @@ -83,3 +83,5 @@ const requestIds = receipt?.hash ? await pod.extractRequestIds(receipt.hash) : [ - [Tutorial: private Adder on Sepolia](tutorial-private-adder-sepolia.md) — full walkthrough including `PodContract` and `extractRequestIds`. - [Tutorial: custom privacy logic with PoD](tutorial-custom-logic.md) — custom COTI-side pattern. +- [TypeScript integration (SDK docs)](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/06-typescript-integration-ux-development.md) +- [PoD SDK docs index](https://github.com/cotitech-io/coti-pod-sdk/tree/main/docs) diff --git a/privacy-on-demand/what-is-privacy-on-demand.md b/privacy-on-demand/what-is-privacy-on-demand.md index 0204c72..dc230ac 100644 --- a/privacy-on-demand/what-is-privacy-on-demand.md +++ b/privacy-on-demand/what-is-privacy-on-demand.md @@ -29,13 +29,13 @@ What PoD does **not** automatically guarantee by itself: ## What ships in the SDK versus what your team builds -The **COTI PoD stack** provides the pattern: TypeScript helpers in [`@coti-io/pod-sdk`](https://www.npmjs.com/package/@coti-io/pod-sdk) ([GitHub](https://github.com/coti-io/coti-sdk-pod)), and Solidity (`PodLib`, **`PodUserSepolia`**, …) in [`@coti-io/coti-contracts`](https://github.com/coti-io/coti-contracts). Your project still typically supplies: +The **COTI PoD SDK** ([GitHub](https://github.com/cotitech-io/coti-pod-sdk), [npm](https://www.npmjs.com/package/@coti/pod-sdk)) provides **contracts and TypeScript helpers** for the PoD pattern. Your project still typically supplies: - **Application-specific** EVM contracts and state machines. - **User experience** for onboarding, showing **pending / completed / failed** private operations, and **safe key handling**. - **Operations**: monitoring, indexing, or internal tools for stuck requests and fee configuration, as appropriate for your deployment. -Those packages do not replace your deployment scripts, indexers, or backend services. +The SDK’s own [documentation README](https://github.com/cotitech-io/coti-pod-sdk/blob/main/docs/README.md) states scope clearly: it does not replace deployment scripts, indexers, or backend services for you. ## Next steps