@ghostspeak/sdk
Version:
TypeScript SDK for GhostSpeak AI Agent Commerce Protocol - Production Ready Beta
156 lines (154 loc) • 6.08 kB
JavaScript
import { __export } from './chunk-UP2VWCW5.js';
import { address } from '@solana/addresses';
import bs58 from 'bs58';
// src/utils/signature-verification.ts
var signature_verification_exports = {};
__export(signature_verification_exports, {
createAuthorizationMessage: () => createAuthorizationMessage,
createSignedAuthorization: () => createSignedAuthorization,
deserializeAuthorization: () => deserializeAuthorization,
generateNonce: () => generateNonce,
getAuthorizationId: () => getAuthorizationId,
isAuthorizationExhausted: () => isAuthorizationExhausted,
isAuthorizationExpired: () => isAuthorizationExpired,
serializeAuthorization: () => serializeAuthorization,
signAuthorizationMessage: () => signAuthorizationMessage,
validateAuthorizationNetwork: () => validateAuthorizationNetwork,
verifyAuthorizationSignature: () => verifyAuthorizationSignature
});
var DOMAIN_SEPARATOR = "GhostSpeak Reputation Authorization";
function createAuthorizationMessage(message) {
const components = [];
components.push(Buffer.from(DOMAIN_SEPARATOR, "utf8"));
const agentBytes = bs58.decode(message.agentAddress);
components.push(Buffer.from(agentBytes));
const sourceBytes = bs58.decode(message.authorizedSource);
components.push(Buffer.from(sourceBytes));
const indexLimitBuffer = Buffer.allocUnsafe(8);
indexLimitBuffer.writeBigUInt64BE(BigInt(message.indexLimit));
components.push(indexLimitBuffer);
const expiresAtBuffer = Buffer.allocUnsafe(8);
expiresAtBuffer.writeBigUInt64BE(BigInt(message.expiresAt));
components.push(expiresAtBuffer);
components.push(Buffer.from(message.network, "utf8"));
if (message.nonce) {
components.push(Buffer.from(message.nonce, "utf8"));
}
return Buffer.concat(components);
}
async function signAuthorizationMessage(message, agentKeypair) {
const keypairAddress = agentKeypair.publicKey.toBase58();
if (keypairAddress !== message.agentAddress) {
throw new Error(
`Keypair public key ${keypairAddress} does not match agent address ${message.agentAddress}`
);
}
const messageBuffer = createAuthorizationMessage(message);
const nacl = await import('./nacl-fast-W5BJ3KZ2.js');
const signature = nacl.sign.detached(messageBuffer, agentKeypair.secretKey);
return signature;
}
async function verifyAuthorizationSignature(authorization) {
try {
const message = {
agentAddress: authorization.agentAddress,
authorizedSource: authorization.authorizedSource,
indexLimit: authorization.indexLimit,
expiresAt: authorization.expiresAt,
network: authorization.network,
nonce: authorization.nonce
};
const messageBuffer = createAuthorizationMessage(message);
const nacl = await import('./nacl-fast-W5BJ3KZ2.js');
const agentPubkeyBytes = bs58.decode(authorization.agentAddress);
const isValid = nacl.sign.detached.verify(
messageBuffer,
authorization.signature,
agentPubkeyBytes
);
return isValid;
} catch (error) {
console.error("[Auth Signature] Verification failed:", error);
return false;
}
}
async function createSignedAuthorization(params, agentKeypair) {
const agentAddress = address(agentKeypair.publicKey.toBase58());
const now = Math.floor(Date.now() / 1e3);
const expiresAt = params.expiresAt || now + (params.expiresIn || 30 * 24 * 60 * 60);
const indexLimit = params.indexLimit || 1e3;
const network = params.network || "devnet";
const nonce = params.nonce !== void 0 ? params.nonce : "default";
const message = {
agentAddress,
authorizedSource: params.authorizedSource,
indexLimit,
expiresAt,
network,
nonce
};
const signature = await signAuthorizationMessage(message, agentKeypair);
const authorization = {
agentAddress,
authorizedSource: params.authorizedSource,
indexLimit,
expiresAt,
network,
signature,
nonce,
metadata: params.metadata
};
return authorization;
}
function generateNonce() {
const buffer = new Uint8Array(32);
globalThis.crypto.getRandomValues(buffer);
return Buffer.from(buffer).toString("hex");
}
function serializeAuthorization(authorization) {
return {
agentAddress: authorization.agentAddress,
authorizedSource: authorization.authorizedSource,
indexLimit: authorization.indexLimit,
expiresAt: authorization.expiresAt,
network: authorization.network,
signature: bs58.encode(authorization.signature),
nonce: authorization.nonce,
metadata: authorization.metadata
};
}
function deserializeAuthorization(data) {
return {
agentAddress: data.agentAddress,
authorizedSource: data.authorizedSource,
indexLimit: data.indexLimit,
expiresAt: data.expiresAt,
network: data.network,
signature: bs58.decode(data.signature),
nonce: data.nonce,
metadata: data.metadata
};
}
async function getAuthorizationId(authorization) {
const serialized = serializeAuthorization(authorization);
const json = JSON.stringify(serialized);
const encoder = new TextEncoder();
const data = encoder.encode(json);
const crypto = globalThis.crypto;
const hashBuffer = await crypto.subtle.digest("SHA-256", data);
const hashArray = new Uint8Array(hashBuffer);
return bs58.encode(hashArray);
}
function isAuthorizationExpired(authorization, currentTime) {
const now = currentTime || Math.floor(Date.now() / 1e3);
return now >= authorization.expiresAt;
}
function isAuthorizationExhausted(authorization, currentIndex) {
return currentIndex >= authorization.indexLimit;
}
function validateAuthorizationNetwork(authorization, expectedNetwork) {
return authorization.network === expectedNetwork;
}
export { createAuthorizationMessage, createSignedAuthorization, deserializeAuthorization, generateNonce, getAuthorizationId, isAuthorizationExhausted, isAuthorizationExpired, serializeAuthorization, signAuthorizationMessage, signature_verification_exports, validateAuthorizationNetwork, verifyAuthorizationSignature };
//# sourceMappingURL=chunk-QWQTPTZ4.js.map
//# sourceMappingURL=chunk-QWQTPTZ4.js.map