Search
Search

Transaction: hzQguHn...oSad

Receiver
Status
Succeeded
Transaction Fee
0.00112 
Deposit Value
0.001 
Gas Used
11 Tgas
Attached Gas
30 Tgas
Created
February 02, 2023 at 5:07:07pm
Hash
hzQguHn9aFtWoez3caNH8yamXGCkeekFq3zExojoSad

Actions

Called method: 'set' in contract: social.near
Arguments:
{ "data": { "events_v2.near": { "widget": { "app__frame": { "": "/* eslint no-magic-numbers: 0 */\n\nconst VERSION = '0.3.0';\n\n/**\n * NEAR Social App\n *\n * This is the main app component that is used to render the app.\n *\n *\n * WHY?\n * - DRY: we don't want to have to copy/paste the same code into every app\n * - Speed: we want to be able to build apps quickly\n * - Functionality: we want to be able to add functionality to all apps at once\n *\n *\n * HOW?\n * this app provides common functionality often needed in apps\n * - routing\n\n * - layout management\n *\n * Requirements:\n * - Fork the following widgets into your account:\n * - app__layouts__default\n * - app__frame (this component)\n * - You should also take a look at: https://github.com/NEARFoundation/events-platform\n * as it provides a lot of the functionality you need to build an app, it provides:\n * - an opinionated way to build apps\n * - directory structure\n * - naming conventions\n * - a way to build apps quickly\n * - development tools (dev server, deploy script)\n * - env var injection\n * - a sample app\n *\n *\n * This component is responsible for:\n * - Loading the app's state/environment\n * - Rendering the app's layouts\n * - Rendering the app's components\n *\n * It follows conventions:\n * - The app's environment is loaded from the props\n * - props.appOwner\n * - props.appName\n * - An app is a collection of widgets\n * - each widget must be namespaced by the app's owner and name\n * Widgets are named as follows:\n * - you choose an app_name like 'my_app'\n * - you choose a widget like 'my_widget'\n * - app, widgets and subwidgets are separated by '__'\n * - In order to use the widget in your app, you must upload it to your account with the name: `my_app__my_widget`\n * - e.g. app_namecomponent1\n * - e.g. app_namecomponent1__subcomponent\n * - Each widget can have a layout\n * - layouts are also widgets\n * - layouts are named as follows:\n * - you choose a layout like 'my_layout'\n * - In order to use the layout in your app, you must upload it to your account with the name: `my_app__layouts__my_layout`\n *\n *\n * Functions available to widgets:\n * - TODO: document\n *\n */\n\n/**\n * Adjust these:\n * */\n\nconst NEAR_STORAGE_BYTES_SAFTY_OFFSET = 42;\nconst PROP_IS_REQUIRED_MESSAGE = 'props.{prop} is required';\nconst PLEASE_CONNECT_WALLET_MESSAGE =\n 'Please connect your NEAR wallet to continue.';\n\nconst ContainerPaddingHorizontal = 'calc(max(28px, 1.6vw))';\n\nconst Select = styled.select`\n background-color: #4caf50;\n border: none;\n color: white;\n padding: 15px 32px;\n text-align: center;\n text-decoration: none;\n display: inline-block;\n font-size: 16px;\n margin: 4px 2px;\n cursor: pointer;\n`;\n\nconst Button = styled.button`\n background-color: #4caf50;\n border: none;\n color: white;\n padding: 15px 32px;\n text-align: center;\n text-decoration: none;\n display: inline-block;\n font-size: 16px;\n transition: all 0.5s ease;\n\n &:hover {\n background-color: #3e8e41;\n }\n`;\n\nconst Loading = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n`;\n\nconst PageTitle = styled.h1`\n font-size: calc(max(32px, 2.5vw));\n color: black;\n`;\n\nconst Container = styled.div`\n padding-left: ${ContainerPaddingHorizontal};\n padding-right: ${ContainerPaddingHorizontal};\n padding-top: 12px;\n padding-bottom: 12px;\n`;\n\nconst InfoBar = styled.div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n padding: 0px ${ContainerPaddingHorizontal};\n border-bottom: 1px solid #e0e0e0;\n`;\n\nconst InfoBarItem = styled.div`\n display: flex;\n align-items: center;\n margin-right: 12px;\n padding: 8px 0;\n`;\n\nconst InfoBarLink = styled.a`\n font-size: 16px;\n color: #424242;\n text-decoration: none;\n margin-right: 12px;\n padding: 8px 0;\n\n &:hover {\n text-decoration: underline;\n }\n\n &:last-child {\n margin-right: 0;\n }\n\n &:visited {\n color: #424242;\n }\n\n &:active {\n color: #424242;\n }\n`;\n\nconst TextHeader = styled.div`\n font-size: 20px;\n color: #424242;\n`;\n\nconst InlineTag = styled.div`\n display: inline-block;\n background-color: #e0e0e0;\n padding: 4px 8px;\n border-radius: 4px;\n margin-right: 8px;\n margin-left: 8px;\n`;\n\nconst Text = styled.div`\n font-size: 16px;\n color: #424242;\n margin-right: 8px;\n`;\n\n/**\n * I suggest you don't edit anything below this line\n * */\n\nconst accountId = context.accountId;\nif (!accountId) {\n return PLEASE_CONNECT_WALLET_MESSAGE;\n}\n\nfunction propIsRequiredMessage(prop) {\n return PROP_IS_REQUIRED_MESSAGE.replace('{prop}', prop);\n}\n\nconst appOwner = props.appOwner;\nif (!appOwner) {\n return propIsRequiredMessage('appOwner');\n}\n\nconst appName = props.appName;\nif (!appName) {\n return propIsRequiredMessage('appName');\n}\n\nconst entryRoute = props.entryRoute;\nif (!entryRoute) {\n return propIsRequiredMessage('entryRoute');\n}\n\nconst entryProps = props.entryProps || {};\n\nconst rootRoute = {\n name: entryRoute,\n props: entryProps,\n};\n\nif (!state) {\n State.init({\n renderCycles: state ? state.renderCycles + 1 : 1,\n layers: [rootRoute],\n });\n return 'Loading...';\n}\n\nconst env = {\n app: {\n owner: appOwner,\n name: appName,\n },\n VERSION,\n};\n\nconst COST_NEAR_PER_BYTE = Math.pow(10, 20);\nconst TGAS_300 = '300000000000000';\n\nconst AppState = {\n _state: {},\n set: (prop, value) => {\n AppState._state[prop] = value;\n return true;\n },\n get: (prop) => {\n return AppState._state[prop];\n },\n};\n\nfunction appStateGet(prop, defaultValue) {\n return AppState.get(`${appOwner}.${appName}.${prop}`) || defaultValue;\n}\nfunction appStateSet(prop, value) {\n return AppState.set(`${appOwner}.${appName}.${prop}`, value);\n}\n\nfunction storageGet(prop, defaultValue) {\n return Storage.get(`${appOwner}.${appName}.${prop}`) || defaultValue;\n}\nfunction storageSet(prop, value) {\n return Storage.set(`${appOwner}.${appName}.${prop}`, value);\n}\n\nfunction restoreRoutes() {\n const info = storageGet('routing', null);\n if (info === null || info === undefined) {\n return;\n }\n\n const layers = state.layers;\n if (\n layers &&\n Array.isArray(info) &&\n JSON.stringify(info) !== JSON.stringify(layers)\n ) {\n State.update({\n layers: info,\n });\n }\n}\n\nrestoreRoutes();\n\nfunction persistRoutingInformation(newState) {\n storageSet('routing', newState);\n}\n\nfunction slugFromName(name) {\n return name.split('.').join('__').split('-').join('_');\n}\n\nfunction widgetPathFromName(name) {\n return `${appOwner}/widget/${appName}__${slugFromName(name)}`;\n}\n\nfunction layoutPathFromName(name) {\n return widgetPathFromName(`layouts.${name}`);\n}\n\nfunction rerender() {\n // HACK: force a re-render\n State.update({\n renderCycles: state.renderCycles + 1,\n });\n}\n\nfunction push(name, props) {\n const layer = {\n name,\n props: props || {},\n };\n const newLayers = [...state.layers, layer];\n\n persistRoutingInformation(newLayers);\n\n State.update({\n layers: newLayers,\n });\n\n // rerender();\n}\n\nfunction replace(name, props) {\n console.log('replace', name, props);\n const layer = {\n name,\n props: props || {},\n };\n const newLayers = [...state.layers.slice(0, -1), layer];\n\n persistRoutingInformation(newLayers);\n\n State.update({\n layers: newLayers,\n });\n\n // rerender();\n}\n\n// pop from the stack, ensure we always have at least one layer\nfunction pop() {\n const newLayers =\n state.layers.length > 1 ? state.layers.slice(0, -1) : state.layers;\n\n persistRoutingInformation(newLayers);\n\n State.update({\n layers: newLayers,\n });\n\n rerender();\n}\n\nfunction dirtyEval(args) {\n const method = args[0];\n const key = args[1];\n const mArgs = args.slice(2);\n\n switch (method) {\n case 'push':\n return push(key, mArgs[0]);\n case 'replace':\n return replace(key, mArgs[0]);\n case 'pop':\n return pop();\n default:\n throw new Error(`Unknown method ${method}`);\n }\n}\n\nfunction isDate(value) {\n // we have no instanceof or typeof, so we check for the interface\n try {\n value.getFullYear();\n value.getMonth();\n value.getDate();\n value.getHours();\n value.getMinutes();\n value.getSeconds();\n return true;\n } catch (e) {\n return false;\n }\n}\n\nfunction formatDate(date, format) {\n const properDate = isDate(date) ? date : new Date(date);\n\n const dateString = properDate.toISOString();\n\n const parts = {\n YYYY: dateString.substring(0, 4),\n YY: dateString.substring(2, 4),\n MM: dateString.substring(5, 7),\n DD: dateString.substring(8, 10),\n hh: dateString.substring(11, 13),\n mm: dateString.substring(14, 16),\n ss: dateString.substring(17, 19),\n };\n\n return format.replace(\n /\\{\\{\\s*(?<part>YYYY|YY|MM|DD|hh|mm|ss)\\s*\\}\\}/gu,\n (match, part) => {\n return parts[part];\n }\n );\n}\n\n// https://stackoverflow.com/questions/5515869/string-length-in-bytes-in-javascript\nfunction byteLength(str) {\n // returns the byte length of an utf8 string\n var s = str.length;\n for (let i = str.length - 1; i >= 0; i--) {\n let code = str.charCodeAt(i);\n if (code > 0x7f && code <= 0x7ff) {\n s++;\n } else if (code > 0x7ff && code <= 0xffff) {\n s += 2;\n }\n if (code >= 0xdc00 && code <= 0xdfff) {\n i--;\n } //trail surrogate\n }\n return s;\n}\n\nfunction calculateStorageCost(value) {\n // get number of bytes without TextEncoder or Blob\n const bytes = byteLength(JSON.stringify(value));\n const estimated =\n COST_NEAR_PER_BYTE * (bytes + NEAR_STORAGE_BYTES_SAFTY_OFFSET);\n console.log('calculateStorageCost', {\n bytes,\n estimated,\n const: NEAR_STORAGE_BYTES_SAFTY_OFFSET,\n });\n return COST_NEAR_PER_BYTE * (bytes + NEAR_STORAGE_BYTES_SAFTY_OFFSET);\n}\n\nfunction contractCall(contractName, methodName, args) {\n const cost = calculateStorageCost(args);\n Near.call(contractName, methodName, args, TGAS_300, cost);\n}\n\nfunction renderComponent(name, props) {\n const engine = {\n env,\n accountId,\n\n push,\n pop,\n replace,\n rerender,\n appStateGet,\n appStateSet,\n storageGet,\n storageSet,\n layoutPathFromName,\n widgetPathFromName,\n\n renderComponent: safeRender,\n\n Components: {\n Select,\n Button,\n Loading,\n PageTitle,\n Container,\n InfoBar,\n InfoBarItem,\n InfoBarLink,\n TextHeader,\n InlineTag,\n Text,\n },\n\n helpers: {\n propIsRequiredMessage,\n calculateStorageCost,\n formatDate,\n },\n\n hacks: {\n dirtyEval,\n },\n\n TGAS_300,\n\n contract: {\n call: contractCall,\n },\n };\n\n const controllerProps = {\n __engine: engine,\n\n component: {\n name: name,\n props: props,\n },\n };\n\n return (\n <Widget\n src={`${appOwner}/widget/app__layout_controller`}\n key={props && props.key ? props.key : name}\n props={controllerProps}\n />\n );\n}\n\nfunction safeRender(_name, _props) {\n try {\n return renderComponent(_name, _props);\n } catch (err) {\n console.log(err);\n return (\n <div>\n Failed to render component <strong>{_name}</strong> with props:{' '}\n <pre>{JSON.stringify(_props, null, 4)}</pre>\n <br />\n <pre>{err.toString()}</pre>\n <br />\n </div>\n );\n }\n}\n\nconst FadeIn = styled.keyframes`\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n`;\n\nconst AppLayer = styled.div`\n animation: ${FadeIn} 0.2s ease-out;\n animation-fill-mode: forwards;\n width: 100vw;\n min-height: 100vh;\n background-color: transparent;\n z-index: ${(props) => props.zIndex};\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: auto;\n`;\n\nconst TimerRef = styled.div`\n animation: ${FadeIn} ${({ duration }) => duration}ms ease-out;\n width: 0;\n height: 0;\n`;\n\nconst Timer = (fn, ms) => {\n return (\n <>\n <button>asl;kdfhja sjdf</button>\n <TimerRef\n onAnimationEnd={() => {\n console.log('timer end');\n fn();\n }}\n props={{ duration: ms }}\n />\n </>\n );\n};\n\nreturn (\n <>\n <div id=\"app-state\" data-state={JSON.stringify(state)}></div>\n {Timer(() => {\n console.log('timer');\n }, 1000)}\n\n {/* state reset button */}\n <div\n style={{\n position: 'fixed',\n bottom: 0,\n right: 0,\n zIndex: 9999,\n padding: 8,\n backgroundColor: 'transparent',\n }}\n >\n <Button\n onClick={() => {\n storageSet('routing', [rootRoute]);\n State.update({\n layers: [rootRoute],\n });\n }}\n >\n Reset\n </Button>\n </div>\n\n {state.layers.map((layer, index) => {\n return (\n <AppLayer key={index} zIndex={index + 100}>\n {safeRender(layer.name, layer.props)}\n </AppLayer>\n );\n })}\n </>\n);\n" } } } } }

Transaction Execution Plan

Convert Transaction To Receipt
Gas Burned:
2 Tgas
Tokens Burned:
0.00025 
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
8 Tgas
Tokens Burned:
0.00087 
Called method: 'set' in contract: social.near
Arguments:
{ "data": { "events_v2.near": { "widget": { "app__frame": { "": "/* eslint no-magic-numbers: 0 */\n\nconst VERSION = '0.3.0';\n\n/**\n * NEAR Social App\n *\n * This is the main app component that is used to render the app.\n *\n *\n * WHY?\n * - DRY: we don't want to have to copy/paste the same code into every app\n * - Speed: we want to be able to build apps quickly\n * - Functionality: we want to be able to add functionality to all apps at once\n *\n *\n * HOW?\n * this app provides common functionality often needed in apps\n * - routing\n\n * - layout management\n *\n * Requirements:\n * - Fork the following widgets into your account:\n * - app__layouts__default\n * - app__frame (this component)\n * - You should also take a look at: https://github.com/NEARFoundation/events-platform\n * as it provides a lot of the functionality you need to build an app, it provides:\n * - an opinionated way to build apps\n * - directory structure\n * - naming conventions\n * - a way to build apps quickly\n * - development tools (dev server, deploy script)\n * - env var injection\n * - a sample app\n *\n *\n * This component is responsible for:\n * - Loading the app's state/environment\n * - Rendering the app's layouts\n * - Rendering the app's components\n *\n * It follows conventions:\n * - The app's environment is loaded from the props\n * - props.appOwner\n * - props.appName\n * - An app is a collection of widgets\n * - each widget must be namespaced by the app's owner and name\n * Widgets are named as follows:\n * - you choose an app_name like 'my_app'\n * - you choose a widget like 'my_widget'\n * - app, widgets and subwidgets are separated by '__'\n * - In order to use the widget in your app, you must upload it to your account with the name: `my_app__my_widget`\n * - e.g. app_namecomponent1\n * - e.g. app_namecomponent1__subcomponent\n * - Each widget can have a layout\n * - layouts are also widgets\n * - layouts are named as follows:\n * - you choose a layout like 'my_layout'\n * - In order to use the layout in your app, you must upload it to your account with the name: `my_app__layouts__my_layout`\n *\n *\n * Functions available to widgets:\n * - TODO: document\n *\n */\n\n/**\n * Adjust these:\n * */\n\nconst NEAR_STORAGE_BYTES_SAFTY_OFFSET = 42;\nconst PROP_IS_REQUIRED_MESSAGE = 'props.{prop} is required';\nconst PLEASE_CONNECT_WALLET_MESSAGE =\n 'Please connect your NEAR wallet to continue.';\n\nconst ContainerPaddingHorizontal = 'calc(max(28px, 1.6vw))';\n\nconst Select = styled.select`\n background-color: #4caf50;\n border: none;\n color: white;\n padding: 15px 32px;\n text-align: center;\n text-decoration: none;\n display: inline-block;\n font-size: 16px;\n margin: 4px 2px;\n cursor: pointer;\n`;\n\nconst Button = styled.button`\n background-color: #4caf50;\n border: none;\n color: white;\n padding: 15px 32px;\n text-align: center;\n text-decoration: none;\n display: inline-block;\n font-size: 16px;\n transition: all 0.5s ease;\n\n &:hover {\n background-color: #3e8e41;\n }\n`;\n\nconst Loading = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n`;\n\nconst PageTitle = styled.h1`\n font-size: calc(max(32px, 2.5vw));\n color: black;\n`;\n\nconst Container = styled.div`\n padding-left: ${ContainerPaddingHorizontal};\n padding-right: ${ContainerPaddingHorizontal};\n padding-top: 12px;\n padding-bottom: 12px;\n`;\n\nconst InfoBar = styled.div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n padding: 0px ${ContainerPaddingHorizontal};\n border-bottom: 1px solid #e0e0e0;\n`;\n\nconst InfoBarItem = styled.div`\n display: flex;\n align-items: center;\n margin-right: 12px;\n padding: 8px 0;\n`;\n\nconst InfoBarLink = styled.a`\n font-size: 16px;\n color: #424242;\n text-decoration: none;\n margin-right: 12px;\n padding: 8px 0;\n\n &:hover {\n text-decoration: underline;\n }\n\n &:last-child {\n margin-right: 0;\n }\n\n &:visited {\n color: #424242;\n }\n\n &:active {\n color: #424242;\n }\n`;\n\nconst TextHeader = styled.div`\n font-size: 20px;\n color: #424242;\n`;\n\nconst InlineTag = styled.div`\n display: inline-block;\n background-color: #e0e0e0;\n padding: 4px 8px;\n border-radius: 4px;\n margin-right: 8px;\n margin-left: 8px;\n`;\n\nconst Text = styled.div`\n font-size: 16px;\n color: #424242;\n margin-right: 8px;\n`;\n\n/**\n * I suggest you don't edit anything below this line\n * */\n\nconst accountId = context.accountId;\nif (!accountId) {\n return PLEASE_CONNECT_WALLET_MESSAGE;\n}\n\nfunction propIsRequiredMessage(prop) {\n return PROP_IS_REQUIRED_MESSAGE.replace('{prop}', prop);\n}\n\nconst appOwner = props.appOwner;\nif (!appOwner) {\n return propIsRequiredMessage('appOwner');\n}\n\nconst appName = props.appName;\nif (!appName) {\n return propIsRequiredMessage('appName');\n}\n\nconst entryRoute = props.entryRoute;\nif (!entryRoute) {\n return propIsRequiredMessage('entryRoute');\n}\n\nconst entryProps = props.entryProps || {};\n\nconst rootRoute = {\n name: entryRoute,\n props: entryProps,\n};\n\nif (!state) {\n State.init({\n renderCycles: state ? state.renderCycles + 1 : 1,\n layers: [rootRoute],\n });\n return 'Loading...';\n}\n\nconst env = {\n app: {\n owner: appOwner,\n name: appName,\n },\n VERSION,\n};\n\nconst COST_NEAR_PER_BYTE = Math.pow(10, 20);\nconst TGAS_300 = '300000000000000';\n\nconst AppState = {\n _state: {},\n set: (prop, value) => {\n AppState._state[prop] = value;\n return true;\n },\n get: (prop) => {\n return AppState._state[prop];\n },\n};\n\nfunction appStateGet(prop, defaultValue) {\n return AppState.get(`${appOwner}.${appName}.${prop}`) || defaultValue;\n}\nfunction appStateSet(prop, value) {\n return AppState.set(`${appOwner}.${appName}.${prop}`, value);\n}\n\nfunction storageGet(prop, defaultValue) {\n return Storage.get(`${appOwner}.${appName}.${prop}`) || defaultValue;\n}\nfunction storageSet(prop, value) {\n return Storage.set(`${appOwner}.${appName}.${prop}`, value);\n}\n\nfunction restoreRoutes() {\n const info = storageGet('routing', null);\n if (info === null || info === undefined) {\n return;\n }\n\n const layers = state.layers;\n if (\n layers &&\n Array.isArray(info) &&\n JSON.stringify(info) !== JSON.stringify(layers)\n ) {\n State.update({\n layers: info,\n });\n }\n}\n\nrestoreRoutes();\n\nfunction persistRoutingInformation(newState) {\n storageSet('routing', newState);\n}\n\nfunction slugFromName(name) {\n return name.split('.').join('__').split('-').join('_');\n}\n\nfunction widgetPathFromName(name) {\n return `${appOwner}/widget/${appName}__${slugFromName(name)}`;\n}\n\nfunction layoutPathFromName(name) {\n return widgetPathFromName(`layouts.${name}`);\n}\n\nfunction rerender() {\n // HACK: force a re-render\n State.update({\n renderCycles: state.renderCycles + 1,\n });\n}\n\nfunction push(name, props) {\n const layer = {\n name,\n props: props || {},\n };\n const newLayers = [...state.layers, layer];\n\n persistRoutingInformation(newLayers);\n\n State.update({\n layers: newLayers,\n });\n\n // rerender();\n}\n\nfunction replace(name, props) {\n console.log('replace', name, props);\n const layer = {\n name,\n props: props || {},\n };\n const newLayers = [...state.layers.slice(0, -1), layer];\n\n persistRoutingInformation(newLayers);\n\n State.update({\n layers: newLayers,\n });\n\n // rerender();\n}\n\n// pop from the stack, ensure we always have at least one layer\nfunction pop() {\n const newLayers =\n state.layers.length > 1 ? state.layers.slice(0, -1) : state.layers;\n\n persistRoutingInformation(newLayers);\n\n State.update({\n layers: newLayers,\n });\n\n rerender();\n}\n\nfunction dirtyEval(args) {\n const method = args[0];\n const key = args[1];\n const mArgs = args.slice(2);\n\n switch (method) {\n case 'push':\n return push(key, mArgs[0]);\n case 'replace':\n return replace(key, mArgs[0]);\n case 'pop':\n return pop();\n default:\n throw new Error(`Unknown method ${method}`);\n }\n}\n\nfunction isDate(value) {\n // we have no instanceof or typeof, so we check for the interface\n try {\n value.getFullYear();\n value.getMonth();\n value.getDate();\n value.getHours();\n value.getMinutes();\n value.getSeconds();\n return true;\n } catch (e) {\n return false;\n }\n}\n\nfunction formatDate(date, format) {\n const properDate = isDate(date) ? date : new Date(date);\n\n const dateString = properDate.toISOString();\n\n const parts = {\n YYYY: dateString.substring(0, 4),\n YY: dateString.substring(2, 4),\n MM: dateString.substring(5, 7),\n DD: dateString.substring(8, 10),\n hh: dateString.substring(11, 13),\n mm: dateString.substring(14, 16),\n ss: dateString.substring(17, 19),\n };\n\n return format.replace(\n /\\{\\{\\s*(?<part>YYYY|YY|MM|DD|hh|mm|ss)\\s*\\}\\}/gu,\n (match, part) => {\n return parts[part];\n }\n );\n}\n\n// https://stackoverflow.com/questions/5515869/string-length-in-bytes-in-javascript\nfunction byteLength(str) {\n // returns the byte length of an utf8 string\n var s = str.length;\n for (let i = str.length - 1; i >= 0; i--) {\n let code = str.charCodeAt(i);\n if (code > 0x7f && code <= 0x7ff) {\n s++;\n } else if (code > 0x7ff && code <= 0xffff) {\n s += 2;\n }\n if (code >= 0xdc00 && code <= 0xdfff) {\n i--;\n } //trail surrogate\n }\n return s;\n}\n\nfunction calculateStorageCost(value) {\n // get number of bytes without TextEncoder or Blob\n const bytes = byteLength(JSON.stringify(value));\n const estimated =\n COST_NEAR_PER_BYTE * (bytes + NEAR_STORAGE_BYTES_SAFTY_OFFSET);\n console.log('calculateStorageCost', {\n bytes,\n estimated,\n const: NEAR_STORAGE_BYTES_SAFTY_OFFSET,\n });\n return COST_NEAR_PER_BYTE * (bytes + NEAR_STORAGE_BYTES_SAFTY_OFFSET);\n}\n\nfunction contractCall(contractName, methodName, args) {\n const cost = calculateStorageCost(args);\n Near.call(contractName, methodName, args, TGAS_300, cost);\n}\n\nfunction renderComponent(name, props) {\n const engine = {\n env,\n accountId,\n\n push,\n pop,\n replace,\n rerender,\n appStateGet,\n appStateSet,\n storageGet,\n storageSet,\n layoutPathFromName,\n widgetPathFromName,\n\n renderComponent: safeRender,\n\n Components: {\n Select,\n Button,\n Loading,\n PageTitle,\n Container,\n InfoBar,\n InfoBarItem,\n InfoBarLink,\n TextHeader,\n InlineTag,\n Text,\n },\n\n helpers: {\n propIsRequiredMessage,\n calculateStorageCost,\n formatDate,\n },\n\n hacks: {\n dirtyEval,\n },\n\n TGAS_300,\n\n contract: {\n call: contractCall,\n },\n };\n\n const controllerProps = {\n __engine: engine,\n\n component: {\n name: name,\n props: props,\n },\n };\n\n return (\n <Widget\n src={`${appOwner}/widget/app__layout_controller`}\n key={props && props.key ? props.key : name}\n props={controllerProps}\n />\n );\n}\n\nfunction safeRender(_name, _props) {\n try {\n return renderComponent(_name, _props);\n } catch (err) {\n console.log(err);\n return (\n <div>\n Failed to render component <strong>{_name}</strong> with props:{' '}\n <pre>{JSON.stringify(_props, null, 4)}</pre>\n <br />\n <pre>{err.toString()}</pre>\n <br />\n </div>\n );\n }\n}\n\nconst FadeIn = styled.keyframes`\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n`;\n\nconst AppLayer = styled.div`\n animation: ${FadeIn} 0.2s ease-out;\n animation-fill-mode: forwards;\n width: 100vw;\n min-height: 100vh;\n background-color: transparent;\n z-index: ${(props) => props.zIndex};\n position: fixed;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n overflow: auto;\n`;\n\nconst TimerRef = styled.div`\n animation: ${FadeIn} ${({ duration }) => duration}ms ease-out;\n width: 0;\n height: 0;\n`;\n\nconst Timer = (fn, ms) => {\n return (\n <>\n <button>asl;kdfhja sjdf</button>\n <TimerRef\n onAnimationEnd={() => {\n console.log('timer end');\n fn();\n }}\n props={{ duration: ms }}\n />\n </>\n );\n};\n\nreturn (\n <>\n <div id=\"app-state\" data-state={JSON.stringify(state)}></div>\n {Timer(() => {\n console.log('timer');\n }, 1000)}\n\n {/* state reset button */}\n <div\n style={{\n position: 'fixed',\n bottom: 0,\n right: 0,\n zIndex: 9999,\n padding: 8,\n backgroundColor: 'transparent',\n }}\n >\n <Button\n onClick={() => {\n storageSet('routing', [rootRoute]);\n State.update({\n layers: [rootRoute],\n });\n }}\n >\n Reset\n </Button>\n </div>\n\n {state.layers.map((layer, index) => {\n return (\n <AppLayer key={index} zIndex={index + 100}>\n {safeRender(layer.name, layer.props)}\n </AppLayer>\n );\n })}\n </>\n);\n" } } } } }
Empty result
No logs
Receipt:
Predecessor ID:
Receiver ID:
Gas Burned:
223 Ggas
Tokens Burned:
0 
Transferred 0.00312  to events_v2.near
Empty result
No logs