hello_soroban_kit/
lib.rs

1/*
2    Copyright (c) 2023-2024 Frederic Kyung-jin Rezeau (오경진 吳景振)
3
4    This file is part of soroban-kit.
5
6    Licensed under the MIT License, this software is provided "AS IS",
7    no liability assumed. For details, see the LICENSE file in the
8    root directory.
9
10    Author: Fred Kyung-jin Rezeau <fred@litemint.com>
11*/
12
13#![no_std]
14
15mod examples; // Examples module.
16mod types; // Contract types.
17
18use examples::{example_circuit_breaker, example_rock_paper_scissors, example_storage};
19
20use soroban_kit::{oracle, oracle_subscriber, storage};
21use soroban_sdk::{contract, contractimpl, Address, Bytes, Env, Symbol, Vec};
22
23use types::{Message, MessageKey, Whitelist, WhitelistKey};
24
25pub trait HelloContractTrait {
26    fn circuit_breaker(env: Env) -> Symbol;
27    fn rock_paper_scissors(env: Env) -> Symbol;
28    fn hello_oracle(env: Env, topic: Bytes) -> Message;
29    fn whitelist_broker(env: Env, broker: Address);
30    fn hello(env: Env, newcomer: Symbol) -> Vec<Symbol>;
31}
32
33#[contract]
34// Implement the Oracle Subscriber interface for the contract.
35// We use `bytes` (native type) for the topic and a custom type `Message`
36// for the data.
37#[oracle_subscriber(Bytes, Message)]
38pub struct HelloContract;
39
40// Implement the Oracle events.
41impl oracle::Events<Bytes, Message> for HelloContract {
42    // This event fires before the call to oracle broker subscribe().
43    fn on_request(env: &Env, _topic: &Bytes, envelope: &oracle::Envelope) {
44        // Example: whitelist brokers allowed to interact with your contract.
45        assert_eq!(
46            storage::get(&env, &WhitelistKey::Broker).unwrap().broker,
47            envelope.broker
48        );
49        envelope.subscriber.require_auth();
50    }
51
52    // This event fires when the data is received synchronously.
53    fn on_sync_receive(env: &Env, topic: &Bytes, envelope: &oracle::Envelope, data: &Message) {
54        assert_eq!(
55            storage::get(&env, &WhitelistKey::Broker).unwrap().broker,
56            envelope.broker
57        );
58        storage::set(&env, &MessageKey::Topic(topic.clone()), &data);
59    }
60
61    // This event fires when the data is received asynchronously.
62    fn on_async_receive(env: &Env, topic: &Bytes, envelope: &oracle::Envelope, data: &Message) {
63        // Only allow whitelisted broker.
64        assert_eq!(
65            storage::get(&env, &WhitelistKey::Broker).unwrap().broker,
66            envelope.broker
67        );
68        // Make sure the broker is authorized (i.e., made the cross-contract call).
69        envelope.broker.require_auth();
70        // Set the data.
71        storage::set(&env, &MessageKey::Topic(topic.clone()), &data);
72    }
73}
74
75#[contractimpl]
76impl HelloContractTrait for HelloContract {
77    // Example implementing a pausable activity with
78    // soroban-kit `circuit-breaker`, `when_opened` and `when_closed` attr. macros.
79    fn circuit_breaker(env: Env) -> Symbol {
80        example_circuit_breaker::hello(env)
81    }
82
83    // Example implementing "rock paper scissors" with
84    // soroban-kit `state-machine`, `commit` and `reveal` attr. macros.
85    fn rock_paper_scissors(env: Env) -> Symbol {
86        example_rock_paper_scissors::hello(env)
87    }
88
89    // Example retrieving a message received from an oracle.
90    fn hello_oracle(env: Env, topic: Bytes) -> Message {
91        storage::get(&env, &MessageKey::Topic(topic)).unwrap()
92    }
93
94    fn whitelist_broker(env: Env, broker: Address) {
95        assert!(!storage::has(&env, &WhitelistKey::Broker));
96        storage::set(&env, &WhitelistKey::Broker, &Whitelist { broker });
97    }
98
99    // Example saying hello with soroban-kit type safe `storage` attr. macros.
100    fn hello(env: Env, newcomer: Symbol) -> Vec<Symbol> {
101        example_storage::hello(env, newcomer)
102    }
103}
104
105#[cfg(test)]
106mod test;