commit 8c49343202050d2411d912760d778dcdbf530aa9
parent d5174a7acaad0a395bbbd48b4e8ab29176eed2ee
Author: nolash <dev@holbrook.no>
Date:   Sat,  8 May 2021 07:34:58 +0200
Implement operator
Diffstat:
2 files changed, 102 insertions(+), 2 deletions(-)
diff --git a/python/eth_devbadge/token.py b/python/eth_devbadge/token.py
@@ -95,6 +95,28 @@ class BadgeToken(TxFactory):
         return tx
 
 
+    def set_approve_for_all(self, contract_address, sender_address, operator_address, flag, tx_format=TxFormat.JSONRPC):
+        enc = ABIContractEncoder()
+        enc.method('setApprovalForAll')
+        enc.typ(ABIContractType.ADDRESS)
+        enc.typ(ABIContractType.BOOLEAN)
+        enc.address(operator_address)
+        enc.uint256(int(flag))
+        data = enc.get()
+        tx = self.template(sender_address, contract_address, use_nonce=True)
+        tx = self.set_code(tx, data)
+        tx = self.finalize(tx, tx_format)
+        return tx
+
+    
+    def set_operator(self, contract_address, sender_address, operator_address, tx_format=TxFormat.JSONRPC):
+        return self.set_approve_for_all(contract_address, sender_address, operator_address, True, tx_format=tx_format)
+
+
+    def remove_operator(self, contract_address, sender_address, operator_address, tx_format=TxFormat.JSONRPC):
+        return self.set_approve_for_all(contract_address, sender_address, operator_address, False, tx_format=tx_format)
+
+
     def token_by_index(self, contract_address, idx, sender_address=ZERO_ADDRESS):
         o = jsonrpc_template()
         o['method'] = 'eth_call'
@@ -125,6 +147,27 @@ class BadgeToken(TxFactory):
         return o
 
 
+    def is_approved_for_all(self, contract_address, holder_address, operator_address, sender_address=ZERO_ADDRESS):
+        o = jsonrpc_template()
+        o['method'] = 'eth_call'
+        enc = ABIContractEncoder()
+        enc.method('isApprovedForAll')
+        enc.typ(ABIContractType.ADDRESS)
+        enc.typ(ABIContractType.ADDRESS)
+        enc.address(holder_address)
+        enc.address(operator_address)
+        data = add_0x(enc.get())
+        tx = self.template(sender_address, contract_address)
+        tx = self.set_code(tx, data)
+        o['params'].append(self.normalize(tx))
+        o['params'].append('latest')
+        return o
+
+
+    def is_operator(self, contract_address, token_id, operator_address, sender_address=ZERO_ADDRESS):
+        return self.is_approved_for_all(contract_address, token_id, operator_address, sender_address=sender_address)
+
+
     def token_of_owner_by_index(self, contract_address, holder_address, idx, sender_address=ZERO_ADDRESS):
         o = jsonrpc_template()
         o['method'] = 'eth_call'
@@ -175,3 +218,11 @@ class BadgeToken(TxFactory):
         return abi_decode_single(ABIContractType.UINT256, v)
 
 
+    @classmethod
+    def parse_is_approved_for_all(self, v):
+        return abi_decode_single(ABIContractType.BOOLEAN, v)
+
+
+    @classmethod
+    def parse_is_operator(self, v):
+        return self.parse_is_approved_for_all(v)
diff --git a/python/tests/test_app.py b/python/tests/test_app.py
@@ -94,6 +94,55 @@ class Test(EthTesterCase):
         r = self.rpc.do(o)
         self.assertEqual(token_bytes.hex(), strip_0x(r))
 
+    
+    def test_operator(self):
+        token_bytes = b'\xee' * 32
+        token_id = int.from_bytes(token_bytes, byteorder='big')
+        c = self._mint(self.accounts[1], token_id)
+
+        nonce_oracle = RPCNonceOracle(self.accounts[1], self.rpc)
+        c = BadgeToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+        (tx_hash_hex, o) = c.set_operator(self.address, self.accounts[1], self.accounts[2])
+        r = self.rpc.do(o)
+
+        o = receipt(tx_hash_hex)
+        r = self.conn.do(o)
+        self.assertEqual(r['status'], 1)
+
+        o = c.is_operator(self.address, self.accounts[1], self.accounts[2], sender_address=self.accounts[0])
+        r = self.rpc.do(o)
+        isop = c.parse_is_operator(r)
+        self.assertTrue(isop)
+
+        (tx_hash_hex, o) = c.remove_operator(self.address, self.accounts[1], self.accounts[2])
+        r = self.rpc.do(o)
+
+        o = receipt(tx_hash_hex)
+        r = self.conn.do(o)
+        self.assertEqual(r['status'], 1)
+
+        o = c.is_operator(self.address, self.accounts[1], self.accounts[2], sender_address=self.accounts[0])
+        r = self.rpc.do(o)
+        isop = c.parse_is_operator(r)
+        self.assertFalse(isop)
+
+        (tx_hash_hex, o) = c.set_operator(self.address, self.accounts[1], self.accounts[2])
+        r = self.rpc.do(o)
+
+        nonce_oracle = RPCNonceOracle(self.accounts[2], self.rpc)
+        c = BadgeToken(self.chain_spec, signer=self.signer, nonce_oracle=nonce_oracle)
+        (tx_hash_hex, o) = c.transfer_from(self.address, self.accounts[2], self.accounts[1], self.accounts[3], token_id)
+        r = self.rpc.do(o)
+
+        o = receipt(tx_hash_hex)
+        r = self.conn.do(o)
+        self.assertEqual(r['status'], 1)
+
+        o = c.owner_of(self.address, token_id, sender_address=self.accounts[0])
+        r = self.rpc.do(o)
+        owner_address = c.parse_owner_of(r)
+        self.assertEqual(owner_address, self.accounts[3])
+
 
     def test_transfer(self):
         token_bytes = b'\xee' * 32
@@ -113,10 +162,10 @@ class Test(EthTesterCase):
         with self.assertRaises(JSONRPCException):
             r = self.rpc.do(o)
 
-
         o = c.token_of_owner_by_index(self.address, self.accounts[2], 0, sender_address=self.accounts[0])
         r = self.rpc.do(o)
         self.assertEqual(token_bytes.hex(), strip_0x(r))
-       
+      
+
 if __name__ == '__main__':
     unittest.main()