@buildonspark/spark-sdk 0.3.6 → 0.3.8
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/CHANGELOG.md +16 -0
- package/dist/bare/index.cjs +11107 -10443
- package/dist/bare/index.d.cts +274 -219
- package/dist/bare/index.d.ts +274 -219
- package/dist/bare/index.js +11459 -10792
- package/dist/{chunk-LIZFXQWK.js → chunk-3LPEQGVJ.js} +1 -1
- package/dist/{chunk-J2P3KTQP.js → chunk-5ASXVNTM.js} +1 -1
- package/dist/{chunk-FJ7LTA2O.js → chunk-5HU5W56H.js} +40 -213
- package/dist/{chunk-XPHYQ2L6.js → chunk-FP2CRVQH.js} +6471 -5813
- package/dist/{chunk-EHKP3Y65.js → chunk-FXIESWE6.js} +8 -11
- package/dist/{chunk-IC4IUEOS.js → chunk-VFN34EOX.js} +56 -43
- package/dist/{chunk-XWLR6G5C.js → chunk-XI6FCNYG.js} +1 -1
- package/dist/{client-GOlkXliC.d.ts → client-By-N7oJS.d.ts} +13 -11
- package/dist/{client-AHn11NHe.d.cts → client-pNpGP15j.d.cts} +13 -11
- package/dist/debug.cjs +11179 -10516
- package/dist/debug.d.cts +12 -8
- package/dist/debug.d.ts +12 -8
- package/dist/debug.js +5 -5
- package/dist/graphql/objects/index.d.cts +3 -3
- package/dist/graphql/objects/index.d.ts +3 -3
- package/dist/index.cjs +7063 -6395
- package/dist/index.d.cts +8 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +12 -6
- package/dist/index.node.cjs +6598 -6100
- package/dist/index.node.d.cts +8 -7
- package/dist/index.node.d.ts +8 -7
- package/dist/index.node.js +11 -5
- package/dist/{logging-CW3kwBaM.d.cts → logging-DMFVY384.d.ts} +10 -4
- package/dist/{logging-D7ukPwRA.d.ts → logging-DxLp34Xm.d.cts} +10 -4
- package/dist/native/{chunk-X2QXUON7.js → chunk-AFP5QR4O.js} +11 -8
- package/dist/native/{index.cjs → index.react-native.cjs} +7143 -6464
- package/dist/native/{index.d.cts → index.react-native.d.cts} +110 -54
- package/dist/native/{index.d.ts → index.react-native.d.ts} +110 -54
- package/dist/native/{index.js → index.react-native.js} +7162 -6484
- package/dist/native/{wasm-GKEDPGTM.js → wasm-D4TI35NF.js} +1 -1
- package/dist/proto/spark.cjs +56 -43
- package/dist/proto/spark.d.cts +1 -1
- package/dist/proto/spark.d.ts +1 -1
- package/dist/proto/spark.js +1 -1
- package/dist/proto/spark_token.d.cts +1 -1
- package/dist/proto/spark_token.d.ts +1 -1
- package/dist/proto/spark_token.js +2 -2
- package/dist/{spark-WA_4wcBr.d.ts → spark-By6yHsrk.d.cts} +31 -6
- package/dist/{spark-WA_4wcBr.d.cts → spark-By6yHsrk.d.ts} +31 -6
- package/dist/{spark-wallet.browser-Cg4fB-Nm.d.ts → spark-wallet.browser-C1dQknVj.d.ts} +8 -8
- package/dist/{spark-wallet.browser-Db7Y95Kt.d.cts → spark-wallet.browser-CNMo3IvO.d.cts} +8 -8
- package/dist/{spark-wallet.node-HEG2ahNd.d.cts → spark-wallet.node-BZJhJZKq.d.cts} +9 -31
- package/dist/{spark-wallet.node-DB3ZqtJG.d.ts → spark-wallet.node-Og6__NMh.d.ts} +9 -31
- package/dist/tests/test-utils.cjs +8835 -8332
- package/dist/tests/test-utils.d.cts +8 -6
- package/dist/tests/test-utils.d.ts +8 -6
- package/dist/tests/test-utils.js +7 -7
- package/dist/{token-transactions-B2-BO7Oz.d.ts → token-transactions-C7yefB2S.d.ts} +2 -2
- package/dist/{token-transactions-BAN68xwg.d.cts → token-transactions-CLR3rnYi.d.cts} +2 -2
- package/dist/types/index.cjs +56 -43
- package/dist/types/index.d.cts +2 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +2 -2
- package/dist/{spark-wallet-jwNvWvpK.d.ts → wallet-config-BoyMVa6n.d.ts} +293 -267
- package/dist/{spark-wallet-NxG55m7K.d.cts → wallet-config-xom-9UFF.d.cts} +293 -267
- package/package.json +16 -6
- package/src/graphql/client.ts +6 -9
- package/src/graphql/mutations/CompleteCoopExit.ts +1 -1
- package/src/graphql/mutations/RequestCoopExit.ts +3 -1
- package/src/graphql/mutations/RequestLightningSend.ts +3 -1
- package/src/graphql/objects/CompleteCoopExitInput.ts +22 -33
- package/src/graphql/objects/RequestCoopExitInput.ts +39 -45
- package/src/graphql/objects/RequestLightningSendInput.ts +31 -39
- package/src/index.react-native.ts +21 -0
- package/src/proto/mock.ts +0 -264
- package/src/proto/spark.ts +94 -51
- package/src/services/config.ts +7 -2
- package/src/services/connection/connection.browser.ts +27 -19
- package/src/services/connection/connection.node.ts +79 -24
- package/src/services/connection/connection.ts +396 -224
- package/src/services/coop-exit.ts +5 -1
- package/src/services/lightning.ts +30 -4
- package/src/services/signing.ts +137 -0
- package/src/services/token-transactions.ts +8 -8
- package/src/services/transfer.ts +116 -1
- package/src/services/wallet-config.ts +6 -0
- package/src/spark-wallet/proto-descriptors.ts +1 -1
- package/src/spark-wallet/spark-wallet.browser.ts +0 -1
- package/src/spark-wallet/spark-wallet.react-native.ts +5 -3
- package/src/spark-wallet/spark-wallet.ts +124 -83
- package/src/spark_descriptors.pb +0 -0
- package/src/tests/connection.test.ts +537 -0
- package/src/tests/integration/connection.test.ts +39 -0
- package/src/tests/integration/coop-exit.test.ts +2 -0
- package/src/tests/integration/lightning.test.ts +30 -12
- package/src/tests/integration/ssp/coop-exit-validation.test.ts +5 -6
- package/src/tests/integration/ssp/static_deposit.test.ts +45 -35
- package/src/tests/integration/static_deposit.test.ts +11 -10
- package/src/tests/integration/transfer.test.ts +13 -1
- package/src/tests/isHermeticTest.ts +1 -1
- package/src/tests/optimize.test.ts +45 -0
- package/src/tests/token-outputs.test.ts +60 -1
- package/src/tests/utils/test-faucet.ts +65 -28
- package/src/utils/htlc-transactions.ts +224 -0
- package/src/utils/optimize.ts +226 -0
- package/src/utils/transaction.ts +36 -0
- package/src/native/index.ts +0 -21
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type ClientFactory as ClientFactoryWeb,
|
|
8
8
|
} from "nice-grpc-web";
|
|
9
9
|
import { ClientMiddlewareCall, Metadata } from "nice-grpc-common";
|
|
10
|
+
import type { ClientMiddleware } from "nice-grpc-common";
|
|
10
11
|
import { retryMiddleware } from "nice-grpc-client-middleware-retry";
|
|
11
12
|
import { RetryOptions, SparkCallOptions } from "../../types/grpc.js";
|
|
12
13
|
import { WalletConfigService } from "../config.js";
|
|
@@ -26,7 +27,7 @@ export class ConnectionManagerBrowser extends ConnectionManager {
|
|
|
26
27
|
this.transport = transport;
|
|
27
28
|
}
|
|
28
29
|
|
|
29
|
-
protected async createChannelWithTLS(address: string
|
|
30
|
+
protected async createChannelWithTLS(address: string) {
|
|
30
31
|
try {
|
|
31
32
|
return createChannel(address, this.transport);
|
|
32
33
|
} catch (error) {
|
|
@@ -45,9 +46,9 @@ export class ConnectionManagerBrowser extends ConnectionManager {
|
|
|
45
46
|
}
|
|
46
47
|
|
|
47
48
|
protected createAuthnMiddleware() {
|
|
48
|
-
return async function* (
|
|
49
|
+
return async function* <Req, Res>(
|
|
49
50
|
this: ConnectionManagerBrowser,
|
|
50
|
-
call: ClientMiddlewareCall<
|
|
51
|
+
call: ClientMiddlewareCall<Req, Res>,
|
|
51
52
|
options: SparkCallOptions,
|
|
52
53
|
) {
|
|
53
54
|
const metadata = Metadata(options.metadata)
|
|
@@ -55,17 +56,20 @@ export class ConnectionManagerBrowser extends ConnectionManager {
|
|
|
55
56
|
.set("X-Grpc-Web", "1")
|
|
56
57
|
.set("X-Client-Env", clientEnv)
|
|
57
58
|
.set("Content-Type", "application/grpc-web+proto");
|
|
58
|
-
return yield* call.next(call.request, {
|
|
59
|
+
return yield* call.next(call.request as Req, {
|
|
59
60
|
...options,
|
|
60
61
|
metadata,
|
|
61
62
|
});
|
|
62
|
-
}.bind(this)
|
|
63
|
+
}.bind(this) as <Req, Res>(
|
|
64
|
+
call: ClientMiddlewareCall<Req, Res>,
|
|
65
|
+
options: SparkCallOptions,
|
|
66
|
+
) => AsyncGenerator<Res, Res | void, undefined>;
|
|
63
67
|
}
|
|
64
68
|
|
|
65
|
-
protected createMiddleware(address: string
|
|
66
|
-
return async function* (
|
|
69
|
+
protected createMiddleware(address: string) {
|
|
70
|
+
return async function* <Req, Res>(
|
|
67
71
|
this: ConnectionManagerBrowser,
|
|
68
|
-
call: ClientMiddlewareCall<
|
|
72
|
+
call: ClientMiddlewareCall<Req, Res>,
|
|
69
73
|
options: SparkCallOptions,
|
|
70
74
|
) {
|
|
71
75
|
const metadata = Metadata(options.metadata)
|
|
@@ -75,14 +79,12 @@ export class ConnectionManagerBrowser extends ConnectionManager {
|
|
|
75
79
|
.set("Content-Type", "application/grpc-web+proto");
|
|
76
80
|
|
|
77
81
|
try {
|
|
78
|
-
|
|
82
|
+
const token = await this.authenticate(address);
|
|
83
|
+
return yield* call.next(call.request as Req, {
|
|
79
84
|
...options,
|
|
80
|
-
metadata: metadata.set(
|
|
81
|
-
"Authorization",
|
|
82
|
-
`Bearer ${this.clients.get(address)?.authToken || initialAuthToken}`,
|
|
83
|
-
),
|
|
85
|
+
metadata: metadata.set("Authorization", `Bearer ${token}`),
|
|
84
86
|
});
|
|
85
|
-
} catch (error:
|
|
87
|
+
} catch (error: unknown) {
|
|
86
88
|
return yield* this.handleMiddlewareError(
|
|
87
89
|
error,
|
|
88
90
|
address,
|
|
@@ -91,17 +93,21 @@ export class ConnectionManagerBrowser extends ConnectionManager {
|
|
|
91
93
|
options,
|
|
92
94
|
);
|
|
93
95
|
}
|
|
94
|
-
}.bind(this)
|
|
96
|
+
}.bind(this) as <Req, Res>(
|
|
97
|
+
call: ClientMiddlewareCall<Req, Res>,
|
|
98
|
+
options: SparkCallOptions,
|
|
99
|
+
) => AsyncGenerator<Res, Res | void, undefined>;
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
protected async createGrpcClient<T>(
|
|
98
|
-
|
|
103
|
+
definition:
|
|
99
104
|
| SparkAuthnServiceDefinition
|
|
100
105
|
| SparkServiceDefinition
|
|
101
106
|
| SparkTokenServiceDefinition,
|
|
102
107
|
channel: ChannelWeb,
|
|
103
108
|
withRetries: boolean,
|
|
104
|
-
middleware?:
|
|
109
|
+
middleware?: ClientMiddleware<RetryOptions, {}>,
|
|
110
|
+
channelKey?: string,
|
|
105
111
|
) {
|
|
106
112
|
let clientFactory: ClientFactoryWeb;
|
|
107
113
|
|
|
@@ -119,12 +125,14 @@ export class ConnectionManagerBrowser extends ConnectionManager {
|
|
|
119
125
|
if (middleware) {
|
|
120
126
|
clientFactory = clientFactory.use(middleware);
|
|
121
127
|
}
|
|
122
|
-
const client = clientFactory.create(
|
|
128
|
+
const client = clientFactory.create(definition, channel, {
|
|
123
129
|
"*": options,
|
|
124
130
|
}) as T;
|
|
125
131
|
return {
|
|
126
132
|
...client,
|
|
127
|
-
close:
|
|
133
|
+
close: channelKey
|
|
134
|
+
? () => ConnectionManager.releaseChannel(channelKey)
|
|
135
|
+
: undefined,
|
|
128
136
|
};
|
|
129
137
|
}
|
|
130
138
|
}
|
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
type Channel,
|
|
8
8
|
} from "nice-grpc";
|
|
9
9
|
import { ClientMiddlewareCall, Metadata } from "nice-grpc-common";
|
|
10
|
+
import type { ClientMiddleware } from "nice-grpc-common";
|
|
10
11
|
import { RetryOptions, SparkCallOptions } from "../../types/grpc.js";
|
|
11
12
|
import { MockServiceClient, MockServiceDefinition } from "../../proto/mock.js";
|
|
12
13
|
import { SparkServiceDefinition } from "../../proto/spark.js";
|
|
@@ -20,6 +21,8 @@ import { clientEnv } from "../../constants.js";
|
|
|
20
21
|
import fs from "fs";
|
|
21
22
|
|
|
22
23
|
export class ConnectionManagerNodeJS extends ConnectionManager {
|
|
24
|
+
private certPath: string | null = null;
|
|
25
|
+
|
|
23
26
|
constructor(config: WalletConfigService) {
|
|
24
27
|
super(config);
|
|
25
28
|
}
|
|
@@ -29,17 +32,25 @@ export class ConnectionManagerNodeJS extends ConnectionManager {
|
|
|
29
32
|
close: () => void;
|
|
30
33
|
}
|
|
31
34
|
> {
|
|
32
|
-
const
|
|
33
|
-
|
|
35
|
+
const key = this.makeChannelKey(address, false);
|
|
36
|
+
const channel = await ConnectionManager.acquireChannel<Channel>(key, () =>
|
|
37
|
+
this.createChannelWithTLS(address, false),
|
|
38
|
+
);
|
|
34
39
|
const client = createClient(MockServiceDefinition, channel);
|
|
35
|
-
return {
|
|
40
|
+
return {
|
|
41
|
+
...client,
|
|
42
|
+
close: () => ConnectionManager.releaseChannel(key),
|
|
43
|
+
};
|
|
36
44
|
}
|
|
37
45
|
|
|
38
|
-
protected async createChannelWithTLS(
|
|
46
|
+
protected async createChannelWithTLS(
|
|
47
|
+
address: string,
|
|
48
|
+
isStreamClientType: boolean = false,
|
|
49
|
+
) {
|
|
39
50
|
try {
|
|
40
|
-
if (certPath) {
|
|
51
|
+
if (this.certPath) {
|
|
41
52
|
try {
|
|
42
|
-
const cert = fs.readFileSync(certPath);
|
|
53
|
+
const cert = fs.readFileSync(this.certPath);
|
|
43
54
|
return createChannel(address, ChannelCredentials.createSsl(cert));
|
|
44
55
|
} catch (error) {
|
|
45
56
|
console.error("Error reading certificate:", error);
|
|
@@ -53,12 +64,13 @@ export class ConnectionManagerNodeJS extends ConnectionManager {
|
|
|
53
64
|
}
|
|
54
65
|
} else {
|
|
55
66
|
// No cert provided, use insecure SSL for development
|
|
56
|
-
|
|
67
|
+
const ch = createChannel(
|
|
57
68
|
address,
|
|
58
69
|
ChannelCredentials.createSsl(null, null, null, {
|
|
59
70
|
rejectUnauthorized: false,
|
|
60
71
|
}),
|
|
61
72
|
);
|
|
73
|
+
return ch;
|
|
62
74
|
}
|
|
63
75
|
} catch (error) {
|
|
64
76
|
console.error("Channel creation error:", error);
|
|
@@ -76,26 +88,29 @@ export class ConnectionManagerNodeJS extends ConnectionManager {
|
|
|
76
88
|
}
|
|
77
89
|
|
|
78
90
|
protected createAuthnMiddleware() {
|
|
79
|
-
return async function* (
|
|
91
|
+
return async function* <Req, Res>(
|
|
80
92
|
this: ConnectionManagerNodeJS,
|
|
81
|
-
call: ClientMiddlewareCall<
|
|
93
|
+
call: ClientMiddlewareCall<Req, Res>,
|
|
82
94
|
options: SparkCallOptions,
|
|
83
95
|
) {
|
|
84
96
|
const metadata = Metadata(options.metadata).set(
|
|
85
97
|
"X-Client-Env",
|
|
86
98
|
clientEnv,
|
|
87
99
|
);
|
|
88
|
-
return yield* call.next(call.request, {
|
|
100
|
+
return yield* call.next(call.request as Req, {
|
|
89
101
|
...options,
|
|
90
102
|
metadata,
|
|
91
103
|
});
|
|
92
|
-
}.bind(this)
|
|
104
|
+
}.bind(this) as <Req, Res>(
|
|
105
|
+
call: ClientMiddlewareCall<Req, Res>,
|
|
106
|
+
options: SparkCallOptions,
|
|
107
|
+
) => AsyncGenerator<Res, Res | void, undefined>;
|
|
93
108
|
}
|
|
94
109
|
|
|
95
|
-
protected createMiddleware(address: string
|
|
96
|
-
return async function* (
|
|
110
|
+
protected createMiddleware(address: string) {
|
|
111
|
+
return async function* <Req, Res>(
|
|
97
112
|
this: ConnectionManagerNodeJS,
|
|
98
|
-
call: ClientMiddlewareCall<
|
|
113
|
+
call: ClientMiddlewareCall<Req, Res>,
|
|
99
114
|
options: SparkCallOptions,
|
|
100
115
|
) {
|
|
101
116
|
const metadata = Metadata(options.metadata).set(
|
|
@@ -103,12 +118,10 @@ export class ConnectionManagerNodeJS extends ConnectionManager {
|
|
|
103
118
|
clientEnv,
|
|
104
119
|
);
|
|
105
120
|
try {
|
|
106
|
-
|
|
121
|
+
const token = await this.authenticate(address);
|
|
122
|
+
return yield* call.next(call.request as Req, {
|
|
107
123
|
...options,
|
|
108
|
-
metadata: metadata.set(
|
|
109
|
-
"Authorization",
|
|
110
|
-
`Bearer ${this.clients.get(address)?.authToken || initialAuthToken}`,
|
|
111
|
-
),
|
|
124
|
+
metadata: metadata.set("Authorization", `Bearer ${token}`),
|
|
112
125
|
});
|
|
113
126
|
} catch (error: unknown) {
|
|
114
127
|
return yield* this.handleMiddlewareError(
|
|
@@ -119,17 +132,21 @@ export class ConnectionManagerNodeJS extends ConnectionManager {
|
|
|
119
132
|
options,
|
|
120
133
|
);
|
|
121
134
|
}
|
|
122
|
-
}.bind(this)
|
|
135
|
+
}.bind(this) as <Req, Res>(
|
|
136
|
+
call: ClientMiddlewareCall<Req, Res>,
|
|
137
|
+
options: SparkCallOptions,
|
|
138
|
+
) => AsyncGenerator<Res, Res | void, undefined>;
|
|
123
139
|
}
|
|
124
140
|
|
|
125
141
|
protected async createGrpcClient<T>(
|
|
126
|
-
|
|
142
|
+
definition:
|
|
127
143
|
| SparkAuthnServiceDefinition
|
|
128
144
|
| SparkServiceDefinition
|
|
129
145
|
| SparkTokenServiceDefinition,
|
|
130
146
|
channel: Channel,
|
|
131
147
|
withRetries: boolean,
|
|
132
|
-
middleware?:
|
|
148
|
+
middleware?: ClientMiddleware<RetryOptions, {}>,
|
|
149
|
+
channelKey?: string,
|
|
133
150
|
) {
|
|
134
151
|
const retryOptions = {
|
|
135
152
|
retry: true,
|
|
@@ -147,12 +164,50 @@ export class ConnectionManagerNodeJS extends ConnectionManager {
|
|
|
147
164
|
if (middleware) {
|
|
148
165
|
clientFactory = clientFactory.use(middleware);
|
|
149
166
|
}
|
|
150
|
-
const client = clientFactory.create(
|
|
167
|
+
const client = clientFactory.create(definition, channel, {
|
|
151
168
|
"*": options,
|
|
152
169
|
}) as T;
|
|
153
170
|
return {
|
|
154
171
|
...client,
|
|
155
|
-
close:
|
|
172
|
+
close: channelKey
|
|
173
|
+
? () => ConnectionManager.releaseChannel(channelKey)
|
|
174
|
+
: channel.close.bind(channel),
|
|
156
175
|
};
|
|
157
176
|
}
|
|
177
|
+
|
|
178
|
+
override async subscribeToEvents(address: string, signal: AbortSignal) {
|
|
179
|
+
const stream = super.subscribeToEvents(address, signal);
|
|
180
|
+
const channel = await this.getChannelForClient("stream", address);
|
|
181
|
+
|
|
182
|
+
if (!channel) {
|
|
183
|
+
throw new Error("Failed to get channel for client");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// In Node.js, long-lived gRPC streams keep the underlying socket "ref'd",
|
|
187
|
+
// which prevents the process from exiting. To avoid that (e.g. in CLI tools),
|
|
188
|
+
// we manually unref the socket so Node can shut down when nothing else is active.
|
|
189
|
+
//
|
|
190
|
+
// The gRPC client doesn't expose the socket directly, so we dig through
|
|
191
|
+
// internal fields to find it. This is a bit of a hack and may break if the
|
|
192
|
+
// internals change.
|
|
193
|
+
//
|
|
194
|
+
// Since the socket isn't always immediately available, we retry with setTimeout
|
|
195
|
+
// until it shows up.
|
|
196
|
+
const maybeUnref = () => {
|
|
197
|
+
const internalChannel = (channel as any).internalChannel;
|
|
198
|
+
if (
|
|
199
|
+
internalChannel?.currentPicker?.subchannel?.child?.transport?.session
|
|
200
|
+
?.socket
|
|
201
|
+
) {
|
|
202
|
+
internalChannel.currentPicker.subchannel.child.transport.session.socket.unref();
|
|
203
|
+
} else {
|
|
204
|
+
setTimeout(maybeUnref, 100);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
// Only need to unref in Node environments.
|
|
209
|
+
// In the browser and React Native, the runtime handles shutdown when the tab/app closes.
|
|
210
|
+
maybeUnref();
|
|
211
|
+
return stream;
|
|
212
|
+
}
|
|
158
213
|
}
|