@boundlessfi/identity-sdk 0.1.3 → 0.1.5
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 +174 -0
- package/dist/server/index.cjs +4 -4
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.js +5 -5
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
- package/src/server/stellar-plugin.ts +6 -7
package/README.md
ADDED
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# @boundlessfi/identity-sdk
|
|
2
|
+
|
|
3
|
+
The **Boundless Identity SDK** provides a seamless way to integrate **Passkey-based Smart Wallets** into your application. Built on top of [Smart Account Kit](https://github.com/stellar/smart-account-kit) and [Better-Auth](https://github.com/better-auth/better-auth), it enables users to sign up with a passkey, automatically deploying a non-custodial Stellar Smart Wallet that is linked to their authenticated session.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🔑 **Passkey-First Authentication**: Users log in and sign transactions using FaceID, TouchID, or other WebAuthn credentials.
|
|
8
|
+
- 🔗 **Session Linking**: Automatically links on-chain smart wallets to your application's user database via Better-Auth.
|
|
9
|
+
- 💳 **Smart Wallet Management**: Deploy contracts, track balances, and transfer assets (XLM & Custom Tokens).
|
|
10
|
+
- 🛡️ **Recovery**: Add multiple passkeys for account recovery.
|
|
11
|
+
- ⛽ **Gas & Fees**: Optimized wrapper for transaction submission.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @boundlessfi/identity-sdk
|
|
19
|
+
# or
|
|
20
|
+
pnpm add @boundlessfi/identity-sdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Peer Dependencies
|
|
24
|
+
|
|
25
|
+
Ensure you have the following peer dependencies installed:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm install better-auth smart-account-kit
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Backend Integration
|
|
34
|
+
|
|
35
|
+
The SDK provides a **Better-Auth Plugin** to handle linking Stellar addresses and Passkey credentials to your users.
|
|
36
|
+
|
|
37
|
+
### 1. Register the Plugin
|
|
38
|
+
|
|
39
|
+
In your Better-Auth configuration (e.g., `auth.ts`):
|
|
40
|
+
|
|
41
|
+
```typescript
|
|
42
|
+
import { betterAuth } from "better-auth";
|
|
43
|
+
import { boundlessStellarPlugin } from "@boundlessfi/identity-sdk/server";
|
|
44
|
+
|
|
45
|
+
export const auth = betterAuth({
|
|
46
|
+
// ... your other config
|
|
47
|
+
plugins: [
|
|
48
|
+
boundlessStellarPlugin(), // <--- Add this
|
|
49
|
+
],
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
This plugin automatically adds `stellarAddress` and `credentialId` fields to your User schema and exposes the `/api/auth/stellar/link` endpoint.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Frontend Usage
|
|
58
|
+
|
|
59
|
+
### 1. Initialize the SDK
|
|
60
|
+
|
|
61
|
+
Create an instance of `BoundlessSDK` in your application (e.g., via a React Context or global singleton).
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { BoundlessSDK } from "@boundlessfi/identity-sdk";
|
|
65
|
+
|
|
66
|
+
const boundless = new BoundlessSDK({
|
|
67
|
+
network: "testnet", // or "mainnet"
|
|
68
|
+
rpcUrl: "https://soroban-testnet.stellar.org", // Optional, defaults to Horizon
|
|
69
|
+
backendUrl: "http://localhost:3000", // Your Better-Auth API base URL
|
|
70
|
+
rpId: "localhost", // WebAuthn Relying Party ID (domain)
|
|
71
|
+
rpName: "My App", // App Name for Passkey Prompt
|
|
72
|
+
// relayerProxyUrl: "..." // Optional: For gas sponsorship
|
|
73
|
+
});
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 2. Connect or Register a Wallet
|
|
77
|
+
|
|
78
|
+
#### Connect (Returning User)
|
|
79
|
+
|
|
80
|
+
Prompts the user to sign in with an existing passkey. Checks if a wallet is already deployed.
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
const result = await boundless.connect();
|
|
84
|
+
// Or force the browser prompt:
|
|
85
|
+
// const result = await boundless.connect({ prompt: true });
|
|
86
|
+
|
|
87
|
+
if (result) {
|
|
88
|
+
console.log("Connected:", result.walletAddress);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Register (New User)
|
|
93
|
+
|
|
94
|
+
Creates a new Passkey credential, deploys the Smart Wallet on-chain, and links it to the current auth session.
|
|
95
|
+
> **Note:** The user must be logged into Better-Auth before calling `register`.
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
try {
|
|
99
|
+
const result = await boundless.register("user_email_or_name");
|
|
100
|
+
console.log("New Wallet Deployed:", result.walletAddress);
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error("Registration failed:", error);
|
|
103
|
+
}
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
### 3. Check Balances
|
|
107
|
+
|
|
108
|
+
Fetch Native XLM or Custom Token balances.
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
// Native XLM
|
|
112
|
+
const xlmBalance = await boundless.getBalance(userAddress);
|
|
113
|
+
|
|
114
|
+
// Custom Token (by Contract ID)
|
|
115
|
+
const usdcBalance = await boundless.getBalance(userAddress, "CDLZFC3SYJYDZS7K67TZIK764C4UGR2HXQ4Q47I2255W577333N3K...");
|
|
116
|
+
|
|
117
|
+
// Custom Token (by Asset Code:Issuer)
|
|
118
|
+
const tokenBalance = await boundless.getBalance(userAddress, "USDC:GBBD47IF...");
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 4. Send Transactions
|
|
122
|
+
|
|
123
|
+
Transfer XLM or Tokens.
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
const txResult = await boundless.transfer(
|
|
127
|
+
"G...", // Recipient Address
|
|
128
|
+
"10.5", // Amount
|
|
129
|
+
"XLM" // Asset (or Contract ID / Code:Issuer)
|
|
130
|
+
);
|
|
131
|
+
|
|
132
|
+
if (txResult.success) {
|
|
133
|
+
console.log("Tx Hash:", txResult.hash);
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### 5. Account Recovery
|
|
138
|
+
|
|
139
|
+
Add a secondary passkey (e.g., iCloud Keychain or YubiKey) to ensure access isn't lost.
|
|
140
|
+
|
|
141
|
+
```typescript
|
|
142
|
+
await boundless.addRecoveryKey({
|
|
143
|
+
appName: "My App",
|
|
144
|
+
userName: "user@example.com",
|
|
145
|
+
nickname: "Backup Key"
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
---
|
|
150
|
+
|
|
151
|
+
## Advanced Usage
|
|
152
|
+
|
|
153
|
+
### Accessing Internal Tools
|
|
154
|
+
|
|
155
|
+
You can access the underlying `SmartAccountKit` instance for lower-level operations.
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
const kit = boundless.smartAccountKit;
|
|
159
|
+
// Use kit directly...
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Events
|
|
163
|
+
|
|
164
|
+
Listen to wallet events for UI updates.
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
const unsubscribe = boundless.onEvent("walletConnected", () => {
|
|
168
|
+
console.log("Wallet connected!");
|
|
169
|
+
});
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
## License
|
|
173
|
+
|
|
174
|
+
MIT
|
package/dist/server/index.cjs
CHANGED
|
@@ -30,7 +30,6 @@ var import_zod = require("zod");
|
|
|
30
30
|
var boundlessStellarPlugin = () => {
|
|
31
31
|
return {
|
|
32
32
|
id: "boundless-stellar",
|
|
33
|
-
// Extend the User table to store Stellar data
|
|
34
33
|
schema: {
|
|
35
34
|
user: {
|
|
36
35
|
fields: {
|
|
@@ -41,7 +40,6 @@ var boundlessStellarPlugin = () => {
|
|
|
41
40
|
}
|
|
42
41
|
},
|
|
43
42
|
endpoints: {
|
|
44
|
-
// Endpoint to link a deployed wallet to a session
|
|
45
43
|
linkStellarAccount: (0, import_api.createAuthEndpoint)(
|
|
46
44
|
"/stellar/link",
|
|
47
45
|
{
|
|
@@ -52,7 +50,9 @@ var boundlessStellarPlugin = () => {
|
|
|
52
50
|
})
|
|
53
51
|
},
|
|
54
52
|
async (ctx) => {
|
|
55
|
-
|
|
53
|
+
const session = await (0, import_api.getSessionFromCtx)(ctx);
|
|
54
|
+
console.log(session);
|
|
55
|
+
if (!session) {
|
|
56
56
|
return ctx.json(
|
|
57
57
|
{ success: false, error: "Unauthorized" },
|
|
58
58
|
{ status: 401 }
|
|
@@ -61,7 +61,7 @@ var boundlessStellarPlugin = () => {
|
|
|
61
61
|
const { stellarAddress, credentialId } = ctx.body;
|
|
62
62
|
await ctx.context.adapter.update({
|
|
63
63
|
model: "user",
|
|
64
|
-
where: [{ field: "id", value:
|
|
64
|
+
where: [{ field: "id", value: session.user.id }],
|
|
65
65
|
update: {
|
|
66
66
|
stellarAddress,
|
|
67
67
|
credentialId
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/index.ts","../../src/server/stellar-plugin.ts"],"sourcesContent":["export { boundlessStellarPlugin } from \"./stellar-plugin\";\n","import type { BetterAuthPlugin } from \"better-auth\";\nimport { createAuthEndpoint } from \"better-auth/api\";\nimport { z } from \"zod\";\n\nexport const boundlessStellarPlugin = () => {\n return {\n id: \"boundless-stellar\",\n
|
|
1
|
+
{"version":3,"sources":["../../src/server/index.ts","../../src/server/stellar-plugin.ts"],"sourcesContent":["export { boundlessStellarPlugin } from \"./stellar-plugin\";\n","import type { BetterAuthPlugin } from \"better-auth\";\nimport { createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { z } from \"zod\";\n\nexport const boundlessStellarPlugin = () => {\n return {\n id: \"boundless-stellar\",\n\n schema: {\n user: {\n fields: {\n stellarAddress: { type: \"string\", required: false, input: false },\n credentialId: { type: \"string\", required: false, input: false }, // From WebAuthn\n },\n },\n },\n endpoints: {\n linkStellarAccount: createAuthEndpoint(\n \"/stellar/link\",\n {\n method: \"POST\",\n body: z.object({\n stellarAddress: z\n .string()\n .min(56)\n .max(56)\n .regex(/^C[A-Z0-9]{55}$/, \"Invalid Stellar address format\"),\n credentialId: z.string().min(1, \"Credential ID is required\"),\n }),\n },\n async (ctx) => {\n const session = await getSessionFromCtx(ctx);\n console.log(session);\n if (!session) {\n return ctx.json(\n { success: false, error: \"Unauthorized\" },\n { status: 401 },\n );\n }\n\n const { stellarAddress, credentialId } = ctx.body;\n\n await ctx.context.adapter.update({\n model: \"user\",\n where: [{ field: \"id\", value: session.user.id }],\n update: {\n stellarAddress,\n credentialId,\n },\n });\n return ctx.json({ success: true });\n },\n ),\n },\n } satisfies BetterAuthPlugin;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,iBAAsD;AACtD,iBAAkB;AAEX,IAAM,yBAAyB,MAAM;AAC1C,SAAO;AAAA,IACL,IAAI;AAAA,IAEJ,QAAQ;AAAA,MACN,MAAM;AAAA,QACJ,QAAQ;AAAA,UACN,gBAAgB,EAAE,MAAM,UAAU,UAAU,OAAO,OAAO,MAAM;AAAA,UAChE,cAAc,EAAE,MAAM,UAAU,UAAU,OAAO,OAAO,MAAM;AAAA;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,wBAAoB;AAAA,QAClB;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,MAAM,aAAE,OAAO;AAAA,YACb,gBAAgB,aACb,OAAO,EACP,IAAI,EAAE,EACN,IAAI,EAAE,EACN,MAAM,mBAAmB,gCAAgC;AAAA,YAC5D,cAAc,aAAE,OAAO,EAAE,IAAI,GAAG,2BAA2B;AAAA,UAC7D,CAAC;AAAA,QACH;AAAA,QACA,OAAO,QAAQ;AACb,gBAAM,UAAU,UAAM,8BAAkB,GAAG;AAC3C,kBAAQ,IAAI,OAAO;AACnB,cAAI,CAAC,SAAS;AACZ,mBAAO,IAAI;AAAA,cACT,EAAE,SAAS,OAAO,OAAO,eAAe;AAAA,cACxC,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAEA,gBAAM,EAAE,gBAAgB,aAAa,IAAI,IAAI;AAE7C,gBAAM,IAAI,QAAQ,QAAQ,OAAO;AAAA,YAC/B,OAAO;AAAA,YACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,QAAQ,KAAK,GAAG,CAAC;AAAA,YAC/C,QAAQ;AAAA,cACN;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AACD,iBAAO,IAAI,KAAK,EAAE,SAAS,KAAK,CAAC;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
package/dist/server/index.js
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
// src/server/stellar-plugin.ts
|
|
2
|
-
import { createAuthEndpoint } from "better-auth/api";
|
|
2
|
+
import { createAuthEndpoint, getSessionFromCtx } from "better-auth/api";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
var boundlessStellarPlugin = () => {
|
|
5
5
|
return {
|
|
6
6
|
id: "boundless-stellar",
|
|
7
|
-
// Extend the User table to store Stellar data
|
|
8
7
|
schema: {
|
|
9
8
|
user: {
|
|
10
9
|
fields: {
|
|
@@ -15,7 +14,6 @@ var boundlessStellarPlugin = () => {
|
|
|
15
14
|
}
|
|
16
15
|
},
|
|
17
16
|
endpoints: {
|
|
18
|
-
// Endpoint to link a deployed wallet to a session
|
|
19
17
|
linkStellarAccount: createAuthEndpoint(
|
|
20
18
|
"/stellar/link",
|
|
21
19
|
{
|
|
@@ -26,7 +24,9 @@ var boundlessStellarPlugin = () => {
|
|
|
26
24
|
})
|
|
27
25
|
},
|
|
28
26
|
async (ctx) => {
|
|
29
|
-
|
|
27
|
+
const session = await getSessionFromCtx(ctx);
|
|
28
|
+
console.log(session);
|
|
29
|
+
if (!session) {
|
|
30
30
|
return ctx.json(
|
|
31
31
|
{ success: false, error: "Unauthorized" },
|
|
32
32
|
{ status: 401 }
|
|
@@ -35,7 +35,7 @@ var boundlessStellarPlugin = () => {
|
|
|
35
35
|
const { stellarAddress, credentialId } = ctx.body;
|
|
36
36
|
await ctx.context.adapter.update({
|
|
37
37
|
model: "user",
|
|
38
|
-
where: [{ field: "id", value:
|
|
38
|
+
where: [{ field: "id", value: session.user.id }],
|
|
39
39
|
update: {
|
|
40
40
|
stellarAddress,
|
|
41
41
|
credentialId
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/stellar-plugin.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"better-auth\";\nimport { createAuthEndpoint } from \"better-auth/api\";\nimport { z } from \"zod\";\n\nexport const boundlessStellarPlugin = () => {\n return {\n id: \"boundless-stellar\",\n
|
|
1
|
+
{"version":3,"sources":["../../src/server/stellar-plugin.ts"],"sourcesContent":["import type { BetterAuthPlugin } from \"better-auth\";\nimport { createAuthEndpoint, getSessionFromCtx } from \"better-auth/api\";\nimport { z } from \"zod\";\n\nexport const boundlessStellarPlugin = () => {\n return {\n id: \"boundless-stellar\",\n\n schema: {\n user: {\n fields: {\n stellarAddress: { type: \"string\", required: false, input: false },\n credentialId: { type: \"string\", required: false, input: false }, // From WebAuthn\n },\n },\n },\n endpoints: {\n linkStellarAccount: createAuthEndpoint(\n \"/stellar/link\",\n {\n method: \"POST\",\n body: z.object({\n stellarAddress: z\n .string()\n .min(56)\n .max(56)\n .regex(/^C[A-Z0-9]{55}$/, \"Invalid Stellar address format\"),\n credentialId: z.string().min(1, \"Credential ID is required\"),\n }),\n },\n async (ctx) => {\n const session = await getSessionFromCtx(ctx);\n console.log(session);\n if (!session) {\n return ctx.json(\n { success: false, error: \"Unauthorized\" },\n { status: 401 },\n );\n }\n\n const { stellarAddress, credentialId } = ctx.body;\n\n await ctx.context.adapter.update({\n model: \"user\",\n where: [{ field: \"id\", value: session.user.id }],\n update: {\n stellarAddress,\n credentialId,\n },\n });\n return ctx.json({ success: true });\n },\n ),\n },\n } satisfies BetterAuthPlugin;\n};\n"],"mappings":";AACA,SAAS,oBAAoB,yBAAyB;AACtD,SAAS,SAAS;AAEX,IAAM,yBAAyB,MAAM;AAC1C,SAAO;AAAA,IACL,IAAI;AAAA,IAEJ,QAAQ;AAAA,MACN,MAAM;AAAA,QACJ,QAAQ;AAAA,UACN,gBAAgB,EAAE,MAAM,UAAU,UAAU,OAAO,OAAO,MAAM;AAAA,UAChE,cAAc,EAAE,MAAM,UAAU,UAAU,OAAO,OAAO,MAAM;AAAA;AAAA,QAChE;AAAA,MACF;AAAA,IACF;AAAA,IACA,WAAW;AAAA,MACT,oBAAoB;AAAA,QAClB;AAAA,QACA;AAAA,UACE,QAAQ;AAAA,UACR,MAAM,EAAE,OAAO;AAAA,YACb,gBAAgB,EACb,OAAO,EACP,IAAI,EAAE,EACN,IAAI,EAAE,EACN,MAAM,mBAAmB,gCAAgC;AAAA,YAC5D,cAAc,EAAE,OAAO,EAAE,IAAI,GAAG,2BAA2B;AAAA,UAC7D,CAAC;AAAA,QACH;AAAA,QACA,OAAO,QAAQ;AACb,gBAAM,UAAU,MAAM,kBAAkB,GAAG;AAC3C,kBAAQ,IAAI,OAAO;AACnB,cAAI,CAAC,SAAS;AACZ,mBAAO,IAAI;AAAA,cACT,EAAE,SAAS,OAAO,OAAO,eAAe;AAAA,cACxC,EAAE,QAAQ,IAAI;AAAA,YAChB;AAAA,UACF;AAEA,gBAAM,EAAE,gBAAgB,aAAa,IAAI,IAAI;AAE7C,gBAAM,IAAI,QAAQ,QAAQ,OAAO;AAAA,YAC/B,OAAO;AAAA,YACP,OAAO,CAAC,EAAE,OAAO,MAAM,OAAO,QAAQ,KAAK,GAAG,CAAC;AAAA,YAC/C,QAAQ;AAAA,cACN;AAAA,cACA;AAAA,YACF;AAAA,UACF,CAAC;AACD,iBAAO,IAAI,KAAK,EAAE,SAAS,KAAK,CAAC;AAAA,QACnC;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { BetterAuthPlugin } from "better-auth";
|
|
2
|
-
import { createAuthEndpoint } from "better-auth/api";
|
|
2
|
+
import { createAuthEndpoint, getSessionFromCtx } from "better-auth/api";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
export const boundlessStellarPlugin = () => {
|
|
6
6
|
return {
|
|
7
7
|
id: "boundless-stellar",
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
schema: {
|
|
10
10
|
user: {
|
|
11
11
|
fields: {
|
|
@@ -15,7 +15,6 @@ export const boundlessStellarPlugin = () => {
|
|
|
15
15
|
},
|
|
16
16
|
},
|
|
17
17
|
endpoints: {
|
|
18
|
-
// Endpoint to link a deployed wallet to a session
|
|
19
18
|
linkStellarAccount: createAuthEndpoint(
|
|
20
19
|
"/stellar/link",
|
|
21
20
|
{
|
|
@@ -30,7 +29,9 @@ export const boundlessStellarPlugin = () => {
|
|
|
30
29
|
}),
|
|
31
30
|
},
|
|
32
31
|
async (ctx) => {
|
|
33
|
-
|
|
32
|
+
const session = await getSessionFromCtx(ctx);
|
|
33
|
+
console.log(session);
|
|
34
|
+
if (!session) {
|
|
34
35
|
return ctx.json(
|
|
35
36
|
{ success: false, error: "Unauthorized" },
|
|
36
37
|
{ status: 401 },
|
|
@@ -39,11 +40,9 @@ export const boundlessStellarPlugin = () => {
|
|
|
39
40
|
|
|
40
41
|
const { stellarAddress, credentialId } = ctx.body;
|
|
41
42
|
|
|
42
|
-
// Logic to update the authenticated user's record in the DB
|
|
43
|
-
|
|
44
43
|
await ctx.context.adapter.update({
|
|
45
44
|
model: "user",
|
|
46
|
-
where: [{ field: "id", value:
|
|
45
|
+
where: [{ field: "id", value: session.user.id }],
|
|
47
46
|
update: {
|
|
48
47
|
stellarAddress,
|
|
49
48
|
credentialId,
|