This commit is contained in:
zramsay 2025-03-21 16:03:36 -04:00
parent 87c2fdb8b3
commit 1001bdad6d
3 changed files with 229 additions and 17 deletions

150
package-lock.json generated
View File

@ -14,6 +14,7 @@
"@google-cloud/vision": "^4.3.2",
"@google/generative-ai": "^0.21.0",
"@sei-js/core": "^3.2.0",
"@sei-js/react": "^3.2.0",
"@solana/spl-token": "^0.3.8",
"@solana/web3.js": "^1.78.4",
"@supabase/supabase-js": "^2.49.1",
@ -285,6 +286,24 @@
"resolved": "https://registry.npmjs.org/@cosmjs/utils/-/utils-0.32.4.tgz",
"integrity": "sha512-D1Yc+Zy8oL/hkUkFUL/bwxvuDBzRGpc4cF7/SkdhxX4iHpSLgdOuTt1mhCh9+kl6NQREy9t7SYZ6xeW5gFe60w=="
},
"node_modules/@emotion/is-prop-valid": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.2.tgz",
"integrity": "sha512-uNsoYd37AFmaCdXlg6EYD1KaPOaRWRByMCYzbKUX4+hhMfrxdVSelShywL4JVaAeM/eHUOSprYBQls+/neX3pw==",
"dependencies": {
"@emotion/memoize": "^0.8.1"
}
},
"node_modules/@emotion/memoize": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.1.tgz",
"integrity": "sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA=="
},
"node_modules/@emotion/unitless": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.1.tgz",
"integrity": "sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ=="
},
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
@ -1269,6 +1288,14 @@
"integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
"license": "BSD-3-Clause"
},
"node_modules/@react-icons/all-files": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/@react-icons/all-files/-/all-files-4.1.0.tgz",
"integrity": "sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ==",
"peerDependencies": {
"react": "*"
}
},
"node_modules/@rtsao/scc": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz",
@ -1701,6 +1728,23 @@
"pbts": "bin/pbts"
}
},
"node_modules/@sei-js/react": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/@sei-js/react/-/react-3.2.0.tgz",
"integrity": "sha512-62E1dQu/zyDq/shoO2Pjtw5Xv3/G3gK6o2FI4lk/lxc69cs/ivR4ao8tAOItPLENGX9KCU5hlSMwXLXUgzg6ig==",
"deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.",
"dependencies": {
"@react-icons/all-files": "^4.1.0",
"@sei-js/core": "^3.1.1",
"buffer": "^6.0.3",
"process": "^0.11.10",
"styled-components": "^6.1.1"
},
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0"
}
},
"node_modules/@solana/buffer-layout": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/@solana/buffer-layout/-/buffer-layout-4.0.1.tgz",
@ -2254,6 +2298,11 @@
"@types/send": "*"
}
},
"node_modules/@types/stylis": {
"version": "4.2.5",
"resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz",
"integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw=="
},
"node_modules/@types/tough-cookie": {
"version": "4.0.5",
"resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
@ -3061,6 +3110,14 @@
"node": ">= 6"
}
},
"node_modules/camelize": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz",
"integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==",
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001690",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001690.tgz",
@ -3334,6 +3391,24 @@
"node": ">= 8"
}
},
"node_modules/css-color-keywords": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz",
"integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==",
"engines": {
"node": ">=4"
}
},
"node_modules/css-to-react-native": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz",
"integrity": "sha512-e8RKaLXMOFii+02mOlqwjbD00KSEKqblnpO9e++1aXS1fPQOpS1YoqdVHBqPjHNoxeF2mimzVqawm2KCbEdtHQ==",
"dependencies": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"node_modules/cssesc": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
@ -3349,8 +3424,7 @@
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
"dev": true
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="
},
"node_modules/damerau-levenshtein": {
"version": "1.0.8",
@ -6972,8 +7046,7 @@
"node_modules/postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
"node_modules/preact": {
"version": "10.11.3",
@ -7524,6 +7597,11 @@
"sha.js": "bin.js"
}
},
"node_modules/shallowequal": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz",
"integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ=="
},
"node_modules/sharp": {
"version": "0.33.5",
"resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz",
@ -7973,6 +8051,65 @@
"integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==",
"license": "MIT"
},
"node_modules/styled-components": {
"version": "6.1.16",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-6.1.16.tgz",
"integrity": "sha512-KpWB6ORAWGmbWM10cDJfEV6sXc/uVkkkQV3SLwTNQ/E/PqWgNHIoMSLh1Lnk2FkB9+JHK7uuMq1i+9ArxDD7iQ==",
"dependencies": {
"@emotion/is-prop-valid": "1.2.2",
"@emotion/unitless": "0.8.1",
"@types/stylis": "4.2.5",
"css-to-react-native": "3.2.0",
"csstype": "3.1.3",
"postcss": "8.4.49",
"shallowequal": "1.1.0",
"stylis": "4.3.2",
"tslib": "2.6.2"
},
"engines": {
"node": ">= 16"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/styled-components"
},
"peerDependencies": {
"react": ">= 16.8.0",
"react-dom": ">= 16.8.0"
}
},
"node_modules/styled-components/node_modules/postcss": {
"version": "8.4.49",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.49.tgz",
"integrity": "sha512-OCVPnIObs4N29kxTjzLfUryOkvZEq+pf8jTF0lg8E7uETuWHA+v7j3c/xJmiqpX450191LlmZfUKkXxkTry7nA==",
"funding": [
{
"type": "opencollective",
"url": "https://opencollective.com/postcss/"
},
{
"type": "tidelift",
"url": "https://tidelift.com/funding/github/npm/postcss"
},
{
"type": "github",
"url": "https://github.com/sponsors/ai"
}
],
"dependencies": {
"nanoid": "^3.3.7",
"picocolors": "^1.1.1",
"source-map-js": "^1.2.1"
},
"engines": {
"node": "^10 || ^12 || >=14"
}
},
"node_modules/styled-components/node_modules/tslib": {
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="
},
"node_modules/styled-jsx": {
"version": "5.1.6",
"resolved": "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz",
@ -7996,6 +8133,11 @@
}
}
},
"node_modules/stylis": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.2.tgz",
"integrity": "sha512-bhtUjWd/z6ltJiQwg0dUfxEJ+W+jdqQd8TbWLWyeIJHlnsqmGLRFFd8e5mA0AZi/zx90smXRlN66YMTcaSFifg=="
},
"node_modules/sucrase": {
"version": "3.35.0",
"resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz",

View File

@ -15,6 +15,7 @@
"@google-cloud/vision": "^4.3.2",
"@google/generative-ai": "^0.21.0",
"@sei-js/core": "^3.2.0",
"@sei-js/react": "^3.2.0",
"@solana/spl-token": "^0.3.8",
"@solana/web3.js": "^1.78.4",
"@supabase/supabase-js": "^2.49.1",

View File

@ -1,7 +1,21 @@
// src/services/blockchain/seiService.ts
import { SeiWallet } from '@sei-js/core';
import { AccountData, OfflineSigner } from '@cosmjs/proto-signing';
import { getSigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate';
import { OfflineSigner } from '@cosmjs/proto-signing';
import { SigningCosmWasmClient } from '@cosmjs/cosmwasm-stargate';
// Add type declarations for wallet extensions
declare global {
interface Window {
keplr?: {
enable: (chainId: string) => Promise<void>;
getOfflineSigner: (chainId: string) => import('@cosmjs/proto-signing').OfflineSigner;
experimentalSuggestChain: (config: any) => Promise<void>;
};
leap?: {
enable: (chainId: string) => Promise<void>;
getOfflineSigner: (chainId: string) => import('@cosmjs/proto-signing').OfflineSigner;
};
}
}
// Sei network configurations
const NETWORKS = {
@ -15,7 +29,7 @@ const NETWORKS = {
};
// Track connected wallet state
let currentWallet: SeiWallet | null = null;
let currentWallet: OfflineSigner | null = null;
let currentAddress: string | null = null;
let cosmWasmClient: any = null;
@ -48,25 +62,80 @@ export const connectSeiWallet = async (): Promise<string | null> => {
return null;
}
// Initialize SeiWallet from @sei-js/core
const wallet = await SeiWallet.connectWallet();
if (!wallet) {
throw new Error('Failed to connect wallet');
// Use Keplr or Leap wallet
const network = NETWORKS.testnet;
let offlineSigner: OfflineSigner;
if (window.keplr) {
// Suggest chain to Keplr if needed
try {
await window.keplr.experimentalSuggestChain({
chainId: network.chainId,
chainName: 'Sei Testnet',
rpc: network.rpcUrl,
rest: network.restUrl,
bip44: {
coinType: 118,
},
coinType: 118,
stakeCurrency: {
coinDenom: 'SEI',
coinMinimalDenom: 'usei',
coinDecimals: 6,
},
bech32Config: {
bech32PrefixAccAddr: 'sei',
bech32PrefixAccPub: 'seipub',
bech32PrefixValAddr: 'seivaloper',
bech32PrefixValPub: 'seivaloperpub',
bech32PrefixConsAddr: 'seivalcons',
bech32PrefixConsPub: 'seivalconspub',
},
currencies: [
{
coinDenom: 'SEI',
coinMinimalDenom: 'usei',
coinDecimals: 6,
},
],
feeCurrencies: [
{
coinDenom: 'SEI',
coinMinimalDenom: 'usei',
coinDecimals: 6,
gasPriceStep: {
low: 0.01,
average: 0.025,
high: 0.04,
},
},
],
});
} catch (error) {
console.warn('Failed to suggest chain to Keplr:', error);
}
await window.keplr.enable(network.chainId);
offlineSigner = window.keplr.getOfflineSigner(network.chainId);
} else if (window.leap) {
await window.leap.enable(network.chainId);
offlineSigner = window.leap.getOfflineSigner(network.chainId);
} else {
throw new Error('No compatible wallet found');
}
// Get the connected wallet's address
const [account] = await wallet.getAccounts();
const [account] = await offlineSigner.getAccounts();
const address = account.address;
// Store wallet and address
currentWallet = wallet;
currentWallet = offlineSigner as any;
currentAddress = address;
// Initialize CosmWasm client for contract interactions
const network = NETWORKS.testnet;
cosmWasmClient = await getSigningCosmWasmClient(
cosmWasmClient = await SigningCosmWasmClient.connectWithSigner(
network.rpcUrl,
wallet as unknown as OfflineSigner
offlineSigner
);
console.log('Sei wallet connected:', address);