diff --git a/.env.example b/.env.example index 299ce21..b05f4c8 100644 --- a/.env.example +++ b/.env.example @@ -1,46 +1,46 @@ # EVM CHAINS -RPC_URL='https://sepolia.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161' -WS_URL='wss://sepolia.infura.io/ws/v3/9aa3d95b3bc440fa88ea12eaa4456161' +EVM_RPC_URL='https://sepolia.infura.io/v3/9aa3d95b3bc440fa88ea12eaa4456161' +EVM_WS_URL='wss://sepolia.infura.io/ws/v3/9aa3d95b3bc440fa88ea12eaa4456161' # Assets -COIN_TRANSFER_TEST_IS_ACTIVE=false -TOKEN_TRANSFER_TEST_IS_ACTIVE=false -TOKEN_APPROVE_TEST_IS_ACTIVE=false -TOKEN_TRANSFER_FROM_TEST_IS_ACTIVE=false -NFT_TRANSACTION_TEST_IS_ACTIVE=false -TRANSACTION_LISTENER_TEST_IS_ACTIVE=false +EVM_COIN_TRANSFER_TEST_IS_ACTIVE=false +EVM_TOKEN_TRANSFER_TEST_IS_ACTIVE=false +EVM_TOKEN_APPROVE_TEST_IS_ACTIVE=false +EVM_TOKEN_TRANSFER_FROM_TEST_IS_ACTIVE=false +EVM_NFT_TRANSACTION_TEST_IS_ACTIVE=false +EVM_TRANSACTION_LISTENER_TEST_IS_ACTIVE=false -COIN_BALANCE_TEST_AMOUNT=0.01 -TOKEN_BALANCE_TEST_AMOUNT=1000 -NFT_BALANCE_TEST_AMOUNT=2 -TRANSFER_TEST_AMOUNT=0.0001 -TOKEN_TRANSFER_TEST_AMOUNT=1 -TOKEN_APPROVE_TEST_AMOUNT=100 -NFT_TRANSFER_ID=7 +EVM_COIN_BALANCE_TEST_AMOUNT=0.01 +EVM_TOKEN_BALANCE_TEST_AMOUNT=1000 +EVM_NFT_BALANCE_TEST_AMOUNT=2 +EVM_TRANSFER_TEST_AMOUNT=0.0001 +EVM_TOKEN_TRANSFER_TEST_AMOUNT=1 +EVM_TOKEN_APPROVE_TEST_AMOUNT=100 +EVM_NFT_TRANSFER_ID=7 -BALANCE_TEST_ADDRESS='0x760A4d3D03928D1e8541A7644B34370c1b79aa9F' -SENDER_PRIVATE_KEY='0x14bd9af4e87981b37b7b2e8a0d1d249b7fcdb7a3bc579c4c31488842d372c0e9' -RECEIVER_PRIVATE_KEY='0x22ac1009c43f251e0b5a808751990abe77a74fe12f390c0cc95ab179a0b61a5a' -SENDER_TEST_ADDRESS='0x110600bF0399174520a159ed425f0D272Ff8b459' -RECEIVER_TEST_ADDRESS='0xbBa4d06D1cEf94b35aDeCfDa893523907fdD36DE' -TOKEN_TEST_ADDRESS='0x4294cb0dD25dC9140B5127f247cBd47Eeb673431' -NFT_TEST_ADDRESS='0x06B8B36e4feD2206E980445C0f0829fc6B2aA91F' +EVM_BALANCE_TEST_ADDRESS='0x760A4d3D03928D1e8541A7644B34370c1b79aa9F' +EVM_SENDER_PRIVATE_KEY='0x14bd9af4e87981b37b7b2e8a0d1d249b7fcdb7a3bc579c4c31488842d372c0e9' +EVM_RECEIVER_PRIVATE_KEY='0x22ac1009c43f251e0b5a808751990abe77a74fe12f390c0cc95ab179a0b61a5a' +EVM_SENDER_TEST_ADDRESS='0x110600bF0399174520a159ed425f0D272Ff8b459' +EVM_RECEIVER_TEST_ADDRESS='0xbBa4d06D1cEf94b35aDeCfDa893523907fdD36DE' +EVM_TOKEN_TEST_ADDRESS='0x4294cb0dD25dC9140B5127f247cBd47Eeb673431' +EVM_NFT_TEST_ADDRESS='0x06B8B36e4feD2206E980445C0f0829fc6B2aA91F' # Assets # Models -NFT_ID=7 -TOKEN_AMOUNT=1 -COIN_AMOUNT=0.002548 +EVM_NFT_ID=7 +EVM_TOKEN_AMOUNT=1 +EVM_COIN_AMOUNT=0.002548 -COIN_SENDER='0x74dBE9cA4F93087A27f23164d4367b8ce66C33e2' -COIN_RECEIVER='0xb3c86232c163a988ce4358b10a2745864bfaa3ba' -TOKEN_SENDER='0x110600bF0399174520a159ed425f0D272Ff8b459' -TOKEN_RECEIVER='0xbBa4d06D1cEf94b35aDeCfDa893523907fdD36DE' -NFT_SENDER='0xbBa4d06D1cEf94b35aDeCfDa893523907fdD36DE' -NFT_RECEIVER='0x110600bF0399174520a159ed425f0D272Ff8b459' +EVM_COIN_SENDER='0x74dBE9cA4F93087A27f23164d4367b8ce66C33e2' +EVM_COIN_RECEIVER='0xb3c86232c163a988ce4358b10a2745864bfaa3ba' +EVM_TOKEN_SENDER='0x110600bF0399174520a159ed425f0D272Ff8b459' +EVM_TOKEN_RECEIVER='0xbBa4d06D1cEf94b35aDeCfDa893523907fdD36DE' +EVM_NFT_SENDER='0xbBa4d06D1cEf94b35aDeCfDa893523907fdD36DE' +EVM_NFT_RECEIVER='0x110600bF0399174520a159ed425f0D272Ff8b459' -ETHER_TRANSFER_TX='0x566002399664e92f82ed654c181095bdd7ff3d3f1921d963257585891f622251' -TOKEN_TRANSFER_TX='0xdabda3905e585db91768f2ef877f7fbef7c0e8612c0a09c7b379981bdbc48975' -NFT_TRANSFER_TX='0x272a4698cd2062f2463481cf9eb78b68b35d59938383679b7642e6d669ac87eb' +EVM_ETHER_TRANSFER_TX='0x566002399664e92f82ed654c181095bdd7ff3d3f1921d963257585891f622251' +EVM_TOKEN_TRANSFER_TX='0xdabda3905e585db91768f2ef877f7fbef7c0e8612c0a09c7b379981bdbc48975' +EVM_NFT_TRANSFER_TX='0x272a4698cd2062f2463481cf9eb78b68b35d59938383679b7642e6d669ac87eb' # Models # EVM CHAINS \ No newline at end of file diff --git a/.gitignore b/.gitignore index 09d282a..d3bc6a7 100644 --- a/.gitignore +++ b/.gitignore @@ -12,7 +12,6 @@ node_modules dist dist-ssr *.local -index.html test*.ts test*.js test*.cjs diff --git a/packages/networks/boilerplate/index.html b/packages/networks/boilerplate/index.html new file mode 100644 index 0000000..7704205 --- /dev/null +++ b/packages/networks/boilerplate/index.html @@ -0,0 +1,340 @@ + + + + + + + Browser Tests + + + + +
+ +
+ +
+
+ Adapter id: +
+
+ Adapter name: +
+
+ Adapter icon: icon +
+
+ Platforms: +
+
+ Download link: +
+
+ Deep link: +
+
+ Chain id: +
+
+ Connected address: +
+ +
+ Result: +
+ +
+ Result: +
+ +
+ Result: +
+
+ + + + \ No newline at end of file diff --git a/packages/networks/boilerplate/package.json b/packages/networks/boilerplate/package.json index 7a27d29..87146fa 100644 --- a/packages/networks/boilerplate/package.json +++ b/packages/networks/boilerplate/package.json @@ -11,7 +11,8 @@ "exports": { ".": { "import": "./dist/index.es.js", - "require": "./dist/index.cjs" + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" } }, "files": [ @@ -47,7 +48,7 @@ "url": "https://github.com/MultipleChain/js/issues" }, "dependencies": { - "@multiplechain/types": "^0.1.35", - "@multiplechain/utils": "^0.1.16" + "@multiplechain/types": "^0.1.53", + "@multiplechain/utils": "^0.1.18" } } \ No newline at end of file diff --git a/packages/networks/boilerplate/pnpm-lock.yaml b/packages/networks/boilerplate/pnpm-lock.yaml index a13694b..ff48dd3 100644 --- a/packages/networks/boilerplate/pnpm-lock.yaml +++ b/packages/networks/boilerplate/pnpm-lock.yaml @@ -6,23 +6,28 @@ settings: dependencies: '@multiplechain/types': - specifier: ^0.1.30 - version: 0.1.30 + specifier: ^0.1.53 + version: 0.1.53 '@multiplechain/utils': - specifier: ^0.1.10 - version: 0.1.10 + specifier: ^0.1.18 + version: 0.1.18 packages: - /@multiplechain/types@0.1.30: - resolution: {integrity: sha512-j72Ydn1FlEWF4lY6xUjI0ojf0y1JAjqYnddAaUUdzv5sRlFw2zze8VLqxzltFtjFigPbSUa7QHmbgTIXQ60HoQ==} + /@multiplechain/types@0.1.53: + resolution: {integrity: sha512-brF6CtNDUwTChwZBy0pTEvf4QdwAK3sL2kvVXE9rARAroK8qUU4Skn5NAHpr2W1ubmuhDezgHDS4XhEdr8BsgA==} dev: false - /@multiplechain/utils@0.1.10: - resolution: {integrity: sha512-Ed0YxvRakds1WiREcLWI+fr6YCNB3bSORPD/ZQNqhELtL5uVgYWunIwbx6yZmLNk4MY8Qqyh0iUjuCOBLplmiA==} + /@multiplechain/utils@0.1.18: + resolution: {integrity: sha512-UCoOOBJrawp/lInepxuoEiYwId0wMPg7rX8p78FLqzGl8f/b93sAtv7sP87/VVKwhdoEuNZ/uQjckycmNeks/w==} dependencies: + '@types/ws': 8.5.10 bignumber.js: 9.1.2 web3-utils: 4.2.1 + ws: 8.16.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate dev: false /@noble/curves@1.3.0: @@ -55,6 +60,18 @@ packages: '@scure/base': 1.1.6 dev: false + /@types/node@20.12.7: + resolution: {integrity: sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==} + dependencies: + undici-types: 5.26.5 + dev: false + + /@types/ws@8.5.10: + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + dependencies: + '@types/node': 20.12.7 + dev: false + /available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} @@ -216,6 +233,10 @@ packages: has-property-descriptors: 1.0.2 dev: false + /undici-types@5.26.5: + resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==} + dev: false + /util@0.12.5: resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} dependencies: @@ -271,6 +292,19 @@ packages: has-tostringtag: 1.0.2 dev: false + /ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false diff --git a/packages/networks/boilerplate/src/browser/Wallet.ts b/packages/networks/boilerplate/src/browser/Wallet.ts new file mode 100644 index 0000000..bda683c --- /dev/null +++ b/packages/networks/boilerplate/src/browser/Wallet.ts @@ -0,0 +1,115 @@ +import type { + WalletInterface, + WalletAdapterInterface, + WalletPlatformEnum, + TransactionSignerInterface +} from '@multiplechain/types' + +export class Wallet implements WalletInterface { + adapter: WalletAdapterInterface + + /** + * @param {WalletAdapterInterface} adapter + */ + constructor(adapter: WalletAdapterInterface) { + this.adapter = adapter + } + + /** + * @returns {string} + */ + getId(): string { + return this.adapter.id + } + + /** + * @returns {string} + */ + getName(): string { + return this.adapter.name + } + + /** + * @returns {string} + */ + getIcon(): string { + return this.adapter.name + } + + /** + * @returns {WalletPlatformEnum[]} + */ + getPlatforms(): WalletPlatformEnum[] { + return this.adapter.platforms + } + + /** + * @returns {string} + */ + getDownloadLink(): string { + return this.adapter.downloadLink + } + + /** + * @param {string} url + * @param {object} ops + * @returns {string} + */ + createDeepLink(url: string, ops?: object): string { + return this.adapter.createDeepLink(url, ops) + } + + /** + * connect to adapter + * @returns {Promise} + */ + async connect(): Promise { + await this.adapter.connect() + return 'wallet address' + } + + /** + * @returns {boolean} + */ + isDetected(): boolean { + return this.adapter.isDetected() + } + + /** + * @returns {boolean} + */ + isConnected(): boolean { + return this.adapter.isConnected() + } + + /** + * @returns {Promise} + */ + async getAddress(): Promise { + return 'wallet address' + } + + /** + * @param {string} message + */ + async signMessage(message: string): Promise { + return 'signed message' + } + + /** + * @param {TransactionSignerInterface} transactionSigner + * @returns {Promise} + */ + async sendTransaction(transactionSigner: TransactionSignerInterface): Promise { + return 'transaction hash' + } + + /** + * @param {string} eventName + * @param {Function} callback + * @returns {void} + */ + on(eventName: string, callback: (...args: any[]) => void): void { + 'wallet events' + } +} diff --git a/packages/networks/boilerplate/src/browser/adapters/Example.ts b/packages/networks/boilerplate/src/browser/adapters/Example.ts new file mode 100644 index 0000000..79ecd67 --- /dev/null +++ b/packages/networks/boilerplate/src/browser/adapters/Example.ts @@ -0,0 +1,29 @@ +import { WalletPlatformEnum } from '@multiplechain/types' +import type { WalletAdapterInterface } from '@multiplechain/types' + +declare global { + interface Window { + example: any + } +} + +const Example: WalletAdapterInterface = { + id: 'example', + name: 'Example', + icon: 'icon base64 string here', + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + downloadLink: 'wallet download link here', + createDeepLink(url: string, ops?: object): string { + return `https://example.com/dapp/${url}` + }, + isDetected: () => Boolean(window?.example), + isConnected: async () => { + return true // return true if connected + }, + connect: async () => { + // connect wallet here + return window.example + } +} + +export default Example diff --git a/packages/networks/boilerplate/src/browser/adapters/index.ts b/packages/networks/boilerplate/src/browser/adapters/index.ts new file mode 100644 index 0000000..de0149d --- /dev/null +++ b/packages/networks/boilerplate/src/browser/adapters/index.ts @@ -0,0 +1 @@ +export { default as Example } from './Example.ts' diff --git a/packages/networks/boilerplate/src/browser/index.ts b/packages/networks/boilerplate/src/browser/index.ts new file mode 100644 index 0000000..16137ee --- /dev/null +++ b/packages/networks/boilerplate/src/browser/index.ts @@ -0,0 +1,28 @@ +import { Wallet } from './Wallet.ts' +import * as adapterList from './adapters/index.ts' +import type { + WalletAdapterListType, + WalletAdapterInterface, + RegisterWalletAdapterType +} from '@multiplechain/types' + + +const adapters: WalletAdapterListType = { + ...adapterList +} + +const registerAdapter: RegisterWalletAdapterType = (adapter: WalletAdapterInterface): void => { + if (Object.values(adapters).find((a) => a.id === adapter.id) !== undefined) { + throw new Error(`Adapter with id ${adapter.id} already exists`) + } + + adapters[adapter.id] = adapter +} + +export * from '../index.ts' + +export const browser = { + Wallet, + adapters, + registerAdapter +} diff --git a/packages/networks/boilerplate/vite.svg b/packages/networks/boilerplate/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/packages/networks/boilerplate/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/networks/evm-chains/index.html b/packages/networks/evm-chains/index.html new file mode 100644 index 0000000..a47fdee --- /dev/null +++ b/packages/networks/evm-chains/index.html @@ -0,0 +1,359 @@ + + + + + + + Browser Tests + + + + +
+
    +
+
+ +
+
+ Adapter id: +
+
+ Adapter name: +
+
+ Adapter icon: icon +
+
+ Platforms: +
+
+ Download link: +
+
+ Deep link: +
+
+ Chain id: +
+
+ Connected address: +
+ +
+ Result: +
+ +
+ Result: +
+ +
+ Result: +
+
+ + + + \ No newline at end of file diff --git a/packages/networks/evm-chains/package.json b/packages/networks/evm-chains/package.json index fd6be2e..ce369c5 100644 --- a/packages/networks/evm-chains/package.json +++ b/packages/networks/evm-chains/package.json @@ -11,7 +11,8 @@ "exports": { ".": { "import": "./dist/index.es.js", - "require": "./dist/index.cjs" + "require": "./dist/index.cjs", + "types": "./dist/index.d.ts" } }, "files": [ @@ -20,6 +21,7 @@ "!tsconfig.tsbuildinfo" ], "scripts": { + "dev": "vite", "clean": "rm -rf dist", "watch": "tsc --watch", "build:vite": "vite build", @@ -50,9 +52,11 @@ "url": "https://github.com/MultipleChain/js/issues" }, "dependencies": { - "@multiplechain/types": "^0.1.35", - "@multiplechain/utils": "^0.1.16", + "@multiplechain/types": "^0.1.53", + "@multiplechain/utils": "^0.1.18", "@wagmi/chains": "^1.8.0", + "@walletconnect/ethereum-provider": "^2.12.2", + "@walletconnect/modal": "^2.6.2", "ethers": "^6.11.1" } } \ No newline at end of file diff --git a/packages/networks/evm-chains/pnpm-lock.yaml b/packages/networks/evm-chains/pnpm-lock.yaml index 63086cb..36b2436 100644 --- a/packages/networks/evm-chains/pnpm-lock.yaml +++ b/packages/networks/evm-chains/pnpm-lock.yaml @@ -6,14 +6,20 @@ settings: dependencies: '@multiplechain/types': - specifier: ^0.1.35 - version: 0.1.35 + specifier: ^0.1.53 + version: 0.1.53 '@multiplechain/utils': - specifier: ^0.1.16 - version: 0.1.16 + specifier: ^0.1.18 + version: 0.1.18 '@wagmi/chains': specifier: ^1.8.0 version: 1.8.0 + '@walletconnect/ethereum-provider': + specifier: ^2.12.2 + version: 2.12.2(react@18.2.0) + '@walletconnect/modal': + specifier: ^2.6.2 + version: 2.6.2(react@18.2.0) ethers: specifier: ^6.11.1 version: 6.11.1 @@ -24,12 +30,84 @@ packages: resolution: {integrity: sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw==} dev: false - /@multiplechain/types@0.1.35: - resolution: {integrity: sha512-szg+arayBvT3WivUa9l6ZYjS6tNjhFMDpQCcAUL94s5yWpDM73OnHMA861XVVVY0xIUgJpzCj32PlJU+CARYow==} + /@lit-labs/ssr-dom-shim@1.2.0: + resolution: {integrity: sha512-yWJKmpGE6lUURKAaIltoPIE/wrbY3TEkqQt+X0m+7fQNnAv0keydnYvbiJFP1PnMhizmIWRWOG5KLhYyc/xl+g==} dev: false - /@multiplechain/utils@0.1.16: - resolution: {integrity: sha512-wJPLuHRt2r8DZt0S6YkeRZRRcy/bc20/Y0xolESOIWfLdBy/N5YKBMJaAwEV+pOWuP77Mx+rzZBlfeOBmvZBXw==} + /@lit/reactive-element@1.6.3: + resolution: {integrity: sha512-QuTgnG52Poic7uM1AN5yJ09QMe0O28e10XzSvWDz02TJiiKee4stsiownEIadWm8nYzyDAyT+gKzUoZmiWQtsQ==} + dependencies: + '@lit-labs/ssr-dom-shim': 1.2.0 + dev: false + + /@motionone/animation@10.17.0: + resolution: {integrity: sha512-ANfIN9+iq1kGgsZxs+Nz96uiNcPLGTXwfNo2Xz/fcJXniPYpaz/Uyrfa+7I5BPLxCP82sh7quVDudf1GABqHbg==} + dependencies: + '@motionone/easing': 10.17.0 + '@motionone/types': 10.17.0 + '@motionone/utils': 10.17.0 + tslib: 2.4.0 + dev: false + + /@motionone/dom@10.17.0: + resolution: {integrity: sha512-cMm33swRlCX/qOPHWGbIlCl0K9Uwi6X5RiL8Ma6OrlJ/TP7Q+Np5GE4xcZkFptysFjMTi4zcZzpnNQGQ5D6M0Q==} + dependencies: + '@motionone/animation': 10.17.0 + '@motionone/generators': 10.17.0 + '@motionone/types': 10.17.0 + '@motionone/utils': 10.17.0 + hey-listen: 1.0.8 + tslib: 2.4.0 + dev: false + + /@motionone/easing@10.17.0: + resolution: {integrity: sha512-Bxe2wSuLu/qxqW4rBFS5m9tMLOw+QBh8v5A7Z5k4Ul4sTj5jAOfZG5R0bn5ywmk+Fs92Ij1feZ5pmC4TeXA8Tg==} + dependencies: + '@motionone/utils': 10.17.0 + tslib: 2.4.0 + dev: false + + /@motionone/generators@10.17.0: + resolution: {integrity: sha512-T6Uo5bDHrZWhIfxG/2Aut7qyWQyJIWehk6OB4qNvr/jwA/SRmixwbd7SOrxZi1z5rH3LIeFFBKK1xHnSbGPZSQ==} + dependencies: + '@motionone/types': 10.17.0 + '@motionone/utils': 10.17.0 + tslib: 2.4.0 + dev: false + + /@motionone/svelte@10.16.4: + resolution: {integrity: sha512-zRVqk20lD1xqe+yEDZhMYgftsuHc25+9JSo+r0a0OWUJFocjSV9D/+UGhX4xgJsuwB9acPzXLr20w40VnY2PQA==} + dependencies: + '@motionone/dom': 10.17.0 + tslib: 2.4.0 + dev: false + + /@motionone/types@10.17.0: + resolution: {integrity: sha512-EgeeqOZVdRUTEHq95Z3t8Rsirc7chN5xFAPMYFobx8TPubkEfRSm5xihmMUkbaR2ErKJTUw3347QDPTHIW12IA==} + dev: false + + /@motionone/utils@10.17.0: + resolution: {integrity: sha512-bGwrki4896apMWIj9yp5rAS2m0xyhxblg6gTB/leWDPt+pb410W8lYWsxyurX+DH+gO1zsQsfx2su/c1/LtTpg==} + dependencies: + '@motionone/types': 10.17.0 + hey-listen: 1.0.8 + tslib: 2.4.0 + dev: false + + /@motionone/vue@10.16.4: + resolution: {integrity: sha512-z10PF9JV6SbjFq+/rYabM+8CVlMokgl8RFGvieSGNTmrkQanfHn+15XBrhG3BgUfvmTeSeyShfOHpG0i9zEdcg==} + deprecated: Motion One for Vue is deprecated. Use Oku Motion instead https://oku-ui.com/motion + dependencies: + '@motionone/dom': 10.17.0 + tslib: 2.4.0 + dev: false + + /@multiplechain/types@0.1.53: + resolution: {integrity: sha512-brF6CtNDUwTChwZBy0pTEvf4QdwAK3sL2kvVXE9rARAroK8qUU4Skn5NAHpr2W1ubmuhDezgHDS4XhEdr8BsgA==} + dev: false + + /@multiplechain/utils@0.1.18: + resolution: {integrity: sha512-UCoOOBJrawp/lInepxuoEiYwId0wMPg7rX8p78FLqzGl8f/b93sAtv7sP87/VVKwhdoEuNZ/uQjckycmNeks/w==} dependencies: '@types/ws': 8.5.10 bignumber.js: 9.1.2 @@ -40,249 +118,1852 @@ packages: - utf-8-validate dev: false - /@noble/curves@1.2.0: - resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + /@noble/curves@1.2.0: + resolution: {integrity: sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw==} + dependencies: + '@noble/hashes': 1.3.2 + dev: false + + /@noble/curves@1.3.0: + resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + dependencies: + '@noble/hashes': 1.3.3 + dev: false + + /@noble/hashes@1.3.2: + resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} + engines: {node: '>= 16'} + dev: false + + /@noble/hashes@1.3.3: + resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} + engines: {node: '>= 16'} + dev: false + + /@parcel/watcher-android-arm64@2.4.1: + resolution: {integrity: sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [android] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-darwin-arm64@2.4.1: + resolution: {integrity: sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-darwin-x64@2.4.1: + resolution: {integrity: sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-freebsd-x64@2.4.1: + resolution: {integrity: sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [freebsd] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm-glibc@2.4.1: + resolution: {integrity: sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==} + engines: {node: '>= 10.0.0'} + cpu: [arm] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm64-glibc@2.4.1: + resolution: {integrity: sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-arm64-musl@2.4.1: + resolution: {integrity: sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-x64-glibc@2.4.1: + resolution: {integrity: sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-linux-x64-musl@2.4.1: + resolution: {integrity: sha512-L2nZTYR1myLNST0O632g0Dx9LyMNHrn6TOt76sYxWLdff3cB22/GZX2UPtJnaqQPdCRoszoY5rcOj4oMTtp5fQ==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [linux] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-wasm@2.4.1: + resolution: {integrity: sha512-/ZR0RxqxU/xxDGzbzosMjh4W6NdYFMqq2nvo2b8SLi7rsl/4jkL8S5stIikorNkdR50oVDvqb/3JT05WM+CRRA==} + engines: {node: '>= 10.0.0'} + dependencies: + is-glob: 4.0.3 + micromatch: 4.0.5 + napi-wasm: 1.1.0 + dev: false + bundledDependencies: + - napi-wasm + + /@parcel/watcher-win32-arm64@2.4.1: + resolution: {integrity: sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==} + engines: {node: '>= 10.0.0'} + cpu: [arm64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-win32-ia32@2.4.1: + resolution: {integrity: sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==} + engines: {node: '>= 10.0.0'} + cpu: [ia32] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher-win32-x64@2.4.1: + resolution: {integrity: sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==} + engines: {node: '>= 10.0.0'} + cpu: [x64] + os: [win32] + requiresBuild: true + dev: false + optional: true + + /@parcel/watcher@2.4.1: + resolution: {integrity: sha512-HNjmfLQEVRZmHRET336f20H/8kOozUGwk7yajvsonjNxbj2wBTK1WsQuHkD5yYh9RxFGL2EyDHryOihOwUoKDA==} + engines: {node: '>= 10.0.0'} + dependencies: + detect-libc: 1.0.3 + is-glob: 4.0.3 + micromatch: 4.0.5 + node-addon-api: 7.1.0 + optionalDependencies: + '@parcel/watcher-android-arm64': 2.4.1 + '@parcel/watcher-darwin-arm64': 2.4.1 + '@parcel/watcher-darwin-x64': 2.4.1 + '@parcel/watcher-freebsd-x64': 2.4.1 + '@parcel/watcher-linux-arm-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-glibc': 2.4.1 + '@parcel/watcher-linux-arm64-musl': 2.4.1 + '@parcel/watcher-linux-x64-glibc': 2.4.1 + '@parcel/watcher-linux-x64-musl': 2.4.1 + '@parcel/watcher-win32-arm64': 2.4.1 + '@parcel/watcher-win32-ia32': 2.4.1 + '@parcel/watcher-win32-x64': 2.4.1 + dev: false + + /@scure/base@1.1.5: + resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} + dev: false + + /@scure/bip32@1.3.3: + resolution: {integrity: sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==} + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.5 + dev: false + + /@scure/bip39@1.2.2: + resolution: {integrity: sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==} + dependencies: + '@noble/hashes': 1.3.3 + '@scure/base': 1.1.5 + dev: false + + /@stablelib/aead@1.0.1: + resolution: {integrity: sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg==} + dev: false + + /@stablelib/binary@1.0.1: + resolution: {integrity: sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q==} + dependencies: + '@stablelib/int': 1.0.1 + dev: false + + /@stablelib/bytes@1.0.1: + resolution: {integrity: sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ==} + dev: false + + /@stablelib/chacha20poly1305@1.0.1: + resolution: {integrity: sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA==} + dependencies: + '@stablelib/aead': 1.0.1 + '@stablelib/binary': 1.0.1 + '@stablelib/chacha': 1.0.1 + '@stablelib/constant-time': 1.0.1 + '@stablelib/poly1305': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/chacha@1.0.1: + resolution: {integrity: sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg==} + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/constant-time@1.0.1: + resolution: {integrity: sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg==} + dev: false + + /@stablelib/ed25519@1.0.3: + resolution: {integrity: sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg==} + dependencies: + '@stablelib/random': 1.0.2 + '@stablelib/sha512': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/hash@1.0.1: + resolution: {integrity: sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg==} + dev: false + + /@stablelib/hkdf@1.0.1: + resolution: {integrity: sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g==} + dependencies: + '@stablelib/hash': 1.0.1 + '@stablelib/hmac': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/hmac@1.0.1: + resolution: {integrity: sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA==} + dependencies: + '@stablelib/constant-time': 1.0.1 + '@stablelib/hash': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/int@1.0.1: + resolution: {integrity: sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w==} + dev: false + + /@stablelib/keyagreement@1.0.1: + resolution: {integrity: sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg==} + dependencies: + '@stablelib/bytes': 1.0.1 + dev: false + + /@stablelib/poly1305@1.0.1: + resolution: {integrity: sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA==} + dependencies: + '@stablelib/constant-time': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/random@1.0.2: + resolution: {integrity: sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w==} + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/sha256@1.0.1: + resolution: {integrity: sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ==} + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/hash': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/sha512@1.0.1: + resolution: {integrity: sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw==} + dependencies: + '@stablelib/binary': 1.0.1 + '@stablelib/hash': 1.0.1 + '@stablelib/wipe': 1.0.1 + dev: false + + /@stablelib/wipe@1.0.1: + resolution: {integrity: sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg==} + dev: false + + /@stablelib/x25519@1.0.3: + resolution: {integrity: sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw==} + dependencies: + '@stablelib/keyagreement': 1.0.1 + '@stablelib/random': 1.0.2 + '@stablelib/wipe': 1.0.1 + dev: false + + /@types/node@18.15.13: + resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + dev: false + + /@types/trusted-types@2.0.7: + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + dev: false + + /@types/ws@8.5.10: + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} + dependencies: + '@types/node': 18.15.13 + dev: false + + /@wagmi/chains@1.8.0: + resolution: {integrity: sha512-UXo0GF0Cl0+neKC2KAmVAahv8L/5rACbFRRqkDvHMefzY6Fh7yzJd8F4GaGNNG3w4hj8eUB/E3+dEpaTYDN62w==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + dev: false + + /@walletconnect/core@2.12.2: + resolution: {integrity: sha512-7Adv/b3pp9F42BkvReaaM4KS8NEvlkS7AMtwO3uF/o6aRMKtcfTJq9/jgWdKJh4RP8pPRTRFjCw6XQ/RZtT4aQ==} + dependencies: + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-provider': 1.0.13 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.14 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.10 + '@walletconnect/relay-auth': 1.0.4 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/utils': 2.12.2 + events: 3.3.0 + isomorphic-unfetch: 3.1.0 + lodash.isequal: 4.5.0 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - uWebSockets.js + - utf-8-validate + dev: false + + /@walletconnect/environment@1.0.1: + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + dependencies: + tslib: 1.14.1 + dev: false + + /@walletconnect/ethereum-provider@2.12.2(react@18.2.0): + resolution: {integrity: sha512-vBl2zCnNm2iPaomJdr5YT16cT7aa8cH2WFs6879XPngU5i7HXS3bU6TamhyhKKl13sdIfifmCkCC+RWn5GdPMw==} + dependencies: + '@walletconnect/jsonrpc-http-connection': 1.0.7 + '@walletconnect/jsonrpc-provider': 1.0.13 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/modal': 2.6.2(react@18.2.0) + '@walletconnect/sign-client': 2.12.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/universal-provider': 2.12.2 + '@walletconnect/utils': 2.12.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - react + - uWebSockets.js + - utf-8-validate + dev: false + + /@walletconnect/events@1.0.1: + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + dev: false + + /@walletconnect/heartbeat@1.2.1: + resolution: {integrity: sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q==} + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + tslib: 1.14.1 + dev: false + + /@walletconnect/jsonrpc-http-connection@1.0.7: + resolution: {integrity: sha512-qlfh8fCfu8LOM9JRR9KE0s0wxP6ZG9/Jom8M0qsoIQeKF3Ni0FyV4V1qy/cc7nfI46SLQLSl4tgWSfLiE1swyQ==} + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.1.8 + tslib: 1.14.1 + transitivePeerDependencies: + - encoding + dev: false + + /@walletconnect/jsonrpc-provider@1.0.13: + resolution: {integrity: sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g==} + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + tslib: 1.14.1 + dev: false + + /@walletconnect/jsonrpc-types@1.0.3: + resolution: {integrity: sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw==} + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + dev: false + + /@walletconnect/jsonrpc-utils@1.0.8: + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.3 + tslib: 1.14.1 + dev: false + + /@walletconnect/jsonrpc-ws-connection@1.0.14: + resolution: {integrity: sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA==} + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.9 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /@walletconnect/keyvaluestorage@1.1.1: + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.1 + unstorage: 1.10.2(idb-keyval@6.2.1) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + dev: false + + /@walletconnect/logger@2.1.2: + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + dev: false + + /@walletconnect/modal-core@2.6.2(react@18.2.0): + resolution: {integrity: sha512-cv8ibvdOJQv2B+nyxP9IIFdxvQznMz8OOr/oR/AaUZym4hjXNL/l1a2UlSQBXrVjo3xxbouMxLb3kBsHoYP2CA==} + dependencies: + valtio: 1.11.2(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - react + dev: false + + /@walletconnect/modal-ui@2.6.2(react@18.2.0): + resolution: {integrity: sha512-rbdstM1HPGvr7jprQkyPggX7rP4XiCG85ZA+zWBEX0dVQg8PpAgRUqpeub4xQKDgY7pY/xLRXSiCVdWGqvG2HA==} + dependencies: + '@walletconnect/modal-core': 2.6.2(react@18.2.0) + lit: 2.8.0 + motion: 10.16.2 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@types/react' + - react + dev: false + + /@walletconnect/modal@2.6.2(react@18.2.0): + resolution: {integrity: sha512-eFopgKi8AjKf/0U4SemvcYw9zlLpx9njVN8sf6DAkowC2Md0gPU/UNEbH1Wwj407pEKnEds98pKWib1NN1ACoA==} + dependencies: + '@walletconnect/modal-core': 2.6.2(react@18.2.0) + '@walletconnect/modal-ui': 2.6.2(react@18.2.0) + transitivePeerDependencies: + - '@types/react' + - react + dev: false + + /@walletconnect/relay-api@1.0.10: + resolution: {integrity: sha512-tqrdd4zU9VBNqUaXXQASaexklv6A54yEyQQEXYOCr+Jz8Ket0dmPBDyg19LVSNUN2cipAghQc45/KVmfFJ0cYw==} + dependencies: + '@walletconnect/jsonrpc-types': 1.0.3 + dev: false + + /@walletconnect/relay-auth@1.0.4: + resolution: {integrity: sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ==} + dependencies: + '@stablelib/ed25519': 1.0.3 + '@stablelib/random': 1.0.2 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + tslib: 1.14.1 + uint8arrays: 3.1.1 + dev: false + + /@walletconnect/safe-json@1.0.2: + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + dependencies: + tslib: 1.14.1 + dev: false + + /@walletconnect/sign-client@2.12.2: + resolution: {integrity: sha512-cM0ualXj6nVvLqS4BDNRk+ZWR+lubcsz/IHreH+3wYrQ2sV+C0fN6ctrd7MMGZss0C0qacWCx0pm62ZBuoKvqA==} + dependencies: + '@walletconnect/core': 2.12.2 + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/utils': 2.12.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - uWebSockets.js + - utf-8-validate + dev: false + + /@walletconnect/time@1.0.2: + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + dependencies: + tslib: 1.14.1 + dev: false + + /@walletconnect/types@2.12.2: + resolution: {integrity: sha512-9CmwTlPbrFTzayTL9q7xM7s3KTJkS6kYFtH2m1/fHFgALs6pIUjf1qAx1TF2E4tv7SEzLAIzU4NqgYUt2vWXTg==} + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.1 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/keyvaluestorage': 1.1.1 + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + dev: false + + /@walletconnect/universal-provider@2.12.2: + resolution: {integrity: sha512-0k5ZgSkABopQLVhkiwl2gRGG7dAP4SWiI915pIlyN5sRvWV+qX1ALhWAmRcdv0TXWlKHDcDgPJw/q2sCSAHuMQ==} + dependencies: + '@walletconnect/jsonrpc-http-connection': 1.0.7 + '@walletconnect/jsonrpc-provider': 1.0.13 + '@walletconnect/jsonrpc-types': 1.0.3 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.12.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/utils': 2.12.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - bufferutil + - encoding + - ioredis + - uWebSockets.js + - utf-8-validate + dev: false + + /@walletconnect/utils@2.12.2: + resolution: {integrity: sha512-zf50HeS3SfoLv1N9GPl2IXTZ9TsXfet4usVAsZmX9P6/Xzq7d/7QakjVQCHH/Wk1O9XkcsfeoZoUhRxoMJ5uJw==} + dependencies: + '@stablelib/chacha20poly1305': 1.0.1 + '@stablelib/hkdf': 1.0.1 + '@stablelib/random': 1.0.2 + '@stablelib/sha256': 1.0.1 + '@stablelib/x25519': 1.0.3 + '@walletconnect/relay-api': 1.0.10 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.12.2 + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.1 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/kv' + - ioredis + - uWebSockets.js + dev: false + + /@walletconnect/window-getters@1.0.1: + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + dependencies: + tslib: 1.14.1 + dev: false + + /@walletconnect/window-metadata@1.0.1: + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + dependencies: + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 + dev: false + + /acorn@8.11.3: + resolution: {integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==} + engines: {node: '>=0.4.0'} + hasBin: true + dev: false + + /aes-js@4.0.0-beta.5: + resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + dev: false + + /ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + dev: false + + /ansi-styles@4.3.0: + resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} + engines: {node: '>=8'} + dependencies: + color-convert: 2.0.1 + dev: false + + /anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + dev: false + + /atomic-sleep@1.0.0: + resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} + engines: {node: '>=8.0.0'} + dev: false + + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} + engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 + dev: false + + /bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + dev: false + + /binary-extensions@2.3.0: + resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} + engines: {node: '>=8'} + dev: false + + /braces@3.0.2: + resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} + engines: {node: '>=8'} + dependencies: + fill-range: 7.0.1 + dev: false + + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.1 + dev: false + + /camelcase@5.3.1: + resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} + engines: {node: '>=6'} + dev: false + + /chokidar@3.6.0: + resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} + engines: {node: '>= 8.10.0'} + dependencies: + anymatch: 3.1.3 + braces: 3.0.2 + glob-parent: 5.1.2 + is-binary-path: 2.1.0 + is-glob: 4.0.3 + normalize-path: 3.0.0 + readdirp: 3.6.0 + optionalDependencies: + fsevents: 2.3.3 + dev: false + + /citty@0.1.6: + resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==} + dependencies: + consola: 3.2.3 + dev: false + + /clipboardy@4.0.0: + resolution: {integrity: sha512-5mOlNS0mhX0707P2I0aZ2V/cmHUEO/fL7VFLqszkhUsxt7RwnmrInf/eEQKlf5GzvYeHIjT+Ov1HRfNmymlG0w==} + engines: {node: '>=18'} + dependencies: + execa: 8.0.1 + is-wsl: 3.1.0 + is64bit: 2.0.0 + dev: false + + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: false + + /color-convert@2.0.1: + resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} + engines: {node: '>=7.0.0'} + dependencies: + color-name: 1.1.4 + dev: false + + /color-name@1.1.4: + resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + dev: false + + /confbox@0.1.7: + resolution: {integrity: sha512-uJcB/FKZtBMCJpK8MQji6bJHgu1tixKPxRLeGkNzBoOZzpnZUJm0jm2/sBDWcuBx1dYgxV4JU+g5hmNxCyAmdA==} + dev: false + + /consola@3.2.3: + resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==} + engines: {node: ^14.18.0 || >=16.10.0} + dev: false + + /cookie-es@1.1.0: + resolution: {integrity: sha512-L2rLOcK0wzWSfSDA33YR+PUHDG10a8px7rUHKWbGLP4YfbsMed2KFUw5fczvDPbT98DDe3LEzviswl810apTEw==} + dev: false + + /cross-fetch@3.1.8: + resolution: {integrity: sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg==} + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + dev: false + + /cross-spawn@7.0.3: + resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} + engines: {node: '>= 8'} + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + dev: false + + /crossws@0.2.4: + resolution: {integrity: sha512-DAxroI2uSOgUKLz00NX6A8U/8EE3SZHmIND+10jkVSaypvyt57J5JEOxAQOL6lQxyzi/wZbTIwssU1uy69h5Vg==} + peerDependencies: + uWebSockets.js: '*' + peerDependenciesMeta: + uWebSockets.js: + optional: true + dev: false + + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: false + + /decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + dev: false + + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + dev: false + + /defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + dev: false + + /destr@2.0.3: + resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==} + dev: false + + /detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + dev: false + + /detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + dev: false + + /dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dev: false + + /duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + dependencies: + end-of-stream: 1.4.4 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + dev: false + + /emoji-regex@8.0.0: + resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false + + /encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + dev: false + + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: false + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + dev: false + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + dev: false + + /ethereum-cryptography@2.1.3: + resolution: {integrity: sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==} + dependencies: + '@noble/curves': 1.3.0 + '@noble/hashes': 1.3.3 + '@scure/bip32': 1.3.3 + '@scure/bip39': 1.2.2 + dev: false + + /ethers@6.11.1: + resolution: {integrity: sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==} + engines: {node: '>=14.0.0'} + dependencies: + '@adraffy/ens-normalize': 1.10.1 + '@noble/curves': 1.2.0 + '@noble/hashes': 1.3.2 + '@types/node': 18.15.13 + aes-js: 4.0.0-beta.5 + tslib: 2.4.0 + ws: 8.5.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + dev: false + + /eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + dev: false + + /events@3.3.0: + resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} + engines: {node: '>=0.8.x'} + dev: false + + /execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + dev: false + + /fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + dev: false + + /fill-range@7.0.1: + resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} + engines: {node: '>=8'} + dependencies: + to-regex-range: 5.0.1 + dev: false + + /filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + dev: false + + /find-up@4.1.0: + resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} + engines: {node: '>=8'} + dependencies: + locate-path: 5.0.0 + path-exists: 4.0.0 + dev: false + + /for-each@0.3.3: + resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} + dependencies: + is-callable: 1.2.7 + dev: false + + /fsevents@2.3.3: + resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} + engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} + os: [darwin] + requiresBuild: true + dev: false + optional: true + + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + dev: false + + /get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + dev: false + + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.1 + dev: false + + /get-port-please@3.1.2: + resolution: {integrity: sha512-Gxc29eLs1fbn6LQ4jSU4vXjlwyZhF5HsGuMAa7gqBP4Rw4yxxltyDUuF5MBclFzDTXO+ACchGQoeela4DSfzdQ==} + dev: false + + /get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + dev: false + + /glob-parent@5.1.2: + resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} + engines: {node: '>= 6'} + dependencies: + is-glob: 4.0.3 + dev: false + + /gopd@1.0.1: + resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + dependencies: + get-intrinsic: 1.2.4 + dev: false + + /h3@1.11.1: + resolution: {integrity: sha512-AbaH6IDnZN6nmbnJOH72y3c5Wwh9P97soSVdGSBbcDACRdkC0FEWf25pzx4f/NuOCK6quHmW18yF2Wx+G4Zi1A==} + dependencies: + cookie-es: 1.1.0 + crossws: 0.2.4 + defu: 6.1.4 + destr: 2.0.3 + iron-webcrypto: 1.1.1 + ohash: 1.1.3 + radix3: 1.1.2 + ufo: 1.5.3 + uncrypto: 0.1.3 + unenv: 1.9.0 + transitivePeerDependencies: + - uWebSockets.js + dev: false + + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + dependencies: + es-define-property: 1.0.0 + dev: false + + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} + engines: {node: '>= 0.4'} + dev: false + + /has-symbols@1.0.3: + resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} + engines: {node: '>= 0.4'} + dev: false + + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} + engines: {node: '>= 0.4'} + dependencies: + has-symbols: 1.0.3 + dev: false + + /hasown@2.0.1: + resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + dev: false + + /hey-listen@1.0.8: + resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==} + dev: false + + /http-shutdown@1.2.2: + resolution: {integrity: sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw==} + engines: {iojs: '>= 1.0.0', node: '>= 0.12.0'} + dev: false + + /human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + dev: false + + /idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + dev: false + + /inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + dev: false + + /iron-webcrypto@1.1.1: + resolution: {integrity: sha512-5xGwQUWHQSy039rFr+5q/zOmj7GP0Ypzvo34Ep+61bPIhaLduEDp/PvLGlU3awD2mzWUR0weN2vJ1mILydFPEg==} + dev: false + + /is-arguments@1.1.1: + resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + has-tostringtag: 1.0.2 + dev: false + + /is-binary-path@2.1.0: + resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} + engines: {node: '>=8'} + dependencies: + binary-extensions: 2.3.0 + dev: false + + /is-callable@1.2.7: + resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} + engines: {node: '>= 0.4'} + dev: false + + /is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + dev: false + + /is-extglob@2.1.1: + resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} + engines: {node: '>=0.10.0'} + dev: false + + /is-fullwidth-code-point@3.0.0: + resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} + engines: {node: '>=8'} + dev: false + + /is-generator-function@1.0.10: + resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} + engines: {node: '>= 0.4'} + dependencies: + has-tostringtag: 1.0.2 + dev: false + + /is-glob@4.0.3: + resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} + engines: {node: '>=0.10.0'} + dependencies: + is-extglob: 2.1.1 + dev: false + + /is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + dependencies: + is-docker: 3.0.0 + dev: false + + /is-number@7.0.0: + resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} + engines: {node: '>=0.12.0'} + dev: false + + /is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dev: false + + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} + engines: {node: '>= 0.4'} + dependencies: + which-typed-array: 1.1.14 + dev: false + + /is-wsl@3.1.0: + resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==} + engines: {node: '>=16'} + dependencies: + is-inside-container: 1.0.0 + dev: false + + /is64bit@2.0.0: + resolution: {integrity: sha512-jv+8jaWCl0g2lSBkNSVXdzfBA0npK1HGC2KtWM9FumFRoGS94g3NbCCLVnCYHLjp4GrW2KZeeSTMo5ddtznmGw==} + engines: {node: '>=18'} + dependencies: + system-architecture: 0.1.0 + dev: false + + /isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + dev: false + + /isomorphic-unfetch@3.1.0: + resolution: {integrity: sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q==} + dependencies: + node-fetch: 2.7.0 + unfetch: 4.2.0 + transitivePeerDependencies: + - encoding + dev: false + + /jiti@1.21.0: + resolution: {integrity: sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q==} + hasBin: true + dev: false + + /js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + dev: false + + /keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + dev: false + + /listhen@1.7.2: + resolution: {integrity: sha512-7/HamOm5YD9Wb7CFgAZkKgVPA96WwhcTQoqtm2VTZGVbVVn3IWKRBTgrU7cchA3Q8k9iCsG8Osoi9GX4JsGM9g==} + hasBin: true + dependencies: + '@parcel/watcher': 2.4.1 + '@parcel/watcher-wasm': 2.4.1 + citty: 0.1.6 + clipboardy: 4.0.0 + consola: 3.2.3 + crossws: 0.2.4 + defu: 6.1.4 + get-port-please: 3.1.2 + h3: 1.11.1 + http-shutdown: 1.2.2 + jiti: 1.21.0 + mlly: 1.6.1 + node-forge: 1.3.1 + pathe: 1.1.2 + std-env: 3.7.0 + ufo: 1.5.3 + untun: 0.1.3 + uqr: 0.1.2 + transitivePeerDependencies: + - uWebSockets.js + dev: false + + /lit-element@3.3.3: + resolution: {integrity: sha512-XbeRxmTHubXENkV4h8RIPyr8lXc+Ff28rkcQzw3G6up2xg5E8Zu1IgOWIwBLEQsu3cOVFqdYwiVi0hv0SlpqUA==} + dependencies: + '@lit-labs/ssr-dom-shim': 1.2.0 + '@lit/reactive-element': 1.6.3 + lit-html: 2.8.0 + dev: false + + /lit-html@2.8.0: + resolution: {integrity: sha512-o9t+MQM3P4y7M7yNzqAyjp7z+mQGa4NS4CxiyLqFPyFWyc4O+nodLrkrxSaCTrla6M5YOLaT3RpbbqjszB5g3Q==} + dependencies: + '@types/trusted-types': 2.0.7 + dev: false + + /lit@2.8.0: + resolution: {integrity: sha512-4Sc3OFX9QHOJaHbmTMk28SYgVxLN3ePDjg7hofEft2zWlehFL3LiAuapWc4U/kYwMYJSh2hTCPZ6/LIC7ii0MA==} + dependencies: + '@lit/reactive-element': 1.6.3 + lit-element: 3.3.3 + lit-html: 2.8.0 + dev: false + + /locate-path@5.0.0: + resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} + engines: {node: '>=8'} + dependencies: + p-locate: 4.1.0 + dev: false + + /lodash.isequal@4.5.0: + resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} + dev: false + + /loose-envify@1.4.0: + resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} + hasBin: true + dependencies: + js-tokens: 4.0.0 + dev: false + + /lru-cache@10.2.0: + resolution: {integrity: sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==} + engines: {node: 14 || >=16.14} + dev: false + + /merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + dev: false + + /micromatch@4.0.5: + resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} + engines: {node: '>=8.6'} + dependencies: + braces: 3.0.2 + picomatch: 2.3.1 + dev: false + + /mime@3.0.0: + resolution: {integrity: sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==} + engines: {node: '>=10.0.0'} + hasBin: true + dev: false + + /mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + dev: false + + /mlly@1.6.1: + resolution: {integrity: sha512-vLgaHvaeunuOXHSmEbZ9izxPx3USsk8KCQ8iC+aTlp5sKRSoZvwhHh5L9VbKSaVC6sJDqbyohIS76E2VmHIPAA==} + dependencies: + acorn: 8.11.3 + pathe: 1.1.2 + pkg-types: 1.1.0 + ufo: 1.5.3 + dev: false + + /motion@10.16.2: + resolution: {integrity: sha512-p+PurYqfUdcJZvtnmAqu5fJgV2kR0uLFQuBKtLeFVTrYEVllI99tiOTSefVNYuip9ELTEkepIIDftNdze76NAQ==} + dependencies: + '@motionone/animation': 10.17.0 + '@motionone/dom': 10.17.0 + '@motionone/svelte': 10.16.4 + '@motionone/types': 10.17.0 + '@motionone/utils': 10.17.0 + '@motionone/vue': 10.16.4 + dev: false + + /mri@1.2.0: + resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} + engines: {node: '>=4'} + dev: false + + /multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + dev: false + + /napi-wasm@1.1.0: + resolution: {integrity: sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg==} + dev: false + + /node-addon-api@7.1.0: + resolution: {integrity: sha512-mNcltoe1R8o7STTegSOHdnJNN7s5EUvhoS7ShnTHDyOSd+8H+UdWODq6qSv67PjC8Zc5JRT8+oLAMCr0SIXw7g==} + engines: {node: ^16 || ^18 || >= 20} + dev: false + + /node-fetch-native@1.6.4: + resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==} + dev: false + + /node-fetch@2.7.0: + resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-forge@1.3.1: + resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} + engines: {node: '>= 6.13.0'} + dev: false + + /normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + dev: false + + /npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + path-key: 4.0.0 + dev: false + + /ofetch@1.3.4: + resolution: {integrity: sha512-KLIET85ik3vhEfS+3fDlc/BAZiAp+43QEC/yCo5zkNoY2YaKvNkOaFr/6wCFgFH1kuYQM5pMNi0Tg8koiIemtw==} + dependencies: + destr: 2.0.3 + node-fetch-native: 1.6.4 + ufo: 1.5.3 + dev: false + + /ohash@1.1.3: + resolution: {integrity: sha512-zuHHiGTYTA1sYJ/wZN+t5HKZaH23i4yI1HMwbuXm24Nid7Dv0KcuRlKoNKS9UNfAVSBlnGLcuQrnOKWOZoEGaw==} + dev: false + + /on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + dev: false + + /once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + dependencies: + wrappy: 1.0.2 + dev: false + + /onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + dependencies: + mimic-fn: 4.0.0 + dev: false + + /p-limit@2.3.0: + resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} + engines: {node: '>=6'} + dependencies: + p-try: 2.2.0 + dev: false + + /p-locate@4.1.0: + resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} + engines: {node: '>=8'} + dependencies: + p-limit: 2.3.0 + dev: false + + /p-try@2.2.0: + resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} + engines: {node: '>=6'} + dev: false + + /path-exists@4.0.0: + resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} + engines: {node: '>=8'} + dev: false + + /path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + dev: false + + /path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + dev: false + + /pathe@1.1.2: + resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + dev: false + + /picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + dev: false + + /pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} dependencies: - '@noble/hashes': 1.3.2 + duplexify: 4.1.3 + split2: 4.2.0 dev: false - /@noble/curves@1.3.0: - resolution: {integrity: sha512-t01iSXPuN+Eqzb4eBX0S5oubSqXbK/xXa1Ne18Hj8f9pStxztHCE2gfboSp/dZRLSqfuLpRK2nDXDK+W9puocA==} + /pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + dev: false + + /pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true dependencies: - '@noble/hashes': 1.3.3 + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.4.3 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 dev: false - /@noble/hashes@1.3.2: - resolution: {integrity: sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ==} - engines: {node: '>= 16'} + /pkg-types@1.1.0: + resolution: {integrity: sha512-/RpmvKdxKf8uILTtoOhAgf30wYbP2Qw+L9p3Rvshx1JZVX+XQNZQFjlbmGHEGIm4CkVPlSn+NXmIM8+9oWQaSA==} + dependencies: + confbox: 0.1.7 + mlly: 1.6.1 + pathe: 1.1.2 dev: false - /@noble/hashes@1.3.3: - resolution: {integrity: sha512-V7/fPHgl+jsVPXqqeOzT8egNj2iBIVt+ECeMMG8TdcnTikP3oaBtUVqpT/gYCR68aEBJSF+XbYUxStjbFMqIIA==} - engines: {node: '>= 16'} + /pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} dev: false - /@scure/base@1.1.5: - resolution: {integrity: sha512-Brj9FiG2W1MRQSTB212YVPRrcbjkv48FoZi/u4l/zds/ieRrqsh7aUf6CLwkAq61oKXr/ZlTzlY66gLIj3TFTQ==} + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} dev: false - /@scure/bip32@1.3.3: - resolution: {integrity: sha512-LJaN3HwRbfQK0X1xFSi0Q9amqOgzQnnDngIt+ZlsBC3Bm7/nE7K0kwshZHyaru79yIVRv/e1mQAjZyuZG6jOFQ==} + /process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + dev: false + + /proxy-compare@2.5.1: + resolution: {integrity: sha512-oyfc0Tx87Cpwva5ZXezSp5V9vht1c7dZBhvuV/y3ctkgMVUmiAGDVeeB0dKhGSyT0v1ZTEQYpe/RXlBVBNuCLA==} + dev: false + + /qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true dependencies: - '@noble/curves': 1.3.0 - '@noble/hashes': 1.3.3 - '@scure/base': 1.1.5 + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 dev: false - /@scure/bip39@1.2.2: - resolution: {integrity: sha512-HYf9TUXG80beW+hGAt3TRM8wU6pQoYur9iNypTROm42dorCGmLnFe3eWjz3gOq6G62H2WRh0FCzAR1PI+29zIA==} + /query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} dependencies: - '@noble/hashes': 1.3.3 - '@scure/base': 1.1.5 + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 dev: false - /@types/node@18.15.13: - resolution: {integrity: sha512-N+0kuo9KgrUQ1Sn/ifDXsvg0TTleP7rIy4zOBGECxAljqvqfqpTfzx0Q1NUedOixRMBfe2Whhb056a42cWs26Q==} + /quick-format-unescaped@4.0.4: + resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} dev: false - /@types/ws@8.5.10: - resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} - dependencies: - '@types/node': 18.15.13 + /radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} dev: false - /@wagmi/chains@1.8.0: - resolution: {integrity: sha512-UXo0GF0Cl0+neKC2KAmVAahv8L/5rACbFRRqkDvHMefzY6Fh7yzJd8F4GaGNNG3w4hj8eUB/E3+dEpaTYDN62w==} - peerDependencies: - typescript: '>=5.0.4' - peerDependenciesMeta: - typescript: - optional: true + /react@18.2.0: + resolution: {integrity: sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==} + engines: {node: '>=0.10.0'} + dependencies: + loose-envify: 1.4.0 dev: false - /aes-js@4.0.0-beta.5: - resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} + /readable-stream@3.6.2: + resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} + engines: {node: '>= 6'} + dependencies: + inherits: 2.0.4 + string_decoder: 1.3.0 + util-deprecate: 1.0.2 dev: false - /available-typed-arrays@1.0.7: - resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} - engines: {node: '>= 0.4'} + /readdirp@3.6.0: + resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} + engines: {node: '>=8.10.0'} dependencies: - possible-typed-array-names: 1.0.0 + picomatch: 2.3.1 dev: false - /bignumber.js@9.1.2: - resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + /real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} dev: false - /call-bind@1.0.7: - resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + /require-directory@2.1.1: + resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} + engines: {node: '>=0.10.0'} + dev: false + + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: false + + /safe-buffer@5.2.1: + resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false + + /safe-stable-stringify@2.4.3: + resolution: {integrity: sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==} + engines: {node: '>=10'} + dev: false + + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: false + + /set-function-length@1.2.1: + resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} engines: {node: '>= 0.4'} dependencies: - es-define-property: 1.0.0 + define-data-property: 1.1.4 es-errors: 1.3.0 function-bind: 1.1.2 get-intrinsic: 1.2.4 - set-function-length: 1.2.1 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 dev: false - /define-data-property@1.1.4: - resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} - engines: {node: '>= 0.4'} + /shebang-command@2.0.0: + resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} + engines: {node: '>=8'} dependencies: - es-define-property: 1.0.0 - es-errors: 1.3.0 - gopd: 1.0.1 + shebang-regex: 3.0.0 dev: false - /es-define-property@1.0.0: - resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.2.4 + /shebang-regex@3.0.0: + resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} + engines: {node: '>=8'} dev: false - /es-errors@1.3.0: - resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} - engines: {node: '>= 0.4'} + /signal-exit@4.1.0: + resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} + engines: {node: '>=14'} dev: false - /ethereum-cryptography@2.1.3: - resolution: {integrity: sha512-BlwbIL7/P45W8FGW2r7LGuvoEZ+7PWsniMvQ4p5s2xCyw9tmaDlpfsN9HjAucbF+t/qpVHwZUisgfK24TCW8aA==} + /sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} dependencies: - '@noble/curves': 1.3.0 - '@noble/hashes': 1.3.3 - '@scure/bip32': 1.3.3 - '@scure/bip39': 1.2.2 + atomic-sleep: 1.0.0 dev: false - /ethers@6.11.1: - resolution: {integrity: sha512-mxTAE6wqJQAbp5QAe/+o+rXOID7Nw91OZXvgpjDa1r4fAbq2Nu314oEZSbjoRLacuCzs7kUC3clEvkCQowffGg==} - engines: {node: '>=14.0.0'} - dependencies: - '@adraffy/ens-normalize': 1.10.1 - '@noble/curves': 1.2.0 - '@noble/hashes': 1.3.2 - '@types/node': 18.15.13 - aes-js: 4.0.0-beta.5 - tslib: 2.4.0 - ws: 8.5.0 - transitivePeerDependencies: - - bufferutil - - utf-8-validate + /split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} dev: false - /eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + /split2@4.2.0: + resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} + engines: {node: '>= 10.x'} dev: false - /for-each@0.3.3: - resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} - dependencies: - is-callable: 1.2.7 + /std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} dev: false - /function-bind@1.1.2: - resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + /stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} dev: false - /get-intrinsic@1.2.4: - resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} - engines: {node: '>= 0.4'} + /strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + dev: false + + /string-width@4.2.3: + resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} + engines: {node: '>=8'} dependencies: - es-errors: 1.3.0 - function-bind: 1.1.2 - has-proto: 1.0.3 - has-symbols: 1.0.3 - hasown: 2.0.1 + emoji-regex: 8.0.0 + is-fullwidth-code-point: 3.0.0 + strip-ansi: 6.0.1 dev: false - /gopd@1.0.1: - resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} + /string_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: - get-intrinsic: 1.2.4 + safe-buffer: 5.2.1 dev: false - /has-property-descriptors@1.0.2: - resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} + /strip-ansi@6.0.1: + resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} + engines: {node: '>=8'} dependencies: - es-define-property: 1.0.0 + ansi-regex: 5.0.1 dev: false - /has-proto@1.0.3: - resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} - engines: {node: '>= 0.4'} + /strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} dev: false - /has-symbols@1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} + /system-architecture@0.1.0: + resolution: {integrity: sha512-ulAk51I9UVUyJgxlv9M6lFot2WP3e7t8Kz9+IS6D4rVba1tR9kON+Ey69f+1R4Q8cd45Lod6a4IcJIxnzGc/zA==} + engines: {node: '>=18'} dev: false - /has-tostringtag@1.0.2: - resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} - engines: {node: '>= 0.4'} + /thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} dependencies: - has-symbols: 1.0.3 + real-require: 0.1.0 dev: false - /hasown@2.0.1: - resolution: {integrity: sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA==} - engines: {node: '>= 0.4'} + /to-regex-range@5.0.1: + resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} + engines: {node: '>=8.0'} dependencies: - function-bind: 1.1.2 + is-number: 7.0.0 dev: false - /inherits@2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + /tr46@0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} dev: false - /is-arguments@1.1.1: - resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} - engines: {node: '>= 0.4'} + /tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + dev: false + + /tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + dev: false + + /ufo@1.5.3: + resolution: {integrity: sha512-Y7HYmWaFwPUmkoQCUIAYpKqkOf+SbVj/2fJJZ4RJMCfZp0rTGwRbzQD+HghfnhKOjL9E01okqz+ncJskGYfBNw==} + dev: false + + /uint8arrays@3.1.1: + resolution: {integrity: sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg==} dependencies: - call-bind: 1.0.7 - has-tostringtag: 1.0.2 + multiformats: 9.9.0 dev: false - /is-callable@1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} + /uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} dev: false - /is-generator-function@1.0.10: - resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} - engines: {node: '>= 0.4'} + /unenv@1.9.0: + resolution: {integrity: sha512-QKnFNznRxmbOF1hDgzpqrlIf6NC5sbZ2OJ+5Wl3OX8uM+LUJXbj4TXvLJCtwbPTmbMHCLIz6JLKNinNsMShK9g==} dependencies: - has-tostringtag: 1.0.2 + consola: 3.2.3 + defu: 6.1.4 + mime: 3.0.0 + node-fetch-native: 1.6.4 + pathe: 1.1.2 dev: false - /is-typed-array@1.1.13: - resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} - engines: {node: '>= 0.4'} + /unfetch@4.2.0: + resolution: {integrity: sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA==} + dev: false + + /unstorage@1.10.2(idb-keyval@6.2.1): + resolution: {integrity: sha512-cULBcwDqrS8UhlIysUJs2Dk0Mmt8h7B0E6mtR+relW9nZvsf/u4SkAYyNliPiPW7XtFNb5u3IUMkxGxFTTRTgQ==} + peerDependencies: + '@azure/app-configuration': ^1.5.0 + '@azure/cosmos': ^4.0.0 + '@azure/data-tables': ^13.2.2 + '@azure/identity': ^4.0.1 + '@azure/keyvault-secrets': ^4.8.0 + '@azure/storage-blob': ^12.17.0 + '@capacitor/preferences': ^5.0.7 + '@netlify/blobs': ^6.5.0 || ^7.0.0 + '@planetscale/database': ^1.16.0 + '@upstash/redis': ^1.28.4 + '@vercel/kv': ^1.0.1 + idb-keyval: ^6.2.1 + ioredis: ^5.3.2 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/kv': + optional: true + idb-keyval: + optional: true + ioredis: + optional: true dependencies: - which-typed-array: 1.1.14 + anymatch: 3.1.3 + chokidar: 3.6.0 + destr: 2.0.3 + h3: 1.11.1 + idb-keyval: 6.2.1 + listhen: 1.7.2 + lru-cache: 10.2.0 + mri: 1.2.0 + node-fetch-native: 1.6.4 + ofetch: 1.3.4 + ufo: 1.5.3 + transitivePeerDependencies: + - uWebSockets.js dev: false - /possible-typed-array-names@1.0.0: - resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} - engines: {node: '>= 0.4'} + /untun@0.1.3: + resolution: {integrity: sha512-4luGP9LMYszMRZwsvyUd9MrxgEGZdZuZgpVQHEEX0lCYFESasVRvZd0EYpCkOIbJKHMuv0LskpXc/8Un+MJzEQ==} + hasBin: true + dependencies: + citty: 0.1.6 + consola: 3.2.3 + pathe: 1.1.2 dev: false - /set-function-length@1.2.1: - resolution: {integrity: sha512-j4t6ccc+VsKwYHso+kElc5neZpjtq9EnRICFZtWyBsLojhmeF/ZBd/elqm22WJh/BziDe/SBiOeAt0m2mfLD0g==} - engines: {node: '>= 0.4'} + /uqr@0.1.2: + resolution: {integrity: sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA==} + dev: false + + /use-sync-external-store@1.2.0(react@18.2.0): + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 dependencies: - define-data-property: 1.1.4 - es-errors: 1.3.0 - function-bind: 1.1.2 - get-intrinsic: 1.2.4 - gopd: 1.0.1 - has-property-descriptors: 1.0.2 + react: 18.2.0 dev: false - /tslib@2.4.0: - resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + /util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: false /util@0.12.5: @@ -295,6 +1976,23 @@ packages: which-typed-array: 1.1.14 dev: false + /valtio@1.11.2(react@18.2.0): + resolution: {integrity: sha512-1XfIxnUXzyswPAPXo1P3Pdx2mq/pIqZICkWN60Hby0d9Iqb+MEIpqgYVlbflvHdrp2YR/q3jyKWRPJJ100yxaw==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + dependencies: + proxy-compare: 2.5.1 + react: 18.2.0 + use-sync-external-store: 1.2.0(react@18.2.0) + dev: false + /web3-errors@1.1.4: resolution: {integrity: sha512-WahtszSqILez+83AxGecVroyZsMuuRT+KmQp4Si5P4Rnqbczno1k748PCrZTS1J4UCPmXMG2/Vt+0Bz2zwXkwQ==} engines: {node: '>=14', npm: '>=6.12.0'} @@ -329,6 +2027,21 @@ packages: zod: 3.22.4 dev: false + /webidl-conversions@3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /whatwg-url@5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: false + /which-typed-array@1.1.14: resolution: {integrity: sha512-VnXFiIW8yNn9kIHN88xvZ4yOWchftKDsRJ8fEPacX/wl1lOvBrhsJ/OeJCXq7B0AaijRuqgzSKalJoPk+D8MPg==} engines: {node: '>= 0.4'} @@ -340,6 +2053,40 @@ packages: has-tostringtag: 1.0.2 dev: false + /which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + dependencies: + isexe: 2.0.0 + dev: false + + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + + /wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + dev: false + + /ws@7.5.9: + resolution: {integrity: sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: false + /ws@8.16.0: resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} engines: {node: '>=10.0.0'} @@ -366,6 +2113,35 @@ packages: optional: true dev: false + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: false + + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: false + + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: false + /zod@3.22.4: resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} dev: false diff --git a/packages/networks/evm-chains/src/assets/Contract.ts b/packages/networks/evm-chains/src/assets/Contract.ts index 2b7de08..a4b74f6 100644 --- a/packages/networks/evm-chains/src/assets/Contract.ts +++ b/packages/networks/evm-chains/src/assets/Contract.ts @@ -2,6 +2,7 @@ import { Provider } from '../services/Provider.ts' import type { Ethers } from '../services/Ethers.ts' import type { ContractInterface } from '@multiplechain/types' import type { Contract as EthersContract, InterfaceAbi } from 'ethers' +import type { TransactionData } from '../services/TransactionSigner.ts' export class Contract implements ContractInterface { /** @@ -76,4 +77,34 @@ export class Contract implements ContractInterface { async getMethodEstimateGas(method: string, from: string, ...args: any[]): Promise { return Number(await this.ethersContract[method].estimateGas(...args, { from })) // eslint-disable-line } + + /** + * @param {string} method Method name + * @param {string} from Sender wallet address + * @param {any[]} args Method parameters + * @returns {Promise} Transaction data + */ + async createTransactionData( + method: string, + from: string, + ...args: any[] + ): Promise { + const [gasPrice, nonce, data, gasLimit] = await Promise.all([ + this.provider.ethers.getGasPrice(), + this.provider.ethers.getNonce(from), + this.getMethodData(method, ...args), // eslint-disable-line + this.getMethodEstimateGas(method, from, ...args) // eslint-disable-line + ]) + + return { + from, + data, + nonce, + gasPrice, + gasLimit, + value: '0x0', + to: this.getAddress(), + chainId: this.provider.network.id + } + } } diff --git a/packages/networks/evm-chains/src/assets/NFT.ts b/packages/networks/evm-chains/src/assets/NFT.ts index 35e3cfd..6d03b69 100644 --- a/packages/networks/evm-chains/src/assets/NFT.ts +++ b/packages/networks/evm-chains/src/assets/NFT.ts @@ -109,23 +109,9 @@ export class NFT extends Contract implements NftInterface { } } - const [gasPrice, nonce, data, gasLimit] = await Promise.all([ - this.provider.ethers.getGasPrice(), - this.provider.ethers.getNonce(spender), - this.getMethodData('transferFrom', owner, receiver, nftId), - this.getMethodEstimateGas('transferFrom', spender, owner, receiver, nftId) - ]) - - return new NftTransactionSigner({ - data, - nonce, - gasPrice, - gasLimit, - value: '0x0', - from: spender, - to: this.getAddress(), - chainId: this.provider.network.id - }) + return new NftTransactionSigner( + await this.createTransactionData('transferFrom', spender, owner, receiver, nftId) + ) } /** @@ -153,22 +139,8 @@ export class NFT extends Contract implements NftInterface { throw new Error(ErrorTypeEnum.UNAUTHORIZED_ADDRESS) } - const [gasPrice, nonce, data, gasLimit] = await Promise.all([ - this.provider.ethers.getGasPrice(), - this.provider.ethers.getNonce(owner), - this.getMethodData('approve', spender, nftId), - this.getMethodEstimateGas('approve', owner, spender, nftId) - ]) - - return new NftTransactionSigner({ - data, - nonce, - gasPrice, - gasLimit, - value: '0x0', - from: owner, - to: this.getAddress(), - chainId: this.provider.network.id - }) + return new NftTransactionSigner( + await this.createTransactionData('approve', owner, spender, nftId) + ) } } diff --git a/packages/networks/evm-chains/src/assets/Token.ts b/packages/networks/evm-chains/src/assets/Token.ts index 985fbbd..cb74a17 100644 --- a/packages/networks/evm-chains/src/assets/Token.ts +++ b/packages/networks/evm-chains/src/assets/Token.ts @@ -96,23 +96,10 @@ export class Token extends Contract implements TokenInterface { } const hexAmount = numberToHex(amount, await this.getDecimals()) - const [gasPrice, nonce, data, gasLimit] = await Promise.all([ - this.provider.ethers.getGasPrice(), - this.provider.ethers.getNonce(sender), - this.getMethodData('transfer', receiver, hexAmount), - this.getMethodEstimateGas('transfer', sender, receiver, hexAmount) - ]) - return new TokenTransactionSigner({ - data, - nonce, - gasPrice, - gasLimit, - value: '0x0', - from: sender, - to: this.getAddress(), - chainId: this.provider.network.id - }) + return new TokenTransactionSigner( + await this.createTransactionData('transfer', sender, receiver, hexAmount) + ) } /** @@ -150,23 +137,9 @@ export class Token extends Contract implements TokenInterface { const hexAmount = numberToHex(amount, await this.getDecimals()) - const [gasPrice, nonce, data, gasLimit] = await Promise.all([ - this.provider.ethers.getGasPrice(), - this.provider.ethers.getNonce(spender), - this.getMethodData('transferFrom', owner, receiver, hexAmount), - this.getMethodEstimateGas('transferFrom', spender, owner, receiver, hexAmount) - ]) - - return new TokenTransactionSigner({ - data, - nonce, - gasPrice, - gasLimit, - value: '0x0', - from: spender, - to: this.getAddress(), - chainId: this.provider.network.id - }) + return new TokenTransactionSigner( + await this.createTransactionData('transferFrom', spender, owner, receiver, hexAmount) + ) } /** @@ -189,22 +162,8 @@ export class Token extends Contract implements TokenInterface { const hexAmount = numberToHex(amount, await this.getDecimals()) - const [gasPrice, nonce, data, gasLimit] = await Promise.all([ - this.provider.ethers.getGasPrice(), - this.provider.ethers.getNonce(owner), - this.getMethodData('approve', spender, hexAmount), - this.getMethodEstimateGas('approve', owner, spender, hexAmount) - ]) - - return new TokenTransactionSigner({ - data, - nonce, - gasPrice, - gasLimit, - value: '0x0', - from: owner, - to: this.getAddress(), - chainId: this.provider.network.id - }) + return new TokenTransactionSigner( + await this.createTransactionData('approve', owner, spender, hexAmount) + ) } } diff --git a/packages/networks/evm-chains/src/browser/Wallet.ts b/packages/networks/evm-chains/src/browser/Wallet.ts new file mode 100644 index 0000000..9b085ab --- /dev/null +++ b/packages/networks/evm-chains/src/browser/Wallet.ts @@ -0,0 +1,271 @@ +import { + type WalletConnectOps, + type WalletInterface, + type WalletAdapterInterface, + type WalletPlatformEnum, + type TransactionSignerInterface, + ErrorTypeEnum, + type ProviderInterface +} from '@multiplechain/types' +import { Provider } from '../services/Provider.ts' +import type { EIP1193Provider } from './adapters/EIP6963.ts' +import { toHex } from '@multiplechain/utils' + +const rejectMap = (error: any, reject: (a: any) => any): any => { + console.error('MultipleChain EVM Wallet Error:', error) + + const errorMessage = String(error.message ?? '') + if ( + errorMessage === 'Not supported chainId' || + errorMessage.includes('chain ID') || + errorMessage.includes('networkConfigurationId') || + errorMessage.includes('The Provider is not connected to the requested chain.') + ) { + return reject(new Error(ErrorTypeEnum.UNACCEPTED_CHAIN)) + } else if ( + error.code === 4001 || + error.error === 'Rejected by user' || + errorMessage === 'cancelled' || + errorMessage === 'User canceled' || + errorMessage === 'user reject this request' || + errorMessage === 'User rejected the transaction' || + errorMessage === 'An unexpected error occurred' || + errorMessage === 'User disapproved requested chains' + ) { + return reject(new Error(ErrorTypeEnum.WALLET_REQUEST_REJECTED)) + } else if ( + errorMessage.includes('User') || + errorMessage.includes('Rejected') || + errorMessage.includes('cancelled') || + errorMessage.includes('canceled') || + errorMessage.includes('rejected') || + errorMessage.includes('disapproved requested chains') + ) { + return reject(new Error(ErrorTypeEnum.WALLET_REQUEST_REJECTED)) + } else if (errorMessage.includes('Invalid RPC URL')) { + return reject(new Error(ErrorTypeEnum.RPC_REQUEST_ERROR)) + } else if ( + error.code === -32000 || + errorMessage.includes('timeout') || + errorMessage.includes('request timed out') + ) { + return reject(new Error(ErrorTypeEnum.RPC_TIMEOUT)) + } else if (error.code === -32603 || error.code === -32602) { + return reject(new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED)) + } else if (error.code === -32601) { + return reject(new Error(ErrorTypeEnum.RPC_REQUEST_ERROR)) + } else if ( + error.code === -32002 || + error.message === 'Already processing eth_requestAccounts. Please wait.' + ) { + return reject(new Error(ErrorTypeEnum.WALLET_ALREADY_PROCESSING)) + } else if (error.message === 'User closed modal') { + return reject(new Error(ErrorTypeEnum.CLOSED_WALLETCONNECT_MODAL)) + } else if (error.message === 'transaction underpriced') { + return reject(new Error(ErrorTypeEnum.TRANSACTION_CREATION_FAILED)) + } + + return reject(error) +} + +export class Wallet implements WalletInterface { + adapter: WalletAdapterInterface + + walletProvider: EIP1193Provider + + networkProvider: Provider + + /** + * @param {WalletAdapterInterface} adapter + * @param {Provider} provider + */ + constructor(adapter: WalletAdapterInterface, provider?: Provider) { + this.adapter = adapter + this.networkProvider = provider ?? Provider.instance + } + + /** + * @param {{ method: string; params?: any[] | object }} payload + * @returns {Promise} + */ + async request(payload: { method: string; params?: any[] | object }): Promise { + const res = await this.walletProvider.request(payload) + if (res?.error !== undefined) { + const error = res.error as { + code: number + message: string + } + if (error.code === -32000) { + throw new Error(ErrorTypeEnum.RPC_TIMEOUT) + } + throw new Error(error.message) + } + return res + } + + /** + * @returns {string} + */ + getId(): string { + return this.adapter.id + } + + /** + * @returns {string} + */ + getName(): string { + return this.adapter.name + } + + /** + * @returns {string} + */ + getIcon(): string { + return this.adapter.icon + } + + /** + * @returns {WalletPlatformEnum[]} + */ + getPlatforms(): WalletPlatformEnum[] { + return this.adapter.platforms + } + + /** + * @returns {string} + */ + getDownloadLink(): string | undefined { + return this.adapter.downloadLink + } + + /** + * @param {string} url + * @param {object} ops + * @returns {string} + */ + createDeepLink(url: string, ops?: object): string | null { + if (this.adapter.createDeepLink === undefined) { + return null + } + + return this.adapter.createDeepLink(url, ops) + } + + /** + * @param {ProviderInterface} provider + * @param {Object | WalletConnectOps} ops + * @returns {Promise} + */ + async connect(provider?: ProviderInterface, ops?: object | WalletConnectOps): Promise { + return await new Promise((resolve, reject) => { + this.adapter + .connect(provider, ops) + .then(async (provider) => { + this.walletProvider = provider as EIP1193Provider + + const chainId = await this.getChainId() + + if (this.networkProvider.network.id !== chainId) { + reject(ErrorTypeEnum.UNACCEPTED_CHAIN) + return + } + + resolve(await this.getAddress()) + }) + .catch((error) => { + const customReject = (error: any): void => { + if (error.message === ErrorTypeEnum.WALLET_REQUEST_REJECTED) { + reject(new Error(ErrorTypeEnum.WALLET_CONNECT_REJECTED)) + } else { + reject(error) + } + } + rejectMap(error, customReject) + }) + }) + } + + /** + * @returns {boolean} + */ + async isDetected(): Promise { + return await this.adapter.isDetected() + } + + /** + * @returns {boolean} + */ + async isConnected(): Promise { + return await this.adapter.isConnected() + } + + /** + * @returns {Promise} + */ + async getChainId(): Promise { + const chainId = await this.request({ method: 'eth_chainId' }) + return typeof chainId === 'number' ? chainId : parseInt(chainId as string, 16) + } + + /** + * @returns {Promise} + */ + async getAddress(): Promise { + return (await this.walletProvider.request({ method: 'eth_accounts' }))[0] + } + + /** + * @param {string} message + */ + async signMessage(message: string): Promise { + const address = await this.getAddress() + return await new Promise((resolve, reject) => { + this.walletProvider + .request({ + method: 'personal_sign', + params: [message, address] + }) + .then((signature: string) => { + resolve(signature) + }) + .catch((error) => { + rejectMap(error, reject) + }) + }) + } + + /** + * @param {TransactionSignerInterface} transactionSigner + * @returns {Promise} + */ + async sendTransaction(transactionSigner: TransactionSignerInterface): Promise { + return await new Promise((resolve, reject) => { + const data = transactionSigner.getRawData() + data.gas = toHex(data.gasLimit as number) + delete data.chainId + delete data.nonce + delete data.gasLimit + delete data.gasPrice + this.walletProvider + .request({ + method: 'eth_sendTransaction', + params: [data] + }) + .then((txHash: string) => { + resolve(txHash) + }) + .catch((error) => { + rejectMap(error, reject) + }) + }) + } + + /** + * @param {string} eventName + * @param {Function} callback + * @returns {void} + */ + on(eventName: string, callback: (...args: any[]) => void): void { + this.walletProvider.on(eventName, callback) + } +} diff --git a/packages/networks/evm-chains/src/browser/adapters/BitgetWallet.ts b/packages/networks/evm-chains/src/browser/adapters/BitgetWallet.ts new file mode 100644 index 0000000..b3eaa39 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/BitgetWallet.ts @@ -0,0 +1,46 @@ +import icons from './icons.ts' +import { switcher } from './switcher.ts' +import type { EIP1193Provider } from './EIP6963.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import type { WalletAdapterInterface, ProviderInterface } from '@multiplechain/types' + +const BitgetWallet: WalletAdapterInterface = { + id: 'bitgetwallet', + name: 'BitgetWallet', + icon: icons.bitgetWallet, + provider: window?.bitkeep?.ethereum, + downloadLink: 'https://web3.bitget.com/en/wallet-download?type=3', + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + createDeepLink: (url: string): string => `https://bkcode.vip?action=dapp&url=${url}`, + isDetected: () => Boolean(window?.bitkeep?.ethereum), + isConnected: async () => { + return Boolean( + (await window?.bitkeep?.ethereum?.request({ method: 'eth_accounts' })).length + ) + }, + connect: async (provider?: ProviderInterface): Promise => { + return await new Promise((resolve, reject) => { + const bitget = window?.bitkeep?.ethereum + try { + bitget + ?.request({ method: 'eth_requestAccounts' }) + .then(() => { + switcher(bitget, provider) + .then(() => { + resolve(bitget) + }) + .catch((error: any) => { + reject(error) + }) + }) + .catch((error: any) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default BitgetWallet diff --git a/packages/networks/evm-chains/src/browser/adapters/EIP6963.ts b/packages/networks/evm-chains/src/browser/adapters/EIP6963.ts new file mode 100644 index 0000000..861bbcd --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/EIP6963.ts @@ -0,0 +1,25 @@ +export interface EIP1193Provider { + request: (payload: { method: string; params?: any[] | object }) => Promise + on: (eventName: string, callback: (...args: any[]) => void) => void +} + +export interface EIP6963ProviderInfo { + uuid: string + name: string + icon: string + rdns?: string +} + +export interface EIP6963ProviderDetail { + info: EIP6963ProviderInfo + provider: EIP1193Provider +} + +export interface EVMProviderDetected extends EIP6963ProviderDetail { + accounts: string[] + request?: EIP1193Provider['request'] +} + +export interface EIP6963AnnounceProviderEvent extends Event { + detail: EIP6963ProviderDetail +} diff --git a/packages/networks/evm-chains/src/browser/adapters/MetaMask.ts b/packages/networks/evm-chains/src/browser/adapters/MetaMask.ts new file mode 100644 index 0000000..c57ed56 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/MetaMask.ts @@ -0,0 +1,44 @@ +import icons from './icons.ts' +import { switcher } from './switcher.ts' +import type { EIP1193Provider } from './EIP6963.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import type { WalletAdapterInterface, ProviderInterface } from '@multiplechain/types' + +const MetaMask: WalletAdapterInterface = { + id: 'metamask', + name: 'MetaMask', + icon: icons.metaMask, + provider: window.ethereum, + downloadLink: 'https://metamask.io/download/', + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + isDetected: () => Boolean(window?.ethereum?.isMetaMask), + createDeepLink: (url: string): string => `https://metamask.app.link/dapp/${url}`, + isConnected: async () => { + return Boolean((await window?.ethereum?.request({ method: 'eth_accounts' })).length) + }, + connect: async (provider?: ProviderInterface): Promise => { + const metamask = window.ethereum + return await new Promise((resolve, reject) => { + try { + metamask + ?.request({ method: 'eth_requestAccounts' }) + .then(() => { + switcher(metamask, provider) + .then(() => { + resolve(metamask) + }) + .catch((error: any) => { + reject(error) + }) + }) + .catch((error: any) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default MetaMask diff --git a/packages/networks/evm-chains/src/browser/adapters/OkxWallet.ts b/packages/networks/evm-chains/src/browser/adapters/OkxWallet.ts new file mode 100644 index 0000000..484b9e3 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/OkxWallet.ts @@ -0,0 +1,44 @@ +import icons from './icons.ts' +import { switcher } from './switcher.ts' +import type { EIP1193Provider } from './EIP6963.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import type { WalletAdapterInterface, ProviderInterface } from '@multiplechain/types' + +const OkxWallet: WalletAdapterInterface = { + id: 'okxwallet', + name: 'OkxWallet', + icon: icons.okxWallet, + provider: window?.okxwallet, + downloadLink: 'https://www.okx.com/download', + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + createDeepLink: (url: string): string => `okx://wallet/dapp/details?dappUrl=${url}`, + isDetected: () => Boolean(window?.okxwallet), + isConnected: async () => { + return Boolean((await window?.okxwallet?.request({ method: 'eth_accounts' })).length) + }, + connect: async (provider?: ProviderInterface): Promise => { + return await new Promise((resolve, reject) => { + const okx = window?.okxwallet + try { + okx + ?.request({ method: 'eth_requestAccounts' }) + .then(() => { + switcher(okx, provider) + .then(() => { + resolve(okx) + }) + .catch((error: any) => { + reject(error) + }) + }) + .catch((error: any) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default OkxWallet diff --git a/packages/networks/evm-chains/src/browser/adapters/Phantom.ts b/packages/networks/evm-chains/src/browser/adapters/Phantom.ts new file mode 100644 index 0000000..21d0d4c --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/Phantom.ts @@ -0,0 +1,39 @@ +import icons from './icons.ts' +import type { EIP1193Provider } from './EIP6963.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import type { WalletAdapterInterface } from '@multiplechain/types' + +const Phantom: WalletAdapterInterface = { + id: 'phantom', + name: 'Phantom', + icon: icons.phantom, + provider: window?.phantom?.ethereum, + downloadLink: 'https://phantom.app/', + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + isDetected: () => Boolean(window?.phantom?.ethereum), + createDeepLink: (url: string): string => `https://phantom.app/ul/browse/${url}?ref=${url}`, + isConnected: async () => { + return Boolean( + (await window?.phantom?.ethereum?.request({ method: 'eth_accounts' })).length + ) + }, + connect: async (): Promise => { + return await new Promise((resolve, reject) => { + const phantom = window?.phantom?.ethereum + try { + phantom + ?.request({ method: 'eth_requestAccounts' }) + .then(() => { + resolve(phantom) + }) + .catch((error: any) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default Phantom diff --git a/packages/networks/evm-chains/src/browser/adapters/TrustWallet.ts b/packages/networks/evm-chains/src/browser/adapters/TrustWallet.ts new file mode 100644 index 0000000..52960c6 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/TrustWallet.ts @@ -0,0 +1,54 @@ +import icons from './icons.ts' +import { switcher } from './switcher.ts' +import type { EIP1193Provider } from './EIP6963.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import type { WalletAdapterInterface, ProviderInterface } from '@multiplechain/types' + +// eslint-disable-next-line +const trustWalletProvider = window?.ethereum?.isTrust ? window.ethereum : window.trustwallet + +const TrustWallet: WalletAdapterInterface = { + id: 'trustwallet', + name: 'TrustWallet', + icon: icons.trustWallet, + provider: trustWalletProvider, + downloadLink: 'https://trustwallet.com/download', + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + isDetected: () => Boolean(window?.ethereum?.isTrust ?? window?.trustwallet), + isConnected: async () => { + return Boolean((await trustWalletProvider?.request({ method: 'eth_accounts' })).length) + }, + connect: async (provider?: ProviderInterface): Promise => { + return await new Promise((resolve, reject) => { + try { + trustWalletProvider + ?.request({ method: 'eth_requestAccounts' }) + .then(() => { + // because mobile wallet doesn't support testnets + if ( + window?.ethereum?.isTrust !== undefined && + provider?.isTestnet() === true + ) { + resolve(trustWalletProvider) + return + } + + switcher(trustWalletProvider, provider) + .then(() => { + resolve(trustWalletProvider) + }) + .catch((error: any) => { + reject(error) + }) + }) + .catch((error: any) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default TrustWallet diff --git a/packages/networks/evm-chains/src/browser/adapters/WalletConnect.ts b/packages/networks/evm-chains/src/browser/adapters/WalletConnect.ts new file mode 100644 index 0000000..97f5708 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/WalletConnect.ts @@ -0,0 +1,96 @@ +import icons from './icons.ts' +import type { EIP1193Provider } from './EIP6963.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import { EthereumProvider } from '@walletconnect/ethereum-provider' +import type { EvmNetworkConfigInterface } from '../../services/Provider.ts' +import type { + WalletConnectOps, + WalletAdapterInterface, + ProviderInterface +} from '@multiplechain/types' + +let isConnected = false + +const WalletConnect: WalletAdapterInterface = { + id: 'walletconnect', + name: 'WalletConnect', + icon: icons.walletConnect, + platforms: [WalletPlatformEnum.UNIVERSAL], + isDetected: () => true, + isConnected: () => isConnected, + disconnect: () => { + isConnected = false + indexedDB.deleteDatabase('WALLET_CONNECT_V2_INDEXED_DB') + }, + connect: async ( + provider?: ProviderInterface, + _ops?: WalletConnectOps | object + ): Promise => { + const ops = _ops as WalletConnectOps + + if (provider === undefined) { + throw new Error('Provider is required') + } + + if (ops === undefined) { + throw new Error('Ops is required') + } + + if (ops.projectId === undefined) { + throw new Error('Project ID is required') + } + + const rpcIdMapping = {} + const network = provider.network as EvmNetworkConfigInterface + // @ts-expect-error allow number index + rpcIdMapping[network.id] = network.rpcUrl + + const connector = await EthereumProvider.init({ + projectId: ops.projectId, + relayUrl: 'wss://relay.walletconnect.com', + optionalChains: [network.id], + rpcMap: rpcIdMapping, + chains: [network.id], + showQrModal: true, + qrModalOptions: { + themeMode: ops.themeMode, + themeVariables: { + '--wcm-z-index': '999999999999' + }, + explorerExcludedWalletIds: 'ALL', + explorerRecommendedWalletIds: [ + 'c57ca95b47569778a828d19178114f4db188b89b763c899ba0be274e97267d96', + '4622a2b2d6af1c9844944291e5e7351a6aa24cd7b23099efac1b2fd875da31a0', + '1ae92b26df02f0abca6304df07debccd18262fdf5fe82daa81593582dac9a369', + '0b415a746fb9ee99cce155c2ceca0c6f6061b1dbca2d722b3ba16381d0562150', + '971e689d0a5be527bac79629b4ee9b925e82208e5168b733496a09c0faed0709', + 'c03dfee351b6fcc421b4494ea33b9d4b92a984f87aa76d1663bb28705e95034a', + 'ecc4036f814562b41a5268adc86270fba1365471402006302e70169465b7ac18', + 'ef333840daf915aafdc4a004525502d6d49d77bd9c65e0642dbaefb3c2893bef', + 'bc949c5d968ae81310268bf9193f9c9fb7bb4e1283e1284af8f2bd4992535fd6', + '74f8092562bd79675e276d8b2062a83601a4106d30202f2d509195e30e19673d', + 'afbd95522f4041c71dd4f1a065f971fd32372865b416f95a0b1db759ae33f2a7', + '20459438007b75f4f4acb98bf29aa3b800550309646d375da5fd4aac6c2a2c66', + '8837dd9413b1d9b585ee937d27a816590248386d9dbf59f5cd3422dbbb65683e', + 'c286eebc742a537cd1d6818363e9dc53b21759a1e8e5d9b263d0c03ec7703576', + '38f5d18bd8522c244bdd70cb4a68e0e718865155811c043f052fb9f1c51de662', + '85db431492aa2e8672e93f4ea7acf10c88b97b867b0d373107af63dc4880f041' + ] + } + }) + + return await new Promise((resolve, reject) => { + connector + .enable() + .then(() => { + isConnected = true + resolve(connector as EIP1193Provider) + }) + .catch((error) => { + reject(error) + }) + }) + } +} + +export default WalletConnect diff --git a/packages/networks/evm-chains/src/browser/adapters/XdefiWallet.ts b/packages/networks/evm-chains/src/browser/adapters/XdefiWallet.ts new file mode 100644 index 0000000..8aabf4d --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/XdefiWallet.ts @@ -0,0 +1,43 @@ +import icons from './icons.ts' +import { switcher } from './switcher.ts' +import type { EIP1193Provider } from './EIP6963.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import type { WalletAdapterInterface, ProviderInterface } from '@multiplechain/types' + +const XdefiWallet: WalletAdapterInterface = { + id: 'xdefiwallet', + name: 'XdefiWallet', + icon: icons.xdefiWallet, + provider: window?.xfi?.ethereum, + downloadLink: 'https://www.xdefi.io/', + platforms: [WalletPlatformEnum.BROWSER], + isDetected: () => Boolean(window?.xfi?.ethereum), + isConnected: async () => { + return Boolean((await window?.xfi?.ethereum?.request({ method: 'eth_accounts' })).length) + }, + connect: async (provider?: ProviderInterface): Promise => { + return await new Promise((resolve, reject) => { + const xfi = window?.xfi?.ethereum + try { + xfi + ?.request({ method: 'eth_requestAccounts' }) + .then(() => { + switcher(xfi, provider) + .then(() => { + resolve(xfi) + }) + .catch((error: any) => { + reject(error) + }) + }) + .catch((error: any) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } +} + +export default XdefiWallet diff --git a/packages/networks/evm-chains/src/browser/adapters/icons.ts b/packages/networks/evm-chains/src/browser/adapters/icons.ts new file mode 100644 index 0000000..fb3eb20 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/icons.ts @@ -0,0 +1,18 @@ +export default { + metaMask: + 'data:image/svg+xml,%3Csvg%20fill%3D%22none%22%20height%3D%2233%22%20viewBox%3D%220%200%2035%2033%22%20width%3D%2235%22%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%3E%3Cg%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%20stroke-width%3D%22.25%22%3E%3Cpath%20d%3D%22m32.9582%201-13.1341%209.7183%202.4424-5.72731z%22%20fill%3D%22%23e17726%22%20stroke%3D%22%23e17726%22%2F%3E%3Cg%20fill%3D%22%23e27625%22%20stroke%3D%22%23e27625%22%3E%3Cpath%20d%3D%22m2.66296%201%2013.01714%209.809-2.3254-5.81802z%22%2F%3E%3Cpath%20d%3D%22m28.2295%2023.5335-3.4947%205.3386%207.4829%202.0603%202.1436-7.2823z%22%2F%3E%3Cpath%20d%3D%22m1.27281%2023.6501%202.13055%207.2823%207.46994-2.0603-3.48166-5.3386z%22%2F%3E%3Cpath%20d%3D%22m10.4706%2014.5149-2.0786%203.1358%207.405.3369-.2469-7.969z%22%2F%3E%3Cpath%20d%3D%22m25.1505%2014.5149-5.1575-4.58704-.1688%208.05974%207.4049-.3369z%22%2F%3E%3Cpath%20d%3D%22m10.8733%2028.8721%204.4819-2.1639-3.8583-3.0062z%22%2F%3E%3Cpath%20d%3D%22m20.2659%2026.7082%204.4689%202.1639-.6105-5.1701z%22%2F%3E%3C%2Fg%3E%3Cpath%20d%3D%22m24.7348%2028.8721-4.469-2.1639.3638%202.9025-.039%201.231z%22%20fill%3D%22%23d5bfb2%22%20stroke%3D%22%23d5bfb2%22%2F%3E%3Cpath%20d%3D%22m10.8732%2028.8721%204.1572%201.9696-.026-1.231.3508-2.9025z%22%20fill%3D%22%23d5bfb2%22%20stroke%3D%22%23d5bfb2%22%2F%3E%3Cpath%20d%3D%22m15.1084%2021.7842-3.7155-1.0884%202.6243-1.2051z%22%20fill%3D%22%23233447%22%20stroke%3D%22%23233447%22%2F%3E%3Cpath%20d%3D%22m20.5126%2021.7842%201.0913-2.2935%202.6372%201.2051z%22%20fill%3D%22%23233447%22%20stroke%3D%22%23233447%22%2F%3E%3Cpath%20d%3D%22m10.8733%2028.8721.6495-5.3386-4.13117.1167z%22%20fill%3D%22%23cc6228%22%20stroke%3D%22%23cc6228%22%2F%3E%3Cpath%20d%3D%22m24.0982%2023.5335.6366%205.3386%203.4946-5.2219z%22%20fill%3D%22%23cc6228%22%20stroke%3D%22%23cc6228%22%2F%3E%3Cpath%20d%3D%22m27.2291%2017.6507-7.405.3369.6885%203.7966%201.0913-2.2935%202.6372%201.2051z%22%20fill%3D%22%23cc6228%22%20stroke%3D%22%23cc6228%22%2F%3E%3Cpath%20d%3D%22m11.3929%2020.6958%202.6242-1.2051%201.0913%202.2935.6885-3.7966-7.40495-.3369z%22%20fill%3D%22%23cc6228%22%20stroke%3D%22%23cc6228%22%2F%3E%3Cpath%20d%3D%22m8.392%2017.6507%203.1049%206.0513-.1039-3.0062z%22%20fill%3D%22%23e27525%22%20stroke%3D%22%23e27525%22%2F%3E%3Cpath%20d%3D%22m24.2412%2020.6958-.1169%203.0062%203.1049-6.0513z%22%20fill%3D%22%23e27525%22%20stroke%3D%22%23e27525%22%2F%3E%3Cpath%20d%3D%22m15.797%2017.9876-.6886%203.7967.8704%204.4833.1949-5.9087z%22%20fill%3D%22%23e27525%22%20stroke%3D%22%23e27525%22%2F%3E%3Cpath%20d%3D%22m19.8242%2017.9876-.3638%202.3584.1819%205.9216.8704-4.4833z%22%20fill%3D%22%23e27525%22%20stroke%3D%22%23e27525%22%2F%3E%3Cpath%20d%3D%22m20.5127%2021.7842-.8704%204.4834.6236.4406%203.8584-3.0062.1169-3.0062z%22%20fill%3D%22%23f5841f%22%20stroke%3D%22%23f5841f%22%2F%3E%3Cpath%20d%3D%22m11.3929%2020.6958.104%203.0062%203.8583%203.0062.6236-.4406-.8704-4.4834z%22%20fill%3D%22%23f5841f%22%20stroke%3D%22%23f5841f%22%2F%3E%3Cpath%20d%3D%22m20.5906%2030.8417.039-1.231-.3378-.2851h-4.9626l-.3248.2851.026%201.231-4.1572-1.9696%201.4551%201.1921%202.9489%202.0344h5.0536l2.962-2.0344%201.442-1.1921z%22%20fill%3D%22%23c0ac9d%22%20stroke%3D%22%23c0ac9d%22%2F%3E%3Cpath%20d%3D%22m20.2659%2026.7082-.6236-.4406h-3.6635l-.6236.4406-.3508%202.9025.3248-.2851h4.9626l.3378.2851z%22%20fill%3D%22%23161616%22%20stroke%3D%22%23161616%22%2F%3E%3Cpath%20d%3D%22m33.5168%2011.3532%201.1043-5.36447-1.6629-4.98873-12.6923%209.3944%204.8846%204.1205%206.8983%202.0085%201.52-1.7752-.6626-.4795%201.0523-.9588-.8054-.622%201.0523-.8034z%22%20fill%3D%22%23763e1a%22%20stroke%3D%22%23763e1a%22%2F%3E%3Cpath%20d%3D%22m1%205.98873%201.11724%205.36447-.71451.5313%201.06527.8034-.80545.622%201.05228.9588-.66255.4795%201.51997%201.7752%206.89835-2.0085%204.8846-4.1205-12.69233-9.3944z%22%20fill%3D%22%23763e1a%22%20stroke%3D%22%23763e1a%22%2F%3E%3Cpath%20d%3D%22m32.0489%2016.5234-6.8983-2.0085%202.0786%203.1358-3.1049%206.0513%204.1052-.0519h6.1318z%22%20fill%3D%22%23f5841f%22%20stroke%3D%22%23f5841f%22%2F%3E%3Cpath%20d%3D%22m10.4705%2014.5149-6.89828%202.0085-2.29944%207.1267h6.11883l4.10519.0519-3.10487-6.0513z%22%20fill%3D%22%23f5841f%22%20stroke%3D%22%23f5841f%22%2F%3E%3Cpath%20d%3D%22m19.8241%2017.9876.4417-7.5932%202.0007-5.4034h-8.9119l2.0006%205.4034.4417%207.5932.1689%202.3842.013%205.8958h3.6635l.013-5.8958z%22%20fill%3D%22%23f5841f%22%20stroke%3D%22%23f5841f%22%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E', + walletConnect: + 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIGJhc2VQcm9maWxlPSJiYXNpYyIgaWQ9IkxheWVyXzEiCgkgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluayIgeD0iMHB4IiB5PSIwcHgiIHZpZXdCb3g9IjAgMCAzODcuNiAyMzcuNiIKCSB4bWw6c3BhY2U9InByZXNlcnZlIj4KPHBhdGggaWQ9IldhbGxldENvbm5lY3RfMDAwMDAwNzM3MDMwNjM0MzgyMjA2NDI3MzAwMDAwMDI5MTc3MTc1NTIyMzY0NzI0OTZfIiBmaWxsPSIjM0I5OUZDIiBkPSJNNzkuNCw0Ni40CgljNjMuMi02MS45LDE2NS43LTYxLjksMjI4LjksMGw3LjYsNy40YzMuMiwzLjEsMy4yLDguMSwwLDExLjJsLTI2LDI1LjVjLTEuNiwxLjUtNC4xLDEuNS01LjcsMGwtMTAuNS0xMC4zCgljLTQ0LjEtNDMuMi0xMTUuNi00My4yLTE1OS43LDBsLTExLjIsMTFjLTEuNiwxLjUtNC4xLDEuNS01LjcsMEw3MSw2NS44Yy0zLjItMy4xLTMuMi04LjEsMC0xMS4yTDc5LjQsNDYuNHogTTM2Mi4xLDk5LjFsMjMuMiwyMi43CgljMy4yLDMuMSwzLjIsOC4xLDAsMTEuMkwyODAuOCwyMzUuM2MtMy4yLDMuMS04LjMsMy4xLTExLjQsMGMwLDAsMCwwLDAsMGwtNzQuMS03Mi42Yy0wLjgtMC44LTIuMS0wLjgtMi45LDBjMCwwLDAsMCwwLDAKCWwtNzQuMSw3Mi42Yy0zLjIsMy4xLTguMywzLjEtMTEuNCwwYzAsMCwwLDAsMCwwTDIuNCwxMzNjLTMuMi0zLjEtMy4yLTguMSwwLTExLjJsMjMuMi0yMi43YzMuMi0zLjEsOC4zLTMuMSwxMS40LDBsNzQuMSw3Mi42CgljMC44LDAuOCwyLjEsMC44LDIuOSwwYzAsMCwwLDAsMCwwbDc0LjEtNzIuNmMzLjItMy4xLDguMy0zLjEsMTEuNCwwYzAsMCwwLDAsMCwwbDc0LjEsNzIuNmMwLjgsMC44LDIuMSwwLjgsMi45LDBsNzQuMS03Mi42CglDMzUzLjgsOTYsMzU4LjksOTYsMzYyLjEsOTkuMXoiLz4KPC9zdmc+', + web3modal: + 'data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIKIHdpZHRoPSI0MDAuMDAwMDAwcHQiIGhlaWdodD0iNDAwLjAwMDAwMHB0IiB2aWV3Qm94PSIwIDAgNDAwLjAwMDAwMCA0MDAuMDAwMDAwIgogcHJlc2VydmVBc3BlY3RSYXRpbz0ieE1pZFlNaWQgbWVldCI+Cgo8ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgwLjAwMDAwMCw0MDAuMDAwMDAwKSBzY2FsZSgwLjEwMDAwMCwtMC4xMDAwMDApIgpmaWxsPSIjMDAwMDAwIiBzdHJva2U9Im5vbmUiPgo8cGF0aCBkPSJNMCAyMDAwIGwwIC0yMDAwIDIwMDAgMCAyMDAwIDAgMCAyMDAwIDAgMjAwMCAtMjAwMCAwIC0yMDAwIDAgMAotMjAwMHogbTIyNjQgNzM2IGMxMjQgLTMyIDI2MSAtOTggMzYzIC0xNzUgOTEgLTY5IDE3MyAtMTUzIDE3MyAtMTc4IDAgLTE3Ci0xODcgLTIwMiAtMjA1IC0yMDMgLTYgMCAtMzEgMjEgLTU1IDQ2IC0yMjcgMjM0IC01NjkgMjk5IC04NTcgMTY0IC03OSAtMzYKLTEzMSAtNzMgLTIxMyAtMTQ5IC0zNiAtMzMgLTcyIC02MCAtODAgLTYxIC0yMCAwIC0yMDAgMTgxIC0yMDAgMjAyIDAgMjQgNDkKNzggMTM2IDE0OCAxMzYgMTA5IDI4MSAxNzkgNDQxIDIxNSAxMDYgMjMgMTE5IDI0IDI2MyAyMCAxMDQgLTMgMTU4IC0xMCAyMzQKLTI5eiBtLTEyODQgLTYwMyBjMTQgLTkgMTMwIC0xMjAgMjU4IC0yNDYgbDIzMyAtMjMxIDU3IDU1IGMzMSAyOSAxNDUgMTQxCjI1MyAyNDYgMTEwIDEwOSAyMDMgMTkzIDIxMyAxOTMgMjAgMCAzOSAtMTggNTIyIC00OTAgMyAtMiA3OCA2OCAxNjcgMTU2IDI3MAoyNjYgMzQ0IDMzNCAzNjIgMzM0IDEwIDAgNTcgLTM5IDEwNiAtODcgNjcgLTY1IDg5IC05MyA4OSAtMTEzIDAgLTIxIC02NiAtOTAKLTM0MSAtMzYwIC0xODggLTE4NCAtMzUwIC0zMzkgLTM2MCAtMzQ0IC0xMSAtNSAtMjcgLTUgLTM4IDAgLTExIDUgLTEyOCAxMTYKLTI2MSAyNDcgLTEzMyAxMzEgLTI0NSAyMzYgLTI0OCAyMzIgLTEzNiAtMTM4IC00OTAgLTQ3MyAtNTA4IC00NzkgLTI4IC0xMQotMTYgLTIyIC00NTEgNDA2IC0yMDMgMTk5IC0yODMgMjg0IC0yODMgMzAwIDAgMjggMTcxIDE5OCAyMDAgMTk4IDMgMCAxNyAtNwozMCAtMTd6Ii8+CjwvZz4KPC9zdmc+Cg==', + phantom: + 'data:image/png;base64,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', + trustWallet: + 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTgiIGhlaWdodD0iNjUiIHZpZXdCb3g9IjAgMCA1OCA2NSIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgOS4zODk0OUwyOC44OTA3IDBWNjUuMDA0MkM4LjI1NDUgNTYuMzM2OSAwIDM5LjcyNDggMCAzMC4zMzUzVjkuMzg5NDlaIiBmaWxsPSIjMDUwMEZGIi8+CjxwYXRoIGQ9Ik01Ny43ODIyIDkuMzg5NDlMMjguODkxNSAwVjY1LjAwNDJDNDkuNTI3NyA1Ni4zMzY5IDU3Ljc4MjIgMzkuNzI0OCA1Ny43ODIyIDMwLjMzNTNWOS4zODk0OVoiIGZpbGw9InVybCgjcGFpbnQwX2xpbmVhcl8yMjAxXzY5NDIpIi8+CjxkZWZzPgo8bGluZWFyR3JhZGllbnQgaWQ9InBhaW50MF9saW5lYXJfMjIwMV82OTQyIiB4MT0iNTEuMzYxNSIgeTE9Ii00LjE1MjkzIiB4Mj0iMjkuNTM4NCIgeTI9IjY0LjUxNDciIGdyYWRpZW50VW5pdHM9InVzZXJTcGFjZU9uVXNlIj4KPHN0b3Agb2Zmc2V0PSIwLjAyMTEyIiBzdG9wLWNvbG9yPSIjMDAwMEZGIi8+CjxzdG9wIG9mZnNldD0iMC4wNzYyNDIzIiBzdG9wLWNvbG9yPSIjMDA5NEZGIi8+CjxzdG9wIG9mZnNldD0iMC4xNjMwODkiIHN0b3AtY29sb3I9IiM0OEZGOTEiLz4KPHN0b3Agb2Zmc2V0PSIwLjQyMDA0OSIgc3RvcC1jb2xvcj0iIzAwOTRGRiIvPgo8c3RvcCBvZmZzZXQ9IjAuNjgyODg2IiBzdG9wLWNvbG9yPSIjMDAzOEZGIi8+CjxzdG9wIG9mZnNldD0iMC45MDI0NjUiIHN0b3AtY29sb3I9IiMwNTAwRkYiLz4KPC9saW5lYXJHcmFkaWVudD4KPC9kZWZzPgo8L3N2Zz4K', + bitgetWallet: + 'data:image/png;base64,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', + okxWallet: + 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAJDSURBVHgB7Zq9jtpAEMfHlhEgQLiioXEkoAGECwoKxMcTRHmC5E3IoyRPkPAEkI7unJYmTgEFTYwA8a3NTKScLnCHN6c9r1e3P2llWQy7M/s1Gv1twCP0ej37dDq9x+Zut1t3t9vZjDEHIiSRSPg4ZpDL5fxkMvn1cDh8m0wmfugfO53OoFQq/crn8wxfY9EymQyrVCqMfHvScZx1p9ls3pFxXBy/bKlUipGPrVbLuQqAfsCliq3zl0H84zwtjQrOw4Mt1W63P5LvBm2d+Xz+YzqdgkqUy+WgWCy+Mc/nc282m4FqLBYL+3g8fjDxenq72WxANZbLJeA13zDX67UDioL5ybXwafMYu64Ltn3bdDweQ5R97fd7GyhBQMipx4POeEDHIu2LfDdBIGGz+hJ9CQ1ABjoA2egAZPM6AgiCAEQhsi/C4jHyPA/6/f5NG3Ks2+3CYDC4aTccDrn6ojG54MnEvG00GoVmWLIRNZ7wTCwDHYBsdACy0QHIhiuRETxlICWpMMhGZHmqS8qH6JLyGegAZKMDkI0uKf8X4SWlaZo+Pp1bRrwlJU8ZKLIvUjKh0WiQ3sRUbNVq9c5Ebew7KEo2m/1p4jJ4qAmDaqDQBzj5XyiAT4VCQezJigAU+IDU+z8vJFnGWeC+bKQV/5VZ71FV6L7PA3gg3tXrdQ+DgLhC+75Wq3no69P3MC0NFQpx2lL04Ql9gHK1bRDjsSBIvScBnDTk1WrlGIZBorIDEYJj+rhdgnQ67VmWRe0zlplXl81vcyEt0rSoYDUAAAAASUVORK5CYII=', + xdefiWallet: + 'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgdmlld0JveD0iMCAwIDUxMiA1MTIiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxnIGNsaXAtcGF0aD0idXJsKCNjbGlwMF8yMTkxXzQyOTApIj4KPHJlY3Qgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHJ4PSIxMDQiIGZpbGw9IiMzMzVERTUiLz4KPHBhdGggZD0iTTQ2My40MzggMjQxLjI0N0M0NjAuNzY1IDIwNS4xMzUgNDQ4LjU4IDE3MC4zMzggNDI4LjA4NyAxNDAuMjcxQzQwNy41OTkgMTEwLjIwOSAzNzkuNTA5IDg1LjkxODIgMzQ2LjU3OSA2OS43OTZDMzEzLjY1MyA1My42NzggMjc3LjAzMiA0Ni4yODA0IDI0MC4zMiA0OC4zMzYzQzIwMy42MDUgNTAuMzkyMSAxNjguMDY5IDYxLjgyNTUgMTM3LjIxMiA4MS41MjAxQzEwNi4zNTQgMTAxLjIxIDgxLjIzOTQgMTI4LjQ4IDY0LjMzODYgMTYwLjYzNkw2My41MzYgMTYyLjI1N0M1OC4xOTcxIDE3My4xMjYgNTQuNTg3OCAxODQuNzQ1IDUyLjg0MTEgMTk2LjY5N0M0Ny44NDU1IDIzMi4wMjEgNTUuNTkyIDI2My40NiA3NS44Mjc1IDI4Ny42NjdDOTcuOTU5OSAzMTQuMTM2IDEzMy45OTMgMzI5Ljg3OSAxNzcuMjE1IDMzMS45NDdDMjI5LjgzMiAzMzQuNTU1IDI4Mi4xNDggMzIwLjQzNCAzMTkuMjc1IDI5NC40NThMMzQxLjI4NyAzMDcuMzUzQzMyMC4yNTggMzI1LjI5MSAyNzEuNjM3IDM1Ny41OTQgMTkxLjExMiAzNjIuMDA5QzEwMC43MTkgMzY2LjkzIDYzLjA0MjUgMzM4LjAwMSA2Mi42OTA1IDMzNy43MDZMNTYuMzUxNyAzNDUuNDAzTDQ4IDM1NS4yNzNDNDkuNjAwOCAzNTYuNiA4NS43Mjg1IDM4NS4zMzUgMTcwLjU3NiAzODUuMzM1QzE3Ny41MiAzODUuMzM1IDE4NC44MTYgMzg1LjMzNSAxOTIuNDEyIDM4NC43NDZDMjg5Ljg3MyAzNzkuMzkxIDM0My40NzYgMzM3LjU3NSAzNjIuMjMxIDMxOS42MjlMMzgwLjY0MiAzMzAuNjM3QzM2OC4yNjEgMzQ2LjY1OCAzNTMuMDI1IDM2MC4zMzMgMzM1LjY3IDM3MC45ODJDMjc0LjUwNCA0MDkuODQ5IDE5Ni43MDggNDE0Ljg2NyAxNDIuMjQyIDQxMi4xNjJMMTQxLjA5NiA0MzQuODMxQzE1MC4yNDIgNDM1LjI3MyAxNTkuMDM1IDQzNS40NzEgMTY3LjU4IDQzNS40NzFDMzIxLjA0OCA0MzUuNDcxIDM4My4xMzIgMzY2LjcxOSA0MDAuNTM5IDM0Mi4wNjJMNDE0LjkyNSAzNTAuNDg3QzQwMS4xMzUgMzczLjYwMyAzODIuMzkzIDM5My41NjcgMzU5LjkzMSA0MDguOTM5QzMzMy4wMzQgNDI3LjM0NSAzMDEuNzM1IDQzOC41MzggMjY5LjExNCA0NDEuNDE1TDI3MS4xMTQgNDY0QzMwNy43MzkgNDYwLjc4NiAzNDIuODg4IDQ0OC4yMzYgMzczLjA4OSA0MjcuNTgxQzQwMy4yOSA0MDYuOTI2IDQyNy41MDggMzc4Ljg4MSA0NDMuMzQ5IDM0Ni4yMDdDNDU5LjE4NSAzMTMuNTI5IDQ2Ni4xMTYgMjc3LjM1OCA0NjMuNDM4IDI0MS4yNDdaTTM3NC44MSAyNDQuNzM5QzM2NC42MjYgMjQ0LjczOSAzNTYuMzY4IDIzNi42MTMgMzU2LjM2OCAyMjYuNTg2QzM1Ni4zNjggMjE2LjU2IDM2NC42MjEgMjA4LjQzMyAzNzQuODEgMjA4LjQzM0MzODQuOTkgMjA4LjQzMyAzOTMuMjQ3IDIxNi41NiAzOTMuMjQ3IDIyNi41ODZDMzkzLjI0NyAyMzYuNjEzIDM4NC45OTQgMjQ0LjczOSAzNzQuODEgMjQ0LjczOVoiIGZpbGw9IiNFQ0VDRUMiLz4KPC9nPgo8ZGVmcz4KPGNsaXBQYXRoIGlkPSJjbGlwMF8yMTkxXzQyOTAiPgo8cmVjdCB3aWR0aD0iNTEyIiBoZWlnaHQ9IjUxMiIgZmlsbD0id2hpdGUiLz4KPC9jbGlwUGF0aD4KPC9kZWZzPgo8L3N2Zz4K' +} diff --git a/packages/networks/evm-chains/src/browser/adapters/index.ts b/packages/networks/evm-chains/src/browser/adapters/index.ts new file mode 100644 index 0000000..303bad6 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/index.ts @@ -0,0 +1,8 @@ +import './types.ts' // global types +export { default as Phantom } from './Phantom.ts' +export { default as MetaMask } from './MetaMask.ts' +export { default as OkxWallet } from './OkxWallet.ts' +export { default as XdefiWallet } from './XdefiWallet.ts' +export { default as TrustWallet } from './TrustWallet.ts' +export { default as BitgetWallet } from './BitgetWallet.ts' +export { default as WalletConnect } from './WalletConnect.ts' diff --git a/packages/networks/evm-chains/src/browser/adapters/switcher.ts b/packages/networks/evm-chains/src/browser/adapters/switcher.ts new file mode 100644 index 0000000..10861ed --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/switcher.ts @@ -0,0 +1,119 @@ +import networks from '../../services/Networks.ts' +import { ErrorTypeEnum, type ProviderInterface } from '@multiplechain/types' +import type { EvmNetworkConfigInterface } from '../../services/Provider.ts' + +export const switcher = async (wallet: any, provider?: ProviderInterface): Promise => { + const network = provider?.network as EvmNetworkConfigInterface + + const request = async (params: any): Promise => { + const res = await wallet.request(params) + if (res?.error !== undefined) { + const error = res.error as { + code: number + message: string + } + if (error.code === -32000) { + throw new Error(ErrorTypeEnum.RPC_TIMEOUT) + } + throw new Error(error.message) + } + + return res + } + + const addNetwork = async (network: EvmNetworkConfigInterface): Promise => { + return await new Promise((resolve, reject) => { + try { + request({ + method: 'wallet_addEthereumChain', + params: [ + { + chainId: network.hexId, + chainName: network.name, + rpcUrls: [network.rpcUrl], + nativeCurrency: network.nativeCurrency, + blockExplorerUrls: [network.explorerUrl] + } + ] + }) + .then(() => { + resolve(true) + }) + .catch((error) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } + + const changeNetwork = async (_network: EvmNetworkConfigInterface): Promise => { + return await new Promise((resolve, reject) => { + const network = networks.findById(_network.id) + if (network === undefined) { + resolve(true) + return + } + const chainId = `0x${network.id.toString(16)}` + request({ + method: 'wallet_switchEthereumChain', + params: [{ chainId }] + }) + .then(() => { + resolve(true) + }) + .catch((error) => { + if ( + error.code === 4902 || + String(error.message).includes('wallet_addEthereumChain') + ) { + addNetwork(network) + .then(() => { + resolve(true) + }) + .catch((error) => { + reject(error) + }) + } else { + reject(error) + } + }) + }) + } + + const getChainId = async (): Promise => { + return parseInt((await request({ method: 'eth_chainId' })) as string, 16) + } + + const maybeSwitch = async (): Promise => { + return await new Promise((resolve, reject) => { + if (network === undefined) { + resolve(true) + return + } + try { + const check = async (): Promise => { + if ((await getChainId()) !== network.id) { + changeNetwork(network) + .then(() => { + setTimeout(() => { + resolve(true) + }, 1000) + }) + .catch((error) => { + reject(error) + }) + } else { + resolve(true) + } + } + void check() + } catch (error) { + reject(error) + } + }) + } + + return await maybeSwitch() +} diff --git a/packages/networks/evm-chains/src/browser/adapters/types.ts b/packages/networks/evm-chains/src/browser/adapters/types.ts new file mode 100644 index 0000000..73629b4 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/adapters/types.ts @@ -0,0 +1,21 @@ +import type { EIP1193Provider } from './EIP6963.ts' + +declare global { + interface Window { + okxwallet?: EIP1193Provider + xfi?: { + ethereum?: EIP1193Provider + } + bitkeep?: { + ethereum?: EIP1193Provider + } + phantom?: { + ethereum?: EIP1193Provider + } + ethereum?: EIP1193Provider & { + isTrust?: boolean + isMetaMask?: boolean + } + trustwallet?: EIP1193Provider + } +} diff --git a/packages/networks/evm-chains/src/browser/index.ts b/packages/networks/evm-chains/src/browser/index.ts new file mode 100644 index 0000000..52eac57 --- /dev/null +++ b/packages/networks/evm-chains/src/browser/index.ts @@ -0,0 +1,94 @@ +import { Wallet } from './Wallet.ts' +import { switcher } from './adapters/switcher.ts' +import * as adapterList from './adapters/index.ts' +import { WalletPlatformEnum } from '@multiplechain/types' +import type { EIP6963ProviderDetail, EIP1193Provider } from './adapters/EIP6963.ts' +import type { + WalletAdapterListType, + WalletAdapterInterface, + RegisterWalletAdapterType +} from '@multiplechain/types' + +const EIP6963AdapterUUIDIndex: Record = { + 'app.phantom': 'phantom', + 'io.metamask': 'metamask', + 'com.bitget.web3': 'bitgetwallet', + 'com.okex.wallet': 'okxwallet', + 'com.trustwallet.app': 'trustwallet', + 'io.xdefi': 'xdefiwallet' +} + +const adapters: WalletAdapterListType = { + ...adapterList +} + +const registerAdapter: RegisterWalletAdapterType = (adapter: WalletAdapterInterface): void => { + if (EIP6963AdapterUUIDIndex[adapter.id] !== undefined) { + console.warn( + `Adapter is not registered, because it is already registered defualtly: ${adapter.id}` + ) + return + } + + if (Object.values(adapters).find((a) => a.id === adapter.id) !== undefined) { + throw new Error(`Adapter with id ${adapter.id} already exists`) + } + + adapters[adapter.id] = adapter +} + +const fromEIP6963ProviderDetail = (detail: EIP6963ProviderDetail): WalletAdapterInterface => { + return { + name: detail.info.name, + icon: detail.info.icon, + provider: detail.provider, + id: detail.info.rdns ?? detail.info.uuid, + platforms: [WalletPlatformEnum.BROWSER, WalletPlatformEnum.MOBILE], + isDetected: () => true, + isConnected: async () => { + return Boolean((await detail.provider.request({ method: 'eth_accounts' })).length) + }, + connect: async (): Promise => { + return await new Promise((resolve, reject) => { + try { + detail.provider + .request({ method: 'eth_requestAccounts' }) + .then(() => { + resolve(detail.provider) + }) + .catch((error: any) => { + reject(error) + }) + } catch (error) { + reject(error) + } + }) + } + } +} + +const toEIP6963ProviderDetail = (adapter: WalletAdapterInterface): EIP6963ProviderDetail => { + if (adapter.provider === undefined) { + throw new Error('Cannot convert adapter without provider to EIP6963ProviderDetail') + } + + return { + info: { + uuid: adapter.id, + name: adapter.name, + icon: adapter.icon + }, + provider: adapter.provider + } +} + +export * from '../index.ts' + +export const browser = { + Wallet, + switcher, + adapters, + registerAdapter, + toEIP6963ProviderDetail, + fromEIP6963ProviderDetail +} diff --git a/packages/networks/evm-chains/src/services/Ethers.ts b/packages/networks/evm-chains/src/services/Ethers.ts index aa3b97c..7012397 100644 --- a/packages/networks/evm-chains/src/services/Ethers.ts +++ b/packages/networks/evm-chains/src/services/Ethers.ts @@ -184,6 +184,77 @@ export class Ethers { return await this.jsonRpcProvider.getTransactionReceipt(id) } + /** + * @param {string} address + * @param {number} limit how many block to go back + * @returns {Promise} + */ + async getLastTransactions(address: string, limit: number = 0): Promise { + const txPromises = [] + const blockPromises = [] + const transactions: TransactionResponse[] = [] + + const block = await this.getBlock('pending') + const blockNumber = block?.number ?? (await this.getBlockNumber()) + + for (let i = blockNumber; i > blockNumber - limit; i--) { + const block = await this.getBlock(i, true) + if (block === null) { + continue + } + blockPromises.push(block) + } + + const blocks = await Promise.all(blockPromises) + for (const block of blocks) { + for (const txHash of block.transactions) { + txPromises.push(this.getTransaction(txHash)) + } + } + + const txs = await Promise.all(txPromises) + for (const tx of txs) { + if ( + tx?.from.toLowerCase() === address.toLowerCase() || + tx?.to?.toLowerCase() === address.toLowerCase() + ) { + transactions.push(tx) + } + } + + return transactions + } + + /** + * @param {String} address + * @param {number} limit + * @returns {Promise} + */ + async getLastTransaction( + address: string, + limit: number = 0 + ): Promise { + const block = await this.getBlock('pending') + const blockNumber = block?.number ?? (await this.getBlockNumber()) + for (let i = blockNumber; i > blockNumber - limit; i--) { + const block = await this.getBlock(i, true) + if (block === null) { + continue + } + for (const txId of block.transactions) { + const tx = await this.getTransaction(txId) + if ( + tx?.from.toLowerCase() === address.toLowerCase() || + tx?.to?.toLowerCase() === address.toLowerCase() + ) { + return tx + } + } + } + + return null + } + /** * @param {String} address * @returns {Promise} diff --git a/packages/networks/evm-chains/src/services/Networks.ts b/packages/networks/evm-chains/src/services/Networks.ts index cfc7b00..ee24153 100644 --- a/packages/networks/evm-chains/src/services/Networks.ts +++ b/packages/networks/evm-chains/src/services/Networks.ts @@ -3,7 +3,7 @@ import type { EvmNetworkConfigInterface } from './Provider.ts' const networks: Record = {} -Object.keys(wagmiChains).forEach((key) => { +for (const key of Object.keys(wagmiChains)) { const wagmiChain: wagmiChains.Chain = wagmiChains[key as keyof typeof wagmiChains] let backupRpcUrl = '' @@ -40,7 +40,7 @@ Object.keys(wagmiChains).forEach((key) => { } networks[key === 'mainnet' ? 'ethereum' : key] = network -}) +} const findById = (id: number): EvmNetworkConfigInterface | undefined => { return Object.values(networks).find((network) => network.id === id) diff --git a/packages/networks/evm-chains/src/services/TransactionListener.ts b/packages/networks/evm-chains/src/services/TransactionListener.ts index b513638..822b275 100644 --- a/packages/networks/evm-chains/src/services/TransactionListener.ts +++ b/packages/networks/evm-chains/src/services/TransactionListener.ts @@ -79,10 +79,10 @@ export class TransactionListener /** * @param {T} type - Transaction type - * @param {Provider} provider - Provider * @param {DynamicTransactionListenerFilterType} filter - Transaction listener filter + * @param {Provider} provider - Provider */ - constructor(type: T, provider?: Provider, filter?: DynamicTransactionListenerFilterType) { + constructor(type: T, filter?: DynamicTransactionListenerFilterType, provider?: Provider) { this.type = type this.filter = filter ?? {} this.provider = provider ?? Provider.instance @@ -150,9 +150,9 @@ export class TransactionListener trigger(transaction: DynamicTransactionType): void { if (!this.triggeredTransactions.includes(transaction.id)) { this.triggeredTransactions.push(transaction.id) - this.callbacks.forEach((callback) => { + for (const callback of this.callbacks) { callback(transaction) - }) + } } } @@ -195,21 +195,9 @@ export class TransactionListener } } - const callback = async (transactionIdOrLog: string | Log): Promise => { - let transaction: TransactionResponse | null - if (typeof transactionIdOrLog === 'string') { - transaction = await this.ethers.getTransaction(transactionIdOrLog) - const contractBytecode = await this.ethers.getByteCode(transaction?.to ?? '') - - if (contractBytecode === '0x') { - return - } - } else { - transaction = await this.ethers.getTransaction(transactionIdOrLog.transactionHash) - } - + const checkSigner = (transaction: TransactionResponse | null): boolean => { if (transaction === null) { - return + return false } interface ParamsType { @@ -225,9 +213,35 @@ export class TransactionListener } if (!objectsEqual(expectedParams, receivedParams)) { + return false + } + + return true + } + + const callback = async (transactionIdOrLog: string | Log): Promise => { + let transaction: TransactionResponse | null + if (typeof transactionIdOrLog === 'string') { + transaction = await this.ethers.getTransaction(transactionIdOrLog) + + if (!checkSigner(transaction)) { + return + } + + const contractBytecode = await this.ethers.getByteCode(transaction?.to ?? '') + + if (contractBytecode === '0x') { + return + } + } else { + transaction = await this.ethers.getTransaction(transactionIdOrLog.transactionHash) + } + + if (!checkSigner(transaction)) { return } + // @ts-expect-error already checking ing checkSigner this.trigger(new ContractTransaction(transaction.hash)) } @@ -256,9 +270,8 @@ export class TransactionListener const callback = async (transactionId: string): Promise => { const tx = await this.ethers.getTransaction(transactionId) - const contractBytecode = await this.ethers.getByteCode(tx?.to ?? '') - if (contractBytecode !== '0x' || tx === null) { + if (tx === null) { return } @@ -286,6 +299,12 @@ export class TransactionListener return } + const contractBytecode = await this.ethers.getByteCode(tx?.to ?? '') + + if (contractBytecode !== '0x') { + return + } + const transaction = new CoinTransaction(transactionId) if (filter.amount !== undefined) { diff --git a/packages/networks/evm-chains/src/services/TransactionSigner.ts b/packages/networks/evm-chains/src/services/TransactionSigner.ts index 2b54da3..eafeaa2 100644 --- a/packages/networks/evm-chains/src/services/TransactionSigner.ts +++ b/packages/networks/evm-chains/src/services/TransactionSigner.ts @@ -4,6 +4,7 @@ import { Transaction } from '../models/Transaction.ts' import { NftTransaction } from '../models/NftTransaction.ts' import { CoinTransaction } from '../models/CoinTransaction.ts' import { TokenTransaction } from '../models/TokenTransaction.ts' +import { ContractTransaction } from '../models/ContractTransaction.ts' import type { TransactionRequest, Wallet, BigNumberish } from 'ethers' import { ErrorTypeEnum, type TransactionSignerInterface } from '@multiplechain/types' @@ -89,6 +90,16 @@ export class TransactionSigner implements TransactionSignerInterface { } } +export class ContractTransactionSigner extends TransactionSigner { + /** + * Send the transaction to the blockchain network + * @returns {Promise} Transaction data + */ + async send(): Promise { + return new ContractTransaction((await super.send()).getId()) + } +} + export class CoinTransactionSigner extends TransactionSigner { /** * Send the transaction to the blockchain network diff --git a/packages/networks/evm-chains/tests/assets.spec.ts b/packages/networks/evm-chains/tests/assets.spec.ts index ad037d0..4e66db1 100644 --- a/packages/networks/evm-chains/tests/assets.spec.ts +++ b/packages/networks/evm-chains/tests/assets.spec.ts @@ -3,34 +3,36 @@ import { describe, it, expect, assert } from 'vitest' import { NFT } from '../src/assets/NFT.ts' import { Coin } from '../src/assets/Coin.ts' import { Token } from '../src/assets/Token.ts' -import { fixFloat } from '@multiplechain/utils' +import { math } from '@multiplechain/utils' import { Transaction } from '../src/models/Transaction.ts' import { TransactionStatusEnum } from '@multiplechain/types' import { TransactionSigner } from '../src/services/TransactionSigner.ts' -const coinBalanceTestAmount = Number(process.env.COIN_BALANCE_TEST_AMOUNT) -const tokenBalanceTestAmount = Number(process.env.TOKEN_BALANCE_TEST_AMOUNT) -const nftBalanceTestAmount = Number(process.env.NFT_BALANCE_TEST_AMOUNT) -const transferTestAmount = Number(process.env.TRANSFER_TEST_AMOUNT) -const tokenTransferTestAmount = Number(process.env.TOKEN_TRANSFER_TEST_AMOUNT) -const tokenApproveTestAmount = Number(process.env.TOKEN_APPROVE_TEST_AMOUNT) -const nftTransferId = Number(process.env.NFT_TRANSFER_ID) - -const coinTransferTestIsActive = Boolean(process.env.COIN_TRANSFER_TEST_IS_ACTIVE !== 'false') -const tokenTransferTestIsActive = Boolean(process.env.TOKEN_TRANSFER_TEST_IS_ACTIVE !== 'false') -const tokenApproveTestIsActive = Boolean(process.env.TOKEN_APPROVE_TEST_IS_ACTIVE !== 'false') -const nftTransactionTestIsActive = Boolean(process.env.NFT_TRANSACTION_TEST_IS_ACTIVE !== 'false') +const coinBalanceTestAmount = Number(process.env.EVM_COIN_BALANCE_TEST_AMOUNT) +const tokenBalanceTestAmount = Number(process.env.EVM_TOKEN_BALANCE_TEST_AMOUNT) +const nftBalanceTestAmount = Number(process.env.EVM_NFT_BALANCE_TEST_AMOUNT) +const transferTestAmount = Number(process.env.EVM_TRANSFER_TEST_AMOUNT) +const tokenTransferTestAmount = Number(process.env.EVM_TOKEN_TRANSFER_TEST_AMOUNT) +const tokenApproveTestAmount = Number(process.env.EVM_TOKEN_APPROVE_TEST_AMOUNT) +const nftTransferId = Number(process.env.EVM_NFT_TRANSFER_ID) + +const coinTransferTestIsActive = Boolean(process.env.EVM_COIN_TRANSFER_TEST_IS_ACTIVE !== 'false') +const tokenTransferTestIsActive = Boolean(process.env.EVM_TOKEN_TRANSFER_TEST_IS_ACTIVE !== 'false') +const tokenApproveTestIsActive = Boolean(process.env.EVM_TOKEN_APPROVE_TEST_IS_ACTIVE !== 'false') +const nftTransactionTestIsActive = Boolean( + process.env.EVM_NFT_TRANSACTION_TEST_IS_ACTIVE !== 'false' +) const tokenTransferFromTestIsActive = Boolean( - process.env.TOKEN_TRANSFER_FROM_TEST_IS_ACTIVE !== 'false' + process.env.EVM_TOKEN_TRANSFER_FROM_TEST_IS_ACTIVE !== 'false' ) -const balanceTestAddress = String(process.env.BALANCE_TEST_ADDRESS) -const senderPrivateKey = String(process.env.SENDER_PRIVATE_KEY) -const receiverPrivateKey = String(process.env.RECEIVER_PRIVATE_KEY) -const senderTestAddress = String(process.env.SENDER_TEST_ADDRESS) -const receiverTestAddress = String(process.env.RECEIVER_TEST_ADDRESS) -const tokenTestAddress = String(process.env.TOKEN_TEST_ADDRESS) -const nftTestAddress = String(process.env.NFT_TEST_ADDRESS) +const balanceTestAddress = String(process.env.EVM_BALANCE_TEST_ADDRESS) +const senderPrivateKey = String(process.env.EVM_SENDER_PRIVATE_KEY) +const receiverPrivateKey = String(process.env.EVM_RECEIVER_PRIVATE_KEY) +const senderTestAddress = String(process.env.EVM_SENDER_TEST_ADDRESS) +const receiverTestAddress = String(process.env.EVM_RECEIVER_TEST_ADDRESS) +const tokenTestAddress = String(process.env.EVM_TOKEN_TEST_ADDRESS) +const nftTestAddress = String(process.env.EVM_NFT_TEST_ADDRESS) const waitSecondsBeforeThanNewTx = async (seconds: number): Promise => { return await new Promise((resolve) => setTimeout(resolve, seconds * 1000)) @@ -86,7 +88,7 @@ describe('Coin', () => { await checkTx(await signer.send()) const afterBalance = await coin.getBalance(receiverTestAddress) - expect(afterBalance).toBe(fixFloat(beforeBalance + transferTestAmount)) + expect(afterBalance).toBe(math.add(beforeBalance, transferTestAmount)) }) }) @@ -130,7 +132,7 @@ describe('Token', () => { await checkTx(await signer.send()) const afterBalance = await token.getBalance(receiverTestAddress) - expect(afterBalance).toBe(fixFloat(beforeBalance + tokenTransferTestAmount)) + expect(afterBalance).toBe(math.add(beforeBalance, tokenTransferTestAmount)) }) it('Approve and Allowance', async () => { @@ -172,7 +174,7 @@ describe('Token', () => { await checkTx(await signer.send()) const afterBalance = await token.getBalance(receiverTestAddress) - expect(afterBalance).toBe(fixFloat(beforeBalance + 2)) + expect(afterBalance).toBe(math.add(beforeBalance, 2)) }) }) diff --git a/packages/networks/evm-chains/tests/models.spec.ts b/packages/networks/evm-chains/tests/models.spec.ts index c8ce377..8912790 100644 --- a/packages/networks/evm-chains/tests/models.spec.ts +++ b/packages/networks/evm-chains/tests/models.spec.ts @@ -6,22 +6,22 @@ import { CoinTransaction } from '../src/models/CoinTransaction.ts' import { TokenTransaction } from '../src/models/TokenTransaction.ts' import { AssetDirectionEnum, TransactionStatusEnum } from '@multiplechain/types' -const nftId = Number(process.env.NFT_ID) -const tokenAmount = Number(process.env.TOKEN_AMOUNT) -const coinAmount = Number(process.env.COIN_AMOUNT) +const nftId = Number(process.env.EVM_NFT_ID) +const tokenAmount = Number(process.env.EVM_TOKEN_AMOUNT) +const coinAmount = Number(process.env.EVM_COIN_AMOUNT) -const etherTransferTx = String(process.env.ETHER_TRANSFER_TX) -const tokenTransferTx = String(process.env.TOKEN_TRANSFER_TX) -const nftTransferTx = String(process.env.NFT_TRANSFER_TX) +const etherTransferTx = String(process.env.EVM_ETHER_TRANSFER_TX) +const tokenTransferTx = String(process.env.EVM_TOKEN_TRANSFER_TX) +const nftTransferTx = String(process.env.EVM_NFT_TRANSFER_TX) -const coinSender = String(process.env.COIN_SENDER) -const coinReceiver = String(process.env.COIN_RECEIVER) +const coinSender = String(process.env.EVM_COIN_SENDER) +const coinReceiver = String(process.env.EVM_COIN_RECEIVER) -const tokenSender = String(process.env.TOKEN_SENDER) -const tokenReceiver = String(process.env.TOKEN_RECEIVER) +const tokenSender = String(process.env.EVM_TOKEN_SENDER) +const tokenReceiver = String(process.env.EVM_TOKEN_RECEIVER) -const nftSender = String(process.env.NFT_SENDER) -const nftReceiver = String(process.env.NFT_RECEIVER) +const nftSender = String(process.env.EVM_NFT_SENDER) +const nftReceiver = String(process.env.EVM_NFT_RECEIVER) describe('Transaction', () => { const tx = new Transaction(etherTransferTx) diff --git a/packages/networks/evm-chains/tests/services.spec.ts b/packages/networks/evm-chains/tests/services.spec.ts index ec39494..9898238 100644 --- a/packages/networks/evm-chains/tests/services.spec.ts +++ b/packages/networks/evm-chains/tests/services.spec.ts @@ -13,15 +13,15 @@ import { TokenTransaction } from '../src/models/TokenTransaction.ts' import { NftTransaction } from '../src/models/NftTransaction.ts' import { NFT } from '../src/assets/NFT.ts' -const senderPrivateKey = String(process.env.SENDER_PRIVATE_KEY) -const receiverPrivateKey = String(process.env.RECEIVER_PRIVATE_KEY) -const senderTestAddress = String(process.env.SENDER_TEST_ADDRESS) -const receiverTestAddress = String(process.env.RECEIVER_TEST_ADDRESS) -const tokenTestAddress = String(process.env.TOKEN_TEST_ADDRESS) -const nftTestAddress = String(process.env.NFT_TEST_ADDRESS) +const senderPrivateKey = String(process.env.EVM_SENDER_PRIVATE_KEY) +const receiverPrivateKey = String(process.env.EVM_RECEIVER_PRIVATE_KEY) +const senderTestAddress = String(process.env.EVM_SENDER_TEST_ADDRESS) +const receiverTestAddress = String(process.env.EVM_RECEIVER_TEST_ADDRESS) +const tokenTestAddress = String(process.env.EVM_TOKEN_TEST_ADDRESS) +const nftTestAddress = String(process.env.EVM_NFT_TEST_ADDRESS) const transactionListenerTestIsActive = Boolean( - process.env.TRANSACTION_LISTENER_TEST_IS_ACTIVE !== 'false' + process.env.EVM_TRANSACTION_LISTENER_TEST_IS_ACTIVE !== 'false' ) const waitSecondsBeforeThanNewTx = async (seconds: number): Promise => { @@ -39,14 +39,16 @@ describe('Provider', () => { it('checkRpcConnection', async () => { expect(await provider.checkRpcConnection('https://sepolia.infura.io/v3')).instanceOf(Error) - expect(await provider.checkRpcConnection(process.env.RPC_URL as unknown as string)).toBe( - true - ) + expect( + await provider.checkRpcConnection(process.env.EVM_RPC_URL as unknown as string) + ).toBe(true) }) it('checkWsConnection', async () => { expect(await provider.checkWsConnection('wss://sepolia.infura.io/v3')).instanceOf(Error) - expect(await provider.checkWsConnection(process.env.WS_URL as unknown as string)).toBe(true) + expect(await provider.checkWsConnection(process.env.EVM_WS_URL as unknown as string)).toBe( + true + ) }) }) @@ -59,7 +61,7 @@ describe('Transaction Listener', () => { } it('General', async () => { - const listener = new TransactionListener(TransactionTypeEnum.GENERAL, provider, { + const listener = new TransactionListener(TransactionTypeEnum.GENERAL, { signer: senderTestAddress }) @@ -80,7 +82,7 @@ describe('Transaction Listener', () => { it('Contract', async () => { await waitSecondsBeforeThanNewTx(10) - const listener = new TransactionListener(TransactionTypeEnum.CONTRACT, provider, { + const listener = new TransactionListener(TransactionTypeEnum.CONTRACT, { signer: senderTestAddress, address: tokenTestAddress }) @@ -106,7 +108,7 @@ describe('Transaction Listener', () => { it('Coin', async () => { await waitSecondsBeforeThanNewTx(10) - const listener = new TransactionListener(TransactionTypeEnum.COIN, provider, { + const listener = new TransactionListener(TransactionTypeEnum.COIN, { signer: senderTestAddress, receiver: receiverTestAddress }) @@ -128,7 +130,7 @@ describe('Transaction Listener', () => { it('Token', async () => { await waitSecondsBeforeThanNewTx(10) - const listener = new TransactionListener(TransactionTypeEnum.TOKEN, provider, { + const listener = new TransactionListener(TransactionTypeEnum.TOKEN, { signer: senderTestAddress, receiver: receiverTestAddress, address: tokenTestAddress @@ -155,7 +157,7 @@ describe('Transaction Listener', () => { it('NFT', async () => { await waitSecondsBeforeThanNewTx(10) - const listener = new TransactionListener(TransactionTypeEnum.NFT, provider, { + const listener = new TransactionListener(TransactionTypeEnum.NFT, { signer: senderTestAddress, receiver: receiverTestAddress, address: nftTestAddress diff --git a/packages/networks/evm-chains/tests/setup.ts b/packages/networks/evm-chains/tests/setup.ts index 0257953..f939bdf 100644 --- a/packages/networks/evm-chains/tests/setup.ts +++ b/packages/networks/evm-chains/tests/setup.ts @@ -12,8 +12,8 @@ try { testnet: true, name: 'Ethereum Sepolia Testnet (QR)', explorerUrl: 'https://sepolia.etherscan.io/', - rpcUrl: process.env.RPC_URL as unknown as string, - wsUrl: process.env.WS_URL as unknown as string, + rpcUrl: process.env.EVM_RPC_URL as unknown as string, + wsUrl: process.env.EVM_WS_URL as unknown as string, nativeCurrency: { symbol: 'ETH', name: 'Ethereum', diff --git a/packages/networks/evm-chains/vite.svg b/packages/networks/evm-chains/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/packages/networks/evm-chains/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/types/package.json b/packages/types/package.json index 6b3bf65..a9fc6e9 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@multiplechain/types", - "version": "0.1.35", + "version": "0.1.53", "type": "module", "main": "./src/index.ts", "types": "./src/index.ts", diff --git a/packages/types/src/assets.ts b/packages/types/src/assets.ts index 03a1226..a023e37 100644 --- a/packages/types/src/assets.ts +++ b/packages/types/src/assets.ts @@ -31,6 +31,14 @@ export interface ContractInterface { * @returns Data used in transaction */ getMethodData: (method: string, ...args: any[]) => Promise + + /** + * @param {string} method Method name + * @param {string} from Sender wallet address + * @param {any[]} args Method parameters + * @returns {Promise} Transaction data + */ + createTransactionData: (method: string, from: string, ...args: any[]) => Promise } export interface AssetInterface { diff --git a/packages/types/src/browser.ts b/packages/types/src/browser.ts new file mode 100644 index 0000000..778b3f8 --- /dev/null +++ b/packages/types/src/browser.ts @@ -0,0 +1,103 @@ +import type { WalletPlatformEnum } from './enums.ts' +import type { ProviderInterface } from './services/ProviderInterface.ts' +import type { TransactionSignerInterface } from './services/TransactionSignerInterface.ts' + +export type RegisterWalletAdapterType = (walletAdapter: WalletAdapterInterface) => void + +export type WalletAdapterListType = Record + +export interface WalletConnectOps { + projectId: string + themeMode?: 'dark' | 'light' +} + +export interface WalletAdapterInterface { + id: string + name: string + icon: string + provider?: any + downloadLink?: string + platforms: WalletPlatformEnum[] + disconnect?: () => void | Promise + isDetected: () => boolean | Promise + isConnected: () => boolean | Promise + createDeepLink?: (url: string, ops?: object) => string + connect: (provider?: ProviderInterface, ops?: object | WalletConnectOps) => Promise +} + +export interface WalletInterface { + adapter: WalletAdapterInterface + + /** + * @returns {String} + */ + getId: () => string + + /** + * @returns {String} + */ + getName: () => string + + /** + * @returns {String} + */ + getIcon: () => string + + /** + * @returns {WalletPlatformEnum[]} + */ + getPlatforms: () => WalletPlatformEnum[] + + /** + * @returns {String | undefined} + */ + getDownloadLink: () => string | undefined + + /** + * @param {String} url + * @param {Object} ops + * @returns {String | null} + */ + createDeepLink: (url: string, ops?: object) => string | null + + /** + * @param {ProviderInterface} provider + * @param {Object | WalletConnectOps} ops + * @returns {Promise} + */ + connect: (provider?: ProviderInterface, ops?: object | WalletConnectOps) => Promise + + /** + * @returns {Boolean | Promise} + */ + isDetected: () => boolean | Promise + + /** + * @returns {Boolean | Promise} + */ + isConnected: () => boolean | Promise + + /** + * @returns {Promise} + */ + getAddress: () => Promise + + /** + * @param {string} message + * @returns {Promise} + */ + signMessage: (message: string) => Promise + + /** + * @param {TransactionSignerInterface} transactionSigner + * @returns {Promise} + */ + sendTransaction: (transactionSigner: TransactionSignerInterface) => Promise + + /** + * @param {string} eventName + * @param {Function} callback + * @returns {void} + */ + on: (eventName: string, callback: (...args: any[]) => void) => void +} diff --git a/packages/types/src/enums.ts b/packages/types/src/enums.ts index 7f01da7..f086e3a 100644 --- a/packages/types/src/enums.ts +++ b/packages/types/src/enums.ts @@ -52,3 +52,10 @@ export enum ErrorTypeEnum { TRANSACTION_CREATION_FAILED = 'TRANSACTION_CREATION_FAILED', CLOSED_WALLETCONNECT_MODAL = 'CLOSED_WALLETCONNECT_MODAL' } + +export enum WalletPlatformEnum { + BROWSER = 'BROWSER', + MOBILE = 'MOBILE', + DESKTOP = 'DESKTOP', + UNIVERSAL = 'UNIVERSAL' +} diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 043bd85..4ff7e39 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -2,6 +2,7 @@ export * from './enums.ts' export type * from './enums.ts' export type * from './assets.ts' export type * from './models.ts' +export type * from './browser.ts' export type * from './services/ProviderInterface.ts' export type * from './services/TransactionListenerInterface.ts' export type * from './services/TransactionSignerInterface.ts' diff --git a/packages/utils/package.json b/packages/utils/package.json index 54b9a49..c04c0b8 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@multiplechain/utils", - "version": "0.1.16", + "version": "0.1.18", "type": "module", "main": "./src/index.ts", "types": "./src/index.ts", diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 8da26e5..2a8e452 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -163,4 +163,92 @@ export const checkWebSocket = async (url: string): Promise => { }) } +export const math = { + add: (a: number, b: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).plus(new BigNumber(b)).toFixed(decimals)) + }, + sub: (a: number, b: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).minus(new BigNumber(b)).toFixed(decimals)) + }, + mul: (a: number, b: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).times(new BigNumber(b)).toFixed(decimals)) + }, + div: (a: number, b: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).div(new BigNumber(b)).toFixed(decimals)) + }, + pow: (a: number, b: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).pow(b).toFixed(decimals)) + }, + sqrt: (a: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).sqrt().toFixed(decimals)) + }, + abs: (a: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).absoluteValue().toFixed(decimals)) + }, + ceil: (a: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).integerValue(BigNumber.ROUND_CEIL).toFixed(decimals)) + }, + floor: (a: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).integerValue(BigNumber.ROUND_FLOOR).toFixed(decimals)) + }, + round: (a: number, decimals: number = 18): number => { + return parseFloat(new BigNumber(a).integerValue(BigNumber.ROUND_HALF_UP).toFixed(decimals)) + } +} + +declare global { + interface Window { + opera?: any + WebViewJavascriptBridge?: any + webkit?: any + } + interface Navigator { + standalone?: any + } +} + +export const isMobile = (): boolean => { + /* eslint-disable */ + return (function (a) { + return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino|android|ipad|playbook|silk/i.test( + a + ) || + /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\\-(n|u)|c55\/|capi|ccwa|cdm\\-|cell|chtm|cldc|cmd\\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\\-s|devi|dica|dmob|do(c|p)o|ds(12|\\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\\-|_)|g1 u|g560|gene|gf\\-5|g\\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\\-(m|p|t)|hei\\-|hi(pt|ta)|hp( i|ip)|hs\\-c|ht(c(\\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\\-(20|go|ma)|i230|iac( |\\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\\-[a-w])|libw|lynx|m1\\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\\-2|po(ck|rt|se)|prox|psio|pt\\-g|qa\\-a|qc(07|12|21|32|60|\\-[2-7]|i\\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\\-|oo|p\\-)|sdk\/|se(c(\\-|0|1)|47|mc|nd|ri)|sgh\\-|shar|sie(\\-|m)|sk\\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\\-|v\\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\\-|tdg\\-|tel(i|m)|tim\\-|t\\-mo|to(pl|sh)|ts(70|m\\-|m3|m5)|tx\\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\\-|your|zeto|zte\\-/i.test( + a.substr(0, 4) + ) + ? true + : false + })(navigator.userAgent || navigator.vendor || window.opera) + /* eslint-enable */ +} + +export const isWebview = (): boolean => { + if (typeof window === 'undefined') { + return false + } + + const navigator = window.navigator + + /* eslint-disable */ + if (window.WebViewJavascriptBridge) { + return true + } + + if (window.webkit && window.webkit.messageHandlers) { + return true + } + + if (navigator.userAgent.match(/WebView/i)) { + return true + } + + const standalone = navigator.standalone + const userAgent = navigator.userAgent.toLowerCase() + const safari = /safari/.test(userAgent) + const ios = /iphone|ipod|ipad/.test(userAgent) + + return ios ? !standalone && !safari : userAgent.includes('wv') + /* eslint-enable */ +} + export { toHex } diff --git a/packages/utils/tests/index.spec.ts b/packages/utils/tests/index.spec.ts index 6a03759..094b5bc 100644 --- a/packages/utils/tests/index.spec.ts +++ b/packages/utils/tests/index.spec.ts @@ -6,7 +6,8 @@ import { base58Encode, base58Decode, bufferToString, - stringToBuffer + stringToBuffer, + math } from '../src/index.js' describe('Helper methods', () => { @@ -44,3 +45,45 @@ describe('Helper methods', () => { ) }) }) + +describe('Math', () => { + it('add', () => { + expect(math.add(0.2, 0.1)).toBe(0.3) + }) + + it('subtract', () => { + expect(math.sub(0.3, 0.1)).toBe(0.2) + }) + + it('multiply', () => { + expect(math.mul(10, 20)).toBe(200) + }) + + it('divide', () => { + expect(math.div(10, 20)).toBe(0.5) + }) + + it('pow', () => { + expect(math.pow(2, 3)).toBe(8) + }) + + it('sqrt', () => { + expect(math.sqrt(9)).toBe(3) + }) + + it('abs', () => { + expect(math.abs(-10)).toBe(10) + }) + + it('ceil', () => { + expect(math.ceil(0.1)).toBe(1) + }) + + it('floor', () => { + expect(math.floor(0.9)).toBe(0) + }) + + it('round', () => { + expect(math.round(0.5)).toBe(1) + }) +}) diff --git a/vite.config.ts b/vite.config.ts index ce9b83c..e20eca5 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -13,8 +13,8 @@ export default defineConfig({ minify: true, sourcemap: true, lib: { - entry: './src/index.ts', formats: ['es', 'umd'], + entry: './src/browser/index.ts', fileName: (format: string) => `index.${format}.js` } }, diff --git a/vitest.config.ts b/vitest.config.ts index 02f5bf0..2c90caf 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -9,9 +9,9 @@ export default mergeConfig( watch: false, testTimeout: 180000, environment: 'node', - setupFiles: ['./packages/networks/evm-chains/tests/setup.ts'], exclude: [...configDefaults.exclude, 'e2e/*'], - root: fileURLToPath(new URL('./', import.meta.url)) + root: fileURLToPath(new URL('./', import.meta.url)), + setupFiles: ['./packages/networks/evm-chains/tests/setup.ts'] } }) )