@layerzerolabs/protocol-stellar-v2 0.2.10 → 0.2.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/.turbo/turbo-build.log +273 -219
  2. package/.turbo/turbo-lint.log +79 -107
  3. package/.turbo/turbo-test.log +1016 -840
  4. package/Cargo.lock +14 -6
  5. package/contracts/common-macros/src/contract_impl.rs +6 -3
  6. package/contracts/common-macros/src/error.rs +9 -17
  7. package/contracts/common-macros/src/lib.rs +4 -37
  8. package/contracts/common-macros/src/ownable.rs +9 -5
  9. package/contracts/common-macros/src/tests/contract_impl.rs +178 -86
  10. package/contracts/common-macros/src/tests/error.rs +168 -0
  11. package/contracts/common-macros/src/tests/mod.rs +2 -4
  12. package/contracts/common-macros/src/tests/ownable.rs +37 -60
  13. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__contract_impl__snapshot_generated_contract_impl_code.snap +16 -6
  14. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__error__snapshot_generated_contract_error_code.snap +20 -0
  15. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_generated_ownable_code.snap +3 -1
  16. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ownable__snapshot_only_owner_preserves_function_signature.snap +12 -2
  17. package/contracts/common-macros/src/tests/snapshots/common_macros__tests__ttl_configurable__snapshot_generated_ttl_configurable_code.snap +5 -1
  18. package/contracts/common-macros/src/tests/utils.rs +267 -0
  19. package/contracts/common-macros/src/ttl_configurable.rs +15 -12
  20. package/contracts/common-macros/src/utils.rs +35 -6
  21. package/contracts/endpoint-v2/src/endpoint_v2.rs +4 -4
  22. package/contracts/endpoint-v2/src/events.rs +40 -22
  23. package/contracts/endpoint-v2/src/interfaces/message_lib.rs +2 -2
  24. package/contracts/endpoint-v2/src/interfaces/message_lib_manager.rs +2 -2
  25. package/contracts/endpoint-v2/src/interfaces/messaging_channel.rs +2 -2
  26. package/contracts/endpoint-v2/src/interfaces/messaging_composer.rs +2 -2
  27. package/contracts/endpoint-v2/src/interfaces/send_lib.rs +2 -2
  28. package/contracts/endpoint-v2/src/message_lib_manager.rs +3 -3
  29. package/contracts/endpoint-v2/src/messaging_channel.rs +1 -1
  30. package/contracts/endpoint-v2/src/messaging_composer.rs +1 -1
  31. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_lib_timeout.rs +4 -8
  32. package/contracts/endpoint-v2/src/tests/message_lib_manager/set_default_receive_library.rs +3 -7
  33. package/contracts/message-libs/{block-message-lib → blocked-message-lib}/Cargo.toml +1 -1
  34. package/contracts/message-libs/treasury/src/events.rs +9 -6
  35. package/contracts/message-libs/uln-302/src/events.rs +19 -11
  36. package/contracts/message-libs/uln-302/src/interfaces/receive_uln.rs +2 -2
  37. package/contracts/message-libs/uln-302/src/interfaces/send_uln.rs +2 -2
  38. package/contracts/message-libs/uln-302/src/receive_uln.rs +2 -2
  39. package/contracts/message-libs/uln-302/src/send_uln.rs +3 -3
  40. package/contracts/message-libs/uln-302/src/tests/receive_uln302/set_default_receive_uln_configs.rs +5 -5
  41. package/contracts/message-libs/uln-302/src/tests/send_uln302/set_default_send_uln_configs.rs +5 -5
  42. package/contracts/message-libs/uln-302/src/tests/setup.rs +3 -3
  43. package/contracts/message-libs/uln-302/src/types.rs +24 -24
  44. package/contracts/message-libs/uln-302/src/uln302.rs +2 -2
  45. package/contracts/oapp-macros/src/oapp_core.rs +1 -1
  46. package/contracts/oapps/counter/integration_tests/utils.rs +1 -1
  47. package/contracts/oapps/oapp/src/oapp_core.rs +4 -3
  48. package/contracts/oapps/oapp/src/oapp_options_type3.rs +4 -3
  49. package/contracts/oapps/oft/integration-tests/setup.rs +4 -3
  50. package/contracts/oapps/oft/integration-tests/utils.rs +1 -1
  51. package/contracts/oapps/oft/src/default_oft_impl.rs +146 -0
  52. package/contracts/oapps/oft/src/events.rs +5 -4
  53. package/contracts/oapps/oft/src/extensions/mod.rs +3 -0
  54. package/contracts/oapps/oft/src/extensions/oft_fee.rs +168 -0
  55. package/contracts/oapps/oft/src/extensions/pausable.rs +50 -0
  56. package/contracts/oapps/oft/src/extensions/rate_limiter.rs +200 -0
  57. package/contracts/oapps/oft/src/lib.rs +2 -3
  58. package/contracts/oapps/oft/src/oft.rs +16 -85
  59. package/contracts/oapps/oft/src/oft_types/mint_burn.rs +1 -1
  60. package/contracts/oapps/oft/src/tests/extensions/mod.rs +11 -0
  61. package/contracts/oapps/oft/src/tests/extensions/setup.rs +888 -0
  62. package/contracts/oapps/oft/src/tests/extensions/test_oft_fee.rs +749 -0
  63. package/contracts/oapps/oft/src/tests/extensions/test_pausable.rs +432 -0
  64. package/contracts/oapps/oft/src/tests/extensions/test_rate_limiter.rs +1078 -0
  65. package/contracts/oapps/oft/src/tests/mod.rs +2 -0
  66. package/contracts/oapps/oft/src/tests/test_utils.rs +24 -6
  67. package/contracts/oapps/{oft-mint-burn → oft-std}/Cargo.toml +1 -8
  68. package/contracts/oapps/oft-std/src/lib.rs +5 -0
  69. package/contracts/oapps/oft-std/src/oft.rs +59 -0
  70. package/contracts/utils/src/ownable.rs +8 -6
  71. package/contracts/utils/src/tests/ownable.rs +0 -63
  72. package/contracts/utils/src/tests/testing_utils.rs +7 -5
  73. package/contracts/utils/src/ttl.rs +21 -2
  74. package/contracts/workers/dvn/src/auth.rs +108 -30
  75. package/contracts/workers/dvn/src/dvn.rs +103 -33
  76. package/contracts/workers/dvn/src/errors.rs +10 -13
  77. package/contracts/workers/dvn/src/events.rs +7 -5
  78. package/contracts/workers/dvn/src/interfaces/dvn.rs +76 -3
  79. package/contracts/workers/dvn/src/interfaces/multisig.rs +41 -0
  80. package/contracts/workers/dvn/src/lib.rs +6 -8
  81. package/contracts/workers/dvn/src/multisig.rs +98 -72
  82. package/contracts/workers/dvn/src/storage.rs +9 -12
  83. package/contracts/workers/dvn/src/tests/auth.rs +56 -26
  84. package/contracts/workers/dvn/src/tests/dvn.rs +40 -41
  85. package/contracts/workers/dvn/src/tests/multisig/set_signer.rs +8 -8
  86. package/contracts/workers/dvn/src/tests/multisig/set_threshold.rs +9 -9
  87. package/contracts/workers/dvn/src/tests/multisig/verify_signatures.rs +6 -6
  88. package/contracts/workers/dvn/src/tests/setup.rs +5 -5
  89. package/contracts/workers/dvn-fee-lib/Cargo.toml +2 -1
  90. package/contracts/workers/dvn-fee-lib/src/dvn_fee_lib.rs +4 -3
  91. package/contracts/workers/dvn-fee-lib/src/tests/dvn_fee_lib.rs +8 -6
  92. package/contracts/workers/executor/src/auth.rs +93 -0
  93. package/contracts/workers/executor/src/events.rs +5 -4
  94. package/contracts/workers/executor/src/{lz_executor.rs → executor.rs} +30 -103
  95. package/contracts/workers/executor/src/interfaces/executor.rs +5 -2
  96. package/contracts/workers/executor/src/interfaces/mod.rs +1 -1
  97. package/contracts/workers/executor/src/lib.rs +6 -5
  98. package/contracts/workers/price-feed/Cargo.toml +21 -0
  99. package/contracts/workers/price-feed/src/errors.rs +9 -0
  100. package/contracts/workers/price-feed/src/events.rs +30 -0
  101. package/contracts/workers/price-feed/src/lib.rs +11 -0
  102. package/contracts/workers/price-feed/src/price_feed.rs +265 -0
  103. package/contracts/workers/price-feed/src/storage.rs +42 -0
  104. package/contracts/workers/price-feed/src/types.rs +59 -0
  105. package/contracts/workers/worker/src/events.rs +23 -13
  106. package/contracts/workers/worker/src/interfaces/dvn_fee_lib.rs +2 -1
  107. package/contracts/workers/worker/src/worker.rs +32 -21
  108. package/package.json +3 -3
  109. package/sdk/dist/generated/bml.js +24 -22
  110. package/sdk/dist/generated/counter.d.ts +102 -0
  111. package/sdk/dist/generated/counter.js +36 -24
  112. package/sdk/dist/generated/endpoint.js +24 -22
  113. package/sdk/dist/generated/sml.js +24 -22
  114. package/sdk/dist/generated/uln302.d.ts +1 -1
  115. package/sdk/dist/generated/uln302.js +34 -32
  116. package/sdk/package.json +1 -1
  117. package/sdk/test/index.test.ts +1 -1
  118. package/sdk/test/oft.test.ts +847 -0
  119. package/sdk/test/suites/scan.ts +20 -4
  120. package/tools/ts-bindings-gen/src/main.rs +2 -1
  121. package/contracts/common-macros/src/event.rs +0 -16
  122. package/contracts/oapps/oft/src/macro_tests/mod.rs +0 -2
  123. package/contracts/oapps/oft/src/macro_tests/test_all_default.rs +0 -41
  124. package/contracts/oapps/oft/src/macro_tests/test_override.rs +0 -83
  125. package/contracts/oapps/oft-mint-burn/src/lib.rs +0 -3
  126. package/contracts/oapps/oft-mint-burn/src/oft.rs +0 -28
  127. package/contracts/oapps/oft-mint-burn/src/tests/mod.rs +0 -1
  128. package/contracts/workers/dvn/src/types.rs +0 -26
  129. /package/contracts/message-libs/{block-message-lib → blocked-message-lib}/src/lib.rs +0 -0
@@ -1,27 +1,50 @@
1
+ //! LayerZero Decentralized Verifier Network (DVN) contract.
2
+ //!
3
+ //! The DVN is responsible for verifying cross-chain messages by providing
4
+ //! cryptographic attestations. It uses a multisig scheme with secp256k1
5
+ //! signatures for authorization and implements Soroban's custom account
6
+ //! interface for transaction signing.
7
+
1
8
  use crate::{
2
- errors::{DvnError, MultisigError},
3
- events::SetDstConfig,
4
- storage::DvnStorage,
5
- types::{DstConfig, DstConfigParam},
6
- IDVN,
9
+ errors::DvnError, events::SetDstConfig, storage::DvnStorage, Call, DstConfig, DstConfigParam, IMultisig, IDVN,
7
10
  };
8
- use common_macros::ttl_configurable;
11
+ use common_macros::{contract_impl, ttl_configurable};
9
12
  use endpoint_v2::FeeRecipient;
10
13
  use message_lib_common::interfaces::ILayerZeroDVN;
11
- use soroban_sdk::{
12
- assert_with_error, contract, contractimpl, crypto::Hash, xdr::ToXdr, Address, Bytes, BytesN, Env, Vec,
13
- };
14
- use utils::{buffer_writer::BufferWriter, option_ext::OptionExt};
14
+ use soroban_sdk::{contract, xdr::ToXdr, Address, Bytes, BytesN, Env, Vec};
15
+ use utils::buffer_writer::BufferWriter;
16
+ use utils::option_ext::OptionExt;
15
17
  use worker::{
16
18
  assert_acl, assert_not_paused, assert_supported_message_lib, init_worker, require_admin_auth, set_admin_by_admin,
17
- set_admin_by_owner, storage::WorkerStorage, DvnFeeLibClient, DvnFeeParams, Worker,
19
+ set_admin_by_owner, DvnFeeLibClient, DvnFeeParams, Worker,
18
20
  };
21
+
22
+ /// LayerZero DVN contract.
23
+ ///
24
+ /// Implements multisig-based verification with custom account authorization.
25
+ /// The contract owns itself, allowing the multisig quorum to authorize operations.
19
26
  #[contract]
20
27
  #[ttl_configurable]
21
- pub struct Dvn;
28
+ pub struct LzDVN;
22
29
 
23
- #[contractimpl]
24
- impl Dvn {
30
+ // ============================================================================
31
+ // Core Implementation
32
+ // ============================================================================
33
+
34
+ #[contract_impl]
35
+ impl LzDVN {
36
+ /// Initializes the DVN contract.
37
+ ///
38
+ /// # Arguments
39
+ /// * `vid` - Verifier ID, unique identifier for this DVN
40
+ /// * `signers` - Initial multisig signers (20-byte Ethereum addresses)
41
+ /// * `threshold` - Minimum signatures required for multisig operations
42
+ /// * `admins` - Initial admin addresses for operational functions
43
+ /// * `supported_msglibs` - Message libraries this DVN supports (e.g., ULN302)
44
+ /// * `price_feed` - Price feed contract for fee calculations
45
+ /// * `default_multiplier_bps` - Default fee multiplier (10000 = 1x)
46
+ /// * `worker_fee_lib` - Fee library contract for computing DVN fees
47
+ /// * `deposit_address` - Address to receive fee payments
25
48
  pub fn __constructor(
26
49
  env: &Env,
27
50
  vid: u32,
@@ -30,15 +53,22 @@ impl Dvn {
30
53
  admins: &Vec<Address>,
31
54
  supported_msglibs: &Vec<Address>,
32
55
  price_feed: &Address,
33
- worker_fee_lib: &Address,
34
56
  default_multiplier_bps: u32,
57
+ worker_fee_lib: &Address,
35
58
  deposit_address: &Address,
36
59
  ) {
37
- init_multisig(env, signers, threshold);
60
+ Self::init_multisig(env, signers, threshold);
38
61
  Self::init_owner(env, &env.current_contract_address());
39
- init_worker::<Self>(env, admins, supported_msglibs, price_feed, default_multiplier_bps);
40
- WorkerStorage::set_worker_fee_lib(env, worker_fee_lib);
41
- WorkerStorage::set_deposit_address(env, deposit_address);
62
+ init_worker::<Self>(
63
+ env,
64
+ admins,
65
+ supported_msglibs,
66
+ price_feed,
67
+ default_multiplier_bps,
68
+ worker_fee_lib,
69
+ deposit_address,
70
+ );
71
+
42
72
  DvnStorage::set_vid(env, &vid);
43
73
  }
44
74
 
@@ -55,10 +85,13 @@ impl Dvn {
55
85
  set_admin_by_admin::<Self>(env, caller, admin, active);
56
86
  }
57
87
 
58
- /// Function for quorum to change the admin without going through the execute function
88
+ /// Allows the quorum to add/remove admins without requiring an admin signature.
59
89
  ///
60
- /// # Arguments
90
+ /// This function bypasses the normal admin verification in `__check_auth`,
91
+ /// requiring only multisig quorum signatures. Must be called as a single
92
+ /// operation (cannot be bundled with other calls).
61
93
  ///
94
+ /// # Arguments
62
95
  /// * `admin` - The address to set admin status for
63
96
  /// * `active` - `true` to add admin, `false` to remove
64
97
  pub fn quorum_change_admin(env: &Env, admin: &Address, active: bool) {
@@ -66,8 +99,13 @@ impl Dvn {
66
99
  }
67
100
  }
68
101
 
69
- #[contractimpl]
70
- impl IDVN for Dvn {
102
+ // ============================================================================
103
+ // IDVN Implementation
104
+ // ============================================================================
105
+
106
+ #[contract_impl]
107
+ impl IDVN for LzDVN {
108
+ /// Sets destination chain configurations. Requires admin authorization.
71
109
  fn set_dst_config(env: &Env, admin: &Address, params: &Vec<DstConfigParam>) {
72
110
  require_admin_auth::<Self>(env, admin);
73
111
  for param in params {
@@ -77,17 +115,35 @@ impl IDVN for Dvn {
77
115
  SetDstConfig { params: params.clone() }.publish(env);
78
116
  }
79
117
 
80
- fn dst_config(env: &Env, dst_eid: u32) -> DstConfig {
81
- DvnStorage::dst_config(env, dst_eid).unwrap_or_panic(env, DvnError::EidNotSupported)
118
+ /// Returns the destination configuration for a specific endpoint ID.
119
+ fn dst_config(env: &Env, dst_eid: u32) -> Option<DstConfig> {
120
+ DvnStorage::dst_config(env, dst_eid)
82
121
  }
83
122
 
123
+ /// Returns the Verifier ID for this DVN.
84
124
  fn vid(env: &Env) -> u32 {
85
125
  DvnStorage::vid(env).unwrap()
86
126
  }
127
+
128
+ /// Computes the hash of call data for multisig signing.
129
+ ///
130
+ /// Off-chain signers use this to compute the hash they need to sign.
131
+ fn hash_call_data(env: &Env, vid: u32, expiration: u64, calls: &Vec<Call>) -> BytesN<32> {
132
+ let mut writer = BufferWriter::new(env);
133
+ let data = writer.write_u32(vid).write_u64(expiration).write_bytes(&calls.to_xdr(env)).to_bytes();
134
+ env.crypto().keccak256(&data).into()
135
+ }
87
136
  }
88
137
 
89
- #[contractimpl]
90
- impl ILayerZeroDVN for Dvn {
138
+ // ============================================================================
139
+ // ILayerZeroDVN Implementation (Send Flow)
140
+ // ============================================================================
141
+
142
+ #[contract_impl]
143
+ impl ILayerZeroDVN for LzDVN {
144
+ /// Calculates the verification fee for a cross-chain message.
145
+ ///
146
+ /// Called by the send library to quote DVN fees before sending.
91
147
  fn get_fee(
92
148
  env: &Env,
93
149
  _send_lib: &Address,
@@ -101,7 +157,7 @@ impl ILayerZeroDVN for Dvn {
101
157
  assert_not_paused::<Self>(env);
102
158
  assert_acl::<Self>(env, sender);
103
159
 
104
- let dst_config = Self::dst_config(env, dst_eid);
160
+ let dst_config = Self::dst_config(env, dst_eid).unwrap_or_panic(env, DvnError::EidNotSupported);
105
161
  let params = DvnFeeParams {
106
162
  sender: sender.clone(),
107
163
  dst_eid,
@@ -115,9 +171,13 @@ impl ILayerZeroDVN for Dvn {
115
171
  floor_margin_usd: dst_config.floor_margin_usd,
116
172
  };
117
173
 
118
- DvnFeeLibClient::new(env, &Self::worker_fee_lib(env)).get_fee(&params)
174
+ DvnFeeLibClient::new(env, &Self::worker_fee_lib(env)).get_fee(&env.current_contract_address(), &params)
119
175
  }
120
176
 
177
+ /// Assigns a verification job to this DVN and returns fee payment info.
178
+ ///
179
+ /// Called by the send library when a message is sent. The DVN will later
180
+ /// verify the message on the destination chain.
121
181
  fn assign_job(
122
182
  env: &Env,
123
183
  send_lib: &Address,
@@ -136,8 +196,18 @@ impl ILayerZeroDVN for Dvn {
136
196
  }
137
197
  }
138
198
 
139
- #[contractimpl(contracttrait)]
140
- impl Worker for Dvn {}
199
+ // ============================================================================
200
+ // Worker Implementation
201
+ // ============================================================================
202
+
203
+ #[contract_impl(contracttrait)]
204
+ impl Worker for LzDVN {}
205
+
206
+ // ============================================================================
207
+ // Include SubModules
208
+ // ============================================================================
141
209
 
142
- include!("multisig.rs");
143
- include!("auth.rs");
210
+ #[path = "auth.rs"]
211
+ pub mod auth;
212
+ #[path = "multisig.rs"]
213
+ pub mod multisig;
@@ -1,21 +1,18 @@
1
1
  use common_macros::contract_error;
2
2
 
3
- #[contract_error]
4
- pub enum MultisigError {
5
- ZeroThreshold,
6
- TotalSignersLessThanThreshold,
7
- InvalidSigner,
8
- SignerAlreadyExists,
9
- SignerNotFound,
10
- UnsortedSigners,
11
- SignatureError,
12
- }
13
-
14
3
  #[contract_error]
15
4
  pub enum DvnError {
16
- InvalidVid,
17
5
  AuthDataExpired,
6
+ EidNotSupported,
18
7
  HashAlreadyUsed,
8
+ InvalidSigner,
9
+ InvalidVid,
10
+ NonContractInvoke,
19
11
  OnlyAdmin,
20
- EidNotSupported,
12
+ SignatureError,
13
+ SignerAlreadyExists,
14
+ SignerNotFound,
15
+ TotalSignersLessThanThreshold,
16
+ UnsortedSigners,
17
+ ZeroThreshold,
21
18
  }
@@ -1,19 +1,21 @@
1
1
  use crate::DstConfigParam;
2
- use common_macros::event;
3
- use soroban_sdk::{BytesN, Vec};
2
+ use soroban_sdk::{contractevent, BytesN, Vec};
4
3
 
5
- #[event]
4
+ #[contractevent]
5
+ #[derive(Clone, Debug, Eq, PartialEq)]
6
6
  pub struct SignerSet {
7
7
  pub signer: BytesN<20>,
8
8
  pub active: bool,
9
9
  }
10
10
 
11
- #[event]
11
+ #[contractevent]
12
+ #[derive(Clone, Debug, Eq, PartialEq)]
12
13
  pub struct ThresholdSet {
13
14
  pub threshold: u32,
14
15
  }
15
16
 
16
- #[event]
17
+ #[contractevent]
18
+ #[derive(Clone, Debug, Eq, PartialEq)]
17
19
  pub struct SetDstConfig {
18
20
  pub params: Vec<DstConfigParam>,
19
21
  }
@@ -1,12 +1,85 @@
1
- use crate::types::{DstConfig, DstConfigParam};
2
1
  use crate::IMultisig;
3
2
  use message_lib_common::interfaces::ILayerZeroDVN;
4
- use soroban_sdk::{contractclient, Address, Env, Vec};
3
+ use soroban_sdk::{contractclient, contracttype, Address, BytesN, Env, Symbol, Val, Vec};
5
4
  use worker::Worker;
6
5
 
6
+ /// Configuration for a destination chain.
7
+ ///
8
+ /// Contains fee calculation parameters specific to each destination endpoint.
9
+ #[contracttype]
10
+ #[derive(Clone, Debug, Eq, PartialEq)]
11
+ pub struct DstConfig {
12
+ /// Gas for verification on the destination chain.
13
+ pub gas: u128,
14
+ /// Fee multiplier in basis points (10000 = 100%).
15
+ /// If 0, the default multiplier from worker config is used.
16
+ pub multiplier_bps: u32,
17
+ /// Minimum fee margin in USD (scaled by native decimals rate).
18
+ pub floor_margin_usd: u128,
19
+ }
20
+
21
+ /// Parameter for setting destination chain configuration.
22
+ #[contracttype]
23
+ #[derive(Clone, Debug, Eq, PartialEq)]
24
+ pub struct DstConfigParam {
25
+ /// The destination endpoint ID.
26
+ pub dst_eid: u32,
27
+ /// The configuration for this destination.
28
+ pub config: DstConfig,
29
+ }
30
+
31
+ /// Represents a single contract invocation for multisig authorization.
32
+ ///
33
+ /// Used in `hash_call_data` to compute the hash that signers sign over.
34
+ #[contracttype]
35
+ #[derive(Clone, Debug, Eq, PartialEq)]
36
+ pub struct Call {
37
+ /// Target contract address.
38
+ pub to: Address,
39
+ /// Function name to invoke.
40
+ pub func: Symbol,
41
+ /// Function arguments.
42
+ pub args: Vec<Val>,
43
+ }
44
+
45
+ /// DVN (Decentralized Verifier Network) contract interface.
46
+ ///
47
+ /// Extends the LayerZero DVN interface with destination configuration management
48
+ /// and multisig capabilities for secure cross-chain message verification.
7
49
  #[contractclient(name = "DVNClient")]
8
50
  pub trait IDVN: ILayerZeroDVN + Worker + IMultisig {
51
+ /// Sets the configuration for one or more destination chains.
52
+ ///
53
+ /// # Arguments
54
+ /// * `admin` - The admin address (must provide authorization)
55
+ /// * `params` - List of destination configurations to set
9
56
  fn set_dst_config(env: &Env, admin: &Address, params: &Vec<DstConfigParam>);
10
- fn dst_config(env: &Env, dst_eid: u32) -> DstConfig;
57
+
58
+ /// Gets the configuration for a destination chain.
59
+ ///
60
+ /// # Arguments
61
+ /// * `dst_eid` - The destination endpoint ID
62
+ ///
63
+ /// # Returns
64
+ /// The destination configuration, or `None` if not configured
65
+ fn dst_config(env: &Env, dst_eid: u32) -> Option<DstConfig>;
66
+
67
+ /// Returns the verifier ID (VID) of this DVN.
68
+ ///
69
+ /// The VID is a unique identifier used in multisig authentication.
11
70
  fn vid(env: &Env) -> u32;
71
+
72
+ /// Computes the hash of call data for multisig signing.
73
+ ///
74
+ /// Off-chain signers use this to compute the hash they need to sign.
75
+ /// The hash includes the VID, expiration, and the calls being authorized.
76
+ ///
77
+ /// # Arguments
78
+ /// * `vid` - Verifier ID (must match contract's VID)
79
+ /// * `expiration` - Expiration timestamp for the authorization
80
+ /// * `calls` - The contract calls being authorized
81
+ ///
82
+ /// # Returns
83
+ /// A 32-byte keccak256 hash to be signed by the multisig quorum
84
+ fn hash_call_data(env: &Env, vid: u32, expiration: u64, calls: &Vec<Call>) -> BytesN<32>;
12
85
  }
@@ -1,15 +1,56 @@
1
1
  use soroban_sdk::{contractclient, BytesN, Env, Vec};
2
2
 
3
+ /// Length of an ECDSA signature (64 bytes) plus recovery ID (1 byte).
3
4
  pub const SIGNATURE_LENGTH: usize = 65;
4
5
 
6
+ /// Multisig interface for threshold-based signature verification.
7
+ ///
8
+ /// Provides functionality to manage signers and verify that a sufficient
9
+ /// number of valid signatures (meeting the threshold) have signed a message.
5
10
  #[contractclient(name = "MultiSigClient")]
6
11
  pub trait IMultisig {
12
+ /// Adds or removes a signer from the multisig.
13
+ ///
14
+ /// # Arguments
15
+ /// * `signer` - The 20-byte signer address (derived from secp256k1 public key)
16
+ /// * `active` - `true` to add, `false` to remove
7
17
  fn set_signer(env: &Env, signer: &BytesN<20>, active: bool);
18
+
19
+ /// Returns all registered signers.
8
20
  fn get_signers(env: &Env) -> Vec<BytesN<20>>;
21
+
22
+ /// Returns the total number of registered signers.
9
23
  fn total_signers(env: &Env) -> u32;
24
+
25
+ /// Checks if an address is a registered signer.
10
26
  fn is_signer(env: &Env, signer: &BytesN<20>) -> bool;
27
+
28
+ /// Returns the current signature threshold (quorum).
11
29
  fn threshold(env: &Env) -> u32;
30
+
31
+ /// Sets the signature threshold (quorum).
32
+ ///
33
+ /// The threshold must be greater than 0 and not exceed total signers.
12
34
  fn set_threshold(env: &Env, threshold: u32);
35
+
36
+ /// Verifies signatures against the configured threshold.
37
+ ///
38
+ /// # Arguments
39
+ /// * `hash` - The 32-byte message hash that was signed
40
+ /// * `signatures` - List of signatures to verify
41
+ ///
42
+ /// # Panics
43
+ /// If fewer than `threshold` valid signatures from registered signers are provided.
13
44
  fn verify_signatures(env: &Env, hash: &BytesN<32>, signatures: &Vec<BytesN<SIGNATURE_LENGTH>>);
45
+
46
+ /// Verifies signatures against a custom threshold.
47
+ ///
48
+ /// # Arguments
49
+ /// * `hash` - The 32-byte message hash that was signed
50
+ /// * `signatures` - List of signatures to verify
51
+ /// * `threshold` - Custom threshold to use instead of the configured one
52
+ ///
53
+ /// # Panics
54
+ /// If fewer than `threshold` valid signatures from registered signers are provided.
14
55
  fn verify_n_signatures(env: &Env, hash: &BytesN<32>, signatures: &Vec<BytesN<SIGNATURE_LENGTH>>, threshold: u32);
15
56
  }
@@ -1,24 +1,22 @@
1
1
  #![no_std]
2
- #[cfg(test)]
3
- extern crate std;
4
2
 
5
- mod errors;
3
+ pub mod errors;
6
4
  pub mod events;
7
- mod interfaces;
8
- mod types;
5
+ pub mod interfaces;
9
6
 
10
- pub use errors::*;
11
7
  pub use interfaces::*;
12
- pub use types::*;
13
8
 
14
9
  cfg_if::cfg_if! {
15
10
  if #[cfg(any(not(feature = "library"), feature = "testutils"))] {
16
11
  mod storage;
17
12
  mod dvn;
18
13
 
19
- pub use dvn::Dvn;
14
+ pub use dvn::*;
20
15
  }
21
16
  }
22
17
 
18
+ #[cfg(test)]
19
+ extern crate std;
20
+
23
21
  #[cfg(test)]
24
22
  mod tests;