Skip to content

Commit 5198377

Browse files
feat(Biz): Add helper functions to support BizPasskeySessionAccount (trustwallet#4516)
* feat(biz-passkey): Add `TWBarzEncodeRegisterSessionCall` FFI * feat(biz-passkey): Add `TWBarzEncodeRemoveSessionCall` FFI * feat(biz-passkey): Add `TWBarzEncodePasskeySessionNonce` FFI * feat(biz-passkey): Add `TWBarzEncodeExecuteWithPasskeySessionCall` FFI * refactor(barz): Move some functions to TWBiz and TWEip7702 modules * feat(biz): Add WebAuthn * feat(biz): Add `TWWebAuthnGetMessageHash` and `TWWebAuthnGetFormattedSignature` * feat(biz): Fix C++ and Mobile * Rename `TWWebAuthn` module to `TWWebAuthnSolidity` * feat(biz): Adjust `executeWithPasskeySession` arguments * feat(biz): Fix fmt * feat(biz): Add Biz Android tests * feat(biz): Add final Biz Android test * feat(biz): Fix lints * feat(biz): Minor change * feat(biz): fmt
1 parent 6d1a0ed commit 5198377

File tree

35 files changed

+2699
-701
lines changed

35 files changed

+2699
-701
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ include/TrustWalletCore/TWCryptoBoxPublicKey.h
5353
include/TrustWalletCore/TWCryptoBoxSecretKey.h
5454
include/TrustWalletCore/TWEthereum.h
5555
include/TrustWalletCore/TWBarz.h
56+
include/TrustWalletCore/TWBiz.h
57+
include/TrustWalletCore/TWEip7702.h
58+
include/TrustWalletCore/TWWebAuthnSolidity.h
5659

5760
# Wasm
5861
emsdk/
@@ -83,3 +86,6 @@ samples/cpp/sample
8386

8487
# Rust target build
8588
**/target/
89+
90+
# Kotlin
91+
kotlin/.kotlin

android/app/src/androidTest/java/com/trustwallet/core/app/blockchains/ethereum/TestBarz.kt

Lines changed: 0 additions & 212 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import org.junit.Assert.assertEquals
66
import org.junit.Test
77
import wallet.core.jni.*
88
import wallet.core.java.AnySigner
9-
import wallet.core.jni.CoinType
109
import wallet.core.jni.CoinType.ETHEREUM
1110
import wallet.core.jni.proto.Ethereum
1211
import wallet.core.jni.EthereumAbi
@@ -17,7 +16,6 @@ import wallet.core.jni.PrivateKey
1716
import wallet.core.jni.PublicKey
1817
import wallet.core.jni.PublicKeyType
1918
import com.trustwallet.core.app.utils.Numeric
20-
import org.junit.Assert.assertArrayEquals
2119
import wallet.core.jni.proto.Barz
2220
import wallet.core.jni.Barz as WCBarz
2321

@@ -234,214 +232,4 @@ class TestBarz {
234232
assertEquals(Numeric.toHexString(output.preHash.toByteArray()), "0x84d0464f5a2b191e06295443970ecdcd2d18f565d0d52b5a79443192153770ab");
235233
assertEquals(output.encoded.toStringUtf8(), "{\"callData\":\"0x47e1da2a000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000000200000000000000000000000003bbb5660b8687c2aa453a0e42dcb6e0732b126600000000000000000000000003bbb5660b8687c2aa453a0e42dcb6e0732b12660000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000044095ea7b30000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27890000000000000000000000000000000000000000000000008ac7230489e80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044a9059cbb0000000000000000000000005ff137d4b0fdcd49dca30c7cf57e578a026d27890000000000000000000000000000000000000000000000008ac7230489e8000000000000000000000000000000000000000000000000000000000000\",\"callGasLimit\":\"88673\",\"initCode\":\"0x\",\"maxFeePerGas\":\"10000000000\",\"maxPriorityFeePerGas\":\"10000000000\",\"nonce\":\"3\",\"paymasterAndData\":\"0x\",\"preVerificationGas\":\"56060\",\"sender\":\"0x1E6c542ebC7c960c6A155A9094DB838cEf842cf5\",\"signature\":\"0x0747b665fe9f3a52407f95a35ac3e76de37c9b89483ae440431244e89a77985f47df712c7364c1a299a5ef62d0b79a2cf4ed63d01772275dd61f72bd1ad5afce1c\",\"verificationGasLimit\":\"522180\"}")
236234
}
237-
238-
// https://bscscan.com/tx/0x425eb17a8e1dee2fcee8352a772d83cbb069c2e03f2c5d9d00da3b3ef66ce48b
239-
@Test
240-
fun testSignEip7702EoaBatched() {
241-
val transferFunc1 = EthereumAbiFunction("transfer")
242-
transferFunc1.addParamAddress("0x2EF648D7C03412B832726fd4683E2625deA047Ba".toHexByteArray(), false)
243-
// 100_000_000_000_000
244-
transferFunc1.addParamUInt256("0x5af3107a4000".toHexByteArray(), false)
245-
val transferPayload1 = EthereumAbi.encode(transferFunc1)
246-
247-
val transferFunc2 = EthereumAbiFunction("transfer")
248-
transferFunc2.addParamAddress("0x95dc01ebd10b6dccf1cc329af1a3f73806117c2e".toHexByteArray(), false)
249-
// 500_000_000_000_000
250-
transferFunc2.addParamUInt256("0x1c6bf52634000".toHexByteArray(), false)
251-
val transferPayload2 = EthereumAbi.encode(transferFunc2)
252-
253-
val signingInput = Ethereum.SigningInput.newBuilder()
254-
signingInput.apply {
255-
privateKey = ByteString.copyFrom(PrivateKey("0xe148e40f06ee3ba316cdb2571f33486cf879c0ffd2b279ce9f9a88c41ce962e7".toHexByteArray()).data())
256-
chainId = ByteString.copyFrom("0x38".toHexByteArray())
257-
nonce = ByteString.copyFrom("0x12".toHexByteArray())
258-
txMode = TransactionMode.SetCode
259-
260-
gasLimit = ByteString.copyFrom("0x186a0".toHexByteArray())
261-
maxFeePerGas = ByteString.copyFrom("0x3b9aca00".toHexByteArray())
262-
maxInclusionFeePerGas = ByteString.copyFrom("0x3b9aca00".toHexByteArray())
263-
264-
transaction = Ethereum.Transaction.newBuilder().apply {
265-
scwBatch = Ethereum.Transaction.SCWalletBatch.newBuilder().apply {
266-
walletType = Ethereum.SCWalletType.Biz
267-
addAllCalls(listOf(
268-
Ethereum.Transaction.SCWalletBatch.BatchedCall.newBuilder().apply {
269-
// TWT
270-
address = "0x4B0F1812e5Df2A09796481Ff14017e6005508003"
271-
amount = ByteString.copyFrom("0x00".toHexByteArray())
272-
payload = ByteString.copyFrom(transferPayload1)
273-
}.build(),
274-
Ethereum.Transaction.SCWalletBatch.BatchedCall.newBuilder().apply {
275-
// TWT
276-
address = "0x4B0F1812e5Df2A09796481Ff14017e6005508003"
277-
amount = ByteString.copyFrom("0x00".toHexByteArray())
278-
payload = ByteString.copyFrom(transferPayload2)
279-
}.build()
280-
))
281-
}.build()
282-
}.build()
283-
284-
eip7702Authorization = Ethereum.Authorization.newBuilder().apply {
285-
address = "0x117BC8454756456A0f83dbd130Bb94D793D3F3F7"
286-
}.build()
287-
}
288-
289-
val output = AnySigner.sign(signingInput.build(), ETHEREUM, SigningOutput.parser())
290-
291-
assertEquals(Numeric.toHexString(output.preHash.toByteArray()), "0x00b2d13719df301927ddcbdad5b6bc6214f2007c6408df883c9ea483b45e6f44")
292-
assertEquals(Numeric.toHexString(output.encoded.toByteArray()), "0x04f9030f3812843b9aca00843b9aca00830186a0945132829820b44dc3e8586cec926a16fca0a5608480b9024434fcd5be00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000001200000000000000000000000004b0f1812e5df2a09796481ff14017e6005508003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044a9059cbb0000000000000000000000002ef648d7c03412b832726fd4683e2625dea047ba00000000000000000000000000000000000000000000000000005af3107a4000000000000000000000000000000000000000000000000000000000000000000000000000000000004b0f1812e5df2a09796481ff14017e6005508003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044a9059cbb00000000000000000000000095dc01ebd10b6dccf1cc329af1a3f73806117c2e0000000000000000000000000000000000000000000000000001c6bf5263400000000000000000000000000000000000000000000000000000000000c0f85cf85a3894117bc8454756456a0f83dbd130bb94d793d3f3f71380a0073afc661c158a2dccf4183f87e1e4d62b4d406af418cfd69959368ec9bec2a6a064292fd61d4d16b840470a86fc4f7a89413f9126d897f2268eb76a1d887c6d7a01a0e8bcbd96323c9d3e67b74366b2f43299100996d9e8874a6fd87186ac8f580d4ca07c25b4f0619af77fb953e8f0e4372bfbee62616ad419697516108eeb9bcebb28")
293-
}
294-
295-
// https://bscscan.com/tx/0x6f8b2c8d50e8bb543d7124703b75d9e495832116a1a61afabf40b9b0ac43c980
296-
@Test
297-
fun testSignEnvelopedBiz() {
298-
val signingInput = Ethereum.SigningInput.newBuilder()
299-
signingInput.apply {
300-
privateKey = ByteString.copyFrom(PrivateKey("0xe762e91cc4889a9fce79b2d2ffc079f86c48331f57b2cd16a33bee060fe448e1".toHexByteArray()).data())
301-
chainId = ByteString.copyFrom("0x38".toHexByteArray())
302-
nonce = ByteString.copyFrom("0x02".toHexByteArray())
303-
txMode = TransactionMode.Enveloped
304-
305-
gasLimit = ByteString.copyFrom("0x186a0".toHexByteArray())
306-
maxFeePerGas = ByteString.copyFrom("0x3b9aca00".toHexByteArray())
307-
maxInclusionFeePerGas = ByteString.copyFrom("0x3b9aca00".toHexByteArray())
308-
309-
transaction = Ethereum.Transaction.newBuilder().apply {
310-
scwExecute = Ethereum.Transaction.SCWalletExecute.newBuilder().apply {
311-
walletType = Ethereum.SCWalletType.Biz
312-
transaction = Ethereum.Transaction.newBuilder().apply {
313-
erc20Transfer = Ethereum.Transaction.ERC20Transfer.newBuilder().apply {
314-
to = "0x95dc01ebd10b6dccf1cc329af1a3f73806117c2e"
315-
amount = ByteString.copyFrom("0xb5e620f48000".toHexByteArray())
316-
}.build()
317-
}.build()
318-
}.build()
319-
}.build()
320-
321-
// TWT token.
322-
toAddress = "0x4B0F1812e5Df2A09796481Ff14017e6005508003"
323-
}
324-
325-
val output = AnySigner.sign(signingInput.build(), ETHEREUM, SigningOutput.parser())
326-
327-
assertEquals(Numeric.toHexString(output.preHash.toByteArray()), "0x60260356568ae70838bd80085b971e1e4ebe42046688fd8511a268986e522121")
328-
assertEquals(Numeric.toHexString(output.encoded.toByteArray()), "0x02f901503802843b9aca00843b9aca00830186a0946e860086bba8fdeafb553815af0f09a854cc887a80b8e4b61d27f60000000000000000000000004b0f1812e5df2a09796481ff14017e6005508003000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000600000000000000000000000000000000000000000000000000000000000000044a9059cbb00000000000000000000000095dc01ebd10b6dccf1cc329af1a3f73806117c2e0000000000000000000000000000000000000000000000000000b5e620f4800000000000000000000000000000000000000000000000000000000000c080a0fb45762a262f4c32090576e9de087482d25cd00b6ea2522eb7d5a40f435acdbaa0151dbd48a4f4bf06080313775fe32ececd68869d721518a92bf292e4a84322f9")
329-
}
330-
331-
@Test
332-
fun testAuthorizationHash() {
333-
val chainId = "0x01".toHexByteArray()
334-
val contractAddress = "0xB91aaa96B138A1B1D94c9df4628187132c5F2bf1"
335-
val nonce = "0x01".toHexByteArray()
336-
337-
val authorizationHash = WCBarz.getAuthorizationHash(chainId, contractAddress, nonce)
338-
assertEquals(Numeric.toHexString(authorizationHash), "0x3ae543b2fa103a39a6985d964a67caed05f6b9bb2430ad6d498cda743fe911d9") // Verified with viem
339-
}
340-
341-
@Test
342-
fun testSignAuthorization() {
343-
val chainId = "0x01".toHexByteArray()
344-
val contractAddress = "0xB91aaa96B138A1B1D94c9df4628187132c5F2bf1"
345-
val nonce = "0x01".toHexByteArray()
346-
val privateKey = "0x947dd69af402e7f48da1b845dfc1df6be593d01a0d8274bd03ec56712e7164e8"
347-
348-
val signedAuthorization = WCBarz.signAuthorization(chainId, contractAddress, nonce, privateKey)
349-
val json = org.json.JSONObject(signedAuthorization)
350-
351-
// Verified with viem
352-
assertEquals(Numeric.toHexString(chainId), json.getString("chainId"))
353-
assertEquals(contractAddress, json.getString("address"))
354-
assertEquals(Numeric.toHexString(nonce), json.getString("nonce"))
355-
assertEquals("0x01", json.getString("yParity"))
356-
assertEquals("0x2c39f2f64441dd38c364ee175dc6b9a87f34ca330bce968f6c8e22811e3bb710", json.getString("r"))
357-
assertEquals("0x5f1bcde93dee4b214e60bc0e63babcc13e4fecb8a23c4098fd89844762aa012c", json.getString("s"))
358-
}
359-
360-
@Test
361-
fun testBarzTransferAccountDeployedV07() {
362-
val chainIdByteArray = "0x7A69".toHexByteArray() // 31337
363-
val wallet = "0x174a240e5147D02dE4d7724D5D3E1c1bF11cE029"
364-
365-
val transfer = Ethereum.Transaction.Transfer.newBuilder().apply {
366-
amount = ByteString.copyFrom("0x2386f26fc10000".toHexByteArray())
367-
data = ByteString.EMPTY
368-
}.build()
369-
370-
val userOpV07 = Ethereum.UserOperationV0_7.newBuilder().apply {
371-
entryPoint = "0x0000000071727De22E5E9d8BAf0edAc6f37da032"
372-
sender = wallet
373-
preVerificationGas = ByteString.copyFrom("0xF4240".toHexByteArray()) // 1000000
374-
verificationGasLimit = ByteString.copyFrom("0x186A0".toHexByteArray()) // 100000
375-
factory = "0xf471789937856d80e589f5996cf8b0511ddd9de4"
376-
factoryData = ByteString.copyFrom("0xf471789937856d80e589f5996cf8b0511ddd9de4".toHexByteArray())
377-
paymaster = "0xf62849f9a0b5bf2913b396098f7c7019b51a820a"
378-
paymasterVerificationGasLimit = ByteString.copyFrom("0x1869F".toHexByteArray()) // 99999
379-
paymasterPostOpGasLimit = ByteString.copyFrom("0x15B38".toHexByteArray()) // 88888
380-
paymasterData = ByteString.copyFrom(
381-
"0x00000000000b0000000000002e234dae75c793f67a35089c9d99245e1c58470b00000000000000000000000000000000000000000000000000000000000186a0072f35038bcacc31bcdeda87c1d9857703a26fb70a053f6e87da5a4e7a1e1f3c4b09fbe2dbff98e7a87ebb45a635234f4b79eff3225d07560039c7764291c97e1b"
382-
.toHexByteArray()
383-
)
384-
}.build()
385-
386-
// Create signing input
387-
val signingInput = Ethereum.SigningInput.newBuilder().apply {
388-
privateKey = ByteString.copyFrom(PrivateKey("3c90badc15c4d35733769093d3733501e92e7f16e101df284cee9a310d36c483".toHexByteArray()).data())
389-
chainId = ByteString.copyFrom(chainIdByteArray) // 31337
390-
nonce = ByteString.copyFrom("0x00".toHexByteArray())
391-
txMode = Ethereum.TransactionMode.UserOp
392-
gasLimit = ByteString.copyFrom("0x186A0".toHexByteArray()) // 100000
393-
maxFeePerGas = ByteString.copyFrom("0x186A0".toHexByteArray()) // 100000
394-
maxInclusionFeePerGas = ByteString.copyFrom("0x186A0".toHexByteArray())
395-
toAddress = "0x61061fCAE11fD5461535e134EfF67A98CFFF44E9"
396-
397-
transaction = Ethereum.Transaction.newBuilder().apply {
398-
scwExecute = Ethereum.Transaction.SCWalletExecute.newBuilder().apply {
399-
transaction = Ethereum.Transaction.newBuilder().apply {
400-
this.transfer = transfer
401-
}.build()
402-
}.build()
403-
}.build()
404-
405-
userOperationV07 = userOpV07
406-
}.build()
407-
408-
val output = AnySigner.sign(signingInput, CoinType.ETHEREUM, Ethereum.SigningOutput.parser())
409-
410-
assertEquals(
411-
"0xf177858c1c500e51f38ffe937bed7e4d3a8678725900be4682d3ce04d97071eb",
412-
Numeric.toHexString(output.preHash.toByteArray())
413-
)
414-
415-
val codeAddress = "0x2e234DAe75C793f67A35089C9d99245E1C58470b"
416-
val codeName = "Biz"
417-
val codeVersion = "v1.0.0"
418-
val typeHash = "0x4f51e7a567f083a31264743067875fc6a7ae45c32c5bd71f6a998c4625b13867"
419-
val domainSeparatorHash = "0xd87cd6ef79d4e2b95e15ce8abf732db51ec771f1ca2edccf22a46c729ac56472"
420-
val hash = "0xf177858c1c500e51f38ffe937bed7e4d3a8678725900be4682d3ce04d97071eb"
421-
422-
val encodedHash = WCBarz.getEncodedHash(
423-
chainIdByteArray,
424-
codeAddress,
425-
codeName,
426-
codeVersion,
427-
typeHash,
428-
domainSeparatorHash,
429-
wallet,
430-
hash
431-
)
432-
assertEquals(
433-
"0xc63891abc38f7a991f89ad7cb6d7e53543627b0536c3f5e545b736756c971635",
434-
Numeric.toHexString(encodedHash)
435-
)
436-
437-
val privateKey = "0x947dd69af402e7f48da1b845dfc1df6be593d01a0d8274bd03ec56712e7164e8"
438-
val signedHash = WCBarz.getSignedHash(
439-
"0xc63891abc38f7a991f89ad7cb6d7e53543627b0536c3f5e545b736756c971635",
440-
privateKey
441-
)
442-
assertEquals(
443-
"0xa29e460720e4b539f593d1a407827d9608cccc2c18b7af7b3689094dca8a016755bca072ffe39bc62285b65aff8f271f20798a421acf18bb2a7be8dbe0eb05f81c",
444-
Numeric.toHexString(signedHash)
445-
)
446-
}
447235
}

0 commit comments

Comments
 (0)