oli-python 2.0.5__tar.gz → 2.0.7__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oli-python
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: Python SDK for interacting with the Open Labels Initiative; A standard, registry and trust layer for EVM address labels.
5
5
  Home-page: https://github.com/openlabelsinitiative/oli-python
6
6
  Author: Lorenz Lehmann
@@ -41,12 +41,15 @@ class OffchainAttestations:
41
41
  else:
42
42
  print("Warning: OLI tag definitions not loaded, skipping tag formatting and validation. Please upgrade to the latest OLI version and ensure internet connectivity at initialization.")
43
43
 
44
+ # Merge chain_id (CAIP2) & address to CAIP10 format
45
+ caip10 = f"{chain_id}:{address}"
46
+
44
47
  # Encode the label data
45
- data = self.oli.utils_other.encode_label_data(chain_id, tags)
48
+ data = self.oli.utils_other.encode_label_data(caip10, tags)
46
49
 
47
50
  # Build the attestation
48
51
  attestation = self.build_offchain_attestation(
49
- recipient=address,
52
+ recipient="0x0000000000000000000000000000000000000001", # use 0x...1 to track python tooling was used
50
53
  schema=self.oli.oli_label_pool_schema,
51
54
  data=data,
52
55
  ref_uid=ref_uid
@@ -108,12 +111,15 @@ class OffchainAttestations:
108
111
  else:
109
112
  print("Warning: OLI tag definitions not loaded, skipping tag formatting and validation. Please upgrade to the latest OLI version and ensure internet connectivity at initialization.")
110
113
 
114
+ # Merge chain_id (CAIP2) & address to CAIP10 format
115
+ caip10 = f"{chain_id}:{address}"
116
+
111
117
  # Encode the label data
112
- data = self.oli.utils_other.encode_label_data(chain_id, tags)
113
-
118
+ data = self.oli.utils_other.encode_label_data(caip10, tags)
119
+
114
120
  # Build the attestation
115
121
  attestation = self.build_offchain_attestation(
116
- recipient=address,
122
+ recipient="0x0000000000000000000000000000000000000001", # use 0x...1 to track python tooling was used
117
123
  schema=self.oli.oli_label_pool_schema,
118
124
  data=data,
119
125
  ref_uid=ref_uid
@@ -164,10 +170,9 @@ class OffchainAttestations:
164
170
  data = self.oli.utils_other.encode_list_data(owner_name, attesters, attestations)
165
171
 
166
172
  # Build the attestation
167
- recipient = "0x0000000000000000000000000000000000000000"
168
173
  ref_uid = "0x0000000000000000000000000000000000000000000000000000000000000000"
169
174
  attestation = self.build_offchain_attestation(
170
- recipient=recipient,
175
+ recipient="0x0000000000000000000000000000000000000001", # use 0x...1 to track python tooling was used
171
176
  schema=self.oli.oli_label_trust_schema,
172
177
  data=data,
173
178
  ref_uid=ref_uid
@@ -18,7 +18,7 @@ class OnchainAttestations:
18
18
  chain_id (str): Chain ID in CAIP-2 format where the address/contract resides
19
19
  tags (dict): OLI compliant tags as a dict information (name, version, etc.)
20
20
  ref_uid (str): Reference UID
21
- gas_limit (int): Gas limit for the transaction. If set to -1, the function will estimate the gas limit.
21
+ gas_limit (int): Gas limit for the transaction. If set to -1, the function will estimate the gas limit
22
22
 
23
23
  Returns:
24
24
  str: Transaction hash
@@ -36,14 +36,17 @@ class OnchainAttestations:
36
36
  else:
37
37
  print("Warning: OLI tag definitions not loaded, skipping tag formatting and validation. Please upgrade to the latest OLI version and ensure internet connectivity at initialization.")
38
38
 
39
+ # Prepare CAIP10 format for the address
40
+ caip10 = f"{chain_id}:{address}"
41
+
39
42
  # Encode the label data
40
- data = self.oli.utils_other.encode_label_data(chain_id, tags)
43
+ data = self.oli.utils_other.encode_label_data(caip10, tags)
41
44
 
42
45
  # Create the attestation
43
46
  function = self.oli.eas.functions.attest({
44
47
  'schema': self.oli.w3.to_bytes(hexstr=self.oli.oli_label_pool_schema),
45
48
  'data': {
46
- 'recipient': self.oli.w3.to_checksum_address(address),
49
+ 'recipient': "0x0000000000000000000000000000000000000001", # use 0x...1 to track python tooling was used
47
50
  'expirationTime': 0,
48
51
  'revocable': True,
49
52
  'refUID': self.oli.w3.to_bytes(hexstr=ref_uid),
@@ -128,10 +131,13 @@ class OnchainAttestations:
128
131
  else:
129
132
  self.oli.validator.validate_ref_uid(label['ref_uid'])
130
133
 
134
+ # Merge chain_id (CAIP2) & address to CAIP10 format
135
+ caip10 = f"{label['chain_id']}:{label['address']}"
136
+
131
137
  # ABI encode data for each attestation
132
- data = self.oli.utils_other.encode_label_data(label['chain_id'], label['tags'])
138
+ data = self.oli.utils_other.encode_label_data(caip10, label['tags'])
133
139
  full_data.append({
134
- 'recipient': self.oli.w3.to_checksum_address(label['address']),
140
+ 'recipient': "0x0000000000000000000000000000000000000001", # use 0x...1 to track python tooling was used
135
141
  'expirationTime': 0,
136
142
  'revocable': True,
137
143
  'refUID': self.oli.w3.to_bytes(hexstr=label['ref_uid']),
@@ -206,7 +212,7 @@ class OnchainAttestations:
206
212
  function = self.oli.eas.functions.attest({
207
213
  'schema': self.oli.w3.to_bytes(hexstr=self.oli.oli_label_trust_schema),
208
214
  'data': {
209
- 'recipient': "0x0000000000000000000000000000000000000000", # Trust lists are not tied to a specific address
215
+ 'recipient': "0x0000000000000000000000000000000000000001", # Trust lists are not tied to a specific address, use 0x...1 to track python tooling was used
210
216
  'expirationTime': 0, # never expires
211
217
  'revocable': True, # can be revoked
212
218
  'refUID': "0x0000000000000000000000000000000000000000000000000000000000000000", # no ref UID for trust lists
@@ -13,12 +13,12 @@ class UtilsOther:
13
13
  """
14
14
  self.oli = oli_client
15
15
 
16
- def encode_label_data(self, chain_id: str, tags_json: dict) -> str:
16
+ def encode_label_data(self, caip10: str, tags_json: dict) -> str:
17
17
  """
18
18
  Encode label data in the OLI format.
19
19
 
20
20
  Args:
21
- chain_id (str): Chain ID in CAIP-2 format of the label (e.g. 'eip155:8453')
21
+ caip10 (str): address and chain_id in caip10 format (e.g. 'eip155:8453:0x3Ae5F83668B75328446c649B6ab342aC46D73B3c')
22
22
  tags_json (dict): Dictionary of tag data following the OLI format
23
23
 
24
24
  Returns:
@@ -27,9 +27,15 @@ class UtilsOther:
27
27
  # Convert dict to JSON string if needed
28
28
  if isinstance(tags_json, dict):
29
29
  tags_json = json.dumps(tags_json)
30
+
31
+ # Convert address to checksum if possible
32
+ try:
33
+ caip10 = caip10[:caip10.rfind(":")+1] + self.oli.w3.to_checksum_address(caip10.split(":")[-1])
34
+ except:
35
+ pass
30
36
 
31
37
  # ABI encode the data
32
- encoded_data = encode(['string', 'string'], [chain_id, tags_json])
38
+ encoded_data = encode(['string', 'string'], [caip10, tags_json])
33
39
  return f"0x{encoded_data.hex()}"
34
40
 
35
41
  def encode_list_data(self, owner: str, trusted: list, untrusted: list) -> str:
@@ -7,20 +7,13 @@ class UtilsValidator:
7
7
  oli_client: The OLI client instance
8
8
  """
9
9
  self.oli = oli_client
10
- self.allowed_prefixes = [
11
- 'eip155:', # Ethereum and EVM-compatible chains
12
- 'solana:', # Solana
13
- 'tron:', # TRON
14
- 'stellar:', # Stellar
15
- 'bip122:', # Bitcoin
16
- 'SN_MAIN' # Starknet
17
- ]
18
10
  # URLs for helpful resources
19
11
  self.url_1_label_schema = "https://github.com/openlabelsinitiative/OLI/tree/main/1_label_schema"
20
12
  self.url_2_label_pool = "https://github.com/openlabelsinitiative/OLI/tree/main/2_label_pool"
21
13
  self.url_3_label_trust = "https://github.com/openlabelsinitiative/OLI/tree/main/3_label_trust"
22
14
  self.url_tag_definitions = "https://github.com/openlabelsinitiative/OLI/blob/main/1_label_schema/tags/tag_definitions.yml"
23
15
  self.url_caip2_format = "https://docs.portalhq.io/resources/chain-id-formatting"
16
+ self.url_caip10_format = "https://github.com/ChainAgnostic/CAIPs/blob/main/CAIPs/caip-10.md"
24
17
 
25
18
  def fix_simple_tags_formatting(self, tags: dict) -> dict:
26
19
  """
@@ -97,7 +90,7 @@ class UtilsValidator:
97
90
  Validates if the label is compliant with the OLI Label Schema. See OLI Github documentation for more details: https://github.com/openlabelsinitiative/OLI/tree/main/1_label_schema
98
91
 
99
92
  Args:
100
- address (str): Address to check
93
+ address (str): Address that is labelled to check
101
94
  chain_id (str): Chain ID to check
102
95
  tags (dict): Tags to check
103
96
  ref_uid (str): Reference UID to check
@@ -107,7 +100,7 @@ class UtilsValidator:
107
100
  bool: True if the label is correct, False otherwise
108
101
  """
109
102
  # basic checks
110
- self.validate_address(address)
103
+ self.validate_address_to_be_labelled(address)
111
104
  self.validate_chain_id(chain_id)
112
105
  self.validate_tags(tags, auto_fix=auto_fix)
113
106
  self.validate_ref_uid(ref_uid)
@@ -145,25 +138,25 @@ class UtilsValidator:
145
138
  Returns:
146
139
  bool: True if correct, False otherwise
147
140
  """
148
- # Check if the chain_id starts with any of the allowed prefixes
149
- for prefix in self.allowed_prefixes:
150
- if chain_id.startswith(prefix):
151
- # For eip155, further validate that the rest is a number or 'any'
152
- if prefix == 'eip155:':
153
- rest = chain_id[len(prefix):]
154
- if rest.isdigit():
155
- return True
156
- elif rest == 'any':
157
- print("Please ensure the label is accurate and consistent across all EVM chains before setting chain_id = 'eip155:any'.")
158
- return True
159
- else:
160
- print(f"Invalid eip155 chain_id format: {chain_id}")
161
- raise ValueError("For eip155 chains, format must be 'eip155:' followed by a number or 'any'")
162
- return True
141
+ # Check if the chain_id has one ":" in it which is not at the start or end
142
+ if ":" in chain_id and chain_id.count(":") == 1 and chain_id.find(":") != 0 and chain_id.find(":") != len(chain_id)-1:
143
+ prefix = chain_id[:chain_id.find(":")+1].lower()
144
+ # For eip155, further validate that the rest is a number or 'any'
145
+ if prefix == 'eip155:':
146
+ rest = chain_id[len(prefix):]
147
+ if rest.isdigit():
148
+ return True
149
+ elif rest == 'any':
150
+ print("Please ensure the label is accurate and consistent across all EVM chains before setting chain_id = 'eip155:any'.")
151
+ return True
152
+ else:
153
+ print(f"Invalid eip155 chain_id format: {chain_id}")
154
+ raise ValueError("For eip155 chains, format must be 'eip155:' followed by a number or 'any'")
155
+ return True
163
156
 
164
157
  # If we get here, the chain_id didn't match any allowed format
165
158
  print(f"Unsupported chain ID format: {chain_id}")
166
- raise ValueError(f"Chain ID must be in CAIP-2 format (e.g., Base -> 'eip155:8453'), see this guide on CAIP-2: {self.url_caip2_format}")
159
+ raise ValueError(f"Chain ID must be in CAIP-2 format (e.g., Base -> 'eip155:8453' or Starknet -> 'starknet:SN_MAIN'), see this guide on CAIP-2: {self.url_caip2_format}")
167
160
 
168
161
  def validate_address(self, address: str) -> bool:
169
162
  """
@@ -181,6 +174,24 @@ class UtilsValidator:
181
174
  print(address)
182
175
  raise ValueError("Address must be a valid Ethereum address in hex format")
183
176
 
177
+ def validate_address_to_be_labelled(self, address: str) -> bool:
178
+ """
179
+ Validates if address to be labelled is within CAIP10 limits
180
+
181
+ Args:
182
+ address (str): Address to check
183
+
184
+ Returns:
185
+ bool: True if correct, False otherwise
186
+ """
187
+ if len(address) > 66 or len(address) == 0:
188
+ print(f"Unexpected address length ({len(address)}): '{address}'")
189
+ raise ValueError(f"Address to be labelled exceeds maximum length of 66 characters or is empty. See this guide on CAIP-10 address limitations: {self.url_caip10_format}")
190
+ if ":" in address:
191
+ print(f"Address to be labelled must not contain ':' character: '{address}'")
192
+ raise ValueError(f"Address to be labelled must not contain ':' character. See this guide on CAIP-10 address limitations: {self.url_caip10_format}")
193
+ return True
194
+
184
195
  def validate_tags(self, tags: dict, auto_fix: bool=False) -> bool:
185
196
  """
186
197
  Check if tags are in the correct format.
@@ -82,7 +82,7 @@ class OLI:
82
82
  self.source_address = None # for Label Trust
83
83
 
84
84
  # Label Pool Schema for OLI Label Pool
85
- self.oli_label_pool_schema = '0xb763e62d940bed6f527dd82418e146a904e62a297b8fa765c9b3e1f0bc6fdd68'
85
+ self.oli_label_pool_schema = '0xcff83309b59685fdae9dad7c63d969150676d51d8eeda66799d1c4898b84556a' # v2.0.0 of EAS schema
86
86
 
87
87
  # Label Trust Schema for OLI Label Trust
88
88
  self.oli_label_trust_schema = '0x6d780a85bfad501090cd82868a0c773c09beafda609d54888a65c106898c363d'
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: oli-python
3
- Version: 2.0.5
3
+ Version: 2.0.7
4
4
  Summary: Python SDK for interacting with the Open Labels Initiative; A standard, registry and trust layer for EVM address labels.
5
5
  Home-page: https://github.com/openlabelsinitiative/oli-python
6
6
  Author: Lorenz Lehmann
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
5
5
 
6
6
  setup(
7
7
  name="oli-python",
8
- version="2.0.5",
8
+ version="2.0.7",
9
9
  author="Lorenz Lehmann",
10
10
  author_email="lorenz@growthepie.com",
11
11
  description="Python SDK for interacting with the Open Labels Initiative; A standard, registry and trust layer for EVM address labels.",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes