diff --git a/package-lock.json b/package-lock.json index 7f88c52..402e1a1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4312,9 +4312,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001600", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001600.tgz", - "integrity": "sha512-+2S9/2JFhYmYaDpZvo0lKkfvuKIglrx68MwOBqMGHhQsNkLjB5xtc/TGoEPs+MxjSyN/72qer2g97nzR641mOQ==", + "version": "1.0.30001668", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001668.tgz", + "integrity": "sha512-nWLrdxqCdblixUO+27JtGJJE/txpJlyUy5YN1u53wLZkP0emYCo5zgS6QYft7VUYR42LGgi/S5hdLZTrnyIddw==", "dev": true, "funding": [ { diff --git a/src/account/account.ts b/src/account/account.ts index da5e718..75b8860 100644 --- a/src/account/account.ts +++ b/src/account/account.ts @@ -9,7 +9,7 @@ export class Account { public readonly rpcHelper: RpcHelper constructor( public readonly config: INetworkConfig, - public readonly signer: HDAccount, + public readonly signer?: HDAccount, ) { this.rpcHelper = new RpcHelper(config, signer) } diff --git a/src/connections/index.ts b/src/connections/index.ts index b7107f8..1e6589d 100644 --- a/src/connections/index.ts +++ b/src/connections/index.ts @@ -12,7 +12,7 @@ export class Connections { constructor( public readonly config: INetworkConfig, public rpcHelper: RpcHelper, - public signer: HDAccount, + public signer?: HDAccount, ) {} getTheContract() { diff --git a/src/filesystem-changes/index.ts b/src/filesystem-changes/index.ts index c537e72..a587e3c 100644 --- a/src/filesystem-changes/index.ts +++ b/src/filesystem-changes/index.ts @@ -12,12 +12,12 @@ export class FilesystemChanges { constructor( public readonly config: INetworkConfig, public rpcHelper: RpcHelper, - public signer: HDAccount, + public signer?: HDAccount, ) {} getTheContract() { return getContract({ - address: this.config.filesystemChangesAddress as `0x${string}`, + address: this.config.filesystemChangesAddress, abi: abi as Abi, client: { public: this.rpcHelper.getPublicClient(), @@ -39,7 +39,7 @@ export class FilesystemChanges { }) return (await this.rpcHelper.getAccountClient()).sendTransaction({ - to: this.config.filesystemChangesAddress as `0x${string}`, + to: this.config.filesystemChangesAddress, value: parseEther('0'), data, }) @@ -59,7 +59,7 @@ export class FilesystemChanges { }) return (await this.rpcHelper.getAccountClient()).sendTransaction({ - to: this.config.filesystemChangesAddress as `0x${string}`, + to: this.config.filesystemChangesAddress, value: parseEther('0'), data, }) @@ -79,7 +79,7 @@ export class FilesystemChanges { }) return (await this.rpcHelper.getAccountClient()).sendTransaction({ - to: this.config.filesystemChangesAddress as `0x${string}`, + to: this.config.filesystemChangesAddress, value: parseEther('0'), data, }) diff --git a/src/index.ts b/src/index.ts index d95a255..ab949e3 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,7 +18,7 @@ const ViemUtils = { mnemonicToAccount, generateMnemonic, privateKeyToAccount, en export { Account, Config, Connections, FilesystemChanges, Gateway, Utils, Verification, FarcasterClient, ViemUtils } export class SDK { - public readonly eoaSigner: HDAccount + public readonly eoaSigner?: HDAccount public readonly account: Account public readonly gateway: Gateway public readonly connections: Connections @@ -28,9 +28,12 @@ export class SDK { constructor( public readonly networkConfig: INetworkConfig, - mnemonic: string, + mnemonic?: string, ) { - this.eoaSigner = mnemonicToAccount(mnemonic) + if (mnemonic) { + this.eoaSigner = mnemonicToAccount(mnemonic) + } + this.account = new Account(networkConfig, this.eoaSigner) this.gateway = new Gateway(networkConfig.appAuthUrl, networkConfig.verificationRpcUrl) this.connections = new Connections(networkConfig, this.account.rpcHelper, this.eoaSigner) diff --git a/src/network-config/INetworkConfig.ts b/src/network-config/INetworkConfig.ts index 5eb675f..1b6d821 100644 --- a/src/network-config/INetworkConfig.ts +++ b/src/network-config/INetworkConfig.ts @@ -25,11 +25,11 @@ export interface INetworkConfig { /** * Address of the filesystem changes contract */ - filesystemChangesAddress: string + filesystemChangesAddress: `0x${string}` /** - * Address of the user verification contract + * Address of the user verification contract. Different for different sources and networks */ - userVerificationAddress: string + userVerificationAddress?: string /** * URL of the app auth server */ diff --git a/src/network-config/base-mainnet-config.ts b/src/network-config/base-mainnet-config.ts new file mode 100644 index 0000000..880d016 --- /dev/null +++ b/src/network-config/base-mainnet-config.ts @@ -0,0 +1,26 @@ +import { INetworkConfig } from './INetworkConfig' + +export const baseMainnetConfig: INetworkConfig = { + networkName: 'Base Mainnet', + chainId: 8453, + accountFactoryAddress: '0x00004EC70002a32400f8ae005A26081065620D20', + /** + * https://docs.alchemy.com/reference/eth-supportedentrypoints (v0.6.0) + */ + entryPointAddress: '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789', + /** + * Create2 Address of Social Connections contract + */ + socialConnectionsAddress: '0xB7C1C10A71d3C90f42351bec7E4BCd647C992743', + /** + * Create2 Address of Filesystem Changes contract + */ + filesystemChangesAddress: '0x55043C8f3e8Ec55D2d60Acef83024F3b6da5AAf0', + appAuthUrl: 'https://dappy.in', + rpcUserOperationsUrl: 'https://base-mainnet.g.alchemy.com/v2/ublj-ZfkDCQxMSsTq-SWrGfHrfvGY58d', + userOperationsExplorerUrl: '', + simpleExplorerUrl: 'https://base.blockscout.com', + verificationRpcUrl: 'https://verify.dappykit.org', + farcasterAuthFrameUrl: 'https://farcaster-auth-frame.dappykit.org', + farcasterAuthApiUrl: 'https://farcaster-auth-api.dappykit.org', +} diff --git a/src/network-config/base-sepolia-config.ts b/src/network-config/base-sepolia-config.ts new file mode 100644 index 0000000..7bba3a1 --- /dev/null +++ b/src/network-config/base-sepolia-config.ts @@ -0,0 +1,27 @@ +import { INetworkConfig } from './INetworkConfig' + +export const baseSepoliaConfig: INetworkConfig = { + networkName: 'Base Sepolia', + chainId: 84532, + /** + * The Simple Account offers a more basic implementation for wallet contracts. + * It is straightforward and easy to use, making it suitable for testing purposes. + * We recommend using Light Account in production. + * + * https://docs.alchemy.com/reference/factory-addresses#testnet-deployments + */ + accountFactoryAddress: '0x9406Cc6185a346906296840746125a0E44976454', + /** + * https://docs.alchemy.com/reference/eth-supportedentrypoints + */ + entryPointAddress: '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789', + socialConnectionsAddress: '0xB7C1C10A71d3C90f42351bec7E4BCd647C992743', + filesystemChangesAddress: '0x55043C8f3e8Ec55D2d60Acef83024F3b6da5AAf0', + appAuthUrl: 'https://dappy.in', + rpcUserOperationsUrl: 'https://base-sepolia.g.alchemy.com/v2/ublj-ZfkDCQxMSsTq-SWrGfHrfvGY58d', + userOperationsExplorerUrl: '', + simpleExplorerUrl: 'https://sepolia-explorer.base.org', + verificationRpcUrl: 'https://verify-api-test.dappykit.org', + farcasterAuthApiUrl: '', + farcasterAuthFrameUrl: '', +} diff --git a/src/network-config/fraxtal-holesky-config.ts b/src/network-config/fraxtal-holesky-config.ts new file mode 100644 index 0000000..181f1ee --- /dev/null +++ b/src/network-config/fraxtal-holesky-config.ts @@ -0,0 +1,27 @@ +import { INetworkConfig } from './INetworkConfig' + +export const fraxtalHoleskyConfig: INetworkConfig = { + networkName: 'Fraxtal Holesky', + chainId: 2522, + /** + * The Simple Account offers a more basic implementation for wallet contracts. + * It is straightforward and easy to use, making it suitable for testing purposes. + * We recommend using Light Account in production. + * + * https://docs.alchemy.com/reference/factory-addresses#testnet-deployments + */ + accountFactoryAddress: '0x9406Cc6185a346906296840746125a0E44976454', + /** + * https://docs.alchemy.com/reference/eth-supportedentrypoints + */ + entryPointAddress: '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789', + socialConnectionsAddress: '0xB7C1C10A71d3C90f42351bec7E4BCd647C992743', + filesystemChangesAddress: '0x55043C8f3e8Ec55D2d60Acef83024F3b6da5AAf0', + appAuthUrl: 'https://dappy.in', + rpcUserOperationsUrl: '', + userOperationsExplorerUrl: '', + simpleExplorerUrl: 'https://holesky.fraxscan.com/', + verificationRpcUrl: 'https://verify-api-test.dappykit.org', + farcasterAuthApiUrl: '', + farcasterAuthFrameUrl: '', +} diff --git a/src/network-config/fraxtal-mainnet-config.ts b/src/network-config/fraxtal-mainnet-config.ts new file mode 100644 index 0000000..d03669d --- /dev/null +++ b/src/network-config/fraxtal-mainnet-config.ts @@ -0,0 +1,26 @@ +import { INetworkConfig } from './INetworkConfig' + +export const fraxtalMainnetConfig: INetworkConfig = { + networkName: 'Fraxtal Mainnet', + chainId: 252, + accountFactoryAddress: '0x00004EC70002a32400f8ae005A26081065620D20', + /** + * https://docs.alchemy.com/reference/eth-supportedentrypoints (v0.6.0) + */ + entryPointAddress: '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789', + /** + * Create2 Address of Social Connections contract + */ + socialConnectionsAddress: '0xB7C1C10A71d3C90f42351bec7E4BCd647C992743', + /** + * Create2 Address of Filesystem Changes contract + */ + filesystemChangesAddress: '0x55043C8f3e8Ec55D2d60Acef83024F3b6da5AAf0', + appAuthUrl: 'https://dappy.in', + rpcUserOperationsUrl: '', + userOperationsExplorerUrl: '', + simpleExplorerUrl: 'https://fraxscan.com/', + verificationRpcUrl: 'https://verify.dappykit.org', + farcasterAuthFrameUrl: 'https://farcaster-auth-frame.dappykit.org', + farcasterAuthApiUrl: 'https://farcaster-auth-api.dappykit.org', +} diff --git a/src/network-config/index.ts b/src/network-config/index.ts index e16d299..57c4b5e 100644 --- a/src/network-config/index.ts +++ b/src/network-config/index.ts @@ -1,5 +1,21 @@ import { optimismSepoliaConfig } from './optimism-sepolia-config' import { optimismMainnetConfig } from './optimism-mainnet-config' +import { baseSepoliaConfig } from './base-sepolia-config' +import { baseMainnetConfig } from './base-mainnet-config' +import { modeMainnetConfig } from './mode-mainnet-config' +import { modeSepoliaConfig } from './mode-sepolia-config' +import { fraxtalHoleskyConfig } from './fraxtal-holesky-config' +import { fraxtalMainnetConfig } from './fraxtal-mainnet-config' import { INetworkConfig } from './INetworkConfig' -export { optimismSepoliaConfig, optimismMainnetConfig, INetworkConfig } +export { + optimismSepoliaConfig, + optimismMainnetConfig, + baseSepoliaConfig, + baseMainnetConfig, + modeMainnetConfig, + modeSepoliaConfig, + fraxtalHoleskyConfig, + fraxtalMainnetConfig, + INetworkConfig, +} diff --git a/src/network-config/mode-mainnet-config.ts b/src/network-config/mode-mainnet-config.ts new file mode 100644 index 0000000..820e5d4 --- /dev/null +++ b/src/network-config/mode-mainnet-config.ts @@ -0,0 +1,26 @@ +import { INetworkConfig } from './INetworkConfig' + +export const modeMainnetConfig: INetworkConfig = { + networkName: 'Mode Mainnet', + chainId: 34443, + accountFactoryAddress: '0x00004EC70002a32400f8ae005A26081065620D20', + /** + * https://docs.alchemy.com/reference/eth-supportedentrypoints (v0.6.0) + */ + entryPointAddress: '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789', + /** + * Create2 Address of Social Connections contract + */ + socialConnectionsAddress: '0xB7C1C10A71d3C90f42351bec7E4BCd647C992743', + /** + * Create2 Address of Filesystem Changes contract + */ + filesystemChangesAddress: '0x55043C8f3e8Ec55D2d60Acef83024F3b6da5AAf0', + appAuthUrl: 'https://dappy.in', + rpcUserOperationsUrl: '', + userOperationsExplorerUrl: '', + simpleExplorerUrl: 'https://explorer.mode.network', + verificationRpcUrl: 'https://verify.dappykit.org', + farcasterAuthFrameUrl: 'https://farcaster-auth-frame.dappykit.org', + farcasterAuthApiUrl: 'https://farcaster-auth-api.dappykit.org', +} diff --git a/src/network-config/mode-sepolia-config.ts b/src/network-config/mode-sepolia-config.ts new file mode 100644 index 0000000..e85d394 --- /dev/null +++ b/src/network-config/mode-sepolia-config.ts @@ -0,0 +1,27 @@ +import { INetworkConfig } from './INetworkConfig' + +export const modeSepoliaConfig: INetworkConfig = { + networkName: 'Mode Sepolia', + chainId: 919, + /** + * The Simple Account offers a more basic implementation for wallet contracts. + * It is straightforward and easy to use, making it suitable for testing purposes. + * We recommend using Light Account in production. + * + * https://docs.alchemy.com/reference/factory-addresses#testnet-deployments + */ + accountFactoryAddress: '0x9406Cc6185a346906296840746125a0E44976454', + /** + * https://docs.alchemy.com/reference/eth-supportedentrypoints + */ + entryPointAddress: '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789', + socialConnectionsAddress: '0xB7C1C10A71d3C90f42351bec7E4BCd647C992743', + filesystemChangesAddress: '0x55043C8f3e8Ec55D2d60Acef83024F3b6da5AAf0', + appAuthUrl: 'https://dappy.in', + rpcUserOperationsUrl: '', + userOperationsExplorerUrl: '', + simpleExplorerUrl: 'https://sepolia.explorer.mode.network/', + verificationRpcUrl: 'https://verify-api-test.dappykit.org', + farcasterAuthApiUrl: '', + farcasterAuthFrameUrl: '', +} diff --git a/src/network-config/optimism-mainnet-config.ts b/src/network-config/optimism-mainnet-config.ts index 0081d14..e277e17 100644 --- a/src/network-config/optimism-mainnet-config.ts +++ b/src/network-config/optimism-mainnet-config.ts @@ -21,9 +21,14 @@ export const optimismMainnetConfig: INetworkConfig = { * https://docs.alchemy.com/reference/eth-supportedentrypoints (v0.6.0) */ entryPointAddress: '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789', - socialConnectionsAddress: '0xD8FC858221428B6b8ce304CE7aF1E838067Ea806', - filesystemChangesAddress: '0x204B8968E70084cDCBad327614334F1D7553aaF2', - userVerificationAddress: '0xBA44aaa2809931401ec099D798A5376cd678a12a', + /** + * Create2 Address of Social Connections contract + */ + socialConnectionsAddress: '0xB7C1C10A71d3C90f42351bec7E4BCd647C992743', + /** + * Create2 Address of Filesystem Changes contract + */ + filesystemChangesAddress: '0x55043C8f3e8Ec55D2d60Acef83024F3b6da5AAf0', appAuthUrl: 'https://dappy.in', rpcUserOperationsUrl: 'https://opt-mainnet.g.alchemy.com/v2/ublj-ZfkDCQxMSsTq-SWrGfHrfvGY58d', userOperationsExplorerUrl: '', diff --git a/src/network-config/optimism-sepolia-config.ts b/src/network-config/optimism-sepolia-config.ts index 0f0511f..9995288 100644 --- a/src/network-config/optimism-sepolia-config.ts +++ b/src/network-config/optimism-sepolia-config.ts @@ -18,9 +18,8 @@ export const optimismSepoliaConfig: INetworkConfig = { * https://docs.alchemy.com/reference/eth-supportedentrypoints */ entryPointAddress: '0x5ff137d4b0fdcd49dca30c7cf57e578a026d2789', - socialConnectionsAddress: '0xD8FC858221428B6b8ce304CE7aF1E838067Ea806', - filesystemChangesAddress: '0x204B8968E70084cDCBad327614334F1D7553aaF2', - userVerificationAddress: '0xBA44aaa2809931401ec099D798A5376cd678a12a', + socialConnectionsAddress: '0xB7C1C10A71d3C90f42351bec7E4BCd647C992743', + filesystemChangesAddress: '0x55043C8f3e8Ec55D2d60Acef83024F3b6da5AAf0', appAuthUrl: 'https://dappy.in', rpcUserOperationsUrl: 'https://opt-sepolia.g.alchemy.com/v2/vzozB27YgXBN9bXvQh5_AeyWVjDmfqGF', userOperationsExplorerUrl: '', diff --git a/src/rpc-helper/index.ts b/src/rpc-helper/index.ts index 1445c27..cdbc9de 100644 --- a/src/rpc-helper/index.ts +++ b/src/rpc-helper/index.ts @@ -5,6 +5,7 @@ import { LightSmartAccount, signerToLightSmartAccount } from 'permissionless/acc import { createSmartAccountClient, ENTRYPOINT_ADDRESS_V06, SmartAccountClient } from 'permissionless' import { ENTRYPOINT_ADDRESS_V06_TYPE } from 'permissionless/types' import { getChain } from '../utils/chain' +import { assertNotEmptySigner } from '../connections/utils' export type LightSmartAccountType = LightSmartAccount @@ -17,7 +18,7 @@ export class RpcHelper { constructor( public readonly config: INetworkConfig, - public readonly eoaSigner: HDAccount, + public readonly eoaSigner?: HDAccount, ) {} /** @@ -34,6 +35,8 @@ export class RpcHelper { * Get smart account instance. With ability to sign transactions. */ async getAccount(): Promise { + assertNotEmptySigner(this.eoaSigner) + if (!this.account) { this.account = await signerToLightSmartAccount(this.getPublicClient(), { signer: this.eoaSigner, diff --git a/test/manual/defaultScenario.js b/test/manual/defaultScenario.js index 4c6ac04..5dc10d4 100644 --- a/test/manual/defaultScenario.js +++ b/test/manual/defaultScenario.js @@ -1,20 +1,20 @@ const { generateMnemonic, english } = window.DappyKit.ViemUtils -const mnemonic = generateMnemonic(english) const optimismMainnetConfig = window.DappyKit.Config.optimismMainnetConfig -const optimismSepoliaConfig = window.DappyKit.Config.optimismSepoliaConfig +const optimismSepoliaConfig = { + ...window.DappyKit.Config.optimismSepoliaConfig, + socialConnectionsAddress: '0xD8FC858221428B6b8ce304CE7aF1E838067Ea806', + filesystemChangesAddress: '0x204B8968E70084cDCBad327614334F1D7553aaF2', +} // example how to create SDK instance with mnemonic -const sdkTestnet = new window.DappyKit.SDK(optimismSepoliaConfig, mnemonic) +const sdkTestnet = new window.DappyKit.SDK(optimismSepoliaConfig) // example how to create SDK instance with mnemonic -const sdkMainnet = new window.DappyKit.SDK(optimismMainnetConfig, mnemonic) +const sdkMainnet = new window.DappyKit.SDK(optimismMainnetConfig) async function defaultScenario() { const verificationContractAddress = '0x721462E34DCC00F8Bd0f0cD07762cfd482a0Fcb4' - // eslint-disable-next-line no-console - console.log('Smart Account address', await sdkTestnet.account.getAddress()) - // eslint-disable-next-line no-console console.log( 'user connection multihash', diff --git a/test/optimism-sepolia/verification.test.ts b/test/optimism-sepolia/verification.test.ts index c7106f8..615ef8e 100644 --- a/test/optimism-sepolia/verification.test.ts +++ b/test/optimism-sepolia/verification.test.ts @@ -27,6 +27,8 @@ describe('Optimism Sepolia Verification', () => { }) it(`should check if the token is expired`, async () => { + // to prolong the token, go to https://sepolia-optimism.etherscan.io/address/0x721462E34DCC00F8Bd0f0cD07762cfd482a0Fcb4#writeContract + // with 0xaE70aEb668D3f6De045765657999957388CDF025, call "extendTokenExpiry" with the tokenId received using "getTokenId" const sdk = await createSdk(optimismSepoliaConfig, Wallet.createRandom()) const tokenId = await sdk.verification.getTokenId(verifiedAddress, verificationContractAddress) expect(await sdk.verification.isTokenExpired(tokenId, verificationContractAddress)).toEqual(false)