1use serde::{Deserialize, Serialize};
12use crate::{Address, BlockHeight, Timestamp};
13
14pub type AgreementId = [u8; 32];
20pub type SignatureId = [u8; 32];
22pub type AttestationId = [u8; 32];
24pub type IpAssetId = [u8; 32];
26pub type ExecutorLinkId = [u8; 32];
28pub type PolicyId = [u8; 32];
30pub type ProofId = [u8; 32];
32pub type SubjectId = [u8; 32];
34
35pub const AGREEMENT_DOMAIN_SEP: &[u8] = b"SRC841-AGREEMENT:";
40pub const AGREEMENT_COMMITMENT_SEP: &[u8] = b"SRC841-COMMITMENT:v1:";
41pub const PARTY_COMMITMENT_SEP: &[u8] = b"SRC841-PARTY:v1:";
42pub const SIGNATURE_DOMAIN_SEP: &[u8] = b"SRC842-SIGNATURE:";
43pub const SIGNATURE_MESSAGE_SEP: &[u8] = b"SRC842-SIGN-MSG:v1:";
44pub const ATTESTATION_DOMAIN_SEP: &[u8] = b"SRC843-ATTESTATION:";
45pub const NOTARY_COMMITMENT_SEP: &[u8] = b"SRC843-NOTARY:v1:";
46pub const IP_ACTION_DOMAIN_SEP: &[u8] = b"SRC844-IP-ACTION:";
47pub const IP_SCOPE_COMMITMENT_SEP: &[u8] = b"SRC844-SCOPE:v1:";
48pub const EXECUTOR_LINK_DOMAIN_SEP: &[u8] = b"SRC845-EXECUTOR:";
49pub const TERMS_COMMITMENT_SEP: &[u8] = b"SRC845-TERMS:v1:";
50pub const PROOF_PROFILE_DOMAIN_SEP: &[u8] = b"SRC846-PROOF:";
51
52#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
58pub enum PartyRef {
59 Commitment([u8; 32]),
61 Subject(SubjectId),
63}
64
65impl PartyRef {
66 pub fn generate_commitment(subject: &SubjectId, salt: &[u8; 32]) -> [u8; 32] {
68 let mut hasher = blake3::Hasher::new();
69 hasher.update(PARTY_COMMITMENT_SEP);
70 hasher.update(subject);
71 hasher.update(salt);
72 *hasher.finalize().as_bytes()
73 }
74
75 pub fn as_hash(&self) -> [u8; 32] {
77 match self {
78 PartyRef::Commitment(c) => *c,
79 PartyRef::Subject(s) => *s,
80 }
81 }
82}
83
84#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
86#[repr(u8)]
87pub enum AgreementRole {
88 Buyer = 0,
89 Seller = 1,
90 Employer = 2,
91 Employee = 3,
92 Landlord = 4,
93 Tenant = 5,
94 Licensor = 6,
95 Licensee = 7,
96 Lender = 8,
97 Borrower = 9,
98 Guarantor = 10,
99 Beneficiary = 11,
100 Trustee = 12,
101 Settlor = 13,
102 Assignor = 14,
103 Assignee = 15,
104 Principal = 16,
105 Agent = 17,
106 Partner = 18,
107 Shareholder = 19,
108 Witness = 20,
109 Notary = 21,
110 Mediator = 22,
111 Arbitrator = 23,
112 Other = 255,
113}
114
115#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
117pub struct AttachmentRef {
118 pub payload_hash: [u8; 32],
120 pub payload_size: u64,
122 pub hint_uri: Option<String>,
124 pub encryption_meta: Option<EncryptionMeta>,
126}
127
128#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
130pub struct EncryptionMeta {
131 pub algorithm: EncryptionAlgorithm,
133 pub key_commitment: Option<[u8; 32]>,
135 pub nonce: Option<Vec<u8>>,
137}
138
139#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
141#[repr(u8)]
142pub enum EncryptionAlgorithm {
143 Aes256Gcm = 0,
145 ChaCha20Poly1305 = 1,
147 X25519Aes256Gcm = 2,
149 ThresholdEncryption = 3,
151}
152
153#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
155pub struct PartyBinding {
156 pub party_ref: PartyRef,
158 pub role: AgreementRole,
160 pub signed: bool,
162 pub signed_at: Option<Timestamp>,
164}
165
166#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
168#[repr(u8)]
169pub enum AgreementStatus {
170 Draft = 0,
172 PendingSignatures = 1,
174 Executed = 2,
176 Active = 3,
178 Expired = 4,
180 Terminated = 5,
182 Superseded = 6,
184 Voided = 7,
186}
187
188#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
190pub struct AgreementCommitment {
191 pub agreement_id: AgreementId,
193 pub agreement_commitment: [u8; 32],
195 pub parties: Vec<PartyBinding>,
197 pub jurisdiction_code: String,
199 pub effective_from: Option<Timestamp>,
201 pub expiry: Option<Timestamp>,
203 pub attachments: Vec<AttachmentRef>,
205 pub policy_id: PolicyId,
207 pub status: AgreementStatus,
209 pub created_at: Timestamp,
211 pub updated_at: Timestamp,
213 pub created_at_height: BlockHeight,
215 pub supersedes: Option<AgreementId>,
217}
218
219impl AgreementCommitment {
220 pub fn generate_id(
222 creator: &Address,
223 agreement_commitment: &[u8; 32],
224 nonce: &[u8; 32],
225 ) -> AgreementId {
226 let mut hasher = blake3::Hasher::new();
227 hasher.update(AGREEMENT_DOMAIN_SEP);
228 hasher.update(b":v1:");
229 hasher.update(creator.as_ref());
230 hasher.update(agreement_commitment);
231 hasher.update(nonce);
232 *hasher.finalize().as_bytes()
233 }
234
235 pub fn generate_commitment(
237 terms_data: &[u8],
238 schema_hash: &[u8; 32],
239 version: u32,
240 ) -> [u8; 32] {
241 let mut hasher = blake3::Hasher::new();
242 hasher.update(AGREEMENT_COMMITMENT_SEP);
243 hasher.update(schema_hash);
244 hasher.update(&version.to_le_bytes());
245 hasher.update(terms_data);
246 *hasher.finalize().as_bytes()
247 }
248
249 pub fn is_fully_signed(&self) -> bool {
251 self.parties.iter().all(|p| p.signed)
252 }
253
254 pub fn signed_count(&self) -> usize {
256 self.parties.iter().filter(|p| p.signed).count()
257 }
258}
259
260#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
266pub enum SignatureType {
267 Single,
269 Threshold { threshold: u8, total: u8 },
271 Multi { required: u8 },
273}
274
275#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
277pub struct PartySignature {
278 pub signature_id: SignatureId,
280 pub agreement_id: AgreementId,
282 pub party_ref: PartyRef,
284 pub role: AgreementRole,
286 pub signature_type: SignatureType,
288 pub signature: Vec<u8>,
290 pub signer_key: [u8; 32],
292 pub signed_at: Timestamp,
294 pub recorded_at_height: BlockHeight,
296 pub witness_attestation_id: Option<AttestationId>,
298}
299
300impl PartySignature {
301 pub fn generate_id(
303 agreement_id: &AgreementId,
304 party_ref: &PartyRef,
305 role: AgreementRole,
306 nonce: &[u8; 32],
307 ) -> SignatureId {
308 let mut hasher = blake3::Hasher::new();
309 hasher.update(SIGNATURE_DOMAIN_SEP);
310 hasher.update(b":v1:");
311 hasher.update(agreement_id);
312 hasher.update(&party_ref.as_hash());
313 hasher.update(&[role as u8]);
314 hasher.update(nonce);
315 *hasher.finalize().as_bytes()
316 }
317
318 pub fn generate_signing_message(
320 agreement_id: &AgreementId,
321 agreement_commitment: &[u8; 32],
322 party_ref: &PartyRef,
323 role: AgreementRole,
324 policy_id: &PolicyId,
325 ) -> [u8; 32] {
326 let mut hasher = blake3::Hasher::new();
327 hasher.update(SIGNATURE_MESSAGE_SEP);
328 hasher.update(agreement_id);
329 hasher.update(agreement_commitment);
330 hasher.update(&party_ref.as_hash());
331 hasher.update(&[role as u8]);
332 hasher.update(policy_id);
333 *hasher.finalize().as_bytes()
334 }
335}
336
337#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
343#[repr(u8)]
344pub enum AttestationIssuerClass {
345 NotaryPublic = 0,
347 LawFirm = 1,
349 Auditor = 2,
351 Cpa = 3,
353 CourtOfficial = 4,
355 GovernmentAgency = 5,
357 RegisteredAgent = 6,
359 EscrowAgent = 7,
361 TitleCompany = 8,
363 Other = 255,
365}
366
367#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
369#[repr(u8)]
370pub enum AttestationType {
371 Notarization = 0,
373 SignatureWitness = 1,
375 IdentityVerification = 2,
377 DocumentAuthentication = 3,
379 Apostille = 4,
381 Certification = 5,
383 Acknowledgment = 6,
385 Jurat = 7,
387 CopyCertification = 8,
389}
390
391#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
393#[repr(u8)]
394pub enum AttestationStatus {
395 Active = 0,
396 Expired = 1,
397 Revoked = 2,
398 Superseded = 3,
399}
400
401#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
403pub struct AttestationPacket {
404 pub attestation_id: AttestationId,
406 pub target_ref: AttestationTarget,
408 pub issuer_address: Address,
410 pub issuer_class: AttestationIssuerClass,
412 pub attestation_type: AttestationType,
414 pub notary_commitment: [u8; 32],
416 pub jurisdiction_code: String,
418 pub valid_from: Timestamp,
420 pub expiry: Option<Timestamp>,
422 pub revocation_ref: Option<[u8; 32]>,
424 pub status: AttestationStatus,
426 pub created_at: Timestamp,
428 pub recorded_at_height: BlockHeight,
430 pub policy_id: PolicyId,
432}
433
434#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
436pub enum AttestationTarget {
437 Agreement(AgreementId),
439 DocumentHash([u8; 32]),
441 Signature(SignatureId),
443 IpAction(IpAssetId),
445}
446
447impl AttestationPacket {
448 pub fn generate_id(
450 issuer: &Address,
451 target: &AttestationTarget,
452 attestation_type: AttestationType,
453 nonce: &[u8; 32],
454 ) -> AttestationId {
455 let mut hasher = blake3::Hasher::new();
456 hasher.update(ATTESTATION_DOMAIN_SEP);
457 hasher.update(b":v1:");
458 hasher.update(issuer.as_ref());
459 match target {
460 AttestationTarget::Agreement(id) => {
461 hasher.update(b"agreement:");
462 hasher.update(id);
463 }
464 AttestationTarget::DocumentHash(h) => {
465 hasher.update(b"document:");
466 hasher.update(h);
467 }
468 AttestationTarget::Signature(id) => {
469 hasher.update(b"signature:");
470 hasher.update(id);
471 }
472 AttestationTarget::IpAction(id) => {
473 hasher.update(b"ip_action:");
474 hasher.update(id);
475 }
476 }
477 hasher.update(&[attestation_type as u8]);
478 hasher.update(nonce);
479 *hasher.finalize().as_bytes()
480 }
481
482 pub fn generate_notary_commitment(
484 commission_number: &str,
485 venue: &str,
486 procedure_hash: &[u8; 32],
487 ) -> [u8; 32] {
488 let mut hasher = blake3::Hasher::new();
489 hasher.update(NOTARY_COMMITMENT_SEP);
490 hasher.update(commission_number.as_bytes());
491 hasher.update(venue.as_bytes());
492 hasher.update(procedure_hash);
493 *hasher.finalize().as_bytes()
494 }
495}
496
497#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
503#[repr(u8)]
504pub enum IpActionType {
505 Assignment = 0,
507 License = 1,
509 Pledge = 2,
511 Release = 3,
513 ExclusiveLicense = 4,
515 NonExclusiveLicense = 5,
517 Sublicense = 6,
519 LicenseTermination = 7,
521 PledgeTransfer = 8,
523 PledgeRelease = 9,
525}
526
527#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
529#[repr(u8)]
530pub enum IpAssetType {
531 Patent = 0,
532 Trademark = 1,
533 Copyright = 2,
534 TradeSecret = 3,
535 Design = 4,
536 Software = 5,
537 Database = 6,
538 Domain = 7,
539 Other = 255,
540}
541
542#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
544#[repr(u8)]
545pub enum IpActionStatus {
546 Pending = 0,
547 Active = 1,
548 Expired = 2,
549 Revoked = 3,
550 Superseded = 4,
551 Terminated = 5,
552}
553
554#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
556pub struct IpRightsAction {
557 pub action_id: IpAssetId,
559 pub ip_asset_commitment: [u8; 32],
561 pub asset_type: IpAssetType,
563 pub action_type: IpActionType,
565 pub scope_commitment: [u8; 32],
567 pub rightsholder_ref: PartyRef,
569 pub counterparty_ref: Option<PartyRef>,
571 pub policy_id: PolicyId,
573 pub valid_from: Timestamp,
575 pub expiry: Option<Timestamp>,
577 pub revocation_ref: Option<[u8; 32]>,
579 pub status: IpActionStatus,
581 pub created_at: Timestamp,
583 pub recorded_at_height: BlockHeight,
585 pub agreement_id: Option<AgreementId>,
587 pub attachments: Vec<AttachmentRef>,
589}
590
591impl IpRightsAction {
592 pub fn generate_id(
594 rightsholder: &PartyRef,
595 ip_asset_commitment: &[u8; 32],
596 action_type: IpActionType,
597 nonce: &[u8; 32],
598 ) -> IpAssetId {
599 let mut hasher = blake3::Hasher::new();
600 hasher.update(IP_ACTION_DOMAIN_SEP);
601 hasher.update(b":v1:");
602 hasher.update(&rightsholder.as_hash());
603 hasher.update(ip_asset_commitment);
604 hasher.update(&[action_type as u8]);
605 hasher.update(nonce);
606 *hasher.finalize().as_bytes()
607 }
608
609 pub fn generate_scope_commitment(
611 territory: &str,
612 field_of_use: &str,
613 duration_secs: Option<u64>,
614 additional_terms: Option<&[u8]>,
615 ) -> [u8; 32] {
616 let mut hasher = blake3::Hasher::new();
617 hasher.update(IP_SCOPE_COMMITMENT_SEP);
618 hasher.update(territory.as_bytes());
619 hasher.update(b"|");
620 hasher.update(field_of_use.as_bytes());
621 if let Some(dur) = duration_secs {
622 hasher.update(b"|");
623 hasher.update(&dur.to_le_bytes());
624 }
625 if let Some(terms) = additional_terms {
626 hasher.update(b"|");
627 hasher.update(terms);
628 }
629 *hasher.finalize().as_bytes()
630 }
631}
632
633#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
639#[repr(u8)]
640pub enum ExecutorState {
641 Draft = 0,
643 Active = 1,
645 Paused = 2,
647 Terminated = 3,
649 Completed = 4,
651 Disputed = 5,
653}
654
655#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
657pub struct ExecutorLink {
658 pub link_id: ExecutorLinkId,
660 pub agreement_id: AgreementId,
662 pub executor_contract: Address,
664 pub executor_interface_id: [u8; 32],
666 pub terms_commitment: [u8; 32],
668 pub activation_policy_id: PolicyId,
670 pub state: ExecutorState,
672 pub created_at: Timestamp,
674 pub updated_at: Timestamp,
676 pub created_at_height: BlockHeight,
678 pub activation_proof_id: Option<ProofId>,
680}
681
682impl ExecutorLink {
683 pub fn generate_id(
685 agreement_id: &AgreementId,
686 executor_contract: &Address,
687 nonce: &[u8; 32],
688 ) -> ExecutorLinkId {
689 let mut hasher = blake3::Hasher::new();
690 hasher.update(EXECUTOR_LINK_DOMAIN_SEP);
691 hasher.update(b":v1:");
692 hasher.update(agreement_id);
693 hasher.update(executor_contract.as_ref());
694 hasher.update(nonce);
695 *hasher.finalize().as_bytes()
696 }
697
698 pub fn generate_terms_commitment(
700 terms_data: &[u8],
701 executor_interface_id: &[u8; 32],
702 ) -> [u8; 32] {
703 let mut hasher = blake3::Hasher::new();
704 hasher.update(TERMS_COMMITMENT_SEP);
705 hasher.update(executor_interface_id);
706 hasher.update(terms_data);
707 *hasher.finalize().as_bytes()
708 }
709}
710
711#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
717#[repr(u8)]
718pub enum AgreementProofProfile {
719 SignedByRoles = 0,
721 NotaryAttested = 1,
723 IpAssignmentValid = 2,
725 ExecutorBoundActive = 3,
727 PartyBound = 4,
729 AgreementStatus = 5,
731}
732
733#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
735#[repr(u8)]
736pub enum AgreementProofType {
737 Mock = 0,
739 Groth16 = 1,
741 Plonk = 2,
743 ThresholdSignature = 3,
745 MerkleInclusion = 4,
747}
748
749#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
751pub struct AgreementProofEnvelope {
752 pub proof_id: ProofId,
754 pub profile: AgreementProofProfile,
756 pub profile_id: String,
758 pub policy_ids: Vec<PolicyId>,
760 pub public_inputs: Vec<u8>,
762 pub proof_data: Vec<u8>,
764 pub proof_type: AgreementProofType,
766 pub subject_nullifier: [u8; 32],
768 pub generated_at: Timestamp,
770 pub expires_at: Timestamp,
772}
773
774impl AgreementProofEnvelope {
775 pub fn generate_id(
777 profile: AgreementProofProfile,
778 subject_nullifier: &[u8; 32],
779 policy_ids: &[PolicyId],
780 nonce: &[u8; 32],
781 ) -> ProofId {
782 let mut hasher = blake3::Hasher::new();
783 hasher.update(PROOF_PROFILE_DOMAIN_SEP);
784 hasher.update(b":v1:");
785 hasher.update(&[profile as u8]);
786 hasher.update(subject_nullifier);
787 for policy_id in policy_ids {
788 hasher.update(policy_id);
789 }
790 hasher.update(nonce);
791 *hasher.finalize().as_bytes()
792 }
793}
794
795#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
801#[repr(u8)]
802pub enum AgreementOperation {
803 CommitAgreement = 0,
805 UpdateAgreement = 1,
806 TerminateAgreement = 2,
807 VoidAgreement = 3,
808 SupersedeAgreement = 4,
809
810 SignAgreement = 10,
812 RevokeSignature = 11,
813 AddParty = 12,
814 RemoveParty = 13,
815
816 CreateAttestation = 20,
818 RevokeAttestation = 21,
819 UpdateAttestationStatus = 22,
820
821 RecordIpAction = 30,
823 UpdateIpAction = 31,
824 TerminateIpAction = 32,
825 RevokeIpAction = 33,
826
827 LinkExecutor = 40,
829 ActivateExecutor = 41,
830 PauseExecutor = 42,
831 ResumeExecutor = 43,
832 TerminateExecutor = 44,
833 CompleteExecutor = 45,
834
835 SubmitProof = 50,
837 VerifyProof = 51,
838}
839
840#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
842pub struct AgreementTxData {
843 pub operation: AgreementOperation,
844 pub data: Vec<u8>,
845 pub recipient: crate::Address,
847}
848
849#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
855pub enum AgreementEvent {
856 AgreementCommitted {
858 agreement_id: AgreementId,
859 policy_id: PolicyId,
860 commitment_hash: [u8; 32],
861 timestamp: Timestamp,
862 },
863 AgreementUpdated {
864 agreement_id: AgreementId,
865 new_status: AgreementStatus,
866 timestamp: Timestamp,
867 },
868 AgreementTerminated {
869 agreement_id: AgreementId,
870 timestamp: Timestamp,
871 },
872 AgreementSuperseded {
873 old_agreement_id: AgreementId,
874 new_agreement_id: AgreementId,
875 timestamp: Timestamp,
876 },
877
878 AgreementSigned {
880 agreement_id: AgreementId,
881 party_ref_hash: [u8; 32],
882 role: AgreementRole,
883 signer: Address,
884 timestamp: Timestamp,
885 },
886 SignatureRevoked {
887 agreement_id: AgreementId,
888 signature_id: SignatureId,
889 timestamp: Timestamp,
890 },
891
892 NotaryAttested {
894 target_id: [u8; 32],
895 notary: Address,
896 attestation_hash: [u8; 32],
897 timestamp: Timestamp,
898 },
899 AttestationRevoked {
900 attestation_id: AttestationId,
901 timestamp: Timestamp,
902 },
903
904 IpActionRecorded {
906 ip_asset_hash: [u8; 32],
907 action_type: IpActionType,
908 policy_id: PolicyId,
909 timestamp: Timestamp,
910 },
911 IpActionUpdated {
912 action_id: IpAssetId,
913 new_status: IpActionStatus,
914 timestamp: Timestamp,
915 },
916
917 ExecutorLinked {
919 agreement_id: AgreementId,
920 executor: Address,
921 interface_id: [u8; 32],
922 state: ExecutorState,
923 timestamp: Timestamp,
924 },
925 ExecutorStateUpdated {
926 agreement_id: AgreementId,
927 link_id: ExecutorLinkId,
928 new_state: ExecutorState,
929 timestamp: Timestamp,
930 },
931
932 ProofSubmitted {
934 proof_id: ProofId,
935 profile: AgreementProofProfile,
936 timestamp: Timestamp,
937 },
938 ProofVerified {
939 proof_id: ProofId,
940 valid: bool,
941 timestamp: Timestamp,
942 },
943}
944
945#[cfg(test)]
946mod tests {
947 use super::*;
948
949 #[test]
950 fn test_party_ref_commitment() {
951 let subject = [1u8; 32];
952 let salt = [2u8; 32];
953 let commitment = PartyRef::generate_commitment(&subject, &salt);
954 assert_ne!(commitment, [0u8; 32]);
955
956 let salt2 = [3u8; 32];
958 let commitment2 = PartyRef::generate_commitment(&subject, &salt2);
959 assert_ne!(commitment, commitment2);
960 }
961
962 #[test]
963 fn test_agreement_id_generation() {
964 let creator = Address::new([1u8; 20]);
965 let commitment = [2u8; 32];
966 let nonce = [3u8; 32];
967
968 let id = AgreementCommitment::generate_id(&creator, &commitment, &nonce);
969 assert_ne!(id, [0u8; 32]);
970
971 let id2 = AgreementCommitment::generate_id(&creator, &commitment, &nonce);
973 assert_eq!(id, id2);
974 }
975
976 #[test]
977 fn test_signing_message_domain_separation() {
978 let agreement_id = [1u8; 32];
979 let commitment = [2u8; 32];
980 let party_ref = PartyRef::Commitment([3u8; 32]);
981 let policy_id = [4u8; 32];
982
983 let msg1 = PartySignature::generate_signing_message(
984 &agreement_id,
985 &commitment,
986 &party_ref,
987 AgreementRole::Buyer,
988 &policy_id,
989 );
990
991 let msg2 = PartySignature::generate_signing_message(
993 &agreement_id,
994 &commitment,
995 &party_ref,
996 AgreementRole::Seller,
997 &policy_id,
998 );
999
1000 assert_ne!(msg1, msg2);
1001 }
1002
1003 #[test]
1004 fn test_attestation_id_generation() {
1005 let issuer = Address::new([1u8; 20]);
1006 let target = AttestationTarget::Agreement([2u8; 32]);
1007 let nonce = [3u8; 32];
1008
1009 let id = AttestationPacket::generate_id(
1010 &issuer,
1011 &target,
1012 AttestationType::Notarization,
1013 &nonce,
1014 );
1015 assert_ne!(id, [0u8; 32]);
1016 }
1017
1018 #[test]
1019 fn test_ip_scope_commitment() {
1020 let commitment = IpRightsAction::generate_scope_commitment(
1021 "US",
1022 "software",
1023 Some(31536000),
1024 None,
1025 );
1026 assert_ne!(commitment, [0u8; 32]);
1027 }
1028
1029 #[test]
1030 fn test_executor_terms_commitment() {
1031 let terms = b"escrow terms here";
1032 let interface = [1u8; 32];
1033
1034 let commitment = ExecutorLink::generate_terms_commitment(terms, &interface);
1035 assert_ne!(commitment, [0u8; 32]);
1036 }
1037}