Socket
Socket
Sign inDemoInstall

blockin

Package Overview
Dependencies
Maintainers
2
Versions
169
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

blockin - npm Package Compare versions

Comparing version 1.0.51 to 1.1.0

dist/index.cjs

4

dist/auth.d.ts

@@ -1,3 +0,3 @@

import { IChainDriver, UniversalTxn } from './@types/ChainDriver';
import { CreateAssetParams, CreateTransferAssetParams } from "./@types/auth";
import { IChainDriver, UniversalTxn } from './types/ChainDriver.types.js';
import { CreateAssetParams, CreateTransferAssetParams } from "./types/auth.types.js";
export declare function initializeAuth(driver: IChainDriver): void;

@@ -4,0 +4,0 @@ /**

@@ -1,2 +0,2 @@

import { IChainDriver } from "./@types/ChainDriver";
import { IChainDriver } from "./types/ChainDriver.types.js";
/**

@@ -3,0 +3,0 @@ * Sets the chain driver for the whole library. All chain-specific functions

@@ -1,8 +0,16 @@

export type { IChainDriver, UniversalTxn } from './@types/ChainDriver';
export type { CreateAssetParams, CreateTransferAssetParams, } from './@types/auth';
export type { ChallengeParams } from './@types/verify';
export type { VerifyChallengeOnBackendRequest, VerifyChallengeOnBackendResponse, ChainProps, PresetAsset, PresetUri, BlockinVerifyChallengeResponse, SupportedChain } from './ui/SignInWithBlockinButton/SignInWithBlockinButton.types';
export { setChainDriver } from './blockin';
export { AlgoDriver } from './ChainDrivers/AlgoDriver';
export { createAssetTxn, createAssetTransferTxn, sendTxn } from './auth';
export { createChallenge, verifyChallenge, constructChallengeObjectFromString, constructChallengeStringFromChallengeObject, validateChallengeObjectIsWellFormed, generateNonceWithLastBlockTimestamp } from './verify';
export type { IChainDriver, UniversalTxn } from './types/ChainDriver.types.js';
export type { CreateAssetParams, CreateTransferAssetParams, } from './types/auth.types.js';
export type { ChallengeParams } from './types/verify.types.js';
export type { VerifyChallengeOnBackendRequest, VerifyChallengeOnBackendResponse, ChainProps, PresetAsset, PresetUri, BlockinVerifyChallengeResponse, SupportedChain } from './ui/SignInWithBlockinButton/SignInWithBlockinButton.types.js';
export { setChainDriver } from './blockin.js';
/**
* We have removed ChainDrivers from being exported for a few reasons.
*
* 1) Package size becomes way too big
* 2) Security considerations
* 3) CJS and ESM support was not fully working with dependencies
*
* We still provide the files in the ChainDrivers folder for convenience
*/
export { createAssetTxn, createAssetTransferTxn, sendTxn } from './auth.js';
export { createChallenge, verifyChallenge, constructChallengeObjectFromString, constructChallengeStringFromChallengeObject, validateChallengeObjectIsWellFormed, generateNonceWithLastBlockTimestamp } from './verify.js';

@@ -1,4 +0,412 @@

export { setChainDriver } from './blockin';
export { AlgoDriver } from './ChainDrivers/AlgoDriver';
export { createAssetTxn, createAssetTransferTxn, sendTxn } from './auth';
export { createChallenge, verifyChallenge, constructChallengeObjectFromString, constructChallengeStringFromChallengeObject, validateChallengeObjectIsWellFormed, generateNonceWithLastBlockTimestamp } from './verify';
var chainDriver$1;
function initializeAuth(driver) {
chainDriver$1 = driver;
}
/**
* This function attempts to create a universal function that will create an asset on-chain. This
* uses the chain driver, so it is chain specific. Generates an unsigned asset creation transaction,
* and this is to be signed and broadcasted to the blockchain network. Note this may
* need an API key defined in your chain driver depending on your chain driver implementation.
* @param createAssetParams - JSON object specifying universal asset creation fields like from, amount,
* decimals, etc.
* @returns If successful, will return a UniversalTxn object that specifies the bytes to sign and submit
* to create a valid asset creation transaction. Throws upon error.
*/
async function createAssetTxn(createAssetParams) {
const { from, to = 'Blockin', assetName = 'Blockin Access Token', assetURL = '', note = 'This is an access token created with Blockin', amount = 1, unitName = '', decimals = 0, total = 1, assetMetadata = '', extras = undefined } = createAssetParams;
return await chainDriver$1.makeAssetTxn({
from,
to,
assetName,
assetURL,
note,
amount,
unitName,
decimals,
total,
assetMetadata,
...extras
});
}
// /**
// * This function attempts to create a universal function that will opt-in to an assets. This
// * uses the chain driver, so it is chain specific. Note that some chains like Ethereum don't have this
// * requirement of opting in, so this may be left blank for some blockchains. This generates an unsigned
// * asset opt-in transaction, and this is to be signed and broadcasted to the blockchain network. Note this may
// * need an API key defined in your chain driver depending on your chain driver implementation.
// * @param optInAssetParams - JSON object specifying universal asset opt-in fields like assetIndex and the
// * 'to' address
// * @returns If successful, will return a UniversalTxn object that specifies the bytes to sign and submit
// * to create a valid asset opt-in transaction. Throws upon error.
// */
// export async function createAssetOptInTxn(optInAssetParams: CreateOptInAssetParams): Promise<UniversalTxn> {
// const {
// to,
// from = to,
// assetIndex,
// extras = undefined
// } = optInAssetParams
// return await chainDriver.makeAssetOptInTxn({
// to,
// from,
// assetIndex,
// ...extras
// });
// }
/**
* This function attempts to create a universal function that will transfer an asset. This
* uses the chain driver, so it is chain specific. Note that the asset must be transferable for this to work.
* This generates an unsigned asset transfer transaction, and this is to be signed and broadcasted to
* the blockchain network. Note this may need an API key defined in your chain driver depending on your
* chain driver implementation.
* @param transferAssetParams - JSON object specifying universal asset transfer fields such as the assetIndex
* and the 'to' address
* @returns If successful, will return a UniversalTxn object that specifies the bytes to sign and submit
* to create a valid asset transfer transaction. Throws upon error.
*/
async function createAssetTransferTxn(transferAssetParams) {
const { to, from, assetIndex, extras = undefined } = transferAssetParams;
return await chainDriver$1.makeAssetTransferTxn({
to,
from,
assetIndex,
...extras
});
}
/**
* Sends a signed transaction to the network. Specific to the specified chain driver. Note this may
* need an API key defined in your chain driver depending on your chain driver implementation.
* @param signedTxnBytes - Uint8Array of the signed transaction bytes.
* @param txnId - Transaction ID string
* @returns Throws on error. If successful, will not throw. May return any metadata depending on chain
* driver implementation.
*/
async function sendTxn(signedTxnBytes, txnId) {
return await chainDriver$1.sendTxn(signedTxnBytes, txnId);
}
// export async function createContractOptInTxn(contractOptInParams: CreateContractOptInParams) {
// const {
// from,
// appIndex,
// extras = undefined
// } = contractOptInParams
// return await chainDriver.makeContractOptInTxn({
// from,
// appIndex,
// ...extras
// })
// }
// export async function createContractNoOpTxn(contractNoOpParams: CreateContractNoOpParams) {
// const {
// from,
// appIndex,
// appArgs,
// accounts,
// foreignAssets
// } = contractNoOpParams
// return await chainDriver.makeContractNoOpTxn({
// from,
// appIndex,
// appArgs,
// accounts,
// foreignAssets
// })
// }
// export async function lookupApplicationLocalState(address: string) {
// return await chainDriver.lookupApplicationLocalState(address);
// }
const URI_REGEX = /\w+:(\/?\/?)[^\s]+/;
const ISO8601_DATE_REGEX = /^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])(.[0-9]+)?(Z)?$/;
var chainDriver;
function initializeVerify(driver) {
chainDriver = driver;
}
/**
* Creates a challenge that is well-formed according to EIP-4361 - Sign in With Ethereum. Some
* slight modifications to EIP-4361 for our library include 1) any blockchain's native address, signature,
* and verification schemes are supported and 2) in resources, one may prefix an asset with 'Asset ID: '
* to specify micro-authorizations or role-based access using an on-chain asset.
*
*
* @param challengeParams - JSON object with the challenge details such as domain, uri, statement, address, etc.
* @param options - JSON object speicfying any additional options when creating the challenge
* @returns Well-formed challenge string to be signed by the user, if successsful. Error string is returned
* upon failure.
*/
async function createChallenge(challengeParams, options) {
/**
* This function should remain completely ChainDriver free. ChainDriver dependencies tend to mess up the
* React component generation in the browser.
*/
const { domain, statement, address, uri, nonce, version = "1", chainId = "1", issuedAt = new Date().toISOString(), expirationDate = undefined, notBefore = undefined, resources = undefined } = challengeParams;
try {
const challenge = {
domain,
statement,
address,
uri,
version,
chainId,
nonce,
issuedAt,
expirationDate,
notBefore,
resources
};
validateChallengeObjectIsWellFormed(challenge); // will throw error if invalid
return constructChallengeStringFromChallengeObject(challenge);
}
catch (error) {
return `Error: ${error}`;
}
}
/**
* verifyChallenge always checks three things: 1) originalChallenge was signed correctly by the user, 2) the
* challenge is still well-formed and valid at the present time, and 3) the user owns all requested assets
* in their wallet upon verification.
* @param originalChallenge - The bytes (Uint8 Array) that were signed that represent the original challenge.
* @param signedChallenge - The result of signing the bytes as a Uint8Array
* @param options - Additional checks to perform when verifying the challenge.
* @returns Returns { message: 'success' } object upon success. Throws an error if challenge is invalid.
*/
async function verifyChallenge(originalChallenge, signedChallenge, options) {
const verificationData = {};
const generatedEIP4361ChallengeStr = await getChallengeStringFromBytes(originalChallenge);
const challenge = constructChallengeObjectFromString(generatedEIP4361ChallengeStr);
validateChallengeObjectIsWellFormed(challenge);
console.log("Success: Constructed challenge from string and verified it is well-formed.");
const currDate = new Date();
verificationData.verificationTime = currDate;
if (challenge.expirationDate && currDate >= new Date(challenge.expirationDate)) {
throw `Error: Challenge expired: ${challenge.expirationDate}`;
}
if (challenge.notBefore && currDate <= new Date(challenge.notBefore)) {
throw `Error: Challenge invalid until: ${challenge.notBefore}`;
}
const originalAddress = challenge.address;
await verifyChallengeSignature(originalChallenge, signedChallenge, originalAddress);
console.log("Success: Signature matches address specified within the challenge.");
if (options?.verifyNonceWithBlockTimestamps) {
let blockTimestamp = await chainDriver.getTimestampForBlock(challenge.nonce);
verificationData.nonceTimestamp = blockTimestamp;
const currentTimestamp = Math.round((new Date()).getTime() / 1000);
const timeLimit = options?.verificationTimeLimit ? options?.verificationTimeLimit : 60;
if (blockTimestamp <= currentTimestamp - timeLimit) {
throw `Error: This challenge uses recent block timestamps for the nonce. The challenge must be verified within ${timeLimit} seconds of creating the challenge`;
}
}
if (options?.expectedDomain && challenge.domain !== options?.expectedDomain) {
throw `Error: Domain !== ${options?.expectedDomain}`;
}
if (options?.expectedUri && challenge.uri !== options?.expectedUri) {
throw `Error: Uri !== ${options?.expectedUri}`;
}
if (challenge.resources) {
const assetLookupData = await verifyOwnershipOfAssets(challenge.address, challenge.resources, options?.assetMinimumBalancesMap, options?.defaultMinimum);
verificationData.assetLookupData = assetLookupData;
}
return {
message: `Successfully granted access via Blockin`, success: true, verificationData
};
}
/**
* Generates a nonce using the most recent block index. Can be called directly
* or by specifiying the useBlockTimestampsForNonce flag in the createChallenge
* options. verifyChallenge also offers two flags: (verifyNonceWithBlockTimestamps?: boolean;
* and verificationTimeLimit?: number;) that ensure timestamp of the block was recent when
* verifying.
* @returns Last block index / timestamp / hash to be used as the nonce
*/
async function generateNonceWithLastBlockTimestamp() {
const nonce = await chainDriver.getLastBlockIndex();
return nonce;
}
/**
* Validates the object is well-formed according to the EIP-4361 interface, plus our additional add-ons
* to the interface for Blockin.
* @param challenge - Valid JSON challenge object
*/
function validateChallengeObjectIsWellFormed(challenge) {
if (!URI_REGEX.test(challenge.domain)) {
throw `Inputted domain (${challenge.domain}) is not a valid URI`;
}
/**
* We only check for existence of an address here for Rollup React purposes (we don't use ChainDriver's isValidAddress).
* Will not be able to generate a valid signature with an invalid address, however.
*/
if (!challenge.address) {
throw `No address specified or address is invalid`;
}
if (!URI_REGEX.test(challenge.uri)) {
throw `Inputted URI (${challenge.uri}) is not a valid URI`;
}
if (!challenge.nonce) {
throw `No nonce (${challenge.nonce}) specified`;
}
if (challenge.issuedAt && !ISO8601_DATE_REGEX.test(challenge.issuedAt)) {
throw `Issued at date (${challenge.issuedAt}) is not in valid ISO 8601 format`;
}
if (challenge.expirationDate && !ISO8601_DATE_REGEX.test(challenge.expirationDate)) {
throw `Inputted expiration date (${challenge.expirationDate}) is not in valid ISO 8601 format`;
}
if (challenge.notBefore && !ISO8601_DATE_REGEX.test(challenge.notBefore)) {
throw `Inputted not before date (${challenge.notBefore}) is not in valid ISO 8601 format`;
}
if (challenge.resources) {
for (const resource of challenge.resources) {
if (!resource.startsWith('Asset ID: ') && !URI_REGEX.test(resource)) {
throw `Inputted resource in resources (${resource}) does not start with 'Asset ID: ' and is not a valid URI`;
}
}
}
}
/**
* Parses a JSON object that specifies the challenge fields and returns a well-formatted EIP-4361 string.
* Note that there is no validity checks on the inputs. It is a precondition that it is well-formed.
* @param challenge - Well-formatted JSON object specifying the EIP-4361 fields.
* @returns - Well-formatted EIP-4361 challenge string to be signed.
*/
function constructChallengeStringFromChallengeObject(challenge) {
let message = "";
message += `${challenge.domain} wants you to sign in with your Algorand account:\n`;
message += `${challenge.address}\n\n`;
if (challenge.statement) {
message += `${challenge.statement}\n`;
}
message += `\n`;
message += `URI: ${challenge.uri}\n`;
message += `Version: ${challenge.version}\n`;
message += `Chain ID: ${challenge.chainId}\n`;
message += `Nonce: ${challenge.nonce}\n`;
message += `Issued At: ${challenge.issuedAt}`;
if (challenge.expirationDate) {
message += `\nExpiration Time: ${challenge.expirationDate}`;
}
if (challenge.notBefore) {
message += `\nNot Before: ${challenge.notBefore}\n`;
}
if (challenge.resources) {
message += `\nResources:`;
for (const resource of challenge.resources) {
message += `\n- ${resource}`;
}
}
return message;
}
/**
* This function is called in order to parse the challenge string from the bytes that were signed.
* It is specific to the specified chain driver. This function is needed because most signing
* algorithms add a prefix to the string before signing, so this function attempts to undo that.
* @param txnBytes - Original bytes that were signed as a Uint8Array
* @returns Parses out and returns the challenge string that was signed
*/
async function getChallengeStringFromBytes(txnBytes) {
return chainDriver.getChallengeStringFromBytesToSign(txnBytes);
}
/**
* Constructs a valid JSON challenge object from a valid well-formed EIP-4361 string. Note this
* doesn't check for validity at all. See the EIP-4361 proposal for more details about exact formatting
* requirements of the string.
* @param challenge - Valid EIP-4361 challenge string
* @returns JSON challenge object with all specified EIP-4361 fields
*/
function constructChallengeObjectFromString(challenge) {
const messageArray = challenge.split("\n");
const domain = messageArray[0].split(' ')[0];
const address = messageArray[1];
const statement = messageArray[3];
const uri = messageArray[5].split(' ')[1];
const version = messageArray[6].split(':')[1].trim();
const chainId = messageArray[7].split(':')[1].trim();
const nonce = messageArray[8].split(':')[1].trim();
const issuedAt = messageArray[9].split(':').slice(1).join(':').trim();
let expirationDate;
let notBefore;
let resources = [];
if (messageArray[10]) {
if (messageArray[10].indexOf('Expiration Time:') != -1) {
expirationDate = messageArray[10].split(':').slice(1).join(':').trim();
}
else if (messageArray[10].indexOf('Not Before:') != -1) {
notBefore = messageArray[10].split(':').slice(1).join(':').trim();
}
else if (messageArray[10].indexOf('Resources:') != -1) {
resources = [];
for (let i = 11; i < messageArray.length; i++) {
const resource = messageArray[i].split(' ').slice(1).join(' ').trim();
resources.push(resource);
}
}
}
if (messageArray[11]) {
if (messageArray[11].indexOf('Not Before:') != -1) {
notBefore = messageArray[11].split(':').slice(1).join(':').trim();
}
else if (messageArray[11].indexOf('Resources:') != -1) {
resources = [];
for (let i = 12; i < messageArray.length; i++) {
const resource = messageArray[i].split(' ').slice(1).join(' ').trim();
resources.push(resource);
}
}
}
if (messageArray[12]) {
if (messageArray[12].indexOf('Resources:') != -1) {
resources = [];
for (let i = 13; i < messageArray.length; i++) {
const resource = messageArray[i].split(' ').slice(1).join(' ').trim();
resources.push(resource);
}
}
}
return { domain, address, statement, expirationDate, notBefore, resources, issuedAt, uri, version, chainId, nonce };
}
/**
* Verifies a challenge is signed by the given addresses. Throws error if invalid. Specific to
* specified chain driver.
* @param originalChallengeToUint8Array - Uint8Array of the original bytes that were signed
* @param signedChallenge - Uint8Array of the signature bytes
* @param originalAddress - string that specifies the address who signed these bytes
*/
async function verifyChallengeSignature(originalChallengeToUint8Array, signedChallenge, originalAddress) {
await chainDriver.verifySignature(originalChallengeToUint8Array, signedChallenge, originalAddress);
}
/**
* Verifies an address owns all specified resources. Ignores everything that doesn't start with 'Asset ID: '.
* Defaults to succeeding if user has a balance of >= 1 for every asset.
* @param address - Address to verify
* @param resources - String array of URIs or Asset IDs. This function ignores every resource that doesn't start
* with 'Asset ID: '
* @param assetMinimumBalancesMap - Optional, but here, one can define a JSON object mapping of
* 'assetIDs' => minimumBalances. If assetMinimumBalancesMap[assetId] exists, it will check that the user owns
* more than the specified minimum balance. If not defined, will use the default.
* @param defaultMinimum - Optional. Default is normally set to check if user owns >= 1. Here, you can specify a
* new default minimum for all assets to fallback on if not defined in assetMinimumBalancesMap.
* @returns If successful, verification was successful. Looked up asset data is also returned for convenience.
* Throws error if invalid.
*/
async function verifyOwnershipOfAssets(address, resources, assetMinimumBalancesMap, defaultMinimum) {
const assetLookupData = await chainDriver.verifyOwnershipOfAssets(address, resources, assetMinimumBalancesMap, defaultMinimum);
return assetLookupData;
}
/**
* Sets the chain driver for the whole library. All chain-specific functions
* depend on a valid chain driver being set, so it is important that you call
* this function before doing anything. We export some already implemented ChainDriver
* classes from this library for your convenience. You may also choose to implement
* your own.
*
* For example in Blockin's sample demo site, we call setDriver(new AlgoDriver('Mainnet', API_KEY)), and
* once this is called, all other functions will use the implemented functions for Algorand defined
* in AlgoDriver
* @param driver - Instantiated ChainDriver object. See IChainDriver for the interface details
*/
function setChainDriver(driver) {
initializeVerify(driver);
initializeAuth(driver);
}
export { constructChallengeObjectFromString, constructChallengeStringFromChallengeObject, createAssetTransferTxn, createAssetTxn, createChallenge, generateNonceWithLastBlockTimestamp, sendTxn, setChainDriver, validateChallengeObjectIsWellFormed, verifyChallenge };
//# sourceMappingURL=index.js.map

@@ -55,3 +55,3 @@ import React, { useState, useEffect } from 'react';

var css_248z$1 = ":root {\n --background: #fff;\n --font-color: #494949; }\n\n@media (prefers-color-scheme: dark) {\n :root {\n --background: #3c3c3c;\n --font-color: #fafafa; } }\n\n.blockin-global {\n font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,\r Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; }\n\n.blockin-button {\n background-color: #b0d7fc;\n opacity: 0.85;\n color: black;\n padding: 12px 15px;\n font-weight: 600;\n border-radius: 10px;\n cursor: pointer; }\n\n.blockin-button:hover {\n opacity: 1; }\n\n.blockin-button:disabled {\n cursor: not-allowed; }\n\n.blockin-input {\n display: block;\n background-color: #ececec;\n border-radius: 5px;\n padding: 5px 10px;\n margin: 10px auto;\n text-align: center; }\n\n.blockin-closebutton {\n background: none;\n fill: black;\n margin: 0px 0px 20px 0px;\n border: none;\n float: right;\n display: flex;\n justify-content: flex-end;\n width: 100%;\n cursor: pointer; }\n\n.blockin-root {\n text-align: center;\n padding: 100px 0px;\n position: fixed;\n background: rgba(0, 0, 0, 0.7);\n top: 0;\n left: 0;\n transition: opacity 500ms;\n z-index: 50;\n min-height: 100vh;\n min-width: 100vw;\n display: flex;\n justify-content: center; }\n\n.blockin-popup-container {\n word-wrap: break-word;\n background-color: white;\n opacity: 100%;\n max-width: 600px;\n max-height: 600px;\n margin: 0px 10px 0px;\n padding: 30px;\n border-radius: 25px;\n justify-content: center; }\n\n.blockin-popup {\n word-wrap: break-word;\n background-color: white;\n opacity: 100%;\n max-width: 600px;\n max-height: 600px;\n justify-content: center;\n overflow-y: auto;\n padding-right: 10px; }\n\n/* width */\n.blockin-popup::-webkit-scrollbar {\n width: 10px; }\n\n/* Track */\n.blockin-popup::-webkit-scrollbar-track {\n background: #f1f1f1; }\n\n/* Handle */\n.blockin-popup::-webkit-scrollbar-thumb {\n background: #888;\n background-clip: padding-box; }\n\n/* Handle on hover */\n.blockin-popup::-webkit-scrollbar-thumb:hover {\n background: #555; }\n\n.blockin-addcustom {\n justify-content: space-between;\n align-items: center;\n width: 100%; }\n\n.blockin-listitem {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%; }\n\n.blockin-listitem-metadata {\n display: flex;\n text-align: left;\n align-items: center;\n height: 100%; }\n\n.blockin-listitem-button {\n display: flex;\n text-align: right;\n align-items: center;\n height: 100%;\n min-width: 125px;\n margin-left: 10px; }\n\n.blockin-listitem-button button {\n width: 100%;\n align-items: center;\n text-align: center;\n vertical-align: middle; }\n\n.blockin-listitem-logo {\n margin-right: 10px; }\n\n.blockin-header {\n display: flex;\n width: 100%; }\n\n.blockin-header-chain-info {\n display: flex;\n justify-content: space-evenly;\n align-items: center; }\n\n.blockin-header .header-end {\n width: 10%; }\n\n.blockin-header .header-middle {\n width: 80%; }\n\n.blockin-header h1 {\n margin-top: 0;\n font-size: larger;\n font-size: 24px; }\n\n.blockin-challenge-details {\n max-width: 500px;\n margin: 0px auto 0px;\n justify-content: center; }\n\n.blockin-chain-select button {\n display: flex;\n align-items: center;\n justify-content: center; }\n\n.blockin-chain-select .blockin-popup button {\n width: 100%;\n margin: 5px; }\n\n.blockin-chain-select-logo {\n margin-left: 5px; }\n\n.blockin-global .main-button {\n height: 50px; }\n\n.foo-bar {\n font-family: \"Avenir Next\", Helvetica, Arial, sans-serif;\n color: #005f20; }\n";
var css_248z$1 = ":root {\n --background: #fff;\n --font-color: #494949; }\n\n@media (prefers-color-scheme: dark) {\n :root {\n --background: #3c3c3c;\n --font-color: #fafafa; } }\n\n.blockin-global {\n font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,\r Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;\n box-sizing: content-box; }\n\n.blockin-button {\n background-color: #b0d7fc;\n opacity: 0.85;\n color: black;\n padding: 12px 15px;\n font-weight: 600;\n border-radius: 10px;\n cursor: pointer; }\n\n.blockin-button:hover {\n opacity: 1; }\n\n.blockin-button:disabled {\n cursor: not-allowed; }\n\n.blockin-input {\n display: block;\n background-color: #ececec;\n border-radius: 5px;\n padding: 5px 10px;\n margin: 10px auto;\n text-align: center; }\n\n.blockin-closebutton {\n background: none;\n fill: black;\n padding: 0px 0px 0px 0px;\n margin: 0px 0px 20px 0px;\n border: none;\n float: right;\n display: flex;\n justify-content: flex-end;\n width: 100%;\n cursor: pointer; }\n\n.blockin-root {\n text-align: center;\n padding: 100px 0px;\n position: fixed;\n background: rgba(0, 0, 0, 0.7);\n top: 0;\n left: 0;\n transition: opacity 500ms;\n z-index: 50;\n min-height: 100vh;\n min-width: 100vw;\n display: flex;\n justify-content: center; }\n\n.blockin-popup-container {\n word-wrap: break-word;\n background-color: white;\n opacity: 100%;\n max-width: 600px;\n max-height: 600px;\n margin: 0px 10px 0px;\n padding: 30px;\n border-radius: 25px;\n justify-content: center; }\n\n.blockin-popup {\n word-wrap: break-word;\n background-color: white;\n opacity: 100%;\n max-width: 600px;\n max-height: 600px;\n justify-content: center;\n overflow-y: auto;\n padding-right: 10px; }\n\n/* width */\n.blockin-popup::-webkit-scrollbar {\n width: 10px; }\n\n/* Track */\n.blockin-popup::-webkit-scrollbar-track {\n background: #f1f1f1; }\n\n/* Handle */\n.blockin-popup::-webkit-scrollbar-thumb {\n background: #888;\n background-clip: padding-box; }\n\n/* Handle on hover */\n.blockin-popup::-webkit-scrollbar-thumb:hover {\n background: #555; }\n\n.blockin-addcustom {\n justify-content: space-between;\n align-items: center;\n width: 100%; }\n\n.blockin-listitem {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%; }\n\n.blockin-listitem-metadata {\n display: flex;\n text-align: left;\n align-items: center;\n height: 100%; }\n\n.blockin-listitem-button {\n display: flex;\n text-align: right;\n align-items: center;\n height: 100%;\n min-width: 125px;\n margin-left: 10px; }\n\n.blockin-listitem-button button {\n width: 100%;\n align-items: center;\n text-align: center;\n vertical-align: middle; }\n\n.blockin-listitem-logo {\n margin-right: 10px; }\n\n.blockin-header {\n display: flex;\n width: 100%; }\n\n.blockin-header-chain-info {\n display: flex;\n justify-content: space-evenly;\n align-items: center; }\n\n.blockin-header .header-end {\n width: 10%; }\n\n.blockin-header .header-middle {\n width: 80%; }\n\n.blockin-header h1 {\n margin-top: 0;\n font-size: larger;\n font-size: 24px; }\n\n.blockin-challenge-details {\n max-width: 500px;\n margin: 0px auto 0px;\n justify-content: center; }\n\n.blockin-chain-select button {\n display: flex;\n align-items: center;\n justify-content: center; }\n\n.blockin-chain-select .blockin-popup button {\n width: 100%;\n margin: 5px; }\n\n.blockin-chain-select-logo {\n margin-left: 5px; }\n\n.blockin-global .main-button {\n height: 50px; }\n";
styleInject(css_248z$1);

@@ -339,8 +339,8 @@

modalIsVisible && React.createElement(React.Fragment, null,
React.createElement("section", { className: 'blockin-root' },
React.createElement("div", { className: 'blockin-root' },
React.createElement("div", { className: "blockin-popup-container" },
React.createElement("div", { className: "blockin-popup" },
React.createElement("header", { className: 'blockin-header' },
React.createElement("span", { className: "header-end" }),
React.createElement("section", { className: "header-middle" },
React.createElement("div", { className: 'blockin-header' },
React.createElement("div", { className: "header-end" }),
React.createElement("div", { className: "header-middle" },
React.createElement("h1", null, "Sign In with Blockin!"),

@@ -356,8 +356,8 @@ React.createElement("div", { className: 'blockin-header-chain-info' },

React.createElement("h5", null, "Blockin")))),
React.createElement("span", { className: "header-end" },
React.createElement("div", { className: "header-end" },
React.createElement("button", { className: 'blockin-closebutton', onClick: () => { setModalIsVisible(!modalIsVisible); } },
React.createElement("svg", { width: 25, height: 25, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 320 512" },
React.createElement("path", { d: "M310.6 361.4c12.5 12.5 12.5 32.75 0 45.25C304.4 412.9 296.2 416 288 416s-16.38-3.125-22.62-9.375L160 301.3L54.63 406.6C48.38 412.9 40.19 416 32 416S15.63 412.9 9.375 406.6c-12.5-12.5-12.5-32.75 0-45.25l105.4-105.4L9.375 150.6c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0L160 210.8l105.4-105.4c12.5-12.5 32.75-12.5 45.25 0s12.5 32.75 0 45.25l-105.4 105.4L310.6 361.4z" }))))),
React.createElement("hr", null),
React.createElement("div", { className: 'blockin-challenge' },
React.createElement("hr", null),
React.createElement("h3", null, "Sign-In Details"),

@@ -401,4 +401,4 @@ React.createElement("div", { className: 'blockin-challenge-details' },

challengeParams.version ? challengeParams.version : '1 (Default)'))))),
React.createElement("hr", null),
React.createElement("div", { className: 'blockin-preset-resources' }, !resourcesAreHidden && React.createElement(React.Fragment, null, (displayedAssets.length !== 0 || displayedUris.length !== 0) && React.createElement(React.Fragment, null,
React.createElement("hr", null),
React.createElement("h3", null, "Select Resources"),

@@ -491,9 +491,8 @@ React.createElement("p", null, "Select the resources you would like to receive access to:"),

setUri('');
}) }, "Add URI"))),
React.createElement("hr", null))),
}) }, "Add URI"))))),
React.createElement("div", { className: 'blockin-selected-resources-summary' },
(selectedResources === null || selectedResources === void 0 ? void 0 : selectedResources.length) > 0 && React.createElement(React.Fragment, null,
React.createElement("hr", null),
React.createElement("h3", null, "Summary of Selected Resources"),
React.createElement("p", null, "Please take a moment to review all your selected resources for this sign-in attempt."),
React.createElement("hr", null)),
React.createElement("p", null, "Please take a moment to review all your selected resources for this sign-in attempt.")),
displayedAssets.map(elem => {

@@ -503,2 +502,3 @@ if (!selectedResources.includes(`Asset ID: ${elem.assetId}`))

return React.createElement(React.Fragment, null,
React.createElement("hr", null),
React.createElement("div", { className: 'blockin-listitem' },

@@ -581,3 +581,3 @@ React.createElement("div", { className: 'blockin-listitem-metadata' },

React.createElement("div", { className: 'blockin-sign-challenge-button' },
(selectedResources === null || selectedResources === void 0 ? void 0 : selectedResources.length) == 0 && React.createElement("hr", null),
React.createElement("hr", null),
React.createElement("h3", null, "Sign Challenge and Submit"),

@@ -596,3 +596,3 @@ React.createElement("p", null,

var css_248z = ":root {\n --background: #fff;\n --font-color: #494949; }\n\n@media (prefers-color-scheme: dark) {\n :root {\n --background: #3c3c3c;\n --font-color: #fafafa; } }\n\n.blockin-global {\n font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,\r Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif; }\n\n.blockin-button {\n background-color: #b0d7fc;\n opacity: 0.85;\n color: black;\n padding: 12px 15px;\n font-weight: 600;\n border-radius: 10px;\n cursor: pointer; }\n\n.blockin-button:hover {\n opacity: 1; }\n\n.blockin-button:disabled {\n cursor: not-allowed; }\n\n.blockin-input {\n display: block;\n background-color: #ececec;\n border-radius: 5px;\n padding: 5px 10px;\n margin: 10px auto;\n text-align: center; }\n\n.blockin-closebutton {\n background: none;\n fill: black;\n margin: 0px 0px 20px 0px;\n border: none;\n float: right;\n display: flex;\n justify-content: flex-end;\n width: 100%;\n cursor: pointer; }\n\n.blockin-root {\n text-align: center;\n padding: 100px 0px;\n position: fixed;\n background: rgba(0, 0, 0, 0.7);\n top: 0;\n left: 0;\n transition: opacity 500ms;\n z-index: 50;\n min-height: 100vh;\n min-width: 100vw;\n display: flex;\n justify-content: center; }\n\n.blockin-popup-container {\n word-wrap: break-word;\n background-color: white;\n opacity: 100%;\n max-width: 600px;\n max-height: 600px;\n margin: 0px 10px 0px;\n padding: 30px;\n border-radius: 25px;\n justify-content: center; }\n\n.blockin-popup {\n word-wrap: break-word;\n background-color: white;\n opacity: 100%;\n max-width: 600px;\n max-height: 600px;\n justify-content: center;\n overflow-y: auto;\n padding-right: 10px; }\n\n/* width */\n.blockin-popup::-webkit-scrollbar {\n width: 10px; }\n\n/* Track */\n.blockin-popup::-webkit-scrollbar-track {\n background: #f1f1f1; }\n\n/* Handle */\n.blockin-popup::-webkit-scrollbar-thumb {\n background: #888;\n background-clip: padding-box; }\n\n/* Handle on hover */\n.blockin-popup::-webkit-scrollbar-thumb:hover {\n background: #555; }\n\n.blockin-addcustom {\n justify-content: space-between;\n align-items: center;\n width: 100%; }\n\n.blockin-listitem {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%; }\n\n.blockin-listitem-metadata {\n display: flex;\n text-align: left;\n align-items: center;\n height: 100%; }\n\n.blockin-listitem-button {\n display: flex;\n text-align: right;\n align-items: center;\n height: 100%;\n min-width: 125px;\n margin-left: 10px; }\n\n.blockin-listitem-button button {\n width: 100%;\n align-items: center;\n text-align: center;\n vertical-align: middle; }\n\n.blockin-listitem-logo {\n margin-right: 10px; }\n\n.blockin-header {\n display: flex;\n width: 100%; }\n\n.blockin-header-chain-info {\n display: flex;\n justify-content: space-evenly;\n align-items: center; }\n\n.blockin-header .header-end {\n width: 10%; }\n\n.blockin-header .header-middle {\n width: 80%; }\n\n.blockin-header h1 {\n margin-top: 0;\n font-size: larger;\n font-size: 24px; }\n\n.blockin-challenge-details {\n max-width: 500px;\n margin: 0px auto 0px;\n justify-content: center; }\n\n.blockin-chain-select button {\n display: flex;\n align-items: center;\n justify-content: center; }\n\n.blockin-chain-select .blockin-popup button {\n width: 100%;\n margin: 5px; }\n\n.blockin-chain-select-logo {\n margin-left: 5px; }\n\n.blockin-global .main-button {\n height: 50px; }\n";
var css_248z = ":root {\n --background: #fff;\n --font-color: #494949; }\n\n@media (prefers-color-scheme: dark) {\n :root {\n --background: #3c3c3c;\n --font-color: #fafafa; } }\n\n.blockin-global {\n font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,\r Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;\n box-sizing: content-box; }\n\n.blockin-button {\n background-color: #b0d7fc;\n opacity: 0.85;\n color: black;\n padding: 12px 15px;\n font-weight: 600;\n border-radius: 10px;\n cursor: pointer; }\n\n.blockin-button:hover {\n opacity: 1; }\n\n.blockin-button:disabled {\n cursor: not-allowed; }\n\n.blockin-input {\n display: block;\n background-color: #ececec;\n border-radius: 5px;\n padding: 5px 10px;\n margin: 10px auto;\n text-align: center; }\n\n.blockin-closebutton {\n background: none;\n fill: black;\n padding: 0px 0px 0px 0px;\n margin: 0px 0px 20px 0px;\n border: none;\n float: right;\n display: flex;\n justify-content: flex-end;\n width: 100%;\n cursor: pointer; }\n\n.blockin-root {\n text-align: center;\n padding: 100px 0px;\n position: fixed;\n background: rgba(0, 0, 0, 0.7);\n top: 0;\n left: 0;\n transition: opacity 500ms;\n z-index: 50;\n min-height: 100vh;\n min-width: 100vw;\n display: flex;\n justify-content: center; }\n\n.blockin-popup-container {\n word-wrap: break-word;\n background-color: white;\n opacity: 100%;\n max-width: 600px;\n max-height: 600px;\n margin: 0px 10px 0px;\n padding: 30px;\n border-radius: 25px;\n justify-content: center; }\n\n.blockin-popup {\n word-wrap: break-word;\n background-color: white;\n opacity: 100%;\n max-width: 600px;\n max-height: 600px;\n justify-content: center;\n overflow-y: auto;\n padding-right: 10px; }\n\n/* width */\n.blockin-popup::-webkit-scrollbar {\n width: 10px; }\n\n/* Track */\n.blockin-popup::-webkit-scrollbar-track {\n background: #f1f1f1; }\n\n/* Handle */\n.blockin-popup::-webkit-scrollbar-thumb {\n background: #888;\n background-clip: padding-box; }\n\n/* Handle on hover */\n.blockin-popup::-webkit-scrollbar-thumb:hover {\n background: #555; }\n\n.blockin-addcustom {\n justify-content: space-between;\n align-items: center;\n width: 100%; }\n\n.blockin-listitem {\n display: flex;\n justify-content: space-between;\n align-items: center;\n width: 100%; }\n\n.blockin-listitem-metadata {\n display: flex;\n text-align: left;\n align-items: center;\n height: 100%; }\n\n.blockin-listitem-button {\n display: flex;\n text-align: right;\n align-items: center;\n height: 100%;\n min-width: 125px;\n margin-left: 10px; }\n\n.blockin-listitem-button button {\n width: 100%;\n align-items: center;\n text-align: center;\n vertical-align: middle; }\n\n.blockin-listitem-logo {\n margin-right: 10px; }\n\n.blockin-header {\n display: flex;\n width: 100%; }\n\n.blockin-header-chain-info {\n display: flex;\n justify-content: space-evenly;\n align-items: center; }\n\n.blockin-header .header-end {\n width: 10%; }\n\n.blockin-header .header-middle {\n width: 80%; }\n\n.blockin-header h1 {\n margin-top: 0;\n font-size: larger;\n font-size: 24px; }\n\n.blockin-challenge-details {\n max-width: 500px;\n margin: 0px auto 0px;\n justify-content: center; }\n\n.blockin-chain-select button {\n display: flex;\n align-items: center;\n justify-content: center; }\n\n.blockin-chain-select .blockin-popup button {\n width: 100%;\n margin: 5px; }\n\n.blockin-chain-select-logo {\n margin-left: 5px; }\n\n.blockin-global .main-button {\n height: 50px; }\n";
styleInject(css_248z);

@@ -629,8 +629,8 @@

React.createElement("div", { className: "blockin-popup" },
React.createElement("header", { className: 'blockin-header' },
React.createElement("span", { className: "header-end" }),
React.createElement("div", { className: 'blockin-header' },
React.createElement("div", { className: "header-end" }),
React.createElement("section", { className: "header-middle" },
React.createElement("h1", null, "Chain Select"),
React.createElement("div", { className: 'blockin-header-chain-info' })),
React.createElement("span", { className: "header-end" },
React.createElement("div", { className: "header-end" },
React.createElement("button", { className: 'blockin-closebutton', onClick: () => { setMenuIsVisible(!menuIsVisible); } },

@@ -637,0 +637,0 @@ React.createElement("svg", { width: 25, height: 25, xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 320 512" },

@@ -1,2 +0,2 @@

import { ChallengeParams } from "../../@types/verify";
import { ChallengeParams } from "../../types/verify.types.js";
/**

@@ -3,0 +3,0 @@ * Used if needed to input different props for multiple chains using ChainSelect.

@@ -1,3 +0,3 @@

import { IChainDriver } from './@types/ChainDriver';
import { ChallengeParams, CreateChallengeOptions, VerifyChallengeOptions } from './@types/verify';
import { IChainDriver } from './types/ChainDriver.types.js';
import { ChallengeParams, CreateChallengeOptions, VerifyChallengeOptions } from './types/verify.types.js';
export declare function initializeVerify(driver: IChainDriver): void;

@@ -4,0 +4,0 @@ /**

{
"name": "blockin",
"version": "1.0.51",
"description": "<div id=\"top\"></div>\r <!--\r *** Thanks for checking out the Best-README-Template. If you have a suggestion\r *** that would make this better, please fork the repo and create a pull request\r *** or simply open an issue with the tag \"enhancement\".\r *** Don't forget to give the project a star!\r *** Thanks again! Now go create something AMAZING! :D\r -->",
"types": "dist/index.d.ts",
"version": "1.1.0",
"description": "",
"files": [
"dist"
],
"prepublish": "tsc",
"main": "./dist/index.js",
"module": "./dist/index.cjs",
"type": "module",
"exports": {
".": {
"require": "./dist/index.cjs",
"import": "./dist/index.js",
"default": "./dist/index.js"
},
"./ui": {
"require": "./dist/ui/index.cjs",
"import": "./dist/ui/index.js",
"default": "./dist/ui/index.js"
},
"./dist/ui": {
"require": "./dist/ui/index.cjs",
"import": "./dist/ui/index.js",
"default": "./dist/ui/index.js"
}
},
"scripts": {
"prepack": "npm run build && rm -rf ./dist/*.map ./dist/ui/*.map",
"test": "echo \"Error: no test specified\" && exit 1",
"build": "rm -rf dist && rollup -c && npm run postrollup && tsc --build",
"postrollup": "mv ./dist/index* ./dist/*.scss ./dist/ui",
"build": "rm -rf dist && npm run build:ui && npm run build:core",
"build:ui": "rollup --config ./ui-rollup.config.js && npm run postuirollup",
"build:core": "rollup --config ./rollup.config.js && npm run postcorerollup",
"postcorerollup": "cp ./dist/index.d.ts ./dist/index.d.cts",
"postuirollup": "mv ./dist/index* ./dist/*.scss ./dist/ui && cp ./dist/ui/index.d.ts ./dist/ui/index.d.cts",
"storybook": "start-storybook -p 6006",

@@ -20,2 +42,7 @@ "storybook:export": "build-storybook"

"license": "ISC",
"peerDependencies": {
"react": ">=18.0.0",
"react-dom": ">=18.0.0"
},
"prepublishOnly": "npm run build",
"devDependencies": {

@@ -39,5 +66,6 @@ "@babel/core": "^7.15.0",

"jest": "^26.6.3",
"local-package-publisher": "^1.0.4",
"node-sass": "^5.0.0",
"postcss": "^8.4.13",
"react": "^17.0.1",
"react": "^18.0.0",
"react-dom": "^17.0.1",

@@ -57,20 +85,3 @@ "rollup": "^2.72.1",

},
"dependencies": {
"algosdk": "^1.15.0",
"react": "^18.1.0",
"tweetnacl": "^1.0.3"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
},
"main": "rollup.config.js",
"repository": {
"type": "git",
"url": "git+https://github.com/matt-davison/blockin.git"
},
"bugs": {
"url": "https://github.com/matt-davison/blockin/issues"
},
"homepage": "https://github.com/matt-davison/blockin#readme"
"dependencies": {}
}

@@ -58,3 +58,3 @@ <div id="top"></div>

This README focuses mainly on this codebase. The [`Blockin Docs`](https://trevormil.gitbook.io/blockin/) and the [`Blockin Demo`](https://blockin.vercel.app/) provide much more documentation on what Blockin is, how it works, and how to use it.
This README focuses mainly on this codebase. The [`Blockin Docs`](https://blockin.gitbook.io/blockin/) and the [`Blockin Demo`](https://blockin.vercel.app/) provide much more documentation on what Blockin is, how it works, and how to use it.

@@ -78,3 +78,3 @@ ## Scope of the Library

```
Visit the [`Blockin Docs`](https://trevormil.gitbook.io/blockin/) for documentation on how to use this library.
Visit the [`Blockin Docs`](https://blockin.gitbook.io/blockin/) for documentation on how to use this library.

@@ -86,3 +86,3 @@ An example frontend and backend using Blockin can be found at [`Blockin Sample Integration Site`](https://github.com/Blockin-Labs/Blockin-Sample-Integration).

These are the chains that are natively supported by this library.
* **Algorand** via AlgoDriver defined in the ChainDrivers folder
* **Algorand** (AlgoDriver) via the blockin-algo-driver NPM package ([`Source Code`](https://github.com/Blockin-Labs/blockin-algo-driver)).
* Uses Purestake API and algosdk npm library

@@ -92,3 +92,3 @@

We are currently working on adding implementations for more blockchains.
We are currently working on adding implementations for more blockchains and also making it more convenient to import/export these templates.

@@ -104,4 +104,4 @@ ## Example Sites Using Blockin

* Blockin Library Functions: These live in the src folder (excluding the src/ui folder). This is for all the asset creation and verification functions.
* If contributing to this part of the library, it is important that you become familiar with the ChainDriver interface and how it used. More information can be found at [`Blockin Docs`](https://trevormil.gitbook.io/blockin/).
* UI Components: These importable UI components can be found in the src/ui folder. This, in theory, should be able to become its own library in the future.
* If contributing to this part of the library, it is important that you become familiar with the ChainDriver interface and how it used. More information can be found at [`Blockin Docs`](https://blockin.gitbook.io/blockin/).
* UI Components: These importable UI components can be found in the src/ui folder. This, in theory, should be decoupled from the core library and able to eventually become its own library in the future.
* View the README in src/ui for more information.

@@ -113,7 +113,7 @@ * <img src="images/signin-chainselect-together.PNG" />

Everything is built using ```npm run build``` which creates a build folder in the ```dist``` directory. The build command first rolls up the UI components using rollup.js, and then it builds everything else.
Everything is built using ```npm run build``` which creates a build folder in the ```dist``` directory. The build command first rolls up the UI components, and then it builds everything else.
## Documentation
For more in-depth documentation, visit the [`Blockin Docs`](https://trevormil.gitbook.io/blockin/) or the [`Blockin Paper`](https://github.com/kking935/Blockin-Demo).
For more in-depth documentation, visit the [`Blockin Docs`](https://blockin.gitbook.io/blockin/) or the [`Blockin Paper`](https://github.com/kking935/Blockin-Demo).

@@ -120,0 +120,0 @@

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc