@@ -29,19 +29,22 @@ devnetGuardianPubKey = "04d4a4629979f0c9fa0f0bb54edf33f87c8c5a1f42c0350a30d68f7e
2929govSetFeeVAA : Bytes
3030govSetFeeVAA = "01000000000100710ab5dcf6885f62016990540e090400f26f41286382dab479a78ed5f85017ff4a562a46379753e94abba1e69b9fec5d1994ac7d9fb145820727df0759bf4f80016553f100000000000001000000000000000000000000000000000000000000000000000000000000000400000000000000010000000000000000000000000000000000000000000000000000000000436f726503004800000000000000000000000000000000000000000000000000000000000003e8"
3131
32- -- | Bootstrap a devnet 'CoreState' as a fresh operator party.
33- setup : Script (Party, ContractId CoreState)
32+ -- | Bootstrap a devnet 'CoreState' as a fresh operator party, allocating the
33+ -- read-only @public@ visibility party that every template observes.
34+ setup : Script (Party, Party, ContractId CoreState)
3435setup = do
3536 operator <- allocateParty "Operator"
37+ public <- allocateParty "Public"
3638 csId <- submit operator do
37- createCmd (mkInitialCoreState operator solanaGovernanceChainId defaultGovernanceContract [devnetGuardian])
38- pure (operator, csId)
39+ createCmd (mkInitialCoreState operator public solanaGovernanceChainId defaultGovernanceContract [devnetGuardian])
40+ pure (operator, public, csId)
3941
4042-- | Register an emitter for @owner@: mints its immutable 'EmitterIdentity' and
41- -- the 'Emitter' bound to it, and returns the 'Emitter' cid.
42- registerEmitter : Party -> Party -> Script (ContractId Emitter)
43- registerEmitter operator owner = do
44- reqId <- submit owner do createCmd EmitterRequest with requester = owner, operator
43+ -- the 'Emitter' bound to it, carrying the @public@ visibility party. Returns the
44+ -- 'Emitter' cid.
45+ registerEmitter : Party -> Party -> Party -> Script (ContractId Emitter)
46+ registerEmitter operator public owner = do
47+ reqId <- submit owner do createCmd EmitterRequest with requester = owner, operator, public
4548 submit operator do exerciseCmd reqId ApproveEmitter
4649
4750-- | Publishing increments the per-emitter sequence and yields the expected
@@ -50,9 +53,9 @@ registerEmitter operator owner = do
5053-- address itself is not stored on-ledger, so there is nothing to assert here.
5154testPublishMessage : Script ()
5255testPublishMessage = do
53- (operator, _) <- setup
56+ (operator, public, _) <- setup
5457 alice <- allocateParty "Alice"
55- emitterId <- registerEmitter operator alice
58+ emitterId <- registerEmitter operator public alice
5659 Some em <- queryContractId alice emitterId
5760
5861 msg0 <- submit alice do
@@ -73,12 +76,41 @@ testPublishMessage = do
7376 msg1.identity === em.identity
7477 pure ()
7578
79+ -- | The @public@ party observes every template, so it can read the full record
80+ -- of the 'CoreState' and each 'Emitter' (including the advanced sequence). A
81+ -- party that is neither a stakeholder nor @public@ sees nothing.
82+ testPublicVisibility : Script ()
83+ testPublicVisibility = do
84+ (operator, public, csId) <- setup
85+ carol <- allocateParty "Carol"
86+ emitterId <- registerEmitter operator public carol
87+ _ <- submit carol do
88+ exerciseCmd emitterId PublishMessage with nonce = 1, payload = "abcd", consistencyLevel = 0
89+
90+ -- public reads the shared config singleton...
91+ [(csId', _)] <- query @CoreState public
92+ csId' === csId
93+ -- ...the recreated emitter with its advanced sequence...
94+ [(_, em)] <- query @Emitter public
95+ em.sequence === 1
96+ -- ...and the emitter's immutable identity.
97+ [(identId, _)] <- query @EmitterIdentity public
98+ em.identity === identId
99+
100+ -- privacy still holds for a party that is neither stakeholder nor public.
101+ outsider <- allocateParty "Outsider"
102+ emsForOutsider <- query @Emitter outsider
103+ length emsForOutsider === 0
104+ csForOutsider <- query @CoreState outsider
105+ length csForOutsider === 0
106+ pure ()
107+
76108-- | Payloads larger than 750 bytes are rejected.
77109testPayloadTooLarge : Script ()
78110testPayloadTooLarge = do
79- (operator, _) <- setup
111+ (operator, public, _) <- setup
80112 bob <- allocateParty "Bob"
81- emitterId <- registerEmitter operator bob
113+ emitterId <- registerEmitter operator public bob
82114 -- 751 bytes = 1502 hex chars.
83115 let bigPayload = mconcat (replicate 1502 "f")
84116 submitMustFail bob do
@@ -97,7 +129,7 @@ testQuorum = do
97129-- | The current guardian set is installed at index 0 and never expires.
98130testInitialGuardianSet : Script ()
99131testInitialGuardianSet = do
100- (operator, csId) <- setup
132+ (operator, _, csId) <- setup
101133 Some cs <- queryContractId operator csId
102134 cs.guardianSetIndex === 0
103135 let gs = fromSome (Map.lookup 0 cs.guardianSets)
@@ -109,7 +141,7 @@ testInitialGuardianSet = do
109141-- exercises the full keccak256 + DER + secp256k1WithEcdsaOnly path.
110142testParseAndVerifyVAA : Script ()
111143testParseAndVerifyVAA = do
112- (operator, csId) <- setup
144+ (operator, _, csId) <- setup
113145 vaa <- submit operator do
114146 exerciseCmd csId ParseAndVerifyVAA with
115147 encodedVAA = govSetFeeVAA
@@ -121,7 +153,7 @@ testParseAndVerifyVAA = do
121153-- | A SetMessageFee governance VAA verifies and updates the message fee.
122154testGovernanceSetMessageFee : Script ()
123155testGovernanceSetMessageFee = do
124- (operator, csId) <- setup
156+ (operator, _, csId) <- setup
125157 newCsId <- submit operator do
126158 exerciseCmd csId SubmitGovernanceVAA with
127159 encodedVAA = govSetFeeVAA
@@ -137,23 +169,23 @@ testGovernanceSetMessageFee = do
137169-- contract-id, which the Go test recomputes to check the mapping.
138170integrationPublish : Script Party
139171integrationPublish = do
140- (operator, _) <- setup
172+ (operator, public, _) <- setup
141173 owner <- allocateParty "IntegrationEmitter"
142- emitterId <- registerEmitter operator owner
174+ emitterId <- registerEmitter operator public owner
143175 _ <- submit owner do
144176 exerciseCmd emitterId PublishMessage with nonce = 42, payload = "11223344", consistencyLevel = 0
145177 pure operator
146178
147179-- | Exercise the auto-generated Archive choice on each template (for coverage).
148180testArchives : Script ()
149181testArchives = do
150- (operator, csId) <- setup
182+ (operator, public, csId) <- setup
151183 submit operator do archiveCmd csId -- Archive CoreState
152184 alice <- allocateParty "ArchAlice"
153- reqId <- submit alice do createCmd EmitterRequest with requester = alice, operator
185+ reqId <- submit alice do createCmd EmitterRequest with requester = alice, operator, public
154186 submit alice do archiveCmd reqId -- Archive EmitterRequest
155187 bob <- allocateParty "ArchBob"
156- emId <- registerEmitter operator bob
188+ emId <- registerEmitter operator public bob
157189 submit operator do archiveCmd emId -- Archive Emitter
158190 -- The immutable identity is normally never archived; exercise it here for
159191 -- coverage (operator is its signatory).
0 commit comments