@1sat/wallet 0.0.3 → 0.0.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.
Files changed (121) hide show
  1. package/dist/OneSatWallet.d.ts +222 -0
  2. package/dist/OneSatWallet.d.ts.map +1 -0
  3. package/dist/OneSatWallet.js +754 -0
  4. package/dist/OneSatWallet.js.map +1 -0
  5. package/dist/address-sync/AddressManager.d.ts +86 -0
  6. package/dist/address-sync/AddressManager.d.ts.map +1 -0
  7. package/dist/address-sync/AddressManager.js +108 -0
  8. package/dist/address-sync/AddressManager.js.map +1 -0
  9. package/dist/address-sync/AddressSyncManager.d.ts +204 -0
  10. package/dist/address-sync/AddressSyncManager.d.ts.map +1 -0
  11. package/dist/address-sync/AddressSyncManager.js +525 -0
  12. package/dist/address-sync/AddressSyncManager.js.map +1 -0
  13. package/dist/address-sync/AddressSyncQueueIdb.d.ts +31 -0
  14. package/dist/address-sync/AddressSyncQueueIdb.d.ts.map +1 -0
  15. package/dist/address-sync/AddressSyncQueueIdb.js +356 -0
  16. package/dist/address-sync/AddressSyncQueueIdb.js.map +1 -0
  17. package/dist/address-sync/AddressSyncQueueSqlite.d.ts +55 -0
  18. package/dist/address-sync/AddressSyncQueueSqlite.d.ts.map +1 -0
  19. package/dist/address-sync/AddressSyncQueueSqlite.js +198 -0
  20. package/dist/address-sync/AddressSyncQueueSqlite.js.map +1 -0
  21. package/dist/address-sync/index.d.ts +8 -0
  22. package/dist/address-sync/index.d.ts.map +1 -0
  23. package/dist/address-sync/index.js +5 -0
  24. package/dist/address-sync/index.js.map +1 -0
  25. package/dist/backup/FileBackupProvider.d.ts +97 -0
  26. package/dist/backup/FileBackupProvider.d.ts.map +1 -0
  27. package/dist/backup/FileBackupProvider.js +185 -0
  28. package/dist/backup/FileBackupProvider.js.map +1 -0
  29. package/dist/backup/FileRestoreReader.d.ts +59 -0
  30. package/dist/backup/FileRestoreReader.d.ts.map +1 -0
  31. package/dist/backup/FileRestoreReader.js +89 -0
  32. package/dist/backup/FileRestoreReader.js.map +1 -0
  33. package/dist/backup/index.d.ts +6 -0
  34. package/dist/backup/index.d.ts.map +1 -0
  35. package/dist/backup/index.js +5 -0
  36. package/dist/backup/index.js.map +1 -0
  37. package/dist/backup/types.d.ts +32 -0
  38. package/dist/backup/types.d.ts.map +1 -0
  39. package/dist/backup/types.js +2 -0
  40. package/dist/backup/types.js.map +1 -0
  41. package/dist/cwi/chrome.d.ts +12 -0
  42. package/dist/cwi/chrome.d.ts.map +1 -0
  43. package/dist/cwi/chrome.js +44 -0
  44. package/dist/cwi/chrome.js.map +1 -0
  45. package/dist/cwi/event.d.ts +12 -0
  46. package/dist/cwi/event.d.ts.map +1 -0
  47. package/dist/cwi/event.js +39 -0
  48. package/dist/cwi/event.js.map +1 -0
  49. package/dist/cwi/factory.d.ts +15 -0
  50. package/dist/cwi/factory.d.ts.map +1 -0
  51. package/dist/cwi/factory.js +45 -0
  52. package/dist/cwi/factory.js.map +1 -0
  53. package/dist/cwi/index.d.ts +12 -0
  54. package/dist/cwi/index.d.ts.map +1 -0
  55. package/dist/cwi/index.js +12 -0
  56. package/dist/cwi/index.js.map +1 -0
  57. package/dist/cwi/types.d.ts +40 -0
  58. package/dist/cwi/types.d.ts.map +1 -0
  59. package/dist/cwi/types.js +40 -0
  60. package/dist/cwi/types.js.map +1 -0
  61. package/dist/index.d.ts +17 -20
  62. package/dist/index.d.ts.map +1 -1
  63. package/dist/index.js +22 -21
  64. package/dist/index.js.map +1 -1
  65. package/dist/indexers/Bsv21Indexer.d.ts +36 -0
  66. package/dist/indexers/Bsv21Indexer.d.ts.map +1 -0
  67. package/dist/indexers/Bsv21Indexer.js +232 -0
  68. package/dist/indexers/Bsv21Indexer.js.map +1 -0
  69. package/dist/indexers/CosignIndexer.d.ts +14 -0
  70. package/dist/indexers/CosignIndexer.d.ts.map +1 -0
  71. package/dist/indexers/CosignIndexer.js +27 -0
  72. package/dist/indexers/CosignIndexer.js.map +1 -0
  73. package/dist/indexers/FundIndexer.d.ts +20 -0
  74. package/dist/indexers/FundIndexer.d.ts.map +1 -0
  75. package/dist/indexers/FundIndexer.js +65 -0
  76. package/dist/indexers/FundIndexer.js.map +1 -0
  77. package/dist/indexers/InscriptionIndexer.d.ts +33 -0
  78. package/dist/indexers/InscriptionIndexer.d.ts.map +1 -0
  79. package/dist/indexers/InscriptionIndexer.js +116 -0
  80. package/dist/indexers/InscriptionIndexer.js.map +1 -0
  81. package/dist/indexers/LockIndexer.d.ts +11 -0
  82. package/dist/indexers/LockIndexer.d.ts.map +1 -0
  83. package/dist/indexers/LockIndexer.js +44 -0
  84. package/dist/indexers/LockIndexer.js.map +1 -0
  85. package/dist/indexers/MapIndexer.d.ts +14 -0
  86. package/dist/indexers/MapIndexer.d.ts.map +1 -0
  87. package/dist/indexers/MapIndexer.js +65 -0
  88. package/dist/indexers/MapIndexer.js.map +1 -0
  89. package/dist/indexers/OpNSIndexer.d.ts +10 -0
  90. package/dist/indexers/OpNSIndexer.d.ts.map +1 -0
  91. package/dist/indexers/OpNSIndexer.js +39 -0
  92. package/dist/indexers/OpNSIndexer.js.map +1 -0
  93. package/dist/indexers/OrdLockIndexer.d.ts +18 -0
  94. package/dist/indexers/OrdLockIndexer.d.ts.map +1 -0
  95. package/dist/indexers/OrdLockIndexer.js +65 -0
  96. package/dist/indexers/OrdLockIndexer.js.map +1 -0
  97. package/dist/indexers/OriginIndexer.d.ts +38 -0
  98. package/dist/indexers/OriginIndexer.d.ts.map +1 -0
  99. package/dist/indexers/OriginIndexer.js +241 -0
  100. package/dist/indexers/OriginIndexer.js.map +1 -0
  101. package/dist/indexers/Outpoint.d.ts +11 -0
  102. package/dist/indexers/Outpoint.d.ts.map +1 -0
  103. package/dist/indexers/Outpoint.js +62 -0
  104. package/dist/indexers/Outpoint.js.map +1 -0
  105. package/dist/indexers/SigmaIndexer.d.ts +29 -0
  106. package/dist/indexers/SigmaIndexer.d.ts.map +1 -0
  107. package/dist/indexers/SigmaIndexer.js +134 -0
  108. package/dist/indexers/SigmaIndexer.js.map +1 -0
  109. package/dist/indexers/index.d.ts +14 -0
  110. package/dist/indexers/index.d.ts.map +1 -0
  111. package/dist/indexers/index.js +14 -0
  112. package/dist/indexers/index.js.map +1 -0
  113. package/dist/indexers/parseAddress.d.ts +10 -0
  114. package/dist/indexers/parseAddress.d.ts.map +1 -0
  115. package/dist/indexers/parseAddress.js +25 -0
  116. package/dist/indexers/parseAddress.js.map +1 -0
  117. package/dist/signers/ReadOnlySigner.d.ts +16 -0
  118. package/dist/signers/ReadOnlySigner.d.ts.map +1 -0
  119. package/dist/signers/ReadOnlySigner.js +48 -0
  120. package/dist/signers/ReadOnlySigner.js.map +1 -0
  121. package/package.json +8 -6
@@ -0,0 +1,232 @@
1
+ import { HttpError } from '@1sat/client';
2
+ import { BSV21_FEE_XPUB } from '@1sat/constants';
3
+ import { Indexer, } from '@1sat/types';
4
+ import { BSV21 } from '@bopen-io/templates';
5
+ import { HD, Hash, Utils } from '@bsv/sdk';
6
+ const hdKey = HD.fromString(BSV21_FEE_XPUB);
7
+ /**
8
+ * Bsv21Indexer identifies and validates BSV21 tokens.
9
+ * These are 1-sat outputs with application/bsv-20 inscription type.
10
+ *
11
+ * Data structure: Bsv21 with id, op, amt, dec, status, etc.
12
+ *
13
+ * Basket: 'bsv21'
14
+ * Events: id, id:status, bsv21:amt
15
+ */
16
+ export class Bsv21Indexer extends Indexer {
17
+ owners;
18
+ network;
19
+ services;
20
+ tag = 'bsv21';
21
+ name = 'BSV21 Tokens';
22
+ constructor(owners, network, services) {
23
+ super(owners, network);
24
+ this.owners = owners;
25
+ this.network = network;
26
+ this.services = services;
27
+ }
28
+ async parse(txo) {
29
+ const lockingScript = txo.output.lockingScript;
30
+ // Use template decode
31
+ const decoded = BSV21.decode(lockingScript);
32
+ if (!decoded)
33
+ return;
34
+ const outpoint = txo.outpoint;
35
+ const tokenData = decoded.tokenData;
36
+ // Determine token ID - for deploy ops it's this outpoint, otherwise from inscription
37
+ const tokenId = tokenData.id || outpoint.toOrdinalString();
38
+ // Determine initial status:
39
+ // - deploy ops (deploy+mint, deploy+auth) are always valid (they create the token)
40
+ // - transfer/burn ops start as pending until validated in summarize()
41
+ const isDeploy = tokenData.op.startsWith('deploy');
42
+ const initialStatus = isDeploy ? 'valid' : 'pending';
43
+ // Create indexer data structure with basic info from inscription
44
+ const bsv21 = {
45
+ id: tokenId,
46
+ op: tokenData.op,
47
+ amt: decoded.getAmount(),
48
+ dec: decoded.getDecimals(),
49
+ sym: tokenData.sym,
50
+ icon: tokenData.icon,
51
+ status: initialStatus,
52
+ fundAddress: deriveFundAddress(outpoint.toBEBinary()),
53
+ };
54
+ // For non-deploy ops, fetch token metadata from server (cached)
55
+ // This ensures we always have sym, dec, icon for any token
56
+ if (!isDeploy) {
57
+ try {
58
+ const details = await this.services.bsv21.getTokenDetails(tokenId);
59
+ bsv21.sym = details.token.sym;
60
+ bsv21.icon = resolveIcon(details.token.icon, tokenId);
61
+ bsv21.dec = Number(details.token.dec) || 0;
62
+ }
63
+ catch (e) {
64
+ // Token not found on server - could be unconfirmed or invalid
65
+ // Keep local values from inscription, status remains pending
66
+ if (!(e instanceof HttpError && e.status === 404)) {
67
+ throw e;
68
+ }
69
+ }
70
+ }
71
+ else {
72
+ // For deploy ops, resolve relative icon reference if present
73
+ bsv21.icon = resolveIcon(bsv21.icon, tokenId);
74
+ }
75
+ // Validate amount range
76
+ if (bsv21.amt <= 0n || bsv21.amt > 2n ** 64n - 1n)
77
+ return;
78
+ const tags = [];
79
+ if (txo.owner && this.owners.has(txo.owner)) {
80
+ tags.push(`id:${bsv21.id}`);
81
+ tags.push(`amt:${bsv21.amt.toString()}`);
82
+ // Add metadata tags for efficient querying
83
+ if (bsv21.sym)
84
+ tags.push(`sym:${bsv21.sym}`);
85
+ if (bsv21.icon)
86
+ tags.push(`icon:${bsv21.icon}`);
87
+ tags.push(`dec:${bsv21.dec}`);
88
+ }
89
+ return {
90
+ data: bsv21,
91
+ tags,
92
+ basket: 'bsv21',
93
+ };
94
+ }
95
+ async summarize(ctx) {
96
+ // Track token flows per token ID for validation
97
+ const tokenFlows = {};
98
+ let summaryToken;
99
+ let summaryBalance = 0;
100
+ // Process inputs from ctx.spends (already parsed)
101
+ for (const spend of ctx.spends) {
102
+ const bsv21 = spend.data.bsv21;
103
+ if (!bsv21)
104
+ continue;
105
+ const tokenData = bsv21.data;
106
+ // Initialize token tracking
107
+ if (!tokenFlows[tokenData.id]) {
108
+ tokenFlows[tokenData.id] = {
109
+ tokensIn: 0n,
110
+ tokensOut: 0n,
111
+ inputsPending: false,
112
+ };
113
+ }
114
+ const flow = tokenFlows[tokenData.id];
115
+ // Validate this input exists on the overlay
116
+ try {
117
+ await this.services.bsv21.getTokenByTxid(tokenData.id, spend.outpoint.txid);
118
+ }
119
+ catch (e) {
120
+ if (e instanceof HttpError && e.status === 404) {
121
+ // Input not on overlay yet - outputs will be pending
122
+ flow.inputsPending = true;
123
+ }
124
+ else {
125
+ throw e;
126
+ }
127
+ }
128
+ // Accumulate tokens in
129
+ flow.tokensIn += tokenData.amt;
130
+ if (!summaryToken)
131
+ summaryToken = tokenData;
132
+ // Track balance change for owned inputs
133
+ if (summaryToken &&
134
+ tokenData.id === summaryToken.id &&
135
+ spend.owner &&
136
+ this.owners.has(spend.owner)) {
137
+ summaryBalance -= Number(tokenData.amt);
138
+ }
139
+ }
140
+ // Process outputs: accumulate tokensOut and validate
141
+ for (const txo of ctx.txos) {
142
+ const bsv21 = txo.data.bsv21;
143
+ if (!bsv21 || !['transfer', 'burn'].includes(bsv21.data.op))
144
+ continue;
145
+ const tokenData = bsv21.data;
146
+ const flow = tokenFlows[tokenData.id];
147
+ if (flow) {
148
+ flow.tokensOut += tokenData.amt;
149
+ }
150
+ else {
151
+ // No inputs for this token - invalid (attempting to create tokens from nothing)
152
+ tokenData.status = 'invalid';
153
+ }
154
+ if (!summaryToken)
155
+ summaryToken = tokenData;
156
+ // Track balance change for owned outputs
157
+ if (summaryToken &&
158
+ tokenData.id === summaryToken.id &&
159
+ txo.owner &&
160
+ this.owners.has(txo.owner)) {
161
+ summaryBalance += Number(tokenData.amt);
162
+ }
163
+ }
164
+ // Finalize validation and apply status to outputs
165
+ for (const txo of ctx.txos) {
166
+ const bsv21 = txo.data.bsv21;
167
+ if (!bsv21 || !['transfer', 'burn'].includes(bsv21.data.op))
168
+ continue;
169
+ const tokenData = bsv21.data;
170
+ if (tokenData.status === 'invalid')
171
+ continue; // Already marked invalid
172
+ const flow = tokenFlows[tokenData.id];
173
+ if (!flow)
174
+ continue;
175
+ // Determine final status
176
+ if (flow.inputsPending) {
177
+ tokenData.status = 'pending';
178
+ }
179
+ else if (flow.tokensIn >= flow.tokensOut) {
180
+ tokenData.status = 'valid';
181
+ }
182
+ else {
183
+ tokenData.status = 'invalid';
184
+ }
185
+ }
186
+ if (summaryToken?.sym) {
187
+ return {
188
+ id: summaryToken.sym,
189
+ amount: summaryBalance / 10 ** (summaryToken.dec || 0),
190
+ icon: summaryToken.icon,
191
+ };
192
+ }
193
+ }
194
+ serialize(bsv21) {
195
+ return JSON.stringify({
196
+ ...bsv21,
197
+ amt: bsv21.amt.toString(10),
198
+ });
199
+ }
200
+ deserialize(str) {
201
+ const obj = JSON.parse(str);
202
+ return {
203
+ ...obj,
204
+ amt: BigInt(obj.amt),
205
+ };
206
+ }
207
+ }
208
+ /**
209
+ * Resolve a relative icon reference to an absolute outpoint.
210
+ * If icon starts with "_", it's a relative reference to another output
211
+ * in the same transaction as the token deploy. We resolve it by
212
+ * prepending the token ID's txid.
213
+ *
214
+ * Example: tokenId = "abc123...def_0", icon = "_1" -> "abc123...def_1"
215
+ */
216
+ function resolveIcon(icon, tokenId) {
217
+ if (!icon || !icon.startsWith('_'))
218
+ return icon;
219
+ // Token ID format is "txid_vout", extract the txid
220
+ const txid = tokenId.substring(0, 64);
221
+ // Icon format is "_vout", combine with txid
222
+ return `${txid}${icon}`;
223
+ }
224
+ export function deriveFundAddress(idOrOutpoint) {
225
+ const hash = Hash.sha256(idOrOutpoint);
226
+ const reader = new Utils.Reader(hash);
227
+ let path = `m/21/${reader.readUInt32BE() >> 1}`;
228
+ reader.pos = 24;
229
+ path += `/${reader.readUInt32BE() >> 1}`;
230
+ return hdKey.derive(path).pubKey.toAddress();
231
+ }
232
+ //# sourceMappingURL=Bsv21Indexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Bsv21Indexer.js","sourceRoot":"","sources":["../../src/indexers/Bsv21Indexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { Indexer, type ParseResult, type Txo } from '@1sat/types';
2
+ export interface CosignData {
3
+ address: string;
4
+ cosigner: string;
5
+ }
6
+ export declare class CosignIndexer extends Indexer {
7
+ owners: Set<string>;
8
+ network: 'mainnet' | 'testnet';
9
+ tag: string;
10
+ name: string;
11
+ constructor(owners?: Set<string>, network?: 'mainnet' | 'testnet');
12
+ parse(txo: Txo): Promise<ParseResult | undefined>;
13
+ }
14
+ //# sourceMappingURL=CosignIndexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CosignIndexer.d.ts","sourceRoot":"","sources":["../../src/indexers/CosignIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,GAAG,EAAE,MAAM,aAAa,CAAA;AAGjE,MAAM,WAAW,UAAU;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CAChB;AAED,qBAAa,aAAc,SAAQ,OAAO;IAKjC,MAAM;IACN,OAAO,EAAE,SAAS,GAAG,SAAS;IALtC,GAAG,SAAW;IACd,IAAI,SAAW;gBAGP,MAAM,cAAoB,EAC1B,OAAO,GAAE,SAAS,GAAG,SAAqB;IAK5C,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;CAcvD"}
@@ -0,0 +1,27 @@
1
+ import { Indexer } from '@1sat/types';
2
+ import { Cosign } from '@bopen-io/templates';
3
+ export class CosignIndexer extends Indexer {
4
+ owners;
5
+ network;
6
+ tag = 'cosign';
7
+ name = 'Cosign';
8
+ constructor(owners = new Set(), network = 'mainnet') {
9
+ super(owners, network);
10
+ this.owners = owners;
11
+ this.network = network;
12
+ }
13
+ async parse(txo) {
14
+ const lockingScript = txo.output.lockingScript;
15
+ // Use template decode
16
+ const decoded = Cosign.decode(lockingScript, this.network === 'mainnet');
17
+ if (!decoded)
18
+ return;
19
+ return {
20
+ data: decoded,
21
+ tags: [],
22
+ owner: decoded.address,
23
+ protocol: 'basket insertion', // Cosign script requires cosigner signature
24
+ };
25
+ }
26
+ }
27
+ //# sourceMappingURL=CosignIndexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CosignIndexer.js","sourceRoot":"","sources":["../../src/indexers/CosignIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAA8B,MAAM,aAAa,CAAA;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAA;AAO5C,MAAM,OAAO,aAAc,SAAQ,OAAO;IAKjC;IACA;IALR,GAAG,GAAG,QAAQ,CAAA;IACd,IAAI,GAAG,QAAQ,CAAA;IAEf,YACQ,SAAS,IAAI,GAAG,EAAU,EAC1B,UAAiC,SAAS;QAEjD,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAHf,WAAM,GAAN,MAAM,CAAoB;QAC1B,YAAO,GAAP,OAAO,CAAmC;IAGlD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAQ;QACnB,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAA;QAE9C,sBAAsB;QACtB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAA;QACxE,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,OAAO;YACN,IAAI,EAAE,OAAqB;YAC3B,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,OAAO,CAAC,OAAO;YACtB,QAAQ,EAAE,kBAAkB,EAAE,4CAA4C;SAC1E,CAAA;IACF,CAAC;CACD"}
@@ -0,0 +1,20 @@
1
+ import { type IndexSummary, Indexer, type ParseContext, type ParseResult, type Txo } from '@1sat/types';
2
+ /**
3
+ * FundIndexer identifies P2PKH outputs to owned addresses.
4
+ * These are standard "funding" UTXOs that can be spent normally.
5
+ *
6
+ * Data structure: string (address)
7
+ *
8
+ * Basket: 'fund'
9
+ * Tags: None
10
+ */
11
+ export declare class FundIndexer extends Indexer {
12
+ owners: Set<string>;
13
+ network: 'mainnet' | 'testnet';
14
+ tag: string;
15
+ name: string;
16
+ constructor(owners?: Set<string>, network?: 'mainnet' | 'testnet');
17
+ parse(txo: Txo): Promise<ParseResult | undefined>;
18
+ summarize(ctx: ParseContext): Promise<IndexSummary | undefined>;
19
+ }
20
+ //# sourceMappingURL=FundIndexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FundIndexer.d.ts","sourceRoot":"","sources":["../../src/indexers/FundIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,OAAO,EACP,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,GAAG,EACR,MAAM,aAAa,CAAA;AAGpB;;;;;;;;GAQG;AACH,qBAAa,WAAY,SAAQ,OAAO;IAK/B,MAAM;IACN,OAAO,EAAE,SAAS,GAAG,SAAS;IALtC,GAAG,SAAS;IACZ,IAAI,SAAU;gBAGN,MAAM,cAAoB,EAC1B,OAAO,GAAE,SAAS,GAAG,SAAqB;IAK5C,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAcjD,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;CAkCrE"}
@@ -0,0 +1,65 @@
1
+ import { Indexer, } from '@1sat/types';
2
+ import { parseAddress } from './parseAddress';
3
+ /**
4
+ * FundIndexer identifies P2PKH outputs to owned addresses.
5
+ * These are standard "funding" UTXOs that can be spent normally.
6
+ *
7
+ * Data structure: string (address)
8
+ *
9
+ * Basket: 'fund'
10
+ * Tags: None
11
+ */
12
+ export class FundIndexer extends Indexer {
13
+ owners;
14
+ network;
15
+ tag = 'fund';
16
+ name = 'Funds';
17
+ constructor(owners = new Set(), network = 'mainnet') {
18
+ super(owners, network);
19
+ this.owners = owners;
20
+ this.network = network;
21
+ }
22
+ async parse(txo) {
23
+ const script = txo.output.lockingScript;
24
+ const satoshis = BigInt(txo.output.satoshis || 0);
25
+ const address = parseAddress(script, 0, this.network);
26
+ if (satoshis < 2n)
27
+ return;
28
+ return {
29
+ data: address,
30
+ tags: [],
31
+ owner: address,
32
+ basket: 'fund',
33
+ };
34
+ }
35
+ async summarize(ctx) {
36
+ let satsOut = 0n;
37
+ let satsIn = 0n;
38
+ // Calculate satoshis spent from our addresses (inputs)
39
+ for (const input of ctx.tx.inputs) {
40
+ if (!input.sourceTransaction) {
41
+ // If we don't have source transaction data, we can't determine balance change
42
+ return;
43
+ }
44
+ const sourceOutput = input.sourceTransaction.outputs[input.sourceOutputIndex];
45
+ const address = parseAddress(sourceOutput.lockingScript, 0, this.network);
46
+ if (this.owners.has(address)) {
47
+ satsOut += BigInt(sourceOutput.satoshis || 0);
48
+ }
49
+ }
50
+ // Calculate satoshis received to our addresses (outputs)
51
+ satsIn = ctx.txos.reduce((acc, txo) => {
52
+ if (!txo.data[this.tag])
53
+ return acc;
54
+ const satoshis = BigInt(txo.output.satoshis || 0);
55
+ return acc + (txo.owner && this.owners.has(txo.owner) ? satoshis : 0n);
56
+ }, 0n);
57
+ const balance = Number(satsIn - satsOut);
58
+ if (balance) {
59
+ return {
60
+ amount: balance,
61
+ };
62
+ }
63
+ }
64
+ }
65
+ //# sourceMappingURL=FundIndexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FundIndexer.js","sourceRoot":"","sources":["../../src/indexers/FundIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,OAAO,GAIP,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAE7C;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAY,SAAQ,OAAO;IAK/B;IACA;IALR,GAAG,GAAG,MAAM,CAAA;IACZ,IAAI,GAAG,OAAO,CAAA;IAEd,YACQ,SAAS,IAAI,GAAG,EAAU,EAC1B,UAAiC,SAAS;QAEjD,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;QAHf,WAAM,GAAN,MAAM,CAAoB;QAC1B,YAAO,GAAP,OAAO,CAAmC;IAGlD,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAQ;QACnB,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAA;QACvC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAA;QACjD,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;QACrD,IAAI,QAAQ,GAAG,EAAE;YAAE,OAAM;QAEzB,OAAO;YACN,IAAI,EAAE,OAAO;YACb,IAAI,EAAE,EAAE;YACR,KAAK,EAAE,OAAO;YACd,MAAM,EAAE,MAAM;SACd,CAAA;IACF,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAiB;QAChC,IAAI,OAAO,GAAG,EAAE,CAAA;QAChB,IAAI,MAAM,GAAG,EAAE,CAAA;QAEf,uDAAuD;QACvD,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;YACnC,IAAI,CAAC,KAAK,CAAC,iBAAiB,EAAE,CAAC;gBAC9B,8EAA8E;gBAC9E,OAAM;YACP,CAAC;YAED,MAAM,YAAY,GACjB,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAA;YACzD,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,CAAA;YAEzE,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9B,OAAO,IAAI,MAAM,CAAC,YAAY,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAA;YAC9C,CAAC;QACF,CAAC;QAED,yDAAyD;QACzD,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YACrC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC;gBAAE,OAAO,GAAG,CAAA;YACnC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAA;YACjD,OAAO,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;QACvE,CAAC,EAAE,EAAE,CAAC,CAAA;QAEN,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,OAAO,CAAC,CAAA;QACxC,IAAI,OAAO,EAAE,CAAC;YACb,OAAO;gBACN,MAAM,EAAE,OAAO;aACf,CAAA;QACF,CAAC;IACF,CAAC;CACD"}
@@ -0,0 +1,33 @@
1
+ import { type IndexSummary, Indexer, type ParseContext, type ParseResult, type Txo } from '@1sat/types';
2
+ export interface File {
3
+ hash: string;
4
+ size: number;
5
+ type: string;
6
+ content: number[];
7
+ }
8
+ export interface Inscription {
9
+ file?: File;
10
+ fields?: {
11
+ [key: string]: string;
12
+ };
13
+ parent?: string;
14
+ }
15
+ /**
16
+ * InscriptionIndexer identifies and parses ordinal inscriptions.
17
+ * These are outputs with exactly 1 satoshi containing OP_FALSE OP_IF "ord" envelope.
18
+ *
19
+ * Data structure: Inscription with file, fields, and optional parent
20
+ *
21
+ * Basket: None (no basket assignment - this is preliminary data for other indexers)
22
+ * Events: address for owned outputs
23
+ */
24
+ export declare class InscriptionIndexer extends Indexer {
25
+ owners: Set<string>;
26
+ network: 'mainnet' | 'testnet';
27
+ tag: string;
28
+ name: string;
29
+ constructor(owners?: Set<string>, network?: 'mainnet' | 'testnet');
30
+ parse(txo: Txo): Promise<ParseResult | undefined>;
31
+ summarize(ctx: ParseContext): Promise<IndexSummary | undefined>;
32
+ }
33
+ //# sourceMappingURL=InscriptionIndexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InscriptionIndexer.d.ts","sourceRoot":"","sources":["../../src/indexers/InscriptionIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,OAAO,EACP,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,GAAG,EACR,MAAM,aAAa,CAAA;AAMpB,MAAM,WAAW,IAAI;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,EAAE,CAAA;CACjB;AAED,MAAM,WAAW,WAAW;IAC3B,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,MAAM,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CACf;AAED;;;;;;;;GAQG;AACH,qBAAa,kBAAmB,SAAQ,OAAO;IAKtC,MAAM;IACN,OAAO,EAAE,SAAS,GAAG,SAAS;IALtC,GAAG,SAAS;IACZ,IAAI,SAAiB;gBAGb,MAAM,cAAoB,EAC1B,OAAO,GAAE,SAAS,GAAG,SAAqB;IAK5C,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IA4FjD,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;CAUrE"}
@@ -0,0 +1,116 @@
1
+ import { Indexer, } from '@1sat/types';
2
+ import { Inscription as InscriptionTemplate } from '@bopen-io/templates';
3
+ import { OP, Script, Utils } from '@bsv/sdk';
4
+ import { MapIndexer } from './MapIndexer';
5
+ import { parseAddress } from './parseAddress';
6
+ /**
7
+ * InscriptionIndexer identifies and parses ordinal inscriptions.
8
+ * These are outputs with exactly 1 satoshi containing OP_FALSE OP_IF "ord" envelope.
9
+ *
10
+ * Data structure: Inscription with file, fields, and optional parent
11
+ *
12
+ * Basket: None (no basket assignment - this is preliminary data for other indexers)
13
+ * Events: address for owned outputs
14
+ */
15
+ export class InscriptionIndexer extends Indexer {
16
+ owners;
17
+ network;
18
+ tag = 'insc';
19
+ name = 'Inscriptions';
20
+ constructor(owners = new Set(), network = 'mainnet') {
21
+ super(owners, network);
22
+ this.owners = owners;
23
+ this.network = network;
24
+ }
25
+ async parse(txo) {
26
+ const satoshis = BigInt(txo.output.satoshis || 0);
27
+ if (satoshis !== 1n)
28
+ return;
29
+ const script = txo.output.lockingScript;
30
+ // Use template decode
31
+ const decoded = InscriptionTemplate.decode(script);
32
+ if (!decoded)
33
+ return;
34
+ // Extract owner from script prefix or suffix
35
+ let owner = parseAddress(script, 0, this.network);
36
+ if (!owner && decoded.scriptSuffix) {
37
+ // Try to find owner in suffix (after OP_ENDIF)
38
+ owner = parseAddress(decoded.scriptSuffix, 0, this.network);
39
+ // Also check for OP_CODESEPARATOR pattern
40
+ if (!owner &&
41
+ decoded.scriptSuffix.chunks[0]?.op === OP.OP_CODESEPARATOR) {
42
+ owner = parseAddress(decoded.scriptSuffix, 1, this.network);
43
+ }
44
+ }
45
+ // Handle MAP field if present (special case)
46
+ // Note: This writes to txo.data.map directly as a side effect
47
+ if (decoded.fields?.has('MAP')) {
48
+ const mapData = decoded.fields.get('MAP');
49
+ if (mapData) {
50
+ const map = MapIndexer.parseMap(Script.fromBinary(Array.from(mapData)), 0);
51
+ if (map) {
52
+ txo.data.map = { data: map, tags: [] };
53
+ }
54
+ }
55
+ }
56
+ // Convert to wallet-toolbox format
57
+ const insc = {
58
+ file: {
59
+ hash: Utils.toBase64(Array.from(decoded.file.hash)),
60
+ size: decoded.file.size,
61
+ type: decoded.file.type,
62
+ content: Array.from(decoded.file.content),
63
+ },
64
+ fields: {},
65
+ };
66
+ // Extract text content if it's a text-based inscription and small enough
67
+ let content;
68
+ const contentType = decoded.file.type.toLowerCase();
69
+ const isTextContent = contentType.startsWith('text/') || contentType === 'application/json';
70
+ if (isTextContent && decoded.file.size <= 1000) {
71
+ try {
72
+ content = new TextDecoder().decode(decoded.file.content);
73
+ }
74
+ catch {
75
+ // Ignore decoding errors
76
+ }
77
+ }
78
+ // Convert parent outpoint to string format
79
+ if (decoded.parent) {
80
+ try {
81
+ const reader = new Utils.Reader(Array.from(decoded.parent));
82
+ const txid = Utils.toHex(reader.read(32).reverse());
83
+ const vout = reader.readInt32LE();
84
+ insc.parent = `${txid}_${vout}`;
85
+ }
86
+ catch {
87
+ // Ignore parsing errors
88
+ }
89
+ }
90
+ // Convert fields to base64 strings
91
+ if (decoded.fields && insc.fields) {
92
+ for (const [key, value] of decoded.fields) {
93
+ if (key !== 'MAP') {
94
+ insc.fields[key] = Utils.toBase64(Array.from(value));
95
+ }
96
+ }
97
+ }
98
+ return {
99
+ data: insc,
100
+ tags: [],
101
+ owner,
102
+ content,
103
+ };
104
+ }
105
+ async summarize(ctx) {
106
+ // Clear file content before saving - content is loaded locally but shouldn't be persisted
107
+ for (const txo of ctx.txos) {
108
+ const insc = txo.data[this.tag]?.data;
109
+ if (insc?.file) {
110
+ insc.file.content = [];
111
+ }
112
+ }
113
+ return undefined;
114
+ }
115
+ }
116
+ //# sourceMappingURL=InscriptionIndexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InscriptionIndexer.js","sourceRoot":"","sources":["../../src/indexers/InscriptionIndexer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { type IndexSummary, Indexer, type ParseContext, type ParseResult, type Txo } from '@1sat/types';
2
+ export interface LockData {
3
+ until: number;
4
+ }
5
+ export declare class LockIndexer extends Indexer {
6
+ tag: string;
7
+ name: string;
8
+ parse(txo: Txo): Promise<ParseResult | undefined>;
9
+ summarize(ctx: ParseContext): Promise<IndexSummary | undefined>;
10
+ }
11
+ //# sourceMappingURL=LockIndexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LockIndexer.d.ts","sourceRoot":"","sources":["../../src/indexers/LockIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,YAAY,EACjB,OAAO,EACP,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,GAAG,EACR,MAAM,aAAa,CAAA;AAGpB,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,MAAM,CAAA;CACb;AAED,qBAAa,WAAY,SAAQ,OAAO;IACvC,GAAG,SAAS;IACZ,IAAI,SAAU;IAER,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IAoBjD,SAAS,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC;CAsBrE"}
@@ -0,0 +1,44 @@
1
+ import { Indexer, } from '@1sat/types';
2
+ import { Lock } from '@bopen-io/templates';
3
+ export class LockIndexer extends Indexer {
4
+ tag = 'lock';
5
+ name = 'Locks';
6
+ async parse(txo) {
7
+ const lockingScript = txo.output.lockingScript;
8
+ const decoded = Lock.decode(lockingScript, this.network === 'mainnet');
9
+ if (!decoded)
10
+ return;
11
+ const tags = [];
12
+ if (this.owners.has(decoded.address)) {
13
+ tags.push(`lock:until:${decoded.until}`);
14
+ }
15
+ return {
16
+ data: { until: decoded.until },
17
+ tags,
18
+ owner: decoded.address,
19
+ basket: 'lock',
20
+ protocol: 'basket insertion', // Custom Lock script requires manual unlock
21
+ };
22
+ }
23
+ async summarize(ctx) {
24
+ let locksOut = 0n;
25
+ for (const spend of ctx.spends) {
26
+ if (spend.data[this.tag]) {
27
+ const satoshis = BigInt(spend.output.satoshis || 0);
28
+ locksOut += spend.owner && this.owners.has(spend.owner) ? satoshis : 0n;
29
+ }
30
+ }
31
+ let locksIn = 0n;
32
+ for (const txo of ctx.txos) {
33
+ if (txo.data[this.tag]) {
34
+ const satoshis = BigInt(txo.output.satoshis || 0);
35
+ locksIn += txo.owner && this.owners.has(txo.owner) ? satoshis : 0n;
36
+ }
37
+ }
38
+ const balance = Number(locksIn - locksOut);
39
+ if (balance) {
40
+ return { amount: balance };
41
+ }
42
+ }
43
+ }
44
+ //# sourceMappingURL=LockIndexer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LockIndexer.js","sourceRoot":"","sources":["../../src/indexers/LockIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAEN,OAAO,GAIP,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAA;AAM1C,MAAM,OAAO,WAAY,SAAQ,OAAO;IACvC,GAAG,GAAG,MAAM,CAAA;IACZ,IAAI,GAAG,OAAO,CAAA;IAEd,KAAK,CAAC,KAAK,CAAC,GAAQ;QACnB,MAAM,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,aAAa,CAAA;QAE9C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAA;QACtE,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,MAAM,IAAI,GAAa,EAAE,CAAA;QACzB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,IAAI,CAAC,cAAc,OAAO,CAAC,KAAK,EAAE,CAAC,CAAA;QACzC,CAAC;QAED,OAAO;YACN,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAc;YAC1C,IAAI;YACJ,KAAK,EAAE,OAAO,CAAC,OAAO;YACtB,MAAM,EAAE,MAAM;YACd,QAAQ,EAAE,kBAAkB,EAAE,4CAA4C;SAC1E,CAAA;IACF,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,GAAiB;QAChC,IAAI,QAAQ,GAAG,EAAE,CAAA;QACjB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAA;gBACnD,QAAQ,IAAI,KAAK,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;YACxE,CAAC;QACF,CAAC;QAED,IAAI,OAAO,GAAG,EAAE,CAAA;QAChB,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxB,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAA;gBACjD,OAAO,IAAI,GAAG,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAA;YACnE,CAAC;QACF,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,CAAA;QAC1C,IAAI,OAAO,EAAE,CAAC;YACb,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,CAAA;QAC3B,CAAC;IACF,CAAC;CACD"}
@@ -0,0 +1,14 @@
1
+ import { Indexer, type ParseResult, type Txo } from '@1sat/types';
2
+ import { Script } from '@bsv/sdk';
3
+ export declare class MapIndexer extends Indexer {
4
+ owners: Set<string>;
5
+ network: 'mainnet' | 'testnet';
6
+ tag: string;
7
+ name: string;
8
+ constructor(owners?: Set<string>, network?: 'mainnet' | 'testnet');
9
+ parse(txo: Txo): Promise<ParseResult | undefined>;
10
+ static parseMap(script: Script, mapPos: number): {
11
+ [key: string]: unknown;
12
+ } | undefined;
13
+ }
14
+ //# sourceMappingURL=MapIndexer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MapIndexer.d.ts","sourceRoot":"","sources":["../../src/indexers/MapIndexer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,GAAG,EAAE,MAAM,aAAa,CAAA;AAEjE,OAAO,EAAM,MAAM,EAAS,MAAM,UAAU,CAAA;AAE5C,qBAAa,UAAW,SAAQ,OAAO;IAK9B,MAAM;IACN,OAAO,EAAE,SAAS,GAAG,SAAS;IALtC,GAAG,SAAQ;IACX,IAAI,SAAQ;gBAGJ,MAAM,cAAoB,EAC1B,OAAO,GAAE,SAAS,GAAG,SAAqB;IAK5C,KAAK,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC;IA4BvD,MAAM,CAAC,QAAQ,CACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACZ;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,GAAG,SAAS;CAgCzC"}