@gemini-wallet/core
Advanced tools
| import { type Address, type Hex } from "viem"; | ||
| export interface WebAuthnValidatorData { | ||
| pubKeyX: bigint; | ||
| pubKeyY: bigint; | ||
| } | ||
| export interface CalculateWalletAddressParams { | ||
| publicKey: Hex; | ||
| credentialId: string; | ||
| index?: bigint; | ||
| } | ||
| /** | ||
| * Calculate smart wallet address from public key and credential ID | ||
| * This handles all validation and setup internally | ||
| */ | ||
| export declare function calculateWalletAddress(params: CalculateWalletAddressParams): Address; | ||
| /** | ||
| * Generate authenticator ID hash from credential ID | ||
| */ | ||
| export declare function generateAuthenticatorIdHash(credentialId: string): Hex; | ||
| /** | ||
| * Validate WebAuthn public key offchain | ||
| * Mirrors the contract's _validateWebAuthnKey function | ||
| */ | ||
| export declare function validateWebAuthnKey(webAuthnData: WebAuthnValidatorData): boolean; | ||
| //# sourceMappingURL=calculateWalletAddress.d.ts.map |
| {"version":3,"file":"calculateWalletAddress.d.ts","sourceRoot":"","sources":["../../src/utils/calculateWalletAddress.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAKZ,KAAK,GAAG,EAET,MAAM,MAAM,CAAC;AAGd,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,MAAM,WAAW,4BAA4B;IAC3C,SAAS,EAAE,GAAG,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAYD;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,4BAA4B,GACnC,OAAO,CAoCT;AAED;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,YAAY,EAAE,MAAM,GAAG,GAAG,CAYrE;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,qBAAqB,GAClC,OAAO,CAyBT"} |
| import type { ReverseEnsResponse } from "@/types"; | ||
| import type { Address } from "viem"; | ||
| export declare function reverseResolveEns(address: Address): Promise<ReverseEnsResponse>; | ||
| //# sourceMappingURL=ens.d.ts.map |
| {"version":3,"file":"ens.d.ts","sourceRoot":"","sources":["../../src/utils/ens.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAEpC,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,kBAAkB,CAAC,CAuB7B"} |
| import { describe, expect, test, mock } from "bun:test"; | ||
| import { GeminiWalletProvider } from "./provider"; | ||
| import { GeminiStorage } from "@/storage"; | ||
| import type { GeminiProviderConfig } from "@/types"; | ||
| describe("GeminiProviderConfig", () => { | ||
| const createMockConfig = (overrides: Partial<GeminiProviderConfig> = {}): GeminiProviderConfig => ({ | ||
| appMetadata: { | ||
| name: "Test App", | ||
| description: "Test Description", | ||
| url: "https://test.com", | ||
| icons: [] | ||
| }, | ||
| chain: { id: 1 }, | ||
| storage: new GeminiStorage(), | ||
| ...overrides | ||
| }); | ||
| test("should preserve user's onDisconnectCallback and call provider cleanup", async () => { | ||
| const userDisconnectCallback = mock(); | ||
| let providerDisconnectCalled = false; | ||
| const provider = new GeminiWalletProvider(createMockConfig({ | ||
| onDisconnectCallback: userDisconnectCallback | ||
| })); | ||
| // Mock the provider disconnect to track if it's called | ||
| const originalDisconnect = provider.disconnect; | ||
| provider.disconnect = async () => { | ||
| providerDisconnectCalled = true; | ||
| return originalDisconnect.call(provider); | ||
| }; | ||
| // Simulate disconnect through the wallet's callback mechanism | ||
| // @ts-ignore - accessing private property for testing | ||
| if (provider.wallet?.communicator) { | ||
| // @ts-ignore - accessing private property for testing | ||
| provider.wallet.communicator.onDisconnectCallback?.(); | ||
| } | ||
| expect(userDisconnectCallback).toHaveBeenCalledTimes(1); | ||
| expect(providerDisconnectCalled).toBe(true); | ||
| }); | ||
| test("should handle missing user onDisconnectCallback gracefully", async () => { | ||
| let providerDisconnectCalled = false; | ||
| const provider = new GeminiWalletProvider(createMockConfig({ | ||
| // No onDisconnectCallback provided | ||
| })); | ||
| // Mock the provider disconnect to track if it's called | ||
| const originalDisconnect = provider.disconnect; | ||
| provider.disconnect = async () => { | ||
| providerDisconnectCalled = true; | ||
| return originalDisconnect.call(provider); | ||
| }; | ||
| // Simulate disconnect through the wallet's callback mechanism | ||
| // @ts-ignore - accessing private property for testing | ||
| if (provider.wallet?.communicator) { | ||
| // @ts-ignore - accessing private property for testing | ||
| provider.wallet.communicator.onDisconnectCallback?.(); | ||
| } | ||
| expect(providerDisconnectCalled).toBe(true); | ||
| }); | ||
| test("should store complete config internally", () => { | ||
| const config = createMockConfig({ | ||
| appMetadata: { | ||
| name: "Custom App", | ||
| description: "Custom Description", | ||
| url: "https://custom.com", | ||
| icons: ["icon1.png", "icon2.png"] | ||
| }, | ||
| chain: { | ||
| id: 42161, | ||
| rpcUrl: "https://custom-rpc.example.com" | ||
| } | ||
| }); | ||
| const provider = new GeminiWalletProvider(config); | ||
| expect(provider).toBeDefined(); | ||
| // @ts-ignore - accessing private property for testing | ||
| expect(provider.config).toEqual(config); | ||
| }); | ||
| test("should pass config correctly to wallet constructor", () => { | ||
| const customStorage = new GeminiStorage(); | ||
| const config = createMockConfig({ | ||
| chain: { | ||
| id: 137, // Polygon | ||
| rpcUrl: "https://polygon-rpc.example.com" | ||
| }, | ||
| storage: customStorage | ||
| }); | ||
| const provider = new GeminiWalletProvider(config); | ||
| expect(provider).toBeDefined(); | ||
| // @ts-ignore - accessing private property for testing | ||
| expect(provider.wallet?.storage).toBe(customStorage); | ||
| }); | ||
| test("should handle wallet recreation with preserved user callback", async () => { | ||
| const userDisconnectCallback = mock(); | ||
| let providerDisconnectCallCount = 0; | ||
| const provider = new GeminiWalletProvider(createMockConfig({ | ||
| onDisconnectCallback: userDisconnectCallback | ||
| })); | ||
| // Mock the provider disconnect to count calls | ||
| const originalDisconnect = provider.disconnect; | ||
| provider.disconnect = async () => { | ||
| providerDisconnectCallCount++; | ||
| return originalDisconnect.call(provider); | ||
| }; | ||
| // Set wallet to undefined to trigger recreation | ||
| // @ts-ignore - accessing private property for testing | ||
| provider.wallet = undefined; | ||
| // Simulate eth_requestAccounts which recreates wallet | ||
| try { | ||
| await provider.request({ method: "eth_requestAccounts" }); | ||
| } catch (error) { | ||
| // Expected to fail in test environment, but wallet should be recreated | ||
| } | ||
| // Verify wallet was recreated | ||
| // @ts-ignore - accessing private property for testing | ||
| expect(provider.wallet).toBeDefined(); | ||
| // Test that the recreated wallet still has the user callback | ||
| // @ts-ignore - accessing private property for testing | ||
| if (provider.wallet?.communicator) { | ||
| // @ts-ignore - accessing private property for testing | ||
| provider.wallet.communicator.onDisconnectCallback?.(); | ||
| } | ||
| expect(userDisconnectCallback).toHaveBeenCalled(); | ||
| expect(providerDisconnectCallCount).toBeGreaterThan(0); | ||
| }); | ||
| test("should support custom chain configuration", () => { | ||
| const customChain = { | ||
| id: 8453, // Base | ||
| rpcUrl: "https://base-mainnet.example.com" | ||
| }; | ||
| const provider = new GeminiWalletProvider(createMockConfig({ | ||
| chain: customChain | ||
| })); | ||
| expect(provider).toBeDefined(); | ||
| // @ts-ignore - accessing private property for testing | ||
| expect(provider.config.chain).toEqual(customChain); | ||
| }); | ||
| }); |
| import { describe, expect, test } from "bun:test"; | ||
| import { calculateWalletAddress, generateAuthenticatorIdHash, validateWebAuthnKey } from "./calculateWalletAddress"; | ||
| describe("calculateWalletAddress", () => { | ||
| test("should calculate exact wallet address", () => { | ||
| const publicKey = "0x900fb1e17b7766916a8dad6f8a26b3dbc4fe4f9b1ea5f2d20b7cb31e44c5ff54e63df1865b444a4e7b74a33ef8e3a269f77a6ba5afd072fc641ad5c7f9d626c7" as const; | ||
| const credentialId = "XJ980eHLIRtTop-iX4-wAtSUQ-GxPv_6JIprPE2nN-RBgfJKZPWEWzC-amiRxzfjpks_7q7A8Q"; | ||
| const calculatedAddress = calculateWalletAddress({ | ||
| publicKey, | ||
| credentialId, | ||
| }); | ||
| const expectedAddress = "0xce97D39F2c1f19d0F3B44f735Cd7A8a6FB29F9E3"; | ||
| console.log("Function API - Calculated:", calculatedAddress); | ||
| console.log("Function API - Expected:", expectedAddress); | ||
| expect(calculatedAddress.toLowerCase()).toBe(expectedAddress.toLowerCase()); | ||
| }); | ||
| test("should validate WebAuthn keys correctly", () => { | ||
| const publicKey = "0x900fb1e17b7766916a8dad6f8a26b3dbc4fe4f9b1ea5f2d20b7cb31e44c5ff54e63df1865b444a4e7b74a33ef8e3a269f77a6ba5afd072fc641ad5c7f9d626c7"; | ||
| const pubKeyX = `0x${publicKey.slice(2, 66)}`; | ||
| const pubKeyY = `0x${publicKey.slice(66, 130)}`; | ||
| const webAuthnData = { | ||
| pubKeyX: BigInt(pubKeyX), | ||
| pubKeyY: BigInt(pubKeyY), | ||
| }; | ||
| const isValid = validateWebAuthnKey(webAuthnData); | ||
| expect(isValid).toBe(true); | ||
| console.log("WebAuthn key validation passed"); | ||
| }); | ||
| test("should generate correct authenticator ID hash", () => { | ||
| const credentialId = "XJ980eHLIRtTop-iX4-wAtSUQ-GxPv_6JIprPE2nN-RBgfJKZPWEWzC-amiRxzfjpks_7q7A8Q"; | ||
| const hash = generateAuthenticatorIdHash(credentialId); | ||
| const expectedHash = "0xa919a485eff73c853844904a444f102f42d302320d3fee7c64136b0f4ef8357c"; | ||
| console.log("Generated hash:", hash); | ||
| console.log("Expected hash:", expectedHash); | ||
| expect(hash.toLowerCase()).toBe(expectedHash.toLowerCase()); | ||
| }); | ||
| test("should throw error for invalid public key", () => { | ||
| expect(() => { | ||
| calculateWalletAddress({ | ||
| publicKey: "0xinvalid", | ||
| credentialId: "test", | ||
| }); | ||
| }).toThrow("Invalid public key: must be 64-byte hex string (0x + 128 chars)"); | ||
| }); | ||
| test("should use default index of 0", () => { | ||
| const publicKey = "0x900fb1e17b7766916a8dad6f8a26b3dbc4fe4f9b1ea5f2d20b7cb31e44c5ff54e63df1865b444a4e7b74a33ef8e3a269f77a6ba5afd072fc641ad5c7f9d626c7" as const; | ||
| const credentialId = "XJ980eHLIRtTop-iX4-wAtSUQ-GxPv_6JIprPE2nN-RBgfJKZPWEWzC-amiRxzfjpks_7q7A8Q"; | ||
| const address1 = calculateWalletAddress({ publicKey, credentialId }); | ||
| const address2 = calculateWalletAddress({ publicKey, credentialId, index: 0n }); | ||
| expect(address1).toBe(address2); | ||
| }); | ||
| test("should calculate address for second test wallet", () => { | ||
| const publicKey = "0x69933403b13f813f8417b5ef0716f39151dd58702aead4f7e991b5fb80bc868f54baf92948c91613d52a891534927c10a4b6b19bbffef9815459ebd77ea690a6" as const; | ||
| const credentialId = "2X4LvYKqkmbs89vIzAMcOFtw58y4uBIjWRMZUlJ43zc"; | ||
| const calculatedAddress = calculateWalletAddress({ | ||
| publicKey, | ||
| credentialId, | ||
| }); | ||
| const expectedAddress = "0x3B3CA0de38c7aa794775E183f4A0D428251d6781"; | ||
| console.log("Second wallet - Calculated:", calculatedAddress); | ||
| console.log("Second wallet - Expected:", expectedAddress); | ||
| expect(calculatedAddress.toLowerCase()).toBe(expectedAddress.toLowerCase()); | ||
| }); | ||
| }); |
| import { | ||
| type Address, | ||
| encodeAbiParameters, | ||
| encodeFunctionData, | ||
| encodePacked, | ||
| getCreate2Address, | ||
| type Hex, | ||
| keccak256, | ||
| } from "viem"; | ||
| // WebAuthn validator data structure | ||
| export interface WebAuthnValidatorData { | ||
| pubKeyX: bigint; | ||
| pubKeyY: bigint; | ||
| } | ||
| // Parameters for calculating wallet address | ||
| export interface CalculateWalletAddressParams { | ||
| publicKey: Hex; // Combined 64-byte hex string (32 bytes X + 32 bytes Y) | ||
| credentialId: string; // Base64URL encoded credential ID | ||
| index?: bigint; // Optional, defaults to 0 | ||
| } | ||
| // Embedded contract addresses for Horizon deployment | ||
| const CONTRACT_ADDRESSES = { | ||
| ACCOUNT_IMPLEMENTATION: "0x0006050168DE255a8672ACaD4821e721CBA44337" as const, | ||
| ATTESTER: "0x000474392a9cd86a4687354f1Ce2964B52e97484" as const, | ||
| BOOTSTRAPPER: "0x00000000D3254452a909E4eeD47455Af7E27C289" as const, | ||
| FACTORY: "0x00E58DF70FaB983a324c4C068c82d20407579FaC" as const, | ||
| REGISTRY: "0x000000000069E2a187AEFFb852bF3cCdC95151B2" as const, | ||
| WEBAUTHN_VALIDATOR: "0xbA45a2BFb8De3D24cA9D7F1B551E14dFF5d690Fd" as const, | ||
| }; | ||
| /** | ||
| * Calculate smart wallet address from public key and credential ID | ||
| * This handles all validation and setup internally | ||
| */ | ||
| export function calculateWalletAddress( | ||
| params: CalculateWalletAddressParams, | ||
| ): Address { | ||
| const { publicKey, credentialId, index = 0n } = params; | ||
| // Validate input | ||
| if (!publicKey.startsWith("0x") || publicKey.length !== 130) { | ||
| throw new Error( | ||
| "Invalid public key: must be 64-byte hex string (0x + 128 chars)", | ||
| ); | ||
| } | ||
| // Extract X and Y coordinates | ||
| const pubKeyX = `0x${publicKey.slice(2, 66)}` as Hex; | ||
| const pubKeyY = `0x${publicKey.slice(66, 130)}` as Hex; | ||
| // Convert to WebAuthnValidatorData | ||
| const webAuthnData: WebAuthnValidatorData = { | ||
| pubKeyX: BigInt(pubKeyX), | ||
| pubKeyY: BigInt(pubKeyY), | ||
| }; | ||
| // Validate the key is on the secp256r1 curve | ||
| if (!validateWebAuthnKey(webAuthnData)) { | ||
| throw new Error( | ||
| "Invalid WebAuthn key: coordinates are not on secp256r1 curve", | ||
| ); | ||
| } | ||
| // Calculate authenticator ID hash from credential ID | ||
| const authenticatorIdHash = generateAuthenticatorIdHash(credentialId); | ||
| // Use the internal calculation with embedded addresses | ||
| return calculateAddressInternal({ | ||
| authenticatorIdHash, | ||
| index, | ||
| webAuthnData, | ||
| }); | ||
| } | ||
| /** | ||
| * Generate authenticator ID hash from credential ID | ||
| */ | ||
| export function generateAuthenticatorIdHash(credentialId: string): Hex { | ||
| // Convert base64url to bytes | ||
| const padding = "=".repeat((4 - (credentialId.length % 4)) % 4); | ||
| const base64 = credentialId.replace(/-/g, "+").replace(/_/g, "/") + padding; | ||
| const binaryString = atob(base64); | ||
| const bytes = new Uint8Array(binaryString.length); | ||
| for (let i = 0; i < binaryString.length; i++) { | ||
| bytes[i] = binaryString.charCodeAt(i); | ||
| } | ||
| return keccak256(bytes); | ||
| } | ||
| /** | ||
| * Validate WebAuthn public key offchain | ||
| * Mirrors the contract's _validateWebAuthnKey function | ||
| */ | ||
| export function validateWebAuthnKey( | ||
| webAuthnData: WebAuthnValidatorData, | ||
| ): boolean { | ||
| const SECP256R1_P = | ||
| 0xffffffff00000001000000000000000000000000ffffffffffffffffffffffffn; | ||
| const SECP256R1_B = | ||
| 0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604bn; | ||
| const { pubKeyX, pubKeyY } = webAuthnData; | ||
| // Check if coordinates are valid | ||
| if ( | ||
| pubKeyX === 0n || | ||
| pubKeyY === 0n || | ||
| pubKeyX >= SECP256R1_P || | ||
| pubKeyY >= SECP256R1_P | ||
| ) { | ||
| return false; | ||
| } | ||
| // Validate curve membership: Y² ≡ X³ - 3X + B (mod P) | ||
| const ySquared = (pubKeyY * pubKeyY) % SECP256R1_P; | ||
| const xCubed = (pubKeyX * pubKeyX * pubKeyX) % SECP256R1_P; | ||
| const threeX = (3n * pubKeyX) % SECP256R1_P; | ||
| const rightSide = (xCubed + SECP256R1_P - threeX + SECP256R1_B) % SECP256R1_P; | ||
| return ySquared === rightSide; | ||
| } | ||
| /** | ||
| * Internal calculation method using embedded contract addresses | ||
| */ | ||
| function calculateAddressInternal(params: { | ||
| webAuthnData: WebAuthnValidatorData; | ||
| authenticatorIdHash: Hex; | ||
| index: bigint; | ||
| }): Address { | ||
| const { webAuthnData, authenticatorIdHash, index } = params; | ||
| // Use embedded contract addresses | ||
| const factoryAddress = CONTRACT_ADDRESSES.FACTORY; | ||
| const accountImplementation = CONTRACT_ADDRESSES.ACCOUNT_IMPLEMENTATION; | ||
| const webAuthnValidator = CONTRACT_ADDRESSES.WEBAUTHN_VALIDATOR; | ||
| const attester = CONTRACT_ADDRESSES.ATTESTER; | ||
| const bootstrapper = CONTRACT_ADDRESSES.BOOTSTRAPPER; | ||
| const registry = CONTRACT_ADDRESSES.REGISTRY; | ||
| // Generate cross-chain consistent salt (same as contract) | ||
| const salt = keccak256( | ||
| encodePacked( | ||
| ["uint256", "uint256", "bytes32", "uint256"], | ||
| [webAuthnData.pubKeyX, webAuthnData.pubKeyY, authenticatorIdHash, index], | ||
| ), | ||
| ); | ||
| // Prepare validator initialization data (WebAuthnValidatorData + authenticatorIdHash) | ||
| const validatorInitData = encodeAbiParameters( | ||
| [ | ||
| { | ||
| components: [ | ||
| { name: "pubKeyX", type: "uint256" }, | ||
| { name: "pubKeyY", type: "uint256" }, | ||
| ], | ||
| type: "tuple", | ||
| }, | ||
| { type: "bytes32" }, | ||
| ], | ||
| [webAuthnData, authenticatorIdHash], | ||
| ); | ||
| // Create RegistryConfig struct | ||
| const registryConfig = { | ||
| attesters: [attester], | ||
| registry, | ||
| threshold: 1n, | ||
| }; | ||
| // Encode the bootstrap call | ||
| const bootstrapCall = encodeFunctionData({ | ||
| abi: [ | ||
| { | ||
| inputs: [ | ||
| { name: "validator", type: "address" }, | ||
| { name: "validatorInitData", type: "bytes" }, | ||
| { | ||
| components: [ | ||
| { name: "registry", type: "address" }, | ||
| { name: "attesters", type: "address[]" }, | ||
| { name: "threshold", type: "uint8" }, | ||
| ], | ||
| name: "registryConfig", | ||
| type: "tuple", | ||
| }, | ||
| ], | ||
| name: "initNexusWithSingleValidator", | ||
| type: "function", | ||
| }, | ||
| ], | ||
| args: [webAuthnValidator, validatorInitData, registryConfig], | ||
| functionName: "initNexusWithSingleValidator", | ||
| }); | ||
| // Format initialization data as expected by ProxyLib | ||
| const initData = encodeAbiParameters( | ||
| [{ type: "address" }, { type: "bytes" }], | ||
| [bootstrapper, bootstrapCall], | ||
| ); | ||
| // Calculate CREATE2 address using the same logic as ProxyLib.predictProxyAddress | ||
| return predictProxyAddress( | ||
| accountImplementation, | ||
| salt, | ||
| initData, | ||
| factoryAddress, | ||
| ); | ||
| } | ||
| /** | ||
| * Predicts the proxy address using CREATE2 | ||
| * Mirrors ProxyLib.predictProxyAddress functionality exactly | ||
| */ | ||
| function predictProxyAddress( | ||
| implementation: Address, | ||
| salt: Hex, | ||
| initData: Hex, | ||
| deployer: Address, | ||
| ): Address { | ||
| // Encode the call to INexus.initializeAccount with initData | ||
| const initializeCall = encodeFunctionData({ | ||
| abi: [ | ||
| { | ||
| inputs: [{ name: "data", type: "bytes" }], | ||
| name: "initializeAccount", | ||
| type: "function", | ||
| }, | ||
| ], | ||
| args: [initData], | ||
| functionName: "initializeAccount", | ||
| }); | ||
| // Encode constructor arguments for NexusProxy | ||
| const constructorArgs = encodeAbiParameters( | ||
| [{ type: "address" }, { type: "bytes" }], | ||
| [implementation, initializeCall], | ||
| ); | ||
| // Calculate initCodeHash using actual compiled NexusProxy creation bytecode | ||
| const nexusProxyCreationCode = | ||
| "0x60806040526102c8803803806100148161018c565b92833981016040828203126101885781516001600160a01b03811692909190838303610188576020810151906001600160401b03821161018857019281601f8501121561018857835161006e610069826101c5565b61018c565b9481865260208601936020838301011161018857815f926020809301865e8601015260017f90b772c2cb8a51aa7a8a65fc23543c6d022d5b3f8e2b92eed79fba7eef8293005d823b15610176577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc80546001600160a01b031916821790557fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b5f80a282511561015e575f8091610146945190845af43d15610156573d91610137610069846101c5565b9283523d5f602085013e6101e0565b505b6040516089908161023f8239f35b6060916101e0565b50505034156101485763b398979f60e01b5f5260045ffd5b634c9c8ce360e01b5f5260045260245ffd5b5f80fd5b6040519190601f01601f191682016001600160401b038111838210176101b157604052565b634e487b7160e01b5f52604160045260245ffd5b6001600160401b0381116101b157601f01601f191660200190565b9061020457508051156101f557805190602001fd5b63d6bda27560e01b5f5260045ffd5b81511580610235575b610215575090565b639996b31560e01b5f9081526001600160a01b0391909116600452602490fd5b50803b1561020d56fe608060405236156051577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc545f9081906001600160a01b0316368280378136915af43d5f803e15604d573d5ff35b3d5ffd5b00fea264697066735822122041b5f70a351952142223f22504ca7b4e6d975f3a302d114ff820442fcf815ac264736f6c634300081b0033" as const; | ||
| const initCodeHash = keccak256( | ||
| encodePacked(["bytes", "bytes"], [nexusProxyCreationCode, constructorArgs]), | ||
| ); | ||
| // Standard CREATE2 formula | ||
| return getCreate2Address({ | ||
| bytecodeHash: initCodeHash, | ||
| from: deployer, | ||
| salt, | ||
| }); | ||
| } |
| import { ENS_API_URL } from "@/constants"; | ||
| import type { ReverseEnsResponse } from "@/types"; | ||
| import type { Address } from "viem"; | ||
| export async function reverseResolveEns( | ||
| address: Address, | ||
| ): Promise<ReverseEnsResponse> { | ||
| try { | ||
| const response = await fetch(`${ENS_API_URL}/reverse/${address}`); | ||
| if (!response.ok) { | ||
| throw new Error( | ||
| `ENS API request failed: ${response.status} ${response.statusText}`, | ||
| ); | ||
| } | ||
| const data: ReverseEnsResponse = await response.json(); | ||
| return { | ||
| address: data.address, | ||
| name: data.name || null, | ||
| }; | ||
| } catch (error) { | ||
| console.error("Failed to resolve ENS name:", error); | ||
| return { | ||
| address, | ||
| name: null, | ||
| }; | ||
| } | ||
| } |
| export declare const SDK_BACKEND_URL = "https://keys.gemini.com"; | ||
| export declare const SDK_VERSION = "0.1.0"; | ||
| export declare const ENS_API_URL = "https://horizon-api.gemini.com/api/ens"; | ||
| export declare const SDK_VERSION = "0.2.0"; | ||
| export declare const DEFAULT_CHAIN_ID = 42161; | ||
| export declare const MAINNET_CHAIN_IDS: { | ||
| readonly ARBITRUM_ONE: 42161; | ||
| readonly BASE: 8453; | ||
| readonly ETHEREUM: 1; | ||
| readonly ARBITRUM_ONE: 42161; | ||
| readonly OP_MAINNET: 10; | ||
| readonly BASE: 8453; | ||
| readonly POLYGON: 137; | ||
| }; | ||
| export declare const TESTNET_CHAIN_IDS: { | ||
| readonly SEPOLIA: 11155111; | ||
| readonly ARBITRUM_SEPOLIA: 421614; | ||
| readonly BASE_SEPOLIA: 84532; | ||
| readonly OP_SEPOLIA: 11155420; | ||
| readonly BASE_SEPOLIA: 84532; | ||
| readonly POLYGON_AMOY: 80002; | ||
| readonly SEPOLIA: 11155111; | ||
| }; | ||
| export declare const SUPPORTED_CHAIN_IDS: (1 | 10 | 42161 | 8453 | 137 | 11155111 | 421614 | 11155420 | 84532 | 80002)[]; | ||
| export declare const SUPPORTED_CHAIN_IDS: (1 | 10 | 42161 | 8453 | 137 | 421614 | 84532 | 11155420 | 80002 | 11155111)[]; | ||
| export declare function getDefaultRpcUrl(chainId: number): string | undefined; | ||
| export declare const POPUP_WIDTH = 420; | ||
| export declare const POPUP_HEIGHT = 650; | ||
| //# sourceMappingURL=constants.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AAGtC,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC;AAGX,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC;AAGX,eAAO,MAAM,mBAAmB,gFAG/B,CAAC;AAGF,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,YAAY,MAAM,CAAC"} | ||
| {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAaA,eAAO,MAAM,eAAe,4BAA4B,CAAC;AACzD,eAAO,MAAM,WAAW,2CAA2C,CAAC;AACpE,eAAO,MAAM,WAAW,UAAU,CAAC;AACnC,eAAO,MAAM,gBAAgB,QAAQ,CAAC;AAGtC,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC;AAGX,eAAO,MAAM,iBAAiB;;;;;;CAMpB,CAAC;AAGX,eAAO,MAAM,mBAAmB,gFAG/B,CAAC;AAGF,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAepE;AAGD,eAAO,MAAM,WAAW,MAAM,CAAC;AAC/B,eAAO,MAAM,YAAY,MAAM,CAAC"} |
+5
-4
@@ -5,8 +5,9 @@ export { Communicator } from "./communicator"; | ||
| export { GeminiWallet } from "./wallets"; | ||
| export type { IStorage } from "./storage"; | ||
| export { GeminiStorage, STORAGE_ETH_ACCOUNTS_KEY, STORAGE_ETH_ACTIVE_CHAIN_KEY, STORAGE_PASSKEY_CREDENTIAL_KEY, STORAGE_SETTINGS_KEY, STORAGE_SMART_ACCOUNT_KEY, } from "./storage"; | ||
| export type { IStorage } from "./storage"; | ||
| export type { AppMetadata, AppContext, Chain, PlatformType, GeminiProviderConfig, RpcRequestArgs, ProviderRpcError, ProviderEventMap, ProviderEventCallback, ProviderInterface, GeminiSdkMessage, GeminiSdkMessageResponse, ConnectResponse, SendTransactionResponse, SignMessageResponse, SignTypedDataResponse, SwitchChainResponse, GeminiSdkSendTransaction, GeminiSdkSignMessage, GeminiSdkSignTypedData, GeminiSdkSwitchChain, GeminiSdkAppContextMessage, } from "./types"; | ||
| export type { AppContext, AppMetadata, Chain, ConnectResponse, GeminiProviderConfig, GeminiSdkAppContextMessage, GeminiSdkMessage, GeminiSdkMessageResponse, GeminiSdkSendTransaction, GeminiSdkSignMessage, GeminiSdkSignTypedData, GeminiSdkSwitchChain, PlatformType, ProviderEventCallback, ProviderEventMap, ProviderInterface, ProviderRpcError, ReverseEnsResponse, RpcRequestArgs, SendTransactionResponse, SignMessageResponse, SignTypedDataResponse, SwitchChainResponse, } from "./types"; | ||
| export { GeminiSdkEvent, ProviderEventEmitter } from "./types"; | ||
| export { openPopup, closePopup, generateRequestId, hexStringFromNumber, encodeBase64, decodeBase64, bufferToBase64URLString, utf8StringToBuffer, base64ToHex, safeJsonStringify } from "./utils"; | ||
| export { SDK_BACKEND_URL, SDK_VERSION, DEFAULT_CHAIN_ID, POPUP_WIDTH, POPUP_HEIGHT } from "./constants"; | ||
| export type { CalculateWalletAddressParams, WebAuthnValidatorData, } from "./utils"; | ||
| export { base64ToHex, bufferToBase64URLString, calculateWalletAddress, closePopup, decodeBase64, encodeBase64, generateAuthenticatorIdHash, generateRequestId, hexStringFromNumber, openPopup, reverseResolveEns, safeJsonStringify, utf8StringToBuffer, validateWebAuthnKey, } from "./utils"; | ||
| export { DEFAULT_CHAIN_ID, POPUP_HEIGHT, POPUP_WIDTH, SDK_BACKEND_URL, SDK_VERSION, } from "./constants"; | ||
| //# sourceMappingURL=index.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,cAAc,2BAA2B,CAAC;AAG1C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,4BAA4B,EAC5B,8BAA8B,EAC9B,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG1C,YAAY,EACV,WAAW,EACX,UAAU,EACV,KAAK,EACL,YAAY,EACZ,oBAAoB,EACpB,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,qBAAqB,EACrB,iBAAiB,EACjB,gBAAgB,EAChB,wBAAwB,EACxB,eAAe,EACf,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,0BAA0B,GAC3B,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,EACL,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,uBAAuB,EACvB,kBAAkB,EAClB,WAAW,EACX,iBAAiB,EAClB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,YAAY,EACb,MAAM,aAAa,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAClD,cAAc,2BAA2B,CAAC;AAG1C,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAGzC,YAAY,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,4BAA4B,EAC5B,8BAA8B,EAC9B,oBAAoB,EACpB,yBAAyB,GAC1B,MAAM,WAAW,CAAC;AAGnB,YAAY,EACV,UAAU,EACV,WAAW,EACX,KAAK,EACL,eAAe,EACf,oBAAoB,EACpB,0BAA0B,EAC1B,gBAAgB,EAChB,wBAAwB,EACxB,wBAAwB,EACxB,oBAAoB,EACpB,sBAAsB,EACtB,oBAAoB,EACpB,YAAY,EACZ,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,uBAAuB,EACvB,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAG/D,YAAY,EACV,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,SAAS,CAAC;AACjB,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,sBAAsB,EACtB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,2BAA2B,EAC3B,iBAAiB,EACjB,mBAAmB,EACnB,SAAS,EACT,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,EAClB,mBAAmB,GACpB,MAAM,SAAS,CAAC;AAGjB,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,eAAe,EACf,WAAW,GACZ,MAAM,aAAa,CAAC"} |
@@ -8,4 +8,5 @@ import { type GeminiProviderConfig, ProviderEventEmitter, type ProviderInterface, type RpcRequestArgs } from "@/types"; | ||
| openSettings(): Promise<void>; | ||
| reverseResolveEns(address: string): Promise<import("@/types").ReverseEnsResponse>; | ||
| disconnect(): Promise<void>; | ||
| } | ||
| //# sourceMappingURL=provider.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/provider/provider.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAgBjB,qBAAa,oBACX,SAAQ,oBACR,YAAW,iBAAiB;IAE5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,MAAM,CAAuC;gBAEzC,cAAc,EAAE,QAAQ,CAAC,oBAAoB,CAAC;IAS7C,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IA0KnD,YAAY;IAIZ,UAAU;CAOjB"} | ||
| {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/provider/provider.ts"],"names":[],"mappings":"AAYA,OAAO,EACL,KAAK,oBAAoB,EACzB,oBAAoB,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACpB,MAAM,SAAS,CAAC;AAgBjB,qBAAa,oBACX,SAAQ,oBACR,YAAW,iBAAiB;IAE5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuB;IAC9C,OAAO,CAAC,MAAM,CAAuC;gBAEzC,cAAc,EAAE,QAAQ,CAAC,oBAAoB,CAAC;IAiB7C,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC;IAoLnD,YAAY;IAKZ,iBAAiB,CAAC,OAAO,EAAE,MAAM;IAIjC,UAAU;CAWjB"} |
+4
-0
@@ -127,2 +127,6 @@ import { EventEmitter } from "eventemitter3"; | ||
| } | ||
| export interface ReverseEnsResponse { | ||
| address: Address; | ||
| name: string | null; | ||
| } | ||
| //# sourceMappingURL=types.d.ts.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"} | ||
| {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"} |
| export { base64ToHex, bufferToBase64URLString, decodeBase64, encodeBase64, utf8StringToBuffer, } from "./base64"; | ||
| export type { CalculateWalletAddressParams, WebAuthnValidatorData, } from "./calculateWalletAddress"; | ||
| export { calculateWalletAddress, generateAuthenticatorIdHash, validateWebAuthnKey, } from "./calculateWalletAddress"; | ||
| export { reverseResolveEns } from "./ens"; | ||
| export { closePopup, openPopup } from "./popup"; | ||
@@ -3,0 +6,0 @@ export { hexStringFromNumber, safeJsonStringify } from "./strings"; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnE,eAAO,MAAM,iBAAiB,QAAO,MAA6B,CAAC"} | ||
| {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,YAAY,EACV,4BAA4B,EAC5B,qBAAqB,GACtB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAEnE,eAAO,MAAM,iBAAiB,QAAO,MAA6B,CAAC"} |
| import { type Address, type SignMessageParameters, type SignTypedDataParameters, type SwitchChainParameters, type TransactionRequest } from "viem"; | ||
| import { type IStorage } from "@/storage"; | ||
| import { type Chain, type GeminiProviderConfig, type SendTransactionResponse, type SignMessageResponse, type SignTypedDataResponse } from "@/types"; | ||
@@ -11,5 +10,3 @@ export declare function isChainSupportedByGeminiSw(chainId: number): boolean; | ||
| chain: Chain; | ||
| constructor({ appMetadata, chain, onDisconnectCallback, storage, }: Readonly<GeminiProviderConfig & { | ||
| storage?: IStorage; | ||
| }>); | ||
| constructor({ appMetadata, chain, onDisconnectCallback, storage, }: Readonly<GeminiProviderConfig>); | ||
| private initializeFromStorage; | ||
@@ -16,0 +13,0 @@ private ensureInitialized; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/wallets/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACxB,MAAM,MAAM,CAAC;AAGd,OAAO,EAEL,KAAK,QAAQ,EAGd,MAAM,WAAW,CAAC;AACnB,OAAO,EACL,KAAK,KAAK,EAEV,KAAK,oBAAoB,EAOzB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAE3B,MAAM,SAAS,CAAC;AAEjB,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAInE;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,OAAO,CAAC,WAAW,CAAgB;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAM;IACzB,KAAK,EAAE,KAAK,CAA4B;gBAEnC,EACV,WAAW,EACX,KAAK,EACL,oBAAoB,EACpB,OAAO,GACR,EAAE,QAAQ,CAAC,oBAAoB,GAAG;QAAE,OAAO,CAAC,EAAE,QAAQ,CAAA;KAAE,CAAC;YAY5C,qBAAqB;YAerB,iBAAiB;IAIzB,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAiB7B,WAAW,CAAC,EAChB,EAAE,GACH,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA0BhD,eAAe,CACnB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAerC,QAAQ,CAAC,EACb,OAAO,GACR,EAAE,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAezD,aAAa,CAAC,EAClB,OAAO,EACP,KAAK,EACL,WAAW,EACX,MAAM,GACP,EAAE,uBAAuB,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAmB7D,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAUnC,OAAO,CAAC,kBAAkB;CAS3B"} | ||
| {"version":3,"file":"wallet.d.ts","sourceRoot":"","sources":["../../src/wallets/wallet.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EACZ,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,kBAAkB,EACxB,MAAM,MAAM,CAAC;AAad,OAAO,EACL,KAAK,KAAK,EAEV,KAAK,oBAAoB,EAOzB,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAE3B,MAAM,SAAS,CAAC;AAEjB,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAInE;AAED,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAW;IACnC,OAAO,CAAC,WAAW,CAAgB;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAM;IACzB,KAAK,EAAE,KAAK,CAA4B;gBAEnC,EACV,WAAW,EACX,KAAK,EACL,oBAAoB,EACpB,OAAO,GACR,EAAE,QAAQ,CAAC,oBAAoB,CAAC;YAanB,qBAAqB;YAyBrB,iBAAiB;IAIzB,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;IAiB7B,WAAW,CAAC,EAChB,EAAE,GACH,EAAE,qBAAqB,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IA6BhD,eAAe,CACnB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,uBAAuB,CAAC,MAAM,CAAC,CAAC;IAerC,QAAQ,CAAC,EACb,OAAO,GACR,EAAE,qBAAqB,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAezD,aAAa,CAAC,EAClB,OAAO,EACP,KAAK,EACL,WAAW,EACX,MAAM,GACP,EAAE,uBAAuB,GAAG,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;IAmB7D,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAUnC,OAAO,CAAC,kBAAkB;CAS3B"} |
+1
-1
| { | ||
| "name": "@gemini-wallet/core", | ||
| "version": "0.1.1", | ||
| "version": "0.2.0", | ||
| "description": "Core SDK for Gemini Wallet integration with popup communication", | ||
@@ -5,0 +5,0 @@ "main": "./dist/index.js", |
+38
-6
@@ -0,3 +1,17 @@ | ||
| import { | ||
| arbitrum, | ||
| arbitrumSepolia, | ||
| base, | ||
| baseSepolia, | ||
| mainnet, | ||
| optimism, | ||
| optimismSepolia, | ||
| polygon, | ||
| polygonAmoy, | ||
| sepolia, | ||
| } from "viem/chains"; | ||
| export const SDK_BACKEND_URL = "https://keys.gemini.com"; | ||
| export const SDK_VERSION = "0.1.0"; | ||
| export const ENS_API_URL = "https://horizon-api.gemini.com/api/ens"; | ||
| export const SDK_VERSION = "0.2.0"; | ||
| export const DEFAULT_CHAIN_ID = 42161; // Arbitrum One | ||
@@ -7,6 +21,6 @@ | ||
| export const MAINNET_CHAIN_IDS = { | ||
| ARBITRUM_ONE: 42161, | ||
| BASE: 8453, | ||
| ETHEREUM: 1, | ||
| ARBITRUM_ONE: 42161, | ||
| OP_MAINNET: 10, | ||
| BASE: 8453, | ||
| POLYGON: 137, | ||
@@ -17,7 +31,7 @@ } as const; | ||
| export const TESTNET_CHAIN_IDS = { | ||
| SEPOLIA: 11155111, | ||
| ARBITRUM_SEPOLIA: 421614, | ||
| BASE_SEPOLIA: 84532, | ||
| OP_SEPOLIA: 11155420, | ||
| BASE_SEPOLIA: 84532, | ||
| POLYGON_AMOY: 80002, | ||
| SEPOLIA: 11155111, | ||
| } as const; | ||
@@ -31,4 +45,22 @@ | ||
| // Helper function to get default RPC URL for a chain using viem chains | ||
| export function getDefaultRpcUrl(chainId: number): string | undefined { | ||
| const chainMap: Record<number, string> = { | ||
| [mainnet.id]: mainnet.rpcUrls.default.http[0], | ||
| [arbitrum.id]: arbitrum.rpcUrls.default.http[0], | ||
| [optimism.id]: optimism.rpcUrls.default.http[0], | ||
| [base.id]: base.rpcUrls.default.http[0], | ||
| [polygon.id]: polygon.rpcUrls.default.http[0], | ||
| [sepolia.id]: sepolia.rpcUrls.default.http[0], | ||
| [arbitrumSepolia.id]: arbitrumSepolia.rpcUrls.default.http[0], | ||
| [optimismSepolia.id]: optimismSepolia.rpcUrls.default.http[0], | ||
| [baseSepolia.id]: baseSepolia.rpcUrls.default.http[0], | ||
| [polygonAmoy.id]: polygonAmoy.rpcUrls.default.http[0], | ||
| }; | ||
| return chainMap[chainId]; | ||
| } | ||
| // Popup window dimensions | ||
| export const POPUP_WIDTH = 420; | ||
| export const POPUP_HEIGHT = 650; | ||
| export const POPUP_HEIGHT = 650; |
+35
-27
@@ -12,2 +12,3 @@ // Main exports | ||
| // Storage exports | ||
| export type { IStorage } from "./storage"; | ||
| export { | ||
@@ -21,19 +22,24 @@ GeminiStorage, | ||
| } from "./storage"; | ||
| export type { IStorage } from "./storage"; | ||
| // Type exports | ||
| export type { | ||
| AppContext, | ||
| AppMetadata, | ||
| AppContext, | ||
| Chain, | ||
| ConnectResponse, | ||
| GeminiProviderConfig, | ||
| GeminiSdkAppContextMessage, | ||
| GeminiSdkMessage, | ||
| GeminiSdkMessageResponse, | ||
| GeminiSdkSendTransaction, | ||
| GeminiSdkSignMessage, | ||
| GeminiSdkSignTypedData, | ||
| GeminiSdkSwitchChain, | ||
| PlatformType, | ||
| GeminiProviderConfig, | ||
| RpcRequestArgs, | ||
| ProviderRpcError, | ||
| ProviderEventCallback, | ||
| ProviderEventMap, | ||
| ProviderEventCallback, | ||
| ProviderInterface, | ||
| GeminiSdkMessage, | ||
| GeminiSdkMessageResponse, | ||
| ConnectResponse, | ||
| ProviderRpcError, | ||
| ReverseEnsResponse, | ||
| RpcRequestArgs, | ||
| SendTransactionResponse, | ||
@@ -43,32 +49,34 @@ SignMessageResponse, | ||
| SwitchChainResponse, | ||
| GeminiSdkSendTransaction, | ||
| GeminiSdkSignMessage, | ||
| GeminiSdkSignTypedData, | ||
| GeminiSdkSwitchChain, | ||
| GeminiSdkAppContextMessage, | ||
| } from "./types"; | ||
| export { GeminiSdkEvent, ProviderEventEmitter } from "./types"; | ||
| // Utility exports | ||
| export { | ||
| openPopup, | ||
| export type { | ||
| CalculateWalletAddressParams, | ||
| WebAuthnValidatorData, | ||
| } from "./utils"; | ||
| export { | ||
| base64ToHex, | ||
| bufferToBase64URLString, | ||
| calculateWalletAddress, | ||
| closePopup, | ||
| decodeBase64, | ||
| encodeBase64, | ||
| generateAuthenticatorIdHash, | ||
| generateRequestId, | ||
| hexStringFromNumber, | ||
| encodeBase64, | ||
| decodeBase64, | ||
| bufferToBase64URLString, | ||
| openPopup, | ||
| reverseResolveEns, | ||
| safeJsonStringify, | ||
| utf8StringToBuffer, | ||
| base64ToHex, | ||
| safeJsonStringify | ||
| validateWebAuthnKey, | ||
| } from "./utils"; | ||
| // Constants | ||
| export { | ||
| SDK_BACKEND_URL, | ||
| SDK_VERSION, | ||
| export { | ||
| DEFAULT_CHAIN_ID, | ||
| POPUP_HEIGHT, | ||
| POPUP_WIDTH, | ||
| POPUP_HEIGHT | ||
| } from "./constants"; | ||
| SDK_BACKEND_URL, | ||
| SDK_VERSION, | ||
| } from "./constants"; |
@@ -19,3 +19,3 @@ import { | ||
| } from "@/types"; | ||
| import { hexStringFromNumber } from "@/utils"; | ||
| import { hexStringFromNumber, reverseResolveEns } from "@/utils"; | ||
| import { GeminiWallet } from "@/wallets"; | ||
@@ -45,5 +45,13 @@ import { | ||
| this.config = providerConfig; | ||
| // Preserve user's disconnect callback while adding provider cleanup | ||
| const userDisconnectCallback = providerConfig.onDisconnectCallback; | ||
| this.wallet = new GeminiWallet({ | ||
| ...providerConfig, | ||
| onDisconnectCallback: this.disconnect.bind(this), | ||
| onDisconnectCallback: () => { | ||
| // Call user's callback first | ||
| userDisconnectCallback?.(); | ||
| // Then handle provider cleanup | ||
| this.disconnect(); | ||
| }, | ||
| }); | ||
@@ -59,6 +67,16 @@ } | ||
| case "eth_requestAccounts": { | ||
| this.wallet = new GeminiWallet({ | ||
| ...this.config, | ||
| onDisconnectCallback: this.disconnect.bind(this), | ||
| }); | ||
| // Use existing wallet instance instead of recreating | ||
| if (!this.wallet) { | ||
| // Preserve user's disconnect callback while adding provider cleanup | ||
| const userDisconnectCallback = this.config.onDisconnectCallback; | ||
| this.wallet = new GeminiWallet({ | ||
| ...this.config, | ||
| onDisconnectCallback: () => { | ||
| // Call user's callback first | ||
| userDisconnectCallback?.(); | ||
| // Then handle provider cleanup | ||
| this.disconnect(); | ||
| }, | ||
| }); | ||
| } | ||
| await this.wallet.connect(); | ||
@@ -227,9 +245,18 @@ this.emit("accountsChanged", this.wallet.accounts); | ||
| // Custom function for reverse ENS resolution | ||
| async reverseResolveEns(address: string) { | ||
| return await reverseResolveEns(address as `0x${string}`); | ||
| } | ||
| async disconnect() { | ||
| // If wallet exists, let it handle its own storage cleanup | ||
| if (this.wallet) { | ||
| // Create a temporary storage instance with the same config to clean up | ||
| const storage = this.config.storage || new GeminiStorage(); | ||
| await storage.removeItem(STORAGE_ETH_ACCOUNTS_KEY); | ||
| await storage.removeItem(STORAGE_ETH_ACTIVE_CHAIN_KEY); | ||
| } | ||
| this.wallet = undefined; | ||
| const Storage = new GeminiStorage(); | ||
| await Storage.removeItem(STORAGE_ETH_ACCOUNTS_KEY); | ||
| await Storage.removeItem(STORAGE_ETH_ACTIVE_CHAIN_KEY); | ||
| await this.emit("disconnect", "User initiated disconnection"); | ||
| } | ||
| } |
+39
-13
| import { EventEmitter } from "eventemitter3"; | ||
| import type { Address, Hex, SignMessageParameters, SignTypedDataParameters, TransactionRequest } from "viem"; | ||
| import type { | ||
| Address, | ||
| Hex, | ||
| SignMessageParameters, | ||
| SignTypedDataParameters, | ||
| TransactionRequest, | ||
| } from "viem"; | ||
@@ -11,3 +17,3 @@ import { type IStorage } from "./storage/storageInterface"; | ||
| POPUP_APP_CONTEXT = "POPUP_APP_CONTEXT", | ||
| // SDK events | ||
@@ -78,8 +84,16 @@ SDK_CONNECT = "SDK_CONNECT", | ||
| export class ProviderEventEmitter extends EventEmitter<keyof ProviderEventMap> {} | ||
| export class ProviderEventEmitter extends EventEmitter< | ||
| keyof ProviderEventMap | ||
| > {} | ||
| export interface ProviderInterface extends ProviderEventEmitter { | ||
| disconnect(): Promise<void>; | ||
| emit<K extends keyof ProviderEventMap>(event: K, ...args: [ProviderEventMap[K]]): boolean; | ||
| on<K extends keyof ProviderEventMap>(event: K, listener: (_: ProviderEventMap[K]) => void): this; | ||
| emit<K extends keyof ProviderEventMap>( | ||
| event: K, | ||
| ...args: [ProviderEventMap[K]] | ||
| ): boolean; | ||
| on<K extends keyof ProviderEventMap>( | ||
| event: K, | ||
| listener: (_: ProviderEventMap[K]) => void, | ||
| ): this; | ||
| request(args: RpcRequestArgs): Promise<any>; | ||
@@ -103,23 +117,29 @@ } | ||
| export interface ConnectResponse extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| export interface ConnectResponse | ||
| extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| data: { address: Address }; | ||
| } | ||
| export interface SendTransactionResponse extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| export interface SendTransactionResponse | ||
| extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| data: { hash?: Hex; error?: string }; | ||
| } | ||
| export interface SignMessageResponse extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| export interface SignMessageResponse | ||
| extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| data: { hash?: Hex; error?: string }; | ||
| } | ||
| export interface SignTypedDataResponse extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| export interface SignTypedDataResponse | ||
| extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| data: { hash?: Hex; error?: string }; | ||
| } | ||
| export interface SwitchChainResponse extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| export interface SwitchChainResponse | ||
| extends Omit<GeminiSdkMessageResponse, "data"> { | ||
| data: { chainId?: number; error?: string }; | ||
| } | ||
| export interface GeminiSdkSendTransaction extends Omit<GeminiSdkMessage, "data"> { | ||
| export interface GeminiSdkSendTransaction | ||
| extends Omit<GeminiSdkMessage, "data"> { | ||
| data: TransactionRequest; | ||
@@ -140,4 +160,10 @@ } | ||
| export interface GeminiSdkAppContextMessage extends Omit<GeminiSdkMessage, "data"> { | ||
| export interface GeminiSdkAppContextMessage | ||
| extends Omit<GeminiSdkMessage, "data"> { | ||
| data: AppContext; | ||
| } | ||
| } | ||
| export interface ReverseEnsResponse { | ||
| address: Address; | ||
| name: string | null; | ||
| } |
+10
-0
@@ -8,2 +8,12 @@ export { | ||
| } from "./base64"; | ||
| export type { | ||
| CalculateWalletAddressParams, | ||
| WebAuthnValidatorData, | ||
| } from "./calculateWalletAddress"; | ||
| export { | ||
| calculateWalletAddress, | ||
| generateAuthenticatorIdHash, | ||
| validateWebAuthnKey, | ||
| } from "./calculateWalletAddress"; | ||
| export { reverseResolveEns } from "./ens"; | ||
| export { closePopup, openPopup } from "./popup"; | ||
@@ -10,0 +20,0 @@ export { hexStringFromNumber, safeJsonStringify } from "./strings"; |
+30
-12
@@ -9,4 +9,8 @@ import { | ||
| import { Communicator } from "@/communicator"; | ||
| import { DEFAULT_CHAIN_ID, SUPPORTED_CHAIN_IDS } from "@/constants"; | ||
| import { | ||
| DEFAULT_CHAIN_ID, | ||
| getDefaultRpcUrl, | ||
| SUPPORTED_CHAIN_IDS, | ||
| } from "@/constants"; | ||
| import { | ||
| GeminiStorage, | ||
@@ -51,3 +55,3 @@ type IStorage, | ||
| storage, | ||
| }: Readonly<GeminiProviderConfig & { storage?: IStorage }>) { | ||
| }: Readonly<GeminiProviderConfig>) { | ||
| this.communicator = new Communicator({ | ||
@@ -60,11 +64,18 @@ appMetadata, | ||
| // Initialize storage data | ||
| this.initPromise = this.initializeFromStorage(chain?.id ?? this.chain.id); | ||
| // Initialize storage data - use provided chain config or fallback to default | ||
| const initialChain = chain || { id: DEFAULT_CHAIN_ID }; | ||
| this.initPromise = this.initializeFromStorage(initialChain); | ||
| } | ||
| private async initializeFromStorage(defaultChainId: number): Promise<void> { | ||
| private async initializeFromStorage(defaultChain: Chain): Promise<void> { | ||
| const fallbackChain: Chain = { | ||
| id: defaultChain.id, | ||
| rpcUrl: defaultChain.rpcUrl || getDefaultRpcUrl(defaultChain.id), | ||
| }; | ||
| const [storedChain, storedAccounts] = await Promise.all([ | ||
| this.storage.loadObject<Chain>(STORAGE_ETH_ACTIVE_CHAIN_KEY, { | ||
| id: defaultChainId, | ||
| }), | ||
| this.storage.loadObject<Chain>( | ||
| STORAGE_ETH_ACTIVE_CHAIN_KEY, | ||
| fallbackChain, | ||
| ), | ||
| this.storage.loadObject<Address[]>( | ||
@@ -76,3 +87,7 @@ STORAGE_ETH_ACCOUNTS_KEY, | ||
| this.chain = storedChain; | ||
| // Ensure chain has rpcUrl fallback | ||
| this.chain = { | ||
| ...storedChain, | ||
| rpcUrl: storedChain.rpcUrl || getDefaultRpcUrl(storedChain.id), | ||
| }; | ||
| this.accounts = storedAccounts; | ||
@@ -108,5 +123,8 @@ } | ||
| if (isChainSupportedByGeminiSw(id)) { | ||
| this.chain = { id }; | ||
| // Store new active chain | ||
| await this.storage.storeObject(STORAGE_ETH_ACTIVE_CHAIN_KEY, { id }); | ||
| this.chain = { | ||
| id, | ||
| rpcUrl: getDefaultRpcUrl(id), | ||
| }; | ||
| // Store new active chain with rpcUrl | ||
| await this.storage.storeObject(STORAGE_ETH_ACTIVE_CHAIN_KEY, this.chain); | ||
| // Per EIP-3326, must return null if chain switch was success | ||
@@ -113,0 +131,0 @@ return undefined; |
Sorry, the diff of this file is too big to display
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
285371
115.89%61
15.09%7783
134.78%3
200%4
100%