runar 0.3.0__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.
Files changed (50) hide show
  1. runar-0.3.0/PKG-INFO +9 -0
  2. runar-0.3.0/README.md +194 -0
  3. runar-0.3.0/pyproject.toml +17 -0
  4. runar-0.3.0/runar/__init__.py +113 -0
  5. runar-0.3.0/runar/base.py +42 -0
  6. runar-0.3.0/runar/builtins.py +454 -0
  7. runar-0.3.0/runar/compile_check.py +46 -0
  8. runar-0.3.0/runar/decorators.py +10 -0
  9. runar-0.3.0/runar/ec.py +149 -0
  10. runar-0.3.0/runar/ecdsa.py +296 -0
  11. runar-0.3.0/runar/rabin_sig.py +50 -0
  12. runar-0.3.0/runar/sdk/__init__.py +35 -0
  13. runar-0.3.0/runar/sdk/anf_interpreter.py +553 -0
  14. runar-0.3.0/runar/sdk/calling.py +190 -0
  15. runar-0.3.0/runar/sdk/codegen.py +539 -0
  16. runar-0.3.0/runar/sdk/contract.py +1079 -0
  17. runar-0.3.0/runar/sdk/deployment.py +197 -0
  18. runar-0.3.0/runar/sdk/local_signer.py +117 -0
  19. runar-0.3.0/runar/sdk/oppushtx.py +274 -0
  20. runar-0.3.0/runar/sdk/provider.py +145 -0
  21. runar-0.3.0/runar/sdk/rpc_provider.py +140 -0
  22. runar-0.3.0/runar/sdk/signer.py +89 -0
  23. runar-0.3.0/runar/sdk/state.py +220 -0
  24. runar-0.3.0/runar/sdk/types.py +217 -0
  25. runar-0.3.0/runar/slhdsa_impl.py +88 -0
  26. runar-0.3.0/runar/test_keys.py +57 -0
  27. runar-0.3.0/runar/types.py +30 -0
  28. runar-0.3.0/runar/wots.py +136 -0
  29. runar-0.3.0/runar.egg-info/PKG-INFO +9 -0
  30. runar-0.3.0/runar.egg-info/SOURCES.txt +48 -0
  31. runar-0.3.0/runar.egg-info/dependency_links.txt +1 -0
  32. runar-0.3.0/runar.egg-info/requires.txt +6 -0
  33. runar-0.3.0/runar.egg-info/top_level.txt +1 -0
  34. runar-0.3.0/setup.cfg +4 -0
  35. runar-0.3.0/tests/test_anf_interpreter.py +390 -0
  36. runar-0.3.0/tests/test_bigint_json.py +189 -0
  37. runar-0.3.0/tests/test_build_unlocking_script.py +167 -0
  38. runar-0.3.0/tests/test_builtins.py +244 -0
  39. runar-0.3.0/tests/test_contract_lifecycle.py +374 -0
  40. runar-0.3.0/tests/test_ec.py +154 -0
  41. runar-0.3.0/tests/test_from_txid.py +192 -0
  42. runar-0.3.0/tests/test_sdk_calling.py +445 -0
  43. runar-0.3.0/tests/test_sdk_deployment.py +250 -0
  44. runar-0.3.0/tests/test_sdk_rpc_provider.py +130 -0
  45. runar-0.3.0/tests/test_sdk_state.py +285 -0
  46. runar-0.3.0/tests/test_sha256_compress.py +34 -0
  47. runar-0.3.0/tests/test_signer.py +307 -0
  48. runar-0.3.0/tests/test_terminal_call.py +113 -0
  49. runar-0.3.0/tests/test_types.py +182 -0
  50. runar-0.3.0/tests/test_wots.py +196 -0
runar-0.3.0/PKG-INFO ADDED
@@ -0,0 +1,9 @@
1
+ Metadata-Version: 2.4
2
+ Name: runar
3
+ Version: 0.3.0
4
+ Summary: Runar - TypeScript-to-Bitcoin Script Compiler (Python runtime)
5
+ Requires-Python: >=3.10
6
+ Provides-Extra: crypto
7
+ Requires-Dist: coincurve>=20.0; extra == "crypto"
8
+ Provides-Extra: dev
9
+ Requires-Dist: pytest>=7.0; extra == "dev"
runar-0.3.0/README.md ADDED
@@ -0,0 +1,194 @@
1
+ # runar-py
2
+
3
+ **Python runtime package for writing and testing Rúnar smart contracts.**
4
+
5
+ ---
6
+
7
+ ## Overview
8
+
9
+ The `runar` Python package provides types, base classes, mock crypto, real hashes, EC operations, and a deployment SDK for writing, testing, and deploying Rúnar smart contracts in Python.
10
+
11
+ Zero required dependencies. EC operations use pure Python int arithmetic with secp256k1 curve parameters. Real hash functions use Python's `hashlib` stdlib.
12
+
13
+ ---
14
+
15
+ ## Installation
16
+
17
+ ```bash
18
+ pip install runar-lang
19
+ # or
20
+ pip install -e packages/runar-py # from the repo root
21
+ ```
22
+
23
+ Optional dependency for real EC (coincurve):
24
+ ```bash
25
+ pip install runar-lang[crypto]
26
+ ```
27
+
28
+ ---
29
+
30
+ ## Writing Contracts
31
+
32
+ Contracts are standard Python classes extending `SmartContract` (stateless) or `StatefulSmartContract` (stateful):
33
+
34
+ ```python
35
+ from runar import SmartContract, Addr, Sig, PubKey, public, assert_, hash160, check_sig
36
+
37
+ class P2PKH(SmartContract):
38
+ pub_key_hash: Addr
39
+
40
+ def __init__(self, pub_key_hash: Addr):
41
+ super().__init__(pub_key_hash)
42
+ self.pub_key_hash = pub_key_hash
43
+
44
+ @public
45
+ def unlock(self, sig: Sig, pub_key: PubKey):
46
+ assert_(hash160(pub_key) == self.pub_key_hash)
47
+ assert_(check_sig(sig, pub_key))
48
+ ```
49
+
50
+ Python contracts use snake_case identifiers which the compiler converts to camelCase in the AST (`pub_key_hash` → `pubKeyHash`, `check_sig` → `checkSig`).
51
+
52
+ ---
53
+
54
+ ## Testing Contracts
55
+
56
+ ```python
57
+ import pytest
58
+ from runar import hash160, mock_sig, mock_pub_key
59
+ from conftest import load_contract
60
+
61
+ contract_mod = load_contract("P2PKH.runar.py")
62
+ P2PKH = contract_mod.P2PKH
63
+
64
+ def test_unlock():
65
+ pk = mock_pub_key()
66
+ c = P2PKH(pub_key_hash=hash160(pk))
67
+ c.unlock(mock_sig(), pk)
68
+
69
+ def test_unlock_wrong_key():
70
+ pk = mock_pub_key()
71
+ wrong_pk = b'\x03' + b'\x00' * 32
72
+ c = P2PKH(pub_key_hash=hash160(pk))
73
+ with pytest.raises(AssertionError):
74
+ c.unlock(mock_sig(), wrong_pk)
75
+ ```
76
+
77
+ Mock crypto functions (`check_sig`, `check_preimage`, `verify_wots`, etc.) always return `True` for business logic testing. Hash functions (`hash160`, `sha256`, etc.) use real `hashlib` implementations.
78
+
79
+ ---
80
+
81
+ ## Compile Check
82
+
83
+ Verify that a contract is valid Rúnar that will compile to Bitcoin Script:
84
+
85
+ ```python
86
+ from runar import compile_check
87
+
88
+ compile_check("P2PKH.runar.py") # raises on error
89
+ ```
90
+
91
+ Runs the contract through the Rúnar frontend (parse → validate → typecheck).
92
+
93
+ ---
94
+
95
+ ## Types
96
+
97
+ | Python Type | Rúnar AST Type |
98
+ |-------------|---------------|
99
+ | `int` / `Bigint` | `bigint` |
100
+ | `bool` | `boolean` |
101
+ | `bytes` / `ByteString` | `ByteString` |
102
+ | `PubKey` | `PubKey` |
103
+ | `Sig` | `Sig` |
104
+ | `Addr` | `Addr` |
105
+ | `Sha256` | `Sha256` |
106
+ | `Ripemd160` | `Ripemd160` |
107
+ | `SigHashPreimage` | `SigHashPreimage` |
108
+ | `RabinSig` | `RabinSig` |
109
+ | `RabinPubKey` | `RabinPubKey` |
110
+ | `Point` | `Point` |
111
+ | `Readonly[T]` | Marks property `readonly: true` |
112
+
113
+ ---
114
+
115
+ ## Built-in Functions
116
+
117
+ ### Crypto
118
+ - `check_sig(sig, pub_key)` — Mock: always returns `True`
119
+ - `check_multi_sig(sigs, pub_keys)` — Mock: always returns `True`
120
+ - `check_preimage(preimage)` — Mock: always returns `True`
121
+ - `verify_rabin_sig(msg, sig, pub_key)` — Mock: always returns `True`
122
+
123
+ ### Hashing (real implementations)
124
+ - `hash160(data)`, `hash256(data)`, `sha256(data)`, `ripemd160(data)`
125
+
126
+ ### Byte manipulation
127
+ - `num2bin(value, length)`, `bin2num(data)`, `cat(a, b)`, `substr(data, start, length)`
128
+ - `reverse_bytes(data)`, `len_(data)`
129
+
130
+ ### Math
131
+ - `abs`, `min`, `max`, `within`, `safediv`, `safemod`, `clamp`, `sign`
132
+ - `pow_`, `mul_div`, `percent_of`, `sqrt`, `gcd`, `divmod_`, `log2`, `bool_cast`
133
+
134
+ ### EC (secp256k1)
135
+ - `ec_add(p, q)`, `ec_mul(p, k)`, `ec_mul_gen(k)`, `ec_negate(p)`
136
+ - `ec_on_curve(p)`, `ec_mod_reduce(x)`, `ec_encode_compressed(p)`
137
+ - `ec_make_point(x, y)`, `ec_point_x(p)`, `ec_point_y(p)`
138
+ - Constants: `EC_P`, `EC_N`, `EC_G`
139
+
140
+ ### Post-Quantum
141
+ - `verify_wots(message, signature, pub_key)` — Mock: always returns `True`
142
+ - `verify_slh_dsa_sha2_128s`, `verify_slh_dsa_sha2_128f`, etc. — Mock: always return `True`
143
+ - `wots_keygen()`, `wots_sign(key_pair, message)` — Real WOTS+ key generation and signing
144
+ - `slh_keygen(param_set)`, `slh_verify(pub_key, message, signature, param_set)` — Real SLH-DSA
145
+
146
+ ---
147
+
148
+ ## Deployment SDK
149
+
150
+ The `runar.sdk` subpackage provides a deployment SDK equivalent to the TypeScript, Go, and Rust SDKs:
151
+
152
+ ```python
153
+ from runar.sdk import RunarContract, MockProvider, MockSigner, DeployOptions
154
+
155
+ # Load a compiled artifact
156
+ contract = RunarContract(artifact, constructor_args)
157
+
158
+ # Connect provider and signer
159
+ provider = MockProvider()
160
+ signer = MockSigner()
161
+ contract.connect(provider, signer)
162
+
163
+ # Deploy
164
+ result = contract.deploy(DeployOptions(satoshis=10000))
165
+
166
+ # Call a method
167
+ result = contract.call("increment", [])
168
+ ```
169
+
170
+ ### SDK Exports
171
+
172
+ - `RunarContract` — Wraps a compiled artifact, manages state and UTXO tracking
173
+ - `MockProvider` — In-memory provider for testing
174
+ - `MockSigner` / `ExternalSigner` — Signer implementations
175
+ - `build_deploy_transaction`, `build_call_transaction` — Low-level transaction builders
176
+ - `serialize_state`, `deserialize_state` — State serialization
177
+
178
+ ---
179
+
180
+ ## Package Structure
181
+
182
+ ```
183
+ runar/
184
+ __init__.py # Public API exports
185
+ types.py # Type aliases (Bigint, ByteString, PubKey, etc.)
186
+ base.py # SmartContract, StatefulSmartContract base classes
187
+ builtins.py # Built-in functions (crypto mocks, real hashes, math)
188
+ decorators.py # @public decorator
189
+ ec.py # Pure Python secp256k1 EC operations
190
+ wots.py # WOTS+ key generation and signing
191
+ slhdsa_impl.py # SLH-DSA (FIPS 205) implementation
192
+ compile_check.py # Contract validation via the Python compiler
193
+ sdk/ # Deployment SDK (RunarContract, providers, signers)
194
+ ```
@@ -0,0 +1,17 @@
1
+ [project]
2
+ name = "runar"
3
+ version = "0.3.0"
4
+ description = "Runar - TypeScript-to-Bitcoin Script Compiler (Python runtime)"
5
+ requires-python = ">=3.10"
6
+ dependencies = []
7
+
8
+ [project.optional-dependencies]
9
+ crypto = ["coincurve>=20.0"]
10
+ dev = ["pytest>=7.0"]
11
+
12
+ [build-system]
13
+ requires = ["setuptools>=68.0"]
14
+ build-backend = "setuptools.build_meta"
15
+
16
+ [tool.setuptools.packages.find]
17
+ include = ["runar*"]
@@ -0,0 +1,113 @@
1
+ """Runar - TypeScript-to-Bitcoin Script Compiler (Python runtime).
2
+
3
+ Provides types, real crypto, real hashes, EC operations, and base classes
4
+ for writing and testing Runar smart contracts in Python.
5
+ """
6
+
7
+ from runar.types import (
8
+ Bigint, Int, ByteString, PubKey, Sig, Addr, Sha256, Ripemd160,
9
+ SigHashPreimage, RabinSig, RabinPubKey, Point, Readonly,
10
+ )
11
+ from runar.builtins import (
12
+ assert_,
13
+ check_sig, check_multi_sig, check_preimage,
14
+ hash160, hash256, sha256, ripemd160,
15
+ extract_locktime, extract_output_hash, extract_amount,
16
+ extract_version, extract_sequence,
17
+ extract_hash_prevouts, extract_outpoint,
18
+ num2bin, bin2num, cat, substr, reverse_bytes, len_,
19
+ verify_rabin_sig,
20
+ safediv, safemod, clamp, sign, pow_, mul_div, percent_of,
21
+ sqrt, gcd, divmod_, log2, bool_cast,
22
+ mock_sig, mock_pub_key, mock_preimage,
23
+ verify_wots,
24
+ verify_slh_dsa_sha2_128s, verify_slh_dsa_sha2_128f,
25
+ verify_slh_dsa_sha2_192s, verify_slh_dsa_sha2_192f,
26
+ verify_slh_dsa_sha2_256s, verify_slh_dsa_sha2_256f,
27
+ blake3_compress, blake3_hash,
28
+ sha256_compress, sha256_finalize,
29
+ )
30
+ from runar.ecdsa import (
31
+ sign_test_message, pub_key_from_priv_key,
32
+ ecdsa_verify, ecdsa_sign,
33
+ TEST_MESSAGE, TEST_MESSAGE_DIGEST,
34
+ )
35
+ from runar.test_keys import (
36
+ TestKeyPair, TEST_KEYS,
37
+ ALICE, BOB, CHARLIE, DAVE, EVE,
38
+ FRANK, GRACE, HEIDI, IVAN, JUDY,
39
+ )
40
+ from runar.wots import wots_keygen, wots_sign, WOTSKeyPair
41
+ from runar.slhdsa_impl import slh_keygen, slh_verify, SLHKeyPair
42
+ from runar.ec import (
43
+ ec_add, ec_mul, ec_mul_gen, ec_negate, ec_on_curve,
44
+ ec_mod_reduce, ec_encode_compressed, ec_make_point,
45
+ ec_point_x, ec_point_y,
46
+ EC_P, EC_N, EC_G,
47
+ )
48
+ from runar.base import SmartContract, StatefulSmartContract
49
+ from runar.decorators import public
50
+ from runar.compile_check import compile_check
51
+
52
+ import builtins as _builtins
53
+
54
+ # Re-export Python builtins that Runar contracts use directly
55
+ abs = _builtins.abs
56
+ min = _builtins.min
57
+ max = _builtins.max
58
+
59
+ def within(x: int, lo: int, hi: int) -> bool:
60
+ return lo <= x < hi
61
+
62
+ __all__ = [
63
+ # Types
64
+ 'Bigint', 'Int', 'ByteString', 'PubKey', 'Sig', 'Addr', 'Sha256',
65
+ 'Ripemd160', 'SigHashPreimage', 'RabinSig', 'RabinPubKey', 'Point',
66
+ 'Readonly',
67
+ # Decorators
68
+ 'public',
69
+ # Base classes
70
+ 'SmartContract', 'StatefulSmartContract',
71
+ # Assertions
72
+ 'assert_',
73
+ # Crypto
74
+ 'check_sig', 'check_multi_sig', 'check_preimage',
75
+ 'hash160', 'hash256', 'sha256', 'ripemd160',
76
+ 'verify_rabin_sig',
77
+ 'verify_wots',
78
+ 'verify_slh_dsa_sha2_128s', 'verify_slh_dsa_sha2_128f',
79
+ 'verify_slh_dsa_sha2_192s', 'verify_slh_dsa_sha2_192f',
80
+ 'verify_slh_dsa_sha2_256s', 'verify_slh_dsa_sha2_256f',
81
+ # ECDSA
82
+ 'ecdsa_verify', 'ecdsa_sign', 'sign_test_message', 'pub_key_from_priv_key',
83
+ 'TEST_MESSAGE', 'TEST_MESSAGE_DIGEST',
84
+ # Test keys
85
+ 'TestKeyPair', 'TEST_KEYS',
86
+ 'ALICE', 'BOB', 'CHARLIE', 'DAVE', 'EVE',
87
+ 'FRANK', 'GRACE', 'HEIDI', 'IVAN', 'JUDY',
88
+ # Preimage extraction
89
+ 'extract_locktime', 'extract_output_hash', 'extract_amount',
90
+ 'extract_version', 'extract_sequence',
91
+ 'extract_hash_prevouts', 'extract_outpoint',
92
+ # Binary utilities
93
+ 'num2bin', 'bin2num', 'cat', 'substr', 'reverse_bytes', 'len_',
94
+ # Math
95
+ 'within', 'safediv', 'safemod', 'clamp', 'sign', 'pow_',
96
+ 'mul_div', 'percent_of', 'sqrt', 'gcd', 'divmod_', 'log2', 'bool_cast',
97
+ # EC
98
+ 'ec_add', 'ec_mul', 'ec_mul_gen', 'ec_negate', 'ec_on_curve',
99
+ 'ec_mod_reduce', 'ec_encode_compressed', 'ec_make_point',
100
+ 'ec_point_x', 'ec_point_y', 'EC_P', 'EC_N', 'EC_G',
101
+ # BLAKE3
102
+ 'blake3_compress', 'blake3_hash',
103
+ # SHA-256 compression
104
+ 'sha256_compress', 'sha256_finalize',
105
+ # Test helpers
106
+ 'mock_sig', 'mock_pub_key', 'mock_preimage',
107
+ # WOTS+ keygen/sign
108
+ 'wots_keygen', 'wots_sign', 'WOTSKeyPair',
109
+ # SLH-DSA keygen/verify
110
+ 'slh_keygen', 'slh_verify', 'SLHKeyPair',
111
+ # Compile check
112
+ 'compile_check',
113
+ ]
@@ -0,0 +1,42 @@
1
+ """Runar base contract classes."""
2
+
3
+ from typing import Any
4
+
5
+
6
+ class SmartContract:
7
+ """Base class for stateless Runar smart contracts.
8
+
9
+ All properties are readonly. The contract logic is pure — no state
10
+ is carried between spending transactions.
11
+ """
12
+
13
+ def __init__(self, *args: Any) -> None:
14
+ pass
15
+
16
+
17
+ class StatefulSmartContract(SmartContract):
18
+ """Base class for stateful Runar smart contracts.
19
+
20
+ Mutable properties are carried in the UTXO state. The compiler
21
+ auto-injects checkPreimage at method entry and state continuation
22
+ at exit.
23
+ """
24
+
25
+ tx_preimage: bytes = b''
26
+ _outputs: list
27
+
28
+ def __init__(self, *args: Any) -> None:
29
+ super().__init__(*args)
30
+ self._outputs = []
31
+
32
+ def add_output(self, satoshis: int, *state_values: Any) -> None:
33
+ """Add an output with the given satoshis and state values."""
34
+ self._outputs.append({"satoshis": satoshis, "values": list(state_values)})
35
+
36
+ def get_state_script(self) -> bytes:
37
+ """Get the state script for the current contract state."""
38
+ return b''
39
+
40
+ def reset_outputs(self) -> None:
41
+ """Reset the outputs list."""
42
+ self._outputs = []