react-native-candle 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +188 -0
- package/ReactNativeCandle.podspec +45 -0
- package/app.plugin.js +1 -0
- package/ios/Sources/CandleLinkSheetWrapperView.swift +53 -0
- package/ios/Sources/CandleLinkViewModel.swift +67 -0
- package/ios/Sources/HostingViewController.swift +56 -0
- package/ios/Sources/RNCandle.swift +155 -0
- package/ios/Sources/UIApplication++.swift +14 -0
- package/lib/commonjs/index.js +49 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/specs/RNCandle.nitro.js +6 -0
- package/lib/commonjs/specs/RNCandle.nitro.js.map +1 -0
- package/lib/module/index.js +38 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/specs/RNCandle.nitro.js +4 -0
- package/lib/module/specs/RNCandle.nitro.js.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/src/index.d.ts +22 -0
- package/lib/typescript/commonjs/src/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/src/specs/RNCandle.nitro.d.ts +21 -0
- package/lib/typescript/commonjs/src/specs/RNCandle.nitro.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/src/index.d.ts +22 -0
- package/lib/typescript/module/src/index.d.ts.map +1 -0
- package/lib/typescript/module/src/specs/RNCandle.nitro.d.ts +21 -0
- package/lib/typescript/module/src/specs/RNCandle.nitro.d.ts.map +1 -0
- package/nitrogen/generated/.gitattributes +1 -0
- package/nitrogen/generated/ios/ReactNativeCandle+autolinking.rb +60 -0
- package/nitrogen/generated/ios/ReactNativeCandle-Swift-Cxx-Bridge.cpp +56 -0
- package/nitrogen/generated/ios/ReactNativeCandle-Swift-Cxx-Bridge.hpp +173 -0
- package/nitrogen/generated/ios/ReactNativeCandle-Swift-Cxx-Umbrella.hpp +58 -0
- package/nitrogen/generated/ios/ReactNativeCandleAutolinking.mm +33 -0
- package/nitrogen/generated/ios/ReactNativeCandleAutolinking.swift +30 -0
- package/nitrogen/generated/ios/c++/HybridRNCandleSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridRNCandleSpecSwift.hpp +139 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__string.swift +46 -0
- package/nitrogen/generated/ios/swift/HybridRNCandleSpec.swift +55 -0
- package/nitrogen/generated/ios/swift/HybridRNCandleSpec_cxx.swift +263 -0
- package/nitrogen/generated/ios/swift/PresentationBackground.swift +40 -0
- package/nitrogen/generated/ios/swift/PresentationStyle.swift +40 -0
- package/nitrogen/generated/ios/swift/Service.swift +56 -0
- package/nitrogen/generated/ios/swift/ToolCall.swift +46 -0
- package/nitrogen/generated/shared/c++/HybridRNCandleSpec.cpp +28 -0
- package/nitrogen/generated/shared/c++/HybridRNCandleSpec.hpp +83 -0
- package/nitrogen/generated/shared/c++/PresentationBackground.hpp +78 -0
- package/nitrogen/generated/shared/c++/PresentationStyle.hpp +78 -0
- package/nitrogen/generated/shared/c++/Service.hpp +94 -0
- package/nitrogen/generated/shared/c++/ToolCall.hpp +73 -0
- package/package.json +111 -0
- package/plugin/withIosDeploymentTarget.js +46 -0
- package/src/index.ts +73 -0
- package/src/specs/RNCandle.nitro.ts +39 -0
package/README.md
ADDED
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# react-native-candle
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install react-native-candle react-native-nitro-modules
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
yarn add react-native-candle react-native-nitro-modules
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
bun add react-native-candle react-native-nitro-modules
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
If you are using Expo add the plugin to your `app.json`
|
|
20
|
+
|
|
21
|
+
```json
|
|
22
|
+
"plugins": [
|
|
23
|
+
// other plugins
|
|
24
|
+
"react-native-candle",
|
|
25
|
+
[
|
|
26
|
+
"expo-build-properties",
|
|
27
|
+
{
|
|
28
|
+
"ios": {
|
|
29
|
+
"deploymentTarget": "17.0",
|
|
30
|
+
"useFrameworks": "dynamic"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
]
|
|
34
|
+
],
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
#### Public API
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { useState } from "react";
|
|
43
|
+
import { ActivityIndicator, Button, StyleSheet, View } from "react-native";
|
|
44
|
+
import {
|
|
45
|
+
deleteUser,
|
|
46
|
+
unlinkAccount,
|
|
47
|
+
executeTool,
|
|
48
|
+
getAvailableTools,
|
|
49
|
+
getFiatAccounts,
|
|
50
|
+
getActivity,
|
|
51
|
+
getLinkedAccounts,
|
|
52
|
+
presentCandleLinkSheet,
|
|
53
|
+
} from "react-native-candle";
|
|
54
|
+
|
|
55
|
+
export default function TabOneScreen() {
|
|
56
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
57
|
+
return (
|
|
58
|
+
<View style={[styles.container]}>
|
|
59
|
+
<ActivityIndicator animating={isLoading} />
|
|
60
|
+
<Button
|
|
61
|
+
title="Unlink Account"
|
|
62
|
+
onPress={() => {
|
|
63
|
+
setIsLoading(true);
|
|
64
|
+
unlinkAccount("linkedAccountID") // Replace with actual linked account ID
|
|
65
|
+
.then(() => {
|
|
66
|
+
console.log("User unlinked successfully.");
|
|
67
|
+
setIsLoading(false);
|
|
68
|
+
})
|
|
69
|
+
.catch((error) => {
|
|
70
|
+
console.error("Error unlinking user:", error);
|
|
71
|
+
setIsLoading(false);
|
|
72
|
+
});
|
|
73
|
+
}}
|
|
74
|
+
/>
|
|
75
|
+
<Button
|
|
76
|
+
title="Delete User"
|
|
77
|
+
onPress={() => {
|
|
78
|
+
setIsLoading(true);
|
|
79
|
+
deleteUser()
|
|
80
|
+
.then(() => {
|
|
81
|
+
console.log("User deleted successfully.");
|
|
82
|
+
setIsLoading(false);
|
|
83
|
+
})
|
|
84
|
+
.catch((error) => {
|
|
85
|
+
console.error("Error deleting user:", error);
|
|
86
|
+
setIsLoading(false);
|
|
87
|
+
});
|
|
88
|
+
}}
|
|
89
|
+
/>
|
|
90
|
+
<Button
|
|
91
|
+
title="Get Available Tools"
|
|
92
|
+
onPress={() => {
|
|
93
|
+
setIsLoading(true);
|
|
94
|
+
getAvailableTools()
|
|
95
|
+
.then((tools) => {
|
|
96
|
+
console.log("Available tools:", tools);
|
|
97
|
+
setIsLoading(false);
|
|
98
|
+
})
|
|
99
|
+
.catch((error) => {
|
|
100
|
+
console.error("Error fetching available tools:", error);
|
|
101
|
+
setIsLoading(false);
|
|
102
|
+
});
|
|
103
|
+
}}
|
|
104
|
+
/>
|
|
105
|
+
<Button
|
|
106
|
+
title="Execute Tool"
|
|
107
|
+
onPress={() => {
|
|
108
|
+
setIsLoading(true);
|
|
109
|
+
executeTool({ arguments: "", name: "get_linked_accounts" })
|
|
110
|
+
.then((result) => {
|
|
111
|
+
console.log("Tool executed successfully:", result);
|
|
112
|
+
setIsLoading(false);
|
|
113
|
+
})
|
|
114
|
+
.catch((error) => {
|
|
115
|
+
console.error("Error executing tool:", error);
|
|
116
|
+
setIsLoading(false);
|
|
117
|
+
});
|
|
118
|
+
}}
|
|
119
|
+
/>
|
|
120
|
+
<Button
|
|
121
|
+
title="Get Fiat Accounts"
|
|
122
|
+
onPress={() => {
|
|
123
|
+
setIsLoading(true);
|
|
124
|
+
getFiatAccounts()
|
|
125
|
+
.then((accounts) => {
|
|
126
|
+
console.log("Fiat accounts:", accounts);
|
|
127
|
+
setIsLoading(false);
|
|
128
|
+
})
|
|
129
|
+
.catch((error) => {
|
|
130
|
+
console.error("Error fetching fiat accounts:", error);
|
|
131
|
+
setIsLoading(false);
|
|
132
|
+
});
|
|
133
|
+
}}
|
|
134
|
+
/>
|
|
135
|
+
<Button
|
|
136
|
+
title="Get Activity"
|
|
137
|
+
onPress={() => {
|
|
138
|
+
setIsLoading(true);
|
|
139
|
+
getActivity("P1D")
|
|
140
|
+
.then((activity) => {
|
|
141
|
+
console.log("Activity:", activity);
|
|
142
|
+
setIsLoading(false);
|
|
143
|
+
})
|
|
144
|
+
.catch((error) => {
|
|
145
|
+
console.error("Error fetching activity:", error);
|
|
146
|
+
setIsLoading(false);
|
|
147
|
+
});
|
|
148
|
+
}}
|
|
149
|
+
/>
|
|
150
|
+
<Button
|
|
151
|
+
title="Get Linked Accounts"
|
|
152
|
+
onPress={() => {
|
|
153
|
+
setIsLoading(true);
|
|
154
|
+
getLinkedAccounts()
|
|
155
|
+
.then((accounts) => {
|
|
156
|
+
console.log("Linked accounts:", accounts);
|
|
157
|
+
setIsLoading(false);
|
|
158
|
+
})
|
|
159
|
+
.catch((error) => {
|
|
160
|
+
console.error("Error fetching linked accounts:", error);
|
|
161
|
+
});
|
|
162
|
+
}}
|
|
163
|
+
/>
|
|
164
|
+
<Button
|
|
165
|
+
title="Show Candle Sheet"
|
|
166
|
+
onPress={() => {
|
|
167
|
+
presentCandleLinkSheet({
|
|
168
|
+
onSuccess: (linkedAccount) => {
|
|
169
|
+
console.log("Account selected:", linkedAccount);
|
|
170
|
+
},
|
|
171
|
+
customerName: "Akme Inc.",
|
|
172
|
+
presentationStyle: "fullScreen",
|
|
173
|
+
});
|
|
174
|
+
}}
|
|
175
|
+
/>
|
|
176
|
+
</View>
|
|
177
|
+
);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const styles = StyleSheet.create({
|
|
181
|
+
container: {
|
|
182
|
+
flex: 1,
|
|
183
|
+
backgroundColor: "#fff",
|
|
184
|
+
alignItems: "center",
|
|
185
|
+
justifyContent: "center",
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
```
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, "package.json")))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = "ReactNativeCandle"
|
|
7
|
+
s.version = package["version"]
|
|
8
|
+
s.summary = package["description"]
|
|
9
|
+
s.homepage = package["homepage"]
|
|
10
|
+
s.license = package["license"]
|
|
11
|
+
s.authors = package["author"]
|
|
12
|
+
|
|
13
|
+
s.platforms = { :ios => '17.0', :visionos => 1.0 }
|
|
14
|
+
s.source = { :git => "https://github.com/candlefinance/candle-react-native.git", :tag => "#{s.version}" }
|
|
15
|
+
|
|
16
|
+
s.source_files = [
|
|
17
|
+
# Implementation (Swift)
|
|
18
|
+
"ios/Sources/**/*.{swift}",
|
|
19
|
+
# Autolinking/Registration (Objective-C++)
|
|
20
|
+
"ios/**/*.{m,mm}",
|
|
21
|
+
# Implementation (C++ objects)
|
|
22
|
+
"cpp/**/*.{hpp,cpp}",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
spm_dependency(s,
|
|
26
|
+
url: "https://github.com/candlefinance/candle-swift.git",
|
|
27
|
+
requirement: {
|
|
28
|
+
"kind": "branch",
|
|
29
|
+
"branch": "main"
|
|
30
|
+
},
|
|
31
|
+
products: ["Candle"]
|
|
32
|
+
)
|
|
33
|
+
|
|
34
|
+
s.pod_target_xcconfig = {
|
|
35
|
+
# C++ compiler flags, mainly for folly.
|
|
36
|
+
"GCC_PREPROCESSOR_DEFINITIONS" => "$(inherited) FOLLY_NO_CONFIG FOLLY_CFG_NO_COROUTINES"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
load 'nitrogen/generated/ios/ReactNativeCandle+autolinking.rb'
|
|
40
|
+
add_nitrogen_files(s)
|
|
41
|
+
|
|
42
|
+
s.dependency 'React-jsi'
|
|
43
|
+
s.dependency 'React-callinvoker'
|
|
44
|
+
install_modules_dependencies(s)
|
|
45
|
+
end
|
package/app.plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
module.exports = require('./plugin/withIosDeploymentTarget');
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import Candle
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
@available(iOS 17.0, *)
|
|
5
|
+
struct CandleLinkSheetWrapper: View {
|
|
6
|
+
|
|
7
|
+
let candleClient = CandleClient(
|
|
8
|
+
appUser:
|
|
9
|
+
.init(
|
|
10
|
+
appKey: Bundle.main.object(forInfoDictionaryKey: "CandleAppKey") as? String ?? "",
|
|
11
|
+
appSecret: Bundle.main.object(forInfoDictionaryKey: "CandleAppSecret") as? String ?? ""
|
|
12
|
+
)
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
@ObservedObject var viewModel: CandleLinkViewModel
|
|
16
|
+
|
|
17
|
+
init(viewModel: CandleLinkViewModel) {
|
|
18
|
+
self.viewModel = viewModel
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
var body: some View {
|
|
22
|
+
if let service = viewModel.toCandleService {
|
|
23
|
+
Spacer()
|
|
24
|
+
.candleLinkSheet(
|
|
25
|
+
isPresented: $viewModel.showSheet,
|
|
26
|
+
service: service,
|
|
27
|
+
customerName: viewModel.customerName,
|
|
28
|
+
cornerRadius: viewModel.cornerRadius,
|
|
29
|
+
showSandbox: viewModel.showSandbox,
|
|
30
|
+
showDynamicLoading: viewModel.showDynamicLoading,
|
|
31
|
+
presentationStyle: viewModel.toCandlePresentationStyle,
|
|
32
|
+
presentationBackground: viewModel.toCandlePresentationBackground
|
|
33
|
+
) { newLinkedAccount in
|
|
34
|
+
viewModel.linkedAccount = newLinkedAccount
|
|
35
|
+
}
|
|
36
|
+
.environment(candleClient)
|
|
37
|
+
} else {
|
|
38
|
+
Spacer()
|
|
39
|
+
.candleLinkSheet(
|
|
40
|
+
isPresented: $viewModel.showSheet,
|
|
41
|
+
customerName: viewModel.customerName,
|
|
42
|
+
cornerRadius: viewModel.cornerRadius,
|
|
43
|
+
showSandbox: viewModel.showSandbox,
|
|
44
|
+
showDynamicLoading: viewModel.showDynamicLoading,
|
|
45
|
+
presentationStyle: viewModel.toCandlePresentationStyle,
|
|
46
|
+
presentationBackground: viewModel.toCandlePresentationBackground
|
|
47
|
+
) { newLinkedAccount in
|
|
48
|
+
viewModel.linkedAccount = newLinkedAccount
|
|
49
|
+
}
|
|
50
|
+
.environment(candleClient)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import Candle
|
|
2
|
+
import SwiftUI
|
|
3
|
+
|
|
4
|
+
@available(iOS 17.0, *)
|
|
5
|
+
final class CandleLinkViewModel: ObservableObject {
|
|
6
|
+
|
|
7
|
+
var candleClient: CandleClient?
|
|
8
|
+
|
|
9
|
+
@Published var showSheet = false
|
|
10
|
+
@Published var linkedAccount: Models.LinkedAccount?
|
|
11
|
+
@Published var isPresented: Bool = false
|
|
12
|
+
@Published var service: Service?
|
|
13
|
+
@Published var cornerRadius: Double = 0
|
|
14
|
+
@Published var customerName: String?
|
|
15
|
+
@Published var showSandbox: Bool = false
|
|
16
|
+
@Published var showDynamicLoading: Bool = false
|
|
17
|
+
@Published var presentationBackground: PresentationBackground = .default
|
|
18
|
+
@Published var presentationStyle: PresentationStyle = .fullscreen
|
|
19
|
+
|
|
20
|
+
init() {
|
|
21
|
+
Task { @MainActor in
|
|
22
|
+
self.candleClient = CandleClient(
|
|
23
|
+
appUser:
|
|
24
|
+
.init(
|
|
25
|
+
appKey: Bundle.main.object(forInfoDictionaryKey: "CandleAppKey") as? String ?? "",
|
|
26
|
+
appSecret: Bundle.main.object(forInfoDictionaryKey: "CandleAppSecret") as? String ?? ""
|
|
27
|
+
)
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@available(iOS 17.0, *)
|
|
33
|
+
var toCandlePresentationStyle: Candle.PresentationStyle {
|
|
34
|
+
switch presentationStyle {
|
|
35
|
+
case .fullscreen:
|
|
36
|
+
return .fullScreen
|
|
37
|
+
case .sheet:
|
|
38
|
+
return .sheet
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
var toCandlePresentationBackground: AnyShapeStyle? {
|
|
43
|
+
switch presentationBackground {
|
|
44
|
+
case .default:
|
|
45
|
+
return nil
|
|
46
|
+
case .blur:
|
|
47
|
+
return AnyShapeStyle(Material.regular)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
var toCandleService: Candle.Models.SupportedService? {
|
|
52
|
+
switch service {
|
|
53
|
+
case .apple:
|
|
54
|
+
return .apple
|
|
55
|
+
case .cashApp:
|
|
56
|
+
return .cashApp
|
|
57
|
+
case .demo:
|
|
58
|
+
return .demo
|
|
59
|
+
case .robinhood:
|
|
60
|
+
return .robinhood
|
|
61
|
+
case .venmo:
|
|
62
|
+
return .venmo
|
|
63
|
+
case .none, .default:
|
|
64
|
+
return nil
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import SwiftUI
|
|
2
|
+
import UIKit
|
|
3
|
+
|
|
4
|
+
class HostingViewController<T: View>: UIViewController {
|
|
5
|
+
|
|
6
|
+
let uiView: T
|
|
7
|
+
|
|
8
|
+
init(uiView: T) {
|
|
9
|
+
self.uiView = uiView
|
|
10
|
+
super.init(nibName: nil, bundle: nil)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
required init?(coder: NSCoder) {
|
|
14
|
+
fatalError("init(coder:) has not been implemented")
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
override func viewDidLoad() {
|
|
18
|
+
super.viewDidLoad()
|
|
19
|
+
|
|
20
|
+
setup(withRootView: uiView)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
func setup<Content: View>(withRootView view: Content) {
|
|
24
|
+
self.children.forEach { $0.removeFromParent() }
|
|
25
|
+
self.view.subviews.forEach { $0.removeFromSuperview() }
|
|
26
|
+
let host = HostingWrapper(rootView: view)
|
|
27
|
+
host.add(to: self)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
public class HostingWrapper<Content: View>: UIHostingController<Content> {
|
|
33
|
+
|
|
34
|
+
public func add(to controller: UIViewController) {
|
|
35
|
+
controller.addChild(self)
|
|
36
|
+
controller.view.addSubview(view)
|
|
37
|
+
didMove(toParent: controller)
|
|
38
|
+
view.backgroundColor = .clear
|
|
39
|
+
view.translatesAutoresizingMaskIntoConstraints = false
|
|
40
|
+
NSLayoutConstraint.activate([
|
|
41
|
+
view.leadingAnchor.constraint(equalTo: controller.view.leadingAnchor),
|
|
42
|
+
view.trailingAnchor.constraint(equalTo: controller.view.trailingAnchor),
|
|
43
|
+
view.topAnchor.constraint(equalTo: controller.view.topAnchor),
|
|
44
|
+
view.bottomAnchor.constraint(equalTo: controller.view.bottomAnchor),
|
|
45
|
+
])
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
deinit {
|
|
49
|
+
removeFromParent()
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public override func viewWillLayoutSubviews() {
|
|
53
|
+
super.viewWillLayoutSubviews()
|
|
54
|
+
updateViewConstraints()
|
|
55
|
+
}
|
|
56
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import Candle
|
|
2
|
+
import Combine
|
|
3
|
+
import Foundation
|
|
4
|
+
import NitroModules
|
|
5
|
+
import SwiftUI
|
|
6
|
+
import UIKit
|
|
7
|
+
|
|
8
|
+
@available(iOS 17.0, *)
|
|
9
|
+
final class HybridRNCandle: HybridRNCandleSpec {
|
|
10
|
+
|
|
11
|
+
private let viewModel = CandleLinkViewModel()
|
|
12
|
+
private var rootVC: UIViewController?
|
|
13
|
+
private var cancellables = Set<AnyCancellable>()
|
|
14
|
+
|
|
15
|
+
override init() {
|
|
16
|
+
super.init()
|
|
17
|
+
Task { @MainActor in
|
|
18
|
+
setup()
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// MARK: - UI
|
|
23
|
+
|
|
24
|
+
public func candleLinkSheet(
|
|
25
|
+
isPresented: Bool,
|
|
26
|
+
service: Service,
|
|
27
|
+
cornerRadius: Double,
|
|
28
|
+
customerName: String?,
|
|
29
|
+
showSandbox: Bool,
|
|
30
|
+
showDynamicLoading: Bool,
|
|
31
|
+
presentationBackground: PresentationBackground,
|
|
32
|
+
presentationStyle: PresentationStyle,
|
|
33
|
+
onSuccess: @escaping (String) -> Void
|
|
34
|
+
) throws {
|
|
35
|
+
Task { @MainActor in
|
|
36
|
+
viewModel.isPresented = isPresented
|
|
37
|
+
viewModel.service = service
|
|
38
|
+
viewModel.cornerRadius = cornerRadius
|
|
39
|
+
viewModel.customerName = customerName
|
|
40
|
+
viewModel.showSandbox = showSandbox
|
|
41
|
+
viewModel.showDynamicLoading = showDynamicLoading
|
|
42
|
+
viewModel.presentationBackground = presentationBackground
|
|
43
|
+
viewModel.presentationStyle = presentationStyle
|
|
44
|
+
viewModel.showSheet = isPresented
|
|
45
|
+
viewModel.$linkedAccount
|
|
46
|
+
.receive(on: RunLoop.main)
|
|
47
|
+
.sink { [weak self] linkedAccount in
|
|
48
|
+
guard let account = try? self?.encodeToJSONString(linkedAccount) else {
|
|
49
|
+
return
|
|
50
|
+
}
|
|
51
|
+
onSuccess(account)
|
|
52
|
+
}
|
|
53
|
+
.store(in: &cancellables)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// MARK: - Public
|
|
58
|
+
|
|
59
|
+
public func unlinkAccount(linkedAccountID: String) throws -> Promise<Void> {
|
|
60
|
+
Promise.async {
|
|
61
|
+
try await self.viewModel.candleClient?.unlinkAccount(linkedAccountID: linkedAccountID)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
public func getLinkedAccounts() throws -> NitroModules.Promise<String> {
|
|
66
|
+
Promise.async {
|
|
67
|
+
let accounts = try await self.viewModel.candleClient?.getLinkedAccounts() ?? []
|
|
68
|
+
return try self.encodeToJSONString(accounts)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
public func getFiatAccounts() throws -> NitroModules.Promise<String> {
|
|
73
|
+
.async {
|
|
74
|
+
let accounts = try await self.viewModel.candleClient?.getFiatAccounts() ?? []
|
|
75
|
+
return try self.encodeToJSONString(accounts)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
public func getActivity(span: String?) throws -> NitroModules.Promise<String> {
|
|
80
|
+
.async {
|
|
81
|
+
let activity =
|
|
82
|
+
try await self.viewModel.candleClient?.getActivity(query: .init(span: span)) ?? []
|
|
83
|
+
return try self.encodeToJSONString(activity)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
public func deleteUser() throws -> NitroModules.Promise<Void> {
|
|
88
|
+
.async {
|
|
89
|
+
try await self.viewModel.candleClient?.deleteUser()
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
public func getAvailableTools() throws -> NitroModules.Promise<String> {
|
|
94
|
+
.async {
|
|
95
|
+
let result = await self.viewModel.candleClient?.getAvailableTools()
|
|
96
|
+
if let result,
|
|
97
|
+
let data = try? JSONSerialization.data(withJSONObject: result, options: []),
|
|
98
|
+
let string = String(data: data, encoding: .utf8)
|
|
99
|
+
{
|
|
100
|
+
return string
|
|
101
|
+
}
|
|
102
|
+
throw RNClientError.badEncoding
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
public func executeTool(tool: ToolCall) throws -> NitroModules.Promise<String> {
|
|
107
|
+
.async {
|
|
108
|
+
let result = await self.viewModel.candleClient?.executeTool(
|
|
109
|
+
tool: RNToolCall(name: tool.name, arguments: tool.arguments)
|
|
110
|
+
)
|
|
111
|
+
return try self.encodeToJSONString(result)
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// MARK: - Private
|
|
116
|
+
|
|
117
|
+
@MainActor
|
|
118
|
+
@available(iOS 17.0, *)
|
|
119
|
+
private func setup() {
|
|
120
|
+
let wrapperView = CandleLinkSheetWrapper(viewModel: viewModel)
|
|
121
|
+
let hostingVC = HostingViewController(uiView: wrapperView)
|
|
122
|
+
self.rootVC = hostingVC
|
|
123
|
+
guard let rootViewController = UIApplication.keyWindow?.rootViewController,
|
|
124
|
+
let view = rootViewController.view,
|
|
125
|
+
let rootView = view.subviews.first
|
|
126
|
+
else {
|
|
127
|
+
fatalError("No root vc :(")
|
|
128
|
+
}
|
|
129
|
+
view.insertSubview(hostingVC.view, belowSubview: rootView)
|
|
130
|
+
hostingVC.view.translatesAutoresizingMaskIntoConstraints = false
|
|
131
|
+
NSLayoutConstraint.activate([
|
|
132
|
+
hostingVC.view.heightAnchor.constraint(equalTo: view.heightAnchor),
|
|
133
|
+
hostingVC.view.widthAnchor.constraint(equalTo: view.widthAnchor),
|
|
134
|
+
hostingVC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
|
|
135
|
+
hostingVC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
|
|
136
|
+
])
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
enum RNClientError: Error {
|
|
140
|
+
case badEncoding
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
struct RNToolCall: ToolCallRequest, Codable {
|
|
144
|
+
let name: String
|
|
145
|
+
let arguments: String
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
private func encodeToJSONString<T: Encodable>(_ value: T) throws -> String {
|
|
149
|
+
let data = try JSONEncoder().encode(value)
|
|
150
|
+
if let string = String(data: data, encoding: .utf8) {
|
|
151
|
+
return string
|
|
152
|
+
}
|
|
153
|
+
throw RNClientError.badEncoding
|
|
154
|
+
}
|
|
155
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import UIKit
|
|
2
|
+
|
|
3
|
+
extension UIApplication {
|
|
4
|
+
/// Returns the current key window if available.
|
|
5
|
+
@MainActor
|
|
6
|
+
static var keyWindow: UIWindow? {
|
|
7
|
+
UIApplication
|
|
8
|
+
.shared
|
|
9
|
+
.connectedScenes
|
|
10
|
+
.compactMap { $0 as? UIWindowScene }
|
|
11
|
+
.flatMap { $0.windows }
|
|
12
|
+
.first { $0.isKeyWindow }
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.deleteUser = deleteUser;
|
|
7
|
+
exports.executeTool = executeTool;
|
|
8
|
+
exports.getActivity = getActivity;
|
|
9
|
+
exports.getAvailableTools = getAvailableTools;
|
|
10
|
+
exports.getFiatAccounts = getFiatAccounts;
|
|
11
|
+
exports.getLinkedAccounts = getLinkedAccounts;
|
|
12
|
+
exports.presentCandleLinkSheet = presentCandleLinkSheet;
|
|
13
|
+
exports.unlinkAccount = unlinkAccount;
|
|
14
|
+
var _reactNativeNitroModules = require("react-native-nitro-modules");
|
|
15
|
+
const CandleHybridObject = _reactNativeNitroModules.NitroModules.createHybridObject("RNCandle");
|
|
16
|
+
function presentCandleLinkSheet({
|
|
17
|
+
service = "default",
|
|
18
|
+
cornerRadius = 24,
|
|
19
|
+
customerName,
|
|
20
|
+
showSandbox = false,
|
|
21
|
+
showDynamicLoading = true,
|
|
22
|
+
presentationBackground = "default",
|
|
23
|
+
presentationStyle = "sheet",
|
|
24
|
+
onSuccess
|
|
25
|
+
}) {
|
|
26
|
+
CandleHybridObject.candleLinkSheet(true, service, cornerRadius, customerName, showSandbox, showDynamicLoading, presentationBackground, presentationStyle, onSuccess);
|
|
27
|
+
}
|
|
28
|
+
async function unlinkAccount(linkedAccountID) {
|
|
29
|
+
await CandleHybridObject.unlinkAccount(linkedAccountID);
|
|
30
|
+
}
|
|
31
|
+
async function getLinkedAccounts() {
|
|
32
|
+
return await CandleHybridObject.getLinkedAccounts();
|
|
33
|
+
}
|
|
34
|
+
async function getFiatAccounts() {
|
|
35
|
+
return await CandleHybridObject.getFiatAccounts();
|
|
36
|
+
}
|
|
37
|
+
async function getActivity(span) {
|
|
38
|
+
return await CandleHybridObject.getActivity(span);
|
|
39
|
+
}
|
|
40
|
+
async function deleteUser() {
|
|
41
|
+
await CandleHybridObject.deleteUser();
|
|
42
|
+
}
|
|
43
|
+
async function getAvailableTools() {
|
|
44
|
+
return await CandleHybridObject.getAvailableTools();
|
|
45
|
+
}
|
|
46
|
+
async function executeTool(tool) {
|
|
47
|
+
return await CandleHybridObject.executeTool(tool);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_reactNativeNitroModules","require","CandleHybridObject","NitroModules","createHybridObject","presentCandleLinkSheet","service","cornerRadius","customerName","showSandbox","showDynamicLoading","presentationBackground","presentationStyle","onSuccess","candleLinkSheet","unlinkAccount","linkedAccountID","getLinkedAccounts","getFiatAccounts","getActivity","span","deleteUser","getAvailableTools","executeTool","tool"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;;;;;;;;;;;;AAAA,IAAAA,wBAAA,GAAAC,OAAA;AAQA,MAAMC,kBAAkB,GACtBC,qCAAY,CAACC,kBAAkB,CAAW,UAAU,CAAC;AAEhD,SAASC,sBAAsBA,CAAC;EACrCC,OAAO,GAAG,SAAS;EACnBC,YAAY,GAAG,EAAE;EACjBC,YAAY;EACZC,WAAW,GAAG,KAAK;EACnBC,kBAAkB,GAAG,IAAI;EACzBC,sBAAsB,GAAG,SAAS;EAClCC,iBAAiB,GAAG,OAAO;EAC3BC;AAUF,CAAC,EAAQ;EACPX,kBAAkB,CAACY,eAAe,CAChC,IAAI,EACJR,OAAO,EACPC,YAAY,EACZC,YAAY,EACZC,WAAW,EACXC,kBAAkB,EAClBC,sBAAsB,EACtBC,iBAAiB,EACjBC,SACF,CAAC;AACH;AAEO,eAAeE,aAAaA,CAACC,eAAuB,EAAiB;EAC1E,MAAMd,kBAAkB,CAACa,aAAa,CAACC,eAAe,CAAC;AACzD;AAEO,eAAeC,iBAAiBA,CAAA,EAAoB;EACzD,OAAO,MAAMf,kBAAkB,CAACe,iBAAiB,CAAC,CAAC;AACrD;AAEO,eAAeC,eAAeA,CAAA,EAAoB;EACvD,OAAO,MAAMhB,kBAAkB,CAACgB,eAAe,CAAC,CAAC;AACnD;AAEO,eAAeC,WAAWA,CAACC,IAAa,EAAmB;EAChE,OAAO,MAAMlB,kBAAkB,CAACiB,WAAW,CAACC,IAAI,CAAC;AACnD;AAEO,eAAeC,UAAUA,CAAA,EAAkB;EAChD,MAAMnB,kBAAkB,CAACmB,UAAU,CAAC,CAAC;AACvC;AAEO,eAAeC,iBAAiBA,CAAA,EAAoB;EACzD,OAAO,MAAMpB,kBAAkB,CAACoB,iBAAiB,CAAC,CAAC;AACrD;AAEO,eAAeC,WAAWA,CAACC,IAGjC,EAAmB;EAClB,OAAO,MAAMtB,kBAAkB,CAACqB,WAAW,CAACC,IAAI,CAAC;AACnD","ignoreList":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../../src","sources":["specs/RNCandle.nitro.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import { NitroModules } from "react-native-nitro-modules";
|
|
4
|
+
const CandleHybridObject = NitroModules.createHybridObject("RNCandle");
|
|
5
|
+
export function presentCandleLinkSheet({
|
|
6
|
+
service = "default",
|
|
7
|
+
cornerRadius = 24,
|
|
8
|
+
customerName,
|
|
9
|
+
showSandbox = false,
|
|
10
|
+
showDynamicLoading = true,
|
|
11
|
+
presentationBackground = "default",
|
|
12
|
+
presentationStyle = "sheet",
|
|
13
|
+
onSuccess
|
|
14
|
+
}) {
|
|
15
|
+
CandleHybridObject.candleLinkSheet(true, service, cornerRadius, customerName, showSandbox, showDynamicLoading, presentationBackground, presentationStyle, onSuccess);
|
|
16
|
+
}
|
|
17
|
+
export async function unlinkAccount(linkedAccountID) {
|
|
18
|
+
await CandleHybridObject.unlinkAccount(linkedAccountID);
|
|
19
|
+
}
|
|
20
|
+
export async function getLinkedAccounts() {
|
|
21
|
+
return await CandleHybridObject.getLinkedAccounts();
|
|
22
|
+
}
|
|
23
|
+
export async function getFiatAccounts() {
|
|
24
|
+
return await CandleHybridObject.getFiatAccounts();
|
|
25
|
+
}
|
|
26
|
+
export async function getActivity(span) {
|
|
27
|
+
return await CandleHybridObject.getActivity(span);
|
|
28
|
+
}
|
|
29
|
+
export async function deleteUser() {
|
|
30
|
+
await CandleHybridObject.deleteUser();
|
|
31
|
+
}
|
|
32
|
+
export async function getAvailableTools() {
|
|
33
|
+
return await CandleHybridObject.getAvailableTools();
|
|
34
|
+
}
|
|
35
|
+
export async function executeTool(tool) {
|
|
36
|
+
return await CandleHybridObject.executeTool(tool);
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["NitroModules","CandleHybridObject","createHybridObject","presentCandleLinkSheet","service","cornerRadius","customerName","showSandbox","showDynamicLoading","presentationBackground","presentationStyle","onSuccess","candleLinkSheet","unlinkAccount","linkedAccountID","getLinkedAccounts","getFiatAccounts","getActivity","span","deleteUser","getAvailableTools","executeTool","tool"],"sourceRoot":"../../src","sources":["index.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;AAQzD,MAAMC,kBAAkB,GACtBD,YAAY,CAACE,kBAAkB,CAAW,UAAU,CAAC;AAEvD,OAAO,SAASC,sBAAsBA,CAAC;EACrCC,OAAO,GAAG,SAAS;EACnBC,YAAY,GAAG,EAAE;EACjBC,YAAY;EACZC,WAAW,GAAG,KAAK;EACnBC,kBAAkB,GAAG,IAAI;EACzBC,sBAAsB,GAAG,SAAS;EAClCC,iBAAiB,GAAG,OAAO;EAC3BC;AAUF,CAAC,EAAQ;EACPV,kBAAkB,CAACW,eAAe,CAChC,IAAI,EACJR,OAAO,EACPC,YAAY,EACZC,YAAY,EACZC,WAAW,EACXC,kBAAkB,EAClBC,sBAAsB,EACtBC,iBAAiB,EACjBC,SACF,CAAC;AACH;AAEA,OAAO,eAAeE,aAAaA,CAACC,eAAuB,EAAiB;EAC1E,MAAMb,kBAAkB,CAACY,aAAa,CAACC,eAAe,CAAC;AACzD;AAEA,OAAO,eAAeC,iBAAiBA,CAAA,EAAoB;EACzD,OAAO,MAAMd,kBAAkB,CAACc,iBAAiB,CAAC,CAAC;AACrD;AAEA,OAAO,eAAeC,eAAeA,CAAA,EAAoB;EACvD,OAAO,MAAMf,kBAAkB,CAACe,eAAe,CAAC,CAAC;AACnD;AAEA,OAAO,eAAeC,WAAWA,CAACC,IAAa,EAAmB;EAChE,OAAO,MAAMjB,kBAAkB,CAACgB,WAAW,CAACC,IAAI,CAAC;AACnD;AAEA,OAAO,eAAeC,UAAUA,CAAA,EAAkB;EAChD,MAAMlB,kBAAkB,CAACkB,UAAU,CAAC,CAAC;AACvC;AAEA,OAAO,eAAeC,iBAAiBA,CAAA,EAAoB;EACzD,OAAO,MAAMnB,kBAAkB,CAACmB,iBAAiB,CAAC,CAAC;AACrD;AAEA,OAAO,eAAeC,WAAWA,CAACC,IAGjC,EAAmB;EAClB,OAAO,MAAMrB,kBAAkB,CAACoB,WAAW,CAACC,IAAI,CAAC;AACnD","ignoreList":[]}
|