Skip to content

Commit 62fc773

Browse files
Tip support (#237)
* Reflect spec changes * Add tip support * Simplify constructors for fee estimate structs * Fix `testSimulateTransactionsV3` * Fix newline * Fix tests * Fix tip value in constructor * Remove unused variables * Restore `ethErc20ContractAddress` * Apply code review suggestions * Add comment
1 parent c566f34 commit 62fc773

File tree

5 files changed

+63
-20
lines changed

5 files changed

+63
-20
lines changed

Sources/Starknet/Accounts/StarknetAccount.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,11 @@ public class StarknetAccount: StarknetAccountProtocol {
2727
}
2828

2929
private func makeInvokeTransactionV3(calldata: StarknetCalldata, signature: StarknetSignature, params: StarknetInvokeParamsV3, forFeeEstimation: Bool = false) -> StarknetInvokeTransactionV3 {
30-
StarknetInvokeTransactionV3(senderAddress: address, calldata: calldata, signature: signature, resourceBounds: params.resourceBounds, nonce: params.nonce, forFeeEstimation: forFeeEstimation)
30+
StarknetInvokeTransactionV3(senderAddress: address, calldata: calldata, signature: signature, resourceBounds: params.resourceBounds, nonce: params.nonce, forFeeEstimation: forFeeEstimation, tip: params.tip)
3131
}
3232

3333
private func makeDeployAccountTransactionV3(classHash: Felt, salt: Felt, calldata: StarknetCalldata, signature: StarknetSignature, params: StarknetDeployAccountParamsV3, forFeeEstimation: Bool) -> StarknetDeployAccountTransactionV3 {
34-
StarknetDeployAccountTransactionV3(signature: signature, resourceBounds: params.resourceBounds, nonce: params.nonce, contractAddressSalt: salt, constructorCalldata: calldata, classHash: classHash, forFeeEstimation: forFeeEstimation)
34+
StarknetDeployAccountTransactionV3(signature: signature, resourceBounds: params.resourceBounds, nonce: params.nonce, contractAddressSalt: salt, constructorCalldata: calldata, classHash: classHash, forFeeEstimation: forFeeEstimation, tip: params.tip)
3535
}
3636

3737
public func signV3(calls: [StarknetCall], params: StarknetInvokeParamsV3, forFeeEstimation: Bool) throws -> StarknetInvokeTransactionV3 {
@@ -73,7 +73,7 @@ public class StarknetAccount: StarknetAccountProtocol {
7373
resourceBounds = feeEstimate.toResourceBounds()
7474
}
7575

76-
let params = StarknetInvokeParamsV3(nonce: nonce, resourceBounds: resourceBounds)
76+
let params = StarknetInvokeParamsV3(nonce: nonce, resourceBounds: resourceBounds, tip: params.tip)
7777
let signedTransaction = try signV3(calls: calls, params: params, forFeeEstimation: false)
7878

7979
return RequestBuilder.addInvokeTransaction(signedTransaction)

Sources/Starknet/Data/Execution.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ public struct StarknetInvokeParamsV3 {
3232
public let nonceDataAvailabilityMode: StarknetDAMode
3333
public let feeDataAvailabilityMode: StarknetDAMode
3434

35-
public init(nonce: Felt, resourceBounds: StarknetResourceBoundsMapping) {
35+
public init(nonce: Felt, resourceBounds: StarknetResourceBoundsMapping, tip: UInt64AsHex = .zero) {
3636
// As of Starknet 0.13, most of v3 fields have hardcoded values.
3737
self.nonce = nonce
3838
self.resourceBounds = resourceBounds
39-
self.tip = .zero
39+
self.tip = tip
4040
self.paymasterData = []
4141
self.accountDeploymentData = []
4242
self.nonceDataAvailabilityMode = .l1
@@ -53,10 +53,10 @@ public struct StarknetOptionalInvokeParamsV3 {
5353
public let nonceDataAvailabilityMode: StarknetDAMode
5454
public let feeDataAvailabilityMode: StarknetDAMode
5555

56-
public init(nonce: Felt? = nil, resourceBounds: StarknetResourceBoundsMapping? = nil) {
56+
public init(nonce: Felt? = nil, resourceBounds: StarknetResourceBoundsMapping? = nil, tip: UInt64AsHex = .zero) {
5757
self.nonce = nonce
5858
self.resourceBounds = resourceBounds
59-
self.tip = .zero
59+
self.tip = tip
6060
self.paymasterData = []
6161
self.accountDeploymentData = []
6262
self.nonceDataAvailabilityMode = .l1
@@ -72,10 +72,10 @@ public struct StarknetDeployAccountParamsV3 {
7272
public let nonceDataAvailabilityMode: StarknetDAMode
7373
public let feeDataAvailabilityMode: StarknetDAMode
7474

75-
public init(nonce: Felt, resourceBounds: StarknetResourceBoundsMapping) {
75+
public init(nonce: Felt, resourceBounds: StarknetResourceBoundsMapping, tip: UInt64AsHex = .zero) {
7676
self.nonce = nonce
7777
self.resourceBounds = resourceBounds
78-
self.tip = .zero
78+
self.tip = tip
7979
self.paymasterData = []
8080
self.nonceDataAvailabilityMode = .l1
8181
self.feeDataAvailabilityMode = .l1

Sources/Starknet/Data/Transaction/Transaction.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,15 @@ public struct StarknetInvokeTransactionV3: StarknetInvokeTransaction, StarknetTr
2828

2929
public let hash: Felt?
3030

31-
public init(senderAddress: Felt, calldata: StarknetCalldata, signature: StarknetSignature, resourceBounds: StarknetResourceBoundsMapping, nonce: Felt, forFeeEstimation: Bool = false, hash: Felt? = nil) {
31+
public init(senderAddress: Felt, calldata: StarknetCalldata, signature: StarknetSignature, resourceBounds: StarknetResourceBoundsMapping, nonce: Felt, forFeeEstimation: Bool = false, hash: Felt? = nil, tip: UInt64AsHex = .zero) {
3232
self.senderAddress = senderAddress
3333
self.calldata = calldata
3434
self.signature = signature
3535
self.nonce = nonce
3636
self.version = forFeeEstimation ? .v3Query : .v3
3737
self.hash = hash
3838
self.resourceBounds = resourceBounds
39-
self.tip = .zero
39+
self.tip = tip
4040
self.paymasterData = []
4141
self.accountDeploymentData = []
4242
self.nonceDataAvailabilityMode = .l1
@@ -208,7 +208,7 @@ public struct StarknetDeployAccountTransactionV3: StarknetDeployAccountTransacti
208208

209209
public let hash: Felt?
210210

211-
public init(signature: StarknetSignature, resourceBounds: StarknetResourceBoundsMapping, nonce: Felt, contractAddressSalt: Felt, constructorCalldata: StarknetCalldata, classHash: Felt, forFeeEstimation: Bool = false, hash: Felt? = nil) {
211+
public init(signature: StarknetSignature, resourceBounds: StarknetResourceBoundsMapping, nonce: Felt, contractAddressSalt: Felt, constructorCalldata: StarknetCalldata, classHash: Felt, forFeeEstimation: Bool = false, hash: Felt? = nil, tip: UInt64AsHex = .zero) {
212212
self.signature = signature
213213
self.nonce = nonce
214214
self.contractAddressSalt = contractAddressSalt
@@ -217,7 +217,7 @@ public struct StarknetDeployAccountTransactionV3: StarknetDeployAccountTransacti
217217
self.version = forFeeEstimation ? .v3Query : .v3
218218
self.hash = hash
219219
self.resourceBounds = resourceBounds
220-
self.tip = .zero
220+
self.tip = tip
221221
self.paymasterData = []
222222
self.nonceDataAvailabilityMode = .l1
223223
self.feeDataAvailabilityMode = .l1
@@ -390,15 +390,15 @@ public struct StarknetDeclareTransactionV3: StarknetDeclareTransaction, Starknet
390390

391391
public let hash: Felt?
392392

393-
public init(signature: StarknetSignature, resourceBounds: StarknetResourceBoundsMapping, nonce: Felt, classHash: Felt, compiledClassHash: Felt, senderAddress: Felt, hash: Felt? = nil) {
393+
public init(signature: StarknetSignature, resourceBounds: StarknetResourceBoundsMapping, nonce: Felt, classHash: Felt, compiledClassHash: Felt, senderAddress: Felt, hash: Felt? = nil, tip: UInt64AsHex = .zero) {
394394
self.signature = signature
395395
self.nonce = nonce
396396
self.classHash = classHash
397397
self.compiledClassHash = compiledClassHash
398398
self.senderAddress = senderAddress
399399
self.hash = hash
400400
self.resourceBounds = resourceBounds
401-
self.tip = .zero
401+
self.tip = tip
402402
self.paymasterData = []
403403
self.accountDeploymentData = []
404404
self.nonceDataAvailabilityMode = .l1

Tests/StarknetTests/Accounts/AccountTest.swift

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ final class AccountTests: XCTestCase {
4242
}
4343

4444
func testGetNonce() async throws {
45-
let _ = try await account.getNonce()
45+
let _ = await (try? provider.send(request: account.getNonce()))
4646
}
4747

4848
func testExecuteV3() async throws {
@@ -61,6 +61,26 @@ final class AccountTests: XCTestCase {
6161
try await Self.devnetClient.assertTransactionSucceeded(transactionHash: result.transactionHash)
6262
}
6363

64+
func testExecuteV3WithTip() async throws {
65+
let recipientAddress = AccountTests.devnetClient.constants.predeployedAccount2.address
66+
67+
let calldata: [Felt] = [
68+
recipientAddress,
69+
1000,
70+
0,
71+
]
72+
73+
let params = StarknetOptionalInvokeParamsV3(tip: UInt64AsHex(12345))
74+
let call = StarknetCall(contractAddress: ethContractAddress, entrypoint: starknetSelector(from: "transfer"), calldata: calldata)
75+
76+
let result = try await provider.send(request: account.executeV3(calls: [call], params: params))
77+
78+
try await Self.devnetClient.assertTransactionSucceeded(transactionHash: result.transactionHash)
79+
80+
let tx = try await provider.send(request: RequestBuilder.getTransactionBy(hash: result.transactionHash)).transaction as? StarknetInvokeTransactionV3
81+
XCTAssertEqual(params.tip, tx?.tip)
82+
}
83+
6484
func testExecuteV3FeeMultipliers() async throws {
6585
let recipientAddress = AccountTests.devnetClient.constants.predeployedAccount2.address
6686

@@ -144,6 +164,33 @@ final class AccountTests: XCTestCase {
144164
XCTAssertEqual(newNonce.value - nonce.value, Felt.one.value)
145165
}
146166

167+
func testDeployAccountV3WithTip() async throws {
168+
let newSigner = StarkCurveSigner(privateKey: 4444)!
169+
let newPublicKey = newSigner.publicKey
170+
let newAccountAddress = StarknetContractAddressCalculator.calculateFrom(classHash: accountContractClassHash, calldata: [newPublicKey], salt: .one)
171+
let newAccount = StarknetAccount(address: newAccountAddress, signer: newSigner, provider: provider, chainId: chainId, cairoVersion: .zero)
172+
173+
try await Self.devnetClient.prefundAccount(address: newAccountAddress, unit: .fri)
174+
175+
let nonce = await (try? provider.send(request: newAccount.getNonce())) ?? .zero
176+
177+
let feeEstimate = try await provider.send(request: newAccount.estimateDeployAccountFeeV3(classHash: accountContractClassHash, calldata: [newPublicKey], salt: .one, nonce: nonce))[0]
178+
179+
let params = StarknetDeployAccountParamsV3(nonce: nonce, resourceBounds: feeEstimate.toResourceBounds(), tip: UInt64AsHex(10))
180+
181+
let deployAccountTransaction = try newAccount.signDeployAccountV3(classHash: accountContractClassHash, calldata: [newPublicKey], salt: .one, params: params, forFeeEstimation: false)
182+
183+
let response = try await provider.send(request: RequestBuilder.addDeployAccountTransaction(deployAccountTransaction))
184+
185+
try await Self.devnetClient.assertTransactionSucceeded(transactionHash: response.transactionHash)
186+
187+
let newNonce = try await provider.send(request: newAccount.getNonce())
188+
XCTAssertEqual(newNonce.value - nonce.value, Felt.one.value)
189+
190+
let tx = try await provider.send(request: RequestBuilder.getTransactionBy(hash: response.transactionHash)).transaction as? StarknetDeployAccountTransactionV3
191+
XCTAssertEqual(params.tip, tx?.tip)
192+
}
193+
147194
func testSignTypedDataRev0() async throws {
148195
let typedData = try loadTypedDataFromFile(name: "typed_data_rev_0_struct_array_example")
149196

Tests/StarknetTests/Utils/DevnetClient/DevnetClientModels.swift

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,7 @@ import Starknet
55
enum DevnetClientConstants {
66
// Source: https://github.com/0xSpaceShard/starknet-devnet/blob/430b3370e60b28b8de430143b26e52bf36380b9a/crates/starknet-devnet-core/src/constants.rs#L25
77
static let accountContractClassHash: Felt = "0x05b4b537eaa2399e3aa99c4e2e0208ebd6c71bc1467938cd52c798c601e43564"
8-
static let erc20ContractClassHash: Felt = "0x6a22bf63c7bc07effa39a25dfbd21523d211db0100a0afd054d172b81840eaf"
98
static let ethErc20ContractAddress: Felt = "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7"
10-
static let strkErc20ContractAddress: Felt = "0x4718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d"
11-
static let udcContractClassHash: Felt = "0x7b3e05f48f0c69e4a65ce5e076a66271a527aff2c34ce1083ec6e1526997a69"
12-
static let udcContractAddress: Felt = "0x41a78e741e5af2fec34b695679bc6891742439f7afb8484ecd7766661ad02bf"
139
// Source: starknet-devnet-rs cli
1410
// Only for seed 1_053_545_547
1511
static let predeployedAccount1: AccountDetails = .init(privateKey: "0x00000000000000000000000000000000a2ed22bb0cb0b49c69f6d6a8d24bc5ea", publicKey: "0x0198e98e771ebb5da7f4f05658a80a3d6be2213dc5096d055cbbefa62901ab06", address: "0x01323cacbc02b4aaed9bb6b24d121fb712d8946376040990f2f2fa0dcf17bb5b", salt: 20)

0 commit comments

Comments
 (0)