@silvana-one/coordination 1.0.37 → 1.0.39

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/src/keypair.ts ADDED
@@ -0,0 +1,106 @@
1
+ import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
2
+ import { Ed25519PublicKey } from "@mysten/sui/keypairs/ed25519";
3
+ import { fromBase64, toBase64 } from "@mysten/sui/utils";
4
+
5
+ export interface GeneratedKeypair {
6
+ address: string;
7
+ suiPrivateKey: string;
8
+ keypair: Ed25519Keypair;
9
+ }
10
+
11
+ /**
12
+ * Generates a new Ed25519 keypair
13
+ * @returns Generated keypair with address, and sui private key
14
+ */
15
+ export function generateEd25519(): GeneratedKeypair {
16
+ const keypair = new Ed25519Keypair();
17
+ const suiPrivateKey = keypair.getSecretKey();
18
+ const address = keypair.getPublicKey().toSuiAddress();
19
+
20
+ return {
21
+ address,
22
+ suiPrivateKey,
23
+ keypair,
24
+ };
25
+ }
26
+
27
+ /**
28
+ * Signs a message with the given secret key
29
+ * @param secretKey - 32-byte secret key as base64 or bech32 string
30
+ * @param message - Message to sign as number[] or Uint8Array
31
+ * @returns Base64-encoded serialized signature string
32
+ */
33
+ export async function signMessage(params: {
34
+ secretKey: string;
35
+ message: number[] | Uint8Array;
36
+ }): Promise<string> {
37
+ const { secretKey, message } = params;
38
+ const keypair = Ed25519Keypair.fromSecretKey(secretKey);
39
+
40
+ // Convert message to Uint8Array if needed
41
+ const messageBytes =
42
+ message instanceof Uint8Array ? message : new Uint8Array(message);
43
+
44
+ // Sign the message - this returns just the 64-byte signature
45
+ const signature = await keypair.sign(messageBytes);
46
+
47
+ // Get the public key bytes
48
+ const publicKeyBytes = keypair.getPublicKey().toRawBytes();
49
+
50
+ // Construct the full Sui signature format: flag || signature || publicKey
51
+ const fullSignature = new Uint8Array(1 + signature.length + publicKeyBytes.length);
52
+ fullSignature[0] = 0x00; // Ed25519 flag
53
+ fullSignature.set(signature, 1);
54
+ fullSignature.set(publicKeyBytes, 1 + signature.length);
55
+
56
+ // Return as base64 string (what the SDK expects)
57
+ return toBase64(fullSignature);
58
+ }
59
+
60
+ /**
61
+ * Verifies a signature against an address
62
+ * @param address - Sui address
63
+ * @param message - Original message as number[] or Uint8Array
64
+ * @param signature - Base64-encoded serialized signature string
65
+ * @returns true if signature is valid, false otherwise
66
+ */
67
+ export async function verifyWithAddress(
68
+ address: string,
69
+ message: number[] | Uint8Array,
70
+ signature: string
71
+ ): Promise<boolean> {
72
+ // Convert message to Uint8Array if needed
73
+ const messageBytes =
74
+ message instanceof Uint8Array ? message : new Uint8Array(message);
75
+
76
+ try {
77
+ // Decode the base64 signature
78
+ const sigBytes = fromBase64(signature);
79
+
80
+ if (sigBytes.length !== 97) {
81
+ return false;
82
+ }
83
+
84
+ // Check the flag byte (0x00 for Ed25519)
85
+ if (sigBytes[0] !== 0x00) {
86
+ return false;
87
+ }
88
+
89
+ // Extract the public key (last 32 bytes)
90
+ const publicKeyBytes = sigBytes.slice(65, 97);
91
+
92
+ // Create an Ed25519PublicKey from the raw bytes
93
+ const publicKey = new Ed25519PublicKey(publicKeyBytes);
94
+
95
+ // Verify the derived address matches
96
+ const derivedAddress = publicKey.toSuiAddress();
97
+ if (derivedAddress !== address) {
98
+ return false;
99
+ }
100
+
101
+ // Verify the signature using the SDK's expected format (base64 string)
102
+ return await publicKey.verify(messageBytes, signature);
103
+ } catch {
104
+ return false;
105
+ }
106
+ }