@actioncodes/protocol 1.1.0 → 1.1.2

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 (32) hide show
  1. package/dist/adapters/base.d.ts +9 -2
  2. package/dist/adapters/base.d.ts.map +1 -1
  3. package/dist/adapters/base.js +1 -1
  4. package/dist/adapters/solana/solana.d.ts +23 -17
  5. package/dist/adapters/solana/solana.d.ts.map +1 -1
  6. package/dist/adapters/solana/solana.js +153 -69
  7. package/dist/protocol.d.ts +9 -6
  8. package/dist/protocol.d.ts.map +1 -1
  9. package/dist/protocol.js +32 -11
  10. package/docs/actioncode/classes/ActionCode.md +23 -23
  11. package/docs/actioncode/interfaces/ActionCodeFields.md +11 -11
  12. package/docs/actioncode/interfaces/ActionCodeMetadata.md +3 -3
  13. package/docs/actioncode/interfaces/ActionCodeTransaction.md +4 -4
  14. package/docs/actioncode/type-aliases/ActionCodeStatus.md +1 -1
  15. package/docs/adapters/base/classes/BaseChainAdapter.md +45 -15
  16. package/docs/adapters/solana/solana/classes/SolanaAdapter.md +88 -62
  17. package/docs/adapters/solana/solana/type-aliases/SolanaTransaction.md +1 -1
  18. package/docs/codegen/classes/CodeGenerator.md +14 -14
  19. package/docs/constants/type-aliases/SupportedChain.md +1 -1
  20. package/docs/constants/variables/CODE_LENGTH.md +1 -1
  21. package/docs/constants/variables/CODE_TTL.md +1 -1
  22. package/docs/constants/variables/MAX_PREFIX_LENGTH.md +1 -1
  23. package/docs/constants/variables/MIN_PREFIX_LENGTH.md +1 -1
  24. package/docs/constants/variables/PROTOCOL_CODE_PREFIX.md +1 -1
  25. package/docs/constants/variables/PROTOCOL_PREFIX.md +1 -1
  26. package/docs/constants/variables/PROTOCOL_VERSION.md +1 -1
  27. package/docs/constants/variables/SUPPORTED_CHAINS.md +1 -1
  28. package/docs/meta/classes/ProtocolMetaParser.md +6 -6
  29. package/docs/meta/interfaces/ProtocolMetaV1.md +7 -7
  30. package/docs/protocol/classes/ActionCodesProtocol.md +45 -27
  31. package/docs/protocol/interfaces/ProtocolConfig.md +7 -7
  32. package/package.json +1 -1
@@ -11,13 +11,20 @@ export declare abstract class BaseChainAdapter<T = any> {
11
11
  * @param meta - ProtocolMetaV1 object
12
12
  * @returns Chain-specific encoded data
13
13
  */
14
- abstract encode(meta: ProtocolMetaV1): any;
14
+ abstract encodeMeta(meta: ProtocolMetaV1): any;
15
15
  /**
16
16
  * Decode protocol meta from chain-specific transaction
17
17
  * @param tx - Chain-specific transaction
18
18
  * @returns Decoded ProtocolMetaV1 or null
19
19
  */
20
- abstract decode(tx: T): ProtocolMetaV1 | null;
20
+ abstract decodeMeta(tx: T): ProtocolMetaV1 | null;
21
+ /**
22
+ * Inject protocol meta into chain-specific transaction
23
+ * @param serializedTx - Serialized transaction string
24
+ * @param meta - ProtocolMetaV1 object
25
+ * @returns Serialized transaction with injected meta
26
+ */
27
+ abstract injectMeta(serializedTx: string, meta: ProtocolMetaV1): string;
21
28
  /**
22
29
  * Validate transaction with protocol meta and authority list
23
30
  * @param tx - Chain-specific transaction
@@ -1 +1 @@
1
- {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC;;;GAGG;AACH,8BAAsB,gBAAgB,CAAC,CAAC,GAAG,GAAG;IAC1C,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEhC;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,GAAG,GAAG;IAE1C;;;;OAIG;IACH,QAAQ,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,cAAc,GAAG,IAAI;IAE7C;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO;IAEjF;;;;;OAKG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAE3D;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,cAAc,GAAE,MAAkB,GAAG,OAAO;IA8B1F;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IAErF;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,MAA6B,GAAG,MAAM;IAIvG;;;;;;OAMG;IACH,QAAQ,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO;IAE7D;;;;;;;;OAQG;IACH,QAAQ,CAAC,mBAAmB,CACxB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,GACT,OAAO,CAAC,UAAU,CAAC;CACzB"}
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../src/adapters/base.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzC;;;GAGG;AACH,8BAAsB,gBAAgB,CAAC,CAAC,GAAG,GAAG;IAC1C,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEhC;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,GAAG;IAE9C;;;;OAIG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,cAAc,GAAG,IAAI;IAEjD;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM;IAEvE;;;;;;OAMG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO;IAEjF;;;;;OAKG;IACH,QAAQ,CAAC,kBAAkB,CAAC,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAE3D;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,EAAE,CAAC,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,cAAc,GAAE,MAAkB,GAAG,OAAO;IA8B1F;;;;;;OAMG;IACH,SAAS,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IAErF;;;;;;OAMG;IACH,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAE,MAA6B,GAAG,MAAM;IAIvG;;;;;;OAMG;IACH,QAAQ,CAAC,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO;IAE7D;;;;;;;;OAQG;IACH,QAAQ,CAAC,mBAAmB,CACxB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,GAAG,GACT,OAAO,CAAC,UAAU,CAAC;CACzB"}
@@ -16,7 +16,7 @@ class BaseChainAdapter {
16
16
  */
17
17
  detectTampering(tx, authorities, expectedPrefix = 'DEFAULT') {
18
18
  // First, decode the protocol meta from the transaction
19
- const meta = this.decode(tx);
19
+ const meta = this.decodeMeta(tx);
20
20
  if (!meta) {
21
21
  return false; // No protocol meta found
22
22
  }
@@ -18,13 +18,26 @@ export declare class SolanaAdapter extends BaseChainAdapter<SolanaTransaction> {
18
18
  * @param meta - The protocol meta to encode
19
19
  * @returns TransactionInstruction for the memo
20
20
  */
21
- encode(meta: ProtocolMetaV1): TransactionInstruction;
21
+ encodeMeta(meta: ProtocolMetaV1): TransactionInstruction;
22
22
  /**
23
23
  * Decode protocol meta from Solana transaction (legacy or versioned)
24
- * @param tx - The Solana transaction
24
+ * @param tx - The Solana transaction (can be deserialized object or base64 string)
25
25
  * @returns Decoded ProtocolMetaV1 or null if not found
26
26
  */
27
- decode(tx: SolanaTransaction): ProtocolMetaV1 | null;
27
+ decodeMeta(tx: SolanaTransaction | string): ProtocolMetaV1 | null;
28
+ /**
29
+ * Deserialize a Solana transaction from base64 string
30
+ * @param base64String - Base64 encoded transaction
31
+ * @returns SolanaTransaction object
32
+ */
33
+ deserializeTransaction(base64String: string): SolanaTransaction;
34
+ /**
35
+ * Inject protocol meta into Solana transaction
36
+ * @param serializedTx - Serialized transaction string (base64)
37
+ * @param meta - ProtocolMetaV1 object
38
+ * @returns Serialized transaction with injected meta
39
+ */
40
+ injectMeta(serializedTx: string, meta: ProtocolMetaV1): string;
28
41
  /**
29
42
  * Validate transaction with protocol meta and authority list
30
43
  * @param tx - The Solana transaction
@@ -35,11 +48,11 @@ export declare class SolanaAdapter extends BaseChainAdapter<SolanaTransaction> {
35
48
  validate(tx: SolanaTransaction, authorities: string[], expectedPrefix?: string): boolean;
36
49
  /**
37
50
  * Check if the issuer has signed the transaction
38
- * @param tx - The Solana transaction
51
+ * @param tx - The Solana transaction (can be deserialized object or base64 string)
39
52
  * @param issuer - Issuer public key to check
40
53
  * @returns True if issuer has signed
41
54
  */
42
- hasIssuerSignature(tx: SolanaTransaction, issuer: string): boolean;
55
+ hasIssuerSignature(tx: SolanaTransaction | string, issuer: string): boolean;
43
56
  /**
44
57
  * Decode protocol meta from legacy Solana transaction
45
58
  */
@@ -67,6 +80,7 @@ export declare class SolanaAdapter extends BaseChainAdapter<SolanaTransaction> {
67
80
  * @returns True if transaction integrity is valid
68
81
  */
69
82
  protected validateTransactionIntegrity(tx: SolanaTransaction, meta: ProtocolMetaV1): boolean;
83
+ verifyCodeSignature(actionCode: ActionCode): boolean;
70
84
  /**
71
85
  * Decode protocol meta from base64 string (for backward compatibility)
72
86
  * @param base64String - Base64 encoded transaction
@@ -74,18 +88,10 @@ export declare class SolanaAdapter extends BaseChainAdapter<SolanaTransaction> {
74
88
  */
75
89
  decodeFromBase64(base64String: string): ProtocolMetaV1 | null;
76
90
  /**
77
- * Validate base64 transaction (for backward compatibility)
78
- * @param base64String - Base64 encoded transaction
79
- * @param authorities - Array of valid protocol authority public keys (base58)
80
- * @param expectedPrefix - Expected protocol prefix (default: 'DEFAULT')
81
- * @returns True if transaction is valid
82
- */
83
- validateFromBase64(base64String: string, authorities: string[], expectedPrefix?: string): boolean;
84
- verifyCodeSignature(actionCode: ActionCode): boolean;
85
- /**
86
- * Sign the transaction with the protocol key using a callback approach
87
- * @param signCallback - Callback function that performs the actual signing
88
- * @returns Promise that resolves to the signed transaction
91
+ * Sign the transaction with the protocol key
92
+ * @param actionCode - The action code containing the transaction
93
+ * @param key - The keypair to sign with
94
+ * @returns Promise that resolves to the signed action code
89
95
  */
90
96
  signWithProtocolKey(actionCode: ActionCode, key: Keypair): Promise<ActionCode>;
91
97
  }
@@ -1 +1 @@
1
- {"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../../src/adapters/solana/solana.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EAGpB,OAAO,EACV,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAsB,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,oBAAoB,CAAC;AAEnE;;;GAGG;AACH,qBAAa,aAAc,SAAQ,gBAAgB,CAAC,iBAAiB,CAAC;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAmB;IAE1D,QAAQ,CAAC,KAAK,YAAY;IAE1B;;;;OAIG;IACH,MAAM,CAAC,IAAI,EAAE,cAAc,GAAG,sBAAsB;IAKpD;;;;OAIG;IACH,MAAM,CAAC,EAAE,EAAE,iBAAiB,GAAG,cAAc,GAAG,IAAI;IAWpD;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,cAAc,GAAE,MAAkB,GAAG,OAAO;IAInG;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAWlE;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAqB/B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAUlC;;OAEG;IACH,OAAO,CAAC,eAAe;IAuBvB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAMhC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAenC;;;;;OAKG;IACH,SAAS,CAAC,4BAA4B,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IA6B5F;;;;OAIG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAgB7D;;;;;;OAMG;IACH,kBAAkB,CAAC,YAAY,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,cAAc,GAAE,MAAkB,GAAG,OAAO;IAiBrG,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO;IAa3D;;;;OAIG;IACG,mBAAmB,CACrB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,OAAO,GACb,OAAO,CAAC,UAAU,CAAC;CAkCzB"}
1
+ {"version":3,"file":"solana.d.ts","sourceRoot":"","sources":["../../../src/adapters/solana/solana.ts"],"names":[],"mappings":"AAAA,OAAO,EACH,WAAW,EACX,sBAAsB,EACtB,oBAAoB,EAGpB,OAAO,EACV,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,cAAc,EAAsB,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,WAAW,GAAG,oBAAoB,CAAC;AAEnE;;;GAGG;AACH,qBAAa,aAAc,SAAQ,gBAAgB,CAAC,iBAAiB,CAAC;IAClE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAmB;IAE1D,QAAQ,CAAC,KAAK,YAAY;IAE1B;;;;OAIG;IACH,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,sBAAsB;IAgBxD;;;;OAIG;IACH,UAAU,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM,GAAG,cAAc,GAAG,IAAI;IAoBjE;;;;OAIG;IACI,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,iBAAiB;IActE;;;;;OAKG;IACH,UAAU,CAAC,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,MAAM;IA2E9D;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,cAAc,GAAE,MAAkB,GAAG,OAAO;IAInG;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,EAAE,iBAAiB,GAAG,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAoB3E;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAqB/B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAUlC;;OAEG;IACH,OAAO,CAAC,eAAe;IAuBvB;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAMhC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAenC;;;;;OAKG;IACH,SAAS,CAAC,4BAA4B,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO;IA6BrF,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO;IAa3D;;;;OAIG;IACH,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAI7D;;;;;OAKG;IACG,mBAAmB,CACrB,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,OAAO,GACb,OAAO,CAAC,UAAU,CAAC;CAwCzB"}
@@ -54,16 +54,35 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
54
54
  * @param meta - The protocol meta to encode
55
55
  * @returns TransactionInstruction for the memo
56
56
  */
57
- encode(meta) {
57
+ encodeMeta(meta) {
58
58
  const metaString = meta_1.ProtocolMetaParser.serialize(meta);
59
- return (0, spl_memo_1.createMemoInstruction)(metaString);
59
+ const signerPubkeys = [];
60
+ try {
61
+ if (meta.iss && meta.iss !== 'undefined') {
62
+ const pubkey = new web3_js_1.PublicKey(meta.iss);
63
+ signerPubkeys.push(pubkey);
64
+ }
65
+ }
66
+ catch (error) {
67
+ // Ignore error, issuer is not a valid public key
68
+ }
69
+ return (0, spl_memo_1.createMemoInstruction)(metaString, signerPubkeys);
60
70
  }
61
71
  /**
62
72
  * Decode protocol meta from Solana transaction (legacy or versioned)
63
- * @param tx - The Solana transaction
73
+ * @param tx - The Solana transaction (can be deserialized object or base64 string)
64
74
  * @returns Decoded ProtocolMetaV1 or null if not found
65
75
  */
66
- decode(tx) {
76
+ decodeMeta(tx) {
77
+ // If it's a string, deserialize it first
78
+ if (typeof tx === 'string') {
79
+ try {
80
+ tx = this.deserializeTransaction(tx);
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
67
86
  // Check if it's a versioned transaction
68
87
  if ('message' in tx && tx.message) {
69
88
  return this.decodeVersionedTransaction(tx);
@@ -75,6 +94,90 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
75
94
  return null;
76
95
  }
77
96
  }
97
+ /**
98
+ * Deserialize a Solana transaction from base64 string
99
+ * @param base64String - Base64 encoded transaction
100
+ * @returns SolanaTransaction object
101
+ */
102
+ deserializeTransaction(base64String) {
103
+ try {
104
+ const buffer = buffer_1.Buffer.from(base64String, 'base64');
105
+ // Try legacy first, then versioned
106
+ try {
107
+ return web3_js_1.Transaction.from(buffer);
108
+ }
109
+ catch {
110
+ return web3_js_1.VersionedTransaction.deserialize(buffer);
111
+ }
112
+ }
113
+ catch (error) {
114
+ throw new Error('Failed to deserialize Solana transaction');
115
+ }
116
+ }
117
+ /**
118
+ * Inject protocol meta into Solana transaction
119
+ * @param serializedTx - Serialized transaction string (base64)
120
+ * @param meta - ProtocolMetaV1 object
121
+ * @returns Serialized transaction with injected meta
122
+ */
123
+ injectMeta(serializedTx, meta) {
124
+ // Deserialize the transaction using existing pattern
125
+ const tx = this.deserializeTransaction(serializedTx);
126
+ const metaIx = this.encodeMeta(meta);
127
+ if (tx instanceof web3_js_1.VersionedTransaction) {
128
+ // Convert TransactionInstruction to MessageCompiledInstruction for versioned transactions
129
+ // Create new static account keys array with all required keys
130
+ const newStaticAccountKeys = [...tx.message.staticAccountKeys];
131
+ // Add any missing keys from the memo instruction
132
+ metaIx.keys.forEach(({ pubkey }) => {
133
+ if (!newStaticAccountKeys.some(key => key.equals(pubkey))) {
134
+ newStaticAccountKeys.push(pubkey);
135
+ }
136
+ });
137
+ // Ensure programId is also in static keys
138
+ if (!newStaticAccountKeys.some(key => key.equals(metaIx.programId))) {
139
+ newStaticAccountKeys.push(metaIx.programId);
140
+ }
141
+ // Create new compiled instructions array
142
+ const newCompiledInstructions = [...tx.message.compiledInstructions];
143
+ // Find the program ID index in the new static keys
144
+ const programIdIndex = newStaticAccountKeys.findIndex(key => key.equals(metaIx.programId));
145
+ const accountKeyIndexes = metaIx.keys.map(key => {
146
+ const index = newStaticAccountKeys.findIndex(staticKey => staticKey.equals(key.pubkey));
147
+ if (index === -1) {
148
+ throw new Error(`Account key ${key.pubkey.toBase58()} not found in static account keys`);
149
+ }
150
+ return index;
151
+ });
152
+ const compiledInstruction = {
153
+ programIdIndex,
154
+ accountKeyIndexes,
155
+ data: metaIx.data
156
+ };
157
+ newCompiledInstructions.push(compiledInstruction);
158
+ // Create new MessageV0 with updated data
159
+ const newMessage = new web3_js_1.MessageV0({
160
+ header: tx.message.header,
161
+ staticAccountKeys: newStaticAccountKeys,
162
+ recentBlockhash: tx.message.recentBlockhash,
163
+ compiledInstructions: newCompiledInstructions,
164
+ addressTableLookups: tx.message.addressTableLookups,
165
+ });
166
+ // Create new VersionedTransaction
167
+ const newVersionedTx = new web3_js_1.VersionedTransaction(newMessage);
168
+ return buffer_1.Buffer.from(newVersionedTx.serialize()).toString('base64');
169
+ }
170
+ else if (tx instanceof web3_js_1.Transaction) {
171
+ tx.instructions.push(metaIx);
172
+ // Clear existing signatures since we modified the transaction
173
+ tx.signatures = [];
174
+ // Serialize the transaction back without requiring signatures
175
+ return tx.serialize({ requireAllSignatures: false }).toString('base64');
176
+ }
177
+ else {
178
+ throw new Error('Invalid transaction type');
179
+ }
180
+ }
78
181
  /**
79
182
  * Validate transaction with protocol meta and authority list
80
183
  * @param tx - The Solana transaction
@@ -87,11 +190,20 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
87
190
  }
88
191
  /**
89
192
  * Check if the issuer has signed the transaction
90
- * @param tx - The Solana transaction
193
+ * @param tx - The Solana transaction (can be deserialized object or base64 string)
91
194
  * @param issuer - Issuer public key to check
92
195
  * @returns True if issuer has signed
93
196
  */
94
197
  hasIssuerSignature(tx, issuer) {
198
+ // If it's a string, deserialize it first
199
+ if (typeof tx === 'string') {
200
+ try {
201
+ tx = this.deserializeTransaction(tx);
202
+ }
203
+ catch {
204
+ return false;
205
+ }
206
+ }
95
207
  // Check if it's a versioned transaction
96
208
  if ('message' in tx && tx.message) {
97
209
  return this.hasIssuerSignatureVersioned(tx, issuer);
@@ -114,13 +226,13 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
114
226
  try {
115
227
  const memoString = new TextDecoder().decode(memoData);
116
228
  const meta = meta_1.ProtocolMetaParser.parse(memoString);
117
- if (meta && meta.version !== '1') {
118
- return null;
229
+ if (meta && meta.version === '1') {
230
+ return meta;
119
231
  }
120
- return meta;
232
+ // Continue searching if this memo is not a valid protocol meta
121
233
  }
122
234
  catch {
123
- return null;
235
+ // Continue searching if this memo cannot be parsed
124
236
  }
125
237
  }
126
238
  }
@@ -151,13 +263,13 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
151
263
  try {
152
264
  const memoString = new TextDecoder().decode(memoData);
153
265
  const meta = meta_1.ProtocolMetaParser.parse(memoString);
154
- if (meta && meta.version !== '1') {
155
- return null;
266
+ if (meta && meta.version === '1') {
267
+ return meta;
156
268
  }
157
- return meta;
269
+ // Continue searching if this memo is not a valid protocol meta
158
270
  }
159
271
  catch {
160
- return null;
272
+ // Continue searching if this memo cannot be parsed
161
273
  }
162
274
  }
163
275
  }
@@ -195,7 +307,7 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
195
307
  // Additional Solana-specific validation can be added here
196
308
  // For example, checking transaction signatures, recent blockhash, etc.
197
309
  // Verify that the memo instruction contains the expected protocol meta
198
- const decodedMeta = this.decode(tx);
310
+ const decodedMeta = this.decodeMeta(tx);
199
311
  if (!decodedMeta) {
200
312
  return false;
201
313
  }
@@ -213,52 +325,6 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
213
325
  decodedMeta.iss === meta.iss &&
214
326
  decodedMeta.params === meta.params);
215
327
  }
216
- /**
217
- * Decode protocol meta from base64 string (for backward compatibility)
218
- * @param base64String - Base64 encoded transaction
219
- * @returns Decoded ProtocolMetaV1 or null
220
- */
221
- decodeFromBase64(base64String) {
222
- try {
223
- const buffer = buffer_1.Buffer.from(base64String, 'base64');
224
- // Try legacy first, then versioned
225
- try {
226
- const transaction = web3_js_1.Transaction.from(buffer);
227
- return this.decode(transaction);
228
- }
229
- catch {
230
- const transaction = web3_js_1.VersionedTransaction.deserialize(buffer);
231
- return this.decode(transaction);
232
- }
233
- }
234
- catch {
235
- return null;
236
- }
237
- }
238
- /**
239
- * Validate base64 transaction (for backward compatibility)
240
- * @param base64String - Base64 encoded transaction
241
- * @param authorities - Array of valid protocol authority public keys (base58)
242
- * @param expectedPrefix - Expected protocol prefix (default: 'DEFAULT')
243
- * @returns True if transaction is valid
244
- */
245
- validateFromBase64(base64String, authorities, expectedPrefix = 'DEFAULT') {
246
- try {
247
- const buffer = buffer_1.Buffer.from(base64String, 'base64');
248
- // Try legacy first, then versioned
249
- try {
250
- const transaction = web3_js_1.Transaction.from(buffer);
251
- return this.validate(transaction, authorities, expectedPrefix);
252
- }
253
- catch {
254
- const transaction = web3_js_1.VersionedTransaction.deserialize(buffer);
255
- return this.validate(transaction, authorities, expectedPrefix);
256
- }
257
- }
258
- catch {
259
- return false;
260
- }
261
- }
262
328
  verifyCodeSignature(actionCode) {
263
329
  try {
264
330
  const message = this.getCodeSignatureMessage(actionCode.code, actionCode.timestamp, actionCode.prefix);
@@ -272,30 +338,48 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
272
338
  }
273
339
  }
274
340
  /**
275
- * Sign the transaction with the protocol key using a callback approach
276
- * @param signCallback - Callback function that performs the actual signing
277
- * @returns Promise that resolves to the signed transaction
341
+ * Decode protocol meta from base64 string (for backward compatibility)
342
+ * @param base64String - Base64 encoded transaction
343
+ * @returns Decoded ProtocolMetaV1 or null
344
+ */
345
+ decodeFromBase64(base64String) {
346
+ return this.decodeMeta(base64String);
347
+ }
348
+ /**
349
+ * Sign the transaction with the protocol key
350
+ * @param actionCode - The action code containing the transaction
351
+ * @param key - The keypair to sign with
352
+ * @returns Promise that resolves to the signed action code
278
353
  */
279
354
  async signWithProtocolKey(actionCode, key) {
280
355
  try {
281
356
  if (!actionCode.transaction?.transaction) {
282
357
  throw new Error('No transaction found');
283
358
  }
284
- const tx = web3_js_1.Transaction.from(buffer_1.Buffer.from(actionCode.transaction.transaction, 'base64'));
285
- tx.partialSign(key);
286
- const meta = this.decode(tx);
359
+ const tx = this.deserializeTransaction(actionCode.transaction.transaction);
360
+ // Check if transaction has protocol meta
361
+ const meta = this.decodeMeta(tx);
287
362
  if (!meta) {
288
363
  throw new Error('Invalid transaction, protocol meta not found');
289
364
  }
365
+ // Validate transaction integrity
290
366
  if (!this.validateTransactionIntegrity(tx, meta)) {
291
367
  throw new Error('Invalid transaction, transaction integrity not valid');
292
368
  }
369
+ // Sign the transaction
370
+ if (tx instanceof web3_js_1.Transaction) {
371
+ tx.partialSign(key);
372
+ }
373
+ else if (tx instanceof web3_js_1.VersionedTransaction) {
374
+ tx.sign([key]);
375
+ }
376
+ else {
377
+ throw new Error('Invalid transaction type');
378
+ }
293
379
  const newActionCode = Object.assign({}, actionCode, {
294
380
  transaction: {
295
381
  ...actionCode.transaction,
296
- transaction: buffer_1.Buffer.from(tx.serialize({
297
- requireAllSignatures: false
298
- })).toString('base64'),
382
+ transaction: tx.serialize({ requireAllSignatures: false }).toString('base64'),
299
383
  }
300
384
  });
301
385
  return newActionCode;
@@ -68,13 +68,15 @@ export declare class ActionCodesProtocol {
68
68
  */
69
69
  createActionCode(pubkey: string, signFn: (message: string) => Promise<string>, chain: SupportedChain, prefix?: string, timestamp?: number): Promise<ActionCode>;
70
70
  /**
71
- * Attach a transaction to an action code
71
+ * Attach a transaction to an action code with automatic protocol meta injection
72
72
  * @param actionCode - ActionCode to attach transaction to
73
- * @param transaction - Chain-specific transaction data
73
+ * @param transaction - Chain-specific transaction data (serialized)
74
+ * @param issuer - Issuer public key for protocol meta, this is the proof of who is attaching the transaction to the action code
75
+ * @param params - Optional parameters for protocol meta
74
76
  * @param txType - Optional transaction type
75
- * @returns Updated ActionCode
77
+ * @returns Updated ActionCode with injected protocol meta
76
78
  */
77
- attachTransaction(actionCode: ActionCode, transaction: string, txType?: string): ActionCode;
79
+ attachTransaction(actionCode: ActionCode, transaction: string, issuer: string, params?: string, txType?: string): ActionCode;
78
80
  /**
79
81
  * Finalize an action code with transaction signature
80
82
  * @param actionCode - ActionCode to finalize
@@ -87,9 +89,10 @@ export declare class ActionCodesProtocol {
87
89
  * @param actionCode - ActionCode to create meta for
88
90
  * @param issuer - Optional issuer public key
89
91
  * @param params - Optional parameters
92
+ * @param timestamp - Optional timestamp (defaults to action code timestamp)
90
93
  * @returns ProtocolMetaV1 object
91
94
  */
92
- createProtocolMeta(actionCode: ActionCode, issuer?: string, params?: string): ProtocolMetaV1;
95
+ createProtocolMeta(actionCode: ActionCode, issuer?: string, params?: string, timestamp?: number): ProtocolMetaV1;
93
96
  /**
94
97
  * Encode protocol meta for a specific chain
95
98
  * @param meta - ProtocolMetaV1 object
@@ -106,7 +109,7 @@ export declare class ActionCodesProtocol {
106
109
  decodeProtocolMeta(transaction: any, chain: string): ProtocolMetaV1 | null;
107
110
  /**
108
111
  * Validate a transaction with protocol meta
109
- * @param transaction - Chain-specific transaction
112
+ * @param transaction - Chain-specific transaction (can be serialized string or deserialized object)
110
113
  * @param chain - Source chain
111
114
  * @param authorities - Array of valid protocol authority identifiers
112
115
  * @param expectedPrefix - Expected protocol prefix
@@ -1 +1 @@
1
- {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../src/protocol.ts"],"names":[],"mappings":"AACA,OAAO,EAAsB,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC5D,OAAO,EAAE,UAAU,EAA2C,MAAM,cAAc,CAAC;AACnF,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAA8D,cAAc,EAA2C,MAAM,aAAa,CAAC;AAElJ;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B,uBAAuB;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,aAAa,EAAE,MAAM,CAAC;IACtB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,4BAA4B;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,4BAA4B;IAC5B,eAAe,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;GAKG;AACH,qBAAa,mBAAmB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,QAAQ,CAAiD;gBAErD,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAY5C;;;OAGG;IACH,eAAe,CAAC,CAAC,EAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,GAAG,IAAI;IAItD;;;OAGG;IACH,mBAAmB,IAAI,MAAM,EAAE;IAI/B;;;;OAIG;IACH,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAIxC;;;;OAIG;IACH,eAAe,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAAC,CAAC,CAAC,GAAG,SAAS;IAIxE;;;;OAIG;IACH,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO;IAgBnD;;;;;;;;OAQG;IACG,gBAAgB,CAClB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EAC5C,KAAK,EAAE,cAAc,EACrB,MAAM,GAAE,MAAkC,EAC1C,SAAS,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,UAAU,CAAC;IAqCtB;;;;;;;;OAQG;IACH,iBAAiB,CACb,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GAChB,UAAU;IA4Cb;;;;;OAKG;IACH,kBAAkB,CACd,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,MAAM,GACpB,UAAU;IAsBb;;;;;;;OAOG;IACH,kBAAkB,CACd,UAAU,EAAE,UAAU,EACtB,MAAM,CAAC,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,EACf,SAAS,CAAC,EAAE,MAAM,GACnB,cAAc;IAUjB;;;;;OAKG;IACH,kBAAkB,CAAC,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,GAAG;IAS5D;;;;;OAKG;IACH,kBAAkB,CAAC,WAAW,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAS1E;;;;;;;OAOG;IACH,mBAAmB,CACf,WAAW,EAAE,GAAG,EAChB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EAAE,EACrB,cAAc,CAAC,EAAE,MAAM,GACxB,OAAO;IAUV;;;;;;;OAOG;IACH,wBAAwB,CAAC,CAAC,EACtB,WAAW,EAAE,CAAC,EACd,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EAAE,EACrB,cAAc,CAAC,EAAE,MAAM,GACxB,OAAO;IASV;;;;;;;OAOG;IACH,eAAe,CAAC,CAAC,EACb,WAAW,EAAE,CAAC,EACd,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EAAE,EACrB,cAAc,CAAC,EAAE,MAAM,GACxB,OAAO;IASV;;;;;OAKG;IACH,uBAAuB,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,GAAG,cAAc,GAAG,IAAI;IAShF;;;OAGG;IACH,SAAS,IAAI,cAAc;IAI3B;;;OAGG;IACH,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI;IAIpD;;;OAGG;IACH,MAAM,CAAC,MAAM,IAAI,mBAAmB;IAIpC;;;;OAIG;IACH,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,mBAAmB;CAGhF;AAGD,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACxF,YAAY,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAG7C,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
package/dist/protocol.js CHANGED
@@ -111,20 +111,39 @@ class ActionCodesProtocol {
111
111
  return actionCode;
112
112
  }
113
113
  /**
114
- * Attach a transaction to an action code
114
+ * Attach a transaction to an action code with automatic protocol meta injection
115
115
  * @param actionCode - ActionCode to attach transaction to
116
- * @param transaction - Chain-specific transaction data
116
+ * @param transaction - Chain-specific transaction data (serialized)
117
+ * @param issuer - Issuer public key for protocol meta, this is the proof of who is attaching the transaction to the action code
118
+ * @param params - Optional parameters for protocol meta
117
119
  * @param txType - Optional transaction type
118
- * @returns Updated ActionCode
120
+ * @returns Updated ActionCode with injected protocol meta
119
121
  */
120
- attachTransaction(actionCode, transaction, txType) {
122
+ attachTransaction(actionCode, transaction, issuer, params, txType) {
121
123
  const chain = actionCode.chain;
122
124
  if (!this.isChainSupported(chain)) {
123
125
  throw new Error(`Chain '${chain}' is not supported`);
124
126
  }
127
+ const adapter = this.getChainAdapter(chain);
128
+ if (!adapter) {
129
+ throw new Error(`No adapter found for chain '${chain}'`);
130
+ }
131
+ // Create protocol meta for the transaction using the action code's timestamp
132
+ const protocolMeta = this.createProtocolMeta(actionCode, issuer, params);
133
+ // Check if transaction already has protocol meta
134
+ const existingMeta = adapter.decodeMeta(transaction);
135
+ let finalTransaction;
136
+ if (existingMeta && existingMeta.id === protocolMeta.id) {
137
+ // Transaction already has the correct protocol meta, use as-is
138
+ finalTransaction = transaction;
139
+ }
140
+ else {
141
+ // Inject protocol meta into the transaction using the adapter
142
+ finalTransaction = adapter.injectMeta(transaction, protocolMeta);
143
+ }
125
144
  // Create transaction object
126
145
  const txObject = {
127
- transaction,
146
+ transaction: finalTransaction,
128
147
  txType: txType || chain
129
148
  };
130
149
  // Update ActionCode
@@ -164,10 +183,11 @@ class ActionCodesProtocol {
164
183
  * @param actionCode - ActionCode to create meta for
165
184
  * @param issuer - Optional issuer public key
166
185
  * @param params - Optional parameters
186
+ * @param timestamp - Optional timestamp (defaults to action code timestamp)
167
187
  * @returns ProtocolMetaV1 object
168
188
  */
169
- createProtocolMeta(actionCode, issuer, params) {
170
- return meta_1.ProtocolMetaParser.fromInitiator(actionCode.pubkey, issuer || actionCode.pubkey, actionCode.prefix, params);
189
+ createProtocolMeta(actionCode, issuer, params, timestamp) {
190
+ return meta_1.ProtocolMetaParser.fromInitiator(actionCode.pubkey, issuer || actionCode.pubkey, actionCode.prefix, params, timestamp || actionCode.timestamp);
171
191
  }
172
192
  /**
173
193
  * Encode protocol meta for a specific chain
@@ -180,7 +200,7 @@ class ActionCodesProtocol {
180
200
  if (!adapter) {
181
201
  throw new Error(`Chain '${chain}' is not supported`);
182
202
  }
183
- return adapter.encode(meta);
203
+ return adapter.encodeMeta(meta);
184
204
  }
185
205
  /**
186
206
  * Decode protocol meta from a transaction
@@ -193,11 +213,11 @@ class ActionCodesProtocol {
193
213
  if (!adapter) {
194
214
  return null;
195
215
  }
196
- return adapter.decode(transaction);
216
+ return adapter.decodeMeta(transaction);
197
217
  }
198
218
  /**
199
219
  * Validate a transaction with protocol meta
200
- * @param transaction - Chain-specific transaction
220
+ * @param transaction - Chain-specific transaction (can be serialized string or deserialized object)
201
221
  * @param chain - Source chain
202
222
  * @param authorities - Array of valid protocol authority identifiers
203
223
  * @param expectedPrefix - Expected protocol prefix
@@ -208,6 +228,7 @@ class ActionCodesProtocol {
208
228
  if (!adapter) {
209
229
  return false;
210
230
  }
231
+ // Otherwise use the regular validate method
211
232
  return adapter.validate(transaction, authorities, expectedPrefix);
212
233
  }
213
234
  /**
@@ -251,7 +272,7 @@ class ActionCodesProtocol {
251
272
  if (!adapter) {
252
273
  return null;
253
274
  }
254
- return adapter.decode(transaction);
275
+ return adapter.decodeMeta(transaction);
255
276
  }
256
277
  /**
257
278
  * Get protocol configuration