Search
Search

Transaction: 7h6bmN6...Rtmw

Receiver
Status
Succeeded
Transaction Fee
0.00115 
Deposit Value
0.001 
Gas Used
11 Tgas
Attached Gas
30 Tgas
Created
February 07, 2023 at 12:01:27pm
Hash
7h6bmN6U2EpQhevAwDfWbxnBL399HZMmKpYMDdXjRtmw

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 * Docs: https://github.com/NEARFoundation/events-platform\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))';\nconst ContainerPaddingVertical = 'calc(max(12px, 1.2vw))';\n\n/**\n * Animation\n * */\nconst FadeIn = styled.keyframes`\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n`;\n\nconst SlideInLeft = styled.keyframes`\n 0% {\n opacity: 0;\n transform: translateX(-20px);\n }\n 100% {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\n/**\n * Components\n * */\n\nconst Components = {\n 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\n 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\n Loading: styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n `,\n\n PageTitle: styled.h1`\n font-size: calc(max(32px, 2.5vw));\n color: black;\n `,\n\n Container: styled.div`\n padding-left: ${ContainerPaddingHorizontal};\n padding-right: ${ContainerPaddingHorizontal};\n padding-top: ${ContainerPaddingVertical};\n padding-bottom: ${ContainerPaddingVertical};\n `,\n\n ContainerHeader: styled.div`\n font-size: 24px;\n color: #424242;\n padding: ${ContainerPaddingVertical} 0;\n @media (max-width: 768px) {\n font-size: 20px;\n }\n `,\n\n 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\n InfoBarItem: styled.div`\n display: flex;\n align-items: center;\n margin-right: 12px;\n padding: 8px 0;\n `,\n\n 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\n TextHeader: styled.div`\n font-size: 20px;\n color: #424242;\n `,\n\n 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\n Text: styled.div`\n font-size: 16px;\n color: #424242;\n margin-right: 8px;\n `,\n\n ValidationError: styled.div`\n color: #c00;\n font-size: 0.8rem;\n margin: 0.5rem 0 0 0;\n `,\n\n FullActionButton: styled.button`\n width: 100%;\n padding: 0.5rem;\n margin: 0;\n border: 1px solid #ccc;\n border-radius: 4px;\n box-sizing: border-box;\n background-color: #ccc;\n `,\n\n FormLabel: styled.label`\n width: 100%;\n color: #666;\n padding: 0.5rem 0;\n margin: 0.5rem 0 0 0;\n box-sizing: border-box;\n `,\n\n GridContainer: styled.div`\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n justify-content: flex-start;\n\n width: auto;\n margin-left: -20px;\n margin-right: -20px;\n\n & > * {\n margin: 20px 20px;\n max-width: 520px;\n min-width: 320px;\n width: ${({ itemWidth }) => itemWidth || '240px'};\n flex-grow: 3;\n flex-shrink: 3;\n\n animation: ${SlideInLeft} 0.3s ease-in-out;\n }\n `,\n\n Card: styled.div`\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n align-items: stretch;\n justify-content: stretch;\n padding: 0;\n background-color: #ffffff;\n border-radius: 16px 16px;\n box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.2);\n border: 0.1vw solid #cccccc;\n cursor: pointer;\n\n transition: all 0.5s cubic-bezier(0.25, 0.8, 0.25, 1);\n\n &:hover {\n box-shadow: 5px 0 15px -2px rgba(0, 0, 0, 0.2);\n }\n `,\n\n CardHeaderImage: styled.div`\n height: auto;\n width: 100%;\n aspect-ratio: 1 / 1;\n overflow: hidden;\n border-radius: 14px 14px 0 0;\n border-bottom: 0.1vw solid #cccccc;\n flex-shrink: 0;\n flex-grow: 0;\n `,\n\n CardBody: styled.div`\n width: 100%;\n height: auto;\n flex-grow: 100;\n flex-shrink: 0;\n padding: 1vw calc(max(0.5rem, 0.5vw));\n `,\n\n CardFooter: styled.div`\n font-size: 0.8vw;\n font-weight: 400;\n margin: 0;\n padding: calc(max(0.5rem, 0.5vw));\n height: 42px;\n flex-grow: 0;\n flex-shrink: 0;\n width: 100%;\n border-top: 0.1vw solid #cccccc;\n `,\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 DEBUG = props.DEBUG || false;\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 SessionState = {\n _state: {},\n set: (prop, value) => {\n SessionState._state[prop] = value;\n return true;\n },\n get: (prop) => {\n return SessionState._state[prop];\n },\n};\n\nfunction sessionGet(prop, defaultValue) {\n return SessionState.get(`${appOwner}.${appName}.${prop}`) || defaultValue;\n}\nfunction sessionSet(prop, value) {\n return SessionState.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 fetchPathOptions(path) {\n const nameParts = path.split(':');\n if (nameParts.length === 1) {\n return {\n owner: appOwner,\n name: appName,\n slug: slugFromName(nameParts[0]),\n };\n }\n if (nameParts.length === 2) {\n return {\n owner: appOwner,\n name: nameParts[0],\n slug: slugFromName(nameParts[1]),\n };\n }\n if (nameParts.length === 3) {\n return {\n owner: nameParts[0],\n name: nameParts[1],\n slug: slugFromName(nameParts[2]),\n };\n }\n throw new Error(`Invalid path: ${path}`);\n}\n\nfunction widgetPathFromName(widgetName) {\n const { owner, name, slug } = fetchPathOptions(widgetName);\n return `${owner}/widget/${name}__${slug}`;\n}\n\nfunction layoutPathFromName(layoutName) {\n return widgetPathFromName(layoutName);\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 return COST_NEAR_PER_BYTE * (bytes + NEAR_STORAGE_BYTES_SAFTY_OFFSET);\n}\n\nfunction contractCall(contractName, methodName, args) {\n const cost = calculateStorageCost(args);\n console.log('contractCall', { contractName, methodName, args, cost });\n Near.call(contractName, methodName, args, TGAS_300, cost);\n}\n\nfunction contractView(contractName, methodName, args) {\n console.log('contractView', { contractName, methodName, args });\n return Near.view(contractName, methodName, args);\n}\n\nfunction loading(displayText) {\n const text = displayText || 'Loading...';\n return renderComponent('app:loading', { text });\n}\n\nfunction renderComponent(name, props) {\n const engine = {\n env,\n accountId,\n\n loading,\n push,\n pop,\n replace,\n rerender,\n sessionGet,\n sessionSet,\n storageGet,\n storageSet,\n layoutPathFromName,\n widgetPathFromName,\n\n renderComponent: safeRender,\n\n Components,\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 view: contractView,\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 AppLayer = styled.div`\n animation: ${FadeIn} 0.3s ease-in-out;\n animation-fill-mode: forwards;\n animation-delay: ${(props) => props.delay};\n animation-duration: ${(props) => props.duration};\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 opacity: 0;\n\n backdrop-filter: ${(props) => {\n return props.backdropFilter;\n }};\n webkit-backdrop-filter: ${(props) => {\n return props.backdropFilter;\n }};\n\n transition: backdrop-filter 0.3s ease-in-out;\n transition-delay: ${(props) => props.transitionDelay};\n`;\n\n// have to deconstruct Components here because of a bug in the VM.\n// It cannot render <Components.Button /> :(\nconst { Button } = Components;\n\nreturn (\n <>\n <div id=\"app-state\" data-state={JSON.stringify(state)}></div>\n\n {/* state reset button */}\n {DEBUG ? (\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 ) : null}\n\n {state.layers.map((layer, index) => {\n const isLast = index === state.layers.length - 1;\n\n return (\n <AppLayer\n key={index}\n delay={isLast ? '0.0s' : '0.2s'}\n duration={isLast ? '0.3s' : '1s'}\n transitionDelay={isLast ? '0s' : '1s'}\n backdropFilter={\n isLast\n ? 'blur(16px) saturate(140%) brightness(80%)'\n : 'blur(0px) saturate(100%) brightness(100%)'\n }\n zIndex={index + 100}\n >\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.0009 
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 * Docs: https://github.com/NEARFoundation/events-platform\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))';\nconst ContainerPaddingVertical = 'calc(max(12px, 1.2vw))';\n\n/**\n * Animation\n * */\nconst FadeIn = styled.keyframes`\n 0% {\n opacity: 0;\n }\n 100% {\n opacity: 1;\n }\n`;\n\nconst SlideInLeft = styled.keyframes`\n 0% {\n opacity: 0;\n transform: translateX(-20px);\n }\n 100% {\n opacity: 1;\n transform: translateX(0);\n }\n`;\n\n/**\n * Components\n * */\n\nconst Components = {\n 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\n 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\n Loading: styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n height: 100%;\n width: 100%;\n `,\n\n PageTitle: styled.h1`\n font-size: calc(max(32px, 2.5vw));\n color: black;\n `,\n\n Container: styled.div`\n padding-left: ${ContainerPaddingHorizontal};\n padding-right: ${ContainerPaddingHorizontal};\n padding-top: ${ContainerPaddingVertical};\n padding-bottom: ${ContainerPaddingVertical};\n `,\n\n ContainerHeader: styled.div`\n font-size: 24px;\n color: #424242;\n padding: ${ContainerPaddingVertical} 0;\n @media (max-width: 768px) {\n font-size: 20px;\n }\n `,\n\n 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\n InfoBarItem: styled.div`\n display: flex;\n align-items: center;\n margin-right: 12px;\n padding: 8px 0;\n `,\n\n 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\n TextHeader: styled.div`\n font-size: 20px;\n color: #424242;\n `,\n\n 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\n Text: styled.div`\n font-size: 16px;\n color: #424242;\n margin-right: 8px;\n `,\n\n ValidationError: styled.div`\n color: #c00;\n font-size: 0.8rem;\n margin: 0.5rem 0 0 0;\n `,\n\n FullActionButton: styled.button`\n width: 100%;\n padding: 0.5rem;\n margin: 0;\n border: 1px solid #ccc;\n border-radius: 4px;\n box-sizing: border-box;\n background-color: #ccc;\n `,\n\n FormLabel: styled.label`\n width: 100%;\n color: #666;\n padding: 0.5rem 0;\n margin: 0.5rem 0 0 0;\n box-sizing: border-box;\n `,\n\n GridContainer: styled.div`\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n justify-content: flex-start;\n\n width: auto;\n margin-left: -20px;\n margin-right: -20px;\n\n & > * {\n margin: 20px 20px;\n max-width: 520px;\n min-width: 320px;\n width: ${({ itemWidth }) => itemWidth || '240px'};\n flex-grow: 3;\n flex-shrink: 3;\n\n animation: ${SlideInLeft} 0.3s ease-in-out;\n }\n `,\n\n Card: styled.div`\n display: flex;\n flex-direction: column;\n flex-wrap: wrap;\n align-items: stretch;\n justify-content: stretch;\n padding: 0;\n background-color: #ffffff;\n border-radius: 16px 16px;\n box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.2);\n border: 0.1vw solid #cccccc;\n cursor: pointer;\n\n transition: all 0.5s cubic-bezier(0.25, 0.8, 0.25, 1);\n\n &:hover {\n box-shadow: 5px 0 15px -2px rgba(0, 0, 0, 0.2);\n }\n `,\n\n CardHeaderImage: styled.div`\n height: auto;\n width: 100%;\n aspect-ratio: 1 / 1;\n overflow: hidden;\n border-radius: 14px 14px 0 0;\n border-bottom: 0.1vw solid #cccccc;\n flex-shrink: 0;\n flex-grow: 0;\n `,\n\n CardBody: styled.div`\n width: 100%;\n height: auto;\n flex-grow: 100;\n flex-shrink: 0;\n padding: 1vw calc(max(0.5rem, 0.5vw));\n `,\n\n CardFooter: styled.div`\n font-size: 0.8vw;\n font-weight: 400;\n margin: 0;\n padding: calc(max(0.5rem, 0.5vw));\n height: 42px;\n flex-grow: 0;\n flex-shrink: 0;\n width: 100%;\n border-top: 0.1vw solid #cccccc;\n `,\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 DEBUG = props.DEBUG || false;\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 SessionState = {\n _state: {},\n set: (prop, value) => {\n SessionState._state[prop] = value;\n return true;\n },\n get: (prop) => {\n return SessionState._state[prop];\n },\n};\n\nfunction sessionGet(prop, defaultValue) {\n return SessionState.get(`${appOwner}.${appName}.${prop}`) || defaultValue;\n}\nfunction sessionSet(prop, value) {\n return SessionState.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 fetchPathOptions(path) {\n const nameParts = path.split(':');\n if (nameParts.length === 1) {\n return {\n owner: appOwner,\n name: appName,\n slug: slugFromName(nameParts[0]),\n };\n }\n if (nameParts.length === 2) {\n return {\n owner: appOwner,\n name: nameParts[0],\n slug: slugFromName(nameParts[1]),\n };\n }\n if (nameParts.length === 3) {\n return {\n owner: nameParts[0],\n name: nameParts[1],\n slug: slugFromName(nameParts[2]),\n };\n }\n throw new Error(`Invalid path: ${path}`);\n}\n\nfunction widgetPathFromName(widgetName) {\n const { owner, name, slug } = fetchPathOptions(widgetName);\n return `${owner}/widget/${name}__${slug}`;\n}\n\nfunction layoutPathFromName(layoutName) {\n return widgetPathFromName(layoutName);\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 return COST_NEAR_PER_BYTE * (bytes + NEAR_STORAGE_BYTES_SAFTY_OFFSET);\n}\n\nfunction contractCall(contractName, methodName, args) {\n const cost = calculateStorageCost(args);\n console.log('contractCall', { contractName, methodName, args, cost });\n Near.call(contractName, methodName, args, TGAS_300, cost);\n}\n\nfunction contractView(contractName, methodName, args) {\n console.log('contractView', { contractName, methodName, args });\n return Near.view(contractName, methodName, args);\n}\n\nfunction loading(displayText) {\n const text = displayText || 'Loading...';\n return renderComponent('app:loading', { text });\n}\n\nfunction renderComponent(name, props) {\n const engine = {\n env,\n accountId,\n\n loading,\n push,\n pop,\n replace,\n rerender,\n sessionGet,\n sessionSet,\n storageGet,\n storageSet,\n layoutPathFromName,\n widgetPathFromName,\n\n renderComponent: safeRender,\n\n Components,\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 view: contractView,\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 AppLayer = styled.div`\n animation: ${FadeIn} 0.3s ease-in-out;\n animation-fill-mode: forwards;\n animation-delay: ${(props) => props.delay};\n animation-duration: ${(props) => props.duration};\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 opacity: 0;\n\n backdrop-filter: ${(props) => {\n return props.backdropFilter;\n }};\n webkit-backdrop-filter: ${(props) => {\n return props.backdropFilter;\n }};\n\n transition: backdrop-filter 0.3s ease-in-out;\n transition-delay: ${(props) => props.transitionDelay};\n`;\n\n// have to deconstruct Components here because of a bug in the VM.\n// It cannot render <Components.Button /> :(\nconst { Button } = Components;\n\nreturn (\n <>\n <div id=\"app-state\" data-state={JSON.stringify(state)}></div>\n\n {/* state reset button */}\n {DEBUG ? (\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 ) : null}\n\n {state.layers.map((layer, index) => {\n const isLast = index === state.layers.length - 1;\n\n return (\n <AppLayer\n key={index}\n delay={isLast ? '0.0s' : '0.2s'}\n duration={isLast ? '0.3s' : '1s'}\n transitionDelay={isLast ? '0s' : '1s'}\n backdropFilter={\n isLast\n ? 'blur(16px) saturate(140%) brightness(80%)'\n : 'blur(0px) saturate(100%) brightness(100%)'\n }\n zIndex={index + 100}\n >\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.00309  to events_v2.near
Empty result
No logs