@openzeppelin/adapter-stellar 1.0.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 +272 -0
- package/dist/config.cjs +21 -0
- package/dist/config.cjs.map +1 -0
- package/dist/config.d.cts +8 -0
- package/dist/config.d.cts.map +1 -0
- package/dist/config.d.mts +8 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +20 -0
- package/dist/config.mjs.map +1 -0
- package/dist/index.cjs +7564 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +261 -0
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.mts +263 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +7529 -0
- package/dist/index.mjs.map +1 -0
- package/dist/metadata.cjs +22 -0
- package/dist/metadata.cjs.map +1 -0
- package/dist/metadata.d.cts +7 -0
- package/dist/metadata.d.cts.map +1 -0
- package/dist/metadata.d.mts +7 -0
- package/dist/metadata.d.mts.map +1 -0
- package/dist/metadata.mjs +21 -0
- package/dist/metadata.mjs.map +1 -0
- package/dist/networks-BrV516-R.d.cts +15 -0
- package/dist/networks-BrV516-R.d.cts.map +1 -0
- package/dist/networks-C0MmhJcu.d.mts +15 -0
- package/dist/networks-C0MmhJcu.d.mts.map +1 -0
- package/dist/networks-DgUFSTiC.cjs +76 -0
- package/dist/networks-DgUFSTiC.cjs.map +1 -0
- package/dist/networks-QbEPbaGT.mjs +46 -0
- package/dist/networks-QbEPbaGT.mjs.map +1 -0
- package/dist/networks.cjs +8 -0
- package/dist/networks.d.cts +2 -0
- package/dist/networks.d.mts +2 -0
- package/dist/networks.mjs +3 -0
- package/dist/vite-config.cjs +43 -0
- package/dist/vite-config.cjs.map +1 -0
- package/dist/vite-config.d.cts +35 -0
- package/dist/vite-config.d.cts.map +1 -0
- package/dist/vite-config.d.mts +35 -0
- package/dist/vite-config.d.mts.map +1 -0
- package/dist/vite-config.mjs +42 -0
- package/dist/vite-config.mjs.map +1 -0
- package/package.json +114 -0
- package/src/__tests__/getDefaultServiceConfig.test.ts +105 -0
- package/src/access-control/actions.ts +214 -0
- package/src/access-control/feature-detection.ts +238 -0
- package/src/access-control/index.ts +54 -0
- package/src/access-control/indexer-client.ts +1474 -0
- package/src/access-control/onchain-reader.ts +446 -0
- package/src/access-control/service.ts +1431 -0
- package/src/access-control/validation.ts +256 -0
- package/src/adapter.ts +659 -0
- package/src/config.ts +43 -0
- package/src/configuration/__tests__/explorer.test.ts +80 -0
- package/src/configuration/__tests__/rpc.test.ts +355 -0
- package/src/configuration/execution.ts +83 -0
- package/src/configuration/explorer.ts +105 -0
- package/src/configuration/index.ts +5 -0
- package/src/configuration/network-services.ts +210 -0
- package/src/configuration/rpc.ts +270 -0
- package/src/configuration.ts +2 -0
- package/src/contract/__tests__/complete-type-coverage.test.ts +78 -0
- package/src/contract/index.ts +3 -0
- package/src/contract/loader.ts +498 -0
- package/src/contract/transformer.ts +1 -0
- package/src/contract/type.ts +65 -0
- package/src/index.ts +23 -0
- package/src/mapping/constants.ts +89 -0
- package/src/mapping/enum-metadata.ts +237 -0
- package/src/mapping/field-generator.ts +296 -0
- package/src/mapping/index.ts +5 -0
- package/src/mapping/struct-fields.ts +106 -0
- package/src/mapping/tuple-components.ts +43 -0
- package/src/mapping/type-coverage-validator.ts +151 -0
- package/src/mapping/type-mapper.ts +203 -0
- package/src/metadata.ts +16 -0
- package/src/networks/README.md +84 -0
- package/src/networks/index.ts +19 -0
- package/src/networks/mainnet.ts +20 -0
- package/src/networks/testnet.ts +20 -0
- package/src/networks.ts +2 -0
- package/src/query/handler.ts +411 -0
- package/src/query/index.ts +4 -0
- package/src/query/view-checker.ts +32 -0
- package/src/sac/spec-cache.ts +68 -0
- package/src/sac/spec-source.ts +35 -0
- package/src/sac/xdr.ts +101 -0
- package/src/transaction/components/AdvancedInfo.tsx +34 -0
- package/src/transaction/components/FeeConfiguration.tsx +41 -0
- package/src/transaction/components/StellarRelayerOptions.tsx +60 -0
- package/src/transaction/components/TransactionTiming.tsx +77 -0
- package/src/transaction/components/index.ts +5 -0
- package/src/transaction/components/useStellarRelayerOptions.ts +114 -0
- package/src/transaction/eoa.ts +229 -0
- package/src/transaction/execution-strategy.ts +33 -0
- package/src/transaction/formatter.ts +296 -0
- package/src/transaction/index.ts +4 -0
- package/src/transaction/relayer.ts +575 -0
- package/src/transaction/sender.ts +156 -0
- package/src/transform/index.ts +4 -0
- package/src/transform/input-parser.ts +9 -0
- package/src/transform/output-formatter.ts +133 -0
- package/src/transform/parsers/complex-parser.ts +157 -0
- package/src/transform/parsers/generic-parser.ts +171 -0
- package/src/transform/parsers/index.ts +86 -0
- package/src/transform/parsers/primitive-parser.ts +123 -0
- package/src/transform/parsers/scval-converter.ts +405 -0
- package/src/transform/parsers/struct-parser.ts +324 -0
- package/src/transform/parsers/types.ts +35 -0
- package/src/types/__tests__/artifacts.test.ts +89 -0
- package/src/types/artifacts.ts +19 -0
- package/src/utils/__tests__/artifacts.test.ts +77 -0
- package/src/utils/artifacts.ts +30 -0
- package/src/utils/formatting.ts +122 -0
- package/src/utils/index.ts +6 -0
- package/src/utils/input-parsing.ts +336 -0
- package/src/utils/safe-type-parser.ts +303 -0
- package/src/utils/stellar-types.ts +35 -0
- package/src/utils/type-detection.ts +163 -0
- package/src/utils/xdr-ordering.ts +36 -0
- package/src/validation/__tests__/address.test.ts +267 -0
- package/src/validation/address.ts +136 -0
- package/src/validation/eoa.ts +33 -0
- package/src/validation/index.ts +3 -0
- package/src/validation/relayer.ts +13 -0
- package/src/vite-config.ts +67 -0
- package/src/wallet/README.md +93 -0
- package/src/wallet/__tests__/connection.test.ts +72 -0
- package/src/wallet/components/StellarWalletUiRoot.tsx +161 -0
- package/src/wallet/components/account/AccountDisplay.tsx +50 -0
- package/src/wallet/components/connect/ConnectButton.tsx +100 -0
- package/src/wallet/components/connect/ConnectorDialog.tsx +125 -0
- package/src/wallet/components/index.ts +3 -0
- package/src/wallet/connection.ts +151 -0
- package/src/wallet/context/StellarWalletContext.ts +32 -0
- package/src/wallet/context/index.ts +4 -0
- package/src/wallet/context/useStellarWalletContext.ts +17 -0
- package/src/wallet/hooks/facade-hooks.ts +31 -0
- package/src/wallet/hooks/index.ts +7 -0
- package/src/wallet/hooks/useStellarAccount.ts +27 -0
- package/src/wallet/hooks/useStellarConnect.ts +60 -0
- package/src/wallet/hooks/useStellarDisconnect.ts +47 -0
- package/src/wallet/hooks/useUiKitConfig.ts +40 -0
- package/src/wallet/implementation/wallets-kit-implementation.ts +379 -0
- package/src/wallet/index.ts +11 -0
- package/src/wallet/services/__tests__/configResolutionService.test.ts +163 -0
- package/src/wallet/services/configResolutionService.ts +65 -0
- package/src/wallet/stellar-wallets-kit/StellarWalletsKitConnectButton.tsx +82 -0
- package/src/wallet/stellar-wallets-kit/__mocks__/@creit.tech/stellar-wallets-kit.ts +48 -0
- package/src/wallet/stellar-wallets-kit/__tests__/export-service.test.ts +93 -0
- package/src/wallet/stellar-wallets-kit/__tests__/stellarUiKitManager.test.ts +0 -0
- package/src/wallet/stellar-wallets-kit/config-generator.ts +75 -0
- package/src/wallet/stellar-wallets-kit/export-service.ts +19 -0
- package/src/wallet/stellar-wallets-kit/index.ts +3 -0
- package/src/wallet/stellar-wallets-kit/stellarUiKitManager.ts +235 -0
- package/src/wallet/types.ts +19 -0
- package/src/wallet/utils/__tests__/filterWalletComponents.test.ts +150 -0
- package/src/wallet/utils/__tests__/uiKitService.test.ts +189 -0
- package/src/wallet/utils/filterWalletComponents.ts +89 -0
- package/src/wallet/utils/index.ts +3 -0
- package/src/wallet/utils/stellarWalletImplementationManager.ts +118 -0
- package/src/wallet/utils/uiKitService.ts +74 -0
package/src/adapter.ts
ADDED
|
@@ -0,0 +1,659 @@
|
|
|
1
|
+
import type React from 'react';
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
AccessControlService,
|
|
5
|
+
AvailableUiKit,
|
|
6
|
+
Connector,
|
|
7
|
+
ContractAdapter,
|
|
8
|
+
ContractFunction,
|
|
9
|
+
ContractSchema,
|
|
10
|
+
EcosystemReactUiProviderProps,
|
|
11
|
+
EcosystemSpecificReactHooks,
|
|
12
|
+
EcosystemWalletComponents,
|
|
13
|
+
ExecutionConfig,
|
|
14
|
+
ExecutionMethodDetail,
|
|
15
|
+
FieldType,
|
|
16
|
+
FormFieldType,
|
|
17
|
+
FunctionParameter,
|
|
18
|
+
NativeConfigLoader,
|
|
19
|
+
NetworkServiceForm,
|
|
20
|
+
RelayerDetails,
|
|
21
|
+
RelayerDetailsRich,
|
|
22
|
+
StellarNetworkConfig,
|
|
23
|
+
TransactionStatusUpdate,
|
|
24
|
+
TxStatus,
|
|
25
|
+
TypeMappingInfo,
|
|
26
|
+
UiKitConfiguration,
|
|
27
|
+
UserRpcProviderConfig,
|
|
28
|
+
WalletConnectionStatus,
|
|
29
|
+
} from '@openzeppelin/ui-types';
|
|
30
|
+
import { isStellarNetworkConfig } from '@openzeppelin/ui-types';
|
|
31
|
+
import { logger } from '@openzeppelin/ui-utils';
|
|
32
|
+
|
|
33
|
+
import { getCurrentLedger } from './access-control/onchain-reader';
|
|
34
|
+
import { createStellarAccessControlService } from './access-control/service';
|
|
35
|
+
import {
|
|
36
|
+
getStellarDefaultServiceConfig,
|
|
37
|
+
getStellarNetworkServiceForms,
|
|
38
|
+
testStellarNetworkServiceConnection,
|
|
39
|
+
validateStellarNetworkServiceConfig,
|
|
40
|
+
} from './configuration/network-services';
|
|
41
|
+
// Import functions from modules
|
|
42
|
+
import { loadStellarContract, loadStellarContractWithMetadata } from './contract/loader';
|
|
43
|
+
import { StellarRelayerOptions } from './transaction/components';
|
|
44
|
+
import { RelayerExecutionStrategy } from './transaction/relayer';
|
|
45
|
+
|
|
46
|
+
import {
|
|
47
|
+
getStellarExplorerAddressUrl,
|
|
48
|
+
getStellarExplorerTxUrl,
|
|
49
|
+
getStellarSupportedExecutionMethods,
|
|
50
|
+
testStellarRpcConnection,
|
|
51
|
+
validateStellarExecutionConfig,
|
|
52
|
+
validateStellarRpcEndpoint,
|
|
53
|
+
} from './configuration';
|
|
54
|
+
import {
|
|
55
|
+
generateStellarDefaultField,
|
|
56
|
+
getStellarCompatibleFieldTypes,
|
|
57
|
+
getStellarTypeMappingInfo,
|
|
58
|
+
mapStellarParameterTypeToFieldType,
|
|
59
|
+
} from './mapping';
|
|
60
|
+
import {
|
|
61
|
+
getStellarWritableFunctions,
|
|
62
|
+
isStellarViewFunction,
|
|
63
|
+
queryStellarViewFunction,
|
|
64
|
+
} from './query';
|
|
65
|
+
import { formatStellarTransactionData, signAndBroadcastStellarTransaction } from './transaction';
|
|
66
|
+
import { formatStellarFunctionResult } from './transform';
|
|
67
|
+
import { validateAndConvertStellarArtifacts } from './utils';
|
|
68
|
+
import { isValidAddress as isStellarValidAddress, type StellarAddressType } from './validation';
|
|
69
|
+
import {
|
|
70
|
+
connectStellarWallet,
|
|
71
|
+
disconnectStellarWallet,
|
|
72
|
+
generateStellarWalletsKitExportables,
|
|
73
|
+
getInitializedStellarWalletImplementation,
|
|
74
|
+
getResolvedWalletComponents,
|
|
75
|
+
getStellarAvailableConnectors,
|
|
76
|
+
getStellarWalletImplementation,
|
|
77
|
+
loadInitialConfigFromAppService,
|
|
78
|
+
resolveFullUiKitConfiguration,
|
|
79
|
+
stellarFacadeHooks,
|
|
80
|
+
stellarUiKitManager,
|
|
81
|
+
StellarWalletConnectionStatus,
|
|
82
|
+
StellarWalletUiRoot,
|
|
83
|
+
supportsStellarWalletConnection,
|
|
84
|
+
} from './wallet';
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Stellar-specific adapter implementation using explicit method delegation.
|
|
88
|
+
*/
|
|
89
|
+
export class StellarAdapter implements ContractAdapter {
|
|
90
|
+
readonly networkConfig: StellarNetworkConfig;
|
|
91
|
+
readonly initialAppServiceKitName: UiKitConfiguration['kitName'];
|
|
92
|
+
private readonly accessControlService: AccessControlService;
|
|
93
|
+
|
|
94
|
+
constructor(networkConfig: StellarNetworkConfig) {
|
|
95
|
+
if (!isStellarNetworkConfig(networkConfig)) {
|
|
96
|
+
throw new Error('StellarAdapter requires a valid Stellar network configuration.');
|
|
97
|
+
}
|
|
98
|
+
this.networkConfig = networkConfig;
|
|
99
|
+
|
|
100
|
+
// Initialize Access Control Service
|
|
101
|
+
this.accessControlService = createStellarAccessControlService(networkConfig);
|
|
102
|
+
|
|
103
|
+
// Set the network config in the wallet UI kit manager
|
|
104
|
+
stellarUiKitManager.setNetworkConfig(networkConfig);
|
|
105
|
+
|
|
106
|
+
// Initialize wallet implementation with network config
|
|
107
|
+
getStellarWalletImplementation(networkConfig).catch((error) => {
|
|
108
|
+
logger.error(
|
|
109
|
+
'StellarAdapter:constructor',
|
|
110
|
+
'Failed to initialize wallet implementation:',
|
|
111
|
+
error
|
|
112
|
+
);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// Determine the initial kitName from AppConfigService at the time of adapter construction.
|
|
116
|
+
// This provides a baseline kitName preference from the application's static/global configuration.
|
|
117
|
+
// It defaults to 'custom' if no specific kitName is found in AppConfigService.
|
|
118
|
+
const initialGlobalConfig = loadInitialConfigFromAppService();
|
|
119
|
+
this.initialAppServiceKitName =
|
|
120
|
+
(initialGlobalConfig.kitName as UiKitConfiguration['kitName']) || 'custom';
|
|
121
|
+
|
|
122
|
+
logger.info(
|
|
123
|
+
'StellarAdapter:constructor',
|
|
124
|
+
'Initial kitName from AppConfigService noted:',
|
|
125
|
+
this.initialAppServiceKitName
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
logger.info(
|
|
129
|
+
'StellarAdapter',
|
|
130
|
+
`Adapter initialized for network: ${networkConfig.name} (ID: ${networkConfig.id})`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* @inheritdoc
|
|
136
|
+
*/
|
|
137
|
+
public getNetworkServiceForms(): NetworkServiceForm[] {
|
|
138
|
+
return getStellarNetworkServiceForms();
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* @inheritdoc
|
|
143
|
+
*/
|
|
144
|
+
public async validateNetworkServiceConfig(
|
|
145
|
+
serviceId: string,
|
|
146
|
+
values: Record<string, unknown>
|
|
147
|
+
): Promise<boolean> {
|
|
148
|
+
return validateStellarNetworkServiceConfig(serviceId, values);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* @inheritdoc
|
|
153
|
+
*/
|
|
154
|
+
public async testNetworkServiceConnection(
|
|
155
|
+
serviceId: string,
|
|
156
|
+
values: Record<string, unknown>
|
|
157
|
+
): Promise<{ success: boolean; latency?: number; error?: string }> {
|
|
158
|
+
return testStellarNetworkServiceConnection(serviceId, values);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* @inheritdoc
|
|
163
|
+
*/
|
|
164
|
+
public getDefaultServiceConfig(serviceId: string): Record<string, unknown> | null {
|
|
165
|
+
return getStellarDefaultServiceConfig(this.networkConfig, serviceId);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* NOTE about artifact inputs (single input with auto-detection):
|
|
170
|
+
*
|
|
171
|
+
* The Builder renders the contract definition step using whatever fields the
|
|
172
|
+
* adapter returns here. EVM uses one optional ABI field; Midnight provides
|
|
173
|
+
* multiple fields. Stellar should use a single input approach with automatic
|
|
174
|
+
* content detection when we add manual-spec support:
|
|
175
|
+
*
|
|
176
|
+
* - Keep `contractAddress` (required)
|
|
177
|
+
* - Add optional `contractDefinition` (type: `code-editor`, language: `json`)
|
|
178
|
+
* with file upload support for both JSON and Wasm binary content
|
|
179
|
+
*
|
|
180
|
+
* When this field is added:
|
|
181
|
+
* - Extend `validateAndConvertStellarArtifacts(...)` to accept
|
|
182
|
+
* `{ contractAddress, contractDefinition? }`
|
|
183
|
+
* - In the loader, branch: if `contractDefinition` provided, auto-detect
|
|
184
|
+
* content type (JSON vs Wasm using magic bytes `\0asm`):
|
|
185
|
+
* - For JSON: Parse and validate as Soroban spec, use `transformStellarSpecToSchema`
|
|
186
|
+
* - For Wasm: Extract embedded spec from binary, parse locally (no RPC)
|
|
187
|
+
* - Set `source: 'manual'` with `contractDefinitionOriginal` to the raw
|
|
188
|
+
* user-provided content. This ensures auto-save captures and restores the
|
|
189
|
+
* manual contract definition exactly like the EVM/Midnight flows.
|
|
190
|
+
* - Provide clear UI hints about supported formats (JSON spec or Wasm binary).
|
|
191
|
+
*/
|
|
192
|
+
/**
|
|
193
|
+
* @inheritdoc
|
|
194
|
+
*/
|
|
195
|
+
public getContractDefinitionInputs(): FormFieldType[] {
|
|
196
|
+
return [
|
|
197
|
+
{
|
|
198
|
+
id: 'contractAddress',
|
|
199
|
+
name: 'contractAddress',
|
|
200
|
+
label: 'Contract ID',
|
|
201
|
+
type: 'blockchain-address',
|
|
202
|
+
validation: { required: true },
|
|
203
|
+
placeholder: 'C...',
|
|
204
|
+
helperText: 'Enter the Stellar contract ID (C...).',
|
|
205
|
+
},
|
|
206
|
+
];
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @inheritdoc
|
|
211
|
+
*/
|
|
212
|
+
public async loadContract(source: string | Record<string, unknown>): Promise<ContractSchema> {
|
|
213
|
+
// Convert generic input to Stellar-specific artifacts
|
|
214
|
+
const artifacts = validateAndConvertStellarArtifacts(source);
|
|
215
|
+
const result = await loadStellarContract(artifacts, this.networkConfig);
|
|
216
|
+
return result.schema;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @inheritdoc
|
|
221
|
+
*/
|
|
222
|
+
public async loadContractWithMetadata(source: string | Record<string, unknown>): Promise<{
|
|
223
|
+
schema: ContractSchema;
|
|
224
|
+
source: 'fetched' | 'manual';
|
|
225
|
+
contractDefinitionOriginal?: string;
|
|
226
|
+
metadata?: {
|
|
227
|
+
fetchedFrom?: string;
|
|
228
|
+
contractName?: string;
|
|
229
|
+
fetchTimestamp?: Date;
|
|
230
|
+
definitionHash?: string;
|
|
231
|
+
};
|
|
232
|
+
}> {
|
|
233
|
+
try {
|
|
234
|
+
// Convert generic input to Stellar-specific artifacts
|
|
235
|
+
const artifacts = validateAndConvertStellarArtifacts(source);
|
|
236
|
+
const result = await loadStellarContractWithMetadata(artifacts, this.networkConfig);
|
|
237
|
+
|
|
238
|
+
return {
|
|
239
|
+
schema: result.schema,
|
|
240
|
+
source: result.source,
|
|
241
|
+
contractDefinitionOriginal: result.contractDefinitionOriginal,
|
|
242
|
+
metadata: result.metadata,
|
|
243
|
+
};
|
|
244
|
+
} catch (error) {
|
|
245
|
+
// Re-throw errors consistently with EVM adapter
|
|
246
|
+
throw error;
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* @inheritdoc
|
|
252
|
+
*/
|
|
253
|
+
getWritableFunctions(contractSchema: ContractSchema): ContractSchema['functions'] {
|
|
254
|
+
return getStellarWritableFunctions(contractSchema);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* @inheritdoc
|
|
259
|
+
*/
|
|
260
|
+
mapParameterTypeToFieldType(parameterType: string): FieldType {
|
|
261
|
+
return mapStellarParameterTypeToFieldType(parameterType);
|
|
262
|
+
}
|
|
263
|
+
getCompatibleFieldTypes(parameterType: string): FieldType[] {
|
|
264
|
+
return getStellarCompatibleFieldTypes(parameterType);
|
|
265
|
+
}
|
|
266
|
+
generateDefaultField<T extends FieldType = FieldType>(
|
|
267
|
+
parameter: FunctionParameter,
|
|
268
|
+
contractSchema?: ContractSchema
|
|
269
|
+
): FormFieldType<T> {
|
|
270
|
+
return generateStellarDefaultField(parameter, contractSchema);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/**
|
|
274
|
+
* @inheritdoc
|
|
275
|
+
*/
|
|
276
|
+
public formatTransactionData(
|
|
277
|
+
contractSchema: ContractSchema,
|
|
278
|
+
functionId: string,
|
|
279
|
+
submittedInputs: Record<string, unknown>,
|
|
280
|
+
fields: FormFieldType[]
|
|
281
|
+
): unknown {
|
|
282
|
+
return formatStellarTransactionData(contractSchema, functionId, submittedInputs, fields);
|
|
283
|
+
}
|
|
284
|
+
async signAndBroadcast(
|
|
285
|
+
transactionData: unknown,
|
|
286
|
+
executionConfig: ExecutionConfig,
|
|
287
|
+
onStatusChange: (status: TxStatus, details: TransactionStatusUpdate) => void,
|
|
288
|
+
runtimeApiKey?: string
|
|
289
|
+
): Promise<{ txHash: string }> {
|
|
290
|
+
return signAndBroadcastStellarTransaction(
|
|
291
|
+
transactionData,
|
|
292
|
+
executionConfig,
|
|
293
|
+
this.networkConfig,
|
|
294
|
+
onStatusChange,
|
|
295
|
+
runtimeApiKey
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* @inheritdoc
|
|
301
|
+
*/
|
|
302
|
+
isViewFunction(functionDetails: ContractFunction): boolean {
|
|
303
|
+
return isStellarViewFunction(functionDetails);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* @inheritdoc
|
|
308
|
+
*/
|
|
309
|
+
async queryViewFunction(
|
|
310
|
+
contractAddress: string,
|
|
311
|
+
functionId: string,
|
|
312
|
+
params: unknown[] = [],
|
|
313
|
+
contractSchema?: ContractSchema
|
|
314
|
+
): Promise<unknown> {
|
|
315
|
+
return queryStellarViewFunction(
|
|
316
|
+
contractAddress,
|
|
317
|
+
functionId,
|
|
318
|
+
this.networkConfig,
|
|
319
|
+
params,
|
|
320
|
+
contractSchema,
|
|
321
|
+
(address: string) => this.loadContract({ contractAddress: address })
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* @inheritdoc
|
|
327
|
+
*/
|
|
328
|
+
formatFunctionResult(decodedValue: unknown, functionDetails: ContractFunction): string {
|
|
329
|
+
return formatStellarFunctionResult(decodedValue, functionDetails);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* @inheritdoc
|
|
334
|
+
*/
|
|
335
|
+
supportsWalletConnection(): boolean {
|
|
336
|
+
return supportsStellarWalletConnection();
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* @inheritdoc
|
|
341
|
+
*/
|
|
342
|
+
async getAvailableConnectors(): Promise<Connector[]> {
|
|
343
|
+
return getStellarAvailableConnectors();
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/**
|
|
347
|
+
* @inheritdoc
|
|
348
|
+
*/
|
|
349
|
+
async connectWallet(
|
|
350
|
+
connectorId: string
|
|
351
|
+
): Promise<{ connected: boolean; address?: string; error?: string }> {
|
|
352
|
+
return connectStellarWallet(connectorId);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* @inheritdoc
|
|
357
|
+
*/
|
|
358
|
+
async disconnectWallet(): Promise<{ disconnected: boolean; error?: string }> {
|
|
359
|
+
return disconnectStellarWallet();
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* @inheritdoc
|
|
364
|
+
*/
|
|
365
|
+
getWalletConnectionStatus(): StellarWalletConnectionStatus {
|
|
366
|
+
const impl = getInitializedStellarWalletImplementation();
|
|
367
|
+
if (!impl) {
|
|
368
|
+
return {
|
|
369
|
+
isConnected: false,
|
|
370
|
+
address: undefined,
|
|
371
|
+
chainId: stellarUiKitManager.getState().networkConfig?.id || 'stellar-testnet',
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const stellarStatus = impl.getWalletConnectionStatus();
|
|
376
|
+
|
|
377
|
+
// Return the rich Stellar-specific status directly
|
|
378
|
+
return stellarStatus;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
/**
|
|
382
|
+
* @inheritdoc
|
|
383
|
+
*/
|
|
384
|
+
onWalletConnectionChange(
|
|
385
|
+
callback: (
|
|
386
|
+
currentStatus: WalletConnectionStatus,
|
|
387
|
+
previousStatus: WalletConnectionStatus
|
|
388
|
+
) => void
|
|
389
|
+
): () => void {
|
|
390
|
+
const walletImplementation = getInitializedStellarWalletImplementation();
|
|
391
|
+
if (!walletImplementation) {
|
|
392
|
+
logger.warn(
|
|
393
|
+
'StellarAdapter:onWalletConnectionChange',
|
|
394
|
+
'Wallet implementation not ready. Subscription may not work.'
|
|
395
|
+
);
|
|
396
|
+
return () => {};
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
return walletImplementation.onWalletConnectionChange(
|
|
400
|
+
(currentImplStatus, previousImplStatus) => {
|
|
401
|
+
callback(currentImplStatus, previousImplStatus);
|
|
402
|
+
}
|
|
403
|
+
);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* @inheritdoc
|
|
408
|
+
*/
|
|
409
|
+
async getSupportedExecutionMethods(): Promise<ExecutionMethodDetail[]> {
|
|
410
|
+
return getStellarSupportedExecutionMethods();
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* @inheritdoc
|
|
415
|
+
*/
|
|
416
|
+
async validateExecutionConfig(config: ExecutionConfig): Promise<true | string> {
|
|
417
|
+
const walletStatus = this.getWalletConnectionStatus();
|
|
418
|
+
return validateStellarExecutionConfig(config, walletStatus);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
/**
|
|
422
|
+
* @inheritdoc
|
|
423
|
+
*/
|
|
424
|
+
getExplorerUrl(address: string): string | null {
|
|
425
|
+
return getStellarExplorerAddressUrl(address, this.networkConfig);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* @inheritdoc
|
|
430
|
+
*/
|
|
431
|
+
getExplorerTxUrl?(txHash: string): string | null {
|
|
432
|
+
if (getStellarExplorerTxUrl) {
|
|
433
|
+
return getStellarExplorerTxUrl(txHash, this.networkConfig);
|
|
434
|
+
}
|
|
435
|
+
return null;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* @inheritdoc
|
|
440
|
+
*/
|
|
441
|
+
async getCurrentBlock(): Promise<number> {
|
|
442
|
+
return getCurrentLedger(this.networkConfig);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
/**
|
|
446
|
+
* @inheritdoc
|
|
447
|
+
*/
|
|
448
|
+
isValidAddress(address: string, addressType?: string): boolean {
|
|
449
|
+
return isStellarValidAddress(address, addressType as StellarAddressType);
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* @inheritdoc
|
|
454
|
+
*/
|
|
455
|
+
public async getAvailableUiKits(): Promise<AvailableUiKit[]> {
|
|
456
|
+
return [
|
|
457
|
+
{
|
|
458
|
+
id: 'custom',
|
|
459
|
+
name: 'Stellar Wallets Kit Custom',
|
|
460
|
+
configFields: [],
|
|
461
|
+
},
|
|
462
|
+
{
|
|
463
|
+
id: 'stellar-wallets-kit',
|
|
464
|
+
name: 'Stellar Wallets Kit',
|
|
465
|
+
configFields: [],
|
|
466
|
+
},
|
|
467
|
+
];
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/**
|
|
471
|
+
* @inheritdoc
|
|
472
|
+
*/
|
|
473
|
+
public async configureUiKit(
|
|
474
|
+
programmaticOverrides: Partial<UiKitConfiguration> = {},
|
|
475
|
+
options?: {
|
|
476
|
+
loadUiKitNativeConfig?: NativeConfigLoader;
|
|
477
|
+
}
|
|
478
|
+
): Promise<void> {
|
|
479
|
+
const currentAppServiceConfig = loadInitialConfigFromAppService();
|
|
480
|
+
|
|
481
|
+
// Delegate the entire configuration resolution to the service function
|
|
482
|
+
const finalFullConfig = await resolveFullUiKitConfiguration(
|
|
483
|
+
programmaticOverrides,
|
|
484
|
+
this.initialAppServiceKitName,
|
|
485
|
+
currentAppServiceConfig,
|
|
486
|
+
options
|
|
487
|
+
);
|
|
488
|
+
|
|
489
|
+
// Configure the Stellar UI kit manager
|
|
490
|
+
await stellarUiKitManager.configure(finalFullConfig);
|
|
491
|
+
logger.info(
|
|
492
|
+
'StellarAdapter:configureUiKit',
|
|
493
|
+
'StellarUiKitManager configuration requested with final config:',
|
|
494
|
+
finalFullConfig
|
|
495
|
+
);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
* @inheritdoc
|
|
500
|
+
*/
|
|
501
|
+
public async getExportableWalletConfigFiles(
|
|
502
|
+
uiKitConfig?: UiKitConfiguration
|
|
503
|
+
): Promise<Record<string, string>> {
|
|
504
|
+
if (uiKitConfig?.kitName === 'stellar-wallets-kit') {
|
|
505
|
+
return generateStellarWalletsKitExportables(uiKitConfig);
|
|
506
|
+
}
|
|
507
|
+
return {};
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
/**
|
|
511
|
+
* @inheritdoc
|
|
512
|
+
*/
|
|
513
|
+
public getEcosystemWalletComponents(): EcosystemWalletComponents | undefined {
|
|
514
|
+
const currentManagerState = stellarUiKitManager.getState();
|
|
515
|
+
|
|
516
|
+
// Only attempt to resolve components if the manager has a configuration set
|
|
517
|
+
if (!currentManagerState.currentFullUiKitConfig) {
|
|
518
|
+
logger.debug(
|
|
519
|
+
'StellarAdapter:getEcosystemWalletComponents',
|
|
520
|
+
'No UI kit configuration available in manager yet. Returning undefined components.'
|
|
521
|
+
);
|
|
522
|
+
return undefined;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// Use the service to resolve components based on the current UI kit configuration
|
|
526
|
+
const components = getResolvedWalletComponents(currentManagerState.currentFullUiKitConfig);
|
|
527
|
+
return components;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* @inheritdoc
|
|
532
|
+
*/
|
|
533
|
+
public getEcosystemReactUiContextProvider():
|
|
534
|
+
| React.ComponentType<EcosystemReactUiProviderProps>
|
|
535
|
+
| undefined {
|
|
536
|
+
logger.info(
|
|
537
|
+
'StellarAdapter:getEcosystemReactUiContextProvider',
|
|
538
|
+
'Returning StellarWalletUiRoot.'
|
|
539
|
+
);
|
|
540
|
+
return StellarWalletUiRoot;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* @inheritdoc
|
|
545
|
+
*/
|
|
546
|
+
public getEcosystemReactHooks(): EcosystemSpecificReactHooks | undefined {
|
|
547
|
+
// Always provide hooks for Stellar adapter regardless of UI kit
|
|
548
|
+
return stellarFacadeHooks;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* @inheritdoc
|
|
553
|
+
*/
|
|
554
|
+
public async getRelayers(serviceUrl: string, accessToken: string): Promise<RelayerDetails[]> {
|
|
555
|
+
const relayerStrategy = new RelayerExecutionStrategy();
|
|
556
|
+
try {
|
|
557
|
+
return await relayerStrategy.getStellarRelayers(serviceUrl, accessToken, this.networkConfig);
|
|
558
|
+
} catch (error) {
|
|
559
|
+
logger.error('StellarAdapter', 'Failed to fetch Stellar relayers:', error);
|
|
560
|
+
return Promise.resolve([]);
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* @inheritdoc
|
|
566
|
+
*/
|
|
567
|
+
public async getRelayer(
|
|
568
|
+
serviceUrl: string,
|
|
569
|
+
accessToken: string,
|
|
570
|
+
relayerId: string
|
|
571
|
+
): Promise<RelayerDetailsRich> {
|
|
572
|
+
const relayerStrategy = new RelayerExecutionStrategy();
|
|
573
|
+
try {
|
|
574
|
+
return await relayerStrategy.getStellarRelayer(
|
|
575
|
+
serviceUrl,
|
|
576
|
+
accessToken,
|
|
577
|
+
relayerId,
|
|
578
|
+
this.networkConfig
|
|
579
|
+
);
|
|
580
|
+
} catch (error) {
|
|
581
|
+
logger.error('StellarAdapter', 'Failed to fetch Stellar relayer details:', error);
|
|
582
|
+
return Promise.resolve({} as RelayerDetailsRich);
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* @inheritdoc
|
|
588
|
+
*/
|
|
589
|
+
public getRelayerOptionsComponent():
|
|
590
|
+
| React.ComponentType<{
|
|
591
|
+
options: Record<string, unknown>;
|
|
592
|
+
onChange: (options: Record<string, unknown>) => void;
|
|
593
|
+
}>
|
|
594
|
+
| undefined {
|
|
595
|
+
return StellarRelayerOptions;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
/**
|
|
599
|
+
* @inheritdoc
|
|
600
|
+
*/
|
|
601
|
+
public async validateRpcEndpoint(rpcConfig: UserRpcProviderConfig): Promise<boolean> {
|
|
602
|
+
// TODO: Implement Stellar-specific RPC validation when needed
|
|
603
|
+
return validateStellarRpcEndpoint(rpcConfig);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* @inheritdoc
|
|
608
|
+
*/
|
|
609
|
+
public async testRpcConnection(rpcConfig: UserRpcProviderConfig): Promise<{
|
|
610
|
+
success: boolean;
|
|
611
|
+
latency?: number;
|
|
612
|
+
error?: string;
|
|
613
|
+
}> {
|
|
614
|
+
// TODO: Implement Stellar-specific RPC validation when needed
|
|
615
|
+
return testStellarRpcConnection(rpcConfig);
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* @inheritdoc
|
|
620
|
+
*/
|
|
621
|
+
public getUiLabels(): Record<string, string> | undefined {
|
|
622
|
+
return {
|
|
623
|
+
relayerConfigTitle: 'Transaction Configuration',
|
|
624
|
+
relayerConfigActiveDesc: 'Customize transaction parameters for submission',
|
|
625
|
+
relayerConfigInactiveDesc: 'Using recommended transaction configuration for reliability',
|
|
626
|
+
relayerConfigPresetTitle: 'Recommended Preset Active',
|
|
627
|
+
relayerConfigPresetDesc: 'Transactions will use recommended parameters for quick inclusion',
|
|
628
|
+
relayerConfigCustomizeBtn: 'Customize Settings',
|
|
629
|
+
detailsTitle: 'Relayer Details',
|
|
630
|
+
network: 'Network',
|
|
631
|
+
relayerId: 'Relayer ID',
|
|
632
|
+
active: 'Active',
|
|
633
|
+
paused: 'Paused',
|
|
634
|
+
systemDisabled: 'System Disabled',
|
|
635
|
+
balance: 'Balance',
|
|
636
|
+
// For Stellar, sequence number is conceptually similar; adapters supply the value
|
|
637
|
+
nonce: 'Sequence',
|
|
638
|
+
pending: 'Pending Transactions',
|
|
639
|
+
lastTransaction: 'Last Transaction',
|
|
640
|
+
};
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
/**
|
|
644
|
+
* @inheritdoc
|
|
645
|
+
*/
|
|
646
|
+
public getAccessControlService(): AccessControlService {
|
|
647
|
+
return this.accessControlService;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* @inheritdoc
|
|
652
|
+
*/
|
|
653
|
+
public getTypeMappingInfo(): TypeMappingInfo {
|
|
654
|
+
return getStellarTypeMappingInfo();
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
// Also export as default to ensure compatibility with various import styles
|
|
659
|
+
export default StellarAdapter;
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Configuration for the Stellar adapter
|
|
3
|
+
*
|
|
4
|
+
* This file defines the dependencies required by the Stellar adapter
|
|
5
|
+
* when generating exported projects. It follows the AdapterConfig
|
|
6
|
+
* interface to provide a structured approach to dependency management.
|
|
7
|
+
*/
|
|
8
|
+
import type { AdapterConfig } from '@openzeppelin/ui-types';
|
|
9
|
+
|
|
10
|
+
export const stellarAdapterConfig: AdapterConfig = {
|
|
11
|
+
/**
|
|
12
|
+
* Dependencies required by the Stellar adapter
|
|
13
|
+
* These will be included in exported projects that use this adapter
|
|
14
|
+
*/
|
|
15
|
+
dependencies: {
|
|
16
|
+
// Runtime dependencies
|
|
17
|
+
runtime: {
|
|
18
|
+
// Core Stellar libraries
|
|
19
|
+
'@stellar/stellar-sdk': '^14.1.1',
|
|
20
|
+
|
|
21
|
+
// SAC (Stellar Asset Contract) support - dynamically loaded from CDN
|
|
22
|
+
// These are needed for XDR encoding when working with SAC contracts
|
|
23
|
+
'@stellar/stellar-xdr-json': '^23.0.0',
|
|
24
|
+
'lossless-json': '^4.0.2',
|
|
25
|
+
|
|
26
|
+
// Wallet connection and integration
|
|
27
|
+
'@creit.tech/stellar-wallets-kit': '^1.9.5',
|
|
28
|
+
|
|
29
|
+
// OpenZeppelin Relayer integration for gasless transactions
|
|
30
|
+
'@openzeppelin/relayer-sdk': '1.9.0',
|
|
31
|
+
|
|
32
|
+
// React integration for wallet components
|
|
33
|
+
react: '^19.0.0',
|
|
34
|
+
'react-dom': '^19.0.0',
|
|
35
|
+
},
|
|
36
|
+
|
|
37
|
+
// Development dependencies
|
|
38
|
+
dev: {
|
|
39
|
+
'@types/react': '^19.0.0',
|
|
40
|
+
'@types/react-dom': '^19.0.0',
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
};
|