Add local instaswap E2E workspace harness

This commit is contained in:
Daniel Taghavi
2026-04-03 17:17:40 -04:00
commit 16d5eb3a86
17 changed files with 2625 additions and 0 deletions

View File

@@ -0,0 +1,53 @@
# OPP Assertion Registry
This file is the numeric assertion registry for the shared OPP protobuf schema in `protocol/opp/v1/opp.proto`.
## Rules
- Numeric assertion IDs remain stable once assigned.
- Direction is part of the assignment. The same business meaning in opposite directions gets a different numeric ID.
- Payload bytes are protobuf messages from `wire.opp.v1`.
- Request/response flows correlate through `request_id`, not through shared batch numbers.
## Assigned Ranges
| Range | Route | Notes |
| --- | --- | --- |
| `2000-2099` | `Ethereum -> Wire` BAR | Existing Ethereum BAR assertions |
| `3000-3099` | `Ethereum -> Wire` Depositor/Pretoken | Existing Ethereum depositor and pretoken assertions |
| `4000-4199` | `Solana -> Wire` | Solana facts and requests |
| `5000-5199` | `Wire -> Solana` | Wire settlement and admin commands |
| `6000-6199` | `Wire -> Ethereum` | Wire settlement and admin commands |
## Active Assignments
| ID | Route | Lane | Payload | Current surface |
| --- | --- | --- | --- | --- |
| `2001` | `Ethereum -> Wire` | `bar` | `BondedActorMirror` | `wire-ethereum/contracts/outpost/BAR.sol` |
| `2002` | `Ethereum -> Wire` | `bar` | `UnbondedActorMirror` | `wire-ethereum/contracts/outpost/BAR.sol` |
| `2003` | `Ethereum -> Wire` | `bar` | `BondSlashMirror` | `wire-ethereum/contracts/outpost/BAR.sol` |
| `3001` | `Ethereum -> Wire` | `depositor` | `StakeMirror` | `wire-ethereum/contracts/outpost/Depositor.sol` |
| `3002` | `Ethereum -> Wire` | `depositor` | `UnstakeMirror` | `wire-ethereum/contracts/outpost/Depositor.sol` |
| `3004` | `Ethereum -> Wire` | `pretoken` | `PretokenPurchaseMirror` | `wire-ethereum/contracts/outpost/Depositor.sol` |
| `3005` | `Ethereum -> Wire` | `pretoken` | `PretokenPurchaseMirror` | `wire-ethereum/contracts/outpost/Pretoken.sol` |
| `3006` | `Ethereum -> Wire` | `pretoken` | `PretokenPurchaseMirror` | `wire-ethereum/contracts/outpost/Depositor.sol` |
| `4001` | `Solana -> Wire` | `depositor` | `StakeMirror` | `capital-staking/.../wire_syndication/syndicate_liqsol.rs` |
| `4002` | `Solana -> Wire` | `depositor` | `WithdrawRequest` | `capital-staking/.../wire_syndication/desyndicate_liqsol.rs` |
| `4003` | `Solana -> Wire` | `pretoken` | `PretokenPurchaseMirror` | `capital-staking/.../wire_pretokens/purchase_pretoken.rs` |
| `4004` | `Solana -> Wire` | `pretoken` | `PretokenPurchaseMirror` | `capital-staking/.../wire_pretokens/purchase_pretokens_from_yield.rs` |
| `4101` | `Solana -> Wire` | `bar` | `RoleBondRequest` | `capital-staking/.../bar/bond_ops.rs` |
| `4102` | `Solana -> Wire` | `bar` | `RoleUnbondRequest` | `capital-staking/.../bar/bond_ops.rs` |
| `5001` | `Wire -> Solana` | `admin` | `CompleteWithdrawCommand` | `capital-staking/.../wire_config/admin_instructions.rs` |
| `5002` | `Wire -> Solana` | `admin` | `CompleteUnbondCommand` | `capital-staking/.../bar/admin_instructions.rs` |
| `5003` | `Wire -> Solana` | `admin` | `SlashBondCommand` | `capital-staking/.../bar/admin_instructions.rs` |
| `5004` | `Wire -> Solana` | `admin` | `AdminForceUnbondCommand` | `capital-staking/.../bar/admin_instructions.rs` |
| `5009` | `Wire -> Solana` | `admin` | `RequestRejected` | Reserved for failed Solana request outcomes |
| `6001` | `Wire -> Ethereum` | `admin` | `CompleteUnbondCommand` | Reserved for Ethereum endpoint implementation |
| `6002` | `Wire -> Ethereum` | `admin` | `SlashBondCommand` | Reserved for Ethereum endpoint implementation |
| `6009` | `Wire -> Ethereum` | `admin` | `RequestRejected` | Reserved for Ethereum endpoint implementation |
## Notes
- `3004`, `3005`, and `3006` all currently describe pretoken-related state, but they remain distinct numeric IDs because they originate from different Ethereum business actions.
- `4002` and the `500x` series are the first Solana request/response pair that should be implemented for end-to-end testing.
- `600x` is intentionally small right now because `Wire -> Ethereum` business handlers do not yet exist in this checkout.

215
protocol/opp/v1/opp.proto Normal file
View File

@@ -0,0 +1,215 @@
syntax = "proto3";
package wire.opp.v1;
enum ChainKind {
CHAIN_KIND_UNKNOWN = 0;
CHAIN_KIND_WIRE = 1;
CHAIN_KIND_ETHEREUM = 2;
CHAIN_KIND_SOLANA = 3;
CHAIN_KIND_SUI = 4;
}
enum OppLane {
OPP_LANE_UNSPECIFIED = 0;
OPP_LANE_DEPOSITOR = 1;
OPP_LANE_PRETOKEN = 2;
OPP_LANE_BAR = 3;
OPP_LANE_ADMIN = 4;
OPP_LANE_SWAP = 5;
}
enum Role {
ROLE_UNSPECIFIED = 0;
ROLE_YIELD_OPERATOR = 1;
ROLE_BATCH_OPERATOR = 2;
ROLE_UNDERWRITER = 4;
ROLE_POOL_OPERATOR = 8;
}
enum AssertionType {
ASSERTION_TYPE_UNSPECIFIED = 0;
ASSERTION_TYPE_ETH_BAR_BONDED_ACTOR = 2001;
ASSERTION_TYPE_ETH_BAR_UNBONDED_ACTOR = 2002;
ASSERTION_TYPE_ETH_BAR_BOND_SLASHED = 2003;
ASSERTION_TYPE_ETH_DEPOSITOR_STAKE = 3001;
ASSERTION_TYPE_ETH_DEPOSITOR_UNSTAKE = 3002;
ASSERTION_TYPE_ETH_DEPOSITOR_LIQ_PRETOKEN_PURCHASE = 3004;
ASSERTION_TYPE_ETH_PRETOKEN_PURCHASE = 3005;
ASSERTION_TYPE_ETH_DEPOSITOR_YIELD_PRETOKEN_PURCHASE = 3006;
ASSERTION_TYPE_SOL_STAKE = 4001;
ASSERTION_TYPE_SOL_WITHDRAW_REQUEST = 4002;
ASSERTION_TYPE_SOL_PRETOKEN_PURCHASE = 4003;
ASSERTION_TYPE_SOL_YIELD_PRETOKEN_PURCHASE = 4004;
ASSERTION_TYPE_SOL_BAR_BOND_ROLE = 4101;
ASSERTION_TYPE_SOL_BAR_UNBOND_REQUEST = 4102;
ASSERTION_TYPE_WIRE_SOL_COMPLETE_WITHDRAW = 5001;
ASSERTION_TYPE_WIRE_SOL_COMPLETE_UNBOND = 5002;
ASSERTION_TYPE_WIRE_SOL_SLASH_BOND = 5003;
ASSERTION_TYPE_WIRE_SOL_ADMIN_FORCE_UNBOND = 5004;
ASSERTION_TYPE_WIRE_SOL_REQUEST_REJECTED = 5009;
ASSERTION_TYPE_WIRE_ETH_COMPLETE_UNBOND = 6001;
ASSERTION_TYPE_WIRE_ETH_SLASH_BOND = 6002;
ASSERTION_TYPE_WIRE_ETH_REQUEST_REJECTED = 6009;
}
message StreamKey {
ChainKind from_chain = 1;
ChainKind to_chain = 2;
bytes origin_system = 3;
bytes destination_system = 4;
OppLane lane = 5;
}
message Assertion {
AssertionType assertion_type = 1;
bytes payload = 2;
}
message Uint256 {
// Exactly 32 bytes, big-endian, unsigned.
bytes be_bytes = 1;
}
message MessageHeader {
StreamKey stream = 1;
uint64 sequence = 2;
bytes previous_message_hash = 3;
uint64 source_timestamp_ms = 4;
bytes source_event_id = 5;
bytes payload_hash = 6;
}
message Message {
MessageHeader header = 1;
repeated Assertion assertions = 2;
}
message BatchHeader {
StreamKey stream = 1;
uint64 batch_number = 2;
bytes previous_batch_hash = 3;
uint64 first_sequence = 4;
uint64 last_sequence = 5;
uint64 sealed_at_ms = 6;
bytes merkle_root = 7;
}
message Batch {
BatchHeader header = 1;
repeated Assertion summary_assertions = 2;
}
message BatchSubmission {
BatchHeader header = 1;
bytes batch_hash = 2;
bytes operator_id = 3;
bytes signature = 4;
}
message RequestRef {
bytes request_id = 1;
bytes origin_message_id = 2;
bytes source_event_id = 3;
}
message StakeMirror {
bytes user = 1;
Uint256 principal = 2;
Uint256 shares = 3;
Uint256 index_at_mint = 4;
}
message UnstakeMirror {
bytes user = 1;
Uint256 amount = 2;
Uint256 shares = 3;
Uint256 index_at_burn = 4;
bytes receipt_id = 5;
}
message PretokenPurchaseMirror {
bytes buyer = 1;
Uint256 principal = 2;
Uint256 shares = 3;
Uint256 index_at_mint = 4;
Uint256 pretokens_out = 5;
}
message BondedActorMirror {
bytes actor = 1;
bytes owner = 2;
bytes bond_level_id = 3;
Uint256 token_id = 4;
uint64 bonded_at_unix_seconds = 5;
}
message UnbondedActorMirror {
bytes actor = 1;
bytes bond_level_id = 2;
Uint256 token_id = 3;
uint64 unbonded_at_unix_seconds = 4;
}
message BondSlashMirror {
bytes actor = 1;
bytes bond_level_id = 2;
Uint256 slashed_amount = 3;
}
message WithdrawRequest {
bytes request_id = 1;
bytes user = 2;
Uint256 amount = 3;
}
message RoleBondRequest {
bytes request_id = 1;
bytes user = 2;
Role role = 3;
Uint256 principal = 4;
uint64 warmup_ends_at_unix_seconds = 5;
}
message RoleUnbondRequest {
bytes request_id = 1;
bytes user = 2;
Role role = 3;
}
message CompleteWithdrawCommand {
RequestRef request = 1;
bytes user = 2;
Uint256 amount = 3;
}
message CompleteUnbondCommand {
RequestRef request = 1;
bytes user = 2;
Role role = 3;
Uint256 principal = 4;
}
message SlashBondCommand {
RequestRef request = 1;
bytes user = 2;
Role role = 3;
Uint256 slashed_amount = 4;
}
message AdminForceUnbondCommand {
RequestRef request = 1;
bytes user = 2;
Role role = 3;
}
message RequestRejected {
RequestRef request = 1;
uint32 code = 2;
string reason = 3;
}