@visa/cli 2.1.1-rc.2 → 2.1.1-rc.4
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/dist/cli.js +103 -105
- package/dist/mcp-server/index.js +16 -16
- package/native/visa-keychain.m +66 -15
- package/package.json +1 -1
- package/server.json +2 -2
package/native/visa-keychain.m
CHANGED
|
@@ -15,6 +15,24 @@ static NSString *kService = @"visa-cli";
|
|
|
15
15
|
static NSString *kKeyAcct = @"attestation-key";
|
|
16
16
|
static NSString *kTokenAcct = @"session-token";
|
|
17
17
|
|
|
18
|
+
static NSString *spkiPublicKeyB64(SecKeyRef key) {
|
|
19
|
+
SecKeyRef pubKey = SecKeyCopyPublicKey(key);
|
|
20
|
+
if (!pubKey) return nil;
|
|
21
|
+
|
|
22
|
+
CFErrorRef pubErr = NULL;
|
|
23
|
+
CFDataRef rawPub = SecKeyCopyExternalRepresentation(pubKey, &pubErr);
|
|
24
|
+
CFRelease(pubKey);
|
|
25
|
+
if (!rawPub) {
|
|
26
|
+
if (pubErr) CFRelease(pubErr);
|
|
27
|
+
return nil;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
NSMutableData *spki = [NSMutableData dataWithBytes:SPKI_HEADER length:sizeof(SPKI_HEADER)];
|
|
31
|
+
[spki appendData:(__bridge NSData *)rawPub];
|
|
32
|
+
CFRelease(rawPub);
|
|
33
|
+
return [spki base64EncodedStringWithOptions:0];
|
|
34
|
+
}
|
|
35
|
+
|
|
18
36
|
// ---------------------------------------------------------------------------
|
|
19
37
|
// Keychain helpers for generic password items
|
|
20
38
|
// ---------------------------------------------------------------------------
|
|
@@ -90,27 +108,59 @@ int cmd_generate_key(void) {
|
|
|
90
108
|
NSString *privB64 = [(__bridge NSData *)rawPriv base64EncodedStringWithOptions:0];
|
|
91
109
|
CFRelease(rawPriv);
|
|
92
110
|
|
|
93
|
-
|
|
94
|
-
SecKeyRef pubKey = SecKeyCopyPublicKey(privKey);
|
|
111
|
+
NSString *pubB64 = spkiPublicKeyB64(privKey);
|
|
95
112
|
CFRelease(privKey);
|
|
96
|
-
if (!
|
|
97
|
-
|
|
98
|
-
CFErrorRef pubErr = NULL;
|
|
99
|
-
CFDataRef rawPub = SecKeyCopyExternalRepresentation(pubKey, &pubErr);
|
|
100
|
-
CFRelease(pubKey);
|
|
101
|
-
if (!rawPub) {
|
|
102
|
-
if (pubErr) CFRelease(pubErr);
|
|
113
|
+
if (!pubB64) {
|
|
103
114
|
printf("ERROR:Failed to export public key\n");
|
|
104
115
|
return 1;
|
|
105
116
|
}
|
|
106
117
|
|
|
107
|
-
NSMutableData *spki = [NSMutableData dataWithBytes:SPKI_HEADER length:sizeof(SPKI_HEADER)];
|
|
108
|
-
[spki appendData:(__bridge NSData *)rawPub];
|
|
109
|
-
CFRelease(rawPub);
|
|
110
|
-
|
|
111
118
|
// Output both keys: OK:<private-b64>:<public-spki-b64>
|
|
112
|
-
printf("OK:%s:%s\n", privB64.UTF8String,
|
|
113
|
-
|
|
119
|
+
printf("OK:%s:%s\n", privB64.UTF8String, pubB64.UTF8String);
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
int cmd_public_key(void) {
|
|
124
|
+
NSFileHandle *input = [NSFileHandle fileHandleWithStandardInput];
|
|
125
|
+
NSData *stdinData = [input readDataToEndOfFile];
|
|
126
|
+
NSString *keyB64 = [[NSString alloc] initWithData:stdinData encoding:NSUTF8StringEncoding];
|
|
127
|
+
keyB64 = [keyB64 stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
|
128
|
+
|
|
129
|
+
if (!keyB64 || keyB64.length == 0) {
|
|
130
|
+
printf("ERROR:No key provided on stdin\n");
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
NSData *rawKey = [[NSData alloc] initWithBase64EncodedString:keyB64 options:0];
|
|
135
|
+
if (!rawKey) {
|
|
136
|
+
printf("ERROR:Invalid base64 key data\n");
|
|
137
|
+
return 1;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
NSDictionary *keyAttrs = @{
|
|
141
|
+
(__bridge id)kSecAttrKeyType: (__bridge id)kSecAttrKeyTypeECSECPrimeRandom,
|
|
142
|
+
(__bridge id)kSecAttrKeyClass: (__bridge id)kSecAttrKeyClassPrivate,
|
|
143
|
+
(__bridge id)kSecAttrKeySizeInBits: @256,
|
|
144
|
+
};
|
|
145
|
+
CFErrorRef importErr = NULL;
|
|
146
|
+
SecKeyRef privKey = SecKeyCreateWithData(
|
|
147
|
+
(__bridge CFDataRef)rawKey,
|
|
148
|
+
(__bridge CFDictionaryRef)keyAttrs,
|
|
149
|
+
&importErr);
|
|
150
|
+
if (!privKey) {
|
|
151
|
+
if (importErr) CFRelease(importErr);
|
|
152
|
+
printf("ERROR:Failed to import key for public export\n");
|
|
153
|
+
return 1;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
NSString *pubB64 = spkiPublicKeyB64(privKey);
|
|
157
|
+
CFRelease(privKey);
|
|
158
|
+
if (!pubB64) {
|
|
159
|
+
printf("ERROR:Failed to export public key\n");
|
|
160
|
+
return 1;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
printf("OK:%s\n", pubB64.UTF8String);
|
|
114
164
|
return 0;
|
|
115
165
|
}
|
|
116
166
|
|
|
@@ -299,6 +349,7 @@ int main(int argc, const char *argv[]) {
|
|
|
299
349
|
}
|
|
300
350
|
const char *cmd = argv[1];
|
|
301
351
|
if (strcmp(cmd, "generate-key") == 0) return cmd_generate_key();
|
|
352
|
+
else if (strcmp(cmd, "public-key") == 0) return cmd_public_key();
|
|
302
353
|
else if (strcmp(cmd, "sign") == 0) {
|
|
303
354
|
if (argc < 3) { fprintf(stderr, "Usage: visa-keychain sign <challenge> [reason]\n"); return 1; }
|
|
304
355
|
return cmd_sign(argv[2], argc >= 4 ? argv[3] : NULL);
|
package/package.json
CHANGED
package/server.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
|
|
3
3
|
"name": "io.github.visa-crypto-labs/visa-cli",
|
|
4
|
-
"version": "2.1.1-rc.
|
|
4
|
+
"version": "2.1.1-rc.4",
|
|
5
5
|
"title": "Visa CLI",
|
|
6
6
|
"description": "AI-powered payments and creative tools for coding agents. Generate images, music, video, query crypto prices, and make purchases — all from your AI coding assistant.",
|
|
7
7
|
"websiteUrl": "https://github.com/Visa-Crypto-Labs/Visa-mono/tree/main/packages/cli#readme",
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
{
|
|
10
10
|
"registryType": "npm",
|
|
11
11
|
"identifier": "@visa/cli",
|
|
12
|
-
"version": "2.1.1-rc.
|
|
12
|
+
"version": "2.1.1-rc.4",
|
|
13
13
|
"transport": {
|
|
14
14
|
"type": "stdio"
|
|
15
15
|
},
|