Skip to content

Commit 94c0237

Browse files
authored
Merge branch 'develop' into multichain-asset-selection
2 parents 31aefeb + a7e1007 commit 94c0237

25 files changed

+624
-7
lines changed

Podfile.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ DEPENDENCIES:
9999
- SwiftyBeaver
100100

101101
SPEC REPOS:
102-
https://github.com/cocoapods/Specs.git:
102+
https://github.com/CocoaPods/Specs.git:
103103
- Charts
104104
- CocoaLumberjack
105105
- Cuckoo

fearless.xcodeproj/project.pbxproj

Lines changed: 167 additions & 1 deletion
Large diffs are not rendered by default.

fearless.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 6 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import Foundation
2+
import CryptoKit
3+
import SSFNetwork
4+
import FearlessKeys
5+
import SoraKeystore
6+
import SSFModels
7+
import SSFUtils
8+
import CommonCrypto
9+
10+
// https://www.okx.com/ru/web3/build/docs/waas/rest-authentication
11+
12+
enum OKXDexRequestSignerError: Error {
13+
case accountUnavailable
14+
case invalidData
15+
case invalidSecret
16+
}
17+
18+
final class OKXDexRequestSigner: RequestSigner {
19+
func sign(request: inout URLRequest, config: SSFNetwork.RequestConfig) throws {
20+
let timestamp = DateFormatter.iso.string(from: Date())
21+
request.setValue(timestamp, forHTTPHeaderField: "OK-ACCESS-TIMESTAMP")
22+
23+
let apiKey = OKXApiKeys.okxApiKey
24+
request.setValue(apiKey, forHTTPHeaderField: "OK-ACCESS-KEY")
25+
26+
let secretKey = OKXApiKeys.okxSecretKey
27+
28+
let passphrase = OKXApiKeys.okxPassphrase
29+
request.setValue(passphrase, forHTTPHeaderField: "OK-ACCESS-PASSPHRASE")
30+
31+
let projectId = OKXApiKeys.okxProjectId
32+
request.setValue(projectId, forHTTPHeaderField: "OK-ACCESS-PROJECT")
33+
34+
let endpoint = request.url?.absoluteString.replacingOccurrences(of: config.baseURL.absoluteString, with: "", options: .caseInsensitive, range: nil)
35+
guard let sign = [timestamp, config.method.rawValue.uppercased(), endpoint.or(""), (config.body?.toUTF8String()).or("")].joined().data(using: .utf8) else {
36+
throw OKXDexRequestSignerError.invalidData
37+
}
38+
let key = SymmetricKey(data: Data(secretKey.utf8))
39+
40+
let signature = HMAC<SHA256>.authenticationCode(for: sign, using: key)
41+
let signatureData = Data(signature)
42+
request.setValue(signatureData.base64EncodedString(), forHTTPHeaderField: "OK-ACCESS-SIGN")
43+
}
44+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Foundation
2+
3+
class OKXDexAllTokensRequestParameters: NetworkRequestUrlParameters, Decodable {
4+
/// Chain ID (e.g., 1 for Ethereum)
5+
let chainId: String
6+
7+
init(chainId: String) {
8+
self.chainId = chainId
9+
}
10+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import Foundation
2+
3+
class OKXDexApproveRequestParameters: NetworkRequestUrlParameters, Decodable {
4+
/// Chain ID (e.g., 1 for Ethereum)
5+
let chainId: String
6+
7+
/// Token contract address (e.g., 0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48)
8+
let tokenContractAddress: String
9+
10+
/// The amount of token that needs to be permitted (set in minimal divisible units, e.g., 1.00 USDT set as 1000000, 1.00 DAI set as 1000000000000000000)
11+
let approveAmount: String
12+
13+
init(
14+
chainId: String,
15+
tokenContractAddress: String,
16+
approveAmount: String
17+
) {
18+
self.chainId = chainId
19+
self.tokenContractAddress = tokenContractAddress
20+
self.approveAmount = approveAmount
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Foundation
2+
3+
class OKXDexLiquiditySourceRequestParameters: NetworkRequestUrlParameters, Decodable {
4+
/// Chain ID (e.g., 1 for Ethereum)
5+
let chainId: String
6+
7+
init(chainId: String) {
8+
self.chainId = chainId
9+
}
10+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import Foundation
2+
3+
class OKXDexQuotesRequestParameters: NetworkRequestUrlParameters, Decodable {
4+
/// Chain ID (e.g., 1 for Ethereum)
5+
let chainId: String
6+
7+
/// The input amount of a token to be sold (set in minimal divisible units, e.g., 1.00 USDT set as 1000000, 1.00 DAI set as 1000000000000000000), you could get the minimal divisible units from https://www.okx.com/api/v5/dex/aggregator/all-tokens
8+
let amount: String
9+
10+
/// The contract address of a token to be sold (e.g., 0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee)
11+
let fromTokenAddress: String
12+
13+
/// The contract address of a token to be bought (e.g., 0xa892e1fef8b31acc44ce78e7db0a2dc610f92d00)
14+
let toTokenAddress: String
15+
16+
/// DexId of the liquidity pool for limited quotes, multiple combinations separated by , (e.g.,1,50,180, see liquidity list for more)
17+
let dexIds: String?
18+
19+
/// (Optional. The default is 90%.) The percentage (between 0 - 1.0) of the price impact allowed. When the priceImpactProtectionPercentage is set, if the estimated price impact is above the percentage indicated, an error will be returned. For example, if PriceImpactProtectionPercentage = .25 (25%), any quote with a price impact higher than 25% will return an error. This is an optional feature, and the default value is 0.9. When it’s set to 1.0 (100%), the feature will be disabled, which means that every transaction will be allowed to pass. Note: If we’re unable to calculate the price impact, we’ll return null, and the price impact protection will be disabled.
20+
let priceImpactProtectionPercentage: String?
21+
22+
/// The percentage of fromTokenAmount will be sent to the referrer's address, the rest will be set as the input amount to be sold. min percentage:0 max percentage:3
23+
let feePercent: String?
24+
25+
init(
26+
chainId: String,
27+
amount: String,
28+
fromTokenAddress: String,
29+
toTokenAddress: String,
30+
dexIds: String? = nil,
31+
priceImpactProtectionPercentage: String? = nil,
32+
feePercent: String? = nil
33+
) {
34+
self.chainId = chainId
35+
self.amount = amount
36+
self.fromTokenAddress = fromTokenAddress
37+
self.toTokenAddress = toTokenAddress
38+
self.dexIds = dexIds
39+
self.priceImpactProtectionPercentage = priceImpactProtectionPercentage
40+
self.feePercent = feePercent
41+
}
42+
}
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
import Foundation
2+
3+
class OKXDexSwapRequestParameters: NetworkRequestUrlParameters, Decodable {
4+
/// Chain ID (e.g., 1 for Ethereum)
5+
let chainId: String
6+
7+
/// The input amount of a token to be sold (set in minimal divisible units, e.g., 1.00 USDT set as 1000000, 1.00 DAI set as 1000000000000000000), you could get the minimal divisible units from https://www.okx.com/api/v5/dex/aggregator/all-tokens
8+
let amount: String
9+
10+
/// The contract address of a token you want to send (e.g.,0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee)
11+
let fromTokenAddress: String
12+
13+
/// The contract address of a token you want to receive (e.g.,0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48)
14+
let toTokenAddress: String
15+
16+
/// The slippage you are willing to accept. If you set 0.5, it means 50% slippage is acceptable. min:0 max:1
17+
let slippage: String
18+
19+
/// User's wallet address (e.g.,0x3f6a3f57569358a512ccc0e513f171516b0fd42a)
20+
let userWalletAddress: String
21+
22+
/// Referrer address (Supports SOL or SPL-Token commissions. SOL commissions use wallet address, and SPL-Token commissions use token account.) The fromToken address that receives the commission. When using the API, the fee rate can be adjusted by adding feePercent. Note: This doesn’t support transactions involving wrapped tokens such as those between SOL and WSOL. In a single transaction, either a fromToken commission or a toToken commission can be selected.
23+
let swapReceiverAddress: String?
24+
25+
/// recipient address of a purchased token if not set, userWalletAddress will receive a purchased token (e.g.,0x3f6a3f57569358a512ccc0e513f171516b0fd42a)
26+
let referrerAddress: String?
27+
28+
/// The percentage of fromTokenAmount will be sent to the referrer's address, the rest will be set as the input amount to be sold. min percentage:0 max percentage:3
29+
let feePercent: String?
30+
31+
/// (Optional, The gas (in wei) for the swap transaction. If the value is too low to achieve the quote, an error will be returned
32+
let gaslimit: String?
33+
34+
/// (Optional, defaults to average) The target gas price level for the swap transaction,set to average or fast or slow
35+
let gasLevel: String?
36+
37+
/// DexId of the liquidity pool for limited quotes, multiple combinations separated by , (e.g., 1,50,180, see liquidity list for more)
38+
let dexIds: String?
39+
40+
/// Account address for toToken in solana transactions, Get method https://www.okx.com/ru/web3/build/docs/waas/dex-use-swap-solana-quick-start
41+
let solTokenAccountAddress: String?
42+
43+
/// (Optional. The default is 90%.) The percentage (between 0 - 1.0) of the price impact allowed. When the priceImpactProtectionPercentage is set, if the estimated price impact is above the percentage indicated, an error will be returned. For example, if PriceImpactProtectionPercentage = .25 (25%), any quote with a price impact higher than 25% will return an error. This is an optional feature, and the default value is 0.9. When it’s set to 1.0 (100%), the feature will be disabled, which means that every transaction will be allowed to pass. Note: If we’re unable to calculate the price impact, we’ll return null, and the price impact protection will be disabled.
44+
let priceImpactProtectionPercentage: String?
45+
46+
/// You can customize the parameters to be sent on the blockchain in callData by encoding the data into a 128-character 64-bytes hexadecimal string. For example, the string “0x111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111” needs to keep the “0x” at its start.
47+
let callDataMemo: String?
48+
49+
/// toToken referrer address (Only supports SPL-Token commissions which use token account.) The toToken address that receives the commission. When using the API, the fee rate can be adjusted by adding feePercent. Note: This doesn’t support transactions involving wrapped tokens such as those between SOL and WSOL. In a single transaction, either a fromToken commission or a toToken commission can be selected.
50+
let toTokenReferrerAddress: String?
51+
52+
/// Used for transactions on the Solana network and similar to gasPrice on Ethereum. This price determines the priority level of the transaction. The higher the price, the more likely that the transaction can be processed faster.
53+
let computeUnitPrice: String?
54+
55+
/// Used for transactions on the Solana network and analogous to gasLimit on Ethereum, which ensures that the transaction won’t take too much computing resource.
56+
let computeUnitLimit: String?
57+
58+
init(
59+
chainId: String,
60+
amount: String,
61+
fromTokenAddress: String,
62+
toTokenAddress: String,
63+
slippage: String,
64+
userWalletAddress: String,
65+
swapReceiverAddress: String? = nil,
66+
referrerAddress: String? = nil,
67+
feePercent: String? = nil,
68+
gaslimit: String? = nil,
69+
gasLevel: String? = nil,
70+
dexIds: String? = nil,
71+
solTokenAccountAddress: String? = nil,
72+
priceImpactProtectionPercentage: String? = nil,
73+
callDataMemo: String? = nil,
74+
toTokenReferrerAddress: String? = nil,
75+
computeUnitPrice: String? = nil,
76+
computeUnitLimit: String? = nil
77+
) {
78+
self.chainId = chainId
79+
self.amount = amount
80+
self.fromTokenAddress = fromTokenAddress
81+
self.toTokenAddress = toTokenAddress
82+
self.slippage = slippage
83+
self.userWalletAddress = userWalletAddress
84+
self.swapReceiverAddress = swapReceiverAddress
85+
self.referrerAddress = referrerAddress
86+
self.feePercent = feePercent
87+
self.gaslimit = gaslimit
88+
self.gasLevel = gasLevel
89+
self.dexIds = dexIds
90+
self.solTokenAccountAddress = solTokenAccountAddress
91+
self.priceImpactProtectionPercentage = priceImpactProtectionPercentage
92+
self.callDataMemo = callDataMemo
93+
self.toTokenReferrerAddress = toTokenReferrerAddress
94+
self.computeUnitPrice = computeUnitPrice
95+
self.computeUnitLimit = computeUnitLimit
96+
}
97+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import Foundation
2+
3+
struct OKXApproveTransaction: Decodable {
4+
let data: String
5+
let dexContractAddress: String
6+
let gasLimit: String
7+
let gasPrice: String
8+
}

0 commit comments

Comments
 (0)