@actioncodes/protocol 1.1.1 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/adapters/base.d.ts +9 -3
  2. package/dist/adapters/base.d.ts.map +1 -1
  3. package/dist/adapters/solana/solana.d.ts +25 -19
  4. package/dist/adapters/solana/solana.d.ts.map +1 -1
  5. package/dist/adapters/solana/solana.js +203 -69
  6. package/dist/protocol.d.ts +9 -6
  7. package/dist/protocol.d.ts.map +1 -1
  8. package/dist/protocol.js +29 -8
  9. package/docs/actioncode/classes/ActionCode.md +23 -23
  10. package/docs/actioncode/interfaces/ActionCodeFields.md +11 -11
  11. package/docs/actioncode/interfaces/ActionCodeMetadata.md +3 -3
  12. package/docs/actioncode/interfaces/ActionCodeTransaction.md +4 -4
  13. package/docs/actioncode/type-aliases/ActionCodeStatus.md +1 -1
  14. package/docs/adapters/base/classes/BaseChainAdapter.md +46 -18
  15. package/docs/adapters/solana/solana/classes/SolanaAdapter.md +87 -61
  16. package/docs/adapters/solana/solana/type-aliases/SolanaTransaction.md +1 -1
  17. package/docs/codegen/classes/CodeGenerator.md +14 -14
  18. package/docs/constants/type-aliases/SupportedChain.md +1 -1
  19. package/docs/constants/variables/CODE_LENGTH.md +1 -1
  20. package/docs/constants/variables/CODE_TTL.md +1 -1
  21. package/docs/constants/variables/MAX_PREFIX_LENGTH.md +1 -1
  22. package/docs/constants/variables/MIN_PREFIX_LENGTH.md +1 -1
  23. package/docs/constants/variables/PROTOCOL_CODE_PREFIX.md +1 -1
  24. package/docs/constants/variables/PROTOCOL_PREFIX.md +1 -1
  25. package/docs/constants/variables/PROTOCOL_VERSION.md +1 -1
  26. package/docs/constants/variables/SUPPORTED_CHAINS.md +1 -1
  27. package/docs/meta/classes/ProtocolMetaParser.md +6 -6
  28. package/docs/meta/interfaces/ProtocolMetaV1.md +7 -7
  29. package/docs/protocol/classes/ActionCodesProtocol.md +45 -27
  30. package/docs/protocol/interfaces/ProtocolConfig.md +7 -7
  31. package/package.json +1 -1
@@ -20,11 +20,11 @@ export declare abstract class BaseChainAdapter<T = any> {
20
20
  abstract decodeMeta(tx: T): ProtocolMetaV1 | null;
21
21
  /**
22
22
  * Inject protocol meta into chain-specific transaction
23
- * @param tx - Chain-specific transaction
23
+ * @param serializedTx - Serialized transaction string
24
24
  * @param meta - ProtocolMetaV1 object
25
- * @returns Chain-specific transaction with injected meta
25
+ * @returns Serialized transaction with injected meta
26
26
  */
27
- abstract injectMeta(tx: T, meta: ProtocolMetaV1): T;
27
+ abstract injectMeta(serializedTx: string, meta: ProtocolMetaV1): string;
28
28
  /**
29
29
  * Validate transaction with protocol meta and authority list
30
30
  * @param tx - Chain-specific transaction
@@ -82,5 +82,11 @@ export declare abstract class BaseChainAdapter<T = any> {
82
82
  * @returns Promise that resolves to the signed transaction
83
83
  */
84
84
  abstract signWithProtocolKey(actionCode: ActionCode, key: any): Promise<ActionCode>;
85
+ /**
86
+ * Verify the finalized transaction
87
+ * @param tx - The finalized transaction to verify
88
+ * @returns True if the transaction is valid
89
+ */
90
+ abstract verifyFinalizedTransaction(tx: any, actionCode: ActionCode): boolean;
85
91
  }
86
92
  //# sourceMappingURL=base.d.ts.map
@@ -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,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,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,GAAG,CAAC;IAEnD;;;;;;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;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,0BAA0B,CAAC,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO;CAChF"}
@@ -1,4 +1,4 @@
1
- import { Transaction, TransactionInstruction, VersionedTransaction, Keypair } from '@solana/web3.js';
1
+ import { Transaction, TransactionInstruction, VersionedTransaction, Keypair, VersionedTransactionResponse } from '@solana/web3.js';
2
2
  import { ProtocolMetaV1 } from '../../meta';
3
3
  import { BaseChainAdapter } from '../base';
4
4
  import { ActionCode } from '../../actioncode';
@@ -21,17 +21,23 @@ export declare class SolanaAdapter extends BaseChainAdapter<SolanaTransaction> {
21
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
- decodeMeta(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;
28
34
  /**
29
35
  * Inject protocol meta into Solana transaction
30
- * @param tx - The Solana transaction
36
+ * @param serializedTx - Serialized transaction string (base64)
31
37
  * @param meta - ProtocolMetaV1 object
32
- * @returns Solana transaction with injected meta
38
+ * @returns Serialized transaction with injected meta
33
39
  */
34
- injectMeta(tx: SolanaTransaction, meta: ProtocolMetaV1): SolanaTransaction;
40
+ injectMeta(serializedTx: string, meta: ProtocolMetaV1): string;
35
41
  /**
36
42
  * Validate transaction with protocol meta and authority list
37
43
  * @param tx - The Solana transaction
@@ -42,11 +48,11 @@ export declare class SolanaAdapter extends BaseChainAdapter<SolanaTransaction> {
42
48
  validate(tx: SolanaTransaction, authorities: string[], expectedPrefix?: string): boolean;
43
49
  /**
44
50
  * Check if the issuer has signed the transaction
45
- * @param tx - The Solana transaction
51
+ * @param tx - The Solana transaction (can be deserialized object or base64 string)
46
52
  * @param issuer - Issuer public key to check
47
53
  * @returns True if issuer has signed
48
54
  */
49
- hasIssuerSignature(tx: SolanaTransaction, issuer: string): boolean;
55
+ hasIssuerSignature(tx: SolanaTransaction | string, issuer: string): boolean;
50
56
  /**
51
57
  * Decode protocol meta from legacy Solana transaction
52
58
  */
@@ -74,6 +80,7 @@ export declare class SolanaAdapter extends BaseChainAdapter<SolanaTransaction> {
74
80
  * @returns True if transaction integrity is valid
75
81
  */
76
82
  protected validateTransactionIntegrity(tx: SolanaTransaction, meta: ProtocolMetaV1): boolean;
83
+ verifyCodeSignature(actionCode: ActionCode): boolean;
77
84
  /**
78
85
  * Decode protocol meta from base64 string (for backward compatibility)
79
86
  * @param base64String - Base64 encoded transaction
@@ -81,19 +88,18 @@ export declare class SolanaAdapter extends BaseChainAdapter<SolanaTransaction> {
81
88
  */
82
89
  decodeFromBase64(base64String: string): ProtocolMetaV1 | null;
83
90
  /**
84
- * Validate base64 transaction (for backward compatibility)
85
- * @param base64String - Base64 encoded transaction
86
- * @param authorities - Array of valid protocol authority public keys (base58)
87
- * @param expectedPrefix - Expected protocol prefix (default: 'DEFAULT')
88
- * @returns True if transaction is valid
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
- validateFromBase64(base64String: string, authorities: string[], expectedPrefix?: string): boolean;
91
- verifyCodeSignature(actionCode: ActionCode): boolean;
96
+ signWithProtocolKey(actionCode: ActionCode, key: Keypair): Promise<ActionCode>;
92
97
  /**
93
- * Sign the transaction with the protocol key using a callback approach
94
- * @param signCallback - Callback function that performs the actual signing
95
- * @returns Promise that resolves to the signed transaction
98
+ * Verify the finalized transaction from blockchain
99
+ * @param tx - The finalized transaction response from blockchain
100
+ * @param actionCode - The action code to verify against
101
+ * @returns True if the transaction is valid and matches the action code
96
102
  */
97
- signWithProtocolKey(actionCode: ActionCode, key: Keypair): Promise<ActionCode>;
103
+ verifyFinalizedTransaction(tx: VersionedTransactionResponse, actionCode: ActionCode): boolean;
98
104
  }
99
105
  //# sourceMappingURL=solana.d.ts.map
@@ -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,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,sBAAsB;IAgBxD;;;;OAIG;IACH,UAAU,CAAC,EAAE,EAAE,iBAAiB,GAAG,cAAc,GAAG,IAAI;IAWxD;;;;;OAKG;IACH,UAAU,CAAC,EAAE,EAAE,iBAAiB,EAAE,IAAI,EAAE,cAAc,GAAG,iBAAiB;IA+C1E;;;;;;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,EACP,4BAA4B,EAC/B,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;IAyCtB;;;;;OAKG;IACH,0BAA0B,CAAC,EAAE,EAAE,4BAA4B,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO;CAwHhG"}
@@ -70,10 +70,19 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
70
70
  }
71
71
  /**
72
72
  * Decode protocol meta from Solana transaction (legacy or versioned)
73
- * @param tx - The Solana transaction
73
+ * @param tx - The Solana transaction (can be deserialized object or base64 string)
74
74
  * @returns Decoded ProtocolMetaV1 or null if not found
75
75
  */
76
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
+ }
77
86
  // Check if it's a versioned transaction
78
87
  if ('message' in tx && tx.message) {
79
88
  return this.decodeVersionedTransaction(tx);
@@ -85,30 +94,56 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
85
94
  return null;
86
95
  }
87
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
+ }
88
117
  /**
89
118
  * Inject protocol meta into Solana transaction
90
- * @param tx - The Solana transaction
119
+ * @param serializedTx - Serialized transaction string (base64)
91
120
  * @param meta - ProtocolMetaV1 object
92
- * @returns Solana transaction with injected meta
121
+ * @returns Serialized transaction with injected meta
93
122
  */
94
- injectMeta(tx, meta) {
123
+ injectMeta(serializedTx, meta) {
124
+ // Deserialize the transaction using existing pattern
125
+ const tx = this.deserializeTransaction(serializedTx);
95
126
  const metaIx = this.encodeMeta(meta);
96
127
  if (tx instanceof web3_js_1.VersionedTransaction) {
97
128
  // Convert TransactionInstruction to MessageCompiledInstruction for versioned transactions
98
- // First, ensure all required keys are in static account keys
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
99
132
  metaIx.keys.forEach(({ pubkey }) => {
100
- if (!tx.message.staticAccountKeys.some(key => key.equals(pubkey))) {
101
- tx.message.staticAccountKeys.push(pubkey);
133
+ if (!newStaticAccountKeys.some(key => key.equals(pubkey))) {
134
+ newStaticAccountKeys.push(pubkey);
102
135
  }
103
136
  });
104
137
  // Ensure programId is also in static keys
105
- if (!tx.message.staticAccountKeys.some(key => key.equals(metaIx.programId))) {
106
- tx.message.staticAccountKeys.push(metaIx.programId);
138
+ if (!newStaticAccountKeys.some(key => key.equals(metaIx.programId))) {
139
+ newStaticAccountKeys.push(metaIx.programId);
107
140
  }
108
- // Now find the program ID index after ensuring it's in the static keys
109
- const programIdIndex = tx.message.staticAccountKeys.findIndex(key => key.equals(metaIx.programId));
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));
110
145
  const accountKeyIndexes = metaIx.keys.map(key => {
111
- const index = tx.message.staticAccountKeys.findIndex(staticKey => staticKey.equals(key.pubkey));
146
+ const index = newStaticAccountKeys.findIndex(staticKey => staticKey.equals(key.pubkey));
112
147
  if (index === -1) {
113
148
  throw new Error(`Account key ${key.pubkey.toBase58()} not found in static account keys`);
114
149
  }
@@ -119,15 +154,29 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
119
154
  accountKeyIndexes,
120
155
  data: metaIx.data
121
156
  };
122
- tx.message.compiledInstructions.push(compiledInstruction);
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');
123
169
  }
124
170
  else if (tx instanceof web3_js_1.Transaction) {
125
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');
126
176
  }
127
177
  else {
128
178
  throw new Error('Invalid transaction type');
129
179
  }
130
- return tx;
131
180
  }
132
181
  /**
133
182
  * Validate transaction with protocol meta and authority list
@@ -141,11 +190,20 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
141
190
  }
142
191
  /**
143
192
  * Check if the issuer has signed the transaction
144
- * @param tx - The Solana transaction
193
+ * @param tx - The Solana transaction (can be deserialized object or base64 string)
145
194
  * @param issuer - Issuer public key to check
146
195
  * @returns True if issuer has signed
147
196
  */
148
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
+ }
149
207
  // Check if it's a versioned transaction
150
208
  if ('message' in tx && tx.message) {
151
209
  return this.hasIssuerSignatureVersioned(tx, issuer);
@@ -267,52 +325,6 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
267
325
  decodedMeta.iss === meta.iss &&
268
326
  decodedMeta.params === meta.params);
269
327
  }
270
- /**
271
- * Decode protocol meta from base64 string (for backward compatibility)
272
- * @param base64String - Base64 encoded transaction
273
- * @returns Decoded ProtocolMetaV1 or null
274
- */
275
- decodeFromBase64(base64String) {
276
- try {
277
- const buffer = buffer_1.Buffer.from(base64String, 'base64');
278
- // Try legacy first, then versioned
279
- try {
280
- const transaction = web3_js_1.Transaction.from(buffer);
281
- return this.decodeMeta(transaction);
282
- }
283
- catch {
284
- const transaction = web3_js_1.VersionedTransaction.deserialize(buffer);
285
- return this.decodeMeta(transaction);
286
- }
287
- }
288
- catch {
289
- return null;
290
- }
291
- }
292
- /**
293
- * Validate base64 transaction (for backward compatibility)
294
- * @param base64String - Base64 encoded transaction
295
- * @param authorities - Array of valid protocol authority public keys (base58)
296
- * @param expectedPrefix - Expected protocol prefix (default: 'DEFAULT')
297
- * @returns True if transaction is valid
298
- */
299
- validateFromBase64(base64String, authorities, expectedPrefix = 'DEFAULT') {
300
- try {
301
- const buffer = buffer_1.Buffer.from(base64String, 'base64');
302
- // Try legacy first, then versioned
303
- try {
304
- const transaction = web3_js_1.Transaction.from(buffer);
305
- return this.validate(transaction, authorities, expectedPrefix);
306
- }
307
- catch {
308
- const transaction = web3_js_1.VersionedTransaction.deserialize(buffer);
309
- return this.validate(transaction, authorities, expectedPrefix);
310
- }
311
- }
312
- catch {
313
- return false;
314
- }
315
- }
316
328
  verifyCodeSignature(actionCode) {
317
329
  try {
318
330
  const message = this.getCodeSignatureMessage(actionCode.code, actionCode.timestamp, actionCode.prefix);
@@ -326,30 +338,48 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
326
338
  }
327
339
  }
328
340
  /**
329
- * Sign the transaction with the protocol key using a callback approach
330
- * @param signCallback - Callback function that performs the actual signing
331
- * @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
332
353
  */
333
354
  async signWithProtocolKey(actionCode, key) {
334
355
  try {
335
356
  if (!actionCode.transaction?.transaction) {
336
357
  throw new Error('No transaction found');
337
358
  }
338
- const tx = web3_js_1.Transaction.from(buffer_1.Buffer.from(actionCode.transaction.transaction, 'base64'));
339
- tx.partialSign(key);
359
+ const tx = this.deserializeTransaction(actionCode.transaction.transaction);
360
+ // Check if transaction has protocol meta
340
361
  const meta = this.decodeMeta(tx);
341
362
  if (!meta) {
342
363
  throw new Error('Invalid transaction, protocol meta not found');
343
364
  }
365
+ // Validate transaction integrity
344
366
  if (!this.validateTransactionIntegrity(tx, meta)) {
345
367
  throw new Error('Invalid transaction, transaction integrity not valid');
346
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
+ }
347
379
  const newActionCode = Object.assign({}, actionCode, {
348
380
  transaction: {
349
381
  ...actionCode.transaction,
350
- transaction: buffer_1.Buffer.from(tx.serialize({
351
- requireAllSignatures: false
352
- })).toString('base64'),
382
+ transaction: tx.serialize({ requireAllSignatures: false }).toString('base64'),
353
383
  }
354
384
  });
355
385
  return newActionCode;
@@ -358,6 +388,110 @@ class SolanaAdapter extends base_1.BaseChainAdapter {
358
388
  throw new Error(`Failed to sign transaction with protocol key: ${error instanceof Error ? error.message : 'Unknown error'}`);
359
389
  }
360
390
  }
391
+ /**
392
+ * Verify the finalized transaction from blockchain
393
+ * @param tx - The finalized transaction response from blockchain
394
+ * @param actionCode - The action code to verify against
395
+ * @returns True if the transaction is valid and matches the action code
396
+ */
397
+ verifyFinalizedTransaction(tx, actionCode) {
398
+ try {
399
+ // Handle null/undefined transaction
400
+ if (tx.transaction === null || tx.transaction === undefined) {
401
+ return false;
402
+ }
403
+ // Both legacy and versioned responses have message and signatures
404
+ const response = tx.transaction;
405
+ if (!response.message || !response.signatures) {
406
+ return false;
407
+ }
408
+ let transaction;
409
+ // Check if it's a versioned transaction by looking at the message structure
410
+ if (response.message instanceof web3_js_1.MessageV0) {
411
+ // Versioned transaction - reconstruct from message and signatures
412
+ transaction = new web3_js_1.VersionedTransaction(response.message);
413
+ // Note: In a real scenario, signatures would be attached, but for testing we just need the message
414
+ }
415
+ else {
416
+ // Legacy transaction - reconstruct from compiled message and signatures
417
+ const compiledMessage = response.message;
418
+ transaction = web3_js_1.Transaction.populate(compiledMessage, response.signatures);
419
+ }
420
+ const meta = this.decodeMeta(transaction);
421
+ if (!meta) {
422
+ return false; // No protocol meta found
423
+ }
424
+ if (!meta.iss) {
425
+ return false; // No issuer field in meta
426
+ }
427
+ if (!actionCode.codeHash) {
428
+ return false; // No codeHash available
429
+ }
430
+ if (!meta.id || meta.id !== actionCode.codeHash) {
431
+ return false; // ID doesn't match expected value
432
+ }
433
+ if (meta.prefix !== actionCode.prefix) {
434
+ return false;
435
+ }
436
+ if (meta.initiator !== actionCode.pubkey) {
437
+ return false;
438
+ }
439
+ let userPubkey = null;
440
+ try {
441
+ userPubkey = new web3_js_1.PublicKey(actionCode.pubkey);
442
+ }
443
+ catch (error) {
444
+ return false;
445
+ }
446
+ if (userPubkey) {
447
+ if (transaction instanceof web3_js_1.VersionedTransaction) {
448
+ const message = transaction.message;
449
+ if (message instanceof web3_js_1.MessageV0) {
450
+ // Check if user's public key is in the static account keys
451
+ const userKeyIndex = message.staticAccountKeys.findIndex(key => key.equals(userPubkey));
452
+ if (userKeyIndex === -1) {
453
+ return false; // User's key not found in transaction
454
+ }
455
+ // Check if user's key is a signer (first bit of header indicates signer status)
456
+ const isUserSigner = (message.header.numRequiredSignatures > 0) &&
457
+ (userKeyIndex < message.header.numRequiredSignatures);
458
+ if (!isUserSigner) {
459
+ return false; // User didn't sign the transaction
460
+ }
461
+ }
462
+ else {
463
+ return false; // Unsupported message type
464
+ }
465
+ }
466
+ else if (transaction instanceof web3_js_1.Transaction) {
467
+ // For legacy transactions, check if user's key is in the account keys
468
+ const accountKeys = transaction.compileMessage().accountKeys;
469
+ const userKeyIndex = accountKeys.findIndex(key => key.equals(userPubkey));
470
+ if (userKeyIndex === -1) {
471
+ return false; // User's key not found in transaction
472
+ }
473
+ // Check if user's key is a signer
474
+ const isUserSigner = userKeyIndex < transaction.compileMessage().header.numRequiredSignatures;
475
+ if (!isUserSigner) {
476
+ return false; // User didn't sign the transaction
477
+ }
478
+ }
479
+ else {
480
+ return false; // Invalid transaction type
481
+ }
482
+ }
483
+ // 5. Check that tx is signed by protocol (issuer)
484
+ if (!this.hasIssuerSignature(transaction, meta.iss)) {
485
+ return false; // Protocol didn't sign the transaction
486
+ }
487
+ // All checks passed
488
+ return true;
489
+ }
490
+ catch (error) {
491
+ // If any error occurs during verification, return false
492
+ return false;
493
+ }
494
+ }
361
495
  }
362
496
  exports.SolanaAdapter = SolanaAdapter;
363
497
  SolanaAdapter.MEMO_PROGRAM_ID = spl_memo_1.MEMO_PROGRAM_ID;
@@ -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":"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"}
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
@@ -197,7 +217,7 @@ class ActionCodesProtocol {
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
  /**