Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🔄 synced file(s) with circlefin/modularwallets-ios-sdk-internal #7

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CircleModularWalletsCore/Resources/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleShortVersionString</key>
<string>1.0.4</string>
<string>1.0.5</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleName</key>
Expand Down
29 changes: 21 additions & 8 deletions CircleModularWalletsCore/Sources/Accounts/CircleSmartAccount.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,25 @@ import BigInt
import Web3Core
import web3swift

/// Creates a Circle smart account.
///
/// - Parameters:
/// - client: The client used to interact with the blockchain.
/// - owner: The owner account associated with the Circle smart account.
/// - version: The version of the Circle smart account. Default is "circle_6900_v1".
/// - name: The wallet name assigned to the newly registered account defaults to the format "passkey-yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
///
/// - Throws: BaseError if there are any problems during the wallet creation process.
///
/// - Returns: The created Circle smart account.
public func toCircleSmartAccount<A: Account>(
client: Client,
owner: A,
version: String = "circle_6900_v1"
version: String = "circle_6900_v1",
name: String? = nil
) async throws -> CircleSmartAccount<A> where A.T == SignResult {
try await .init(client: client, owner: owner, version: version)
let name = name ?? "passkey-\(Utils.getCurrentDateTime())"
return try await .init(client: client, owner: owner, version: version, name: name)
}

public class CircleSmartAccount<A: Account>: SmartAccount where A.T == SignResult {
Expand All @@ -44,7 +57,7 @@ public class CircleSmartAccount<A: Account>: SmartAccount where A.T == SignResul
self.entryPoint = entryPoint
}

convenience init(client: Client, owner: A, version: String) async throws {
convenience init(client: Client, owner: A, version: String, name: String?) async throws {
guard let buidlTransport = client.transport as? ModularTransport else {
throw BaseError(shortMessage: "The property client.transport is not the ModularTransport")
}
Expand All @@ -56,7 +69,7 @@ public class CircleSmartAccount<A: Account>: SmartAccount where A.T == SignResul
transport: buidlTransport,
hexPublicKey: webAuthnAccount.credential.publicKey,
version: version,
name: webAuthnAccount.credential.userName
name: name
)

self.init(client: client, owner: owner, wallet: wallet)
Expand Down Expand Up @@ -84,10 +97,10 @@ public class CircleSmartAccount<A: Account>: SmartAccount where A.T == SignResul
}
}

static func create(url: String, apiKey: String, client: Client, owner: A) -> CircleSmartAccount {
let account = CircleSmartAccount(client: client, owner: owner, wallet: Wallet())
return account
}
// static func create(url: String, apiKey: String, client: Client, owner: A) -> CircleSmartAccount {
// let account = CircleSmartAccount(client: client, owner: owner, wallet: Wallet())
// return account
// }

public func getAddress() -> String {
return wallet.address ?? ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,6 @@ public struct WebAuthnCredential: RpRpcApi {
/// Relying party identifier
public let rpId: String

/// User name
public var userName: String? = nil

static func register(transport: Transport,
userName: String) async throws -> WebAuthnCredential {
do {
Expand Down Expand Up @@ -99,13 +96,12 @@ public struct WebAuthnCredential: RpRpcApi {
}

/// After the server verifies the registration and creates the user account, sign in the user with the new account.
/// Step 4. parse and serialized public key
/// Step 4. Parse and serialized public key
let serializedPublicKey = HexUtils.bytesToHex(publicKey.decodedBytes)
return WebAuthnCredential(id: credential.id,
publicKey: serializedPublicKey,
raw: credential,
rpId: option.relyingParty.id,
userName: userName)
rpId: option.relyingParty.id)
} catch let error as BaseError {
throw error
} catch {
Expand Down Expand Up @@ -135,7 +131,7 @@ public struct WebAuthnCredential: RpRpcApi {
)

/// After the server verifies the assertion, sign in the user.
/// Step 4. parse and serialized public key
/// Step 4. Parse and serialized public key
let coseKey = try Utils.pemToCOSE(pemKey: loginResult.publicKey)
let serializedPublicKey = HexUtils.bytesToHex(coseKey)
return WebAuthnCredential(id: credential.id,
Expand Down
29 changes: 29 additions & 0 deletions CircleModularWalletsCore/Sources/Chains/Arbitrum.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright (c) 2025, Circle Internet Group, Inc. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

let Arbitrum = _Arbitrum()

struct _Arbitrum: Chain {

let chainId: Int = 42161

let blockchain: String = "ARB"

}
29 changes: 29 additions & 0 deletions CircleModularWalletsCore/Sources/Chains/ArbitrumSepolia.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright (c) 2025, Circle Internet Group, Inc. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

let ArbitrumSepolia = _ArbitrumSepolia()

struct _ArbitrumSepolia: Chain {

let chainId: Int = 421614

let blockchain: String = "ARB-SEPOLIA"

}
29 changes: 29 additions & 0 deletions CircleModularWalletsCore/Sources/Chains/Polygon.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright (c) 2025, Circle Internet Group, Inc. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

let Polygon = _Polygon()

struct _Polygon: Chain {

let chainId: Int = 137

let blockchain: String = "MATIC"

}
29 changes: 29 additions & 0 deletions CircleModularWalletsCore/Sources/Chains/PolygonAmoy.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
//
// Copyright (c) 2025, Circle Internet Group, Inc. All rights reserved.
//
// SPDX-License-Identifier: Apache-2.0
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//

import Foundation

let PolygonAmoy = _PolygonAmoy()

struct _PolygonAmoy: Chain {

let chainId: Int = 80_002

let blockchain: String = "MATIC-AMOY"

}
70 changes: 67 additions & 3 deletions CircleModularWalletsCore/Sources/Helpers/Constants.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,73 @@ public let CIRCLE_BASE_URL = "https://modular-sdk.circle.com/v1/rpc/w3s/buidl"
public let ENTRYPOINT_V07_ADDRESS = "0x0000000071727De22E5E9d8BAf0edAc6f37da032"

let CONTRACT_ADDRESS: [String: String] = [
"token_1": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"token_2": "0xdac17f958d2ee523a2206206994597c13d831ec7",
"token_3": "0xb8c77482e45f1f44de1745f52c74426c631bdd52"
MainnetToken.USDT.name: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
MainnetToken.BNB.name: "0xB8c77482e45F1F44dE1745F52C74426C631bDD52",
MainnetToken.USDC.name: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
MainnetToken.stETH.name: "0xae7ab96520DE3A18E5e111B5EaAb095312D7fE84",
MainnetToken.TONCOIN.name: "0x582d872A1B094FC48F5DE31D3B73F2D9bE47def1",
MainnetToken.LINK.name: "0x514910771AF9Ca656af840dff83E8264EcF986CA",
MainnetToken.wstETH.name: "0x7f39C581F595B53c5cb19bD0b3f8dA6c935E2Ca0",
MainnetToken.SHIB.name: "0x95aD61b0a150d79219dCF64E1E6Cc01f0B64C4cE",
MainnetToken.WBTC.name: "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599",
MainnetToken.WETH.name: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
MainnetToken.DOT.name: "0x21c2c96Dbfa137E23946143c71AC8330F9B44001",
MainnetToken.BlurPool.name: "0x0000000000A39bb272e79075ade125fd351887Ac",
MainnetToken.BGB.name: "0x54D2252757e1672EEaD234D27B1270728fF90581",
MainnetToken.LEO.name: "0x2AF5D2aD76741191D15Dfe7bF6aC92d4Bd912Ca3",
MainnetToken.UNI.name: "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
MainnetToken.PEPE.name: "0x6982508145454Ce325dDbE47a25d4ec3d2311933",
MainnetToken.weETH.name: "0xCd5fE23C85820F7B72D0926FC9b05b43E359b7ee",
MainnetToken.NEAR.name: "0x85F17Cf997934a597031b2E18a9aB6ebD4B9f6a4",
MainnetToken.USDe.name: "0x4c9EDD5852cd905f086C759E8383e09bff1E68B3",
MainnetToken.USDS.name: "0xdC035D45d973E3EC169d2276DDab16f1e407384F",

PolygonToken.WETH.name: "0x7ceB23fD6bC0adD59E62ac25578270cFf1b9f619",
PolygonToken.USDT.name: "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
PolygonToken.BNB.name: "0x3BA4c387f786bFEE076A58914F5Bd38d668B42c3",
PolygonToken.SOL.name: "0xd93f7E271cB87c23AaA73edC008A79646d1F9912",
PolygonToken.USDC.name: "0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
PolygonToken.USDC_e.name: "0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174",
PolygonToken.BUSD.name: "0xdAb529f40E671A1D4bF91361c21bf9f0C9712ab7",
PolygonToken.AVAX.name: "0x2C89bbc92BD86F8075d1DEcc58C7F4E0107f286b",
PolygonToken.LINK.name: "0xb0897686c545045aFc77CF20eC7A532E3120E0F1",
PolygonToken.SHIB.name: "0x6f8a06447Ff6FcF75d803135a7de15CE88C1d4ec",
PolygonToken.WBTC.name: "0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6",
PolygonToken.LEO.name: "0x06D02e9D62A13fC76BB229373FB3BBBD1101D2fC",
PolygonToken.UNI.name: "0xb33EaAd8d922B1083446DC23f610c2567fB5180f",
PolygonToken.AAVE.name: "0xD6DF932A45C0f255f85145f286eA0b292B21C90B",
PolygonToken.CRO.name: "0xAdA58DF0F643D959C2A47c9D4d4c1a4deFe3F11C",
PolygonToken.RNDR.name: "0x61299774020dA444Af134c82fa83E3810b309991",
PolygonToken.DAI.name: "0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063",
PolygonToken.OM.name: "0xC3Ec80343D2bae2F8E680FDADDe7C17E71E114ea",
PolygonToken.FET.name: "0x7583FEDDbceFA813dc18259940F76a02710A8905",

ArbitrumToken.USDT.name: "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
ArbitrumToken.USDC_e.name: "0xFF970A61A04b1cA14834A43f5dE4533eBDDB5CC8",
ArbitrumToken.USDC.name: "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
ArbitrumToken.LINK.name: "0xf97f4df75117a78c1A5a0DBb814Af92458539FB4",
ArbitrumToken.wstETH.name: "0x0fBcbaEA96Ce0cF7Ee00A8c19c3ab6f5Dc8E1921",
ArbitrumToken.WBTC.name: "0x2f2a2543B76A4166549F7aaB2e75Bef0aefC5B0f",
ArbitrumToken.WETH.name: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
ArbitrumToken.UNI.name: "0xFa7F8980b0f1E64A2062791cc3b0871572f1F7f0",
ArbitrumToken.PEPE.name: "0x25d887Ce7a35172C62FeBFD67a1856F20FaEbB00",
ArbitrumToken.USDe.name: "0x5d3a1Ff2b6BAb83b63cd9AD0787074081a52ef34",
ArbitrumToken.DAI.name: "0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1",
ArbitrumToken.ARB.name: "0x912CE59144191C1204E64559FE8253a0e49E6548",
ArbitrumToken.ENA.name: "0x58538e6A46E07434d7E7375Bc268D3cb839C0133",
ArbitrumToken.cbBTC.name: "0xcbB7C0000aB88B473b1f5aFd9ef808440eed33Bf",
ArbitrumToken.GRT.name: "0x9623063377AD1B27544C965cCd7342f7EA7e88C7",
ArbitrumToken.USD0.name: "0x35f1C5cB7Fb977E669fD244C567Da99d8a3a6850",
ArbitrumToken.LDO.name: "0x13Ad51ed4F1B7e9Dc168d8a00cB3f4dDD85EfA60",
ArbitrumToken.PYTH.name: "0xE4D5c6aE46ADFAF04313081e8C0052A30b6Dd724",
ArbitrumToken.ezETH.name: "0x2416092f143378750bb29b79eD961ab195CcEea5",
ArbitrumToken.CRV.name: "0x11cDb42B0EB46D95f990BeDD4695A6e3fA034978",

SepoliaToken.USDC.name: "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",

PolygonAmoyToken.USDC.name: "0x41e94eb019c0762f9bfcf9fb1e58725bfb0e7582",

ArbitrumSepoliaToken.USDC.name: "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d"
]

let STUB_SIGNATURE = "0x0000be58786f7ae825e097256fc83a4749b95189e03e9963348373e9c595b15200000000000000000000000000000000000000000000000000000000000000412200000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000006091077742edaf8be2fa866827236532ec2a5547fe2721e606ba591d1ffae7a15c022e5f8fe5614bbf65ea23ad3781910eb04a1a60fae88190001ecf46e5f5680a00000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000002549960de5880e8c687434170f6476605b8fe4aeb9a28632c7995cf3ba831d9763050000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000867b2274797065223a22776562617574686e2e676574222c226368616c6c656e6765223a224b6d62474d316a4d554b57794d6352414c6774553953537144384841744867486178564b6547516b503541222c226f726967696e223a22687474703a2f2f6c6f63616c686f73743a35313733222c2263726f73734f726967696e223a66616c73657d0000000000000000000000000000000000000000000000000000"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Foundation
#if SWIFT_PACKAGE
extension Bundle {
public enum SDK {
public static let version = "1.0.4"
public static let version = "1.0.5"
}
}
#else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,33 +26,33 @@ extension KeyedDecodingContainer {
return HexUtils.hexToBigInt(hex: hexString)
}

func decodeBytesFromURLEncodedBase64(forKey key: KeyedDecodingContainer.Key) throws -> [UInt8] {
guard let bytes = try decode(
URLEncodedBase64.self,
forKey: key
).decodedBytes else {
throw DecodingError.dataCorruptedError(
forKey: key,
in: self,
debugDescription: "Failed to decode base64url encoded string at \(key) into bytes"
)
}
return bytes
}

func decodeBytesFromURLEncodedBase64IfPresent(forKey key: KeyedDecodingContainer.Key) throws -> [UInt8]? {
guard let bytes = try decodeIfPresent(
URLEncodedBase64.self,
forKey: key
) else { return nil }
// func decodeBytesFromURLEncodedBase64(forKey key: KeyedDecodingContainer.Key) throws -> [UInt8] {
// guard let bytes = try decode(
// URLEncodedBase64.self,
// forKey: key
// ).decodedBytes else {
// throw DecodingError.dataCorruptedError(
// forKey: key,
// in: self,
// debugDescription: "Failed to decode base64url encoded string at \(key) into bytes"
// )
// }
// return bytes
// }

guard let decodedBytes = bytes.decodedBytes else {
throw DecodingError.dataCorruptedError(
forKey: key,
in: self,
debugDescription: "Failed to decode base64url encoded string at \(key) into bytes"
)
}
return decodedBytes
}
// func decodeBytesFromURLEncodedBase64IfPresent(forKey key: KeyedDecodingContainer.Key) throws -> [UInt8]? {
// guard let bytes = try decodeIfPresent(
// URLEncodedBase64.self,
// forKey: key
// ) else { return nil }
//
// guard let decodedBytes = bytes.decodedBytes else {
// throw DecodingError.dataCorruptedError(
// forKey: key,
// in: self,
// debugDescription: "Failed to decode base64url encoded string at \(key) into bytes"
// )
// }
// return decodedBytes
// }
}
Loading
Loading