New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@lit-protocol/auth-browser

Package Overview
Dependencies
Maintainers
0
Versions
528
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lit-protocol/auth-browser - npm Package Compare versions

Comparing version

to
6.4.2-pr-621

20

package.json

@@ -24,3 +24,3 @@ {

],
"version": "6.4.1",
"version": "6.4.2-pr-621",
"dependencies": {

@@ -33,15 +33,11 @@ "@ethersproject/abstract-provider": "5.7.0",

"@ethersproject/wallet": "5.7.0",
"@lit-protocol/accs-schemas": "0.0.9",
"@lit-protocol/contracts": "^0.0.39",
"@openagenda/verror": "^3.1.4",
"ajv": "^8.12.0",
"ethers": "^5.7.1",
"jszip": "^3.10.1",
"punycode": "2.3.1",
"uint8arrays": "^4.0.3",
"@lit-protocol/constants": "6.4.1",
"@lit-protocol/logger": "6.4.1",
"@lit-protocol/misc": "6.4.1",
"@lit-protocol/misc-browser": "6.4.1",
"@lit-protocol/types": "6.4.1",
"@lit-protocol/uint8arrays": "6.4.1",
"@lit-protocol/constants": "6.4.2-pr-621",
"@lit-protocol/logger": "6.4.2-pr-621",
"@lit-protocol/misc": "6.4.2-pr-621",
"@lit-protocol/misc-browser": "6.4.2-pr-621",
"@lit-protocol/types": "6.4.2-pr-621",
"@lit-protocol/uint8arrays": "6.4.2-pr-621",
"tslib": "1.14.1"

@@ -48,0 +44,0 @@ },

24

src/lib/auth-browser.js

@@ -8,3 +8,2 @@ "use strict";

const constants_1 = require("@lit-protocol/constants");
const misc_1 = require("@lit-protocol/misc");
const cosmos_1 = require("./chains/cosmos");

@@ -30,7 +29,7 @@ const eth_1 = require("./chains/eth");

if (!chainInfo) {
(0, misc_1.throwError)({
message: `Unsupported chain selected. Please select one of: ${Object.keys(constants_1.ALL_LIT_CHAINS)}`,
errorKind: constants_1.LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.kind,
errorCode: constants_1.LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.name,
});
throw new constants_1.UnsupportedChainException({
info: {
chain,
},
}, `Unsupported chain selected. Please select one of: %s`, Object.keys(constants_1.ALL_LIT_CHAINS));
}

@@ -62,11 +61,10 @@ if (!expiration) {

}
else {
return (0, misc_1.throwError)({
message: `vmType not found for this chain: ${chain}. This should not happen. Unsupported chain selected. Please select one of: ${Object.keys(constants_1.ALL_LIT_CHAINS)}`,
errorKind: constants_1.LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.kind,
errorCode: constants_1.LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.name,
});
}
// Else, throw an error
throw new constants_1.UnsupportedChainException({
info: {
chain,
},
}, `vmType not found for this chain: %s. This should not happen. Unsupported chain selected. Please select one of: %s`, chain, Object.keys(constants_1.ALL_LIT_CHAINS));
};
exports.checkAndSignAuthMessage = checkAndSignAuthMessage;
//# sourceMappingURL=auth-browser.js.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.serializeSignDoc = exports.signAndSaveAuthMessage = exports.checkAndSignCosmosAuthMessage = exports.connectCosmosProvider = void 0;
const uint8arrays_1 = require("@lit-protocol/uint8arrays");
const constants_1 = require("@lit-protocol/constants");
const misc_1 = require("@lit-protocol/misc");
const uint8arrays_1 = require("@lit-protocol/uint8arrays");
/** ---------- Local Helpers ---------- */

@@ -27,10 +27,8 @@ /**

}
// -- finally
const message = 'No web3 wallet was found that works with Cosmos. Install a Cosmos wallet or choose another chain';
const error = constants_1.LIT_ERROR.NO_WALLET_EXCEPTION;
(0, misc_1.throwError)({
message,
errorKind: error.kind,
errorCode: error.name,
});
// no provider found
throw new constants_1.NoWalletException({
info: {
walletType,
},
}, 'No web3 wallet was found that works with Cosmos. Install a Cosmos wallet or choose another chain');
};

@@ -75,11 +73,11 @@ /** ---------- Exports ---------- */

const storageKey = constants_1.LOCAL_STORAGE_KEYS.AUTH_COSMOS_SIGNATURE;
let authSig = localStorage.getItem(storageKey);
let authSigString = localStorage.getItem(storageKey);
// -- if not found in local storage
if (!authSig) {
if (!authSigString) {
(0, misc_1.log)('signing auth message because sig is not in local storage');
await (0, exports.signAndSaveAuthMessage)(connectedCosmosProvider);
authSig = localStorage.getItem(storageKey);
authSigString = localStorage.getItem(storageKey);
}
// -- if found in local storage
authSig = JSON.parse(authSig);
let authSig = JSON.parse(authSigString);
// -- validate

@@ -89,4 +87,4 @@ if (connectedCosmosProvider.account != authSig.address) {

await (0, exports.signAndSaveAuthMessage)(connectedCosmosProvider);
authSig = localStorage.getItem(storageKey);
authSig = JSON.parse(authSig);
authSigString = localStorage.getItem(storageKey);
authSig = JSON.parse(authSigString);
}

@@ -133,3 +131,3 @@ (0, misc_1.log)('authSig', authSig);

const digest_hex = (0, uint8arrays_1.uint8arrayToString)(new Uint8Array(digest), 'base16');
let authSig = {
const authSig = {
sig: signed.signature,

@@ -136,0 +134,0 @@ derivedVia: 'cosmos.signArbitrary',

@@ -0,4 +1,5 @@

import { Web3Provider, JsonRpcSigner } from '@ethersproject/providers';
import { ethers } from 'ethers';
import { IEither } from '@lit-protocol/constants';
import { AuthSig, AuthCallbackParams } from '@lit-protocol/types';
import { Web3Provider, JsonRpcSigner } from '@ethersproject/providers';
/** ---------- Local Interfaces ---------- */

@@ -13,5 +14,3 @@ interface ConnectWeb3 {

}
interface RPCUrls {
[chainId: string]: string;
}
declare type RPCUrls = Record<string, string>;
interface signAndSaveAuthParams {

@@ -29,7 +28,7 @@ web3: Web3Provider;

name: string;
outputs: Array<{
outputs: {
internalType: string;
name: string;
type: string;
}>;
}[];
stateMutability: string;

@@ -39,3 +38,3 @@ type: string;

interface IABIEncode {
abi: Array<IABI>;
abi: IABI[];
functionName: string;

@@ -45,3 +44,3 @@ functionParams: [];

interface IABIDecode {
abi: Array<IABI>;
abi: IABI[];
functionName: string;

@@ -59,2 +58,8 @@ data: any;

}
declare const WALLET_ERROR: {
readonly REQUESTED_CHAIN_HAS_NOT_BEEN_ADDED: 4902;
readonly NO_SUCH_METHOD: -32601;
};
export declare type WALLET_ERROR_TYPE = keyof typeof WALLET_ERROR;
export declare type WALLET_ERROR_VALUES = (typeof WALLET_ERROR)[keyof typeof WALLET_ERROR];
/** ---------- Local Helpers ---------- */

@@ -120,3 +125,2 @@ /**

* (ABI) Decode call data
* TODO: fix "any"
*

@@ -126,5 +130,3 @@ * @param { IABIDecode }

*/
export declare const decodeCallResult: ({ abi, functionName, data, }: IABIDecode) => {
answer: string;
} | any;
export declare const decodeCallResult: ({ abi, functionName, data, }: IABIDecode) => ethers.utils.Result;
/**

@@ -131,0 +133,0 @@ * @browserOnly

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.signMessageAsync = exports.signMessage = exports.signAndSaveAuthMessage = exports.checkAndSignEVMAuthMessage = exports.disconnectWeb3 = exports.connectWeb3 = exports.decodeCallResult = exports.encodeCallData = exports.getRPCUrls = exports.getMustResign = exports.isSignedMessageExpired = exports.getChainId = exports.chainHexIdToChainName = void 0;
const constants_1 = require("@lit-protocol/constants");
const ethers_1 = require("ethers");
const buffer_1 = require("buffer");
const bytes_1 = require("@ethersproject/bytes");
const providers_1 = require("@ethersproject/providers");
const strings_1 = require("@ethersproject/strings");
// import WalletConnectProvider from '@walletconnect/ethereum-provider';
const strings_1 = require("@ethersproject/strings");
const bytes_1 = require("@ethersproject/bytes");
const wallet_1 = require("@ethersproject/wallet");
const ethereum_provider_1 = require("@walletconnect/ethereum-provider");
const modal_1 = require("../connect-modal/modal");
const providers_1 = require("@ethersproject/providers");
const ethers_1 = require("ethers");
const utils_1 = require("ethers/lib/utils");
const siwe_1 = require("siwe");
const utils_1 = require("ethers/lib/utils");
// @ts-ignore: If importing 'nacl' directly, the built files will use .default instead
const nacl = require("tweetnacl");
const naclUtil = require("tweetnacl-util");
// @ts-ignore: If importing 'nacl' directly, the built files will use .default instead
const nacl = require("tweetnacl");
const buffer_1 = require("buffer");
const constants_1 = require("@lit-protocol/constants");
const misc_1 = require("@lit-protocol/misc");
const misc_browser_1 = require("@lit-protocol/misc-browser");
const modal_1 = require("../connect-modal/modal");
if (globalThis && typeof globalThis.Buffer === 'undefined') {
globalThis.Buffer = buffer_1.Buffer;
}
var WALLET_ERROR;
(function (WALLET_ERROR) {
WALLET_ERROR[WALLET_ERROR["REQUESTED_CHAIN_HAS_NOT_BEEN_ADDED"] = 4902] = "REQUESTED_CHAIN_HAS_NOT_BEEN_ADDED";
WALLET_ERROR[WALLET_ERROR["NO_SUCH_METHOD"] = -32601] = "NO_SUCH_METHOD";
})(WALLET_ERROR || (WALLET_ERROR = {}));
const WALLET_ERROR = {
REQUESTED_CHAIN_HAS_NOT_BEEN_ADDED: 4902,
NO_SUCH_METHOD: -32601,
};
/** ---------- Local Helpers ---------- */

@@ -40,3 +39,2 @@ /**

// -- setup
const keys = Object.keys(constants_1.LIT_CHAINS);
const entries = Object.entries(constants_1.LIT_CHAINS);

@@ -46,15 +44,16 @@ const hexIds = Object.values(constants_1.LIT_CHAINS).map((chain) => '0x' + chain.chainId.toString(16));

if (!chainHexId.startsWith('0x')) {
(0, misc_1.throwError)({
message: `${chainHexId} should begin with "0x"`,
errorKind: constants_1.LIT_ERROR.WRONG_PARAM_FORMAT.kind,
errorCode: constants_1.LIT_ERROR.WRONG_PARAM_FORMAT.name,
});
throw new constants_1.WrongParamFormat({
info: {
param: 'chainHexId',
value: chainHexId,
},
}, '%s should begin with "0x"', chainHexId);
}
// -- validate:: hex id must be listed in constants
if (!hexIds.includes(chainHexId)) {
(0, misc_1.throwError)({
message: `${chainHexId} cannot be found in LIT_CHAINS`,
errorKind: constants_1.LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.kind,
errorCode: constants_1.LIT_ERROR.UNSUPPORTED_CHAIN_EXCEPTION.name,
});
throw new constants_1.UnsupportedChainException({
info: {
chainHexId,
},
}, `Unsupported chain selected. Please select one of: %s`, Object.keys(constants_1.LIT_CHAINS));
}

@@ -68,7 +67,7 @@ // -- search

// -- fail case
(0, misc_1.throwError)({
message: `Failed to convert ${chainHexId}`,
errorKind: constants_1.LIT_ERROR.UNKNOWN_ERROR.kind,
errorCode: constants_1.LIT_ERROR.UNKNOWN_ERROR.name,
});
throw new constants_1.UnknownError({
info: {
chainHexId,
},
}, 'Failed to convert %s', chainHexId);
};

@@ -91,7 +90,7 @@ exports.chainHexIdToChainName = chainHexIdToChainName;

(0, misc_1.log)('getNetwork threw an exception', e);
resultOrError = (0, constants_1.ELeft)({
message: `Incorrect network selected. Please switch to the ${chain} network in your wallet and try again.`,
errorKind: constants_1.LIT_ERROR.WRONG_NETWORK_EXCEPTION.kind,
errorCode: constants_1.LIT_ERROR.WRONG_NETWORK_EXCEPTION.name,
});
resultOrError = (0, constants_1.ELeft)(new constants_1.WrongNetworkException({
info: {
chain,
},
}, `Incorrect network selected. Please switch to the %s network in your wallet and try again.`, chain));
}

@@ -169,4 +168,3 @@ return resultOrError;

const keys = Object.keys(constants_1.LIT_CHAINS);
for (let i = 0; i < keys.length; i++) {
const chainName = keys[i];
for (const chainName of keys) {
const chainId = constants_1.LIT_CHAINS[chainName].chainId;

@@ -188,3 +186,3 @@ const rpcUrl = constants_1.LIT_CHAINS[chainName].rpcUrls[0];

const encodeCallData = ({ abi, functionName, functionParams, }) => {
throw new Error('encodeCallData has been removed.');
throw new constants_1.RemovedFunctionError({}, 'encodeCallData has been removed.');
};

@@ -195,3 +193,2 @@ exports.encodeCallData = encodeCallData;

* (ABI) Decode call data
* TODO: fix "any"
*

@@ -315,7 +312,7 @@ * @param { IABIDecode }

if (error.code === WALLET_ERROR.NO_SUCH_METHOD) {
(0, misc_1.throwError)({
message: `Incorrect network selected. Please switch to the ${chain} network in your wallet and try again.`,
errorKind: constants_1.LIT_ERROR.WRONG_NETWORK_EXCEPTION.kind,
errorCode: constants_1.LIT_ERROR.WRONG_NETWORK_EXCEPTION.name,
});
throw new constants_1.WrongNetworkException({
info: {
chain,
},
}, `Incorrect network selected. Please switch to the ${chain} network in your wallet and try again.`);
}

@@ -338,3 +335,3 @@ else {

const selectedChainIdHex = (0, misc_1.numberToHex)(selectedChainId);
const authSigOrError = (0, misc_browser_1.getStorageItem)(constants_1.LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
let authSigOrError = (0, misc_browser_1.getStorageItem)(constants_1.LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
(0, misc_1.log)('currentChainIdOrError:', currentChainIdOrError);

@@ -345,4 +342,9 @@ (0, misc_1.log)('selectedChainId:', selectedChainId);

// -- 3. check all variables before executing business logic
if (currentChainIdOrError.type === "ERROR" /* EITHER_TYPE.ERROR */) {
return (0, misc_1.throwError)(currentChainIdOrError.result);
if (currentChainIdOrError.type === constants_1.EITHER_TYPE.ERROR) {
throw new constants_1.UnknownError({
info: {
chainId: chain,
},
cause: currentChainIdOrError.result,
}, 'Unknown error when getting chain id');
}

@@ -406,7 +408,6 @@ (0, misc_1.log)('chainId from web3', currentChainIdOrError);

(0, misc_1.log)('checking if sig is in local storage');
if (authSigOrError.type === "ERROR" /* EITHER_TYPE.ERROR */) {
if (authSigOrError.type === constants_1.EITHER_TYPE.ERROR) {
(0, misc_1.log)('signing auth message because sig is not in local storage');
try {
// @ts-ignore
authSigOrError.result = await _signAndGetAuth({
const authSig = await _signAndGetAuth({
web3,

@@ -420,20 +421,26 @@ account,

});
authSigOrError = {
type: constants_1.EITHER_TYPE.SUCCESS,
result: JSON.stringify(authSig),
};
}
catch (e) {
(0, misc_1.log)(e);
return (0, misc_1.throwError)({
message: e.message,
errorKind: constants_1.LIT_ERROR.UNKNOWN_ERROR.kind,
errorCode: constants_1.LIT_ERROR.UNKNOWN_ERROR.name,
});
throw new constants_1.UnknownError({
info: {
account,
chainId: selectedChain.chainId,
resources,
expiration: expirationString,
uri,
nonce,
},
cause: e,
}, 'Could not get authenticated message');
}
authSigOrError.type = "SUCCESS" /* EITHER_TYPE.SUCCESS */;
// Log new authSig
(0, misc_1.log)('5. authSigOrError:', authSigOrError);
}
// -- 6. case: Lit auth signature IS in the local storage
// @ts-ignore
let authSig = authSigOrError.result;
if (typeof authSig === 'string') {
authSig = JSON.parse(authSig);
}
const authSigString = authSigOrError.result;
let authSig = JSON.parse(authSigString);
(0, misc_1.log)('6. authSig:', authSig);

@@ -456,3 +463,3 @@ // -- 7. case: when we are NOT on the right wallet address

else {
let mustResign = (0, exports.getMustResign)(authSig, resources);
const mustResign = (0, exports.getMustResign)(authSig, resources);
if (mustResign) {

@@ -501,11 +508,11 @@ authSig = await _signAndGetAuth({

});
let authSigOrError = (0, misc_browser_1.getStorageItem)(constants_1.LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
const authSigOrError = (0, misc_browser_1.getStorageItem)(constants_1.LOCAL_STORAGE_KEYS.AUTH_SIGNATURE);
if (authSigOrError.type === 'ERROR') {
(0, misc_1.throwError)({
message: 'Failed to get authSig from local storage',
errorKind: constants_1.LIT_ERROR.LOCAL_STORAGE_ITEM_NOT_FOUND_EXCEPTION.kind,
errorCode: constants_1.LIT_ERROR.LOCAL_STORAGE_ITEM_NOT_FOUND_EXCEPTION.name,
});
throw new constants_1.LocalStorageItemNotFoundException({
info: {
storageKey: constants_1.LOCAL_STORAGE_KEYS.AUTH_SIGNATURE,
},
}, 'Failed to get authSig from local storage');
}
let authSig = typeof authSigOrError.result === 'string'
const authSig = typeof authSigOrError.result === 'string'
? JSON.parse(authSigOrError.result)

@@ -556,3 +563,3 @@ : authSigOrError.result;

// -- 2. sign the message
let signedResult = await (0, exports.signMessage)({
const signedResult = await (0, exports.signMessage)({
body,

@@ -563,3 +570,3 @@ web3,

// -- 3. prepare auth message
let authSig = {
const authSig = {
sig: signedResult.signature,

@@ -605,3 +612,3 @@ derivedVia: 'web3.eth.personal.sign',

(0, misc_1.log)(`web3: ${web3} OR ${account} not found. Connecting web3..`);
let res = await (0, exports.connectWeb3)({ chainId: 1 });
const res = await (0, exports.connectWeb3)({ chainId: 1 });
web3 = res.web3;

@@ -618,6 +625,10 @@ account = res.account;

if (address.toLowerCase() !== account.toLowerCase()) {
const msg = `ruh roh, the user signed with a different address (${address}) then they\'re using with web3 (${account}). this will lead to confusion.`;
(0, misc_1.log)(msg);
alert('something seems to be wrong with your wallets message signing. maybe restart your browser or your wallet. your recovered sig address does not match your web3 account address');
throw new Error(msg);
const msg = `ruh roh, the user signed with a different address (${address}) then they're using with web3 (${account}). This will lead to confusion.`;
alert('Something seems to be wrong with your wallets message signing. maybe restart your browser or your wallet. Your recovered sig address does not match your web3 account address');
throw new constants_1.InvalidSignatureError({
info: {
address,
account,
},
}, msg);
}

@@ -624,0 +635,0 @@ return { signature, address };

@@ -6,5 +6,5 @@ import { IProvider, AuthSig } from '@lit-protocol/types';

*
* @returns { Promise<IProvider | undefined }
* @returns { Promise<IProvider }
*/
export declare const connectSolProvider: () => Promise<IProvider | undefined>;
export declare const connectSolProvider: () => Promise<IProvider>;
/**

@@ -27,2 +27,2 @@ *

provider: any;
}) => Promise<AuthSig | undefined>;
}) => Promise<AuthSig>;

@@ -25,9 +25,3 @@ "use strict";

else {
// -- finally
const message = 'No web3 wallet was found that works with Solana. Install a Solana wallet or choose another chain';
resultOrError = (0, constants_1.ELeft)({
message,
errorKind: constants_1.LIT_ERROR.NO_WALLET_EXCEPTION.kind,
errorCode: constants_1.LIT_ERROR.NO_WALLET_EXCEPTION.name,
});
resultOrError = (0, constants_1.ELeft)(new constants_1.NoWalletException({}, 'No web3 wallet was found that works with Solana. Install a Solana wallet or choose another chain'));
}

@@ -40,3 +34,3 @@ return resultOrError;

*
* @returns { Promise<IProvider | undefined }
* @returns { Promise<IProvider }
*/

@@ -46,6 +40,9 @@ const connectSolProvider = async () => {

if (providerOrError.type === 'ERROR') {
(0, misc_1.throwError)(providerOrError.result);
return;
throw new constants_1.UnknownError({
info: {
provider: providerOrError.result,
},
}, 'Failed to get provider');
}
let provider = providerOrError.result;
const provider = providerOrError.result;
// No need to reconnect if already connected, some wallets such as Backpack throws an error when doing so.

@@ -74,24 +71,12 @@ if (!provider.isConnected) {

let authSigOrError = (0, misc_browser_1.getStorageItem)(key);
// let authSig = localStorage.getItem("lit-auth-sol-signature");
let authSig;
// -- case: if unable to get auth from local storage
if (authSigOrError.type === "ERROR" /* EITHER_TYPE.ERROR */) {
if (authSigOrError.type === constants_1.EITHER_TYPE.ERROR) {
(0, misc_1.log)('signing auth message because sig is not in local storage');
await (0, exports.signAndSaveAuthMessage)({ provider });
authSigOrError.type = "SUCCESS" /* EITHER_TYPE.SUCCESS */;
// @ts-ignore
authSigOrError.result = (0, misc_browser_1.getStorageItem)(key);
// Refetch authSigOrError written in previous line
authSigOrError = (0, misc_browser_1.getStorageItem)(key);
}
// @ts-ignore
window.test = authSigOrError;
try {
// when it's not in local storage, it's a string
// @ts-ignore
authSig = JSON.parse(authSigOrError.result.result);
}
catch (e) {
// when it's in local storage, it's an object
// @ts-ignore
authSig = JSON.parse(authSigOrError.result);
}
let authSig = JSON.parse(authSigOrError.result);
// -- if the wallet address isn't the same as the address from local storage

@@ -101,6 +86,3 @@ if (account !== authSig.address) {

await (0, exports.signAndSaveAuthMessage)({ provider });
authSigOrError.type = "SUCCESS" /* EITHER_TYPE.SUCCESS */;
// @ts-ignore
authSigOrError.result = (0, misc_browser_1.getStorageItem)(key);
// @ts-ignore
authSigOrError = (0, misc_browser_1.getStorageItem)(key);
authSig = JSON.parse(authSigOrError.result);

@@ -107,0 +89,0 @@ }

@@ -6,2 +6,3 @@ "use strict";

// node_modules/micromodal/dist/micromodal.es.js
const constants_1 = require("@lit-protocol/constants");
function e(e2, t2) {

@@ -448,4 +449,5 @@ for (var o2 = 0; o2 < t2.length; o2++) {

if (filteredListOfWalletsArray.length === 0) {
alert('No wallets installed or provided.');
throw new Error('No wallets installed or provided.');
const message = 'No wallets installed or provided.';
alert(message);
throw new constants_1.NoWalletException({}, message);
}

@@ -452,0 +454,0 @@ this.filteredListOfWalletsArray = filteredListOfWalletsArray;

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet