first commit

This commit is contained in:
Samuel Andert
2023-07-18 15:36:33 +02:00
parent bb4cd43210
commit 5fdaefac93
44 changed files with 23022 additions and 41530 deletions

View File

@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

View File

@ -1,8 +0,0 @@
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});

View File

@ -1,968 +0,0 @@
import * as LitJsSdk_accessControlConditions from "@lit-protocol/access-control-conditions";
import * as LitJsSdk_blsSdk from "@lit-protocol/bls-sdk";
import * as LitJsSdk_authHelpers from "@lit-protocol/auth-helpers";
import * as LitJsSdk_types from "@lit-protocol/types";
import * as LitJsSdk from "@lit-protocol/lit-node-client";
import { AccsDefaultParams, AuthSig, AuthCallback } from "@lit-protocol/types";
import { Button, ButtonGroup, TextField } from "@mui/material";
import { GoogleLogin } from "@react-oauth/google";
import {
startAuthentication,
startRegistration,
} from "@simplewebauthn/browser";
import base64url from "base64url";
import { ethers, utils } from "ethers";
import { computeAddress } from "ethers/lib/utils";
import { useState } from "react";
import "./App.css";
import { getDomainFromOrigin } from "./utils/string";
type CredentialResponse = any;
declare global {
interface Window {
cbor: any;
}
}
const RELAY_API_URL =
process.env.REACT_APP_RELAY_API_URL || "http://localhost:3001";
function App() {
const [registeredPkpEthAddress, setRegisteredPkpEthAddress] = useState<
string
>("");
const [
googleCredentialResponse,
setGoogleCredentialResponse,
] = useState<CredentialResponse | null>(null);
const [registeredPkpPublicKey, setRegisteredPkpPublicKey] = useState<
string
>("");
const [
authenticatedPkpEthAddress,
setAuthenticatedPkpEthAddress,
] = useState<string>("");
const [authenticatedPkpPublicKey, setAuthenticatedPkpPublicKey] = useState<
string
>("");
const [status, setStatus] = useState("");
const [selectedAuthMethod, setSelectedAuthMethod] = useState(6);
const [webAuthnUsername, setWebAuthnUsername] = useState<string>("");
const [authSig, setAuthSig] = useState<AuthSig | null>(null);
const [executeJsSignature, setExecuteJsSignature] = useState<string | null>(
null
);
const [encryptedSymmetricKey, setEncryptedSymmetricKey] = useState<
Uint8Array
>(new Uint8Array());
const [encryptedString, setEncryptedString] = useState<Blob | null>(null);
console.log("STATE", {
authenticatedPkpPublicKey,
authenticatedPkpEthAddress,
});
const handleLoggedInToGoogle = async (
credentialResponse: CredentialResponse
) => {
setStatus("Logged in to Google");
console.log("Got response from google sign in: ", {
credentialResponse,
});
setGoogleCredentialResponse(credentialResponse);
};
return (
<div className="App">
<div style={{ height: 80 }} />
<h1>Welcome To The PKP Demo!</h1>
<div style={{ height: 24 }} />
<h3>Choose an authentication method to begin:</h3>
<ButtonGroup variant="outlined">
<Button
variant={
selectedAuthMethod === 6 ? "contained" : "outlined"
}
onClick={() => setSelectedAuthMethod(6)}
>
Google
</Button>
<Button
variant={
selectedAuthMethod === 3 ? "contained" : "outlined"
}
onClick={() => setSelectedAuthMethod(3)}
>
WebAuthn
</Button>
</ButtonGroup>
<div style={{ height: 24 }} />
<h1>{status}</h1>
<div style={{ height: 24 }} />
{selectedAuthMethod === 6 && (
<>
<h3>Step 1: Log in with Google.</h3>
<GoogleLogin
onSuccess={handleLoggedInToGoogle}
onError={() => {
console.log("Login Failed");
}}
useOneTap
/>
{googleCredentialResponse && (
<div>
<b>Google Credential Response: </b>
{JSON.stringify(googleCredentialResponse)}
</div>
)}
<h3>Step 2: Use Google Credential to Mint PKP.</h3>
<button
onClick={() =>
handleMintPkpUsingGoogleAuth(
googleCredentialResponse,
setStatus,
({ pkpEthAddress, pkpPublicKey }) => {
setRegisteredPkpEthAddress(pkpEthAddress);
setRegisteredPkpPublicKey(pkpPublicKey);
}
)
}
>
Mint PKP
</button>
{registeredPkpEthAddress && (
<div>
Registered PKP Eth Address:{" "}
{registeredPkpEthAddress}
</div>
)}
<h3>
Step 3: Generate auth sigs from Lit Nodes, then generate
session sigs for storing an encryption condition.
</h3>
<Button
variant="contained"
onClick={async () => {
const {
encryptedString,
encryptedSymmetricKey,
} = await handleStoreEncryptionConditionNodes(
setStatus,
googleCredentialResponse,
registeredPkpPublicKey
);
setEncryptedString(encryptedString);
setEncryptedSymmetricKey(encryptedSymmetricKey);
setAuthenticatedPkpPublicKey(
registeredPkpPublicKey
);
setAuthenticatedPkpEthAddress(
publicKeyToAddress(registeredPkpPublicKey)
);
}}
>
Authenticate + Encrypt with Lit
</Button>
{authenticatedPkpEthAddress && (
<div>
Authenticated PKP Eth Address:{" "}
{authenticatedPkpEthAddress}
</div>
)}
<h3>
Step 4: Retrieve the decrypted symmetric key from Lit
Nodes.
</h3>
<Button
variant="contained"
onClick={async () => {
await handleRetrieveSymmetricKeyNodes(
setStatus,
encryptedSymmetricKey,
encryptedString!,
googleCredentialResponse,
authenticatedPkpEthAddress
);
}}
>
Decrypt
</Button>
</>
)}
{selectedAuthMethod === 3 && (
<>
<h3>Step 1: Register to mint PKP. (optional username)</h3>
<TextField
label="Username"
variant="outlined"
onChange={e => setWebAuthnUsername(e.target.value)}
/>
<Button
variant="contained"
onClick={async () => {
await handleWebAuthnRegister(
webAuthnUsername,
setStatus,
({ pkpEthAddress, pkpPublicKey }) => {
setRegisteredPkpEthAddress(pkpEthAddress);
setRegisteredPkpPublicKey(pkpPublicKey);
}
);
}}
>
Register
</Button>
{registeredPkpEthAddress && (
<div>
<b>Registered PKP Eth Address: </b>
{registeredPkpEthAddress}
</div>
)}
<h3>
Step 2: Authenticate against Lit Nodes to generate auth
sigs.
</h3>
<Button
variant="contained"
onClick={async () => {
const {
authSig,
pkpPublicKey,
} = await handleWebAuthnAuthenticate(setStatus);
setAuthSig(authSig);
// After authenticating, we can store the pkpPublicKey for executing a
// Lit Action later.
setAuthenticatedPkpPublicKey(pkpPublicKey);
setAuthenticatedPkpEthAddress(
computeAddress(`0x${pkpPublicKey}`)
);
}}
>
Authenticate
</Button>
{authenticatedPkpPublicKey && authSig && (
<>
<div>
<b>Authenticated PKP Public Key: </b>
{authenticatedPkpPublicKey}
</div>
<div>
<b>Auth Sig: </b>
{JSON.stringify(authSig)}
</div>
</>
)}
<h3>
Step 3: Generate session signatures and use them to
execute a Lit Action.
</h3>
<Button
variant="contained"
onClick={async () => {
const signature = await handleExecuteJs(
setStatus,
authSig!,
authenticatedPkpPublicKey
);
setExecuteJsSignature(signature);
}}
>
Execute Lit Action
</Button>
{executeJsSignature && (
<div>
<b>Executed Lit Action Signature: </b>
{executeJsSignature}
</div>
)}
</>
)}
</div>
);
}
export default App;
const handleMintPkpUsingGoogleAuth = async (
credentialResponse: CredentialResponse,
setStatusFn: (status: string) => void,
onSuccess: ({
pkpEthAddress,
pkpPublicKey,
}: {
pkpEthAddress: string;
pkpPublicKey: string;
}) => void
) => {
setStatusFn("Minting PKP...");
const requestId = await mintPkpUsingRelayerGoogleAuthVerificationEndpoint(
credentialResponse,
setStatusFn
);
return pollRequestUntilTerminalState(requestId, setStatusFn, onSuccess);
};
async function getLitNodeClient(): Promise<LitJsSdk.LitNodeClient> {
const litNodeClient = new LitJsSdk.LitNodeClient({
litNetwork: "serrano",
});
await litNodeClient.connect();
return litNodeClient;
}
async function handleExecuteJs(
setStatusFn: (status: string) => void,
authSig: AuthSig,
pkpPublicKey: string
): Promise<string> {
setStatusFn("Executing JS...");
const litActionCode = `
const go = async () => {
// this requests a signature share from the Lit Node
// the signature share will be automatically returned in the response from the node
// and combined into a full signature by the LitJsSdk for you to use on the client
// all the params (toSign, publicKey, sigName) are passed in from the LitJsSdk.executeJs() function
const sigShare = await LitActions.signEcdsa({ toSign, publicKey, sigName });
};
go();
`;
const litNodeClient = await getLitNodeClient();
const results = await litNodeClient.executeJs({
code: litActionCode,
authSig,
// all jsParams can be used anywhere in your litActionCode
jsParams: {
// this is the string "Hello World" for testing
toSign: [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100],
publicKey: `0x${pkpPublicKey}`,
sigName: "sig1",
},
});
console.log("results: ", results);
return results.signatures["sig1"].signature;
}
async function mintPkpUsingRelayerGoogleAuthVerificationEndpoint(
credentialResponse: any,
setStatusFn: (status: string) => void
) {
setStatusFn("Minting PKP with relayer...");
const mintRes = await fetch(`${RELAY_API_URL}/auth/google`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"api-key": "1234567890",
},
body: JSON.stringify({
idToken: credentialResponse.credential,
}),
});
if (mintRes.status < 200 || mintRes.status >= 400) {
console.warn("Something wrong with the API call", await mintRes.json());
setStatusFn("Uh oh, something's not quite right.");
return null;
} else {
const resBody = await mintRes.json();
console.log("Response OK", { body: resBody });
setStatusFn("Successfully initiated minting PKP with relayer.");
return resBody.requestId;
}
}
async function pollRequestUntilTerminalState(
requestId: string,
setStatusFn: (status: string) => void,
onSuccess: ({
pkpEthAddress,
pkpPublicKey,
}: {
pkpEthAddress: string;
pkpPublicKey: string;
}) => void
) {
if (!requestId) {
return;
}
const maxPollCount = 20;
for (let i = 0; i < maxPollCount; i++) {
setStatusFn(`Waiting for auth completion (poll #${i + 1})`);
const getAuthStatusRes = await fetch(
`${RELAY_API_URL}/auth/status/${requestId}`,
{
headers: {
"api-key": "1234567890",
},
}
);
if (getAuthStatusRes.status < 200 || getAuthStatusRes.status >= 400) {
console.warn(
"Something wrong with the API call",
await getAuthStatusRes.json()
);
setStatusFn("Uh oh, something's not quite right.");
return;
}
const resBody = await getAuthStatusRes.json();
console.log("Response OK", { body: resBody });
if (resBody.error) {
// exit loop since error
console.warn("Something wrong with the API call", {
error: resBody.error,
});
setStatusFn("Uh oh, something's not quite right.");
return;
} else if (resBody.status === "Succeeded") {
// exit loop since success
console.info("Successfully authed", { ...resBody });
setStatusFn("Successfully authed and minted PKP!");
onSuccess({
pkpEthAddress: resBody.pkpEthAddress,
pkpPublicKey: resBody.pkpPublicKey,
});
return;
}
// otherwise, sleep then continue polling
await new Promise(r => setTimeout(r, 15000));
}
// at this point, polling ended and still no success, set failure status
setStatusFn(`Hmm this is taking longer than expected...`);
}
async function handleStoreEncryptionConditionNodes(
setStatusFn: (status: string) => void,
googleCredentialResponse: any,
requestedPkpPublicKey: string
): Promise<{
encryptedSymmetricKey: Uint8Array;
encryptedString: Blob;
}> {
setStatusFn("Storing encryption condition with the network...");
// get the user a session with it
const litNodeClient = await getLitNodeClient();
const { encryptedString, symmetricKey } = await LitJsSdk.encryptString(
"this is a secret message"
);
// key parameter - encrypt symmetric key then hash it
const encryptedSymmetricKey = LitJsSdk_blsSdk.wasmBlsSdkHelpers.encrypt(
LitJsSdk.uint8arrayFromString(litNodeClient.subnetPubKey, "base16"),
symmetricKey
);
// get the session sigs
const { sessionSigs } = await getSessionSigs(
litNodeClient,
encryptedSymmetricKey,
litNodeClient.generateAuthMethodForGoogleJWT(
googleCredentialResponse.credential
),
requestedPkpPublicKey
);
const pkpEthAddress = publicKeyToAddress(requestedPkpPublicKey);
const unifiedAccessControlConditions = getUnifiedAccessControlConditions(
pkpEthAddress
);
console.log(
"unifiedAccessControlConditions: ",
unifiedAccessControlConditions
);
// store the decryption conditions
await litNodeClient.saveEncryptionKey({
unifiedAccessControlConditions,
symmetricKey,
encryptedSymmetricKey,
sessionSigs, // Not actually needed for storing encryption condition.
chain: "ethereum",
});
console.log("encryptedSymmetricKey: ", encryptedSymmetricKey);
return {
encryptedSymmetricKey,
encryptedString,
};
}
async function getSessionSigs(
litNodeClient: LitJsSdk.LitNodeClient,
encryptedSymmetricKey: Uint8Array,
authMethod: LitJsSdk_types.AuthMethod,
requestedPkpPublicKey: string
): Promise<{
sessionSigs: LitJsSdk_types.SessionSigsMap;
}> {
// this will be fired if auth is needed. we can use this to prompt the user to sign in
const authNeededCallback: AuthCallback = async ({
resources,
expiration,
statement,
}) => {
console.log("authNeededCallback fired");
// Generate authMethod.
const authMethods = [authMethod];
// Get AuthSig
const { authSig, pkpPublicKey } = await litNodeClient.signSessionKey({
pkpPublicKey: requestedPkpPublicKey,
authMethods,
statement,
expiration:
expiration ||
new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
resources: resources || [],
});
console.log("got session sig from node and PKP: ", {
authSig,
pkpPublicKey,
});
return authSig;
};
const hashedEncryptedSymmetricKeyStr = await hashBytes({
bytes: new Uint8Array(encryptedSymmetricKey),
});
// Construct the LitResource
const litResource = new LitJsSdk_authHelpers.LitAccessControlConditionResource(
hashedEncryptedSymmetricKeyStr
);
// Get the session sigs
const sessionSigs = await litNodeClient.getSessionSigs({
expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
chain: "ethereum",
resourceAbilityRequests: [
{
resource: litResource,
ability:
LitJsSdk_authHelpers.LitAbility
.AccessControlConditionDecryption,
},
],
switchChain: false,
authNeededCallback,
});
console.log("sessionSigs: ", sessionSigs);
return {
sessionSigs
};
}
// TODO: use when system migrates to reading from chain for access control conditions
async function handleStoreEncryptionConditionRelay(
setStatusFn: (status: string) => void,
pkpEthAddress: string
) {
setStatusFn("Storing encryption condition...");
// get the user a session with it
const litNodeClient = await getLitNodeClient();
const { encryptedZip, symmetricKey } = await LitJsSdk.zipAndEncryptString(
"this is a secret message"
);
// get the ACCs
const unifiedAccessControlConditions = getUnifiedAccessControlConditions(
pkpEthAddress
);
// value parameter - hash unified conditions
const hashedAccessControlConditions = await LitJsSdk_accessControlConditions.hashUnifiedAccessControlConditions(
unifiedAccessControlConditions
);
console.log("hashedAccessControlConditions", {
hashedAccessControlConditions,
});
const hashedAccessControlConditionsStr = LitJsSdk.uint8arrayToString(
new Uint8Array(hashedAccessControlConditions),
"base16"
);
// key parameter - encrypt symmetric key then hash it
const encryptedSymmetricKey = LitJsSdk_blsSdk.wasmBlsSdkHelpers.encrypt(
LitJsSdk.uint8arrayFromString(litNodeClient.subnetPubKey, "base16"),
symmetricKey
);
const hashedEncryptedSymmetricKeyStr = await hashBytes({
bytes: new Uint8Array(encryptedSymmetricKey),
});
// securityHash parameter - encrypt symmetric key, concat with creator address
const pkpEthAddressBytes = utils.arrayify(pkpEthAddress);
const securityHashPreimage = new Uint8Array([
...encryptedSymmetricKey,
...pkpEthAddressBytes,
]);
const securityHashStr = await hashBytes({
bytes: securityHashPreimage,
});
console.log("Storing encryption condition with relay", {
hashedEncryptedSymmetricKeyStr,
hashedAccessControlConditionsStr,
securityHashStr,
});
// call centralized conditions relayer to write encryption conditions to chain.
const storeRes = await fetch(`${RELAY_API_URL}/store-condition`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"api-key": "1234567890",
},
body: JSON.stringify({
key: hashedEncryptedSymmetricKeyStr,
value: hashedAccessControlConditionsStr,
securityHash: securityHashStr,
chainId: "1",
permanent: false,
capabilityProtocolPrefix: "litEncryptionCondition",
}),
});
if (storeRes.status < 200 || storeRes.status >= 400) {
console.warn(
"Something wrong with the API call",
await storeRes.json()
);
setStatusFn("Uh oh, something's not quite right");
} else {
setStatusFn("Successfully stored encryption condition with relayer!");
}
}
async function handleRetrieveSymmetricKeyNodes(
setStatusFn: (status: string) => void,
encryptedSymmetricKey: Uint8Array,
encryptedString: Blob,
googleCredentialResponse: any,
pkpEthAddress: string
) {
setStatusFn("Retrieving symmetric key...");
const litNodeClient = await getLitNodeClient();
// get the session sigs
const { sessionSigs } = await getSessionSigs(
litNodeClient,
encryptedSymmetricKey,
litNodeClient.generateAuthMethodForGoogleJWT(
googleCredentialResponse.credential
),
);
// get the ACC
const unifiedAccessControlConditions = getUnifiedAccessControlConditions(
pkpEthAddress
);
console.log(
"unifiedAccessControlConditions: ",
unifiedAccessControlConditions
);
const retrievedSymmKey = await litNodeClient.getEncryptionKey({
unifiedAccessControlConditions,
toDecrypt: LitJsSdk.uint8arrayToString(encryptedSymmetricKey, "base16"),
sessionSigs,
});
const decryptedString = await LitJsSdk.decryptString(
encryptedString,
retrievedSymmKey
);
console.log("decrypted string", decryptedString);
}
function publicKeyToAddress(publicKey: string) {
return utils.computeAddress(`${publicKey}`);
}
async function hashBytes({ bytes }: { bytes: Uint8Array }): Promise<string> {
const hashOfBytes = await crypto.subtle.digest("SHA-256", bytes);
const hashOfBytesStr = LitJsSdk.uint8arrayToString(
new Uint8Array(hashOfBytes),
"base16"
);
return hashOfBytesStr;
}
// async function handleEncryptThenDecrypt(
// setStatusFn,
// googleCredentialResponse,
// pkpEthAddress,
// pkpPublicKey
// ) {
// setStatusFn("Encrypting then decrypting...");
// var unifiedAccessControlConditions = [
// {
// conditionType: "evmBasic",
// contractAddress: "",
// standardContractType: "",
// chain: "mumbai",
// method: "",
// parameters: [":userAddress"],
// returnValueTest: {
// comparator: "=",
// value: pkpEthAddress,
// },
// },
// ];
// // this will be fired if auth is needed. we can use this to prompt the user to sign in
// const authNeededCallback = async ({
// chain,
// resources,
// expiration,
// uri,
// litNodeClient,
// }) => {
// console.log("authNeededCallback fired");
// const sessionSig = await litNodeClient.signSessionKey({
// sessionKey: uri,
// authMethods: [
// {
// authMethodType: 6,
// accessToken: googleCredentialResponse.credential,
// },
// ],
// pkpPublicKey,
// expiration,
// resources,
// chain,
// });
// console.log("got session sig from node and PKP: ", sessionSig);
// return sessionSig;
// };
// // get the user a session with it
// const litNodeClient = await getLitNodeClient();
// const sessionSigs = await litNodeClient.getSessionSigs({
// expiration: new Date(Date.now() + 1000 * 60 * 60 * 24).toISOString(), // 24 hours
// chain: "ethereum",
// resources: [`litEncryptionCondition://*`],
// switchChain: false,
// authNeededCallback,
// });
// console.log("sessionSigs before saving encryption key: ", sessionSigs);
// const { encryptedZip, symmetricKey } = await LitJsSdk.zipAndEncryptString(
// "this is a secret message"
// );
// const encryptedSymmetricKey = await litNodeClient.saveEncryptionKey({
// unifiedAccessControlConditions,
// symmetricKey,
// sessionSigs,
// });
// const hashOfKey = await LitJsSdk.hashEncryptionKey({
// encryptedSymmetricKey,
// });
// console.log("encrypted symmetric key", encryptedSymmetricKey);
// const retrievedSymmKey = await litNodeClient.getEncryptionKey({
// unifiedAccessControlConditions,
// toDecrypt: LitJsSdk.uint8arrayToString(encryptedSymmetricKey, "base16"),
// sessionSigs,
// });
// const decryptedFiles = await LitJsSdk.decryptZip(
// encryptedZip,
// retrievedSymmKey
// );
// const decryptedString = await decryptedFiles["string.txt"].async("text");
// console.log("decrypted string", decryptedString);
// setStatusFn("Success!");
// }
async function handleWebAuthnRegister(
username: string,
setStatusFn: (status: string) => void,
onSuccess: ({
pkpEthAddress,
pkpPublicKey,
}: {
pkpEthAddress: string;
pkpPublicKey: string;
}) => void
) {
let url = `${RELAY_API_URL}/auth/webauthn/generate-registration-options`;
// Handle optional username
if (username !== "") {
url += `?username=${encodeURIComponent(username)}`;
}
const resp = await fetch(url, { headers: { "api-key": "1234567890" } });
let attResp;
try {
const opts = await resp.json();
// Require a resident key for this demo
opts.authenticatorSelection.residentKey = "required";
opts.authenticatorSelection.requireResidentKey = true;
opts.extensions = {
credProps: true,
};
attResp = await startRegistration(opts);
} catch (error) {
// TODO: Handle error
throw error;
}
console.log("attResp", { attResp });
// Verify and mint PKP.
setStatusFn("Verifying WebAuthn registration...");
const verificationAndMintResp = await fetch(
`${RELAY_API_URL}/auth/webauthn/verify-registration`,
{
method: "POST",
headers: {
"Content-Type": "application/json",
"api-key": "1234567890",
},
body: JSON.stringify({ credential: attResp }),
}
);
if (
verificationAndMintResp.status < 200 ||
verificationAndMintResp.status >= 400
) {
console.warn(
"Something went wrong with the API call",
await verificationAndMintResp.json()
);
setStatusFn("Uh oh, something's not quite right.");
return null;
}
const resBody = await verificationAndMintResp.json();
console.log("Response OK", { body: resBody });
setStatusFn(
"Successfully registered using WebAuthn! PKP minting initiated..."
);
// Poll until success
const mintRequestId = resBody.requestId;
await pollRequestUntilTerminalState(mintRequestId, setStatusFn, onSuccess);
}
const rpcUrl = process.env.REACT_APP_RPC_URL || "http://localhost:8545";
async function handleWebAuthnAuthenticate(
setStatusFn: (status: string) => void
): Promise<{
authSig: AuthSig;
pkpPublicKey: string;
}> {
// Fetch latest blockHash
setStatusFn("Fetching latest block hash...");
const provider = new ethers.providers.JsonRpcProvider(rpcUrl);
const block = await provider.getBlock("latest");
const blockHash = block.hash;
// Turn into byte array.
const blockHashBytes = ethers.utils.arrayify(blockHash);
console.log(
"blockHash",
blockHash,
blockHashBytes,
base64url(Buffer.from(blockHashBytes))
);
// Construct authentication options.
const rpId = getDomainFromOrigin(window.location.origin);
console.log("Using rpId: ", { rpId });
const authenticationOptions = {
challenge: base64url(Buffer.from(blockHashBytes)),
timeout: 60000,
userVerification: "required",
rpId,
};
// Authenticate with WebAuthn.
setStatusFn("Authenticating with WebAuthn...");
const authenticationResponse = await startAuthentication(
authenticationOptions
);
// BUG: We need to make sure userHandle is base64url encoded.
// Deep copy the authentication response.
const actualAuthenticationResponse = JSON.parse(
JSON.stringify(authenticationResponse)
);
actualAuthenticationResponse.response.userHandle = base64url.encode(
authenticationResponse.response.userHandle
);
// Call all nodes POST /web/auth/webauthn to generate authSig.
setStatusFn("Verifying WebAuthn authentication against Lit Network...");
const litNodeClient = await getLitNodeClient();
// Generate authMethod.
const authMethod = litNodeClient.generateAuthMethodForWebAuthn(
actualAuthenticationResponse
);
// Get authSig.
const { authSig, pkpPublicKey } = await litNodeClient.signSessionKey({
authMethods: [authMethod],
expiration: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
resources: [],
});
return { authSig, pkpPublicKey };
}
function getUnifiedAccessControlConditions(
pkpEthAddress?: string
): AccsDefaultParams[] {
return [
{
conditionType: "evmBasic",
contractAddress: "",
standardContractType: "",
chain: "mumbai",
method: "",
parameters: [":userAddress"],
returnValueTest: {
comparator: "=",
value:
pkpEthAddress ||
"0x3c3CA2BFFfffE532aed2923A34D6c1F9307F8076",
},
},
];
}

View File

@ -1,277 +0,0 @@
{
"address": "0xffD53EeAD24a54CA7189596eF1aa3f1369753611",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_pkpNft",
"type": "address"
},
{
"internalType": "address",
"name": "_pkpPermissions",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
},
{
"internalType": "uint256[]",
"name": "permittedAuthMethodTypes",
"type": "uint256[]"
},
{
"internalType": "bytes[]",
"name": "permittedAuthMethodIds",
"type": "bytes[]"
},
{
"internalType": "bytes[]",
"name": "permittedAuthMethodPubkeys",
"type": "bytes[]"
},
{
"internalType": "uint256[][]",
"name": "permittedAuthMethodScopes",
"type": "uint256[][]"
},
{
"internalType": "bool",
"name": "addPkpEthAddressAsPermittedAddress",
"type": "bool"
},
{
"internalType": "bool",
"name": "sendPkpToItself",
"type": "bool"
}
],
"name": "mintNextAndAddAuthMethods",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
},
{
"internalType": "bytes[]",
"name": "permittedIpfsCIDs",
"type": "bytes[]"
},
{
"internalType": "uint256[][]",
"name": "permittedIpfsCIDScopes",
"type": "uint256[][]"
},
{
"internalType": "address[]",
"name": "permittedAddresses",
"type": "address[]"
},
{
"internalType": "uint256[][]",
"name": "permittedAddressScopes",
"type": "uint256[][]"
},
{
"internalType": "uint256[]",
"name": "permittedAuthMethodTypes",
"type": "uint256[]"
},
{
"internalType": "bytes[]",
"name": "permittedAuthMethodIds",
"type": "bytes[]"
},
{
"internalType": "bytes[]",
"name": "permittedAuthMethodPubkeys",
"type": "bytes[]"
},
{
"internalType": "uint256[][]",
"name": "permittedAuthMethodScopes",
"type": "uint256[][]"
},
{
"internalType": "bool",
"name": "addPkpEthAddressAsPermittedAddress",
"type": "bool"
},
{
"internalType": "bool",
"name": "sendPkpToItself",
"type": "bool"
}
],
"name": "mintNextAndAddAuthMethodsWithTypes",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"name": "onERC721Received",
"outputs": [
{
"internalType": "bytes4",
"name": "",
"type": "bytes4"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pkpNFT",
"outputs": [
{
"internalType": "contract PKPNFT",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pkpPermissions",
"outputs": [
{
"internalType": "contract PKPPermissions",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newPkpNftAddress",
"type": "address"
}
],
"name": "setPkpNftAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newPkpPermissionsAddress",
"type": "address"
}
],
"name": "setPkpPermissionsAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
}

View File

@ -1,967 +0,0 @@
{
"address": "0x86062B7a01B8b2e22619dBE0C15cbe3F7EBd0E92",
"abi": [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "approved",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "approve",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "burn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "contractBalance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "exists",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "freeMintId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "ipfsCID",
"type": "bytes"
},
{
"internalType": "bytes32",
"name": "msgHash",
"type": "bytes32"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "freeMintGrantAndBurnNext",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "freeMintId",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "msgHash",
"type": "bytes32"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "freeMintNext",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "freeMintId",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "msgHash",
"type": "bytes32"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "freeMintSigTest",
"outputs": [],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "freeMintSigner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getApproved",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getEthAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getPubkey",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"name": "getUnmintedRoutedTokenIdCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "mintCost",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "ipfsCID",
"type": "bytes"
}
],
"name": "mintGrantAndBurnNext",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "ipfsCID",
"type": "bytes"
}
],
"name": "mintGrantAndBurnSpecific",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"name": "mintNext",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "mintSpecific",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "ownerOf",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pkpNftMetadata",
"outputs": [
{
"internalType": "contract PKPNFTMetadata",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pkpPermissions",
"outputs": [
{
"internalType": "contract PKPPermissions",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"name": "pkpRouted",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "hash",
"type": "bytes32"
}
],
"name": "prefixed",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "redeemedFreeMintIds",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "router",
"outputs": [
{
"internalType": "contract PubkeyRouter",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newFreeMintSigner",
"type": "address"
}
],
"name": "setFreeMintSigner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newMintCost",
"type": "uint256"
}
],
"name": "setMintCost",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "pkpNftMetadataAddress",
"type": "address"
}
],
"name": "setPkpNftMetadataAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "pkpPermissionsAddress",
"type": "address"
}
],
"name": "setPkpPermissionsAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "routerAddress",
"type": "address"
}
],
"name": "setRouterAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenOfOwnerByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "tokenURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "unmintedRoutedTokenIds",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
}

View File

@ -1,795 +0,0 @@
{
"address": "0x274d0C69fCfC40f71E57f81E8eA5Bd786a96B832",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_pkpNft",
"type": "address"
},
{
"internalType": "address",
"name": "_router",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"indexed": false,
"internalType": "bytes",
"name": "userPubkey",
"type": "bytes"
}
],
"name": "PermittedAuthMethodAdded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "id",
"type": "bytes"
}
],
"name": "PermittedAuthMethodRemoved",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"indexed": false,
"internalType": "uint256",
"name": "scopeId",
"type": "uint256"
}
],
"name": "PermittedAuthMethodScopeAdded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"indexed": false,
"internalType": "uint256",
"name": "scopeId",
"type": "uint256"
}
],
"name": "PermittedAuthMethodScopeRemoved",
"type": "event"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "ipfsCID",
"type": "bytes"
},
{
"internalType": "uint256[]",
"name": "scopes",
"type": "uint256[]"
}
],
"name": "addPermittedAction",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "address",
"name": "user",
"type": "address"
},
{
"internalType": "uint256[]",
"name": "scopes",
"type": "uint256[]"
}
],
"name": "addPermittedAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "userPubkey",
"type": "bytes"
},
{
"internalType": "uint256[]",
"name": "scopes",
"type": "uint256[]"
}
],
"name": "addPermittedAuthMethod",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "scopeId",
"type": "uint256"
}
],
"name": "addPermittedAuthMethodScope",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "authMethods",
"outputs": [
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "userPubkey",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
}
],
"name": "getAuthMethodId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getEthAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getPermittedActions",
"outputs": [
{
"internalType": "bytes[]",
"name": "",
"type": "bytes[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getPermittedAddresses",
"outputs": [
{
"internalType": "address[]",
"name": "",
"type": "address[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "maxScopeId",
"type": "uint256"
}
],
"name": "getPermittedAuthMethodScopes",
"outputs": [
{
"internalType": "bool[]",
"name": "",
"type": "bool[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getPermittedAuthMethods",
"outputs": [
{
"components": [
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"internalType": "bytes",
"name": "userPubkey",
"type": "bytes"
}
],
"internalType": "struct PKPPermissions.AuthMethod[]",
"name": "",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getPubkey",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
}
],
"name": "getTokenIdsForAuthMethod",
"outputs": [
{
"internalType": "uint256[]",
"name": "",
"type": "uint256[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
}
],
"name": "getUserPubkeyForAuthMethod",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "ipfsCID",
"type": "bytes"
}
],
"name": "isPermittedAction",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "isPermittedAddress",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
}
],
"name": "isPermittedAuthMethod",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "scopeId",
"type": "uint256"
}
],
"name": "isPermittedAuthMethodScopePresent",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pkpNFT",
"outputs": [
{
"internalType": "contract PKPNFT",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "ipfsCID",
"type": "bytes"
}
],
"name": "removePermittedAction",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "address",
"name": "user",
"type": "address"
}
],
"name": "removePermittedAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
}
],
"name": "removePermittedAuthMethod",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "authMethodType",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "id",
"type": "bytes"
},
{
"internalType": "uint256",
"name": "scopeId",
"type": "uint256"
}
],
"name": "removePermittedAuthMethodScope",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "router",
"outputs": [
{
"internalType": "contract PubkeyRouter",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newPkpNftAddress",
"type": "address"
}
],
"name": "setPkpNftAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newRouterAddress",
"type": "address"
}
],
"name": "setRouterAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
}

View File

@ -1,405 +0,0 @@
{
"address": "0xEA287AF8d8835eb20175875e89576bf583539B37",
"abi": [
{
"inputs": [
{
"internalType": "address",
"name": "_pkpNft",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bytes",
"name": "pubkey",
"type": "bytes"
},
{
"indexed": false,
"internalType": "address",
"name": "stakingContract",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"name": "PubkeyRoutingDataSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "nodeAddress",
"type": "address"
},
{
"indexed": false,
"internalType": "bytes",
"name": "pubkey",
"type": "bytes"
},
{
"indexed": false,
"internalType": "address",
"name": "stakingContract",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"name": "PubkeyRoutingDataVote",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "ethAddressToPkpId",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getEthAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getPubkey",
"outputs": [
{
"internalType": "bytes",
"name": "",
"type": "bytes"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getRoutingData",
"outputs": [
{
"components": [
{
"internalType": "bytes",
"name": "pubkey",
"type": "bytes"
},
{
"internalType": "address",
"name": "stakingContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"internalType": "struct PubkeyRouter.PubkeyRoutingData",
"name": "",
"type": "tuple"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "isRouted",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "pkpNFT",
"outputs": [
{
"internalType": "contract PKPNFT",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "pubkeyRegistrations",
"outputs": [
{
"components": [
{
"internalType": "bytes",
"name": "pubkey",
"type": "bytes"
},
{
"internalType": "address",
"name": "stakingContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"internalType": "struct PubkeyRouter.PubkeyRoutingData",
"name": "routingData",
"type": "tuple"
},
{
"internalType": "uint256",
"name": "nodeVoteCount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "nodeVoteThreshold",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "pubkeys",
"outputs": [
{
"internalType": "bytes",
"name": "pubkey",
"type": "bytes"
},
{
"internalType": "address",
"name": "stakingContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newPkpNftAddress",
"type": "address"
}
],
"name": "setPkpNftAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "pubkey",
"type": "bytes"
},
{
"internalType": "address",
"name": "stakingContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"name": "setRoutingData",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "pubkey",
"type": "bytes"
},
{
"internalType": "address",
"name": "stakingContract",
"type": "address"
},
{
"internalType": "uint256",
"name": "keyType",
"type": "uint256"
}
],
"name": "voteForRoutingData",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
}

View File

@ -1,842 +0,0 @@
{
"address": "0xE094c76Ec6bad7CbA6181C8b34Bc41faC7EbdF43",
"abi": [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "approved",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "ApprovalForAll",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"inputs": [],
"name": "RLIHolderRateLimitWindowMilliseconds",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "additionalRequestsPerMillisecondCost",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "approve",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "burn",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "requestsPerMillisecond",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expiresAt",
"type": "uint256"
}
],
"name": "calculateCost",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "payingAmount",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expiresAt",
"type": "uint256"
}
],
"name": "calculateRequestsPerSecond",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "capacity",
"outputs": [
{
"internalType": "uint256",
"name": "requestsPerMillisecond",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "expiresAt",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "contractBalance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "defaultRateLimitWindowMilliseconds",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "expiresAt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requestsPerMillisecond",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "msgHash",
"type": "bytes32"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "freeMint",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "expiresAt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "requestsPerMillisecond",
"type": "uint256"
},
{
"internalType": "bytes32",
"name": "msgHash",
"type": "bytes32"
},
{
"internalType": "uint8",
"name": "v",
"type": "uint8"
},
{
"internalType": "bytes32",
"name": "r",
"type": "bytes32"
},
{
"internalType": "bytes32",
"name": "s",
"type": "bytes32"
}
],
"name": "freeMintSigTest",
"outputs": [],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "freeMintSigner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "freeRequestsPerRateLimitWindow",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "getApproved",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
}
],
"name": "isApprovedForAll",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "isExpired",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "expiresAt",
"type": "uint256"
}
],
"name": "mint",
"outputs": [],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "ownerOf",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "hash",
"type": "bytes32"
}
],
"name": "prefixed",
"outputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"stateMutability": "pure",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes32",
"name": "",
"type": "bytes32"
}
],
"name": "redeemedFreeMints",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "data",
"type": "bytes"
}
],
"name": "safeTransferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newAdditionalRequestsPerMillisecondCost",
"type": "uint256"
}
],
"name": "setAdditionalRequestsPerSecondCost",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "bool",
"name": "approved",
"type": "bool"
}
],
"name": "setApprovalForAll",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newFreeMintSigner",
"type": "address"
}
],
"name": "setFreeMintSigner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newFreeRequestsPerRateLimitWindow",
"type": "uint256"
}
],
"name": "setFreeRequestsPerRateLimitWindow",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newRLIHolderRateLimitWindowMilliseconds",
"type": "uint256"
}
],
"name": "setRLIHolderRateLimitWindowMilliseconds",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "newRateLimitWindowMilliseconds",
"type": "uint256"
}
],
"name": "setRateLimitWindowMilliseconds",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "bytes4",
"name": "interfaceId",
"type": "bytes4"
}
],
"name": "supportsInterface",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "tokenIdCounter",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"internalType": "uint256",
"name": "index",
"type": "uint256"
}
],
"name": "tokenOfOwnerByIndex",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "tokenURI",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "withdraw",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
}
]
}

View File

@ -1,18 +0,0 @@
{
"stakingContractAddress": "0x091e9b0a5A404A394377d08C0Fd8C3418075e1fe",
"multisenderContractAddress": "0x1D907ec0CE55E7E3164Da56e50D64DC2d8933142",
"litTokenContractAddress": "0x541C8a3D27643002fb8A37dCf42D22940B5b2F51",
"accessControlConditionsContractAddress": "0x6620A0e03Ca33a3818f1539DF94f9807b12B9Ec2",
"pubkeyRouterContractAddress": "0xEA287AF8d8835eb20175875e89576bf583539B37",
"pkpNftContractAddress": "0x86062B7a01B8b2e22619dBE0C15cbe3F7EBd0E92",
"rateLimitNftContractAddress": "0xE094c76Ec6bad7CbA6181C8b34Bc41faC7EbdF43",
"pkpHelperContractAddress": "0xffD53EeAD24a54CA7189596eF1aa3f1369753611",
"pkpPermissionsContractAddress": "0x274d0C69fCfC40f71E57f81E8eA5Bd786a96B832",
"pkpNftMetadataContractAddress": "0x46c568B561Cde9ded66Be7d8044C141481c74d0f",
"chainId": 80001,
"rpcUrl": "https://polygon-mumbai.g.alchemy.com/v2/onvoLvV97DDoLkAmdi0Cj7sxvfglKqDh",
"chainName": "mumbai",
"litNodeDomainName": "127.0.0.1",
"litNodePort": 7470,
"rocketPort": 7470
}

BIN
src/app/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

140
src/app/globals.css Normal file
View File

@ -0,0 +1,140 @@
:root {
--max-width: 1100px;
--border-radius: 12px;
--font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono',
'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro',
'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace;
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
--primary-glow: conic-gradient(
from 180deg at 50% 50%,
#16abff33 0deg,
#0885ff33 55deg,
#54d6ff33 120deg,
#0071ff33 160deg,
transparent 360deg
);
--secondary-glow: radial-gradient(
rgba(255, 255, 255, 1),
rgba(255, 255, 255, 0)
);
--tile-start-rgb: 239, 245, 249;
--tile-end-rgb: 228, 232, 233;
--tile-border: conic-gradient(
#00000080,
#00000040,
#00000030,
#00000020,
#00000010,
#00000010,
#00000080
);
--callout-rgb: 238, 240, 241;
--callout-border-rgb: 172, 175, 176;
--card-rgb: 180, 185, 188;
--card-border-rgb: 131, 134, 135;
}
@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
--primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
--secondary-glow: linear-gradient(
to bottom right,
rgba(1, 65, 255, 0),
rgba(1, 65, 255, 0),
rgba(1, 65, 255, 0.3)
);
--tile-start-rgb: 2, 13, 46;
--tile-end-rgb: 2, 5, 19;
--tile-border: conic-gradient(
#ffffff80,
#ffffff40,
#ffffff30,
#ffffff20,
#ffffff10,
#ffffff10,
#ffffff80
);
--callout-rgb: 20, 20, 20;
--callout-border-rgb: 108, 108, 108;
--card-rgb: 100, 100, 100;
--card-border-rgb: 200, 200, 200;
}
}
* {
box-sizing: border-box;
padding: 0;
margin: 0;
}
html,
body {
max-width: 100vw;
overflow-x: hidden;
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
a {
color: inherit;
text-decoration: none;
}
@media (prefers-color-scheme: dark) {
html {
color-scheme: dark;
}
}
.main {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 6rem;
min-height: 100vh;
}
.alert {
background-color: rgb(var(--callout-rgb));
border: 1px solid rgb(var(--callout-border-rgb));
border-radius: 0.5rem;
padding: 1rem 0.875rem;
margin: 1rem 0;
max-width: 32rem;
font-size: 0.875rem;
}
.alert__btn {
margin-top: 1rem;
padding: 0.375rem 0.5rem;
cursor: pointer;
}
.alert--error {
border-color: red;
}
.alert--success {
border-color: green;
}

21
src/app/layout.js Normal file
View File

@ -0,0 +1,21 @@
import './globals.css'
import { Inter } from 'next/font/google'
import { Providers } from './provider'
import '@rainbow-me/rainbowkit/styles.css'
const inter = Inter({ subsets: ['latin'] })
export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>
<Providers>{children}</Providers>
</body>
</html>
)
}

113
src/app/page.js Normal file
View File

@ -0,0 +1,113 @@
'use client'
import { ConnectButton } from '@rainbow-me/rainbowkit'
import { useAccount, useNetwork, useSigner } from 'wagmi'
import { ethConnect, disconnectWeb3 } from '@lit-protocol/lit-node-client'
import { LOCAL_STORAGE_KEYS } from '@lit-protocol/constants'
import { useEffect, useState } from 'react'
import { PKPEthersWallet } from "@lit-protocol/pkp-ethers";
export default function Home() {
const [authSig, setAuthSig] = useState(null)
const [error, setError] = useState(null)
const { address, isConnected, isDisconnected } = useAccount()
const { data: signer } = useSigner()
const { chain } = useNetwork()
async function generateAuthSig(signer, address, chainId) {
setAuthSig(null);
setError(null);
try {
const newAuthSig = await ethConnect.signAndSaveAuthMessage({
web3: signer.provider,
account: address.toLowerCase(),
chainId: chainId,
});
setAuthSig(newAuthSig);
} catch (err) {
console.error(err);
setError(`Failed to sign auth message: ${err.message}`);
}
}
async function sendTX(){
const pkpWallet = new PKPEthersWallet({
controllerAuthSig: authSig,
pkpPubKey: "046da3ba67065fd1e2726242ca01cd4601524893f4aa4b0042578fa6cbec28fa8c9a28eb9f7893932fc09717edc9e1db57e157a21eed346247c1db5a722a01f571",
rpc: "https://rpc.gnosischain.com/",
});
await pkpWallet.init();
console.log(pkpWallet);
const from = "0x06B6BE47c86cfcDF3f77c0e17e7aD8af750782aE";
const to = "0x1A5cfC9EA11afb50011F847fb7dC07bA1e18b05A";
const value = BigInt(5000000000000000);
// @lit-protocol/pkp-ethers will automatically add missing fields (nonce, chainId, gasPrice, gasLimit)
const transactionRequest = {
from,
to,
value,
};
const signedTransactionRequest = await pkpWallet.signTransaction(
transactionRequest
);
await pkpWallet.sendTransaction(signedTransactionRequest);
}
// Fetch auth sig from local storage
useEffect(() => {
if (!authSig) {
const storedAuthSig = localStorage.getItem(LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
if (storedAuthSig) {
const parsedAuthSig = JSON.parse(storedAuthSig);
setAuthSig(parsedAuthSig);
}
}
}, [authSig])
// Generate auth sig if not already generated and if wallet is connected
useEffect(() => {
if (!authSig && isConnected && signer) {
generateAuthSig(signer, address, chain.id);
}
}, [authSig, isConnected, signer, address, chain])
// Clear auth sig if wallet is disconnected
useEffect(() => {
if (isDisconnected) {
disconnectWeb3();
setAuthSig(null);
}
}, [isDisconnected])
return (
<main className="main">
{error &&
<div className='alert alert--error'>
<p> {error}</p>
<button className='alert__btn' onClick={() => generateAuthSig(signer, address, chain.id)}>
Try again
</button>
</div>
}
{authSig &&
<p className='alert alert--success'>🔐 Auth sig has been generated and stored in local storage under {' '}
<code>{LOCAL_STORAGE_KEYS.AUTH_SIGNATURE}</code>
!
</p>
}
<ConnectButton />
<button class="btn btn--primary" onClick={() => sendTX()}>
send
</button>
</main>
)
}

61
src/app/provider.js Normal file
View File

@ -0,0 +1,61 @@
'use client';
import * as React from 'react';
import {
RainbowKitProvider,
getDefaultWallets,
connectorsForWallets,
darkTheme,
} from '@rainbow-me/rainbowkit';
import { configureChains, createClient, WagmiConfig } from 'wagmi';
import {
mainnet,
polygon,
goerli,
polygonMumbai,
} from 'wagmi/chains';
import { publicProvider } from 'wagmi/providers/public';
const { chains, provider, webSocketProvider } = configureChains(
[
mainnet,
polygon,
...(process.env.NEXT_PUBLIC_ENABLE_TESTNETS === 'true' ? [goerli, polygonMumbai] : []),
],
[publicProvider()]
);
const projectId = process.env.NEXT_PUBLIC_WC_PROJECT_ID;
const { wallets } = getDefaultWallets({
appName: 'My RainbowKit App',
projectId,
chains,
});
const connectors = connectorsForWallets([
...wallets,
]);
const client = createClient({
autoConnect: true,
connectors,
provider,
webSocketProvider,
});
const demoAppInfo = {
appName: 'Rainbowkit Demo',
};
export function Providers({ children }) {
const [mounted, setMounted] = React.useState(false);
React.useEffect(() => setMounted(true), []);
return (
<WagmiConfig client={client}>
<RainbowKitProvider chains={chains} appInfo={demoAppInfo} theme={darkTheme()}>
{mounted && children}
</RainbowKitProvider>
</WagmiConfig>
);
}

View File

@ -1,13 +0,0 @@
body {
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
monospace;
}

View File

@ -1,22 +0,0 @@
import React from "react";
import ReactDOM from "react-dom/client";
import "./index.css";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import { GoogleOAuthProvider } from "@react-oauth/google";
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<GoogleOAuthProvider clientId="1071348522014-3qq1ln33ful535dnd8r4f6f9vtjrv2nu.apps.googleusercontent.com">
<App />
</GoogleOAuthProvider>
</React.StrictMode>
);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();

View File

@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3"><g fill="#61DAFB"><path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/><circle cx="420.9" cy="296.5" r="45.7"/><path d="M520.5 78.1z"/></g></svg>

Before

Width:  |  Height:  |  Size: 2.6 KiB

View File

@ -1 +0,0 @@
/// <reference types="react-scripts" />

View File

@ -1,15 +0,0 @@
import { ReportHandler } from "web-vitals";
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
getLCP(onPerfEntry);
getTTFB(onPerfEntry);
});
}
};
export default reportWebVitals;

View File

@ -1,5 +0,0 @@
// jest-dom adds custom jest matchers for asserting on DOM nodes.
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
import '@testing-library/jest-dom';

View File

@ -1,33 +0,0 @@
// copy-🍝 from https://github.com/MasterKale/SimpleWebAuthn/blob/33528afe001d4aca62052dce204c0398c3127ffd/packages/server/src/helpers/decodeCbor.ts
export function decodeCborFirst(
cbor: any,
input:
| string
| Buffer
| ArrayBuffer
| Uint8Array
| Uint8ClampedArray
| DataView
): any {
try {
// throws if there are extra bytes
return cbor.decodeFirstSync(input);
} catch (err) {
const _err = err as CborDecoderError;
// if the error was due to extra bytes, return the unpacked value
if (_err.value) {
return _err.value;
}
throw err;
}
}
/**
* Intuited from a quick scan of `cbor.decodeFirstSync()` here:
*
* https://github.com/hildjj/node-cbor/blob/v5.1.0/lib/decoder.js#L189
*/
class CborDecoderError extends Error {
value: any;
}

View File

@ -1,39 +0,0 @@
// copy-🍝 from https://github.com/MasterKale/SimpleWebAuthn/blob/33528afe001d4aca62052dce204c0398c3127ffd/packages/server/src/helpers/decodeAttestationObject.ts#L8
/**
* Convert an AttestationObject buffer to a proper object
*
* @param base64AttestationObject Attestation Object buffer
*/
export function decodeAttestationObject(
cbor: any,
attestationObject: Buffer
): AttestationObject {
const toCBOR: AttestationObject = cbor.decodeAllSync(attestationObject)[0];
return toCBOR;
}
export type AttestationFormat =
| "fido-u2f"
| "packed"
| "android-safetynet"
| "android-key"
| "tpm"
| "apple"
| "none";
export type AttestationObject = {
fmt: AttestationFormat;
attStmt: AttestationStatement;
authData: Buffer;
};
export type AttestationStatement = {
sig?: Buffer;
x5c?: Buffer[];
response?: Buffer;
alg?: number;
ver?: string;
certInfo?: Buffer;
pubArea?: Buffer;
};

View File

@ -1,19 +0,0 @@
// copy-🍝 from https://github.com/MasterKale/SimpleWebAuthn/blob/33528afe001d4aca62052dce204c0398c3127ffd/packages/server/src/helpers/decodeAuthenticatorExtensions.ts
/**
* Convert authenticator extension data buffer to a proper object
*
* @param extensionData Authenticator Extension Data buffer
*/
export function decodeAuthenticatorExtensions(cbor, extensionData) {
let toCBOR;
try {
toCBOR = cbor.decodeAllSync(extensionData)[0];
} catch (err) {
const _err = err;
throw new Error(
`Error decoding authenticator extensions: ${_err.message}`
);
}
return toCBOR;
}

View File

@ -1,112 +0,0 @@
import { decodeCborFirst } from "./cbor";
import { decodeAuthenticatorExtensions } from "./decodeAuthenticatorExtensions";
/**
* Make sense of the authData buffer contained in an Attestation
*/
export function parseAuthenticatorData(
cbor: any,
authData: Buffer
): ParsedAuthenticatorData {
if (authData.byteLength < 37) {
throw new Error(
`Authenticator data was ${authData.byteLength} bytes, expected at least 37 bytes`
);
}
let pointer = 0;
const rpIdHash = authData.slice(pointer, (pointer += 32));
const flagsBuf = authData.slice(pointer, (pointer += 1));
const flagsInt = flagsBuf[0];
// Bit positions can be referenced here:
// https://www.w3.org/TR/webauthn-2/#flags
const flags = {
up: !!(flagsInt & (1 << 0)), // User Presence
uv: !!(flagsInt & (1 << 2)), // User Verified
be: !!(flagsInt & (1 << 3)), // Backup Eligibility
bs: !!(flagsInt & (1 << 4)), // Backup State
at: !!(flagsInt & (1 << 6)), // Attested Credential Data Present
ed: !!(flagsInt & (1 << 7)), // Extension Data Present
flagsInt,
};
const counterBuf = authData.slice(pointer, (pointer += 4));
const counter = counterBuf.readUInt32BE(0);
let aaguid: Buffer | undefined = undefined;
let credentialID: Buffer | undefined = undefined;
let credentialPublicKey: Buffer | undefined = undefined;
if (flags.at) {
aaguid = authData.slice(pointer, (pointer += 16));
const credIDLenBuf = authData.slice(pointer, (pointer += 2));
const credIDLen = credIDLenBuf.readUInt16BE(0);
credentialID = authData.slice(pointer, (pointer += credIDLen));
// Decode the next CBOR item in the buffer, then re-encode it back to a Buffer
const firstDecoded = decodeCborFirst(cbor, authData.slice(pointer));
const firstEncoded = Buffer.from(cbor.encode(firstDecoded));
credentialPublicKey = firstEncoded;
pointer += firstEncoded.byteLength;
}
let extensionsData: any | undefined = undefined;
let extensionsDataBuffer: Buffer | undefined = undefined;
if (flags.ed) {
const firstDecoded = decodeCborFirst(cbor, authData.slice(pointer));
const firstEncoded = Buffer.from(cbor.encode(firstDecoded));
extensionsDataBuffer = firstEncoded;
extensionsData = decodeAuthenticatorExtensions(
cbor,
extensionsDataBuffer
);
pointer += firstEncoded.byteLength;
}
// Pointer should be at the end of the authenticator data, otherwise too much data was sent
if (authData.byteLength > pointer) {
throw new Error(
"Leftover bytes detected while parsing authenticator data"
);
}
return {
rpIdHash,
flagsBuf,
flags,
counter,
counterBuf,
aaguid,
credentialID,
credentialPublicKey,
extensionsData,
extensionsDataBuffer,
};
}
export type ParsedAuthenticatorData = {
rpIdHash: Buffer;
flagsBuf: Buffer;
flags: {
up: boolean;
uv: boolean;
be: boolean;
bs: boolean;
at: boolean;
ed: boolean;
flagsInt: number;
};
counter: number;
counterBuf: Buffer;
aaguid?: Buffer;
credentialID?: Buffer;
credentialPublicKey?: Buffer;
extensionsData?: any;
extensionsDataBuffer?: Buffer;
};

View File

@ -1,6 +0,0 @@
export function getDomainFromOrigin(origin: string): string {
// remove protocol with regex
let newOrigin = origin.replace(/(^\w+:|^)\/\//, "");
// remove port with regex
return newOrigin.replace(/:\d+$/, "");
}