You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have 2 accounts on Testnet, previously I was able to send Flow tokens between accounts using Flow CLI. Now trying to send transaction using this SDK, but transaction fails on validation with error:
[Error Code: 1009] error caused by: 1 error occurred:
* transaction verification failed: [Error Code: 1006] invalid proposal key: public key 0 on account 31bbb88233df243d does not have a valid signature: [Error Code: 1009] invalid envelope key: public key 0 on account 31bbb88233df243d does not have a valid signature: signature is not valid
I'd be grateful If you could point where to dig, because I totally stuck now.
Here's my code in ViewController.swift file:
import UIKit
import Flow
import CryptoKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
flow.configure(chainID: .testnet)
Task {
do {
let aliceAddress = Flow.Address(hex: "0x31bbb88233df243d")
let bobAddress = Flow.Address(hex: "0x8ce1531666464325")
// get Alice account info:
let aliceAccount: Flow.Account = try await flow.getAccountAtLatestBlock(address: aliceAddress)
print("Alice's Balance:\(Double(aliceAccount.balance) / 100000000)")
let bobAccount: Flow.Account = try await flow.getAccountAtLatestBlock(address: bobAddress)
print("Bob's Balance:\(Double(bobAccount.balance) / 100000000)\n")
// Preparing Alice's transaction:
let amountArg = Flow.Argument(type: .ufix64, value: .ufix64(120))
let recipientArg = Flow.Argument(type: .address, value: .address(bobAddress))
let alicePrivateKey = try P256.Signing.PrivateKey(rawRepresentation: "0xd08382ba70946ee82af61147e6f84c69932e9c69baaf0c7177731fa0ddc28477".hexValue)
let signer = ECDSA_P256_Signer(
address: aliceAccount.address,
keyIndex: aliceAccount.keys.first!.index,
privateKey: alicePrivateKey
)
let txID = try await flow.sendTransaction(chainID: .testnet,
signers: [signer],
script: Transactions.tokenTransfer,
agrument: [amountArg, recipientArg],
authorizer: [aliceAddress],
payerAddress: aliceAddress,
proposerKey: Flow.TransactionProposalKey(
address: aliceAddress,
keyIndex: aliceAccount.keys.first!.index,
sequenceNumber: aliceAccount.keys.first!.sequenceNumber
),
blockID: nil)
print("Transaction sent.\nTx ID: \(txID)")
let transactionResult = try await flow.getTransactionResultById(id: txID)
print("Transaction Details:\n\(transactionResult)")
// Check balances for both accounts after transaction:
let aliceUpdated: Flow.Account = try await flow.getAccountAtLatestBlock(address: aliceAddress)
print("Alice Updated Balance:\(Double(aliceUpdated.balance) / 100000000)\n")
let bobUpdated: Flow.Account = try await flow.getAccountAtLatestBlock(address: bobAddress)
print("Bob's Updated Balance:\(Double(bobUpdated.balance) / 100000000)\n")
print("End of sequence.")
} catch let error {
print("Something went wrong")
print(error.localizedDescription)
}
}
}
}
private extension String {
/// Convert hex string to bytes
var hexValue: [UInt8] {
var startIndex = self.startIndex
return (0 ..< count / 2).compactMap { _ in
let endIndex = index(after: startIndex)
defer { startIndex = index(after: endIndex) }
return UInt8(self[startIndex ... endIndex], radix: 16)
}
}
}
There was no example of correct FlowSigner implementation, but I found one in TestCases and modified it a bit:
import CryptoKit
import Foundation
import Flow
import CryptoSwift
struct ECDSA_P256_Signer: FlowSigner {
var address: Flow.Address
var keyIndex: Int
var privateKey: P256.Signing.PrivateKey
init(address: Flow.Address, keyIndex: Int, privateKey: P256.Signing.PrivateKey) {
self.address = address
self.keyIndex = keyIndex
self.privateKey = privateKey
}
func sign(transaction _: Flow.Transaction, signableData: Data) throws -> Data {
do {
let digest = SHA256.hash(data: signableData.sha3(.sha256))
return try privateKey.signature(for: digest).rawRepresentation
} catch {
throw error
}
}
}
Transaction Cadence code:
import Foundation
public struct Transactions {
private static let fungibleTokenContractAddr: String = "0x9a0766d93b6608b7"
private static let flowTokenContractAddr: String = "0x7e60df042a9c0868"
public static let tokenTransfer: String = """
import FungibleToken from \(fungibleTokenContractAddr)
import FlowToken from \(flowTokenContractAddr)
transaction(amount: UFix64, to: Address) {
// The Vault resource that holds the tokens that are being transferred
let sentVault: @FungibleToken.Vault
prepare(signer: AuthAccount) {
// Get a reference to the signer's stored vault
let vaultRef = signer.borrow<&FlowToken.Vault>(from: /storage/flowTokenVault)
?? panic("Could not borrow reference to the owner's Vault!")
// Withdraw tokens from the signer's stored vault
self.sentVault <- vaultRef.withdraw(amount: amount)
}
execute {
// Get the recipient's public account object
let recipient = getAccount(to)
// Get a reference to the recipient's Receiver
let receiverRef = recipient.getCapability(/public/flowTokenReceiver)
.borrow<&FlowToken.Vault{FungibleToken.Receiver}>()
?? panic("Could not borrow receiver reference to the recipient's Vault")
// Deposit the withdrawn tokens in the recipient's receiver
receiverRef.deposit(from: <-self.sentVault)
}
}
"""
}
The text was updated successfully, but these errors were encountered:
I have 2 accounts on Testnet, previously I was able to send Flow tokens between accounts using Flow CLI. Now trying to send transaction using this SDK, but transaction fails on validation with error:
Info:
https://f.dnz.dev/d6ff9c65feb166505043c420843d5504523f7a784f9b151550933dda6bb169db
I'd be grateful If you could point where to dig, because I totally stuck now.
Here's my code in ViewController.swift file:
There was no example of correct FlowSigner implementation, but I found one in TestCases and modified it a bit:
Transaction Cadence code:
The text was updated successfully, but these errors were encountered: