@turtleclub/turtle-basic 0.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +2 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +109 -0
- package/dist/index.d.ts +109 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -0
- package/package.json +61 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var react=require('react'),jsxRuntime=require('react/jsx-runtime');var R=Object.defineProperty;var b=(e,t,o)=>t in e?R(e,t,{enumerable:true,configurable:true,writable:true,value:o}):e[t]=o;var l=(e,t,o)=>b(e,typeof t!="symbol"?t+"":t,o);var s=null,m="turtle-platform-detection";function D(){if(typeof window>"u"||typeof sessionStorage>"u")return null;try{let e=sessionStorage.getItem(m);if(e)return JSON.parse(e)}catch(e){console.warn("[Platform Detection] Failed to load cached detection:",e);}return null}function E(e){if(!(typeof window>"u"||typeof sessionStorage>"u"))try{sessionStorage.setItem(m,JSON.stringify(e));}catch(t){console.warn("[Platform Detection] Failed to save cached detection:",t);}}function N(){if(typeof window>"u")return null;let e=window.location.hostname;return e.includes("worldcoin.")?"worldcoin":e.includes("lemon.")?"lemon":null}function f(e=false){if(!e){if(s)return s;let r=D();if(r)return s=r,r}let t=r=>(s=r,E(r),r),o=N();return t(o?{platformId:o,detectionMethod:"subdomain",isValidated:true}:{platformId:"turtle-web",detectionMethod:"default",isValidated:true})}var i=class{constructor(){l(this,"platformId","turtle-web");l(this,"platformName","Turtle Web");l(this,"user",null);}isAvailable(){return typeof window<"u"}async authenticate(t){return console.log("[TurtleWebAdapter] authenticate() called - NOT IMPLEMENTED",{nonce:t}),{success:false,error:"Authentication not implemented yet"}}getUser(){return this.user}async depositToOpportunity(t){return console.log("[TurtleWebAdapter] depositToOpportunity() called - NOT IMPLEMENTED",t),{success:false,error:"Deposit not implemented yet"}}getCapabilities(){return {canChangeNetwork:true,canDisconnect:true,showNetworkSelector:true,showGasEstimate:true,showUsername:false,requiresGasPayment:true,supportsNotifications:false}}getOpportunities(){return console.log("[TurtleWebAdapter] getOpportunities() called - NOT IMPLEMENTED"),Promise.resolve([])}getOpportunity(t){return console.log("[TurtleWebAdapter] getOpportunity() called - NOT IMPLEMENTED",{opportunityId:t}),Promise.reject(new Error("getOpportunity not implemented yet"))}};function P(e){switch(e){case "turtle-web":return new i;case "lemon":return console.warn("[createAdapter] Lemon adapter not implemented yet, falling back to turtle-web"),new i;case "worldcoin":return console.warn("[createAdapter] WorldCoin adapter not implemented yet, falling back to turtle-web"),new i;default:return console.warn("[createAdapter] Unknown platform, falling back to turtle-web"),new i}}var g=react.createContext(null);function M({children:e,loadingComponent:t,errorComponent:o,forcePlatform:r}){let[d,x]=react.useState(null),[c,p]=react.useState(null),u=react.useCallback(()=>{try{p(null);let n;r?n={platformId:r,detectionMethod:"forced",isValidated:!1,warnings:["Platform was manually forced via forcePlatform prop"]}:n=f();let A=P(n.platformId);x({adapter:A,detection:n,isReady:!0});}catch(n){console.error("[PlatformProvider] Error during platform initialization:",n),p(n instanceof Error?n:new Error("Unknown error during platform initialization"));}},[r]);return react.useEffect(()=>{u();},[u]),c?o?jsxRuntime.jsx(jsxRuntime.Fragment,{children:o(c,u)}):jsxRuntime.jsxs("main",{className:"flex flex-col items-center justify-center h-screen",children:[jsxRuntime.jsx("div",{className:"text-lg font-bold",children:"There was an error initializing the platform"}),jsxRuntime.jsx("span",{className:"text-sm text-gray-500",children:c.message}),jsxRuntime.jsx("span",{className:"text-xs text-gray-500",children:"Please provide an Error component to the PlatformProvider."})]}):d?jsxRuntime.jsx(g.Provider,{value:d,children:e}):t?jsxRuntime.jsx(jsxRuntime.Fragment,{children:t}):jsxRuntime.jsxs("main",{className:"flex flex-col items-center justify-center h-screen",children:[jsxRuntime.jsx("span",{className:"text-lg font-bold",children:"Detecting platform..."}),jsxRuntime.jsx("span",{className:"text-xs text-gray-500",children:"Please provide a Loading component to the PlatformProvider."})]})}function O(){let e=react.useContext(g);if(!e)throw new Error("usePlatform must be used within a PlatformProvider");return e}exports.PlatformProvider=M;exports.usePlatform=O;//# sourceMappingURL=index.cjs.map
|
|
2
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/platform/core/PlatformProvider.tsx","../src/platform/core/detector.ts","../src/platform/adapters/turtle-web-adapter.ts","../src/platform/adapters/index.ts"],"names":["cachedDetectionResult","CACHE_KEY","loadCachedDetection","cached","error","saveCachedDetection","result","detectFromSubdomain","hostname","detectPlatform","forceRedetect","sessionCached","cacheAndReturn","subdomainPlatform","TurtleWebAdapter","__publicField","nonce","params","opportunityId","createAdapter","platformId","PlatformContext","createContext","PlatformProvider","children","loadingComponent","errorComponent","forcePlatform","contextValue","setContextValue","useState","setError","initializePlatform","useCallback","detection","adapter","err","useEffect","jsx","Fragment","jsxs","usePlatform","context","useContext"],"mappings":"gFAEA,IAAA,CAAA,CAAA,MAAA,CAAA,cAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,UAAA,CAAA,IAAA,CAAA,YAAA,CAAA,IAAA,CAAA,QAAA,CAAA,IAAA,CAAA,KAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,IAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CAAA,GAAA,CAAA,CAAA,CAAA,CAAA,OAAA,CAAA,EAAA,QAAA,CAAA,CAAA,CAAA,EAAA,CAAA,CAAA,CAAA,CAAA,CAAA,CCCA,IAAIA,CAAAA,CAAgD,IAAA,CAG9CC,CAAAA,CAAY,2BAAA,CAKlB,SAASC,CAAAA,EAA8C,CACrD,GAAI,OAAO,MAAA,CAAW,GAAA,EAAe,OAAO,cAAA,CAAmB,GAAA,CAC7D,OAAO,IAAA,CAGT,GAAI,CACF,IAAMC,CAAAA,CAAS,cAAA,CAAe,OAAA,CAAQF,CAAS,CAAA,CAC/C,GAAIE,CAAAA,CACF,OAAO,IAAA,CAAK,KAAA,CAAMA,CAAM,CAE5B,CAAA,MAASC,CAAAA,CAAO,CACd,OAAA,CAAQ,IAAA,CAAK,uDAAA,CAAyDA,CAAK,EAC7E,CAEA,OAAO,IACT,CAKA,SAASC,CAAAA,CAAoBC,CAAAA,CAA+B,CAC1D,GAAI,EAAA,OAAO,MAAA,CAAW,KAAe,OAAO,cAAA,CAAmB,GAAA,CAAA,CAI/D,GAAI,CACF,cAAA,CAAe,OAAA,CAAQL,CAAAA,CAAW,IAAA,CAAK,SAAA,CAAUK,CAAM,CAAC,EAC1D,CAAA,MAASF,CAAAA,CAAO,CACd,OAAA,CAAQ,IAAA,CAAK,uDAAA,CAAyDA,CAAK,EAC7E,CACF,CAMA,SAASG,CAAAA,EAAyC,CAChD,GAAI,OAAO,MAAA,CAAW,GAAA,CAAa,OAAO,IAAA,CAE1C,IAAMC,CAAAA,CAAW,MAAA,CAAO,QAAA,CAAS,QAAA,CAGjC,OAAIA,CAAAA,CAAS,QAAA,CAAS,YAAY,CAAA,CACzB,WAAA,CAELA,CAAAA,CAAS,QAAA,CAAS,QAAQ,CAAA,CACrB,OAAA,CAGF,IACT,CAQO,SAASC,CAAAA,CAAeC,CAAAA,CAAgB,KAAA,CAAwB,CAErE,GAAI,CAACA,CAAAA,CAAe,CAElB,GAAIV,CAAAA,CACF,OAAOA,CAAAA,CAIT,IAAMW,CAAAA,CAAgBT,CAAAA,GACtB,GAAIS,CAAAA,CACF,OAAAX,CAAAA,CAAwBW,CAAAA,CACjBA,CAEX,CAEA,IAAMC,CAAAA,CAAkBN,CAAAA,GACtBN,CAAAA,CAAwBM,CAAAA,CACxBD,CAAAA,CAAoBC,CAAM,CAAA,CACnBA,CAAAA,CAAAA,CAIHO,CAAAA,CAAoBN,CAAAA,EAAoB,CAC9C,OACSK,CAAAA,CADLC,CAAAA,CACoB,CACpB,UAAA,CAAYA,CAAAA,CACZ,eAAA,CAAiB,WAAA,CACjB,WAAA,CAAa,IACf,CAAA,CAIoB,CACpB,UAAA,CAAY,aACZ,eAAA,CAAiB,SAAA,CACjB,WAAA,CAAa,IACf,CARG,CASL,CC9FO,IAAMC,CAAAA,CAAN,KAAiD,CAAjD,WAAA,EAAA,CACLC,CAAAA,CAAA,IAAA,CAAS,YAAA,CAAa,YAAA,CAAA,CACtBA,EAAA,IAAA,CAAS,cAAA,CAAe,YAAA,CAAA,CAExBA,CAAAA,CAAA,IAAA,CAAQ,MAAA,CAAoB,IAAA,EAAA,CAM5B,WAAA,EAAuB,CACrB,OAAO,OAAO,MAAA,CAAW,GAC3B,CAMA,MAAM,YAAA,CAAaC,EAAqC,CACtD,OAAA,OAAA,CAAQ,GAAA,CAAI,4DAAA,CAA8D,CAAE,KAAA,CAAAA,CAAM,CAAC,CAAA,CAC5E,CACL,OAAA,CAAS,KAAA,CACT,KAAA,CAAO,oCACT,CACF,CAKA,OAAA,EAAuB,CACrB,OAAO,IAAA,CAAK,IACd,CAMA,MAAM,oBAAA,CAAqBC,CAAAA,CAAmD,CAC5E,OAAA,OAAA,CAAQ,GAAA,CAAI,oEAAA,CAAsEA,CAAM,CAAA,CAGjF,CACL,QAAS,KAAA,CACT,KAAA,CAAO,6BACT,CACF,CAKA,eAAA,EAAwC,CACtC,OAAO,CACL,gBAAA,CAAkB,IAAA,CAClB,aAAA,CAAe,IAAA,CACf,mBAAA,CAAqB,IAAA,CACrB,eAAA,CAAiB,KACjB,YAAA,CAAc,KAAA,CACd,kBAAA,CAAoB,IAAA,CACpB,qBAAA,CAAuB,KACzB,CACF,CAMA,gBAAA,EAA2C,CACzC,OAAA,OAAA,CAAQ,GAAA,CAAI,gEAAgE,CAAA,CACrE,OAAA,CAAQ,OAAA,CAAQ,EAAE,CAC3B,CAMA,cAAA,CAAeC,CAAAA,CAA6C,CAC1D,OAAA,OAAA,CAAQ,GAAA,CAAI,8DAAA,CAAgE,CAAE,aAAA,CAAAA,CAAc,CAAC,CAAA,CACtF,OAAA,CAAQ,MAAA,CAAO,IAAI,KAAA,CAAM,oCAAoC,CAAC,CACvE,CACF,CAAA,CCtFO,SAASC,CAAAA,CAAcC,CAAAA,CAAwC,CACpE,OAAQA,CAAAA,EACN,KAAK,YAAA,CACH,OAAO,IAAIN,CAAAA,CAGb,KAAK,OAAA,CACH,OAAA,OAAA,CAAQ,IAAA,CAAK,+EAA+E,CAAA,CACrF,IAAIA,CAAAA,CAEb,KAAK,WAAA,CACH,OAAA,OAAA,CAAQ,IAAA,CAAK,mFAAmF,CAAA,CACzF,IAAIA,CAAAA,CAEb,QACE,OAAA,OAAA,CAAQ,IAAA,CAAK,8DAA8D,CAAA,CACpE,IAAIA,CACf,CACF,CHRA,IAAMO,CAAAA,CAAkBC,mBAAAA,CAA2C,IAAI,CAAA,CAehE,SAASC,CAAAA,CAAiB,CAC/B,QAAA,CAAAC,CAAAA,CACA,gBAAA,CAAAC,CAAAA,CACA,cAAA,CAAAC,CAAAA,CACA,aAAA,CAAAC,CACF,CAAA,CAA0B,CACxB,GAAM,CAACC,CAAAA,CAAcC,CAAe,CAAA,CAAIC,cAAAA,CAAsC,IAAI,CAAA,CAC5E,CAAC1B,CAAAA,CAAO2B,CAAQ,CAAA,CAAID,cAAAA,CAAuB,IAAI,EAC/CE,CAAAA,CAAqBC,iBAAAA,CAAY,IAAM,CAC3C,GAAI,CACFF,CAAAA,CAAS,IAAI,CAAA,CACb,IAAIG,CAAAA,CAEAP,CAAAA,CACFO,CAAAA,CAAY,CACV,UAAA,CAAYP,CAAAA,CACZ,gBAAiB,QAAA,CACjB,WAAA,CAAa,CAAA,CAAA,CACb,QAAA,CAAU,CAAC,qDAAqD,CAClE,CAAA,CAEAO,CAAAA,CAAYzB,CAAAA,EAAe,CAG7B,IAAM0B,CAAAA,CAAUhB,CAAAA,CAAce,CAAAA,CAAU,UAAU,EAElDL,CAAAA,CAAgB,CACd,OAAA,CAAAM,CAAAA,CACA,SAAA,CAAAD,CAAAA,CACA,OAAA,CAAS,CAAA,CACX,CAAC,EACH,CAAA,MAASE,CAAAA,CAAK,CACZ,OAAA,CAAQ,KAAA,CAAM,0DAAA,CAA4DA,CAAG,CAAA,CAC7EL,CAAAA,CACEK,CAAAA,YAAe,KAAA,CAAQA,CAAAA,CAAM,IAAI,KAAA,CAAM,8CAA8C,CACvF,EACF,CACF,CAAA,CAAG,CAACT,CAAa,CAAC,EAOlB,OALAU,eAAAA,CAAU,IAAM,CACdL,CAAAA,GACF,CAAA,CAAG,CAACA,CAAkB,CAAC,CAAA,CAGnB5B,CAAAA,CACEsB,CAAAA,CACKY,cAAAA,CAAAC,mBAAAA,CAAA,CAAG,SAAAb,CAAAA,CAAetB,CAAAA,CAAO4B,CAAkB,CAAA,CAAE,CAAA,CAGpDQ,eAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,oDAAA,CACd,QAAA,CAAA,CAAAF,cAAAA,CAAC,KAAA,CAAA,CAAI,SAAA,CAAU,mBAAA,CAAoB,QAAA,CAAA,8CAAA,CAA4C,CAAA,CAC/EA,eAAC,MAAA,CAAA,CAAK,SAAA,CAAU,uBAAA,CAAyB,QAAA,CAAAlC,CAAAA,CAAM,OAAA,CAAQ,CAAA,CACvDkC,cAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,uBAAA,CAAwB,QAAA,CAAA,4DAAA,CAExC,CAAA,CAAA,CACF,CAAA,CAKCV,CAAAA,CAcEU,cAAAA,CAACjB,CAAAA,CAAgB,QAAA,CAAhB,CAAyB,KAAA,CAAOO,CAAAA,CAAe,QAAA,CAAAJ,CAAAA,CAAS,CAAA,CAb1DC,CAAAA,CACKa,cAAAA,CAAAC,mBAAAA,CAAA,CAAG,QAAA,CAAAd,CAAAA,CAAiB,CAAA,CAG3Be,eAAAA,CAAC,QAAK,SAAA,CAAU,oDAAA,CACd,QAAA,CAAA,CAAAF,cAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,mBAAA,CAAoB,QAAA,CAAA,uBAAA,CAAqB,CAAA,CACzDA,cAAAA,CAAC,MAAA,CAAA,CAAK,SAAA,CAAU,uBAAA,CAAwB,QAAA,CAAA,6DAAA,CAExC,CAAA,CAAA,CACF,CAKN,CAMO,SAASG,CAAAA,EAAoC,CAClD,IAAMC,CAAAA,CAAUC,gBAAAA,CAAWtB,CAAe,CAAA,CAE1C,GAAI,CAACqB,CAAAA,CACH,MAAM,IAAI,KAAA,CAAM,oDAAoD,CAAA,CAGtE,OAAOA,CACT","file":"index.cjs","sourcesContent":["\"use client\";\n\nimport React, { createContext, useContext, useEffect, useState, useCallback } from \"react\";\nimport type { MiniAppAdapter, DetectionResult, PlatformId } from \"./types\";\nimport { detectPlatform } from \"./detector\";\nimport { createAdapter } from \"../adapters\";\n\ninterface PlatformContextValue {\n /** The platform adapter instance */\n adapter: MiniAppAdapter;\n /** Platform detection result */\n detection: DetectionResult;\n /** Whether platform is ready */\n isReady: boolean;\n}\n\nconst PlatformContext = createContext<PlatformContextValue | null>(null);\n\ninterface PlatformProviderProps {\n children: React.ReactNode;\n /** Custom loading component to show while platform is being detected */\n loadingComponent?: React.ReactNode;\n /** Custom error component to show if initialization fails. Receives error and retry function */\n errorComponent?: (error: Error, retry: () => void) => React.ReactNode;\n /** Force a specific platform (useful for testing/debugging) */\n forcePlatform?: PlatformId;\n}\n\n/**\n * Platform Provider - handles platform detection and adapter creation\n */\nexport function PlatformProvider({\n children,\n loadingComponent,\n errorComponent,\n forcePlatform,\n}: PlatformProviderProps) {\n const [contextValue, setContextValue] = useState<PlatformContextValue | null>(null);\n const [error, setError] = useState<Error | null>(null);\n const initializePlatform = useCallback(() => {\n try {\n setError(null);\n let detection: DetectionResult;\n //For local testing only.\n if (forcePlatform) {\n detection = {\n platformId: forcePlatform,\n detectionMethod: \"forced\",\n isValidated: false,\n warnings: [\"Platform was manually forced via forcePlatform prop\"],\n };\n } else {\n detection = detectPlatform();\n }\n\n const adapter = createAdapter(detection.platformId);\n\n setContextValue({\n adapter,\n detection,\n isReady: true,\n });\n } catch (err) {\n console.error(\"[PlatformProvider] Error during platform initialization:\", err);\n setError(\n err instanceof Error ? err : new Error(\"Unknown error during platform initialization\")\n );\n }\n }, [forcePlatform]);\n\n useEffect(() => {\n initializePlatform();\n }, [initializePlatform]);\n\n // Show error state if initialization failed\n if (error) {\n if (errorComponent) {\n return <>{errorComponent(error, initializePlatform)}</>;\n }\n return (\n <main className=\"flex flex-col items-center justify-center h-screen\">\n <div className=\"text-lg font-bold\">There was an error initializing the platform</div>\n <span className=\"text-sm text-gray-500\">{error.message}</span>\n <span className=\"text-xs text-gray-500\">\n Please provide an Error component to the PlatformProvider.\n </span>\n </main>\n );\n }\n\n // Show loading state while detecting\n if (!contextValue) {\n if (loadingComponent) {\n return <>{loadingComponent}</>;\n }\n return (\n <main className=\"flex flex-col items-center justify-center h-screen\">\n <span className=\"text-lg font-bold\">Detecting platform...</span>\n <span className=\"text-xs text-gray-500\">\n Please provide a Loading component to the PlatformProvider.\n </span>\n </main>\n );\n }\n\n return <PlatformContext.Provider value={contextValue}>{children}</PlatformContext.Provider>;\n}\n\n/**\n * Hook to access platform context\n * @throws Error if used outside PlatformProvider\n */\nexport function usePlatform(): PlatformContextValue {\n const context = useContext(PlatformContext);\n\n if (!context) {\n throw new Error(\"usePlatform must be used within a PlatformProvider\");\n }\n\n return context;\n}\n","import type { PlatformId, DetectionResult } from './types';\n\n// Cached detection result (singleton pattern)\nlet cachedDetectionResult: DetectionResult | null = null;\n\n// SessionStorage key for caching\nconst CACHE_KEY = 'turtle-platform-detection';\n\n/**\n * Load cached detection result from sessionStorage\n */\nfunction loadCachedDetection(): DetectionResult | null {\n if (typeof window === 'undefined' || typeof sessionStorage === 'undefined') {\n return null;\n }\n\n try {\n const cached = sessionStorage.getItem(CACHE_KEY);\n if (cached) {\n return JSON.parse(cached) as DetectionResult;\n }\n } catch (error) {\n console.warn('[Platform Detection] Failed to load cached detection:', error);\n }\n\n return null;\n}\n\n/**\n * Save detection result to sessionStorage\n */\nfunction saveCachedDetection(result: DetectionResult): void {\n if (typeof window === 'undefined' || typeof sessionStorage === 'undefined') {\n return;\n }\n\n try {\n sessionStorage.setItem(CACHE_KEY, JSON.stringify(result));\n } catch (error) {\n console.warn('[Platform Detection] Failed to save cached detection:', error);\n }\n}\n\n\n/**\n * Detect platform from subdomain\n */\nfunction detectFromSubdomain(): PlatformId | null {\n if (typeof window === 'undefined') return null;\n\n const hostname = window.location.hostname;\n\n // Check for platform-specific subdomains\n if (hostname.includes('worldcoin.')) {\n return 'worldcoin';\n }\n if (hostname.includes('lemon.')) {\n return 'lemon';\n }\n\n return null;\n}\n\n\n/**\n * Main platform detection function\n * Detects platform based on subdomain\n * @param forceRedetect - Force re-detection even if cached result exists\n */\nexport function detectPlatform(forceRedetect = false): DetectionResult {\n // Return cached result if available and not forcing re-detection\n if (!forceRedetect) {\n // Check in-memory cache first (fastest)\n if (cachedDetectionResult) {\n return cachedDetectionResult;\n }\n\n // Check sessionStorage cache\n const sessionCached = loadCachedDetection();\n if (sessionCached) {\n cachedDetectionResult = sessionCached;\n return sessionCached;\n }\n }\n\n const cacheAndReturn = (result: DetectionResult): DetectionResult => {\n cachedDetectionResult = result;\n saveCachedDetection(result);\n return result;\n };\n\n // Priority 1: Subdomain detection\n const subdomainPlatform = detectFromSubdomain();\n if (subdomainPlatform) {\n return cacheAndReturn({\n platformId: subdomainPlatform,\n detectionMethod: 'subdomain',\n isValidated: true,\n });\n }\n\n // Priority 2: Default to turtle-web\n return cacheAndReturn({\n platformId: 'turtle-web',\n detectionMethod: 'default',\n isValidated: true,\n });\n}\n","import { Opportunity } from '@turtleclub/hooks';\nimport type {\n MiniAppAdapter,\n User,\n AuthResult,\n DepositParams,\n TransactionResult,\n PlatformCapabilities,\n} from '../core/types';\n\n/**\n * Turtle Web Adapter - for standard web browsers\n */\nexport class TurtleWebAdapter implements MiniAppAdapter {\n readonly platformId = 'turtle-web';\n readonly platformName = 'Turtle Web';\n\n private user: User | null = null;\n\n /**\n * Check if platform is available\n * Web is always available in browser\n */\n isAvailable(): boolean {\n return typeof window !== 'undefined';\n }\n\n /**\n * Authenticate user via wallet connection\n * TODO: Implement\n */\n async authenticate(nonce?: string): Promise<AuthResult> {\n console.log('[TurtleWebAdapter] authenticate() called - NOT IMPLEMENTED', { nonce });\n return {\n success: false,\n error: 'Authentication not implemented yet',\n };\n }\n\n /**\n * Get currently authenticated user\n */\n getUser(): User | null {\n return this.user;\n }\n\n /**\n * Deposit tokens to an opportunity\n * TODO: Implement\n */\n async depositToOpportunity(params: DepositParams): Promise<TransactionResult> {\n console.log('[TurtleWebAdapter] depositToOpportunity() called - NOT IMPLEMENTED', params);\n\n\n return {\n success: false,\n error: 'Deposit not implemented yet',\n };\n }\n\n /**\n * Get platform capabilities\n */\n getCapabilities(): PlatformCapabilities {\n return {\n canChangeNetwork: true,\n canDisconnect: true,\n showNetworkSelector: true,\n showGasEstimate: true,\n showUsername: false,\n requiresGasPayment: true,\n supportsNotifications: false,\n };\n }\n\n /**\n * Get all opportunities\n * TODO: Implement\n */\n getOpportunities(): Promise<Opportunity[]> {\n console.log('[TurtleWebAdapter] getOpportunities() called - NOT IMPLEMENTED');\n return Promise.resolve([]);\n }\n\n /**\n * Get a single opportunity\n * TODO: Implement\n */\n getOpportunity(opportunityId: string): Promise<Opportunity> {\n console.log('[TurtleWebAdapter] getOpportunity() called - NOT IMPLEMENTED', { opportunityId });\n return Promise.reject(new Error('getOpportunity not implemented yet'));\n }\n}\n","import type { PlatformId, MiniAppAdapter } from '../core/types';\nimport { TurtleWebAdapter } from './turtle-web-adapter';\n\n/**\n * Create the appropriate adapter for the given platform\n */\nexport function createAdapter(platformId: PlatformId): MiniAppAdapter {\n switch (platformId) {\n case 'turtle-web':\n return new TurtleWebAdapter();\n\n // For now, we are always going to return the TurtleWebAdapter.\n case 'lemon':\n console.warn('[createAdapter] Lemon adapter not implemented yet, falling back to turtle-web');\n return new TurtleWebAdapter();\n\n case 'worldcoin':\n console.warn('[createAdapter] WorldCoin adapter not implemented yet, falling back to turtle-web');\n return new TurtleWebAdapter();\n\n default:\n console.warn('[createAdapter] Unknown platform, falling back to turtle-web');\n return new TurtleWebAdapter();\n }\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Opportunity } from '@turtleclub/hooks';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Platform identifier type union
|
|
7
|
+
*/
|
|
8
|
+
type PlatformId = 'turtle-web' | 'lemon' | 'worldcoin';
|
|
9
|
+
/**
|
|
10
|
+
* User information from platform authentication
|
|
11
|
+
*/
|
|
12
|
+
interface User {
|
|
13
|
+
id: string;
|
|
14
|
+
username?: string;
|
|
15
|
+
email?: string;
|
|
16
|
+
avatar?: string;
|
|
17
|
+
metadata?: Record<string, any>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Result of authentication attempt
|
|
21
|
+
*/
|
|
22
|
+
interface AuthResult {
|
|
23
|
+
success: boolean;
|
|
24
|
+
user?: User;
|
|
25
|
+
error?: string;
|
|
26
|
+
metadata?: Record<string, any>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parameters for depositing to an opportunity
|
|
30
|
+
*/
|
|
31
|
+
interface DepositParams {
|
|
32
|
+
opportunityAddress: string;
|
|
33
|
+
tokenAddress: string;
|
|
34
|
+
amount: string;
|
|
35
|
+
chainId: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Result of a transaction attempt
|
|
39
|
+
*/
|
|
40
|
+
interface TransactionResult {
|
|
41
|
+
success: boolean;
|
|
42
|
+
txHash?: string;
|
|
43
|
+
error?: string;
|
|
44
|
+
metadata?: Record<string, any>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Platform capabilities - what features are available/should be shown
|
|
48
|
+
*/
|
|
49
|
+
interface PlatformCapabilities {
|
|
50
|
+
canChangeNetwork: boolean;
|
|
51
|
+
canDisconnect: boolean;
|
|
52
|
+
showNetworkSelector: boolean;
|
|
53
|
+
showGasEstimate: boolean;
|
|
54
|
+
showUsername: boolean;
|
|
55
|
+
requiresGasPayment: boolean;
|
|
56
|
+
supportsNotifications: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Main adapter interface - implemented by each platform
|
|
60
|
+
*/
|
|
61
|
+
interface MiniAppAdapter {
|
|
62
|
+
readonly platformId: PlatformId;
|
|
63
|
+
readonly platformName: string;
|
|
64
|
+
isAvailable(): boolean;
|
|
65
|
+
authenticate(nonce?: string): Promise<AuthResult>;
|
|
66
|
+
getUser(): User | null;
|
|
67
|
+
depositToOpportunity(params: DepositParams): Promise<TransactionResult>;
|
|
68
|
+
getOpportunities(): Promise<Opportunity[]>;
|
|
69
|
+
getOpportunity(opportunityId: string): Promise<Opportunity>;
|
|
70
|
+
getCapabilities(): PlatformCapabilities;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Result of platform detection
|
|
74
|
+
*/
|
|
75
|
+
interface DetectionResult {
|
|
76
|
+
platformId: PlatformId;
|
|
77
|
+
detectionMethod: 'subdomain' | 'sdk' | 'forced' | 'default';
|
|
78
|
+
isValidated: boolean;
|
|
79
|
+
warnings?: string[];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface PlatformContextValue {
|
|
83
|
+
/** The platform adapter instance */
|
|
84
|
+
adapter: MiniAppAdapter;
|
|
85
|
+
/** Platform detection result */
|
|
86
|
+
detection: DetectionResult;
|
|
87
|
+
/** Whether platform is ready */
|
|
88
|
+
isReady: boolean;
|
|
89
|
+
}
|
|
90
|
+
interface PlatformProviderProps {
|
|
91
|
+
children: React.ReactNode;
|
|
92
|
+
/** Custom loading component to show while platform is being detected */
|
|
93
|
+
loadingComponent?: React.ReactNode;
|
|
94
|
+
/** Custom error component to show if initialization fails. Receives error and retry function */
|
|
95
|
+
errorComponent?: (error: Error, retry: () => void) => React.ReactNode;
|
|
96
|
+
/** Force a specific platform (useful for testing/debugging) */
|
|
97
|
+
forcePlatform?: PlatformId;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Platform Provider - handles platform detection and adapter creation
|
|
101
|
+
*/
|
|
102
|
+
declare function PlatformProvider({ children, loadingComponent, errorComponent, forcePlatform, }: PlatformProviderProps): react_jsx_runtime.JSX.Element;
|
|
103
|
+
/**
|
|
104
|
+
* Hook to access platform context
|
|
105
|
+
* @throws Error if used outside PlatformProvider
|
|
106
|
+
*/
|
|
107
|
+
declare function usePlatform(): PlatformContextValue;
|
|
108
|
+
|
|
109
|
+
export { type AuthResult, type DepositParams, type DetectionResult, type MiniAppAdapter, type PlatformCapabilities, type PlatformId, PlatformProvider, type TransactionResult, type User, usePlatform };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { Opportunity } from '@turtleclub/hooks';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Platform identifier type union
|
|
7
|
+
*/
|
|
8
|
+
type PlatformId = 'turtle-web' | 'lemon' | 'worldcoin';
|
|
9
|
+
/**
|
|
10
|
+
* User information from platform authentication
|
|
11
|
+
*/
|
|
12
|
+
interface User {
|
|
13
|
+
id: string;
|
|
14
|
+
username?: string;
|
|
15
|
+
email?: string;
|
|
16
|
+
avatar?: string;
|
|
17
|
+
metadata?: Record<string, any>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Result of authentication attempt
|
|
21
|
+
*/
|
|
22
|
+
interface AuthResult {
|
|
23
|
+
success: boolean;
|
|
24
|
+
user?: User;
|
|
25
|
+
error?: string;
|
|
26
|
+
metadata?: Record<string, any>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Parameters for depositing to an opportunity
|
|
30
|
+
*/
|
|
31
|
+
interface DepositParams {
|
|
32
|
+
opportunityAddress: string;
|
|
33
|
+
tokenAddress: string;
|
|
34
|
+
amount: string;
|
|
35
|
+
chainId: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Result of a transaction attempt
|
|
39
|
+
*/
|
|
40
|
+
interface TransactionResult {
|
|
41
|
+
success: boolean;
|
|
42
|
+
txHash?: string;
|
|
43
|
+
error?: string;
|
|
44
|
+
metadata?: Record<string, any>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Platform capabilities - what features are available/should be shown
|
|
48
|
+
*/
|
|
49
|
+
interface PlatformCapabilities {
|
|
50
|
+
canChangeNetwork: boolean;
|
|
51
|
+
canDisconnect: boolean;
|
|
52
|
+
showNetworkSelector: boolean;
|
|
53
|
+
showGasEstimate: boolean;
|
|
54
|
+
showUsername: boolean;
|
|
55
|
+
requiresGasPayment: boolean;
|
|
56
|
+
supportsNotifications: boolean;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Main adapter interface - implemented by each platform
|
|
60
|
+
*/
|
|
61
|
+
interface MiniAppAdapter {
|
|
62
|
+
readonly platformId: PlatformId;
|
|
63
|
+
readonly platformName: string;
|
|
64
|
+
isAvailable(): boolean;
|
|
65
|
+
authenticate(nonce?: string): Promise<AuthResult>;
|
|
66
|
+
getUser(): User | null;
|
|
67
|
+
depositToOpportunity(params: DepositParams): Promise<TransactionResult>;
|
|
68
|
+
getOpportunities(): Promise<Opportunity[]>;
|
|
69
|
+
getOpportunity(opportunityId: string): Promise<Opportunity>;
|
|
70
|
+
getCapabilities(): PlatformCapabilities;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Result of platform detection
|
|
74
|
+
*/
|
|
75
|
+
interface DetectionResult {
|
|
76
|
+
platformId: PlatformId;
|
|
77
|
+
detectionMethod: 'subdomain' | 'sdk' | 'forced' | 'default';
|
|
78
|
+
isValidated: boolean;
|
|
79
|
+
warnings?: string[];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
interface PlatformContextValue {
|
|
83
|
+
/** The platform adapter instance */
|
|
84
|
+
adapter: MiniAppAdapter;
|
|
85
|
+
/** Platform detection result */
|
|
86
|
+
detection: DetectionResult;
|
|
87
|
+
/** Whether platform is ready */
|
|
88
|
+
isReady: boolean;
|
|
89
|
+
}
|
|
90
|
+
interface PlatformProviderProps {
|
|
91
|
+
children: React.ReactNode;
|
|
92
|
+
/** Custom loading component to show while platform is being detected */
|
|
93
|
+
loadingComponent?: React.ReactNode;
|
|
94
|
+
/** Custom error component to show if initialization fails. Receives error and retry function */
|
|
95
|
+
errorComponent?: (error: Error, retry: () => void) => React.ReactNode;
|
|
96
|
+
/** Force a specific platform (useful for testing/debugging) */
|
|
97
|
+
forcePlatform?: PlatformId;
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Platform Provider - handles platform detection and adapter creation
|
|
101
|
+
*/
|
|
102
|
+
declare function PlatformProvider({ children, loadingComponent, errorComponent, forcePlatform, }: PlatformProviderProps): react_jsx_runtime.JSX.Element;
|
|
103
|
+
/**
|
|
104
|
+
* Hook to access platform context
|
|
105
|
+
* @throws Error if used outside PlatformProvider
|
|
106
|
+
*/
|
|
107
|
+
declare function usePlatform(): PlatformContextValue;
|
|
108
|
+
|
|
109
|
+
export { type AuthResult, type DepositParams, type DetectionResult, type MiniAppAdapter, type PlatformCapabilities, type PlatformId, PlatformProvider, type TransactionResult, type User, usePlatform };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {createContext,useState,useCallback,useEffect,useContext}from'react';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var R=Object.defineProperty;var b=(e,t,o)=>t in e?R(e,t,{enumerable:true,configurable:true,writable:true,value:o}):e[t]=o;var l=(e,t,o)=>b(e,typeof t!="symbol"?t+"":t,o);var s=null,m="turtle-platform-detection";function D(){if(typeof window>"u"||typeof sessionStorage>"u")return null;try{let e=sessionStorage.getItem(m);if(e)return JSON.parse(e)}catch(e){console.warn("[Platform Detection] Failed to load cached detection:",e);}return null}function E(e){if(!(typeof window>"u"||typeof sessionStorage>"u"))try{sessionStorage.setItem(m,JSON.stringify(e));}catch(t){console.warn("[Platform Detection] Failed to save cached detection:",t);}}function N(){if(typeof window>"u")return null;let e=window.location.hostname;return e.includes("worldcoin.")?"worldcoin":e.includes("lemon.")?"lemon":null}function f(e=false){if(!e){if(s)return s;let r=D();if(r)return s=r,r}let t=r=>(s=r,E(r),r),o=N();return t(o?{platformId:o,detectionMethod:"subdomain",isValidated:true}:{platformId:"turtle-web",detectionMethod:"default",isValidated:true})}var i=class{constructor(){l(this,"platformId","turtle-web");l(this,"platformName","Turtle Web");l(this,"user",null);}isAvailable(){return typeof window<"u"}async authenticate(t){return console.log("[TurtleWebAdapter] authenticate() called - NOT IMPLEMENTED",{nonce:t}),{success:false,error:"Authentication not implemented yet"}}getUser(){return this.user}async depositToOpportunity(t){return console.log("[TurtleWebAdapter] depositToOpportunity() called - NOT IMPLEMENTED",t),{success:false,error:"Deposit not implemented yet"}}getCapabilities(){return {canChangeNetwork:true,canDisconnect:true,showNetworkSelector:true,showGasEstimate:true,showUsername:false,requiresGasPayment:true,supportsNotifications:false}}getOpportunities(){return console.log("[TurtleWebAdapter] getOpportunities() called - NOT IMPLEMENTED"),Promise.resolve([])}getOpportunity(t){return console.log("[TurtleWebAdapter] getOpportunity() called - NOT IMPLEMENTED",{opportunityId:t}),Promise.reject(new Error("getOpportunity not implemented yet"))}};function P(e){switch(e){case "turtle-web":return new i;case "lemon":return console.warn("[createAdapter] Lemon adapter not implemented yet, falling back to turtle-web"),new i;case "worldcoin":return console.warn("[createAdapter] WorldCoin adapter not implemented yet, falling back to turtle-web"),new i;default:return console.warn("[createAdapter] Unknown platform, falling back to turtle-web"),new i}}var g=createContext(null);function M({children:e,loadingComponent:t,errorComponent:o,forcePlatform:r}){let[d,x]=useState(null),[c,p]=useState(null),u=useCallback(()=>{try{p(null);let n;r?n={platformId:r,detectionMethod:"forced",isValidated:!1,warnings:["Platform was manually forced via forcePlatform prop"]}:n=f();let A=P(n.platformId);x({adapter:A,detection:n,isReady:!0});}catch(n){console.error("[PlatformProvider] Error during platform initialization:",n),p(n instanceof Error?n:new Error("Unknown error during platform initialization"));}},[r]);return useEffect(()=>{u();},[u]),c?o?jsx(Fragment,{children:o(c,u)}):jsxs("main",{className:"flex flex-col items-center justify-center h-screen",children:[jsx("div",{className:"text-lg font-bold",children:"There was an error initializing the platform"}),jsx("span",{className:"text-sm text-gray-500",children:c.message}),jsx("span",{className:"text-xs text-gray-500",children:"Please provide an Error component to the PlatformProvider."})]}):d?jsx(g.Provider,{value:d,children:e}):t?jsx(Fragment,{children:t}):jsxs("main",{className:"flex flex-col items-center justify-center h-screen",children:[jsx("span",{className:"text-lg font-bold",children:"Detecting platform..."}),jsx("span",{className:"text-xs text-gray-500",children:"Please provide a Loading component to the PlatformProvider."})]})}function O(){let e=useContext(g);if(!e)throw new Error("usePlatform must be used within a PlatformProvider");return e}export{M as PlatformProvider,O as usePlatform};//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/platform/core/PlatformProvider.tsx","../src/platform/core/detector.ts","../src/platform/adapters/turtle-web-adapter.ts","../src/platform/adapters/index.ts"],"names":["cachedDetectionResult","CACHE_KEY","loadCachedDetection","cached","error","saveCachedDetection","result","detectFromSubdomain","hostname","detectPlatform","forceRedetect","sessionCached","cacheAndReturn","subdomainPlatform","TurtleWebAdapter","__publicField","nonce","params","opportunityId","createAdapter","platformId","PlatformContext","createContext","PlatformProvider","children","loadingComponent","errorComponent","forcePlatform","contextValue","setContextValue","useState","setError","initializePlatform","useCallback","detection","adapter","err","useEffect","jsx","Fragment","jsxs","usePlatform","context","useContext"],"mappings":"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","file":"index.js","sourcesContent":["\"use client\";\n\nimport React, { createContext, useContext, useEffect, useState, useCallback } from \"react\";\nimport type { MiniAppAdapter, DetectionResult, PlatformId } from \"./types\";\nimport { detectPlatform } from \"./detector\";\nimport { createAdapter } from \"../adapters\";\n\ninterface PlatformContextValue {\n /** The platform adapter instance */\n adapter: MiniAppAdapter;\n /** Platform detection result */\n detection: DetectionResult;\n /** Whether platform is ready */\n isReady: boolean;\n}\n\nconst PlatformContext = createContext<PlatformContextValue | null>(null);\n\ninterface PlatformProviderProps {\n children: React.ReactNode;\n /** Custom loading component to show while platform is being detected */\n loadingComponent?: React.ReactNode;\n /** Custom error component to show if initialization fails. Receives error and retry function */\n errorComponent?: (error: Error, retry: () => void) => React.ReactNode;\n /** Force a specific platform (useful for testing/debugging) */\n forcePlatform?: PlatformId;\n}\n\n/**\n * Platform Provider - handles platform detection and adapter creation\n */\nexport function PlatformProvider({\n children,\n loadingComponent,\n errorComponent,\n forcePlatform,\n}: PlatformProviderProps) {\n const [contextValue, setContextValue] = useState<PlatformContextValue | null>(null);\n const [error, setError] = useState<Error | null>(null);\n const initializePlatform = useCallback(() => {\n try {\n setError(null);\n let detection: DetectionResult;\n //For local testing only.\n if (forcePlatform) {\n detection = {\n platformId: forcePlatform,\n detectionMethod: \"forced\",\n isValidated: false,\n warnings: [\"Platform was manually forced via forcePlatform prop\"],\n };\n } else {\n detection = detectPlatform();\n }\n\n const adapter = createAdapter(detection.platformId);\n\n setContextValue({\n adapter,\n detection,\n isReady: true,\n });\n } catch (err) {\n console.error(\"[PlatformProvider] Error during platform initialization:\", err);\n setError(\n err instanceof Error ? err : new Error(\"Unknown error during platform initialization\")\n );\n }\n }, [forcePlatform]);\n\n useEffect(() => {\n initializePlatform();\n }, [initializePlatform]);\n\n // Show error state if initialization failed\n if (error) {\n if (errorComponent) {\n return <>{errorComponent(error, initializePlatform)}</>;\n }\n return (\n <main className=\"flex flex-col items-center justify-center h-screen\">\n <div className=\"text-lg font-bold\">There was an error initializing the platform</div>\n <span className=\"text-sm text-gray-500\">{error.message}</span>\n <span className=\"text-xs text-gray-500\">\n Please provide an Error component to the PlatformProvider.\n </span>\n </main>\n );\n }\n\n // Show loading state while detecting\n if (!contextValue) {\n if (loadingComponent) {\n return <>{loadingComponent}</>;\n }\n return (\n <main className=\"flex flex-col items-center justify-center h-screen\">\n <span className=\"text-lg font-bold\">Detecting platform...</span>\n <span className=\"text-xs text-gray-500\">\n Please provide a Loading component to the PlatformProvider.\n </span>\n </main>\n );\n }\n\n return <PlatformContext.Provider value={contextValue}>{children}</PlatformContext.Provider>;\n}\n\n/**\n * Hook to access platform context\n * @throws Error if used outside PlatformProvider\n */\nexport function usePlatform(): PlatformContextValue {\n const context = useContext(PlatformContext);\n\n if (!context) {\n throw new Error(\"usePlatform must be used within a PlatformProvider\");\n }\n\n return context;\n}\n","import type { PlatformId, DetectionResult } from './types';\n\n// Cached detection result (singleton pattern)\nlet cachedDetectionResult: DetectionResult | null = null;\n\n// SessionStorage key for caching\nconst CACHE_KEY = 'turtle-platform-detection';\n\n/**\n * Load cached detection result from sessionStorage\n */\nfunction loadCachedDetection(): DetectionResult | null {\n if (typeof window === 'undefined' || typeof sessionStorage === 'undefined') {\n return null;\n }\n\n try {\n const cached = sessionStorage.getItem(CACHE_KEY);\n if (cached) {\n return JSON.parse(cached) as DetectionResult;\n }\n } catch (error) {\n console.warn('[Platform Detection] Failed to load cached detection:', error);\n }\n\n return null;\n}\n\n/**\n * Save detection result to sessionStorage\n */\nfunction saveCachedDetection(result: DetectionResult): void {\n if (typeof window === 'undefined' || typeof sessionStorage === 'undefined') {\n return;\n }\n\n try {\n sessionStorage.setItem(CACHE_KEY, JSON.stringify(result));\n } catch (error) {\n console.warn('[Platform Detection] Failed to save cached detection:', error);\n }\n}\n\n\n/**\n * Detect platform from subdomain\n */\nfunction detectFromSubdomain(): PlatformId | null {\n if (typeof window === 'undefined') return null;\n\n const hostname = window.location.hostname;\n\n // Check for platform-specific subdomains\n if (hostname.includes('worldcoin.')) {\n return 'worldcoin';\n }\n if (hostname.includes('lemon.')) {\n return 'lemon';\n }\n\n return null;\n}\n\n\n/**\n * Main platform detection function\n * Detects platform based on subdomain\n * @param forceRedetect - Force re-detection even if cached result exists\n */\nexport function detectPlatform(forceRedetect = false): DetectionResult {\n // Return cached result if available and not forcing re-detection\n if (!forceRedetect) {\n // Check in-memory cache first (fastest)\n if (cachedDetectionResult) {\n return cachedDetectionResult;\n }\n\n // Check sessionStorage cache\n const sessionCached = loadCachedDetection();\n if (sessionCached) {\n cachedDetectionResult = sessionCached;\n return sessionCached;\n }\n }\n\n const cacheAndReturn = (result: DetectionResult): DetectionResult => {\n cachedDetectionResult = result;\n saveCachedDetection(result);\n return result;\n };\n\n // Priority 1: Subdomain detection\n const subdomainPlatform = detectFromSubdomain();\n if (subdomainPlatform) {\n return cacheAndReturn({\n platformId: subdomainPlatform,\n detectionMethod: 'subdomain',\n isValidated: true,\n });\n }\n\n // Priority 2: Default to turtle-web\n return cacheAndReturn({\n platformId: 'turtle-web',\n detectionMethod: 'default',\n isValidated: true,\n });\n}\n","import { Opportunity } from '@turtleclub/hooks';\nimport type {\n MiniAppAdapter,\n User,\n AuthResult,\n DepositParams,\n TransactionResult,\n PlatformCapabilities,\n} from '../core/types';\n\n/**\n * Turtle Web Adapter - for standard web browsers\n */\nexport class TurtleWebAdapter implements MiniAppAdapter {\n readonly platformId = 'turtle-web';\n readonly platformName = 'Turtle Web';\n\n private user: User | null = null;\n\n /**\n * Check if platform is available\n * Web is always available in browser\n */\n isAvailable(): boolean {\n return typeof window !== 'undefined';\n }\n\n /**\n * Authenticate user via wallet connection\n * TODO: Implement\n */\n async authenticate(nonce?: string): Promise<AuthResult> {\n console.log('[TurtleWebAdapter] authenticate() called - NOT IMPLEMENTED', { nonce });\n return {\n success: false,\n error: 'Authentication not implemented yet',\n };\n }\n\n /**\n * Get currently authenticated user\n */\n getUser(): User | null {\n return this.user;\n }\n\n /**\n * Deposit tokens to an opportunity\n * TODO: Implement\n */\n async depositToOpportunity(params: DepositParams): Promise<TransactionResult> {\n console.log('[TurtleWebAdapter] depositToOpportunity() called - NOT IMPLEMENTED', params);\n\n\n return {\n success: false,\n error: 'Deposit not implemented yet',\n };\n }\n\n /**\n * Get platform capabilities\n */\n getCapabilities(): PlatformCapabilities {\n return {\n canChangeNetwork: true,\n canDisconnect: true,\n showNetworkSelector: true,\n showGasEstimate: true,\n showUsername: false,\n requiresGasPayment: true,\n supportsNotifications: false,\n };\n }\n\n /**\n * Get all opportunities\n * TODO: Implement\n */\n getOpportunities(): Promise<Opportunity[]> {\n console.log('[TurtleWebAdapter] getOpportunities() called - NOT IMPLEMENTED');\n return Promise.resolve([]);\n }\n\n /**\n * Get a single opportunity\n * TODO: Implement\n */\n getOpportunity(opportunityId: string): Promise<Opportunity> {\n console.log('[TurtleWebAdapter] getOpportunity() called - NOT IMPLEMENTED', { opportunityId });\n return Promise.reject(new Error('getOpportunity not implemented yet'));\n }\n}\n","import type { PlatformId, MiniAppAdapter } from '../core/types';\nimport { TurtleWebAdapter } from './turtle-web-adapter';\n\n/**\n * Create the appropriate adapter for the given platform\n */\nexport function createAdapter(platformId: PlatformId): MiniAppAdapter {\n switch (platformId) {\n case 'turtle-web':\n return new TurtleWebAdapter();\n\n // For now, we are always going to return the TurtleWebAdapter.\n case 'lemon':\n console.warn('[createAdapter] Lemon adapter not implemented yet, falling back to turtle-web');\n return new TurtleWebAdapter();\n\n case 'worldcoin':\n console.warn('[createAdapter] WorldCoin adapter not implemented yet, falling back to turtle-web');\n return new TurtleWebAdapter();\n\n default:\n console.warn('[createAdapter] Unknown platform, falling back to turtle-web');\n return new TurtleWebAdapter();\n }\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@turtleclub/turtle-basic",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"description": "Multi-platform mini-app adapter system for Turtle Basic",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/turtledev/packages.git",
|
|
9
|
+
"directory": "packages/turtle-basic"
|
|
10
|
+
},
|
|
11
|
+
"type": "module",
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"README.md",
|
|
15
|
+
"package.json"
|
|
16
|
+
],
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"development": "./src/index.ts",
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"import": "./dist/index.js",
|
|
22
|
+
"require": "./dist/index.cjs"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"main": "./dist/index.cjs",
|
|
26
|
+
"module": "./dist/index.js",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "tsup",
|
|
30
|
+
"dev": "tsup --watch",
|
|
31
|
+
"type-check": "tsc --noEmit",
|
|
32
|
+
"lint": "eslint . --max-warnings 0"
|
|
33
|
+
},
|
|
34
|
+
"dependencies": {
|
|
35
|
+
"@turtleclub/hooks": "0.5.0-beta.30",
|
|
36
|
+
"@turtleclub/opportunities": "0.1.0-beta.45",
|
|
37
|
+
"@turtleclub/ui": "0.7.0-beta.19",
|
|
38
|
+
"@turtleclub/utils": "0.4.0-beta.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"@tanstack/react-query": ">=5.0.0",
|
|
42
|
+
"react": ">=18.0.0",
|
|
43
|
+
"react-dom": ">=18.0.0",
|
|
44
|
+
"viem": ">=2.0.0",
|
|
45
|
+
"wagmi": ">=2.0.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@types/react": "^19.0.0",
|
|
49
|
+
"@types/react-dom": "^19.0.0",
|
|
50
|
+
"react": "^19.0.0",
|
|
51
|
+
"react-dom": "^19.0.0",
|
|
52
|
+
"tsup": "^8.5.0",
|
|
53
|
+
"typescript": "^5.0.0",
|
|
54
|
+
"viem": "^2.0.0",
|
|
55
|
+
"wagmi": "^2.0.0"
|
|
56
|
+
},
|
|
57
|
+
"publishConfig": {
|
|
58
|
+
"access": "public"
|
|
59
|
+
},
|
|
60
|
+
"gitHead": "1405cd183ec0411d8fc87d3f8350b96cdd02ab42"
|
|
61
|
+
}
|