@@ -101,6 +101,40 @@ message OpenExplorerUiResponse {
101101 OpenExplorerUiResult open_result = 1 ;
102102}
103103
104+ // Verdict of an OpenItemPurchase request. Values are prefixed because proto3 enum values are siblings
105+ // of their enum, so bare names would collide with OpenExplorerUiResult above.
106+ //
107+ // Deliberately coarse: a purchase that could not be completed is always OIP_FAILED, never a reason.
108+ // Reporting "insufficient credits" separately would let scene code probe a wallet's balance by
109+ // offering items at different prices, and the client already tells the player what happened.
110+ enum OpenItemPurchaseResult {
111+ OIP_UNSPECIFIED = 0 ;
112+ OIP_PURCHASED = 1 ; // the purchase was confirmed and its transaction was broadcast
113+ OIP_DISMISSED = 2 ; // the player closed the confirmation without buying
114+ OIP_REJECTED_NOT_CURRENT_SCENE = 3 ; // the standard restricted-actions current-scene gate rejected the call
115+ OIP_REJECTED_NO_USER_GESTURE = 4 ; // rejected: the call did not originate from a user gesture
116+ OIP_REJECTED_FEATURE_DISABLED = 5 ; // in-world purchases are unavailable for this player or client
117+ OIP_REJECTED_NOT_PURCHASABLE = 6 ; // no listing for that urn: sold out, never listed, or not a collection item
118+ OIP_FAILED = 7 ;
119+ }
120+
121+ message OpenItemPurchaseRequest {
122+ // The item to offer, e.g. urn:decentraland:matic:collections-v2:0x<contract>:<itemId>.
123+ //
124+ // The URN is the ONLY thing the scene supplies: the client resolves the price from the catalog,
125+ // signs and runs its own confirmation. A scene-supplied price would let it overcharge the player,
126+ // and a scene-supplied transaction could redirect the payment.
127+ string urn = 1 ;
128+
129+ // Extension point for future fields (e.g. a quantity, or a campaign id for attribution) without
130+ // touching existing ones. Quantity is absent on purpose: one offer, one confirmation.
131+ }
132+
133+ message OpenItemPurchaseResponse {
134+ // Carries only the verdict. Nothing about price, credit or transaction reaches the scene.
135+ OpenItemPurchaseResult result = 1 ;
136+ }
137+
104138service RestrictedActionsService {
105139 // MovePlayerTo will move the player to a position relative to the current scene.
106140 // If 'duration' field is used in the request, the success response depends on the
@@ -137,4 +171,8 @@ service RestrictedActionsService {
137171
138172 // OpenExplorerUi opens a specific fullscreen explorer panel and returns the open verdict.
139173 rpc OpenExplorerUi (OpenExplorerUiRequest ) returns (OpenExplorerUiResponse ) {}
174+
175+ // OpenItemPurchase asks the client to offer a marketplace item for sale in-world, running its own
176+ // price resolution and confirmation, and returns the verdict so the scene can react.
177+ rpc OpenItemPurchase (OpenItemPurchaseRequest ) returns (OpenItemPurchaseResponse ) {}
140178}
0 commit comments