@boundlessfi/identity-sdk 0.1.2 → 0.1.4
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/dist/index.cjs +441 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +157 -0
- package/dist/index.d.ts +157 -7
- package/dist/index.js +423 -6
- package/dist/index.js.map +1 -1
- package/dist/server/index.cjs +80 -0
- package/dist/server/index.cjs.map +1 -0
- package/dist/server/{stellar-plugin.d.ts → index.d.cts} +7 -4
- package/dist/server/index.d.ts +35 -2
- package/dist/server/index.js +52 -1
- package/dist/server/index.js.map +1 -1
- package/package.json +8 -4
- package/src/server/stellar-plugin.ts +6 -7
- package/tsup.config.ts +11 -0
- package/dist/boundless-sdk.d.ts +0 -69
- package/dist/boundless-sdk.d.ts.map +0 -1
- package/dist/boundless-sdk.js +0 -380
- package/dist/boundless-sdk.js.map +0 -1
- package/dist/constants.d.ts +0 -32
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -31
- package/dist/constants.js.map +0 -1
- package/dist/errors.d.ts +0 -9
- package/dist/errors.d.ts.map +0 -1
- package/dist/errors.js +0 -16
- package/dist/errors.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/stellar-plugin.d.ts.map +0 -1
- package/dist/server/stellar-plugin.js +0 -46
- package/dist/server/stellar-plugin.js.map +0 -1
- package/dist/types.d.ts +0 -33
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -4
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -14
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -20
- package/dist/utils.js.map +0 -1
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,441 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
21
|
+
|
|
22
|
+
// src/index.ts
|
|
23
|
+
var index_exports = {};
|
|
24
|
+
__export(index_exports, {
|
|
25
|
+
BoundlessAuthError: () => BoundlessAuthError,
|
|
26
|
+
BoundlessLinkError: () => BoundlessLinkError,
|
|
27
|
+
BoundlessSDK: () => BoundlessSDK,
|
|
28
|
+
CredentialNotFoundError: () => import_smart_account_kit3.CredentialNotFoundError,
|
|
29
|
+
NETWORK_CONFIGS: () => NETWORK_CONFIGS,
|
|
30
|
+
SessionError: () => import_smart_account_kit3.SessionError,
|
|
31
|
+
SignerNotFoundError: () => import_smart_account_kit3.SignerNotFoundError,
|
|
32
|
+
SimulationError: () => import_smart_account_kit3.SimulationError,
|
|
33
|
+
SmartAccountError: () => import_smart_account_kit3.SmartAccountError,
|
|
34
|
+
SubmissionError: () => import_smart_account_kit3.SubmissionError,
|
|
35
|
+
ValidationError: () => import_smart_account_kit3.ValidationError,
|
|
36
|
+
WalletNotConnectedError: () => import_smart_account_kit3.WalletNotConnectedError,
|
|
37
|
+
WebAuthnError: () => import_smart_account_kit3.WebAuthnError,
|
|
38
|
+
isValidContractAddress: () => isValidContractAddress,
|
|
39
|
+
isValidStellarAddress: () => isValidStellarAddress,
|
|
40
|
+
sleep: () => sleep,
|
|
41
|
+
wrapError: () => import_smart_account_kit3.wrapError
|
|
42
|
+
});
|
|
43
|
+
module.exports = __toCommonJS(index_exports);
|
|
44
|
+
|
|
45
|
+
// src/boundless-sdk.ts
|
|
46
|
+
var import_smart_account_kit2 = require("smart-account-kit");
|
|
47
|
+
var import_stellar_sdk = require("@stellar/stellar-sdk");
|
|
48
|
+
var import_client = require("better-auth/client");
|
|
49
|
+
var import_plugins = require("better-auth/client/plugins");
|
|
50
|
+
|
|
51
|
+
// src/constants.ts
|
|
52
|
+
var NETWORK_CONFIGS = {
|
|
53
|
+
testnet: {
|
|
54
|
+
networkPassphrase: "Test SDF Network ; September 2015",
|
|
55
|
+
defaultRpcUrl: "https://soroban-testnet.stellar.org",
|
|
56
|
+
accountWasmHash: "a12e8fa9621efd20315753bd4007d974390e31fbcb4a7ddc4dd0a0dec728bf2e",
|
|
57
|
+
webauthnVerifierAddress: "CBSHV66WG7UV6FQVUTB67P3DZUEJ2KJ5X6JKQH5MFRAAFNFJUAJVXJYV",
|
|
58
|
+
ed25519VerifierAddress: "CDGMOL3BP6Y6LYOXXTRNXBNJ2SLNTQ47BGG3LOS2OBBE657E3NYCN54B",
|
|
59
|
+
nativeTokenContract: "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
|
|
60
|
+
policies: {
|
|
61
|
+
threshold: "CCT4MMN5MJ6O2OU6LXPYTCVORQ2QVTBMDJ7MYBZQ2ULSYQVUIYP4IFYD",
|
|
62
|
+
spendingLimit: "CBMMWY54XOV6JJHSWCMKWWPXVRXASR5U26UJMLZDN4SP6CFFTVZARPTY",
|
|
63
|
+
weightedThreshold: "CBYDQ5XUBP7G24FI3LLGLW56QZCIEUSVRPX7FVOUCKHJQQ6DTF6BQGBZ"
|
|
64
|
+
},
|
|
65
|
+
relayerUrl: ""
|
|
66
|
+
},
|
|
67
|
+
mainnet: {
|
|
68
|
+
networkPassphrase: "Public Global Stellar Network ; September 2015",
|
|
69
|
+
defaultRpcUrl: "https://soroban-rpc.mainnet.stellar.org",
|
|
70
|
+
accountWasmHash: "REPLACE_WITH_MAINNET_WASM_HASH",
|
|
71
|
+
webauthnVerifierAddress: "REPLACE_WITH_MAINNET_VERIFIER",
|
|
72
|
+
ed25519VerifierAddress: "REPLACE_WITH_MAINNET_VERIFIER",
|
|
73
|
+
nativeTokenContract: "REPLACE_WITH_MAINNET_CONTRACT",
|
|
74
|
+
policies: {
|
|
75
|
+
threshold: "REPLACE_WITH_MAINNET_POLICY",
|
|
76
|
+
spendingLimit: "REPLACE_WITH_MAINNET_POLICY",
|
|
77
|
+
weightedThreshold: "REPLACE_WITH_MAINNET_POLICY"
|
|
78
|
+
},
|
|
79
|
+
relayerUrl: ""
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/errors.ts
|
|
84
|
+
var import_smart_account_kit = require("smart-account-kit");
|
|
85
|
+
var BoundlessAuthError = class extends import_smart_account_kit.SmartAccountError {
|
|
86
|
+
constructor(message) {
|
|
87
|
+
super(message, "BOUNDLESS_AUTH");
|
|
88
|
+
this.name = "BoundlessAuthError";
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
var BoundlessLinkError = class extends import_smart_account_kit.SmartAccountError {
|
|
92
|
+
constructor(message, statusCode) {
|
|
93
|
+
super(message, "BOUNDLESS_LINK");
|
|
94
|
+
this.statusCode = statusCode;
|
|
95
|
+
this.name = "BoundlessLinkError";
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
// src/boundless-sdk.ts
|
|
100
|
+
var DUMMY_SOURCE = "GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5";
|
|
101
|
+
var BoundlessSDK = class {
|
|
102
|
+
// typed via createAuthClient return
|
|
103
|
+
constructor(config) {
|
|
104
|
+
__publicField(this, "config");
|
|
105
|
+
__publicField(this, "kit");
|
|
106
|
+
__publicField(this, "_walletAddress", null);
|
|
107
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
108
|
+
__publicField(this, "authClient");
|
|
109
|
+
this.config = config;
|
|
110
|
+
const networkConfig = NETWORK_CONFIGS[config.network];
|
|
111
|
+
const rpcUrl = config.rpcUrl || networkConfig.defaultRpcUrl;
|
|
112
|
+
this.kit = new import_smart_account_kit2.SmartAccountKit({
|
|
113
|
+
rpcUrl,
|
|
114
|
+
networkPassphrase: networkConfig.networkPassphrase,
|
|
115
|
+
accountWasmHash: networkConfig.accountWasmHash,
|
|
116
|
+
webauthnVerifierAddress: networkConfig.webauthnVerifierAddress,
|
|
117
|
+
rpId: config.rpId,
|
|
118
|
+
rpName: config.rpName,
|
|
119
|
+
storage: config.storage,
|
|
120
|
+
// optional
|
|
121
|
+
relayerUrl: config.relayerProxyUrl
|
|
122
|
+
// optional
|
|
123
|
+
});
|
|
124
|
+
this.authClient = (0, import_client.createAuthClient)({
|
|
125
|
+
baseURL: config.backendUrl,
|
|
126
|
+
plugins: [
|
|
127
|
+
(0, import_plugins.inferAdditionalFields)({
|
|
128
|
+
user: {
|
|
129
|
+
stellarAddress: { type: "string" },
|
|
130
|
+
credentialId: { type: "string" }
|
|
131
|
+
}
|
|
132
|
+
})
|
|
133
|
+
]
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Access the underlying SmartAccountKit instance for advanced usage.
|
|
138
|
+
*/
|
|
139
|
+
get smartAccountKit() {
|
|
140
|
+
return this.kit;
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Connect to an existing passkey wallet.
|
|
144
|
+
* If prompt is true, forces the browser passkey selection UI.
|
|
145
|
+
* Does NOT deploy a new wallet.
|
|
146
|
+
*/
|
|
147
|
+
async connect(options) {
|
|
148
|
+
const prompt = options?.prompt === true;
|
|
149
|
+
let result = await this.kit.connectWallet();
|
|
150
|
+
if (result) {
|
|
151
|
+
this._walletAddress = result.contractId;
|
|
152
|
+
return {
|
|
153
|
+
walletAddress: result.contractId,
|
|
154
|
+
credentialId: result.credentialId || "",
|
|
155
|
+
isNew: false
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
if (prompt) {
|
|
159
|
+
result = await this.kit.connectWallet({ prompt: true });
|
|
160
|
+
if (result) {
|
|
161
|
+
this._walletAddress = result.contractId;
|
|
162
|
+
return {
|
|
163
|
+
walletAddress: result.contractId,
|
|
164
|
+
credentialId: result.credentialId || "",
|
|
165
|
+
isNew: false
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return null;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Create a new wallet + credential for a user.
|
|
173
|
+
* Triggers browser passkey prompt.
|
|
174
|
+
* Links to the active Better-Auth session.
|
|
175
|
+
*/
|
|
176
|
+
async register(userName) {
|
|
177
|
+
const result = await this.kit.createWallet(this.config.rpName, userName, {
|
|
178
|
+
autoSubmit: true
|
|
179
|
+
});
|
|
180
|
+
if (!result.credentialId) {
|
|
181
|
+
console.warn("No credentialId returned from createWallet for new user.");
|
|
182
|
+
}
|
|
183
|
+
await this.linkToSession(result.contractId, result.credentialId || "");
|
|
184
|
+
this._walletAddress = result.contractId;
|
|
185
|
+
return {
|
|
186
|
+
walletAddress: result.contractId,
|
|
187
|
+
credentialId: result.credentialId,
|
|
188
|
+
isNew: true
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Link a Stellar wallet address to the currently authenticated user session.
|
|
193
|
+
*/
|
|
194
|
+
async linkToSession(contractId, credentialId) {
|
|
195
|
+
const res = await this.authClient.getSession();
|
|
196
|
+
const session = res?.data;
|
|
197
|
+
if (!session?.user) {
|
|
198
|
+
throw new BoundlessAuthError(
|
|
199
|
+
"No active auth session. User must be logged in via Better-Auth before linking a wallet."
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
const linkUrl = `${this.config.backendUrl}/api/auth/stellar/link`;
|
|
203
|
+
const response = await fetch(linkUrl, {
|
|
204
|
+
method: "POST",
|
|
205
|
+
headers: {
|
|
206
|
+
"Content-Type": "application/json"
|
|
207
|
+
},
|
|
208
|
+
body: JSON.stringify({
|
|
209
|
+
stellarAddress: contractId,
|
|
210
|
+
credentialId
|
|
211
|
+
}),
|
|
212
|
+
// Credentials include cookies for the session
|
|
213
|
+
credentials: "include"
|
|
214
|
+
});
|
|
215
|
+
if (!response.ok) {
|
|
216
|
+
const text = await response.text();
|
|
217
|
+
throw new BoundlessLinkError(
|
|
218
|
+
`Failed to link wallet: ${text}`,
|
|
219
|
+
response.status
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Sign and submit a transaction.
|
|
225
|
+
* Delegates to SmartAccountKit (which handles relayer if configured).
|
|
226
|
+
*/
|
|
227
|
+
async signAndSubmit(transaction) {
|
|
228
|
+
const result = await this.kit.signAndSubmit(transaction);
|
|
229
|
+
return {
|
|
230
|
+
hash: result.hash,
|
|
231
|
+
success: result.success
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Fetch the balance of the connected wallet (or any specific address).
|
|
236
|
+
* By default, fetches native XLM balance.
|
|
237
|
+
* If assetCode (and issuer) is provided, fetches that asset's balance.
|
|
238
|
+
* If assetCode starts with 'C', it is treated as a contract ID.
|
|
239
|
+
*/
|
|
240
|
+
async getBalance(address, assetCode = "XLM", assetIssuer) {
|
|
241
|
+
if (!address) return "0.00";
|
|
242
|
+
const networkConfig = NETWORK_CONFIGS[this.config.network];
|
|
243
|
+
const server = new import_stellar_sdk.rpc.Server(
|
|
244
|
+
this.config.rpcUrl || networkConfig.defaultRpcUrl
|
|
245
|
+
);
|
|
246
|
+
if (assetCode === "XLM") {
|
|
247
|
+
try {
|
|
248
|
+
const result = await server.getSACBalance(
|
|
249
|
+
networkConfig.nativeTokenContract,
|
|
250
|
+
import_stellar_sdk.Asset.native(),
|
|
251
|
+
networkConfig.networkPassphrase
|
|
252
|
+
);
|
|
253
|
+
if (result.balanceEntry) {
|
|
254
|
+
return (Number(result.balanceEntry.amount) / import_smart_account_kit2.STROOPS_PER_XLM).toFixed(
|
|
255
|
+
2
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
return "0.00";
|
|
259
|
+
} catch (e) {
|
|
260
|
+
console.error("Error fetching native balance:", e);
|
|
261
|
+
return "0.00";
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
let targetContractId = assetCode;
|
|
265
|
+
if (assetCode.includes(":")) {
|
|
266
|
+
const [code, issuer] = assetCode.split(":");
|
|
267
|
+
try {
|
|
268
|
+
const asset = new import_stellar_sdk.Asset(code, issuer);
|
|
269
|
+
targetContractId = asset.contractId(networkConfig.networkPassphrase);
|
|
270
|
+
} catch (e) {
|
|
271
|
+
console.error(`Invalid asset format: ${assetCode}`, e);
|
|
272
|
+
return "0";
|
|
273
|
+
}
|
|
274
|
+
} else if (assetIssuer) {
|
|
275
|
+
try {
|
|
276
|
+
const asset = new import_stellar_sdk.Asset(assetCode, assetIssuer);
|
|
277
|
+
targetContractId = asset.contractId(networkConfig.networkPassphrase);
|
|
278
|
+
} catch (e) {
|
|
279
|
+
console.error(`Failed to derive contract for ${assetCode}`, e);
|
|
280
|
+
return "0";
|
|
281
|
+
}
|
|
282
|
+
} else if (!assetCode.startsWith("C")) {
|
|
283
|
+
if (!assetCode.startsWith("C") || assetCode.length !== 56) {
|
|
284
|
+
console.warn(
|
|
285
|
+
"getBalance: Asset code must be XLM, C... contract ID, or CODE:ISSUER"
|
|
286
|
+
);
|
|
287
|
+
return "0";
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
try {
|
|
291
|
+
const sourceAccount = new import_stellar_sdk.Account(DUMMY_SOURCE, "0");
|
|
292
|
+
const tokenContract = new import_stellar_sdk.Contract(targetContractId);
|
|
293
|
+
const op = tokenContract.call("balance", new import_stellar_sdk.Address(address).toScVal());
|
|
294
|
+
const tx = new import_stellar_sdk.TransactionBuilder(sourceAccount, {
|
|
295
|
+
fee: "100",
|
|
296
|
+
networkPassphrase: networkConfig.networkPassphrase
|
|
297
|
+
}).addOperation(op).setTimeout(import_stellar_sdk.TimeoutInfinite).build();
|
|
298
|
+
const sim = await server.simulateTransaction(tx);
|
|
299
|
+
if (import_stellar_sdk.rpc.Api.isSimulationSuccess(sim) && sim.result && "retval" in sim.result) {
|
|
300
|
+
const val = (0, import_stellar_sdk.scValToNative)(sim.result.retval);
|
|
301
|
+
return (Number(val) / 1e7).toFixed(2);
|
|
302
|
+
}
|
|
303
|
+
} catch (e) {
|
|
304
|
+
console.error(`Error fetching token balance for ${assetCode}:`, e);
|
|
305
|
+
}
|
|
306
|
+
return "0";
|
|
307
|
+
}
|
|
308
|
+
/**
|
|
309
|
+
* Transfer funds (XLM or Token).
|
|
310
|
+
* Automatically resolves Asset-to-Contract if needed.
|
|
311
|
+
*/
|
|
312
|
+
async transfer(to, amount, assetCode = "XLM", assetIssuer) {
|
|
313
|
+
const networkConfig = NETWORK_CONFIGS[this.config.network];
|
|
314
|
+
let tokenContract = networkConfig.nativeTokenContract;
|
|
315
|
+
if (assetCode !== "XLM") {
|
|
316
|
+
if (assetCode.startsWith("C") && assetCode.length === 56) {
|
|
317
|
+
tokenContract = assetCode;
|
|
318
|
+
} else if (assetCode.includes(":")) {
|
|
319
|
+
const [code, issuer] = assetCode.split(":");
|
|
320
|
+
const asset = new import_stellar_sdk.Asset(code, issuer);
|
|
321
|
+
tokenContract = asset.contractId(networkConfig.networkPassphrase);
|
|
322
|
+
} else if (assetIssuer) {
|
|
323
|
+
const asset = new import_stellar_sdk.Asset(assetCode, assetIssuer);
|
|
324
|
+
tokenContract = asset.contractId(networkConfig.networkPassphrase);
|
|
325
|
+
} else {
|
|
326
|
+
throw new Error(
|
|
327
|
+
"Invalid asset specifier. Use XLM, Contract ID, or Code + Issuer."
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
const amountNum = typeof amount === "string" ? parseFloat(amount) : amount;
|
|
332
|
+
const result = await this.kit.transfer(tokenContract, to, amountNum);
|
|
333
|
+
return {
|
|
334
|
+
hash: result.hash,
|
|
335
|
+
success: result.success
|
|
336
|
+
};
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Disconnect the wallet (clear local session).
|
|
340
|
+
* Does NOT sign out of Better-Auth.
|
|
341
|
+
*/
|
|
342
|
+
async disconnect() {
|
|
343
|
+
await this.kit.disconnect();
|
|
344
|
+
this._walletAddress = null;
|
|
345
|
+
}
|
|
346
|
+
/**
|
|
347
|
+
* Get the connected wallet address synchronously.
|
|
348
|
+
*/
|
|
349
|
+
getWalletAddress() {
|
|
350
|
+
return this._walletAddress || this.kit.address || null;
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* Add a recovery key (new passkey) to the existing account.
|
|
354
|
+
*/
|
|
355
|
+
async addRecoveryKey(options) {
|
|
356
|
+
const address = this.getWalletAddress();
|
|
357
|
+
if (!address) {
|
|
358
|
+
throw new import_smart_account_kit2.WalletNotConnectedError(
|
|
359
|
+
"Wallet must be connected to add a recovery key."
|
|
360
|
+
);
|
|
361
|
+
}
|
|
362
|
+
const { credentialId } = await this.kit.signers.addPasskey(
|
|
363
|
+
0,
|
|
364
|
+
// contextRuleId (0 = default)
|
|
365
|
+
options.appName,
|
|
366
|
+
options.userName,
|
|
367
|
+
{ nickname: options.nickname }
|
|
368
|
+
);
|
|
369
|
+
return { credentialId };
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Remove a credential by ID.
|
|
373
|
+
*/
|
|
374
|
+
async removeCredential(credentialId) {
|
|
375
|
+
const address = this.getWalletAddress();
|
|
376
|
+
if (!address) {
|
|
377
|
+
throw new import_smart_account_kit2.WalletNotConnectedError(
|
|
378
|
+
"Wallet must be connected to remove a credential."
|
|
379
|
+
);
|
|
380
|
+
}
|
|
381
|
+
await this.kit.signers.removePasskey(0, credentialId);
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Subscribe to events.
|
|
385
|
+
*/
|
|
386
|
+
onEvent(event, handler) {
|
|
387
|
+
const validEvents = [
|
|
388
|
+
"walletConnected",
|
|
389
|
+
"walletDisconnected",
|
|
390
|
+
"credentialCreated",
|
|
391
|
+
"credentialDeleted",
|
|
392
|
+
"sessionExpired",
|
|
393
|
+
"transactionSigned",
|
|
394
|
+
"transactionSubmitted"
|
|
395
|
+
];
|
|
396
|
+
if (!validEvents.includes(event)) {
|
|
397
|
+
console.warn(`BoundlessSDK: Unknown event "${event}"`);
|
|
398
|
+
return () => {
|
|
399
|
+
};
|
|
400
|
+
}
|
|
401
|
+
this.kit.events.on(event, handler);
|
|
402
|
+
return () => {
|
|
403
|
+
this.kit.events.off(event, handler);
|
|
404
|
+
};
|
|
405
|
+
}
|
|
406
|
+
};
|
|
407
|
+
|
|
408
|
+
// src/utils.ts
|
|
409
|
+
function isValidContractAddress(addr) {
|
|
410
|
+
return typeof addr === "string" && addr.length === 56 && addr.startsWith("C");
|
|
411
|
+
}
|
|
412
|
+
function isValidStellarAddress(addr) {
|
|
413
|
+
return typeof addr === "string" && addr.length === 56 && addr.startsWith("G");
|
|
414
|
+
}
|
|
415
|
+
function sleep(ms) {
|
|
416
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// src/index.ts
|
|
420
|
+
var import_smart_account_kit3 = require("smart-account-kit");
|
|
421
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
422
|
+
0 && (module.exports = {
|
|
423
|
+
BoundlessAuthError,
|
|
424
|
+
BoundlessLinkError,
|
|
425
|
+
BoundlessSDK,
|
|
426
|
+
CredentialNotFoundError,
|
|
427
|
+
NETWORK_CONFIGS,
|
|
428
|
+
SessionError,
|
|
429
|
+
SignerNotFoundError,
|
|
430
|
+
SimulationError,
|
|
431
|
+
SmartAccountError,
|
|
432
|
+
SubmissionError,
|
|
433
|
+
ValidationError,
|
|
434
|
+
WalletNotConnectedError,
|
|
435
|
+
WebAuthnError,
|
|
436
|
+
isValidContractAddress,
|
|
437
|
+
isValidStellarAddress,
|
|
438
|
+
sleep,
|
|
439
|
+
wrapError
|
|
440
|
+
});
|
|
441
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/boundless-sdk.ts","../src/constants.ts","../src/errors.ts","../src/utils.ts"],"sourcesContent":["export * from \"./boundless-sdk\";\nexport * from \"./types\";\nexport * from \"./errors\";\nexport * from \"./constants\";\nexport * from \"./utils\";\nexport {\n SmartAccountError,\n WalletNotConnectedError,\n CredentialNotFoundError,\n SignerNotFoundError,\n SimulationError,\n SubmissionError,\n ValidationError,\n WebAuthnError,\n SessionError,\n wrapError,\n} from \"smart-account-kit\";\n","import {\n SmartAccountKit,\n IndexedDBStorage,\n WalletNotConnectedError,\n STROOPS_PER_XLM,\n} from \"smart-account-kit\";\nimport {\n rpc,\n Asset,\n Address,\n Contract,\n Account,\n TransactionBuilder,\n scValToNative,\n TimeoutInfinite,\n} from \"@stellar/stellar-sdk\";\nimport type { AssembledTransaction } from \"smart-account-kit\";\nimport { createAuthClient } from \"better-auth/client\";\nimport { inferAdditionalFields } from \"better-auth/client/plugins\";\n\nimport { NETWORK_CONFIGS } from \"./constants\";\nimport { BoundlessAuthError, BoundlessLinkError } from \"./errors\";\nimport type {\n BoundlessSdkConfig,\n ConnectOptions,\n ConnectResult,\n SignAndSubmitResult,\n AddRecoveryKeyOptions,\n RecoveryKeyResult,\n BoundlessEventName,\n BoundlessEventHandler,\n} from \"./types\";\n\n// Valid G-address for simulation source (USDC Issuer)\nconst DUMMY_SOURCE = \"GBBD47IF6LWK7P7MDEVSCWR7DPUWV3NY3DTQEVFL4NAT4AQH3ZLLFLA5\";\n\nexport class BoundlessSDK {\n private config: BoundlessSdkConfig;\n private kit: SmartAccountKit;\n private _walletAddress: string | null = null;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n private authClient: any; // typed via createAuthClient return\n\n constructor(config: BoundlessSdkConfig) {\n this.config = config;\n\n // 1. Resolve network config\n const networkConfig = NETWORK_CONFIGS[config.network];\n const rpcUrl = config.rpcUrl || networkConfig.defaultRpcUrl;\n\n // 2. Initialize SmartAccountKit\n this.kit = new SmartAccountKit({\n rpcUrl,\n networkPassphrase: networkConfig.networkPassphrase,\n accountWasmHash: networkConfig.accountWasmHash,\n webauthnVerifierAddress: networkConfig.webauthnVerifierAddress,\n rpId: config.rpId,\n rpName: config.rpName,\n storage: config.storage, // optional\n relayerUrl: config.relayerProxyUrl, // optional\n });\n\n // 3. Create Better-Auth client\n // We cannot do `typeof auth` inference across packages easily without importing backend code.\n // inferAdditionalFields is the standard polyrepo pattern.\n this.authClient = createAuthClient({\n baseURL: config.backendUrl,\n plugins: [\n inferAdditionalFields({\n user: {\n stellarAddress: { type: \"string\" },\n credentialId: { type: \"string\" },\n },\n }),\n ],\n }) as any;\n }\n\n /**\n * Access the underlying SmartAccountKit instance for advanced usage.\n */\n get smartAccountKit(): SmartAccountKit {\n return this.kit;\n }\n\n /**\n * Connect to an existing passkey wallet.\n * If prompt is true, forces the browser passkey selection UI.\n * Does NOT deploy a new wallet.\n */\n async connect(options?: ConnectOptions): Promise<ConnectResult | null> {\n const prompt = options?.prompt === true;\n\n // 1. Silent restore first (default behavior of connectWallet without args)\n // If prompt is true, we skip silent restore if we want to force UI,\n // but smart-account-kit connectWallet handles 'prompt: true' by forcing it.\n // However, the spec says:\n // \"Call kit.connectWallet() ← silent restore\"\n // \"If result → return mapped... \"\n // \"If null AND options?.prompt === true → call kit.connectWallet({ prompt: true })\"\n\n let result = await this.kit.connectWallet();\n\n if (result) {\n this._walletAddress = result.contractId;\n return {\n walletAddress: result.contractId,\n credentialId: (result as any).credentialId || \"\",\n isNew: false,\n };\n }\n\n if (prompt) {\n result = await this.kit.connectWallet({ prompt: true });\n if (result) {\n this._walletAddress = result.contractId;\n return {\n walletAddress: result.contractId,\n credentialId: (result as any).credentialId || \"\",\n isNew: false,\n };\n }\n }\n\n // \"If null AND prompt is falsy → return null.\"\n return null;\n }\n\n /**\n * Create a new wallet + credential for a user.\n * Triggers browser passkey prompt.\n * Links to the active Better-Auth session.\n */\n async register(userName: string): Promise<ConnectResult> {\n // 1. Create wallet (deploys on-chain + persists credential)\n const result = await this.kit.createWallet(this.config.rpName, userName, {\n autoSubmit: true,\n });\n\n // 2. Link to Better-Auth session\n // We expect credentialId to be present for new registrations via SmartAccountKit\n if (!result.credentialId) {\n console.warn(\"No credentialId returned from createWallet for new user.\");\n }\n await this.linkToSession(result.contractId, result.credentialId || \"\");\n\n this._walletAddress = result.contractId;\n\n // 3. Return result\n return {\n walletAddress: result.contractId,\n credentialId: result.credentialId,\n isNew: true,\n };\n }\n\n /**\n * Link a Stellar wallet address to the currently authenticated user session.\n */\n private async linkToSession(\n contractId: string,\n credentialId: string,\n ): Promise<void> {\n // 1. Check session\n const res = await this.authClient.getSession();\n const session = res?.data;\n if (!session?.user) {\n throw new BoundlessAuthError(\n \"No active auth session. User must be logged in via Better-Auth before linking a wallet.\",\n );\n }\n\n // 2. POST /api/auth/stellar/link\n // Using fetch to manually hit the endpoint registered by the plugin.\n // The SDK's authClient base URL is config.backendUrl.\n const linkUrl = `${this.config.backendUrl}/api/auth/stellar/link`;\n\n const response = await fetch(linkUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n stellarAddress: contractId,\n credentialId: credentialId,\n }),\n // Credentials include cookies for the session\n credentials: \"include\",\n });\n\n if (!response.ok) {\n const text = await response.text();\n throw new BoundlessLinkError(\n `Failed to link wallet: ${text}`,\n response.status,\n );\n }\n }\n\n /**\n * Sign and submit a transaction.\n * Delegates to SmartAccountKit (which handles relayer if configured).\n */\n async signAndSubmit(\n transaction: AssembledTransaction<any>,\n ): Promise<SignAndSubmitResult> {\n const result = await this.kit.signAndSubmit(transaction);\n return {\n hash: result.hash,\n success: result.success,\n };\n }\n\n /**\n * Fetch the balance of the connected wallet (or any specific address).\n * By default, fetches native XLM balance.\n * If assetCode (and issuer) is provided, fetches that asset's balance.\n * If assetCode starts with 'C', it is treated as a contract ID.\n */\n async getBalance(\n address: string,\n assetCode = \"XLM\",\n assetIssuer?: string,\n ): Promise<string> {\n if (!address) return \"0.00\";\n\n const networkConfig = NETWORK_CONFIGS[this.config.network];\n const server = new rpc.Server(\n this.config.rpcUrl || networkConfig.defaultRpcUrl,\n );\n\n // 1. Native Balance\n if (assetCode === \"XLM\") {\n try {\n const result = await server.getSACBalance(\n networkConfig.nativeTokenContract,\n Asset.native(),\n networkConfig.networkPassphrase,\n );\n if (result.balanceEntry) {\n return (Number(result.balanceEntry.amount) / STROOPS_PER_XLM).toFixed(\n 2,\n );\n }\n return \"0.00\";\n } catch (e) {\n console.error(\"Error fetching native balance:\", e);\n return \"0.00\";\n }\n }\n\n // 2. Custom Token Balance\n let targetContractId = assetCode;\n\n // Resolve Contract ID\n if (assetCode.includes(\":\")) {\n // CODE:ISSUER\n const [code, issuer] = assetCode.split(\":\");\n try {\n const asset = new Asset(code, issuer);\n targetContractId = asset.contractId(networkConfig.networkPassphrase);\n } catch (e) {\n console.error(`Invalid asset format: ${assetCode}`, e);\n return \"0\";\n }\n } else if (assetIssuer) {\n // Explicit Code + Issuer\n try {\n const asset = new Asset(assetCode, assetIssuer);\n targetContractId = asset.contractId(networkConfig.networkPassphrase);\n } catch (e) {\n console.error(`Failed to derive contract for ${assetCode}`, e);\n return \"0\";\n }\n } else if (!assetCode.startsWith(\"C\")) {\n // If it's just \"USDC\" without issuer, we might need a known list or fail.\n // For SDK, we assume the user must provide enough info.\n // However, if the user passes a contract address directly, we use it.\n // Check if it's a valid contract address?\n // For now, we assume if it's 56 chars starting with C, it's a contract.\n // If not, we can't guess.\n // But we'll try to treat it as a contract ID if it looks like one.\n if (!assetCode.startsWith(\"C\") || assetCode.length !== 56) {\n console.warn(\n \"getBalance: Asset code must be XLM, C... contract ID, or CODE:ISSUER\",\n );\n return \"0\";\n }\n }\n\n try {\n // Simulate Balance Call\n // Use DUMMY_SOURCE for simulation to avoid accountId errors with Smart Accounts\n const sourceAccount = new Account(DUMMY_SOURCE, \"0\");\n\n const tokenContract = new Contract(targetContractId);\n const op = tokenContract.call(\"balance\", new Address(address).toScVal());\n\n const tx = new TransactionBuilder(sourceAccount, {\n fee: \"100\",\n networkPassphrase: networkConfig.networkPassphrase,\n })\n .addOperation(op)\n .setTimeout(TimeoutInfinite)\n .build();\n\n const sim = await server.simulateTransaction(tx);\n\n if (\n rpc.Api.isSimulationSuccess(sim) &&\n sim.result &&\n \"retval\" in sim.result\n ) {\n const val = scValToNative(sim.result.retval);\n // Default formatting: Assume 7 decimals for now or return raw?\n // Returning human-readable for convenience.\n // Most Stellar tokens are 7 decimals.\n return (Number(val) / 1e7).toFixed(2);\n }\n } catch (e) {\n console.error(`Error fetching token balance for ${assetCode}:`, e);\n }\n\n return \"0\";\n }\n\n /**\n * Transfer funds (XLM or Token).\n * Automatically resolves Asset-to-Contract if needed.\n */\n async transfer(\n to: string,\n amount: string | number,\n assetCode = \"XLM\",\n assetIssuer?: string,\n ): Promise<SignAndSubmitResult> {\n const networkConfig = NETWORK_CONFIGS[this.config.network];\n let tokenContract: string = networkConfig.nativeTokenContract;\n\n if (assetCode !== \"XLM\") {\n if (assetCode.startsWith(\"C\") && assetCode.length === 56) {\n tokenContract = assetCode;\n } else if (assetCode.includes(\":\")) {\n const [code, issuer] = assetCode.split(\":\");\n const asset = new Asset(code, issuer);\n tokenContract = asset.contractId(networkConfig.networkPassphrase);\n } else if (assetIssuer) {\n const asset = new Asset(assetCode, assetIssuer);\n tokenContract = asset.contractId(networkConfig.networkPassphrase);\n } else {\n throw new Error(\n \"Invalid asset specifier. Use XLM, Contract ID, or Code + Issuer.\",\n );\n }\n }\n\n const amountNum = typeof amount === \"string\" ? parseFloat(amount) : amount;\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const result = await this.kit.transfer(tokenContract as any, to, amountNum);\n\n return {\n hash: result.hash,\n success: result.success,\n };\n }\n\n /**\n * Disconnect the wallet (clear local session).\n * Does NOT sign out of Better-Auth.\n */\n async disconnect(): Promise<void> {\n await this.kit.disconnect();\n this._walletAddress = null;\n }\n\n /**\n * Get the connected wallet address synchronously.\n */\n getWalletAddress(): string | null {\n // smart-account-kit doesn't have a direct synchronous getter documented in the spec provided?\n // \"Read from the session state that SmartAccountKit maintains internally (check kit after connectWallet result).\"\n // Usually kit.address or similar is available if connected.\n // Based on \"sub-managers\" list, it doesn't explicitly show 'address' property on kit intance.\n // However, typical usage implies we can track it.\n // BUT the prompt says: \"check kit after connectWallet result\".\n // Wait, SmartAccountKit instance usage in 6.1 doesn't show a public 'address' field.\n // But section 7.3 says: \"Read from the session state that SmartAccountKit maintains internally\".\n // I will assume `kit.address` exists or I need to track it myself?\n // \"The SDK is one package... Client SDK class... It owns the client-side BoundlessSDK class\".\n // If I look at `kit` internals or typical patterns, it often exposes the address.\n // If not, I should probably cache it on `connect` / `register`.\n // BUT, `kit.connectWallet` returns the result.\n // If the page reloads, `kit` is re-instantiated. `kit.connectWallet()` (silent) restores it.\n // So `getWalletAddress` might need to rely on the *result* of the last connect/register.\n //\n // HOWEVER, `kit` might have an `address` getter.\n // Let's assume for now I should inspect `kit` typings if I could, but I can't.\n // \"Read from the session state that SmartAccountKit maintains internally\"\n // implies `kit` has state.\n // If `kit` tracks it, it's likely `kit.address`.\n // I'll check if I can assume it.\n // If `kit` does not expose it, I'd have to store it in `this.currentAddress`.\n // But if `kit` disconnects, I need to know.\n // `kit.events` emit 'walletDisconnected'.\n\n // I'll use a safer approach: check if `kit` has a known property or Method.\n // The spec 6.1 Core Methods allows `connectWallet`.\n // If `kit` doesn't expose `address` directly, I'll rely on my own state updated via events/method calls.\n // BUT Section 7.3 says \"Read from the session state that SmartAccountKit maintains internally\".\n // This strongly suggests `kit` has it. I will try `(this.kit as any).address`.\n // Or better, I will assume it might be there.\n\n // Actually, looking at `smart-account-kit` typical implementations, it usually has `address`.\n // I'll assume `this.kit.address` is the way.\n // If TS complains, I'll fix it. I can't check types right now.\n // I will use `(this.kit as any).address` to be safe if strict types block it,\n // but better to try `this.kit.address` first? No, I want to avoid build errors.\n // I'll cast for now to avoid blocking if the types aren't exactly matching my assumption.\n // \"Read from the session state that SmartAccountKit maintains internally\"\n\n return this._walletAddress || (this.kit as any).address || null;\n }\n\n /**\n * Add a recovery key (new passkey) to the existing account.\n */\n async addRecoveryKey(\n options: AddRecoveryKeyOptions,\n ): Promise<RecoveryKeyResult> {\n const address = this.getWalletAddress();\n if (!address) {\n throw new WalletNotConnectedError(\n \"Wallet must be connected to add a recovery key.\",\n );\n }\n\n const { credentialId } = await this.kit.signers.addPasskey(\n 0, // contextRuleId (0 = default)\n options.appName,\n options.userName,\n { nickname: options.nickname },\n );\n\n return { credentialId };\n }\n\n /**\n * Remove a credential by ID.\n */\n async removeCredential(credentialId: string): Promise<void> {\n const address = this.getWalletAddress();\n if (!address) {\n throw new WalletNotConnectedError(\n \"Wallet must be connected to remove a credential.\",\n );\n }\n\n await this.kit.signers.removePasskey(0, credentialId);\n }\n\n /**\n * Subscribe to events.\n */\n onEvent(\n event: BoundlessEventName,\n handler: BoundlessEventHandler,\n ): () => void {\n const validEvents: BoundlessEventName[] = [\n \"walletConnected\",\n \"walletDisconnected\",\n \"credentialCreated\",\n \"credentialDeleted\",\n \"sessionExpired\",\n \"transactionSigned\",\n \"transactionSubmitted\",\n ];\n\n if (!validEvents.includes(event)) {\n // Just ignore or warn? Types prevent this usually.\n console.warn(`BoundlessSDK: Unknown event \"${event}\"`);\n return () => {};\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.kit.events.on(event, handler as any);\n\n return () => {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n this.kit.events.off(event, handler as any);\n };\n }\n}\n","export const NETWORK_CONFIGS = {\n testnet: {\n networkPassphrase: \"Test SDF Network ; September 2015\",\n defaultRpcUrl: \"https://soroban-testnet.stellar.org\",\n accountWasmHash:\n \"a12e8fa9621efd20315753bd4007d974390e31fbcb4a7ddc4dd0a0dec728bf2e\",\n webauthnVerifierAddress:\n \"CBSHV66WG7UV6FQVUTB67P3DZUEJ2KJ5X6JKQH5MFRAAFNFJUAJVXJYV\",\n ed25519VerifierAddress:\n \"CDGMOL3BP6Y6LYOXXTRNXBNJ2SLNTQ47BGG3LOS2OBBE657E3NYCN54B\",\n nativeTokenContract:\n \"CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC\",\n policies: {\n threshold: \"CCT4MMN5MJ6O2OU6LXPYTCVORQ2QVTBMDJ7MYBZQ2ULSYQVUIYP4IFYD\",\n spendingLimit: \"CBMMWY54XOV6JJHSWCMKWWPXVRXASR5U26UJMLZDN4SP6CFFTVZARPTY\",\n weightedThreshold:\n \"CBYDQ5XUBP7G24FI3LLGLW56QZCIEUSVRPX7FVOUCKHJQQ6DTF6BQGBZ\",\n },\n relayerUrl: \"\",\n },\n mainnet: {\n networkPassphrase: \"Public Global Stellar Network ; September 2015\",\n defaultRpcUrl: \"https://soroban-rpc.mainnet.stellar.org\",\n accountWasmHash: \"REPLACE_WITH_MAINNET_WASM_HASH\",\n webauthnVerifierAddress: \"REPLACE_WITH_MAINNET_VERIFIER\",\n ed25519VerifierAddress: \"REPLACE_WITH_MAINNET_VERIFIER\",\n nativeTokenContract: \"REPLACE_WITH_MAINNET_CONTRACT\",\n policies: {\n threshold: \"REPLACE_WITH_MAINNET_POLICY\",\n spendingLimit: \"REPLACE_WITH_MAINNET_POLICY\",\n weightedThreshold: \"REPLACE_WITH_MAINNET_POLICY\",\n },\n relayerUrl: \"\",\n },\n} as const;\n\nexport type NetworkName = keyof typeof NETWORK_CONFIGS;\n","import { SmartAccountError } from \"smart-account-kit\";\n\nexport class BoundlessAuthError extends SmartAccountError {\n constructor(message: string) {\n super(message, \"BOUNDLESS_AUTH\" as any);\n this.name = \"BoundlessAuthError\";\n }\n}\n\nexport class BoundlessLinkError extends SmartAccountError {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message, \"BOUNDLESS_LINK\" as any);\n this.name = \"BoundlessLinkError\";\n }\n}\n","/**\n * Validate that a string looks like a Soroban contract address.\n * Soroban contract IDs start with 'C' and are 56 characters (StrKey).\n */\nexport function isValidContractAddress(addr: string): boolean {\n return typeof addr === \"string\" && addr.length === 56 && addr.startsWith(\"C\");\n}\n\n/**\n * Validate that a string looks like a Stellar account address (G…).\n */\nexport function isValidStellarAddress(addr: string): boolean {\n return typeof addr === \"string\" && addr.length === 56 && addr.startsWith(\"G\");\n}\n\n/**\n * Sleep for N milliseconds. Useful in retry loops.\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n"],"mappings":"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","names":["import_smart_account_kit","import_smart_account_kit"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import * as smart_account_kit from 'smart-account-kit';
|
|
2
|
+
import { SmartAccountKit, AssembledTransaction, SmartAccountError } from 'smart-account-kit';
|
|
3
|
+
export { AssembledTransaction, ConnectWalletResult, ContextRule, ContextRuleType, ContractSigner, CreateWalletResult, CredentialNotFoundError, ExternalWalletAdapter, SelectedSigner, SessionError, SignerNotFoundError, SimulationError, SmartAccountError, StorageAdapter, StoredCredential, StoredSession, SubmissionError, TransactionResult, ValidationError, WalletNotConnectedError, WebAuthnError, wrapError } from 'smart-account-kit';
|
|
4
|
+
|
|
5
|
+
interface BoundlessSdkConfig {
|
|
6
|
+
network: "mainnet" | "testnet";
|
|
7
|
+
rpcUrl?: string;
|
|
8
|
+
rpId: string;
|
|
9
|
+
rpName: string;
|
|
10
|
+
backendUrl: string;
|
|
11
|
+
relayerProxyUrl?: string;
|
|
12
|
+
storage?: smart_account_kit.StorageAdapter;
|
|
13
|
+
}
|
|
14
|
+
interface ConnectOptions {
|
|
15
|
+
prompt?: boolean;
|
|
16
|
+
}
|
|
17
|
+
interface ConnectResult {
|
|
18
|
+
walletAddress: string;
|
|
19
|
+
credentialId: string;
|
|
20
|
+
isNew: boolean;
|
|
21
|
+
}
|
|
22
|
+
interface SignAndSubmitResult {
|
|
23
|
+
hash: string;
|
|
24
|
+
success: boolean;
|
|
25
|
+
}
|
|
26
|
+
interface AddRecoveryKeyOptions {
|
|
27
|
+
appName: string;
|
|
28
|
+
userName: string;
|
|
29
|
+
nickname?: string;
|
|
30
|
+
}
|
|
31
|
+
interface RecoveryKeyResult {
|
|
32
|
+
credentialId: string;
|
|
33
|
+
}
|
|
34
|
+
type BoundlessEventName = "walletConnected" | "walletDisconnected" | "credentialCreated" | "credentialDeleted" | "sessionExpired" | "transactionSigned" | "transactionSubmitted";
|
|
35
|
+
type BoundlessEventHandler = (...args: unknown[]) => void;
|
|
36
|
+
|
|
37
|
+
declare class BoundlessSDK {
|
|
38
|
+
private config;
|
|
39
|
+
private kit;
|
|
40
|
+
private _walletAddress;
|
|
41
|
+
private authClient;
|
|
42
|
+
constructor(config: BoundlessSdkConfig);
|
|
43
|
+
/**
|
|
44
|
+
* Access the underlying SmartAccountKit instance for advanced usage.
|
|
45
|
+
*/
|
|
46
|
+
get smartAccountKit(): SmartAccountKit;
|
|
47
|
+
/**
|
|
48
|
+
* Connect to an existing passkey wallet.
|
|
49
|
+
* If prompt is true, forces the browser passkey selection UI.
|
|
50
|
+
* Does NOT deploy a new wallet.
|
|
51
|
+
*/
|
|
52
|
+
connect(options?: ConnectOptions): Promise<ConnectResult | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Create a new wallet + credential for a user.
|
|
55
|
+
* Triggers browser passkey prompt.
|
|
56
|
+
* Links to the active Better-Auth session.
|
|
57
|
+
*/
|
|
58
|
+
register(userName: string): Promise<ConnectResult>;
|
|
59
|
+
/**
|
|
60
|
+
* Link a Stellar wallet address to the currently authenticated user session.
|
|
61
|
+
*/
|
|
62
|
+
private linkToSession;
|
|
63
|
+
/**
|
|
64
|
+
* Sign and submit a transaction.
|
|
65
|
+
* Delegates to SmartAccountKit (which handles relayer if configured).
|
|
66
|
+
*/
|
|
67
|
+
signAndSubmit(transaction: AssembledTransaction<any>): Promise<SignAndSubmitResult>;
|
|
68
|
+
/**
|
|
69
|
+
* Fetch the balance of the connected wallet (or any specific address).
|
|
70
|
+
* By default, fetches native XLM balance.
|
|
71
|
+
* If assetCode (and issuer) is provided, fetches that asset's balance.
|
|
72
|
+
* If assetCode starts with 'C', it is treated as a contract ID.
|
|
73
|
+
*/
|
|
74
|
+
getBalance(address: string, assetCode?: string, assetIssuer?: string): Promise<string>;
|
|
75
|
+
/**
|
|
76
|
+
* Transfer funds (XLM or Token).
|
|
77
|
+
* Automatically resolves Asset-to-Contract if needed.
|
|
78
|
+
*/
|
|
79
|
+
transfer(to: string, amount: string | number, assetCode?: string, assetIssuer?: string): Promise<SignAndSubmitResult>;
|
|
80
|
+
/**
|
|
81
|
+
* Disconnect the wallet (clear local session).
|
|
82
|
+
* Does NOT sign out of Better-Auth.
|
|
83
|
+
*/
|
|
84
|
+
disconnect(): Promise<void>;
|
|
85
|
+
/**
|
|
86
|
+
* Get the connected wallet address synchronously.
|
|
87
|
+
*/
|
|
88
|
+
getWalletAddress(): string | null;
|
|
89
|
+
/**
|
|
90
|
+
* Add a recovery key (new passkey) to the existing account.
|
|
91
|
+
*/
|
|
92
|
+
addRecoveryKey(options: AddRecoveryKeyOptions): Promise<RecoveryKeyResult>;
|
|
93
|
+
/**
|
|
94
|
+
* Remove a credential by ID.
|
|
95
|
+
*/
|
|
96
|
+
removeCredential(credentialId: string): Promise<void>;
|
|
97
|
+
/**
|
|
98
|
+
* Subscribe to events.
|
|
99
|
+
*/
|
|
100
|
+
onEvent(event: BoundlessEventName, handler: BoundlessEventHandler): () => void;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
declare class BoundlessAuthError extends SmartAccountError {
|
|
104
|
+
constructor(message: string);
|
|
105
|
+
}
|
|
106
|
+
declare class BoundlessLinkError extends SmartAccountError {
|
|
107
|
+
statusCode?: number | undefined;
|
|
108
|
+
constructor(message: string, statusCode?: number | undefined);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
declare const NETWORK_CONFIGS: {
|
|
112
|
+
readonly testnet: {
|
|
113
|
+
readonly networkPassphrase: "Test SDF Network ; September 2015";
|
|
114
|
+
readonly defaultRpcUrl: "https://soroban-testnet.stellar.org";
|
|
115
|
+
readonly accountWasmHash: "a12e8fa9621efd20315753bd4007d974390e31fbcb4a7ddc4dd0a0dec728bf2e";
|
|
116
|
+
readonly webauthnVerifierAddress: "CBSHV66WG7UV6FQVUTB67P3DZUEJ2KJ5X6JKQH5MFRAAFNFJUAJVXJYV";
|
|
117
|
+
readonly ed25519VerifierAddress: "CDGMOL3BP6Y6LYOXXTRNXBNJ2SLNTQ47BGG3LOS2OBBE657E3NYCN54B";
|
|
118
|
+
readonly nativeTokenContract: "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC";
|
|
119
|
+
readonly policies: {
|
|
120
|
+
readonly threshold: "CCT4MMN5MJ6O2OU6LXPYTCVORQ2QVTBMDJ7MYBZQ2ULSYQVUIYP4IFYD";
|
|
121
|
+
readonly spendingLimit: "CBMMWY54XOV6JJHSWCMKWWPXVRXASR5U26UJMLZDN4SP6CFFTVZARPTY";
|
|
122
|
+
readonly weightedThreshold: "CBYDQ5XUBP7G24FI3LLGLW56QZCIEUSVRPX7FVOUCKHJQQ6DTF6BQGBZ";
|
|
123
|
+
};
|
|
124
|
+
readonly relayerUrl: "";
|
|
125
|
+
};
|
|
126
|
+
readonly mainnet: {
|
|
127
|
+
readonly networkPassphrase: "Public Global Stellar Network ; September 2015";
|
|
128
|
+
readonly defaultRpcUrl: "https://soroban-rpc.mainnet.stellar.org";
|
|
129
|
+
readonly accountWasmHash: "REPLACE_WITH_MAINNET_WASM_HASH";
|
|
130
|
+
readonly webauthnVerifierAddress: "REPLACE_WITH_MAINNET_VERIFIER";
|
|
131
|
+
readonly ed25519VerifierAddress: "REPLACE_WITH_MAINNET_VERIFIER";
|
|
132
|
+
readonly nativeTokenContract: "REPLACE_WITH_MAINNET_CONTRACT";
|
|
133
|
+
readonly policies: {
|
|
134
|
+
readonly threshold: "REPLACE_WITH_MAINNET_POLICY";
|
|
135
|
+
readonly spendingLimit: "REPLACE_WITH_MAINNET_POLICY";
|
|
136
|
+
readonly weightedThreshold: "REPLACE_WITH_MAINNET_POLICY";
|
|
137
|
+
};
|
|
138
|
+
readonly relayerUrl: "";
|
|
139
|
+
};
|
|
140
|
+
};
|
|
141
|
+
type NetworkName = keyof typeof NETWORK_CONFIGS;
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Validate that a string looks like a Soroban contract address.
|
|
145
|
+
* Soroban contract IDs start with 'C' and are 56 characters (StrKey).
|
|
146
|
+
*/
|
|
147
|
+
declare function isValidContractAddress(addr: string): boolean;
|
|
148
|
+
/**
|
|
149
|
+
* Validate that a string looks like a Stellar account address (G…).
|
|
150
|
+
*/
|
|
151
|
+
declare function isValidStellarAddress(addr: string): boolean;
|
|
152
|
+
/**
|
|
153
|
+
* Sleep for N milliseconds. Useful in retry loops.
|
|
154
|
+
*/
|
|
155
|
+
declare function sleep(ms: number): Promise<void>;
|
|
156
|
+
|
|
157
|
+
export { type AddRecoveryKeyOptions, BoundlessAuthError, type BoundlessEventHandler, type BoundlessEventName, BoundlessLinkError, BoundlessSDK, type BoundlessSdkConfig, type ConnectOptions, type ConnectResult, NETWORK_CONFIGS, type NetworkName, type RecoveryKeyResult, type SignAndSubmitResult, isValidContractAddress, isValidStellarAddress, sleep };
|