Skip to content
This repository has been archived by the owner on Dec 15, 2023. It is now read-only.

Commit

Permalink
feat: interpret special instruction
Browse files Browse the repository at this point in the history
  • Loading branch information
mariz-ov committed Nov 8, 2023
1 parent 358e147 commit 81fcf0d
Show file tree
Hide file tree
Showing 4 changed files with 270 additions and 37 deletions.
58 changes: 46 additions & 12 deletions web/src/dojo/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -1439,7 +1439,7 @@
{
"name": "rps_actions",
"address": "0x617decd4dbeb7291a7a00a506f9287389eb75a7fc125edf49e3cad4611ef175",
"class_hash": "0x228537cbbe84dc8b27aa65df0d9276954980788eccd0b5c3a26de431ef51380",
"class_hash": "0x4adb5993f78b47b1f3ee3ce4c228d947c26a7cb31b61a94bac5e6913ba8d3c8",
"abi": [
{
"type": "impl",
Expand Down Expand Up @@ -1505,6 +1505,28 @@
}
]
},
{
"type": "enum",
"name": "pixelaw::apps::rps::app::Move",
"variants": [
{
"name": "None",
"type": "()"
},
{
"name": "Rock",
"type": "()"
},
{
"name": "Paper",
"type": "()"
},
{
"name": "Scissors",
"type": "()"
}
]
},
{
"type": "interface",
"name": "pixelaw::apps::rps::app::IRpsActions",
Expand All @@ -1516,6 +1538,18 @@
"outputs": [],
"state_mutability": "view"
},
{
"type": "function",
"name": "secondary",
"inputs": [
{
"name": "default_params",
"type": "pixelaw::core::utils::DefaultParameters"
}
],
"outputs": [],
"state_mutability": "view"
},
{
"type": "function",
"name": "interact",
Expand All @@ -1525,7 +1559,7 @@
"type": "pixelaw::core::utils::DefaultParameters"
},
{
"name": "commit",
"name": "cr_Move_move",
"type": "core::felt252"
}
],
Expand All @@ -1542,7 +1576,7 @@
},
{
"name": "player2_move",
"type": "core::integer::u8"
"type": "pixelaw::apps::rps::app::Move"
}
],
"outputs": [],
Expand All @@ -1557,11 +1591,11 @@
"type": "pixelaw::core::utils::DefaultParameters"
},
{
"name": "player1_move",
"type": "core::integer::u8"
"name": "rv_move",
"type": "pixelaw::apps::rps::app::Move"
},
{
"name": "player1_salt",
"name": "rs_move",
"type": "core::felt252"
}
],
Expand Down Expand Up @@ -1622,7 +1656,7 @@
{
"name": "snake_actions",
"address": "0x26c141617c37324fa943e5509d29a21b4017abad5ee56f6351deef299c819d0",
"class_hash": "0x7a6fdb8251ea693ee2fa142ff0c2c8db507f9a9021d771de2d3c183ece14aec",
"class_hash": "0x6bd83e497e84342eb1469bdbf2014f09d10f3ee8ef597df295da884cbb4fd3",
"abi": [
{
"type": "impl",
Expand Down Expand Up @@ -2572,7 +2606,7 @@
},
{
"name": "state",
"type": "u8",
"type": "State",
"key": false
},
{
Expand All @@ -2592,12 +2626,12 @@
},
{
"name": "player1_move",
"type": "u8",
"type": "Move",
"key": false
},
{
"name": "player2_move",
"type": "u8",
"type": "Move",
"key": false
},
{
Expand All @@ -2606,7 +2640,7 @@
"key": false
}
],
"class_hash": "0x6d7c8c64cc0e865a542e071598421fb12a80bcdf716bad8dc63e6b4b2797ceb",
"class_hash": "0x7013e36daf8e106b7e02a57309a1fe6fcaaacbfacbcb922c64831ff45d46b78",
"abi": [
{
"type": "function",
Expand Down Expand Up @@ -3942,4 +3976,4 @@
]
}
]
}
}
2 changes: 2 additions & 0 deletions web/src/global/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ export async function streamToString(readableStream: ReadableStream) {
export const felt252ToString = (felt252: string | number) => {
switch (felt252) {
case '0x7061696e74': return 'Paint'
case '0x6a6f696e': return 'join'
case '0x66696e697368': return 'finish'
default: return felt252 as string
}
}
Expand Down
78 changes: 53 additions & 25 deletions web/src/hooks/systems/useInteract.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { EntityIndex, getComponentValue } from '@latticexyz/recs'
import { getEntityIdFromKeys } from '@dojoengine/utils'
import manifest from './../../dojo/manifest.json'
import { num } from 'starknet'
import interpret, { isInstruction } from '@/lib/Instruction'

const DEFAULT_PARAMETERS_TYPE = 'pixelaw::core::utils::DefaultParameters'

Expand All @@ -14,7 +15,6 @@ const convertSnakeToPascal = (snakeCaseString: string) => {
}).join('')
}

/// @dev this does not handle enum and struct lookup yet for the params
const useInteract = (
contractName: string,
color: string,
Expand All @@ -30,6 +30,8 @@ const useInteract = (
} = useDojo()




const solidColor = color.replace('#', '0xFF')
const decimalColor = convertToDecimal(solidColor)

Expand All @@ -46,66 +48,92 @@ const useInteract = (
if (!methods) throw new Error(`unknown interface: ${interfaceName}`)
if (!methods?.items) throw new Error(`no methods for interface: ${interfaceName}`)

const functionDef = methods.items.find(method => method.name === methodName && method.type === 'function')
if (!functionDef) throw new Error(`function ${methodName} not found`)
let functionDef = methods.items.find(method => method.name === methodName && method.type === 'function')
if (!functionDef) {
functionDef = methods.items.find(method => method.name === 'interact' && method.type === 'function')
if (!functionDef) throw new Error(`function ${methodName} not found`)
}
const parameters = functionDef.inputs.filter(input => input.type !== DEFAULT_PARAMETERS_TYPE)

const paramsDef = parameters.map(param => {
if (isInstruction(param.name)) {
// problem with types on contract.abi
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
return interpret(contractName, position, param.name, contract.abi)
}
const isPrimitiveType = param.type.includes("core::integer") || param.type.includes("core::felt252")
let type: 'number' | 'string' | 'enum' | 'struct' = 'number'
let variants: {name: string, value: number}[] = []
if (!isPrimitiveType) {
const typeDefinition = contract.abi.find(x => x.name === param.type)
if (typeDefinition?.type === "enum") {
variants = (typeDefinition?.variants ?? []).map((variant, index) => {
return {
name: variant.name,
value: index
}
})
type = 'enum'
}
const typeDefinition = contract.abi.find(x => x.name === param.type)
if (typeDefinition?.type === "enum") {
variants = (typeDefinition?.variants ?? []).map((variant, index) => {
return {
name: variant.name,
value: index
}
})
type = 'enum'
}
} else if (param.type.includes("core::felt252")) {
type = 'string'
}
return {
name: param.name,
type,

// if is not primitive type fill these out
variants,
structDefinition: {}
structDefinition: {},

// for interpret instruction only
transformValue: undefined,
value: undefined,

}
})

const fillableParamDefs = paramsDef.filter(paramDef => !paramDef?.value)

return {
interact: useMutation({
mutationKey: ['useInteract', contractName, color],
mutationFn: async ({otherParams}: {
otherParams?: Record<string, any>
}) => {
if (!otherParams && paramsDef.length > 0) throw new Error('incomplete parameters')
else if (!otherParams) {
if (!otherParams && fillableParamDefs.length > 0) throw new Error('incomplete parameters')
else if (!otherParams && !paramsDef.length) {
return interact(account, contractName, position, decimalColor, methodName)
}

const additionalParams: num.BigNumberish[] = []

for (const paramDef of paramsDef) {
const param = otherParams[paramDef.name]
if (
(paramDef.type === 'string' && typeof param !== 'string') ||
(paramDef.type === 'number' && typeof param !== 'number')
) throw new Error(`incorrect parameter for ${paramDef.name}. supplied is ${param}`)

// TODO handle structs and enums
additionalParams.push(param)
if (paramDef.value) {
additionalParams.push(paramDef.value)
} else {
if(!otherParams) continue
const param = otherParams[paramDef.name]
if (
(paramDef.type === 'string' && typeof param !== 'string') ||
(paramDef.type === 'number' && typeof param !== 'number')
) throw new Error(`incorrect parameter for ${paramDef.name}. supplied is ${param}`)

// TODO handle structs
if (paramDef.transformValue) {
additionalParams.push(paramDef.transformValue(param))
}
else additionalParams.push(param)
}
}

console.log(additionalParams)

interact(account, contractName, position, decimalColor, methodName, additionalParams)
}
}),
params: paramsDef
params: fillableParamDefs
}
}

Expand Down
Loading

0 comments on commit 81fcf0d

Please sign in to comment.