Closed efeint01 closed 6 months ago
Websocket connection is successful, We're getting this error on while running funds transfer function.
extrinsic = extBuilder.transfer(keypair.publicKey, BigInteger.TEN).build()
Full Error:
java.lang.IllegalStateException: Type Address was not found.
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: java.lang.IllegalStateException: Type Address was not found.
at jp.co.soramitsu.fearless_utils.runtime.definitions.registry.TypeRegistryExtKt.getOrThrow(TypeRegistryExt.kt:8)
at jp.co.soramitsu.fearless_utils.runtime.definitions.types.instances.AddressInstanceConstructor.constructInstance(AddressInstanceConstructor.kt:16)
at jp.co.soramitsu.fearless_utils.runtime.definitions.types.instances.AddressInstanceConstructor.constructInstance(AddressInstanceConstructor.kt:13)
at jp.co.soramitsu.fearless_utils.runtime.extrinsic.ExtrinsicBuilder.buildEncodableAddressInstance(ExtrinsicBuilder.kt:195)
at jp.co.soramitsu.fearless_utils.runtime.extrinsic.ExtrinsicBuilder.build(ExtrinsicBuilder.kt:129)
at jp.co.soramitsu.fearless_utils.runtime.extrinsic.ExtrinsicBuilder.build(ExtrinsicBuilder.kt:94)
at jp.co.soramitsu.fearless_utils.runtime.extrinsic.ExtrinsicBuilder.build$default(ExtrinsicBuilder.kt:90)
For better analysis please provide the following:
Typefile details: typefile.json
Related code:
suspend fun testQuery(context: Context) {
val reconnector = Reconnector(strategy = ConstantReconnectStrategy(1000L))
val requestExecutor = RequestExecutor()
val socketService = SocketService(
Gson(),
StdoutLogger,
WebSocketFactory(),
reconnector,
requestExecutor,
)
socketService.start(websocketUrl)
val blockchainService = BlockchainService()
val runtime = blockchainService.buildRuntimeV14(context)
val keypair = SubstrateKeypairFactory.generate(EncryptionType.SR25519, ByteArray(32))
val extBuilder = ExtrinsicBuilder(
runtime = runtime,
signer = KeyPairSigner(
keypair = keypair,
encryption = MultiChainEncryption.Substrate(EncryptionType.SR25519)
),
nonce = 0.toBigInteger(),
runtimeVersion = RuntimeVersion(103, 1),
accountId = keypair.publicKey.publicKeyToSubstrateAccountId(),
genesisHash = "0xbc6eb9753e2417476601485f9f8ef8474701ec199d456f989bd397682c9425c5".fromHex()
)
fun ExtrinsicBuilder.transfer(
recipientAccountId: ByteArray,
amount: BigInteger
): ExtrinsicBuilder {
return call(
moduleName = "Balances",
callName = "transfer",
arguments = mapOf(
"dest" to DictEnum.Entry(
name = "Id",
value = "340a806419d5e278172e45cb0e50da1b031795366c99ddfe0a680bd53b142c63".fromHex()
),
"value" to amount
)
)
}
val extrinsic = extBuilder.transfer(keypair.publicKey, BigInteger.TEN).build()
val result = socketService.executeAsync(SubmitExtrinsicRequest(extrinsic)).result
Log.e("TAG", "testQuery: $result")
}
Please share code of buildRuntimeV14
. In general, missing Address
type means that you dont actually apply the additional types file. There are two ways to fix it:
TypeRegsitry
constructor, exampleI've updated sdk version to 2.0.1 (latest version) -Here is buildRuntimeV14 code
class BlockchainService {
fun buildRuntimeV14(context: Context, networkName: String = "network"): RuntimeSnapshot {
val gson = Gson()
val metadataRaw = buildRawMetadata(context, networkName)
val metadataTypePreset =
TypesParserV14.parse(metadataRaw.metadata[RuntimeMetadataSchemaV14.lookup], v14Preset())
val networkTypesReader = JsonReader(context.getResourceReader(R.raw.typefile))
val networkTypesTree =
gson.fromJson<TypeDefinitionsTree>(networkTypesReader, TypeDefinitionsTree::class.java)
val completeTypes =
TypeDefinitionParser.parseBaseDefinitions(networkTypesTree, metadataTypePreset)
val typeRegistry = TypeRegistry(
types = completeTypes,
dynamicTypeResolver = DynamicTypeResolver(
DynamicTypeResolver.DEFAULT_COMPOUND_EXTENSIONS + GenericsExtension
)
)
val metadata = VersionedRuntimeBuilder.buildMetadata(metadataRaw, typeRegistry)
return RuntimeSnapshot(typeRegistry, metadata)
}
private fun Context.getResourceReader(@RawRes resId: Int): BufferedReader {
val inputStream: InputStream = resources.openRawResource(resId)
return BufferedReader(InputStreamReader(inputStream))
}
private fun Context.getFileContentFromAssets(fileName: String): String {
return assets.open(fileName).bufferedReader().use { it.readText() }
}
fun buildRawMetadata(context: Context, networkName: String = "metadata") =
context.getFileContentFromAssets("metadata").run {
RuntimeMetadataReader.read(this)
}
}
If you have updated to 2.0.1 please try to just supply v14Preset()
to TypeRegistry
constructor without even parsing and passing the types.json
file. I think the file itself might contain issues (e.g. not sure what MultiAddress
type referes to)
Not passing the types file means SDK will try only types inferred from the metadata and in most cases (at least in 70+ networks we support in Nova) it dervives everything needed
Thank you for your reply, Now im only passing v14Preset()
while building typeregistry:
val typeRegistry = TypeRegistry(
types = v14Preset(),
dynamicTypeResolver = DynamicTypeResolver(
DynamicTypeResolver.DEFAULT_COMPOUND_EXTENSIONS + GenericsExtension
)
)
but gotIllegalArgumentException: Cannot construct StorageEntryType from io.novasama.substrate_sdk_android.scale.EncodableStruct@a3bdc75
This error comes from while building metadata: val metadata = VersionedRuntimeBuilder.buildMetadata(metadataRaw, typeRegistry)
Full code:
class BlockchainService {
fun buildRuntimeV14(context: Context, networkName: String = "network"): RuntimeSnapshot {
val gson = Gson()
val metadataRaw = buildRawMetadata(context, networkName)
val metadataTypePreset =
TypesParserV14.parse(metadataRaw.metadata[RuntimeMetadataSchemaV14.lookup], v14Preset())
val networkTypesReader = JsonReader(context.getResourceReader(R.raw.typefile))
val networkTypesTree =
gson.fromJson<TypeDefinitionsTree>(networkTypesReader, TypeDefinitionsTree::class.java)
val completeTypes =
TypeDefinitionParser.parseBaseDefinitions(networkTypesTree, metadataTypePreset)
val typeRegistry = TypeRegistry(
types = v14Preset(),
dynamicTypeResolver = DynamicTypeResolver(
DynamicTypeResolver.DEFAULT_COMPOUND_EXTENSIONS + GenericsExtension
)
)
val metadata = VersionedRuntimeBuilder.buildMetadata(metadataRaw, typeRegistry)
return RuntimeSnapshot(typeRegistry, metadata)
}
private fun Context.getResourceReader(@RawRes resId: Int): BufferedReader {
val inputStream: InputStream = resources.openRawResource(resId)
return BufferedReader(InputStreamReader(inputStream))
}
private fun Context.getFileContentFromAssets(fileName: String): String {
return assets.open(fileName).bufferedReader().use { it.readText() }
}
fun buildRawMetadata(context: Context, networkName: String = "metadata") =
context.getFileContentFromAssets("metadata").run {
RuntimeMetadataReader.read(this)
}
}
Full Error:
java.lang.IllegalArgumentException: Cannot construct StorageEntryType from io.novasama.substrate_sdk_android.scale.EncodableStruct@a3bdc75
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3782)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Caused by: java.lang.IllegalArgumentException: Cannot construct StorageEntryType from io.novasama.substrate_sdk_android.scale.EncodableStruct@a3bdc75
at io.novasama.substrate_sdk_android.runtime.metadata.builder.V14RuntimeBuilder.cannotConstructStorageEntry(V14RuntimeBuilder.kt:268)
at io.novasama.substrate_sdk_android.runtime.metadata.builder.V14RuntimeBuilder.buildEntryType(V14RuntimeBuilder.kt:227)
at io.novasama.substrate_sdk_android.runtime.metadata.builder.V14RuntimeBuilder.buildStorage(V14RuntimeBuilder.kt:105)
at io.novasama.substrate_sdk_android.runtime.metadata.builder.V14RuntimeBuilder.buildModule(V14RuntimeBuilder.kt:81)
at io.novasama.substrate_sdk_android.runtime.metadata.builder.V14RuntimeBuilder.buildModules(V14RuntimeBuilder.kt:66)
at io.novasama.substrate_sdk_android.runtime.metadata.builder.V14RuntimeBuilder.buildMetadata(V14RuntimeBuilder.kt:56)
at io.novasama.substrate_sdk_android.runtime.metadata.builder.VersionedRuntimeBuilder.buildMetadata(RuntimeBuilder.kt:26)
at io.novasama.substrate_sdk_android.runtime.metadata.builder.RuntimeBuilder$DefaultImpls.buildMetadata$default(RuntimeBuilder.kt:14)
at com.sweb.wallet.BlockchainService.buildRuntimeV14(MainActivity.kt:163)
at com.sweb.wallet.BlockchainService.buildRuntimeV14$default(MainActivity.kt:140)
at com.sweb.wallet.MainActivityKt.testQuery(MainActivity.kt:199)
at com.sweb.wallet.TestRun$callCoroutine$1.invokeSuspend(MainActivity.kt:86)
at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
at kotlinx.coroutines.EventLoopImplBase.processNextEvent(EventLoop.common.kt:284)
at kotlinx.coroutines.BlockingCoroutine.joinBlocking(Builders.kt:85)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking(Builders.kt:59)
at kotlinx.coroutines.BuildersKt.runBlocking(Unknown Source:1)
at kotlinx.coroutines.BuildersKt__BuildersKt.runBlocking$default(Builders.kt:38)
at kotlinx.coroutines.BuildersKt.runBlocking$default(Unknown Source:1)
at com.sweb.wallet.TestRun.callCoroutine(MainActivity.kt:85)
at com.sweb.wallet.TestRun.<init>(MainActivity.kt:81)
at com.sweb.wallet.MainActivity.onCreate(MainActivity.kt:73)
at android.app.Activity.performCreate(Activity.java:8595)
at android.app.Activity.performCreate(Activity.java:8573)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1456)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3764)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3922)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:139)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:96)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2443)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:205)
at android.os.Looper.loop(Looper.java:294)
at android.app.ActivityThread.main(ActivityThread.java:8177)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)
Please share the minimum reproducable example (it should be self-contained, to be able to run it in the test):
Since in the examples loading metadata using hardcoded file, How we can obtain metadata with connecting node websocket?
Please try the following code to fetch & construct runtime snapshot from the latest chain state:
private suspend fun SocketService.fetchRuntimeSnapshot(): RuntimeSnapshot {
val metadataHex = stateGetMetadata()
val metadataReader = RuntimeMetadataReader.read(metadataHex)
val types = TypesParserV14.parse(
lookup = metadataReader.metadata[RuntimeMetadataSchemaV14.lookup],
typePreset = v14Preset(),
)
val typeRegistry = TypeRegistry(types, DynamicTypeResolver(DynamicTypeResolver.DEFAULT_COMPOUND_EXTENSIONS + GenericsExtension))
val runtimeMetadata = VersionedRuntimeBuilder.buildMetadata(metadataReader, typeRegistry)
return RuntimeSnapshot(typeRegistry, runtimeMetadata)
}
suspend fun SocketService.stateGetMetadata(): String {
return executeAsync(GetMetadataRequest, mapper = pojo<String>().nonNull())
}
I can get socket: start log
but metadata
log doesn't get printed.
suspend fun testQuery() {
val reconnector = Reconnector(strategy = ConstantReconnectStrategy(1000L))
val requestExecutor = RequestExecutor()
val socketService = SocketService(
Gson(),
StdoutLogger,
WebSocketFactory(),
reconnector,
requestExecutor,
)
val websocketUrl = "wss://commune.api.onfinality.io/public-ws"
socketService.start(websocketUrl)
Log.d("TAG", "socket: start" )
val metadataHex = socketService.executeAsync(GetMetadataRequest, mapper = pojo<String>().nonNull())
Log.d("TAG", "metadata: $metadataHex")
val metadataReader = RuntimeMetadataReader.read(metadataHex)
val types = TypesParserV14.parse(
lookup = metadataReader.metadata[RuntimeMetadataSchemaV14.lookup],
typePreset = v14Preset(),
)
val typeRegistry = TypeRegistry(types, DynamicTypeResolver(DynamicTypeResolver.DEFAULT_COMPOUND_EXTENSIONS + GenericsExtension))
val runtimeMetadata = VersionedRuntimeBuilder.buildMetadata(metadataReader, typeRegistry)
val runtime = RuntimeSnapshot(typeRegistry, runtimeMetadata)
Log.d("TAG", "runtime: created $runtime")
}
After debugging it for some time - there seems to be a bug that prevents response to be propagated when socket doesn't have a response interceptor set. Try setting an interceptor which always returns ResponseDelivery.DELIVER_TO_SENDER (via socket.setInterceptor) We will fix it in the next version
Socket service worked but we're got error Caused by: io.novasama.substrate_sdk_android.runtime.definitions.types.errors.EncodeDecodeException: null (null) is not a valid instance of (Alias)
While building extrinsic: val extrinsic = extBuilder.build()
val extBuilder = ExtrinsicBuilder(
runtime = runtime,
signer = KeyPairSigner(
keypair = keypair,
encryption = MultiChainEncryption.Substrate(EncryptionType.SR25519)
),
nonce = Nonce.singleTx(1.toBigInteger()),
runtimeVersion = RuntimeVersion(103, 1),
accountId = keypair.publicKey,
genesisHash = "0xbc6eb9753e2417476601485f9f8ef8474701ec199d456f989bd397682c9425c5".fromHex()
)
extBuilder.call(
moduleName = "SubspaceModule",
callName = "add_stake",
arguments = mapOf(
"netuid" to 0.toBigInteger(),
"moduleKey" to SS58Encoder.decode("5EhxqnrHHFy32DhcaqYrWiwC82yDiVS4xySysGxsUn462nX2"),
"amount" to 1.toBigInteger()
)
)
val extrinsic = extBuilder.build()
val res = socketService.executeAsync(SubmitExtrinsicRequest(extrinsic)).result
Log.d("TAG", "testQuery: $res")
Log.d("TAG", "Runtime: $runtime") // Log the runtime for testing
Please do not put everything into single issue. If original problem is solved please close this issue and open a new one, with the new problem. Closing this one as the issue was solved
Regarding the next problem - seems like you either not passing one of the arguments to the call or you misspelled argument name for one of those you passed. Most likely "moduleKey" should be "module_key". Or else check other arguments