Jump To
Features · Installation · Quick Start · License Types · API Reference · Examples · Security
OnewaySWP is a Python library for building one-way license verification systems without requiring a server.
Licenses are generated on the admin side, distributed to clients, and verified entirely offline.
The framework internally handles license generation, cryptographic signing, protected local state, and verification. Client applications only require a public key to validate licenses.
No internet connection. No license server. No backend infrastructure.
OnewaySWP is designed for developers who want a practical licensing solution that stays portable, self-contained, and independent.
✦ Features
| Feature | Description | |
|---|---|---|
| ◉ | Offline Verification | No internet connection or license server required |
| ◉ | Auto-Detection | Automatically detects the current OS and architecture |
| ◉ | Cross-Platform | Supports Windows, Linux, macOS, and Android |
| ◉ | Multi-Mode | Supports Date, Credit, and Duration license types |
| ◉ | Session-Based Duration | Duration licenses measured during active sessions |
| ◉ | Credit System | Credit-based licenses with automatic decrement |
| ◉ | Cryptographic Protection | License integrity and tamper detection |
| ◉ | Protected Local Storage | Local license state protected with internal protection mechanisms |
| ◉ | Clock Rollback Protection | Detects system clock manipulation |
| ◉ | Multi-License Support | Multiple independent license states per application |
| ◉ | Session Context Manager | Automatic start/stop for duration licenses |
| ◉ | State Export & Import | Move license state between environments |
| ◉ | Retry on File Lock | Automatic retry when state file is locked |
Installation
Install directly from PyPI:
pip install onewayswp
| Command | Purpose |
|---|---|
pip |
Python package installer |
install |
Installs a package |
onewayswp |
OnewaySWP package |
Quick Start
01 — Admin Setup
Create an admin instance and generate the key pair.
from onewayswp import Admin
# Create admin instance
admin = Admin()
# Load existing key pair.
# If it does not exist yet, it will be generated automatically.
admin.load_keys(auto_generate=True)
# Display keys
print("Secret:", admin.secret_key)
print("Public:", admin.public_key)
Recommended: Always use load_keys(auto_generate=True) on the admin side.
Manual key generation via generate_keys() should only be used when you intentionally want to replace the existing key pair. Replacing the key pair will invalidate all previously issued licenses.
Important: The secret key is used to sign licenses and must remain private. The public key is distributed to client applications for verification.
02 — Create a License
Load the existing keys and create a license.
from onewayswp import Admin
admin = Admin()
# Load existing keys
admin.load_keys(auto_generate=True)
# Create a license
result = admin.create_license(
type="date",
expires="2027-12-31",
additional_data={
"client_name": "username123"
}
)
print(result["token"])
03 — Client Verification
The client application only needs the public key.
from onewayswp import Client
# Create client instance
client = Client("data/license.swpb")
# Load public key
client.open_key("~/.owswp/public.key")
# Check whether a license is already active
if not client.is_active():
token = input("Enter key: ")
# Validate license
result = client.validate_key(token)
if not result["status"]:
print(result["message"])
exit(1)
# Verify protection state
protection = client.protection_verify()
if protection["status"]:
print("Application running...")
else:
print(protection["message"])
Basic Flow
┌─────────────────────┐
│ ADMIN │
├─────────────────────┤
│ Load Key Pair │
│ ↓ │
│ Create License │
│ ↓ │
│ Distribute Token │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ CLIENT │
├─────────────────────┤
│ Public Key │
│ ↓ │
│ Validate Token │
│ ↓ │
│ Verify Local State │
└─────────────────────┘
License Types
OnewaySWP provides three license modes.
Date License
A license that expires on a specific date.
result = admin.create_license(
type="date",
expires="2027-12-31"
)
| Parameter | Description |
|---|---|
type |
"date" |
expires |
Expiration date in YYYY-MM-DD format |
Returns information such as:
tokentypeexpiredexpires_at
Credit License
A license containing a credit balance that decreases when used.
result = admin.create_license(
type="credit",
credits=100
)
| Parameter | Description |
|---|---|
type |
"credit" |
credits |
Initial credit amount |
Returns information such as:
tokentypecredit_value
Duration License
A license valid for a fixed amount of active usage time.
result = admin.create_license(
type="duration",
hours=2
)
| Parameter | Description |
|---|---|
type |
"duration" |
hours |
Duration in hours |
duration_seconds |
Alternative duration in seconds |
Returns information such as:
tokentypeduration_hours
API Reference
Admin
| Method | Parameters | Returns | Description |
|---|---|---|---|
__init__ |
key_dir: str = None |
Admin |
Create admin instance |
keys_exist |
key_dir: str = None |
bool |
Check if key files exist |
generate_keys |
auto_save: bool = True, file_path: str = None |
tuple |
Generate key pair |
save_keys |
target_dir: str = None |
None |
Save keys to disk |
load_keys |
key_dir: str = None, validate: bool = True, auto_generate: bool = False |
tuple |
Load keys |
set_keys |
secret_key: str, public_key: str, validate: bool = True |
None |
Set keys manually |
validate_keys |
none |
bool |
Verify key pair |
create_license |
type, expires, credits, duration_seconds, hours, additional_data |
dict |
Create license token |
regenerate_keys |
key_dir: str = None |
tuple |
Generate new key pair |
platform |
none |
dict |
Get OS and architecture |
version |
none |
str |
Get library version |
Client
| Method | Parameters | Returns | Description |
|---|---|---|---|
__init__ |
data_path: str = None, extra_paths: List[str] = None |
Client |
Create client instance |
open_key |
path: str |
None |
Load public key |
set_public_key |
key: str |
None |
Set public key |
is_active |
none |
bool |
Check active license |
validate_key |
token: str |
dict |
Validate license |
inspect_key |
token: str |
dict |
Inspect token without activation |
protection_verify |
none |
dict |
Verify local protection state |
use_credit |
amount: int = 1 |
dict |
Decrement credits |
session |
none |
context |
Duration session context |
export_state |
none |
dict |
Export license state |
import_state |
data: dict or str |
dict |
Import license state |
status |
none |
dict |
Get last status |
state_path |
none |
str |
Get state file path |
reset |
none |
None |
Delete local state |
version |
none |
str |
Get library version |
Info Object
The info object provides library information and supports both attribute-style and dictionary-style access.
| Method | Description |
|---|---|
__getattr__ |
Access field as attribute |
__getitem__ |
Access field by key |
__contains__ |
Check whether field exists |
__iter__ |
Iterate over field names |
keys() |
Get field names |
values() |
Get field values |
items() |
Get field/value pairs |
get() |
Get field with default |
to_dict() |
Convert to dictionary |
Response Format
Validation and operation methods use a consistent dictionary-based response format.
Success
{
"status": True,
"code": "SUCCESS",
"message": "License valid and activated",
"type": "credit",
"credit_value": 100,
"remaining_credits": 100,
"created_at": "2026-10-03 12:00:00",
"last_time": "2026-10-03 12:05:00",
"additional_data": {
"hardware_id": "1234567890"
}
}
Failure
{
"status": False,
"code": "EXPIRED",
"message": "Token expired"
}
Failure responses contain:
status
code
message
Data Dictionary
Common Fields
| Field | Type | Description |
|---|---|---|
status |
bool |
True when operation succeeds |
code |
str |
Status or error code |
message |
str |
Human-readable message |
type |
str |
date, credit, or duration |
Date License
| Field | Type | Description |
|---|---|---|
expired |
str |
Expiration date |
expires_at |
int |
Unix expiration timestamp |
remaining_days |
int |
Remaining days |
Credit License
| Field | Type | Description |
|---|---|---|
credit_value |
int |
Initial credit |
remaining_credits |
int |
Remaining credit |
used |
int |
Credit used in last operation |
Duration License
| Field | Type | Description |
|---|---|---|
duration_hours |
float |
Total duration |
duration_seconds |
int |
Total duration in seconds |
remaining_hours |
float |
Remaining duration |
remaining_seconds |
int |
Remaining seconds |
elapsed_seconds |
int |
Elapsed session time |
started_at |
str |
Session start |
stopped_at |
str |
Session stop |
Session
| Field | Type | Description |
|---|---|---|
created_at |
str |
License creation timestamp |
last_time |
str |
Last verification timestamp |
Error Codes
| Code | Description |
|---|---|
SUCCESS |
Operation completed successfully |
INVALID_SIGNATURE |
Token signature is invalid |
INVALID_MAGIC |
File format is invalid |
INVALID_KEY_FORMAT |
Key format is invalid |
UNSUPPORTED_VERSION |
File version is not supported |
KEY_MISMATCH |
Key pair does not match |
SECURITY_ERROR |
Security violation detected |
EXPIRED |
Token has expired |
CLOCK_ROLLBACK_DETECTED |
System clock rollback detected |
CORRUPTED_FILE |
File is corrupted |
INSUFFICIENT_CREDITS |
Credit balance is insufficient |
FILE_LOCKED |
File is locked by another process |
IO_ERROR |
Input/output error |
CRYPTO_ERROR |
Cryptographic error |
SERIALIZATION_ERROR |
Serialization error |
FFI_ERROR |
Foreign function interface error |
NO_STATE_FILE |
State file does not exist |
Examples
Generate Keys
from onewayswp import Admin
admin = Admin(key_dir="./keys")
secret, public = admin.generate_keys(
auto_save=True
)
print("Secret Key:", secret)
print("Public Key:", public)
Load Existing Keys
from onewayswp import Admin
admin = Admin()
secret, public = admin.load_keys(
validate=True,
auto_generate=True
)
print("Keys loaded successfully")
Load Keys with Auto-Generate
from onewayswp import Admin
admin = Admin()
secret, public = admin.load_keys(
auto_generate=True
)
print("Keys ready")
print("Public:", public)
Create Date License
from onewayswp import Admin
admin = Admin()
admin.load_keys()
result = admin.create_license(
type="date",
expires="2027-12-31",
additional_data={
"client_name": "user12345",
"plan": "pro"
}
)
token = result["token"]
print("Token:", token)
print("Expires:", result["expired"])
print("Expires at:", result["expires_at"])
Create Credit License
from onewayswp import Admin
admin = Admin()
admin.load_keys()
result = admin.create_license(
type="credit",
credits=100,
additional_data={
"client_name": "user12345"
}
)
print("Token:", result["token"])
print("Credits:", result["credit_value"])
Create Duration License
from onewayswp import Admin
admin = Admin()
admin.load_keys()
result = admin.create_license(
type="duration",
hours=2,
additional_data={
"client_name": "user12345"
}
)
print("Token:", result["token"])
print("Duration:", result["duration_hours"], "hours")
Alternative using seconds:
result = admin.create_license(
type="duration",
duration_seconds=3600
)
print(
"Duration:",
result["duration_hours"],
"hours"
)
Set Keys Manually
from onewayswp import Admin
admin = Admin()
admin.set_keys(
secret_key="OWSWP-sec-...",
public_key="OWSWP-pub-...",
validate=True
)
print("Keys set")
Regenerate Keys
from onewayswp import Admin
admin = Admin()
admin.load_keys()
new_secret, new_public = admin.regenerate_keys()
print("New secret:", new_secret)
print("New public:", new_public)
Regenerating the key pair will cause previously issued tokens to become invalid.
Platform Information
from onewayswp import Admin
admin = Admin()
info = admin.platform()
print("OS:", info["os"])
print("Arch:", info["arch"])
Client Validation
from onewayswp import Client
client = Client(
"data/license.swpb"
)
client.set_public_key(
"OWSWP-pub-..."
)
if client.is_active():
print("License already active")
else:
token = input("Enter key: ")
result = client.validate_key(token)
if result["status"]:
print("License activated")
print("Type:", result["type"])
else:
print("Failed:", result["message"])
Use Credits
from onewayswp import Client
client = Client(
"data/license.swpb"
)
client.open_key(
"~/.owswp/public.key"
)
result = client.validate_key(
"OWSWP-..."
)
if not result["status"]:
print("Invalid license")
exit(1)
result = client.use_credit(5)
if result["status"]:
print("Used 5 credits")
print(
"Remaining:",
result["remaining_credits"]
)
else:
print("Failed:", result["message"])
Duration Session
Duration licenses can measure usage during an active session.
from onewayswp import Client
import time
client = Client(
"data/license.swpb"
)
client.open_key(
"~/.owswp/public.key"
)
result = client.validate_key(
"OWSWP-..."
)
if not result["status"]:
print("Invalid license")
exit(1)
with client.session():
print("Application running...")
time.sleep(10)
protection = client.protection_verify()
print(
"Remaining:",
protection["remaining_hours"],
"hours"
)
Inspect License Without Activating
from onewayswp import Client
client = Client(
"data/license.swpb"
)
client.set_public_key(
"OWSWP-pub-..."
)
result = client.inspect_key(
"OWSWP-..."
)
if result["status"]:
print("Type:", result["type"])
print("Is expired:", result["is_expired"])
if result["type"] == "date":
print(
"Expires:",
result["expired"]
)
print(
"Remaining days:",
result["remaining_days"]
)
elif result["type"] == "credit":
print(
"Credits:",
result["credit_value"]
)
elif result["type"] == "duration":
print(
"Duration hours:",
result["duration_hours"]
)
Export & Import State
Export state:
from onewayswp import Client
client1 = Client(
"data/license1.swpb"
)
client1.open_key(
"~/.owswp/public.key"
)
exported = client1.export_state()
print(
"Exported data:",
exported["data"][:50],
"..."
)
print(
"Public key:",
exported["public_key"]
)
Import state:
client2 = Client(
"data/license2.swpb"
)
client2.set_public_key(
exported["public_key"]
)
result = client2.import_state(
exported
)
if result["status"]:
print(
"State imported successfully"
)
Reset Client State
from onewayswp import Client
client = Client(
"data/license.swpb"
)
client.set_public_key(
"OWSWP-pub-..."
)
client.reset()
print("State reset")
After resetting, the next validation will require a new token.
Library Information
from onewayswp import info
print(info)
print("Author:", info.author)
print("Version:", info.oneway_version)
print("GitHub:", info.swp_github)
Dictionary-style access:
print("Author:", info["author"])
Convert to dictionary:
data = info.to_dict()
for key, value in data.items():
print(f"{key}: {value}")
Error Handling
from onewayswp import (
Client,
OnewaySWPError,
InvalidTokenError,
ExpiredError,
SecurityError,
)
client = Client(
"data/license.swbp"
)
client.set_public_key(
"OWSWP-pub-..."
)
try:
result = client.validate_key(
"OWSWP-..."
)
if not result["status"]:
code = result["code"]
message = result["message"]
print(
f"Error [{code}]: {message}"
)
except InvalidTokenError as e:
print(
f"Invalid token: {e}"
)
except ExpiredError as e:
print(
f"Token expired: {e}"
)
except SecurityError as e:
print(
f"Security error: {e}"
)
except OnewaySWPError as e:
print(
f"Error: {e}"
)
Security Notes
OnewaySWP is designed to help developers create one-way license verification systems for applications that cannot rely on a server.
It is a licensing framework, not a replacement for application-level security.
The library applies internal cryptographic protection to help preserve license integrity, protect local license state, and detect unauthorized modification.
However, the overall security of an application still depends on how the framework is integrated by the developer.
Any bypass, modification, or direct interaction with the application code is outside the scope of this library.
Keep Your Secret Key Private
The secret key is used to sign licenses.
Never distribute it with client applications.
If the secret key is exposed, another party may be able to generate valid licenses.
Protect Your Key Pair
Store the secret key and public key safely.
Losing the key pair may prevent future licenses from being verified against previously issued tokens.
Public Key Distribution
Client applications only require the public key to validate licenses.
The secret key should remain on the administrative side.
Protect Local State
Treat the .swpb state file as protected application data.
Manual modification may invalidate the license state.
Integration Matters
OnewaySWP is a tool.
The way it is integrated into an application determines how effectively it contributes to the application's licensing protection.
Compatibility
OnewaySWP is designed for cross-platform usage:
Windows
Linux
macOS
Android
Platform and architecture information can be detected automatically:
from onewayswp import Admin
admin = Admin()
info = admin.platform()
print(info["os"])
print(info["arch"])
Project Information
| Project | OnewaySWP |
| Description | Offline One-Way License Framework |
| Version | 0.1.0 |
| Author | Juan Hulu |
| Organization | SilentWolfProject |
| License | MIT |
Links
-
Author — TikTok https://tiktok.com/@juanhulu.xyz
-
SWP — TikTok https://tiktok.com/@silentwolfproject
-
Author — Instagram https://www.instagram.com/juanhulu.xyz
-
SWP — Instagram https://www.instagram.com/silentwolfproject
-
GitHub Pages https://silentwolfproject.github.io
Metadata
Release files for onewayswp 0.1.0.post1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| onewayswp-0.1.0.post1.tar.gz | 4.2 MB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| onewayswp-0.1.0.post1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 8.4 MB
Release files / onewayswp-0.1.0.post1.tar.gz
| Download URL | onewayswp-0.1.0.post1.tar.gz |
|---|---|
| Size | 4.2 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
632188d44d4b3e03d4098c5b37a6429a2b776a5d267be4076506273b31eb9785
|
|
BLAKE2b-256 checksum How to use checksums |
928f561aa5a032720237c6f87c38a77d86244fc7cb2123bcb6fe847ace5cd4ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.8
|
Release files / onewayswp-0.1.0.post1-py3-none-any.whl
| Download URL | onewayswp-0.1.0.post1-py3-none-any.whl |
|---|---|
| Size | 4.2 MB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e56aa66b2a07f9a6ae6d0fa69b485dce9bfae8226b8c6f2ad2fda642af315a1f
|
|
BLAKE2b-256 checksum How to use checksums |
ee531229a78823f8aa67cb7eed21fa4965799829a8861aa7efe03d158d12e4be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.10.8
|