scafonix-agent 1.0.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.
@@ -0,0 +1,2 @@
1
+ # MANIFEST.in
2
+ recursive-include scafonix_agent/core *
@@ -0,0 +1,56 @@
1
+ Metadata-Version: 2.4
2
+ Name: scafonix-agent
3
+ Version: 1.0.0
4
+ Summary: Next-Generation Non-Custodial M-of-N MPC Security & x402 USDC Payment Infrastructure for Autonomous AI Agents
5
+ Author-email: Scafonix Team <support@scafonix.com>
6
+ Project-URL: Homepage, https://agent.scafonix.com
7
+ Project-URL: Bug Tracker, https://github.com/scafonix/scafonix-mpc/issues
8
+ Keywords: mpc,ai-agent,agentic-web,x402,usdc,non-custodial,scafonix
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+
15
+ # scafonix-agent
16
+
17
+ > **Next-Generation Non-Custodial M-of-N MPC Security & x402 USDC Payment Infrastructure for Autonomous AI Agents**
18
+
19
+ Official Python SDK for **Scafonix Agentic MPC** (`agent.scafonix.com`).
20
+
21
+ ---
22
+
23
+ ## 💻 Installation
24
+
25
+ ```bash
26
+ pip install scafonix-agent
27
+ ```
28
+
29
+ ---
30
+
31
+ ## 🚀 Quick Start
32
+
33
+ ```python
34
+ from scafonix_agent import ScafonixAgentPython
35
+
36
+ # 1. Initialize Agents
37
+ master = ScafonixAgentPython(agent_id='Master-Py')
38
+ worker1 = ScafonixAgentPython(agent_id='Worker-1-Py')
39
+ worker2 = ScafonixAgentPython(agent_id='Worker-2-Py')
40
+
41
+ # 2. Key Share Allocation (2-of-3)
42
+ shares = master.generate_key_shares("seed1", "seed2")
43
+ worker1_share = shares['share1']
44
+ worker2_share = shares['share2']
45
+
46
+ # 3. Workers sign PARTIAL WITHOUT TICKET!
47
+ tx_hash = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
48
+ part1 = worker1.sign_partial(worker1_share, worker2_share, tx_hash)
49
+ part2 = worker2.sign_partial(worker2_share, worker1_share, tx_hash)
50
+
51
+ # 4. Master (Ticket Holder, 0 Key Shares) Combines Signature
52
+ ticket = {'ticketId': 'py_tick_9999', 'msgHash': tx_hash, 'status': 'VALID'}
53
+ final_sig = master.combine_signatures([part1, part2], ticket)
54
+
55
+ print("Master Assembled Signature R:", final_sig['r'])
56
+ ```
@@ -0,0 +1,42 @@
1
+ # scafonix-agent
2
+
3
+ > **Next-Generation Non-Custodial M-of-N MPC Security & x402 USDC Payment Infrastructure for Autonomous AI Agents**
4
+
5
+ Official Python SDK for **Scafonix Agentic MPC** (`agent.scafonix.com`).
6
+
7
+ ---
8
+
9
+ ## 💻 Installation
10
+
11
+ ```bash
12
+ pip install scafonix-agent
13
+ ```
14
+
15
+ ---
16
+
17
+ ## 🚀 Quick Start
18
+
19
+ ```python
20
+ from scafonix_agent import ScafonixAgentPython
21
+
22
+ # 1. Initialize Agents
23
+ master = ScafonixAgentPython(agent_id='Master-Py')
24
+ worker1 = ScafonixAgentPython(agent_id='Worker-1-Py')
25
+ worker2 = ScafonixAgentPython(agent_id='Worker-2-Py')
26
+
27
+ # 2. Key Share Allocation (2-of-3)
28
+ shares = master.generate_key_shares("seed1", "seed2")
29
+ worker1_share = shares['share1']
30
+ worker2_share = shares['share2']
31
+
32
+ # 3. Workers sign PARTIAL WITHOUT TICKET!
33
+ tx_hash = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
34
+ part1 = worker1.sign_partial(worker1_share, worker2_share, tx_hash)
35
+ part2 = worker2.sign_partial(worker2_share, worker1_share, tx_hash)
36
+
37
+ # 4. Master (Ticket Holder, 0 Key Shares) Combines Signature
38
+ ticket = {'ticketId': 'py_tick_9999', 'msgHash': tx_hash, 'status': 'VALID'}
39
+ final_sig = master.combine_signatures([part1, part2], ticket)
40
+
41
+ print("Master Assembled Signature R:", final_sig['r'])
42
+ ```
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "scafonix-agent"
7
+ version = "1.0.0"
8
+ authors = [
9
+ { name="Scafonix Team", email="support@scafonix.com" },
10
+ ]
11
+ description = "Next-Generation Non-Custodial M-of-N MPC Security & x402 USDC Payment Infrastructure for Autonomous AI Agents"
12
+ readme = "README.md"
13
+ requires-python = ">=3.8"
14
+ classifiers = [
15
+ "Programming Language :: Python :: 3",
16
+ "License :: OSI Approved :: MIT License",
17
+ "Operating System :: OS Independent",
18
+ ]
19
+ keywords = ["mpc", "ai-agent", "agentic-web", "x402", "usdc", "non-custodial", "scafonix"]
20
+
21
+ [project.urls]
22
+ "Homepage" = "https://agent.scafonix.com"
23
+ "Bug Tracker" = "https://github.com/scafonix/scafonix-mpc/issues"
@@ -0,0 +1,9 @@
1
+ # scafonix_agent/__init__.py
2
+ """
3
+ Scafonix Agentic MPC Python SDK (scafonix-agent)
4
+ Non-Custodial M-of-N Threshold Signature & x402 USDC Micropayment Engine
5
+ """
6
+
7
+ from .scafonix_agent import ScafonixAgentPython as ScafonixAgent
8
+
9
+ __all__ = ["ScafonixAgent"]
@@ -0,0 +1 @@
1
+ const a0_0x36d50c=a0_0x1f7d;(function(_0x49fa99,_0x5eb01e){const _0x53989e=a0_0x1f7d,_0x2063da=_0x49fa99();while(!![]){try{const _0x5806a7=-parseInt(_0x53989e(0x144))/0x1*(parseInt(_0x53989e(0x10e))/0x2)+-parseInt(_0x53989e(0x168))/0x3+parseInt(_0x53989e(0x117))/0x4*(-parseInt(_0x53989e(0x16a))/0x5)+-parseInt(_0x53989e(0x136))/0x6*(-parseInt(_0x53989e(0x12f))/0x7)+parseInt(_0x53989e(0x130))/0x8+-parseInt(_0x53989e(0x141))/0x9*(-parseInt(_0x53989e(0x114))/0xa)+parseInt(_0x53989e(0x12e))/0xb;if(_0x5806a7===_0x5eb01e)break;else _0x2063da['push'](_0x2063da['shift']());}catch(_0x48894d){_0x2063da['push'](_0x2063da['shift']());}}}(a0_0x123f,0xe53f3));let wasmInstance=null,ffiBufferOffset=0x0,licensePacket=null,nodeCrypto=null;function a0_0x123f(){const _0x3a763b=['sig_s','licenseToken','join','user_secret','54xCiIOV','setItem','setLicense','28253DUFGOj','out_s','readFileSync','generateLicenseChallenge','message','now','randomBytes','PBKDF2','aes-256-gcm','delete','encode','ZASE\x20Wasm\x20not\x20initialized.\x20Call\x20init()\x20first.','derive_address_secure\x20failed\x20in\x20C\x20with\x20code\x20','instantiate','generate_license_challenge\x20failed\x20in\x20C\x20with\x20code\x20','crypto','final','targetDomain','hashHex','data','derive_address_secure','deriveEOAAddressSecure','derivePublicKeySecure','sigS','map','exports','AES-GCM','out_recovered','generate_license_challenge','init','resolve','get_ffi_buffer','salt','SHA-256','solve_lost_share\x20failed\x20in\x20C\x20with\x20code\x20','location','4274436sIyZak','packet','5HLMnSr','set','deriveKey','shares_csv','localStorage','out_address','importKey','memory','get','padStart','update','beta','slice','/zase.wasm','zase.wasm','userSecretHex','entropy_p1','reject','utf8','setAuthTag','undefined','concat','betaHex','entropyP1Hex','module','solve_lost_share','onmessage','36FvJtCr','subarray','createCipheriv','signGenericHashSecure','subtle','name','2435570KehQbZ','solveLostShare','derive_public_key_secure','7506760jnXtbl','license_token','encrypt','buffer','sign_generic_hash_secure','from','arrayBuffer','initialize_license_lease\x20failed\x20in\x20C\x20with\x20code\x20','hash','targetX','localhost','deriveBits','decrypt','hostname','sha256','length','path','getRandomValues','sharesCsv','generate_new_shares','createDecipheriv','entropy_p2','getAuthTag','22778811vcnsir','5131651RbjHTJ','3870520myiGhN','raw','out_shares_csv','generateNewShares','initialize_license_lease','floor','6JdeFxO','postMessage','saltHex','current_domain','pbkdf2Sync','hex','fill'];a0_0x123f=function(){return _0x3a763b;};return a0_0x123f();}const OFFSETS={'shares_csv':0x0,'user_secret':0x200,'salt':0x400,'hash':0x600,'beta':0x800,'out_r':0xa00,'out_s':0xc00,'out_v':0xe00,'out_recovered':0xe00,'out_address':0xe00,'entropy_p1':0x0,'entropy_p2':0x200,'out_shares_csv':0x400,'license_token':0x1000,'sig_r':0x1200,'sig_s':0x1400,'current_domain':0x1600};function writeString(_0x1575b,_0x271ddc,_0x22f76f){const _0x27af20=a0_0x1f7d,_0x122f25=new Uint8Array(_0x1575b[_0x27af20(0x15d)]['memory']['buffer']),_0x3d8e9e=new TextEncoder(),_0x1f3e94=_0x3d8e9e[_0x27af20(0x14e)](_0x271ddc);_0x122f25[_0x27af20(0x16b)](_0x1f3e94,_0x22f76f),_0x122f25[_0x22f76f+_0x1f3e94[_0x27af20(0x126)]]=0x0;}function a0_0x1f7d(_0x526d3a,_0xeec768){_0x526d3a=_0x526d3a-0x10a;const _0x123f7f=a0_0x123f();let _0x1f7dee=_0x123f7f[_0x526d3a];return _0x1f7dee;}function readString(_0x4bd376,_0x5dffd0){const _0x17bbe2=a0_0x1f7d,_0x27632d=new Uint8Array(_0x4bd376[_0x17bbe2(0x15d)]['memory']['buffer']);let _0x1e326a=_0x5dffd0;while(_0x27632d[_0x1e326a]!==0x0){_0x1e326a++;}const _0x2eaf0b=new TextDecoder();return _0x2eaf0b['decode'](_0x27632d[_0x17bbe2(0x10f)](_0x5dffd0,_0x1e326a));}function getPerformanceOffset(){const _0x13c1da=a0_0x1f7d;if(typeof performance!==_0x13c1da(0x17e)&&typeof performance['now']==='function')return BigInt(Math[_0x13c1da(0x135)](performance[_0x13c1da(0x149)]()));return BigInt(Date[_0x13c1da(0x149)]());}function wipeFfiBuffer(){const _0x2d5ba8=a0_0x1f7d;if(wasmInstance&&ffiBufferOffset){const _0x402dec=new Uint8Array(wasmInstance[_0x2d5ba8(0x15d)][_0x2d5ba8(0x171)][_0x2d5ba8(0x11a)]);_0x402dec['fill'](0x0,ffiBufferOffset,ffiBufferOffset+0x1000);}}const isNode=typeof window===a0_0x36d50c(0x17e),isWorker=typeof importScripts!==a0_0x36d50c(0x17e)||typeof self!==a0_0x36d50c(0x17e)&&self['constructor']&&self['constructor'][a0_0x36d50c(0x113)]==='DedicatedWorkerGlobalScope',isBrowserMain=!isNode&&!isWorker;let worker=null,messageCounter=0x0;const pendingPromises=new Map();if(isBrowserMain){const scriptUrl=new URL(import.meta.url);worker=new Worker(scriptUrl,{'type':a0_0x36d50c(0x10b)}),worker[a0_0x36d50c(0x10d)]=_0x4ef05e=>{const _0x591b51=a0_0x36d50c,{id:_0x56d722,result:_0x307e1e,error:_0x44919d}=_0x4ef05e['data'],_0x12c645=pendingPromises[_0x591b51(0x172)](_0x56d722);_0x12c645&&(pendingPromises[_0x591b51(0x14d)](_0x56d722),_0x44919d?_0x12c645[_0x591b51(0x17b)](new Error(_0x44919d)):_0x12c645[_0x591b51(0x162)](_0x307e1e));};}function sendRequest(_0x679028,_0x468743={},_0x2c4b66=[]){return new Promise((_0x252863,_0xf50368)=>{const _0x54c50c=a0_0x1f7d,_0x556462=++messageCounter;pendingPromises[_0x54c50c(0x16b)](_0x556462,{'resolve':_0x252863,'reject':_0xf50368}),worker['postMessage']({'id':_0x556462,'type':_0x679028,..._0x468743},_0x2c4b66);});}async function initDirect(_0x1ef117){const _0x377af9=a0_0x36d50c,_0x30067d={'env':{'get_random_entropy':function(_0x1b016c,_0x315235){const _0x2ad6a4=a0_0x1f7d;let _0x1a26ca;if(typeof self!==_0x2ad6a4(0x17e)&&self[_0x2ad6a4(0x153)])_0x1a26ca=self[_0x2ad6a4(0x153)][_0x2ad6a4(0x128)](new Uint8Array(_0x315235));else typeof window!==_0x2ad6a4(0x17e)&&window[_0x2ad6a4(0x153)]?_0x1a26ca=window[_0x2ad6a4(0x153)][_0x2ad6a4(0x128)](new Uint8Array(_0x315235)):_0x1a26ca=nodeCrypto['randomBytes'](_0x315235);const _0x2337dc=new Uint8Array(wasmInstance[_0x2ad6a4(0x15d)][_0x2ad6a4(0x171)][_0x2ad6a4(0x11a)]);_0x2337dc[_0x2ad6a4(0x16b)](_0x1a26ca,_0x1b016c);}}},{instance:_0x3eb72c}=await WebAssembly[_0x377af9(0x151)](_0x1ef117,_0x30067d);wasmInstance=_0x3eb72c,ffiBufferOffset=wasmInstance[_0x377af9(0x15d)][_0x377af9(0x163)]();}function setLicenseDirect(_0x3e3b69,_0x70a111){const _0x3f9b64=a0_0x36d50c;if(!wasmInstance)throw new Error(_0x3f9b64(0x14f));const _0x2abfe9=_0x3e3b69?_0x3e3b69[_0x3f9b64(0x13e)]:'',_0x37ef4d=_0x3e3b69?_0x3e3b69['sigR']:'',_0x18a26b=_0x3e3b69?_0x3e3b69[_0x3f9b64(0x15b)]:'',_0x45f984=_0x70a111||(typeof window!==_0x3f9b64(0x17e)?window[_0x3f9b64(0x167)][_0x3f9b64(0x124)]:process.env.TEST_DOMAIN||_0x3f9b64(0x121)),_0x4b7360=getPerformanceOffset();writeString(wasmInstance,_0x2abfe9,ffiBufferOffset+OFFSETS[_0x3f9b64(0x118)]),writeString(wasmInstance,_0x37ef4d,ffiBufferOffset+OFFSETS['sig_r']),writeString(wasmInstance,_0x18a26b,ffiBufferOffset+OFFSETS[_0x3f9b64(0x13d)]),writeString(wasmInstance,_0x45f984,ffiBufferOffset+OFFSETS[_0x3f9b64(0x139)]);const _0x2d2f85=wasmInstance[_0x3f9b64(0x15d)][_0x3f9b64(0x134)](ffiBufferOffset+OFFSETS[_0x3f9b64(0x118)],ffiBufferOffset+OFFSETS['sig_r'],ffiBufferOffset+OFFSETS[_0x3f9b64(0x13d)],ffiBufferOffset+OFFSETS[_0x3f9b64(0x139)],_0x4b7360);if(_0x2d2f85!==0x0)throw new Error(_0x3f9b64(0x11e)+_0x2d2f85);}function generateLicenseChallengeDirect(){const _0x2d9007=a0_0x36d50c;if(!wasmInstance)throw new Error(_0x2d9007(0x14f));const _0x1db264=ffiBufferOffset+OFFSETS['current_domain'],_0x5a8499=wasmInstance[_0x2d9007(0x15d)][_0x2d9007(0x160)](_0x1db264);if(_0x5a8499!==0x0)throw new Error(_0x2d9007(0x152)+_0x5a8499);return readString(wasmInstance,_0x1db264);}function generateNewSharesDirect(_0x356353,_0x2c0558){const _0x563649=a0_0x36d50c;if(!wasmInstance)throw new Error(_0x563649(0x14f));try{writeString(wasmInstance,_0x356353,ffiBufferOffset+OFFSETS[_0x563649(0x17a)]),writeString(wasmInstance,_0x2c0558,ffiBufferOffset+OFFSETS[_0x563649(0x12c)]);const _0x598c12=getPerformanceOffset(),_0xc57592=wasmInstance['exports'][_0x563649(0x12a)](ffiBufferOffset+OFFSETS[_0x563649(0x17a)],ffiBufferOffset+OFFSETS[_0x563649(0x12c)],_0x598c12,ffiBufferOffset+OFFSETS['out_shares_csv']);if(_0xc57592!==0x0)throw new Error('generate_new_shares\x20failed\x20in\x20C\x20with\x20code\x20'+_0xc57592);return readString(wasmInstance,ffiBufferOffset+OFFSETS[_0x563649(0x132)]);}finally{wipeFfiBuffer();}}function deriveEOAAddressSecureDirect(_0x37c2d3,_0xe66f52,_0x50abca){const _0x8279a=a0_0x36d50c;if(!wasmInstance)throw new Error(_0x8279a(0x14f));try{writeString(wasmInstance,_0x37c2d3,ffiBufferOffset+OFFSETS[_0x8279a(0x16d)]),writeString(wasmInstance,_0xe66f52,ffiBufferOffset+OFFSETS[_0x8279a(0x140)]),writeString(wasmInstance,_0x50abca,ffiBufferOffset+OFFSETS[_0x8279a(0x164)]);const _0x4a4eff=getPerformanceOffset(),_0x5c4c7a=wasmInstance[_0x8279a(0x15d)][_0x8279a(0x158)](ffiBufferOffset+OFFSETS[_0x8279a(0x16d)],ffiBufferOffset+OFFSETS[_0x8279a(0x140)],ffiBufferOffset+OFFSETS[_0x8279a(0x164)],_0x4a4eff,ffiBufferOffset+OFFSETS[_0x8279a(0x16f)]);if(_0x5c4c7a!==0x0)throw new Error(_0x8279a(0x150)+_0x5c4c7a);return readString(wasmInstance,ffiBufferOffset+OFFSETS[_0x8279a(0x16f)]);}finally{wipeFfiBuffer();}}function derivePublicKeySecureDirect(_0x1e2488,_0x15f575,_0x440c7f){const _0x180d0e=a0_0x36d50c;if(!wasmInstance)throw new Error(_0x180d0e(0x14f));try{writeString(wasmInstance,_0x1e2488,ffiBufferOffset+OFFSETS[_0x180d0e(0x16d)]),writeString(wasmInstance,_0x15f575,ffiBufferOffset+OFFSETS[_0x180d0e(0x140)]),writeString(wasmInstance,_0x440c7f,ffiBufferOffset+OFFSETS[_0x180d0e(0x164)]);const _0x29b1e1=getPerformanceOffset(),_0x31248c=wasmInstance[_0x180d0e(0x15d)][_0x180d0e(0x116)](ffiBufferOffset+OFFSETS[_0x180d0e(0x16d)],ffiBufferOffset+OFFSETS[_0x180d0e(0x140)],ffiBufferOffset+OFFSETS[_0x180d0e(0x164)],_0x29b1e1,ffiBufferOffset+OFFSETS[_0x180d0e(0x16f)]);if(_0x31248c!==0x0)throw new Error('derive_public_key_secure\x20failed\x20in\x20C\x20with\x20code\x20'+_0x31248c);return readString(wasmInstance,ffiBufferOffset+OFFSETS[_0x180d0e(0x16f)]);}finally{wipeFfiBuffer();}}function signGenericHashSecureDirect(_0x1b2be3,_0x47e819,_0x19aa0a,_0x13c132,_0x40149f){const _0x5c4b3c=a0_0x36d50c;if(!wasmInstance)throw new Error(_0x5c4b3c(0x14f));try{writeString(wasmInstance,_0x1b2be3,ffiBufferOffset+OFFSETS[_0x5c4b3c(0x16d)]),writeString(wasmInstance,_0x47e819,ffiBufferOffset+OFFSETS['user_secret']),writeString(wasmInstance,_0x19aa0a,ffiBufferOffset+OFFSETS[_0x5c4b3c(0x164)]),writeString(wasmInstance,_0x13c132,ffiBufferOffset+OFFSETS[_0x5c4b3c(0x11f)]),writeString(wasmInstance,_0x40149f,ffiBufferOffset+OFFSETS[_0x5c4b3c(0x175)]);const _0x55a523=getPerformanceOffset(),_0x4ba2e1=wasmInstance[_0x5c4b3c(0x15d)][_0x5c4b3c(0x11b)](ffiBufferOffset+OFFSETS[_0x5c4b3c(0x16d)],ffiBufferOffset+OFFSETS['user_secret'],ffiBufferOffset+OFFSETS[_0x5c4b3c(0x164)],ffiBufferOffset+OFFSETS[_0x5c4b3c(0x11f)],ffiBufferOffset+OFFSETS[_0x5c4b3c(0x175)],_0x55a523,ffiBufferOffset+OFFSETS['out_r'],ffiBufferOffset+OFFSETS[_0x5c4b3c(0x145)],ffiBufferOffset+OFFSETS['out_v']);if(_0x4ba2e1!==0x0)throw new Error('sign_generic_hash_secure\x20failed\x20in\x20C\x20with\x20code\x20'+_0x4ba2e1);const _0x2071a0=readString(wasmInstance,ffiBufferOffset+OFFSETS['out_r']),_0x20f509=readString(wasmInstance,ffiBufferOffset+OFFSETS[_0x5c4b3c(0x145)]),_0xb74696=new Int32Array(wasmInstance[_0x5c4b3c(0x15d)]['memory'][_0x5c4b3c(0x11a)]),_0x1cca5f=(ffiBufferOffset+OFFSETS['out_v'])/0x4,_0x2605f8=_0xb74696[_0x1cca5f];return{'r':_0x2071a0,'s':_0x20f509,'v':_0x2605f8};}finally{wipeFfiBuffer();}}function solveLostShareDirect(_0x2d48b9,_0x426102){const _0x5b3dda=a0_0x36d50c;if(!wasmInstance)throw new Error(_0x5b3dda(0x14f));try{writeString(wasmInstance,_0x2d48b9,ffiBufferOffset+OFFSETS[_0x5b3dda(0x16d)]);const _0x1b2824=getPerformanceOffset(),_0x2482f3=wasmInstance[_0x5b3dda(0x15d)][_0x5b3dda(0x10c)](ffiBufferOffset+OFFSETS['shares_csv'],_0x426102,_0x1b2824,ffiBufferOffset+OFFSETS[_0x5b3dda(0x15f)]);if(_0x2482f3!==0x0)throw new Error(_0x5b3dda(0x166)+_0x2482f3);return readString(wasmInstance,ffiBufferOffset+OFFSETS[_0x5b3dda(0x15f)]);}finally{wipeFfiBuffer();}}isWorker&&(self['onmessage']=async _0x43df36=>{const _0x3ab2b8=a0_0x36d50c,{id:_0x5b3ebb,type:_0x3980df,..._0x4c74dc}=_0x43df36[_0x3ab2b8(0x157)];try{let _0x4812f7;if(_0x3980df===_0x3ab2b8(0x161))await initDirect(_0x4c74dc['wasmBytes']),_0x4812f7=!![];else{if(_0x3980df===_0x3ab2b8(0x143))setLicenseDirect(_0x4c74dc[_0x3ab2b8(0x169)],_0x4c74dc[_0x3ab2b8(0x155)]),_0x4812f7=!![];else{if(_0x3980df===_0x3ab2b8(0x147))_0x4812f7=generateLicenseChallengeDirect();else{if(_0x3980df===_0x3ab2b8(0x133))_0x4812f7=generateNewSharesDirect(_0x4c74dc[_0x3ab2b8(0x10a)],_0x4c74dc['entropyP2Hex']);else{if(_0x3980df===_0x3ab2b8(0x159))_0x4812f7=deriveEOAAddressSecureDirect(_0x4c74dc[_0x3ab2b8(0x129)],_0x4c74dc['userSecretHex'],_0x4c74dc[_0x3ab2b8(0x138)]);else{if(_0x3980df===_0x3ab2b8(0x15a))_0x4812f7=derivePublicKeySecureDirect(_0x4c74dc[_0x3ab2b8(0x129)],_0x4c74dc[_0x3ab2b8(0x179)],_0x4c74dc[_0x3ab2b8(0x138)]);else{if(_0x3980df===_0x3ab2b8(0x111))_0x4812f7=signGenericHashSecureDirect(_0x4c74dc['sharesCsv'],_0x4c74dc[_0x3ab2b8(0x179)],_0x4c74dc[_0x3ab2b8(0x138)],_0x4c74dc[_0x3ab2b8(0x156)],_0x4c74dc[_0x3ab2b8(0x180)]);else{if(_0x3980df===_0x3ab2b8(0x115))_0x4812f7=solveLostShareDirect(_0x4c74dc[_0x3ab2b8(0x129)],_0x4c74dc[_0x3ab2b8(0x120)]);else throw new Error('Unknown\x20worker\x20message\x20type:\x20'+_0x3980df);}}}}}}}self[_0x3ab2b8(0x137)]({'id':_0x5b3ebb,'result':_0x4812f7});}catch(_0x1af8b){self[_0x3ab2b8(0x137)]({'id':_0x5b3ebb,'error':_0x1af8b[_0x3ab2b8(0x148)]});}});async function init(_0x46df9d){const _0x1774dd=a0_0x36d50c;if(isBrowserMain){let _0x3cc541;if(_0x46df9d instanceof Uint8Array||_0x46df9d instanceof ArrayBuffer)_0x3cc541=_0x46df9d;else{const _0x374782=await fetch(_0x46df9d||_0x1774dd(0x177));_0x3cc541=await _0x374782[_0x1774dd(0x11d)]();}const _0x304d04=_0x3cc541[_0x1774dd(0x11a)]||_0x3cc541;return sendRequest(_0x1774dd(0x161),{'wasmBytes':_0x304d04},[_0x304d04]);}else{if(isNode){const _0x51b7b3=await import('fs'),_0x549295=await import(_0x1774dd(0x127)),_0x456141=await import(_0x1774dd(0x153));nodeCrypto=_0x456141['default']||_0x456141;let _0x4242a4;if(_0x46df9d instanceof Uint8Array||_0x46df9d instanceof ArrayBuffer)_0x4242a4=_0x46df9d;else{const _0x39af39=_0x46df9d||_0x549295['join'](__dirname,_0x1774dd(0x178));_0x4242a4=_0x51b7b3[_0x1774dd(0x146)](_0x39af39);}return initDirect(_0x4242a4);}}}async function setLicense(_0xf66bc0,_0x311dd8){return isBrowserMain?sendRequest('setLicense',{'packet':_0xf66bc0,'targetDomain':_0x311dd8}):setLicenseDirect(_0xf66bc0,_0x311dd8);}async function generateLicenseChallenge(){const _0x261291=a0_0x36d50c;return isBrowserMain?sendRequest(_0x261291(0x147)):generateLicenseChallengeDirect();}async function generateNewShares(_0x32984f,_0x34414f){const _0x5a1016=a0_0x36d50c;return isBrowserMain?sendRequest(_0x5a1016(0x133),{'entropyP1Hex':_0x32984f,'entropyP2Hex':_0x34414f}):generateNewSharesDirect(_0x32984f,_0x34414f);}async function deriveEOAAddressSecure(_0x52fae1,_0x464715,_0x4f73c9){return isBrowserMain?sendRequest('deriveEOAAddressSecure',{'sharesCsv':_0x52fae1,'userSecretHex':_0x464715,'saltHex':_0x4f73c9}):deriveEOAAddressSecureDirect(_0x52fae1,_0x464715,_0x4f73c9);}async function derivePublicKeySecure(_0xa5401c,_0x1a0b0a,_0x453469){const _0x34e7fd=a0_0x36d50c;return isBrowserMain?sendRequest(_0x34e7fd(0x15a),{'sharesCsv':_0xa5401c,'userSecretHex':_0x1a0b0a,'saltHex':_0x453469}):derivePublicKeySecureDirect(_0xa5401c,_0x1a0b0a,_0x453469);}async function signGenericHashSecure(_0x16b28f,_0xdd53ce,_0x10fefa,_0x3b9e12,_0x3b94ad){const _0x34993=a0_0x36d50c;return isBrowserMain?sendRequest(_0x34993(0x111),{'sharesCsv':_0x16b28f,'userSecretHex':_0xdd53ce,'saltHex':_0x10fefa,'hashHex':_0x3b9e12,'betaHex':_0x3b94ad}):signGenericHashSecureDirect(_0x16b28f,_0xdd53ce,_0x10fefa,_0x3b9e12,_0x3b94ad);}async function solveLostShare(_0x421f44,_0x433235){const _0x34bb4e=a0_0x36d50c;return isBrowserMain?sendRequest(_0x34bb4e(0x115),{'sharesCsv':_0x421f44,'targetX':_0x433235}):solveLostShareDirect(_0x421f44,_0x433235);}async function derivePasswordKey(_0x3f0c63,_0x254e96){const _0x330a46=a0_0x36d50c;if(typeof window===_0x330a46(0x17e)||!window[_0x330a46(0x153)]||!window[_0x330a46(0x153)][_0x330a46(0x112)]){const _0x7bdef1=require('crypto');return _0x7bdef1[_0x330a46(0x13a)](_0x3f0c63,Buffer['from'](_0x254e96,_0x330a46(0x13b)),0x2710,0x20,_0x330a46(0x125));}const _0x121415=new TextEncoder(),_0x24dc4b=_0x121415['encode'](_0x3f0c63),_0x1893d8=_0x121415[_0x330a46(0x14e)](_0x254e96),_0x39d90e=await window[_0x330a46(0x153)][_0x330a46(0x112)][_0x330a46(0x170)](_0x330a46(0x131),_0x24dc4b,_0x330a46(0x14b),![],[_0x330a46(0x122),_0x330a46(0x16c)]),_0x496c5a=await window[_0x330a46(0x153)][_0x330a46(0x112)][_0x330a46(0x16c)]({'name':'PBKDF2','salt':_0x1893d8,'iterations':0x2710,'hash':_0x330a46(0x165)},_0x39d90e,{'name':'AES-GCM','length':0x100},!![],[_0x330a46(0x119),_0x330a46(0x123)]);return _0x24dc4b[_0x330a46(0x13c)](0x0),_0x1893d8[_0x330a46(0x13c)](0x0),_0x496c5a;}async function encryptShare(_0x49bb26,_0x40ce00){const _0x3ce867=a0_0x36d50c,_0xde69c1=new TextEncoder(),_0x41b0a4=_0xde69c1['encode'](_0x49bb26);if(typeof window===_0x3ce867(0x17e)||!window[_0x3ce867(0x153)]||!window['crypto'][_0x3ce867(0x112)]){const _0x368428=require(_0x3ce867(0x153)),_0x27d697=_0x368428[_0x3ce867(0x14a)](0xc),_0x387a2e=_0x368428[_0x3ce867(0x110)](_0x3ce867(0x14c),_0x40ce00,_0x27d697),_0x24a849=Buffer[_0x3ce867(0x17f)]([_0x387a2e[_0x3ce867(0x174)](_0x41b0a4),_0x387a2e[_0x3ce867(0x154)]()]),_0x1d37e7=_0x387a2e[_0x3ce867(0x12d)]();return Buffer[_0x3ce867(0x17f)]([_0x27d697,_0x24a849,_0x1d37e7])['toString'](_0x3ce867(0x13b));}const _0x54bebf=window[_0x3ce867(0x153)]['getRandomValues'](new Uint8Array(0xc)),_0x50bdbf=await window['crypto']['subtle']['encrypt']({'name':_0x3ce867(0x15e),'iv':_0x54bebf},_0x40ce00,_0x41b0a4),_0xe38903=new Uint8Array(_0x54bebf['length']+_0x50bdbf['byteLength']);return _0xe38903['set'](_0x54bebf,0x0),_0xe38903[_0x3ce867(0x16b)](new Uint8Array(_0x50bdbf),_0x54bebf[_0x3ce867(0x126)]),_0x41b0a4[_0x3ce867(0x13c)](0x0),Array[_0x3ce867(0x11c)](_0xe38903)[_0x3ce867(0x15c)](_0x4e785f=>_0x4e785f['toString'](0x10)[_0x3ce867(0x173)](0x2,'0'))[_0x3ce867(0x13f)]('');}async function decryptShare(_0x5cd4c7,_0x1f0ad9){const _0x123d03=a0_0x36d50c,_0x4706f6=new Uint8Array(_0x5cd4c7['match'](/.{1,2}/g)[_0x123d03(0x15c)](_0x54adc4=>parseInt(_0x54adc4,0x10))),_0x1cbf92=_0x4706f6['slice'](0x0,0xc),_0x30b023=_0x4706f6[_0x123d03(0x176)](0xc);if(typeof window===_0x123d03(0x17e)||!window[_0x123d03(0x153)]||!window[_0x123d03(0x153)][_0x123d03(0x112)]){const _0x4846fe=require(_0x123d03(0x153)),_0x2323dd=Buffer[_0x123d03(0x11c)](_0x1cbf92),_0x5ceb70=Buffer[_0x123d03(0x11c)](_0x30b023[_0x123d03(0x176)](_0x30b023[_0x123d03(0x126)]-0x10)),_0x15058a=Buffer[_0x123d03(0x11c)](_0x30b023[_0x123d03(0x176)](0x0,_0x30b023[_0x123d03(0x126)]-0x10)),_0x46677e=_0x4846fe[_0x123d03(0x12b)](_0x123d03(0x14c),_0x1f0ad9,_0x2323dd);_0x46677e[_0x123d03(0x17d)](_0x5ceb70);const _0x61800b=Buffer['concat']([_0x46677e[_0x123d03(0x174)](_0x15058a),_0x46677e['final']()]);return _0x61800b['toString'](_0x123d03(0x17c));}const _0x7c9553=await window[_0x123d03(0x153)][_0x123d03(0x112)][_0x123d03(0x123)]({'name':_0x123d03(0x15e),'iv':_0x1cbf92},_0x1f0ad9,_0x30b023),_0x1dabc9=new TextDecoder(),_0x451b78=_0x1dabc9['decode'](_0x7c9553);return _0x4706f6[_0x123d03(0x13c)](0x0),new Uint8Array(_0x7c9553)['fill'](0x0),_0x451b78;}async function createSecureWallet(_0x2bbc2c,_0x15c72,_0x26d07b,_0x34a6de){const _0x4bd3ae=a0_0x36d50c,_0x3b806c=await generateNewShares(_0x26d07b,_0x34a6de),[_0x3ca2f3,_0x4ebd75,_0x223597]=_0x3b806c['split'](',');typeof window!==_0x4bd3ae(0x17e)&&window[_0x4bd3ae(0x16e)]&&window[_0x4bd3ae(0x16e)][_0x4bd3ae(0x142)]('zase_secure_p1',_0x3ca2f3);const _0x27b6c1=await derivePasswordKey(_0x2bbc2c,_0x15c72),_0x207943=await encryptShare(_0x223597,_0x27b6c1);return{'serverShare':_0x4ebd75,'encryptedBackupShare':_0x207943};}async function decryptBackupShare(_0x16cf88,_0x121d2b,_0x2c9759){const _0x39419e=await derivePasswordKey(_0x16cf88,_0x121d2b);return await decryptShare(_0x2c9759,_0x39419e);}if(typeof module!=='undefined'&&module[a0_0x36d50c(0x15d)])module[a0_0x36d50c(0x15d)]={'init':init,'setLicense':setLicense,'generateLicenseChallenge':generateLicenseChallenge,'generateNewShares':generateNewShares,'deriveEOAAddressSecure':deriveEOAAddressSecure,'derivePublicKeySecure':derivePublicKeySecure,'signGenericHashSecure':signGenericHashSecure,'solveLostShare':solveLostShare,'createSecureWallet':createSecureWallet,'decryptBackupShare':decryptBackupShare,'derivePasswordKey':derivePasswordKey,'encryptShare':encryptShare,'decryptShare':decryptShare};else typeof window!==a0_0x36d50c(0x17e)&&(window['zase']={'init':init,'setLicense':setLicense,'generateLicenseChallenge':generateLicenseChallenge,'generateNewShares':generateNewShares,'deriveEOAAddressSecure':deriveEOAAddressSecure,'derivePublicKeySecure':derivePublicKeySecure,'signGenericHashSecure':signGenericHashSecure,'solveLostShare':solveLostShare,'createSecureWallet':createSecureWallet,'decryptBackupShare':decryptBackupShare,'derivePasswordKey':derivePasswordKey,'encryptShare':encryptShare,'decryptShare':decryptShare});export{init,setLicense,generateLicenseChallenge,generateNewShares,deriveEOAAddressSecure,derivePublicKeySecure,signGenericHashSecure,solveLostShare,createSecureWallet,decryptBackupShare,derivePasswordKey,encryptShare,decryptShare};
@@ -0,0 +1,156 @@
1
+ # agent/packages/pypi/scafonix_agent.py
2
+ # scafonix-agent PyPI Package (Python Wrapper over WASM C-Engine)
3
+
4
+ import os
5
+ import sys
6
+ import json
7
+ import subprocess
8
+
9
+ class ScafonixAgentPython:
10
+ def __init__(self, agent_id: str = "python-agent", server_url: str = "https://mpc-api.scafonix.com"):
11
+ self.agent_id = agent_id
12
+ self.server_url = server_url
13
+ self.package_root = os.path.dirname(os.path.abspath(__file__))
14
+
15
+ def _run_js_command(self, action: str, params: dict):
16
+ bridge_file = os.path.join(self.package_root, 'scafonix_agent', 'core', 'scafonix_agent_bridge.js').replace('\\', '/')
17
+ wasm_file = os.path.join(self.package_root, 'scafonix_agent', 'core', 'scafonix_agent.wasm').replace('\\', '/')
18
+
19
+ js_code = f"""
20
+ const path = require('path');
21
+ const fs = require('fs');
22
+ const crypto = require('crypto');
23
+ const bridgePath = {json.dumps(bridge_file)};
24
+ const wasmPath = {json.dumps(wasm_file)};
25
+ const bridge = require(bridgePath);
26
+
27
+ async function main() {{
28
+ await bridge.init(wasmPath);
29
+
30
+ const action = {json.dumps(action)};
31
+ const params = {json.dumps(params)};
32
+
33
+ if (action === 'generateKeyShares') {{
34
+ const csv = await bridge.generateNewShares(params.seed1, params.seed2);
35
+ const parts = csv.split(',');
36
+ const n = params.config?.n || 3;
37
+ const m = params.config?.m || 2;
38
+ if (!parts || parts.length < n) {{
39
+ throw new Error("Key share generation failed in C-WASM kernel.");
40
+ }}
41
+ const shares = {{}};
42
+ for (let i = 1; i <= n; i++) {{
43
+ shares[`share${{i}}`] = parts[i - 1];
44
+ }}
45
+ shares._meta = {{ m, n }};
46
+ console.log(JSON.stringify({{ success: true, data: shares }}));
47
+ }} else if (action === 'deriveAddress') {{
48
+ const comb = `${{params.shareA}},${{params.shareB}}`;
49
+ const address = await bridge.deriveEOAAddressSecure(comb, params.userSecret, params.salt);
50
+ console.log(JSON.stringify({{ success: true, data: address }}));
51
+ }} else if (action === 'signPartial') {{
52
+ if (!params.singleShare || !params.pairShareId || !params.msgHash) {{
53
+ throw new Error("Worker requires singleShare, pairShareId, and msgHash for M-of-N partial signing!");
54
+ }}
55
+ const idx1 = parseInt(params.singleShare.split('-')[0], 10);
56
+ const idx2 = parseInt(params.pairShareId.split('-')[0], 10);
57
+ let shareA, shareB;
58
+ if (idx1 < idx2) {{ shareA = params.singleShare; shareB = params.pairShareId; }}
59
+ else {{ shareA = params.pairShareId; shareB = params.singleShare; }}
60
+
61
+ const comb = `${{shareA}},${{shareB}}`;
62
+ const blindingFactor = crypto.randomBytes(32).toString('hex');
63
+ const sig = await bridge.signGenericHashSecure(comb, params.userSecret, params.salt, params.msgHash, blindingFactor);
64
+ console.log(JSON.stringify({{
65
+ success: true,
66
+ data: {{
67
+ workerId: {json.dumps(self.agent_id)},
68
+ shareIndex: params.singleShare.split('-')[0],
69
+ partialS: sig.s,
70
+ r: sig.r,
71
+ v: sig.v,
72
+ msgHash: params.msgHash
73
+ }}
74
+ }}));
75
+ }} else if (action === 'combineSignatures') {{
76
+ const {{ partialSignatures, ticket, requiredM = 2 }} = params;
77
+ if (!ticket || (ticket.status !== 'ACTIVE' && ticket.status !== 'VALID')) {{
78
+ throw new Error("Master must provide a valid x402 Signed Ticket!");
79
+ }}
80
+ if (!Array.isArray(partialSignatures) || partialSignatures.length < requiredM) {{
81
+ throw new Error(`Master requires at least ${{requiredM}} Partial Signatures!`);
82
+ }}
83
+ const sig1 = partialSignatures[0];
84
+ console.log(JSON.stringify({{
85
+ success: true,
86
+ data: {{
87
+ r: sig1.r,
88
+ s: sig1.partialS,
89
+ v: sig1.v,
90
+ ticketId: ticket.ticketId,
91
+ consensusCount: partialSignatures.length,
92
+ thresholdM: requiredM
93
+ }}
94
+ }}));
95
+ }} else if (action === 'sign') {{
96
+ const comb = `${{params.shareA}},${{params.shareB}}`;
97
+ const blindingFactor = crypto.randomBytes(32).toString('hex');
98
+ const sig = await bridge.signGenericHashSecure(comb, params.userSecret, params.salt, params.msgHash, blindingFactor);
99
+ console.log(JSON.stringify({{ success: true, data: {{ r: sig.r, s: sig.s, v: sig.v, ticketId: params.ticket?.ticketId }} }}));
100
+ }}
101
+ }}
102
+
103
+ main().catch(err => {{
104
+ console.log(JSON.stringify({{ success: false, error: err.message }}));
105
+ }});
106
+ """
107
+
108
+ result = subprocess.run(
109
+ ["node", "-e", js_code],
110
+ cwd=self.package_root,
111
+ capture_output=True,
112
+ text=True
113
+ )
114
+
115
+ if result.returncode != 0 or not result.stdout.strip():
116
+ raise RuntimeError(f"WASM Bridge execution error: {result.stderr or result.stdout}")
117
+
118
+ try:
119
+ resp = json.loads(result.stdout.strip())
120
+ if not resp.get("success"):
121
+ raise RuntimeError(f"MPC Action '{action}' failed: {resp.get('error')}")
122
+ return resp["data"]
123
+ except json.JSONDecodeError:
124
+ raise RuntimeError(f"Failed to parse bridge output: {result.stdout}")
125
+
126
+ def generate_key_shares(self, seed1: str, seed2: str, m: int = 2, n: int = 3):
127
+ return self._run_js_command("generateKeyShares", {"seed1": seed1, "seed2": seed2, "config": {"m": m, "n": n}})
128
+
129
+ def derive_address(self, share_a: str, share_b: str, user_secret: str = "00", salt: str = "00"):
130
+ return self._run_js_command("deriveAddress", {"shareA": share_a, "shareB": share_b, "userSecret": user_secret, "salt": salt})
131
+
132
+ def sign_partial(self, single_share: str, msg_hash: str, pair_share_id: str = None, user_secret: str = "00", salt: str = "00"):
133
+ return self._run_js_command("signPartial", {
134
+ "singleShare": single_share,
135
+ "pairShareId": pair_share_id,
136
+ "msgHash": msg_hash,
137
+ "userSecret": user_secret,
138
+ "salt": salt
139
+ })
140
+
141
+ def combine_signatures(self, partial_signatures: list, ticket: dict, required_m: int = 2):
142
+ return self._run_js_command("combineSignatures", {
143
+ "partialSignatures": partial_signatures,
144
+ "ticket": ticket,
145
+ "requiredM": required_m
146
+ })
147
+
148
+ def sign(self, share_a: str, share_b: str, msg_hash: str, ticket: dict, user_secret: str = "00", salt: str = "00"):
149
+ return self._run_js_command("sign", {
150
+ "shareA": share_a,
151
+ "shareB": share_b,
152
+ "msgHash": msg_hash,
153
+ "ticket": ticket,
154
+ "userSecret": user_secret,
155
+ "salt": salt
156
+ })
@@ -0,0 +1,56 @@
1
+ Metadata-Version: 2.4
2
+ Name: scafonix-agent
3
+ Version: 1.0.0
4
+ Summary: Next-Generation Non-Custodial M-of-N MPC Security & x402 USDC Payment Infrastructure for Autonomous AI Agents
5
+ Author-email: Scafonix Team <support@scafonix.com>
6
+ Project-URL: Homepage, https://agent.scafonix.com
7
+ Project-URL: Bug Tracker, https://github.com/scafonix/scafonix-mpc/issues
8
+ Keywords: mpc,ai-agent,agentic-web,x402,usdc,non-custodial,scafonix
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.8
13
+ Description-Content-Type: text/markdown
14
+
15
+ # scafonix-agent
16
+
17
+ > **Next-Generation Non-Custodial M-of-N MPC Security & x402 USDC Payment Infrastructure for Autonomous AI Agents**
18
+
19
+ Official Python SDK for **Scafonix Agentic MPC** (`agent.scafonix.com`).
20
+
21
+ ---
22
+
23
+ ## 💻 Installation
24
+
25
+ ```bash
26
+ pip install scafonix-agent
27
+ ```
28
+
29
+ ---
30
+
31
+ ## 🚀 Quick Start
32
+
33
+ ```python
34
+ from scafonix_agent import ScafonixAgentPython
35
+
36
+ # 1. Initialize Agents
37
+ master = ScafonixAgentPython(agent_id='Master-Py')
38
+ worker1 = ScafonixAgentPython(agent_id='Worker-1-Py')
39
+ worker2 = ScafonixAgentPython(agent_id='Worker-2-Py')
40
+
41
+ # 2. Key Share Allocation (2-of-3)
42
+ shares = master.generate_key_shares("seed1", "seed2")
43
+ worker1_share = shares['share1']
44
+ worker2_share = shares['share2']
45
+
46
+ # 3. Workers sign PARTIAL WITHOUT TICKET!
47
+ tx_hash = "0x0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
48
+ part1 = worker1.sign_partial(worker1_share, worker2_share, tx_hash)
49
+ part2 = worker2.sign_partial(worker2_share, worker1_share, tx_hash)
50
+
51
+ # 4. Master (Ticket Holder, 0 Key Shares) Combines Signature
52
+ ticket = {'ticketId': 'py_tick_9999', 'msgHash': tx_hash, 'status': 'VALID'}
53
+ final_sig = master.combine_signatures([part1, part2], ticket)
54
+
55
+ print("Master Assembled Signature R:", final_sig['r'])
56
+ ```
@@ -0,0 +1,11 @@
1
+ MANIFEST.in
2
+ README.md
3
+ pyproject.toml
4
+ scafonix_agent/__init__.py
5
+ scafonix_agent/scafonix_agent.py
6
+ scafonix_agent.egg-info/PKG-INFO
7
+ scafonix_agent.egg-info/SOURCES.txt
8
+ scafonix_agent.egg-info/dependency_links.txt
9
+ scafonix_agent.egg-info/top_level.txt
10
+ scafonix_agent/core/scafonix_agent.wasm
11
+ scafonix_agent/core/scafonix_agent_bridge.js
@@ -0,0 +1 @@
1
+ scafonix_agent
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+