@actioncodes/protocol 1.2.2 → 2.0.1

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 (144) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +318 -33
  3. package/dist/ActionCodesProtocol.d.ts +37 -0
  4. package/dist/ActionCodesProtocol.d.ts.map +1 -0
  5. package/dist/adapters/BaseChainAdapter.d.ts +22 -0
  6. package/dist/adapters/BaseChainAdapter.d.ts.map +1 -0
  7. package/dist/adapters/SolanaAdapter.d.ts +44 -0
  8. package/dist/adapters/SolanaAdapter.d.ts.map +1 -0
  9. package/dist/constants.d.ts +6 -8
  10. package/dist/constants.d.ts.map +1 -1
  11. package/dist/errors.d.ts +63 -0
  12. package/dist/errors.d.ts.map +1 -0
  13. package/dist/index.cjs +3 -0
  14. package/dist/index.cjs.map +25 -0
  15. package/dist/index.d.ts +10 -8
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +3 -36
  18. package/dist/index.js.map +25 -0
  19. package/dist/strategy/DelegationStrategy.d.ts +45 -0
  20. package/dist/strategy/DelegationStrategy.d.ts.map +1 -0
  21. package/dist/strategy/WalletStrategy.d.ts +8 -0
  22. package/dist/strategy/WalletStrategy.d.ts.map +1 -0
  23. package/dist/types.d.ts +40 -0
  24. package/dist/types.d.ts.map +1 -0
  25. package/dist/utils/canonical.d.ts +5 -0
  26. package/dist/utils/canonical.d.ts.map +1 -0
  27. package/dist/utils/crypto.d.ts +13 -0
  28. package/dist/utils/crypto.d.ts.map +1 -0
  29. package/dist/utils/protocolMeta.d.ts +16 -0
  30. package/dist/utils/protocolMeta.d.ts.map +1 -0
  31. package/docs/ActionCodesProtocol/README.md +11 -0
  32. package/docs/ActionCodesProtocol/classes/ActionCodesProtocol.md +147 -0
  33. package/docs/README.md +10 -50
  34. package/docs/adapters/BaseChainAdapter/README.md +20 -0
  35. package/docs/adapters/BaseChainAdapter/classes/BaseChainAdapter.md +56 -0
  36. package/docs/adapters/BaseChainAdapter/interfaces/BaseContext.md +17 -0
  37. package/docs/adapters/BaseChainAdapter/interfaces/ChainAdapter.md +33 -0
  38. package/docs/adapters/BaseChainAdapter/type-aliases/ChainContext.md +23 -0
  39. package/docs/adapters/NodeCryptoAdapter/README.md +15 -0
  40. package/docs/adapters/NodeCryptoAdapter/classes/NodeCryptoAdapter.md +254 -0
  41. package/docs/adapters/NodeCryptoAdapter/type-aliases/NodeCryptoContext.md +27 -0
  42. package/docs/adapters/SolanaAdapter/README.md +16 -0
  43. package/docs/adapters/SolanaAdapter/classes/SolanaAdapter.md +190 -0
  44. package/docs/adapters/SolanaAdapter/type-aliases/SolanaContext.md +27 -0
  45. package/docs/adapters/SolanaAdapter/type-aliases/SolanaTransaction.md +13 -0
  46. package/docs/constants/README.md +8 -13
  47. package/docs/constants/variables/CODE_CHARSET_DIGITS.md +11 -0
  48. package/docs/constants/variables/CODE_DEFAULT_LENGTH.md +11 -0
  49. package/docs/constants/variables/CODE_MAX_LENGTH.md +11 -0
  50. package/docs/constants/variables/CODE_MIN_LENGTH.md +11 -0
  51. package/docs/constants/variables/PROTOCOL_META_MAX_BYTES.md +11 -0
  52. package/docs/constants/variables/PROTOCOL_NORMALIZATION.md +11 -0
  53. package/docs/constants/variables/SUPPORTED_CHAINS.md +3 -3
  54. package/docs/errors/README.md +22 -0
  55. package/docs/errors/classes/ExpiredCodeError.md +695 -0
  56. package/docs/errors/classes/InvalidCodeFormatError.md +691 -0
  57. package/docs/errors/classes/InvalidPubkeyFormatError.md +691 -0
  58. package/docs/errors/classes/InvalidSignatureError.md +687 -0
  59. package/docs/errors/classes/MetaMismatchError.md +695 -0
  60. package/docs/errors/classes/MissingMetaError.md +681 -0
  61. package/docs/errors/classes/ProtocolError.md +637 -0
  62. package/docs/errors/classes/TransactionNotSignedByIntendedOwnerError.md +691 -0
  63. package/docs/errors/enumerations/ProtocolErrorCode.md +121 -0
  64. package/docs/index/README.md +83 -41
  65. package/docs/modules.md +12 -9
  66. package/docs/strategy/WalletStrategy/README.md +11 -0
  67. package/docs/strategy/WalletStrategy/classes/WalletStrategy.md +67 -0
  68. package/docs/types/README.md +14 -0
  69. package/docs/types/interfaces/ActionCode.md +65 -0
  70. package/docs/types/interfaces/CanonicalMessageParts.md +33 -0
  71. package/docs/types/interfaces/CodeGenerationConfig.md +33 -0
  72. package/docs/types/interfaces/CodeGenerationResult.md +25 -0
  73. package/docs/utils/canonical/README.md +16 -0
  74. package/docs/utils/canonical/functions/serializeCanonical.md +21 -0
  75. package/docs/utils/canonical/variables/CANONICAL_MESSAGE_PREFIX.md +11 -0
  76. package/docs/utils/canonical/variables/CANONICAL_MESSAGE_VERSION.md +11 -0
  77. package/docs/utils/crypto/README.md +18 -0
  78. package/docs/utils/crypto/functions/base32EncodeCrockford.md +21 -0
  79. package/docs/utils/crypto/functions/codeHash.md +21 -0
  80. package/docs/utils/crypto/functions/digestToDigits.md +25 -0
  81. package/docs/utils/crypto/functions/generateRandomSecret.md +15 -0
  82. package/docs/utils/crypto/functions/hkdfSha256.md +35 -0
  83. package/docs/utils/crypto/functions/hmacSha256.md +25 -0
  84. package/docs/utils/crypto/functions/sha256.md +21 -0
  85. package/docs/utils/crypto/functions/truncateBits.md +25 -0
  86. package/docs/utils/protocolMeta/README.md +21 -0
  87. package/docs/utils/protocolMeta/functions/buildProtocolMeta.md +21 -0
  88. package/docs/utils/protocolMeta/functions/parseProtocolMeta.md +21 -0
  89. package/docs/utils/protocolMeta/functions/validateProtocolMetaFormat.md +21 -0
  90. package/docs/utils/protocolMeta/interfaces/ProtocolMetaFields.md +41 -0
  91. package/docs/utils/protocolMeta/variables/SCHEME.md +11 -0
  92. package/package.json +42 -47
  93. package/dist/actioncode.d.ts +0 -120
  94. package/dist/actioncode.d.ts.map +0 -1
  95. package/dist/actioncode.js +0 -186
  96. package/dist/adapters/base.d.ts +0 -93
  97. package/dist/adapters/base.d.ts.map +0 -1
  98. package/dist/adapters/base.js +0 -65
  99. package/dist/adapters/solana/index.d.ts +0 -2
  100. package/dist/adapters/solana/index.d.ts.map +0 -1
  101. package/dist/adapters/solana/index.js +0 -30
  102. package/dist/adapters/solana/solana.d.ts +0 -113
  103. package/dist/adapters/solana/solana.d.ts.map +0 -1
  104. package/dist/adapters/solana/solana.js +0 -537
  105. package/dist/codegen.d.ts +0 -76
  106. package/dist/codegen.d.ts.map +0 -1
  107. package/dist/codegen.js +0 -211
  108. package/dist/constants.js +0 -24
  109. package/dist/meta.d.ts +0 -54
  110. package/dist/meta.d.ts.map +0 -1
  111. package/dist/meta.js +0 -104
  112. package/dist/protocol.d.ts +0 -179
  113. package/dist/protocol.d.ts.map +0 -1
  114. package/dist/protocol.js +0 -390
  115. package/docs/_media/LICENSE +0 -201
  116. package/docs/_media/README.md +0 -28
  117. package/docs/actioncode/README.md +0 -21
  118. package/docs/actioncode/classes/ActionCode.md +0 -430
  119. package/docs/actioncode/interfaces/ActionCodeFields.md +0 -89
  120. package/docs/actioncode/interfaces/ActionCodeMetadata.md +0 -25
  121. package/docs/actioncode/interfaces/ActionCodeTransaction.md +0 -57
  122. package/docs/actioncode/type-aliases/ActionCodeStatus.md +0 -11
  123. package/docs/adapters/base/README.md +0 -11
  124. package/docs/adapters/base/classes/BaseChainAdapter.md +0 -396
  125. package/docs/adapters/solana/README.md +0 -19
  126. package/docs/adapters/solana/solana/README.md +0 -15
  127. package/docs/adapters/solana/solana/classes/SolanaAdapter.md +0 -506
  128. package/docs/adapters/solana/solana/type-aliases/SolanaTransaction.md +0 -13
  129. package/docs/codegen/README.md +0 -11
  130. package/docs/codegen/classes/CodeGenerator.md +0 -341
  131. package/docs/constants/type-aliases/SupportedChain.md +0 -11
  132. package/docs/constants/variables/CODE_LENGTH.md +0 -11
  133. package/docs/constants/variables/CODE_TTL.md +0 -11
  134. package/docs/constants/variables/MAX_PREFIX_LENGTH.md +0 -11
  135. package/docs/constants/variables/MIN_PREFIX_LENGTH.md +0 -11
  136. package/docs/constants/variables/PROTOCOL_CODE_PREFIX.md +0 -11
  137. package/docs/constants/variables/PROTOCOL_PREFIX.md +0 -11
  138. package/docs/constants/variables/PROTOCOL_VERSION.md +0 -11
  139. package/docs/meta/README.md +0 -15
  140. package/docs/meta/classes/ProtocolMetaParser.md +0 -177
  141. package/docs/meta/interfaces/ProtocolMetaV1.md +0 -59
  142. package/docs/protocol/README.md +0 -51
  143. package/docs/protocol/classes/ActionCodesProtocol.md +0 -676
  144. package/docs/protocol/interfaces/ProtocolConfig.md +0 -71
@@ -1,537 +0,0 @@
1
- "use strict";
2
- // Copyright 2025 Trana, Inc.
3
- //
4
- // Licensed under the Apache License, Version 2.0 (the "License");
5
- // you may not use this file except in compliance with the License.
6
- // You may obtain a copy of the License at
7
- //
8
- // http://www.apache.org/licenses/LICENSE-2.0
9
- //
10
- // Unless required by applicable law or agreed to in writing, software
11
- // distributed under the License is distributed on an "AS IS" BASIS,
12
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- // See the License for the specific language governing permissions and
14
- // limitations under the License.
15
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
16
- if (k2 === undefined) k2 = k;
17
- var desc = Object.getOwnPropertyDescriptor(m, k);
18
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
19
- desc = { enumerable: true, get: function() { return m[k]; } };
20
- }
21
- Object.defineProperty(o, k2, desc);
22
- }) : (function(o, m, k, k2) {
23
- if (k2 === undefined) k2 = k;
24
- o[k2] = m[k];
25
- }));
26
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
27
- Object.defineProperty(o, "default", { enumerable: true, value: v });
28
- }) : function(o, v) {
29
- o["default"] = v;
30
- });
31
- var __importStar = (this && this.__importStar) || (function () {
32
- var ownKeys = function(o) {
33
- ownKeys = Object.getOwnPropertyNames || function (o) {
34
- var ar = [];
35
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
36
- return ar;
37
- };
38
- return ownKeys(o);
39
- };
40
- return function (mod) {
41
- if (mod && mod.__esModule) return mod;
42
- var result = {};
43
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
44
- __setModuleDefault(result, mod);
45
- return result;
46
- };
47
- })();
48
- var __importDefault = (this && this.__importDefault) || function (mod) {
49
- return (mod && mod.__esModule) ? mod : { "default": mod };
50
- };
51
- Object.defineProperty(exports, "__esModule", { value: true });
52
- exports.SolanaAdapter = void 0;
53
- const web3_js_1 = require("@solana/web3.js");
54
- const spl_memo_1 = require("@solana/spl-memo");
55
- const meta_1 = require("../../meta");
56
- const base_1 = require("../base");
57
- const nacl = __importStar(require("tweetnacl"));
58
- const actioncode_1 = require("../../actioncode");
59
- const buffer_1 = require("buffer");
60
- const bs58_1 = __importDefault(require("bs58"));
61
- /**
62
- * Simple Solana adapter for protocol meta operations
63
- * Supports both legacy and versioned transactions
64
- */
65
- class SolanaAdapter extends base_1.BaseChainAdapter {
66
- constructor() {
67
- super(...arguments);
68
- this.chain = 'solana';
69
- }
70
- /**
71
- * Encode protocol meta as a Solana memo instruction
72
- * @param meta - The protocol meta to encode
73
- * @returns TransactionInstruction for the memo
74
- */
75
- encodeMeta(meta) {
76
- const metaString = meta_1.ProtocolMetaParser.serialize(meta);
77
- const signerPubkeys = [];
78
- try {
79
- if (meta.iss && meta.iss !== 'undefined') {
80
- const pubkey = new web3_js_1.PublicKey(meta.iss);
81
- signerPubkeys.push(pubkey);
82
- }
83
- }
84
- catch (error) {
85
- // Ignore error, issuer is not a valid public key
86
- }
87
- return (0, spl_memo_1.createMemoInstruction)(metaString, signerPubkeys);
88
- }
89
- /**
90
- * Decode protocol meta from Solana transaction (legacy or versioned)
91
- * @param tx - The Solana transaction (can be deserialized object or base64 string)
92
- * @returns Decoded ProtocolMetaV1 or null if not found
93
- */
94
- decodeMeta(tx) {
95
- // If it's a string, deserialize it first
96
- if (typeof tx === 'string') {
97
- try {
98
- tx = this.deserializeTransaction(tx);
99
- }
100
- catch {
101
- return null;
102
- }
103
- }
104
- // Check if it's a versioned transaction
105
- if ('message' in tx && tx.message) {
106
- return this.decodeVersionedTransaction(tx);
107
- }
108
- else if ('instructions' in tx && Array.isArray(tx.instructions)) {
109
- return this.decodeLegacyTransaction(tx);
110
- }
111
- else {
112
- return null;
113
- }
114
- }
115
- /**
116
- * Deserialize a Solana transaction from base64 string
117
- * @param base64String - Base64 encoded transaction
118
- * @returns SolanaTransaction object
119
- */
120
- deserializeTransaction(base64String) {
121
- try {
122
- const buffer = buffer_1.Buffer.from(base64String, 'base64');
123
- // Try legacy first, then versioned
124
- try {
125
- return web3_js_1.Transaction.from(buffer);
126
- }
127
- catch {
128
- return web3_js_1.VersionedTransaction.deserialize(buffer);
129
- }
130
- }
131
- catch (error) {
132
- throw new Error('Failed to deserialize Solana transaction');
133
- }
134
- }
135
- /**
136
- * Inject protocol meta into Solana transaction
137
- * @param serializedTx - Serialized transaction string (base64)
138
- * @param meta - ProtocolMetaV1 object
139
- * @returns Serialized transaction with injected meta
140
- */
141
- injectMeta(serializedTx, meta) {
142
- // Deserialize the transaction using existing pattern
143
- const tx = this.deserializeTransaction(serializedTx);
144
- const metaIx = this.encodeMeta(meta);
145
- if (tx instanceof web3_js_1.VersionedTransaction) {
146
- // Convert TransactionInstruction to MessageCompiledInstruction for versioned transactions
147
- // Create new static account keys array with all required keys
148
- const newStaticAccountKeys = [...tx.message.staticAccountKeys];
149
- // Add any missing keys from the memo instruction
150
- metaIx.keys.forEach(({ pubkey }) => {
151
- if (!newStaticAccountKeys.some(key => key.equals(pubkey))) {
152
- newStaticAccountKeys.push(pubkey);
153
- }
154
- });
155
- // Ensure programId is also in static keys
156
- if (!newStaticAccountKeys.some(key => key.equals(metaIx.programId))) {
157
- newStaticAccountKeys.push(metaIx.programId);
158
- }
159
- // Create new compiled instructions array
160
- const newCompiledInstructions = [...tx.message.compiledInstructions];
161
- // Find the program ID index in the new static keys
162
- const programIdIndex = newStaticAccountKeys.findIndex(key => key.equals(metaIx.programId));
163
- const accountKeyIndexes = metaIx.keys.map(key => {
164
- const index = newStaticAccountKeys.findIndex(staticKey => staticKey.equals(key.pubkey));
165
- if (index === -1) {
166
- throw new Error(`Account key ${key.pubkey.toBase58()} not found in static account keys`);
167
- }
168
- return index;
169
- });
170
- const compiledInstruction = {
171
- programIdIndex,
172
- accountKeyIndexes,
173
- data: metaIx.data
174
- };
175
- newCompiledInstructions.push(compiledInstruction);
176
- // Create new MessageV0 with updated data
177
- const newMessage = new web3_js_1.MessageV0({
178
- header: tx.message.header,
179
- staticAccountKeys: newStaticAccountKeys,
180
- recentBlockhash: tx.message.recentBlockhash,
181
- compiledInstructions: newCompiledInstructions,
182
- addressTableLookups: tx.message.addressTableLookups,
183
- });
184
- // Create new VersionedTransaction
185
- const newVersionedTx = new web3_js_1.VersionedTransaction(newMessage);
186
- return buffer_1.Buffer.from(newVersionedTx.serialize()).toString('base64');
187
- }
188
- else if (tx instanceof web3_js_1.Transaction) {
189
- tx.instructions.push(metaIx);
190
- // Clear existing signatures since we modified the transaction
191
- tx.signatures = [];
192
- // Serialize the transaction back without requiring signatures
193
- return tx.serialize({ requireAllSignatures: false }).toString('base64');
194
- }
195
- else {
196
- throw new Error('Invalid transaction type');
197
- }
198
- }
199
- /**
200
- * Validate transaction with protocol meta and authority list
201
- * @param tx - The Solana transaction
202
- * @param authorities - Array of valid protocol authority public keys (base58)
203
- * @param expectedPrefix - Expected protocol prefix (default: 'DEFAULT')
204
- * @returns True if transaction is valid
205
- */
206
- validate(tx, authorities, expectedPrefix = 'DEFAULT') {
207
- return this.detectTampering(tx, authorities, expectedPrefix);
208
- }
209
- /**
210
- * Check if the issuer has signed the transaction
211
- * @param tx - The Solana transaction (can be deserialized object or base64 string)
212
- * @param issuer - Issuer public key to check
213
- * @returns True if issuer has signed
214
- */
215
- hasIssuerSignature(tx, issuer) {
216
- // If it's a string, deserialize it first
217
- if (typeof tx === 'string') {
218
- try {
219
- tx = this.deserializeTransaction(tx);
220
- }
221
- catch {
222
- return false;
223
- }
224
- }
225
- // Check if it's a versioned transaction
226
- if ('message' in tx && tx.message) {
227
- return this.hasIssuerSignatureVersioned(tx, issuer);
228
- }
229
- else if ('signatures' in tx && Array.isArray(tx.signatures)) {
230
- return this.hasIssuerSignatureLegacy(tx, issuer);
231
- }
232
- else {
233
- return false;
234
- }
235
- }
236
- /**
237
- * Decode protocol meta from legacy Solana transaction
238
- */
239
- decodeLegacyTransaction(transaction) {
240
- for (const instruction of transaction.instructions) {
241
- if (instruction.programId.equals(SolanaAdapter.MEMO_PROGRAM_ID)) {
242
- const memoData = instruction.data;
243
- if (memoData && memoData.length > 0) {
244
- try {
245
- const memoString = new TextDecoder().decode(memoData);
246
- const meta = meta_1.ProtocolMetaParser.parse(memoString);
247
- if (meta && meta.version === '1') {
248
- return meta;
249
- }
250
- // Continue searching if this memo is not a valid protocol meta
251
- }
252
- catch {
253
- // Continue searching if this memo cannot be parsed
254
- }
255
- }
256
- }
257
- }
258
- return null;
259
- }
260
- /**
261
- * Decode protocol meta from versioned Solana transaction
262
- */
263
- decodeVersionedTransaction(transaction) {
264
- const message = transaction.message;
265
- if (message instanceof web3_js_1.MessageV0) {
266
- return this.decodeMessageV0(message);
267
- }
268
- else {
269
- return null;
270
- }
271
- }
272
- /**
273
- * Decode protocol meta from MessageV0
274
- */
275
- decodeMessageV0(message) {
276
- for (const instruction of message.compiledInstructions) {
277
- const programId = message.staticAccountKeys[instruction.programIdIndex];
278
- if (programId.equals(SolanaAdapter.MEMO_PROGRAM_ID)) {
279
- const memoData = instruction.data;
280
- if (memoData && memoData.length > 0) {
281
- try {
282
- const memoString = new TextDecoder().decode(memoData);
283
- const meta = meta_1.ProtocolMetaParser.parse(memoString);
284
- if (meta && meta.version === '1') {
285
- return meta;
286
- }
287
- // Continue searching if this memo is not a valid protocol meta
288
- }
289
- catch {
290
- // Continue searching if this memo cannot be parsed
291
- }
292
- }
293
- }
294
- }
295
- return null;
296
- }
297
- /**
298
- * Check if the issuer has signed a legacy transaction
299
- */
300
- hasIssuerSignatureLegacy(transaction, issuer) {
301
- return transaction.signatures.some(sig => sig.publicKey.toBase58() === issuer);
302
- }
303
- /**
304
- * Check if the issuer has signed a versioned transaction
305
- */
306
- hasIssuerSignatureVersioned(transaction, issuer) {
307
- const message = transaction.message;
308
- if (message instanceof web3_js_1.MessageV0) {
309
- // Check static account keys
310
- for (const key of message.staticAccountKeys) {
311
- if (key.toBase58() === issuer) {
312
- return true;
313
- }
314
- }
315
- }
316
- return false;
317
- }
318
- /**
319
- * Validate Solana transaction integrity with additional checks
320
- * @param tx - The Solana transaction
321
- * @param meta - Decoded protocol meta
322
- * @returns True if transaction integrity is valid
323
- */
324
- validateTransactionIntegrity(tx, meta) {
325
- // Additional Solana-specific validation can be added here
326
- // For example, checking transaction signatures, recent blockhash, etc.
327
- // Verify that the memo instruction contains the expected protocol meta
328
- const decodedMeta = this.decodeMeta(tx);
329
- if (!decodedMeta) {
330
- return false;
331
- }
332
- if (!meta.iss) {
333
- return false;
334
- }
335
- if (!this.hasIssuerSignature(tx, meta.iss)) {
336
- return false;
337
- }
338
- // Cross-check the decoded meta with the provided meta
339
- return (decodedMeta.version === meta.version &&
340
- decodedMeta.prefix === meta.prefix &&
341
- decodedMeta.initiator === meta.initiator &&
342
- decodedMeta.id === meta.id &&
343
- decodedMeta.iss === meta.iss &&
344
- decodedMeta.params === meta.params);
345
- }
346
- verifyCodeSignature(actionCode) {
347
- try {
348
- const message = this.getCodeSignatureMessage(actionCode.code, actionCode.timestamp, actionCode.prefix);
349
- const messageBytes = new TextEncoder().encode(message);
350
- const pubkeyBytes = new web3_js_1.PublicKey(actionCode.pubkey).toBytes();
351
- const sigBytes = bs58_1.default.decode(actionCode.signature);
352
- return nacl.sign.detached.verify(messageBytes, sigBytes, pubkeyBytes);
353
- }
354
- catch (error) {
355
- return false;
356
- }
357
- }
358
- /**
359
- * Decode protocol meta from base64 string (for backward compatibility)
360
- * @param base64String - Base64 encoded transaction
361
- * @returns Decoded ProtocolMetaV1 or null
362
- */
363
- decodeFromBase64(base64String) {
364
- return this.decodeMeta(base64String);
365
- }
366
- /**
367
- * Sign the transaction with the protocol key
368
- * @param actionCode - The action code containing the transaction
369
- * @param key - The keypair to sign with
370
- * @returns Promise that resolves to the signed action code
371
- */
372
- async signWithProtocolKey(actionCode, key) {
373
- try {
374
- if (!actionCode.transaction?.transaction) {
375
- throw new Error('No transaction found');
376
- }
377
- const tx = this.deserializeTransaction(actionCode.transaction.transaction);
378
- // Check if transaction has protocol meta
379
- const meta = this.decodeMeta(tx);
380
- if (!meta) {
381
- throw new Error('Invalid transaction, protocol meta not found');
382
- }
383
- // Validate transaction integrity
384
- if (!this.validateTransactionIntegrity(tx, meta)) {
385
- throw new Error('Invalid transaction, transaction integrity not valid');
386
- }
387
- // Sign the transaction
388
- if (tx instanceof web3_js_1.Transaction) {
389
- tx.partialSign(key);
390
- }
391
- else if (tx instanceof web3_js_1.VersionedTransaction) {
392
- tx.sign([key]);
393
- }
394
- else {
395
- throw new Error('Invalid transaction type');
396
- }
397
- const updatedTransaction = {
398
- ...actionCode.transaction,
399
- transaction: tx.serialize({ requireAllSignatures: false }).toString('base64'),
400
- };
401
- const updatedFields = {
402
- ...actionCode.json,
403
- transaction: updatedTransaction,
404
- };
405
- return actioncode_1.ActionCode.fromPayload(updatedFields);
406
- }
407
- catch (error) {
408
- throw new Error(`Failed to sign transaction with protocol key: ${error instanceof Error ? error.message : 'Unknown error'}`);
409
- }
410
- }
411
- /**
412
- * Verify the finalized transaction from blockchain
413
- * @param tx - The finalized transaction response from blockchain
414
- * @param actionCode - The action code to verify against
415
- * @returns True if the transaction is valid and matches the action code
416
- */
417
- verifyFinalizedTransaction(tx, actionCode) {
418
- try {
419
- // Handle null/undefined transaction
420
- if (tx.transaction === null || tx.transaction === undefined) {
421
- return false;
422
- }
423
- // Both legacy and versioned responses have message and signatures
424
- const response = tx.transaction;
425
- if (!response.message || !response.signatures) {
426
- return false;
427
- }
428
- let transaction;
429
- // Check if it's a versioned transaction by looking at the message structure
430
- if (response.message instanceof web3_js_1.MessageV0) {
431
- // Versioned transaction - reconstruct from message and signatures
432
- transaction = new web3_js_1.VersionedTransaction(response.message);
433
- // Note: In a real scenario, signatures would be attached, but for testing we just need the message
434
- }
435
- else {
436
- // Legacy transaction - reconstruct from compiled message and signatures
437
- const compiledMessage = response.message;
438
- transaction = web3_js_1.Transaction.populate(compiledMessage, response.signatures);
439
- }
440
- const meta = this.decodeMeta(transaction);
441
- if (!meta) {
442
- return false; // No protocol meta found
443
- }
444
- if (!meta.iss) {
445
- return false; // No issuer field in meta
446
- }
447
- if (!actionCode.codeHash) {
448
- return false; // No codeHash available
449
- }
450
- if (!meta.id || meta.id !== actionCode.codeHash) {
451
- return false; // ID doesn't match expected value
452
- }
453
- if (meta.prefix !== actionCode.prefix) {
454
- return false;
455
- }
456
- if (meta.initiator !== actionCode.pubkey) {
457
- return false;
458
- }
459
- let userPubkey = null;
460
- try {
461
- userPubkey = new web3_js_1.PublicKey(actionCode.pubkey);
462
- }
463
- catch (error) {
464
- return false;
465
- }
466
- if (userPubkey) {
467
- if (transaction instanceof web3_js_1.VersionedTransaction) {
468
- const message = transaction.message;
469
- if (message instanceof web3_js_1.MessageV0) {
470
- // Check if user's public key is in the static account keys
471
- const userKeyIndex = message.staticAccountKeys.findIndex(key => key.equals(userPubkey));
472
- if (userKeyIndex === -1) {
473
- return false; // User's key not found in transaction
474
- }
475
- // Check if user's key is a signer (first bit of header indicates signer status)
476
- const isUserSigner = (message.header.numRequiredSignatures > 0) &&
477
- (userKeyIndex < message.header.numRequiredSignatures);
478
- if (!isUserSigner) {
479
- return false; // User didn't sign the transaction
480
- }
481
- }
482
- else {
483
- return false; // Unsupported message type
484
- }
485
- }
486
- else if (transaction instanceof web3_js_1.Transaction) {
487
- // For legacy transactions, check if user's key is in the account keys
488
- const accountKeys = transaction.compileMessage().accountKeys;
489
- const userKeyIndex = accountKeys.findIndex(key => key.equals(userPubkey));
490
- if (userKeyIndex === -1) {
491
- return false; // User's key not found in transaction
492
- }
493
- // Check if user's key is a signer
494
- const isUserSigner = userKeyIndex < transaction.compileMessage().header.numRequiredSignatures;
495
- if (!isUserSigner) {
496
- return false; // User didn't sign the transaction
497
- }
498
- }
499
- else {
500
- return false; // Invalid transaction type
501
- }
502
- }
503
- // 5. Check that tx is signed by protocol (issuer)
504
- if (!this.hasIssuerSignature(transaction, meta.iss)) {
505
- return false; // Protocol didn't sign the transaction
506
- }
507
- // All checks passed
508
- return true;
509
- }
510
- catch (error) {
511
- // If any error occurs during verification, return false
512
- return false;
513
- }
514
- }
515
- /**
516
- * Validate a signed message for sign-only mode
517
- * @param message - The message that was signed
518
- * @param signedMessage - The signed message (base64 or hex)
519
- * @param pubkey - The public key that should have signed the message
520
- * @returns True if the signature is valid
521
- */
522
- validateSignedMessage(message, signedMessage, pubkey) {
523
- try {
524
- // Decode the public key (base58)
525
- const publicKeyBytes = bs58_1.default.decode(pubkey);
526
- // Decode the signature as base58 (Solana convention)
527
- const signature = bs58_1.default.decode(signedMessage);
528
- const messageBuffer = buffer_1.Buffer.from(message, 'utf8');
529
- return nacl.sign.detached.verify(messageBuffer, signature, publicKeyBytes);
530
- }
531
- catch (e) {
532
- return false;
533
- }
534
- }
535
- }
536
- exports.SolanaAdapter = SolanaAdapter;
537
- SolanaAdapter.MEMO_PROGRAM_ID = spl_memo_1.MEMO_PROGRAM_ID;
package/dist/codegen.d.ts DELETED
@@ -1,76 +0,0 @@
1
- export declare class CodeGenerator {
2
- static TIME_WINDOW_MS: number;
3
- static CODE_DIGITS: number;
4
- static MIN_PREFIX_LENGTH: number;
5
- static MAX_PREFIX_LENGTH: number;
6
- /**
7
- * Validate prefix format
8
- * @param prefix - The prefix to validate
9
- * @returns True if prefix is valid, false otherwise
10
- */
11
- static validatePrefix(prefix: string): boolean;
12
- /**
13
- * Validate generated code format (prefix + exactly 8 digits)
14
- * @param code - The code to validate
15
- * @returns True if code is valid, false otherwise
16
- */
17
- static validateCodeFormat(code: string): boolean;
18
- /**
19
- * Validate that the numeric part of a code is exactly 8 digits
20
- * @param code - The code to validate (can include prefix)
21
- * @returns True if numeric part is valid, false otherwise
22
- */
23
- static validateCodeDigits(code: string): boolean;
24
- /**
25
- * Normalize prefix - convert PROTOCOL_CODE_PREFIX to empty string, validate others
26
- * @param prefix - The prefix to normalize
27
- * @returns Normalized prefix
28
- * @throws Error if prefix is invalid
29
- */
30
- static normalizePrefix(prefix: string): string;
31
- /**
32
- * Generate a deterministic 8-digit code based on public key, prefix, and timestamp
33
- * @param pubkey - Solana wallet public key (base58)
34
- * @param prefix - Optional namespace prefix (default: PROTOCOL_CODE_PREFIX)
35
- * @param timestamp - UNIX timestamp in milliseconds (defaults to now)
36
- * @returns Object containing code, issuedAt, and expiresAt timestamps
37
- * @throws Error if generated code is invalid
38
- */
39
- static generateCode(pubkey: string, prefix?: string, timestamp?: number): {
40
- code: string;
41
- issuedAt: number;
42
- expiresAt: number;
43
- };
44
- /**
45
- * Derive the full SHA-256 hash for storage or encryption key generation
46
- * @param pubkey - Solana wallet public key (base58)
47
- * @param prefix - Optional namespace prefix (default: PROTOCOL_CODE_PREFIX)
48
- * @param timestamp - UNIX timestamp in milliseconds (defaults to now)
49
- * @returns Full SHA-256 hash string
50
- */
51
- static deriveCodeHash(pubkey: string, prefix?: string, timestamp?: number): string;
52
- /**
53
- * Get the expected code for a given public key and timestamp
54
- * @param pubkey - Solana wallet public key (base58)
55
- * @param timestamp - UNIX timestamp in milliseconds
56
- * @param prefix - Optional namespace prefix (default: PROTOCOL_CODE_PREFIX)
57
- * @returns Full code string with prefix + 8 digits
58
- */
59
- static getExpectedCode(pubkey: string, timestamp: number, prefix?: string): string;
60
- /**
61
- * Validate if a code matches the expected code for a given public key and timestamp
62
- * @param code - The code to validate (can include prefix)
63
- * @param pubkey - Solana wallet public key (base58)
64
- * @param timestamp - UNIX timestamp in milliseconds
65
- * @param prefix - Optional namespace prefix (default: PROTOCOL_CODE_PREFIX)
66
- * @returns True if code matches expected code and timestamp is valid
67
- */
68
- static validateCode(code: string, pubkey: string, timestamp: number, prefix?: string): boolean;
69
- /**
70
- * Check if a timestamp falls within a valid time window
71
- * @param timestamp - UNIX timestamp in milliseconds
72
- * @returns True if timestamp is valid
73
- */
74
- static isValidTimestamp(timestamp: number): boolean;
75
- }
76
- //# sourceMappingURL=codegen.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"codegen.d.ts","sourceRoot":"","sources":["../src/codegen.ts"],"names":[],"mappings":"AAiBA,qBAAa,aAAa;IACtB,MAAM,CAAC,cAAc,SAAY;IACjC,MAAM,CAAC,WAAW,SAAe;IACjC,MAAM,CAAC,iBAAiB,SAAqB;IAC7C,MAAM,CAAC,iBAAiB,SAAqB;IAE7C;;;;OAIG;IACH,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAM9C;;;;OAIG;IACH,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAoChD;;;;OAIG;IACH,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAkChD;;;;;OAKG;IACH,MAAM,CAAC,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAQ9C;;;;;;;OAOG;IACH,MAAM,CAAC,YAAY,CACf,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAA6B,EACrC,SAAS,GAAE,MAAmB,GAC/B;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE;IAiCxD;;;;;;OAMG;IACH,MAAM,CAAC,cAAc,CACjB,MAAM,EAAE,MAAM,EACd,MAAM,GAAE,MAA6B,EACrC,SAAS,CAAC,EAAE,MAAM,GACnB,MAAM;IAQT;;;;;;OAMG;IACH,MAAM,CAAC,eAAe,CAClB,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAA6B,GACtC,MAAM;IAIT;;;;;;;OAOG;IACH,MAAM,CAAC,YAAY,CACf,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,MAAM,GAAE,MAA6B,GACtC,OAAO;IAgBV;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO;CAGtD"}