@biconomy/abstractjs
Version:
SDK for Biconomy integration with support for account abstraction, smart accounts, ERC-4337.
64 lines • 2.52 kB
JavaScript
import { p256 } from "@noble/curves/nist.js";
import { hashMessage, hashTypedData, hexToBytes, keccak256, toHex } from "viem";
import { toAccount } from "viem/accounts";
/**
* Checks if a signer is a P256 signer.
* @param signer - The signer to check
* @returns True if the signer is a P256 signer
*/
export const isP256Signer = (signer) => signer?.source === "p256";
/**
* Creates a P256 (secp256r1) signer that implements viem's LocalAccount interface.
*
* The signer produces raw P256 ECDSA signatures (r || s, 64 bytes) suitable for
* on-chain verification by P256StatelessValidator.
*
* The publicKey field contains the uncompressed P256 public key (04 || x || y).
* To extract coordinates for ownership data:
* x = publicKey.slice(4, 68) // 32 bytes hex
* y = publicKey.slice(68, 132) // 32 bytes hex
*
* @param privateKey - The P256 private key as a hex string
* @returns A LocalAccount<'p256'> with P256 signing capabilities
*/
export const toP256Signer = (privateKey) => {
const privateKeyBytesArray = hexToBytes(privateKey);
const publicKeyBytes = p256.getPublicKey(privateKeyBytesArray, false); // uncompressed: 04 || x || y
const publicKey = toHex(publicKeyBytes);
// Derive an Ethereum-style address from the P256 public key coordinates for type compatibility
const xyHex = toHex(publicKeyBytes.slice(1)); // x || y (64 bytes)
const address = keccak256(xyHex).slice(0, 42);
const signP256 = (hash) => {
const hashBytesArray = hexToBytes(hash);
// sign returns compact format (r || s, 64 bytes) by default with prehash: false
const sigBytes = p256.sign(hashBytesArray, privateKeyBytesArray, {
prehash: false
});
// This has some type issues and it is bypassed but still everything works
return toHex(sigBytes);
};
const account = toAccount({
address,
async sign({ hash }) {
return signP256(hash);
},
async signMessage({ message }) {
const hash = hashMessage(message);
return signP256(hash);
},
async signTransaction(_) {
throw new Error("signTransaction is not supported for P256 signer");
},
async signTypedData(typedData) {
const hash = hashTypedData(typedData);
return signP256(hash);
}
});
return {
...account,
signP256,
publicKey,
source: "p256"
};
};
//# sourceMappingURL=toP256Signer.js.map