1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::engine::scrypto_env::ScryptoVmV1Api;
use crate::prelude::{scrypto_encode, ScryptoEncode, ScryptoSbor};
use crate::runtime::*;
use crate::*;
use radix_engine_interface::data::scrypto::{scrypto_decode, ScryptoDecode};
use radix_engine_interface::types::*;
use sbor::rust::prelude::*;

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, ScryptoSbor)]
pub enum ObjectStubHandle {
    Own(Own),
    Global(GlobalAddress),
}

impl ObjectStubHandle {
    pub fn as_node_id(&self) -> &NodeId {
        match self {
            ObjectStubHandle::Own(own) => own.as_node_id(),
            ObjectStubHandle::Global(address) => address.as_node_id(),
        }
    }
}

pub trait ObjectStub: Copy {
    type AddressType: TryFrom<[u8; NodeId::LENGTH]>;

    fn new(handle: ObjectStubHandle) -> Self;

    fn handle(&self) -> &ObjectStubHandle;

    fn call<A: ScryptoEncode, T: ScryptoDecode>(&self, method: &str, args: &A) -> T {
        let output = ScryptoVmV1Api::object_call(
            self.handle().as_node_id(),
            method,
            scrypto_encode(args).unwrap(),
        );
        scrypto_decode(&output).unwrap()
    }

    fn call_ignore_rtn<A: ScryptoEncode>(&self, method: &str, args: &A) {
        ScryptoVmV1Api::object_call(
            self.handle().as_node_id(),
            method,
            scrypto_encode(args).unwrap(),
        );
    }

    fn call_raw<T: ScryptoDecode>(&self, method: &str, args: Vec<u8>) -> T {
        let output = ScryptoVmV1Api::object_call(self.handle().as_node_id(), method, args);
        scrypto_decode(&output).unwrap()
    }

    fn instance_of(&self, blueprint_id: &BlueprintId) -> bool {
        ScryptoVmV1Api::object_instance_of(self.handle().as_node_id(), blueprint_id)
    }

    fn blueprint_id(&self) -> BlueprintId {
        ScryptoVmV1Api::object_get_blueprint_id(self.handle().as_node_id())
    }
}