create-agent 0.0.7 → 0.0.10
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.
- package/.claude/settings.local.json +23 -0
- package/README.md +2 -0
- package/bin/create-agent.js +35 -33
- package/index.js +47 -0
- package/package.json +2 -3
- package/test/index.test.js +66 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"permissions": {
|
|
3
|
+
"allow": [
|
|
4
|
+
"Bash(tree:*)",
|
|
5
|
+
"Bash(git checkout:*)",
|
|
6
|
+
"Bash(git add:*)",
|
|
7
|
+
"Bash(git commit:*)",
|
|
8
|
+
"Bash(node -e:*)",
|
|
9
|
+
"Bash(npm test)",
|
|
10
|
+
"Bash(git pull:*)",
|
|
11
|
+
"Bash(gh pr list:*)",
|
|
12
|
+
"Bash(gh issue list:*)",
|
|
13
|
+
"WebFetch(domain:nostrcg.github.io)",
|
|
14
|
+
"Bash(node bin/create-agent.js:*)",
|
|
15
|
+
"WebSearch",
|
|
16
|
+
"Bash(gh issue view:*)",
|
|
17
|
+
"Bash(gh api:*)",
|
|
18
|
+
"WebFetch(domain:ai-sdk.dev)",
|
|
19
|
+
"WebFetch(domain:github.com)",
|
|
20
|
+
"Bash(git fetch:*)"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
package/README.md
CHANGED
package/bin/create-agent.js
CHANGED
|
@@ -1,35 +1,37 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
//
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
3
|
+
import { generateAgent } from '../index.js'
|
|
4
|
+
|
|
5
|
+
// Generate agent identity
|
|
6
|
+
const { privkey, pubkey, nsec, npub, did } = generateAgent()
|
|
7
|
+
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// CONSOLE OUTPUT
|
|
10
|
+
// =============================================================================
|
|
11
|
+
// First output the initial warning message to stderr
|
|
12
|
+
process.stderr.write('\x1b[36m🤖 Creating new Nostr agent identity...\x1b[0m\n');
|
|
13
|
+
process.stderr.write('\x1b[36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
|
14
|
+
process.stderr.write('\x1b[33m⚠️ IMPORTANT: Keep your private key (nsec/privkey) secret!\x1b[0m\n');
|
|
15
|
+
process.stderr.write('\x1b[33m Never share it with anyone or input it on websites.\x1b[0m\n');
|
|
16
|
+
process.stderr.write('\n');
|
|
17
|
+
|
|
18
|
+
// Then output the Nostr identity information to stderr
|
|
19
|
+
process.stderr.write('\n\x1b[32m📋 Your Nostr Identity:\x1b[0m\n');
|
|
20
|
+
process.stderr.write('\x1b[32m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
|
21
|
+
process.stderr.write(`\x1b[0mPublic Key (hex) : \x1b[33m${pubkey}\x1b[0m\n`);
|
|
22
|
+
process.stderr.write(`\x1b[0mNostr Public Key : \x1b[33m${npub}\x1b[0m\n`);
|
|
23
|
+
process.stderr.write(`\x1b[0mPrivate Key (hex): \x1b[31m${privkey}\x1b[0m\n`);
|
|
24
|
+
process.stderr.write(`\x1b[0mNostr Secret Key : \x1b[31m${nsec}\x1b[0m\n`);
|
|
25
|
+
process.stderr.write('\n');
|
|
26
|
+
process.stderr.write('\x1b[36m🔍 Usage:\x1b[0m\n');
|
|
27
|
+
process.stderr.write('\x1b[0m- Use your npub to identify yourself to others\x1b[0m\n');
|
|
28
|
+
process.stderr.write('\x1b[0m- Add relays to the services array for discovery\x1b[0m\n');
|
|
29
|
+
process.stderr.write('\x1b[0m- Use nsec to sign into Nostr clients (handle with extreme care!)\x1b[0m\n');
|
|
30
|
+
process.stderr.write('\n');
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
// Then output the DID document to stdout with a clear header in the output
|
|
34
|
+
process.stderr.write('\x1b[36m📄 DID Nostr Document:\x1b[0m\n');
|
|
35
|
+
process.stderr.write('\x1b[36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
|
36
|
+
console.log(JSON.stringify(did, null, 2));
|
|
37
|
+
process.stderr.write('\x1b[36m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\x1b[0m\n');
|
package/index.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { generateSecretKey, getPublicKey } from 'nostr-tools/pure'
|
|
2
|
+
import { nip19 } from 'nostr-tools'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Generate a new Nostr agent identity
|
|
6
|
+
* @returns {{ privkey: string, pubkey: string, nsec: string, npub: string, did: object }}
|
|
7
|
+
*/
|
|
8
|
+
export function generateAgent() {
|
|
9
|
+
// Generate cryptographically secure private key (32 bytes)
|
|
10
|
+
const sk = generateSecretKey()
|
|
11
|
+
const privkey = Array.from(sk)
|
|
12
|
+
.map(b => b.toString(16).padStart(2, '0'))
|
|
13
|
+
.join('')
|
|
14
|
+
|
|
15
|
+
// Derive public key using Schnorr signatures
|
|
16
|
+
const pubkey = getPublicKey(sk)
|
|
17
|
+
|
|
18
|
+
// Encode keys in Nostr formats
|
|
19
|
+
const nsec = nip19.nsecEncode(sk)
|
|
20
|
+
const npub = nip19.npubEncode(pubkey)
|
|
21
|
+
|
|
22
|
+
// Create publicKeyMultibase: f (base16-lower) + e701 (secp256k1-pub varint) + 02 (even parity) + pubkey
|
|
23
|
+
const publicKeyMultibase = `fe70102${pubkey}`
|
|
24
|
+
|
|
25
|
+
// Create DID document per https://nostrcg.github.io/did-nostr/
|
|
26
|
+
const did = {
|
|
27
|
+
"@context": [
|
|
28
|
+
"https://w3id.org/did",
|
|
29
|
+
"https://w3id.org/nostr/context"
|
|
30
|
+
],
|
|
31
|
+
"id": `did:nostr:${pubkey}`,
|
|
32
|
+
"type": "DIDNostr",
|
|
33
|
+
"verificationMethod": [
|
|
34
|
+
{
|
|
35
|
+
"id": `did:nostr:${pubkey}#key1`,
|
|
36
|
+
"type": "Multikey",
|
|
37
|
+
"controller": `did:nostr:${pubkey}`,
|
|
38
|
+
"publicKeyMultibase": publicKeyMultibase
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"authentication": ["#key1"],
|
|
42
|
+
"assertionMethod": ["#key1"],
|
|
43
|
+
"service": []
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return { privkey, pubkey, nsec, npub, did }
|
|
47
|
+
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-agent",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.10",
|
|
5
5
|
"description": "create an agent",
|
|
6
|
-
"main": "index.js",
|
|
7
6
|
"scripts": {
|
|
8
|
-
"test": "
|
|
7
|
+
"test": "node --test"
|
|
9
8
|
},
|
|
10
9
|
"bin": {
|
|
11
10
|
"create-agent": "bin/create-agent.js"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { test, describe } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { generateAgent } from '../index.js'
|
|
4
|
+
|
|
5
|
+
describe('generateAgent', () => {
|
|
6
|
+
test('returns all expected properties', () => {
|
|
7
|
+
const agent = generateAgent()
|
|
8
|
+
|
|
9
|
+
assert.ok(agent.privkey, 'should have privkey')
|
|
10
|
+
assert.ok(agent.pubkey, 'should have pubkey')
|
|
11
|
+
assert.ok(agent.nsec, 'should have nsec')
|
|
12
|
+
assert.ok(agent.npub, 'should have npub')
|
|
13
|
+
assert.ok(agent.did, 'should have did')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
test('privkey is 64-character hex string', () => {
|
|
17
|
+
const { privkey } = generateAgent()
|
|
18
|
+
|
|
19
|
+
assert.strictEqual(privkey.length, 64)
|
|
20
|
+
assert.match(privkey, /^[0-9a-f]{64}$/)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
test('pubkey is 64-character hex string', () => {
|
|
24
|
+
const { pubkey } = generateAgent()
|
|
25
|
+
|
|
26
|
+
assert.strictEqual(pubkey.length, 64)
|
|
27
|
+
assert.match(pubkey, /^[0-9a-f]{64}$/)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test('nsec starts with nsec1', () => {
|
|
31
|
+
const { nsec } = generateAgent()
|
|
32
|
+
|
|
33
|
+
assert.ok(nsec.startsWith('nsec1'))
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
test('npub starts with npub1', () => {
|
|
37
|
+
const { npub } = generateAgent()
|
|
38
|
+
|
|
39
|
+
assert.ok(npub.startsWith('npub1'))
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
test('did document has correct structure', () => {
|
|
43
|
+
const { did, pubkey } = generateAgent()
|
|
44
|
+
|
|
45
|
+
assert.deepStrictEqual(did['@context'], [
|
|
46
|
+
'https://www.w3.org/ns/did/v1',
|
|
47
|
+
'https://w3id.org/nostr/context'
|
|
48
|
+
])
|
|
49
|
+
assert.strictEqual(did.id, `did:nostr:${pubkey}`)
|
|
50
|
+
assert.ok(Array.isArray(did.verificationMethod))
|
|
51
|
+
assert.strictEqual(did.verificationMethod[0].type, 'SchnorrVerification2025')
|
|
52
|
+
assert.deepStrictEqual(did.authentication, ['#key1'])
|
|
53
|
+
assert.deepStrictEqual(did.assertionMethod, ['#key1'])
|
|
54
|
+
assert.deepStrictEqual(did.service, [])
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('generates unique keys on each call', () => {
|
|
58
|
+
const agent1 = generateAgent()
|
|
59
|
+
const agent2 = generateAgent()
|
|
60
|
+
|
|
61
|
+
assert.notStrictEqual(agent1.privkey, agent2.privkey)
|
|
62
|
+
assert.notStrictEqual(agent1.pubkey, agent2.pubkey)
|
|
63
|
+
assert.notStrictEqual(agent1.nsec, agent2.nsec)
|
|
64
|
+
assert.notStrictEqual(agent1.npub, agent2.npub)
|
|
65
|
+
})
|
|
66
|
+
})
|