Skip to content

Commit 4c0f853

Browse files
committed
[type conversion] Add ability to take in plain types and convert them to entry function types
1 parent 214ab6c commit 4c0f853

File tree

4 files changed

+1456
-0
lines changed

4 files changed

+1456
-0
lines changed

bcs/serializer.go

+7
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,13 @@ func SerializeU256(input big.Int) ([]byte, error) {
293293
})
294294
}
295295

296+
// SerializeUleb128 Serializes a single uleb128
297+
func SerializeUleb128(input uint32) ([]byte, error) {
298+
return SerializeSingle(func(ser *Serializer) {
299+
ser.Uleb128(input)
300+
})
301+
}
302+
296303
// SerializeBytes Serializes a single byte array
297304
//
298305
// input := []byte{0x1, 0x2}

nodeClient.go

+103
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,109 @@ func (rc *NodeClient) AccountResourcesBCS(address AccountAddress, ledgerVersion
177177
return
178178
}
179179

180+
// AccountModule
181+
func (rc *NodeClient) AccountModule(address AccountAddress, moduleName string, ledgerVersion ...uint64) (data *api.MoveModule, err error) {
182+
au := rc.baseUrl.JoinPath("accounts", address.String(), "module", moduleName)
183+
if len(ledgerVersion) > 0 {
184+
params := url.Values{}
185+
params.Set("ledger_version", strconv.FormatUint(ledgerVersion[0], 10))
186+
au.RawQuery = params.Encode()
187+
}
188+
data, err = Get[*api.MoveModule](rc, au.String())
189+
if err != nil {
190+
return nil, fmt.Errorf("get module api err: %w", err)
191+
}
192+
return data, nil
193+
}
194+
195+
func (rc *NodeClient) EntryFunctionWithArgs(address AccountAddress, moduleName string, functionName string, typeArgs []any, args []any) (entry *EntryFunction, err error) {
196+
// TODO: This should be cached / we should be able to take in an ABI
197+
module, err := rc.AccountModule(address, moduleName)
198+
if err != nil {
199+
return nil, err
200+
}
201+
202+
// TODO: everything below should be moved out of the client
203+
// Find function
204+
var function *api.MoveFunction
205+
for _, fun := range module.ExposedFunctions {
206+
if fun.Name == functionName {
207+
if fun.IsEntry == false {
208+
return nil, fmt.Errorf("function %s is not a entry function in module %s", functionName, moduleName)
209+
}
210+
211+
function = fun
212+
break
213+
}
214+
}
215+
216+
if function == nil {
217+
return nil, fmt.Errorf("entry function %s not found in module %s", functionName, moduleName)
218+
}
219+
220+
// Check type args length matches
221+
if len(typeArgs) != len(function.GenericTypeParams) {
222+
return nil, fmt.Errorf("entry function %s does not have the correct number of type arguments for function %s", functionName, functionName)
223+
}
224+
225+
// TODO: Convert args, skipping signers
226+
227+
// Convert TypeTag, *TypeTag, and string to TypeTag
228+
// TODO: Check properties of generic type?
229+
convertedTypeArgs := make([]TypeTag, len(typeArgs))
230+
for i, typeArg := range typeArgs {
231+
tag, err := ConvertTypeTag(typeArg)
232+
if err != nil {
233+
return nil, err
234+
}
235+
convertedTypeArgs[i] = *tag
236+
}
237+
238+
// Convert string types to actual types
239+
argTypes := make([]TypeTag, 0)
240+
for _, typeStr := range function.Params {
241+
typeArg, err := ParseTypeTag(typeStr)
242+
if err != nil {
243+
return nil, err
244+
}
245+
246+
// If it's `signer` or `&signer` need to skip
247+
// TODO: only skip at the beginning
248+
switch typeArg.Value.(type) {
249+
case *SignerTag:
250+
// Skip
251+
continue
252+
case *ReferenceTag:
253+
innerArg := typeArg.Value.(*ReferenceTag)
254+
switch innerArg.TypeParam.Value.(type) {
255+
case *SignerTag:
256+
// Skip
257+
continue
258+
default:
259+
argTypes = append(argTypes, *typeArg)
260+
}
261+
default:
262+
argTypes = append(argTypes, *typeArg)
263+
}
264+
}
265+
266+
// Check args length matches
267+
if len(args) != len(function.Params) {
268+
return nil, fmt.Errorf("entry function %s does not have the correct number of arguments for function %s", functionName, functionName)
269+
}
270+
271+
convertedArgs := make([][]byte, len(args))
272+
for i, arg := range args {
273+
b, err := ConvertArg(argTypes[i], arg, argTypes)
274+
if err != nil {
275+
return nil, err
276+
}
277+
convertedArgs[i] = b
278+
}
279+
280+
return entry, err
281+
}
282+
180283
// TransactionByHash gets info on a transaction
181284
// The transaction may be pending or recently committed. If the transaction is a [api.PendingTransaction], then it is
182285
// still in the mempool. If the transaction is any other type, it has been committed.

0 commit comments

Comments
 (0)