@samouraiwallet/auth47
Version:
A JS implementation of the Auth47 protocol
49 lines • 2.01 kB
JavaScript
import { BIP47Factory } from '@samouraiwallet/bip47';
import * as utils from '@samouraiwallet/bip47/utils';
import { bitcoinMessageFactory } from '@samouraiwallet/bitcoinjs-message';
import { Auth47Error, validateProof, createCallbackUri, validateGenerateUriArgs } from './decoders.js';
const getNetwork = (networkString) => {
return utils.networks[networkString] ?? null;
};
export class Auth47Verifier {
constructor(ecc, callbackUri) {
this.bip47 = BIP47Factory(ecc);
this.bitcoinjsMessage = bitcoinMessageFactory(ecc);
this.callbackUri = createCallbackUri(callbackUri);
}
generateURI(args) {
validateGenerateUriArgs(args);
const uri = new URL(`auth47://${args.nonce}`);
uri.searchParams.set('c', this.callbackUri);
if (args.expires)
uri.searchParams.set('e', args.expires.toString(10));
if (args.resource)
uri.searchParams.set('r', args.resource);
return decodeURIComponent(uri.toString());
}
verifyProof(proof, networkString = 'bitcoin') {
const network = getNetwork(networkString);
if (!network) {
throw new Auth47Error(`Invalid network: ${networkString} (expected "bitcoin", "testnet" or "regtest")`);
}
try {
validateProof(proof);
const address = 'address' in proof ? proof.address : this.bip47.fromBase58(proof.nym, network).getNotificationAddress();
const verified = this.bitcoinjsMessage.verify(proof.challenge, address, proof.signature, network.messagePrefix);
if (!verified) {
throw new Auth47Error('invalid signature');
}
return {
result: 'ok',
data: proof
};
}
catch (error) {
return {
result: 'error',
error: error instanceof Auth47Error ? error.message : String(error)
};
}
}
}
//# sourceMappingURL=index.js.map