Skip to content

Commit

Permalink
Merge branch 'feature/fake_signing'
Browse files Browse the repository at this point in the history
  • Loading branch information
grishamsc committed Nov 17, 2023
2 parents 49636b0 + 930f927 commit d6d3437
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 50 deletions.
22 changes: 18 additions & 4 deletions Source/TonSwift/Wallets/WalletContract.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,39 @@ import Foundation

/// All wallets implement a compatible interface for sending messages
public protocol WalletContract: Contract {
func createTransfer(args: WalletTransferData) throws -> Cell
func createTransfer(args: WalletTransferData) throws -> WalletTransfer
}

public struct WalletTransferData {
public let seqno: UInt64
public let secretKey: Data
public let messages: [MessageRelaxed]
public let sendMode: SendMode
public let timeout: UInt64?

public init(seqno: UInt64,
secretKey: Data,
messages: [MessageRelaxed],
sendMode: SendMode,
timeout: UInt64?) {
self.seqno = seqno
self.secretKey = secretKey
self.messages = messages
self.sendMode = sendMode
self.timeout = timeout
}
}

public struct WalletTransfer {
private let signingMessage: Builder

init(signingMessage: Builder) {
self.signingMessage = signingMessage
}

func signMessage(signer: WalletTransferSigner) throws -> Cell {
let signature = try signer.signMessage(signingMessage.endCell().hash())
let body = Builder()
try body.store(data: signature)
try body.store(signingMessage)

return try body.endCell()
}
}
39 changes: 39 additions & 0 deletions Source/TonSwift/Wallets/WalletTransferSigner.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Foundation
import TweetNacl

public enum WalletTransferSignerError: Swift.Error {
case failedToSignMessage
}

public protocol WalletTransferSigner {
func signMessage(_ message: Data) throws -> Data
}

public struct WalletTransferSecretKeySigner: WalletTransferSigner {
private let secretKey: Data

public init(secretKey: Data) {
self.secretKey = secretKey
}

public func signMessage(_ message: Data) throws -> Data {
do {
return try NaclSign.signDetached(message: message, secretKey: secretKey)
} catch {
throw WalletTransferSignerError.failedToSignMessage
}
}
}

public struct WalletTransferEmptyKeySigner: WalletTransferSigner {
public func signMessage(_ message: Data) throws -> Data {
guard let data = String(repeating: "0", count: .signatureBytesCount).data(using: .utf8) else {
throw WalletTransferSignerError.failedToSignMessage
}
return data
}
}

private extension Int {
static let signatureBytesCount = 64
}
10 changes: 2 additions & 8 deletions Source/TonSwift/Wallets/WalletV1.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,14 @@ public final class WalletV1: WalletContract {
self.stateInit = StateInit(code: cell, data: try data.endCell())
}

public func createTransfer(args: WalletTransferData) throws -> Cell {
public func createTransfer(args: WalletTransferData) throws -> WalletTransfer {
let signingMessage = try Builder().store(uint: args.seqno, bits: 32)

if let message = args.messages.first {
try signingMessage.store(uint: UInt64(args.sendMode.rawValue), bits: 8)
try signingMessage.store(ref:try Builder().store(message))
}

let signature = try NaclSign.signDetached(message: signingMessage.endCell().hash(), secretKey: args.secretKey)

let body = Builder()
try body.store(data: signature)
try body.store(signingMessage)

return try body.endCell()
return WalletTransfer(signingMessage: signingMessage)
}
}
10 changes: 2 additions & 8 deletions Source/TonSwift/Wallets/WalletV2.swift
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public final class WalletV2: WalletContract {
self.stateInit = StateInit(code: cell, data: try data.endCell())
}

public func createTransfer(args: WalletTransferData) throws -> Cell {
public func createTransfer(args: WalletTransferData) throws -> WalletTransfer {
guard args.messages.count <= 4 else {
throw TonError.custom("Maximum number of messages in a single transfer is 4")
}
Expand All @@ -47,12 +47,6 @@ public final class WalletV2: WalletContract {
try signingMessage.store(ref:try Builder().store(message))
}

let signature = try NaclSign.signDetached(message: signingMessage.endCell().hash(), secretKey: args.secretKey)

let body = Builder()
try body.store(data: signature)
try body.store(signingMessage)

return try body.endCell()
return WalletTransfer(signingMessage: signingMessage)
}
}
12 changes: 3 additions & 9 deletions Source/TonSwift/Wallets/WalletV3.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public final class WalletV3: WalletContract {
self.stateInit = StateInit(code: cell, data: try data.endCell())
}

public func createTransfer(args: WalletTransferData) throws -> Cell {
public func createTransfer(args: WalletTransferData) throws -> WalletTransfer {
guard args.messages.count <= 4 else {
throw TonError.custom("Maximum number of messages in a single transfer is 4")
}
Expand All @@ -56,13 +56,7 @@ public final class WalletV3: WalletContract {
try signingMessage.store(uint: UInt64(args.sendMode.rawValue), bits: 8)
try signingMessage.store(ref: try Builder().store(message))
}

let signature = try NaclSign.signDetached(message: signingMessage.endCell().hash(), secretKey: args.secretKey)

let body = Builder()
try body.store(data: signature)
try body.store(signingMessage)

return try body.endCell()

return WalletTransfer(signingMessage: signingMessage)
}
}
10 changes: 2 additions & 8 deletions Source/TonSwift/Wallets/WalletV4.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public class WalletV4: WalletContract {
Set(self.plugins.map{ a in CompactAddress(a) })
}

public func createTransfer(args: WalletTransferData) throws -> Cell {
public func createTransfer(args: WalletTransferData) throws -> WalletTransfer {
guard args.messages.count <= 4 else {
throw TonError.custom("Maximum number of messages in a single transfer is 4")
}
Expand All @@ -85,13 +85,7 @@ public class WalletV4: WalletContract {
try signingMessage.store(uint: UInt64(args.sendMode.rawValue), bits: 8)
try signingMessage.store(ref: try Builder().store(message))
}

let signature = try NaclSign.signDetached(message: signingMessage.endCell().hash(), secretKey: args.secretKey)

let body = Builder()
try body.store(data: signature)
try body.store(signingMessage)

return try body.endCell()
return WalletTransfer(signingMessage: signingMessage)
}
}
10 changes: 6 additions & 4 deletions Tests/TonSwiftTests/Wallets/WalletContractV1Test.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ final class WalletContractV1Test: XCTestCase {
XCTAssertEqual(try contractR1.stateInit.code?.toString(), "x{FF0020DDA4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54}")

let transfer = try contractR1.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), "x{44811DCDDFD331B4CF82F2AE62532E0EDCA1976BDF50B48E6EC3E108347CBB47DDDFCCB4A8980F3AED4417084B62268F8F19CCCD3940835DE54C5151722957030000003E01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}")
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))
XCTAssertEqual(try transferCell.toString(), "x{44811DCDDFD331B4CF82F2AE62532E0EDCA1976BDF50B48E6EC3E108347CBB47DDDFCCB4A8980F3AED4417084B62268F8F19CCCD3940835DE54C5151722957030000003E01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}")
}

func testR2() throws {
Expand All @@ -27,7 +28,8 @@ final class WalletContractV1Test: XCTestCase {
XCTAssertEqual(try contractR2.stateInit.code?.toString(), "x{FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54}")

let transfer = try contractR2.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), "x{44811DCDDFD331B4CF82F2AE62532E0EDCA1976BDF50B48E6EC3E108347CBB47DDDFCCB4A8980F3AED4417084B62268F8F19CCCD3940835DE54C5151722957030000003E01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}")
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))
XCTAssertEqual(try transferCell.toString(), "x{44811DCDDFD331B4CF82F2AE62532E0EDCA1976BDF50B48E6EC3E108347CBB47DDDFCCB4A8980F3AED4417084B62268F8F19CCCD3940835DE54C5151722957030000003E01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}")
}

func testR3() throws {
Expand All @@ -38,13 +40,13 @@ final class WalletContractV1Test: XCTestCase {
XCTAssertEqual(try contractR3.stateInit.code?.toString(), "x{FF0020DD2082014C97BA218201339CBAB19C71B0ED44D0D31FD70BFFE304E0A4F260810200D71820D70B1FED44D0D31FD3FFD15112BAF2A122F901541044F910F2A2F80001D31F3120D74A96D307D402FB00DED1A4C8CB1FCBFFC9ED54}")

let transfer = try contractR3.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), "x{44811DCDDFD331B4CF82F2AE62532E0EDCA1976BDF50B48E6EC3E108347CBB47DDDFCCB4A8980F3AED4417084B62268F8F19CCCD3940835DE54C5151722957030000003E01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}")
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))
XCTAssertEqual(try transferCell.toString(), "x{44811DCDDFD331B4CF82F2AE62532E0EDCA1976BDF50B48E6EC3E108347CBB47DDDFCCB4A8980F3AED4417084B62268F8F19CCCD3940835DE54C5151722957030000003E01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}")
}

private func args() throws -> WalletTransferData {
return try WalletTransferData(
seqno: 62,
secretKey: secretKey,
messages: [
.internal(
to: Address.parse("kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt"),
Expand Down
7 changes: 4 additions & 3 deletions Tests/TonSwiftTests/Wallets/WalletContractV2Test.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ final class WalletContractV2Test: XCTestCase {
XCTAssertEqual(try contractR1.stateInit.code?.toString(), "x{FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F2608308D71820D31FD31F01F823BBF263ED44D0D31FD3FFD15131BAF2A103F901541042F910F2A2F800029320D74A96D307D402FB00E8D1A4C8CB1FCBFFC9ED54}")

let transfer = try contractR1.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), """
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))
XCTAssertEqual(try transferCell.toString(), """
x{6DC1459A6FF72EEE1384045986E70817819D4AF22F0F05CBF932927D1887C3CC68F624CD310132C32DE03941BF40AFC6917AA4579BB1CFDB2C4A390476D51C010000003E642574FF01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}
""")
}
Expand All @@ -29,7 +30,8 @@ final class WalletContractV2Test: XCTestCase {
XCTAssertEqual(try contractR2.stateInit.code?.toString(), "x{FF0020DD2082014C97BA218201339CBAB19C71B0ED44D0D31FD70BFFE304E0A4F2608308D71820D31FD31F01F823BBF263ED44D0D31FD3FFD15131BAF2A103F901541042F910F2A2F800029320D74A96D307D402FB00E8D1A4C8CB1FCBFFC9ED54}")

let transfer = try contractR2.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), """
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))
XCTAssertEqual(try transferCell.toString(), """
x{6DC1459A6FF72EEE1384045986E70817819D4AF22F0F05CBF932927D1887C3CC68F624CD310132C32DE03941BF40AFC6917AA4579BB1CFDB2C4A390476D51C010000003E642574FF01}
x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}
""")
Expand All @@ -38,7 +40,6 @@ final class WalletContractV2Test: XCTestCase {
private func args() throws -> WalletTransferData {
return try WalletTransferData(
seqno: 62,
secretKey: secretKey,
messages: [
.internal(
to: Address.parse("kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt"),
Expand Down
7 changes: 4 additions & 3 deletions Tests/TonSwiftTests/Wallets/WalletContractV3Test.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ final class WalletContractV3Test: XCTestCase {
XCTAssertEqual(try contractR1.stateInit.code?.toString(), "x{FF0020DD2082014C97BA9730ED44D0D70B1FE0A4F2608308D71820D31FD31FD31FF82313BBF263ED44D0D31FD31FD3FFD15132BAF2A15144BAF2A204F901541055F910F2A3F8009320D74A96D307D402FB00E8D101A4C8CB1FCB1FCBFFC9ED54}")

let transfer = try contractR1.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), """
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))
XCTAssertEqual(try transferCell.toString(), """
x{69F1EA5C971E9889111C705568732F513D8419E6BB0A022D01E8620EE81067BBA08A89264E8200152F831241E95108A0E432FA4397B940045213383FBA0E3B0C29A9A31764257CB40000003E01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}
""")
}
Expand All @@ -34,15 +35,15 @@ final class WalletContractV3Test: XCTestCase {
XCTAssertEqual(try contractR2.stateInit.code?.toString(), "x{FF0020DD2082014C97BA218201339CBAB19F71B0ED44D0D31FD31F31D70BFFE304E0A4F2608308D71820D31FD31FD31FF82313BBF263ED44D0D31FD31FD3FFD15132BAF2A15144BAF2A204F901541055F910F2A3F8009320D74A96D307D402FB00E8D101A4C8CB1FCB1FCBFFC9ED54}")

let transfer = try contractR2.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), """
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))
XCTAssertEqual(try transferCell.toString(), """
x{69F1EA5C971E9889111C705568732F513D8419E6BB0A022D01E8620EE81067BBA08A89264E8200152F831241E95108A0E432FA4397B940045213383FBA0E3B0C29A9A31764257CB40000003E01}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F2C20776F726C6421}
""")
}

private func args() throws -> WalletTransferData {
return try WalletTransferData(
seqno: 62,
secretKey: secretKey,
messages: [
.internal(
to: Address.parse("kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt"),
Expand Down
8 changes: 5 additions & 3 deletions Tests/TonSwiftTests/Wallets/WalletContractV4Test.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ final class WalletContractV4Test: XCTestCase {
XCTAssertEqual(try contractR1.stateInit.code?.toString(), "x{FF00F4A413F4BCF2C80B}\n x{2_}\n x{4}\n x{D001D0D3030171B0915BE021D749C120915BE001D31F218210706C7567BD228210626C6E63BDB022821064737472BDB0925F03E002FA403020FA4401C8CA07CBFFC9D0ED44D0810140D721F404305C810108F40A6FA131B3925F05E004D33FC8258210706C7567BA9131E30D248210626C6E63BAE30004}\n x{01FA00F404308210706C7567831EB17080185005CB0527CF165003FA02F40012CB69CB1F5210CB3F}\n x{F8276F228210626C6E63831EB17080185005CB0527CF1624FA0214CB6A13CB1F5230CB3F01FA02F400}\n x{821064737472BA8E3504810108F45930ED44D0810140D720C801CF16F400C9ED54821064737472831EB17080185004CB0558CF1622FA0212CB6ACB1FCB3F9410345F04E2C98040FB00}\n x{2_}\n x{2_}\n x{5}\n x{B29DFB513420405035C87D010C00B23281F2FFF274006040423D029BE84C6_}\n x{2_}\n x{ADCE76A26840206B90EB85FFC_}\n x{AF1DF6A26840106B90EB858FC_}\n x{B8C97ED44D0D70B1F}\n x{BD242B6F6A2684080A06B90FA0218470D4080847A4937D29910CE6903E9FF9837812801B7810148987159F3184_}\n x{F28308D71820D31FD31FD31F02F823BBF263ED44D0D31FD31FD3FFF404D15143BAF2A15151BAF2A205F901541064F910F2A3F80024A4C8CB1F5240CB1F5230CBFF5210F400C9ED54F80F01D30721C0009F6C519320D74A96D307D402FB00E830E021C001E30021C002E30001C0039130E30D03A4C8CB1F12CB1FCBFF}\n x{D207FA00D4D422F90005C8CA0715CBFFC9D077748018C8CB05CB0222CF165005FA0214CB6B12CCCCC971FB00C84014810108F451F2A702}\n x{810108D718C8542025810108F451F2A782106E6F746570748018C8CB05CB025004CF16821005F5E100FA0213CB6A12CB1FC971FB0002}\n x{810108D718305202810108F459F2A7F82582106473747270748018C8CB05CB025005CF16821005F5E100FA0214CB6A13CB1F12CB3FC973FB00}\n x{F400C9ED54}")

let transfer = try contractR1.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), """
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))

XCTAssertEqual(try transferCell.toString(), """
x{000355EAEDB79E63A350B6700310D9E31F6CBD9285B5C990BBF510385FC7D2CCCF6412C8005DD767B8178078500C4498F011565D4C56901B90A5A9F7B9DAB10F29A9A31764257F4F0000003E000101}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F20776F726C643A2031}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F20776F726C643A2032}
""")
}
Expand All @@ -29,15 +31,15 @@ final class WalletContractV4Test: XCTestCase {
XCTAssertEqual(try contractR2.stateInit.code?.toString(), "x{FF00F4A413F4BCF2C80B}\n x{2_}\n x{4}\n x{D001D0D3032171B0925F04E022D749C120925F04E002D31F218210706C7567BD22821064737472BDB0925F05E003FA403020FA4401C8CA07CBFFC9D0ED44D0810140D721F404305C810108F40A6FA131B3925F07E005D33FC8258210706C7567BA923830E30D03821064737472BA925F06E30D}\n x{01FA00F40430F8276F2230500AA121BEF2E0508210706C7567831EB17080185004CB0526CF1658FA0219F400CB6917CB1F5260CB3F20C98040FB0006}\n x{5004810108F45930ED44D0810140D720C801CF16F400C9ED540172B08E23821064737472831EB17080185005CB055003CF1623FA0213CB6ACB1FCB3FC98040FB00925F03E2}\n x{2_}\n x{2_}\n x{5}\n x{B29DFB513420405035C87D010C00B23281F2FFF274006040423D029BE84C6_}\n x{2_}\n x{ADCE76A26840206B90EB85FFC_}\n x{AF1DF6A26840106B90EB858FC_}\n x{B8C97ED44D0D70B1F}\n x{BD242B6F6A2684080A06B90FA0218470D4080847A4937D29910CE6903E9FF9837812801B7810148987159F3184_}\n x{F28308D71820D31FD31FD31F02F823BBF264ED44D0D31FD31FD3FFF404D15143BAF2A15151BAF2A205F901541064F910F2A3F80024A4C8CB1F5240CB1F5230CBFF5210F400C9ED54F80F01D30721C0009F6C519320D74A96D307D402FB00E830E021C001E30021C002E30001C0039130E30D03A4C8CB1F12CB1FCBFF}\n x{D207FA00D4D422F90005C8CA0715CBFFC9D077748018C8CB05CB0222CF165005FA0214CB6B12CCCCC973FB00C84014810108F451F2A702}\n x{810108D718FA00D33FC8542047810108F451F2A782106E6F746570748018C8CB05CB025006CF165004FA0214CB6A12CB1FCB3FC973FB0002}\n x{810108D718FA00D33F305224810108F459F2A782106473747270748018C8CB05CB025005CF165003FA0213CB6ACB1F12CB3FC973FB00}\n x{F400C9ED54}")

let transfer = try contractR2.createTransfer(args: try args())
XCTAssertEqual(try transfer.toString(), """
let transferCell = try transfer.signMessage(signer: WalletTransferSecretKeySigner(secretKey: secretKey))
XCTAssertEqual(try transferCell.toString(), """
x{000355EAEDB79E63A350B6700310D9E31F6CBD9285B5C990BBF510385FC7D2CCCF6412C8005DD767B8178078500C4498F011565D4C56901B90A5A9F7B9DAB10F29A9A31764257F4F0000003E000101}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F20776F726C643A2031}\n x{62007D507CF9B4D00622B6DC23E0BA7F3CA9584A13C5A3830F3DA8E9B76F27EFF641202FAF0800000000000000000000000000000000000048656C6C6F20776F726C643A2032}
""")
}

private func args() throws -> WalletTransferData {
return try WalletTransferData(
seqno: 62,
secretKey: secretKey,
messages: [
.internal(
to: Address.parse("kQD6oPnzaaAMRW24R8F0_nlSsJQni0cGHntR027eT9_sgtwt"),
Expand Down

0 comments on commit d6d3437

Please sign in to comment.