stxer 0.3.1 → 0.3.3
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 +93 -4
- package/dist/batch-api.d.ts +16 -3
- package/dist/stxer.cjs.development.js +56 -49
- package/dist/stxer.cjs.development.js.map +1 -1
- package/dist/stxer.cjs.production.min.js +1 -1
- package/dist/stxer.cjs.production.min.js.map +1 -1
- package/dist/stxer.esm.js +57 -50
- package/dist/stxer.esm.js.map +1 -1
- package/package.json +5 -1
- package/src/batch-api.ts +174 -143
- package/src/sample/read.ts +1 -1
package/src/batch-api.ts
CHANGED
|
@@ -1,157 +1,188 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WARNING:
|
|
3
|
+
*
|
|
4
|
+
* this file will be used in cross-runtime environments (browser, cloudflare workers, XLinkSDK, etc.),
|
|
5
|
+
* so please be careful when adding `import`s to it.
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
9
|
+
type ClarityValue,
|
|
10
|
+
type ContractPrincipalCV,
|
|
11
|
+
deserializeCV,
|
|
12
|
+
type OptionalCV,
|
|
13
|
+
serializeCV,
|
|
14
|
+
} from '@stacks/transactions';
|
|
15
|
+
|
|
16
|
+
export interface BatchReads {
|
|
17
|
+
variables?: {
|
|
18
|
+
contract: ContractPrincipalCV;
|
|
19
|
+
variableName: string;
|
|
20
|
+
}[];
|
|
21
|
+
maps?: {
|
|
22
|
+
contract: ContractPrincipalCV;
|
|
23
|
+
mapName: string;
|
|
24
|
+
mapKey: ClarityValue;
|
|
25
|
+
}[];
|
|
26
|
+
readonly?: {
|
|
27
|
+
contract: ContractPrincipalCV;
|
|
28
|
+
functionName: string;
|
|
29
|
+
functionArgs: ClarityValue[];
|
|
30
|
+
}[];
|
|
31
|
+
index_block_hash?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export interface BatchReadsResult {
|
|
35
|
+
tip: string;
|
|
36
|
+
vars: (ClarityValue | Error)[];
|
|
37
|
+
maps: (ClarityValue | Error)[];
|
|
38
|
+
readonly: (ClarityValue | Error)[];
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface BatchApiOptions {
|
|
42
|
+
stxerApi?: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const DEFAULT_STXER_API = 'https://api.stxer.xyz';
|
|
46
|
+
|
|
47
|
+
function convertResults(
|
|
48
|
+
rs: ({ Ok: string } | { Err: string })[],
|
|
49
|
+
): (ClarityValue | Error)[] {
|
|
50
|
+
const results: (ClarityValue | Error)[] = [];
|
|
51
|
+
for (const v of rs) {
|
|
52
|
+
if ('Ok' in v) {
|
|
53
|
+
results.push(deserializeCV(v.Ok));
|
|
54
|
+
} else {
|
|
55
|
+
results.push(new Error(v.Err));
|
|
42
56
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
reads.index_block_hash
|
|
55
|
-
? null
|
|
56
|
-
: reads.index_block_hash.startsWith('0x')
|
|
57
|
+
}
|
|
58
|
+
return results;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export async function batchRead(
|
|
62
|
+
reads: BatchReads,
|
|
63
|
+
options: BatchApiOptions = {}
|
|
64
|
+
): Promise<BatchReadsResult> {
|
|
65
|
+
const ibh =
|
|
66
|
+
reads.index_block_hash == null
|
|
67
|
+
? undefined
|
|
68
|
+
: reads.index_block_hash.startsWith('0x')
|
|
57
69
|
? reads.index_block_hash.substring(2)
|
|
58
70
|
: reads.index_block_hash;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
`Requesting batch reads failed: ${text}, url: ${url}, payload: ${JSON.stringify(
|
|
71
|
-
payload
|
|
72
|
-
)}`
|
|
73
|
-
);
|
|
71
|
+
|
|
72
|
+
const payload: {
|
|
73
|
+
tip?: string;
|
|
74
|
+
vars: string[][];
|
|
75
|
+
maps: string[][];
|
|
76
|
+
readonly: string[][];
|
|
77
|
+
} = { vars: [], maps: [], readonly: [], tip: ibh };
|
|
78
|
+
|
|
79
|
+
if (reads.variables != null) {
|
|
80
|
+
for (const variable of reads.variables) {
|
|
81
|
+
payload.vars.push([serializeCV(variable.contract), variable.variableName]);
|
|
74
82
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
const result = results[i];
|
|
85
|
-
if ('Ok' in result) {
|
|
86
|
-
rs.variables.push(deserializeCV(result.Ok));
|
|
87
|
-
} else {
|
|
88
|
-
rs.variables.push(new Error(result.Err));
|
|
89
|
-
}
|
|
90
|
-
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
if (reads.maps != null) {
|
|
86
|
+
for (const map of reads.maps) {
|
|
87
|
+
payload.maps.push([
|
|
88
|
+
serializeCV(map.contract),
|
|
89
|
+
map.mapName,
|
|
90
|
+
serializeCV(map.mapKey),
|
|
91
|
+
]);
|
|
91
92
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (reads.readonly != null) {
|
|
96
|
+
for (const ro of reads.readonly) {
|
|
97
|
+
payload.readonly.push([
|
|
98
|
+
serializeCV(ro.contract),
|
|
99
|
+
ro.functionName,
|
|
100
|
+
...ro.functionArgs.map(v => serializeCV(v)),
|
|
101
|
+
]);
|
|
101
102
|
}
|
|
102
|
-
return rs;
|
|
103
103
|
}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
104
|
+
|
|
105
|
+
const url = `${options.stxerApi ?? DEFAULT_STXER_API}/sidecar/v2/batch`;
|
|
106
|
+
const data = await fetch(url, {
|
|
107
|
+
method: 'POST',
|
|
108
|
+
body: JSON.stringify(payload),
|
|
109
|
+
headers: {
|
|
110
|
+
'Content-Type': 'application/json',
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const text = await data.text();
|
|
115
|
+
if (!text.includes('Ok') && !text.includes('Err')) {
|
|
116
|
+
throw new Error(
|
|
117
|
+
`Requesting batch reads failed: ${text}, url: ${url}, payload: ${JSON.stringify(
|
|
118
|
+
payload,
|
|
119
|
+
)}`,
|
|
120
|
+
);
|
|
112
121
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
|
|
123
|
+
const rs = JSON.parse(text) as {
|
|
124
|
+
tip: string;
|
|
125
|
+
vars: ({ Ok: string } | { Err: string })[];
|
|
126
|
+
maps: ({ Ok: string } | { Err: string })[];
|
|
127
|
+
readonly: ({ Ok: string } | { Err: string })[];
|
|
128
|
+
};
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
tip: rs.tip,
|
|
132
|
+
vars: convertResults(rs.vars),
|
|
133
|
+
maps: convertResults(rs.maps),
|
|
134
|
+
readonly: convertResults(rs.readonly),
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
export interface BatchReadonlyRequest {
|
|
139
|
+
readonly: {
|
|
140
|
+
contract: ContractPrincipalCV;
|
|
141
|
+
functionName: string;
|
|
142
|
+
functionArgs: ClarityValue[];
|
|
143
|
+
}[];
|
|
144
|
+
index_block_hash?: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export async function batchReadonly(
|
|
148
|
+
req: BatchReadonlyRequest,
|
|
149
|
+
options: BatchApiOptions = {}
|
|
150
|
+
): Promise<(ClarityValue | Error)[]> {
|
|
151
|
+
const payload = req.readonly.map((r) => [
|
|
152
|
+
serializeCV(r.contract),
|
|
153
|
+
r.functionName,
|
|
154
|
+
...r.functionArgs.map((arg) => serializeCV(arg)),
|
|
155
|
+
]);
|
|
156
|
+
|
|
157
|
+
const ibh =
|
|
158
|
+
req.index_block_hash == null
|
|
159
|
+
? null
|
|
160
|
+
: req.index_block_hash.startsWith('0x')
|
|
128
161
|
? req.index_block_hash.substring(2)
|
|
129
162
|
: req.index_block_hash;
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
ibh == null ? '' : `?tip=${ibh}`
|
|
163
|
+
|
|
164
|
+
const url = `${options.stxerApi ?? DEFAULT_STXER_API}/sidecar/v2/batch-readonly${ibh == null ? '' : `?tip=${ibh}`
|
|
133
165
|
}`;
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
}
|
|
166
|
+
const data = await fetch(url, {
|
|
167
|
+
method: 'POST',
|
|
168
|
+
body: JSON.stringify(payload),
|
|
169
|
+
});
|
|
170
|
+
const text = await data.text();
|
|
171
|
+
if (!text.includes('Ok') && !text.includes('Err')) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`Requesting batch readonly failed: ${text}, url: ${url}, payload: ${JSON.stringify(
|
|
174
|
+
payload
|
|
175
|
+
)}`
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
const results = JSON.parse(text) as [{ Ok: string } | { Err: string }];
|
|
179
|
+
const rs: (ClarityValue | Error)[] = [];
|
|
180
|
+
for (const result of results) {
|
|
181
|
+
if ('Ok' in result) {
|
|
182
|
+
rs.push(deserializeCV(result.Ok));
|
|
183
|
+
} else {
|
|
184
|
+
rs.push(new Error(result.Err));
|
|
154
185
|
}
|
|
155
|
-
return rs;
|
|
156
186
|
}
|
|
157
|
-
|
|
187
|
+
return rs;
|
|
188
|
+
}
|