@@ -5,29 +5,36 @@ import {
55 PostConditionPrincipalId ,
66 PostConditionType ,
77} from './constants' ;
8- import { PostCondition , PostConditionModeName } from './postcondition-types' ;
98import {
9+ FungibleComparator ,
10+ NonFungibleComparator ,
11+ PostCondition ,
12+ PostConditionModeName ,
13+ } from './postcondition-types' ;
14+ import { AssetString } from './types' ;
15+ import {
16+ AssetWire ,
17+ PostConditionPrincipalWire ,
1018 PostConditionWire ,
1119 StacksWireType ,
20+ addressToString ,
1221 parseAssetString ,
1322 parsePrincipalString ,
1423 serializePostConditionWire ,
1524} from './wire' ;
1625
17- const FUNGIBLE_COMPARATOR_MAPPING = {
18- eq : FungibleConditionCode . Equal ,
19- gt : FungibleConditionCode . Greater ,
20- lt : FungibleConditionCode . Less ,
21- gte : FungibleConditionCode . GreaterEqual ,
22- lte : FungibleConditionCode . LessEqual ,
23- } ;
26+ /** @internal */
27+ enum PostConditionCodeWireType {
28+ eq = FungibleConditionCode . Equal ,
29+ gt = FungibleConditionCode . Greater ,
30+ lt = FungibleConditionCode . Less ,
31+ gte = FungibleConditionCode . GreaterEqual ,
32+ lte = FungibleConditionCode . LessEqual ,
2433
25- const NON_FUNGIBLE_COMPARATOR_MAPPING = {
26- sent : NonFungibleConditionCode . Sends ,
27- 'not-sent' : NonFungibleConditionCode . DoesNotSend ,
28- } ;
34+ sent = NonFungibleConditionCode . Sends ,
35+ 'not-sent' = NonFungibleConditionCode . DoesNotSend ,
36+ }
2937
30- /** @ignore */
3138export function postConditionToWire ( postcondition : PostCondition ) : PostConditionWire {
3239 switch ( postcondition . type ) {
3340 case 'stx-postcondition' :
@@ -38,7 +45,7 @@ export function postConditionToWire(postcondition: PostCondition): PostCondition
3845 postcondition . address === 'origin'
3946 ? { type : StacksWireType . Principal , prefix : PostConditionPrincipalId . Origin }
4047 : parsePrincipalString ( postcondition . address ) ,
41- conditionCode : FUNGIBLE_COMPARATOR_MAPPING [ postcondition . condition ] ,
48+ conditionCode : conditionTypeToByte ( postcondition . condition ) as FungibleConditionCode ,
4249 amount : BigInt ( postcondition . amount ) ,
4350 } ;
4451 case 'ft-postcondition' :
@@ -49,7 +56,7 @@ export function postConditionToWire(postcondition: PostCondition): PostCondition
4956 postcondition . address === 'origin'
5057 ? { type : StacksWireType . Principal , prefix : PostConditionPrincipalId . Origin }
5158 : parsePrincipalString ( postcondition . address ) ,
52- conditionCode : FUNGIBLE_COMPARATOR_MAPPING [ postcondition . condition ] ,
59+ conditionCode : conditionTypeToByte ( postcondition . condition ) as FungibleConditionCode ,
5360 amount : BigInt ( postcondition . amount ) ,
5461 asset : parseAssetString ( postcondition . asset ) ,
5562 } ;
@@ -61,7 +68,7 @@ export function postConditionToWire(postcondition: PostCondition): PostCondition
6168 postcondition . address === 'origin'
6269 ? { type : StacksWireType . Principal , prefix : PostConditionPrincipalId . Origin }
6370 : parsePrincipalString ( postcondition . address ) ,
64- conditionCode : NON_FUNGIBLE_COMPARATOR_MAPPING [ postcondition . condition ] ,
71+ conditionCode : conditionTypeToByte ( postcondition . condition ) ,
6572 asset : parseAssetString ( postcondition . asset ) ,
6673 assetName : postcondition . assetId ,
6774 } ;
@@ -70,6 +77,63 @@ export function postConditionToWire(postcondition: PostCondition): PostCondition
7077 }
7178}
7279
80+ export function wireToPostCondition ( wire : PostConditionWire ) : PostCondition {
81+ switch ( wire . conditionType ) {
82+ case PostConditionType . STX :
83+ return {
84+ type : 'stx-postcondition' ,
85+ address : principalWireToString ( wire . principal ) ,
86+ condition : conditionByteToType ( wire . conditionCode ) ,
87+ amount : wire . amount . toString ( ) ,
88+ } ;
89+ case PostConditionType . Fungible :
90+ return {
91+ type : 'ft-postcondition' ,
92+ address : principalWireToString ( wire . principal ) ,
93+ condition : conditionByteToType ( wire . conditionCode ) ,
94+ amount : wire . amount . toString ( ) ,
95+ asset : assetWireToString ( wire . asset ) ,
96+ } ;
97+ case PostConditionType . NonFungible :
98+ return {
99+ type : 'nft-postcondition' ,
100+ address : principalWireToString ( wire . principal ) ,
101+ condition : conditionByteToType ( wire . conditionCode ) ,
102+ asset : assetWireToString ( wire . asset ) ,
103+ assetId : wire . assetName ,
104+ } ;
105+ default : {
106+ const _exhaustiveCheck : never = wire ;
107+ throw new Error ( `Invalid post condition type: ${ _exhaustiveCheck } ` ) ;
108+ }
109+ }
110+ }
111+
112+ /** @internal */
113+ export function conditionTypeToByte < T extends FungibleComparator | NonFungibleComparator > (
114+ condition : T
115+ ) : T extends FungibleComparator ? FungibleConditionCode : NonFungibleConditionCode {
116+ return (
117+ PostConditionCodeWireType as unknown as Record <
118+ T ,
119+ T extends FungibleComparator ? FungibleConditionCode : NonFungibleConditionCode
120+ >
121+ ) [ condition ] ;
122+ }
123+
124+ /** @internal */
125+ export function conditionByteToType < T extends FungibleConditionCode | NonFungibleConditionCode > (
126+ wireType : T
127+ ) : T extends FungibleConditionCode ? FungibleComparator : NonFungibleComparator {
128+ return (
129+ PostConditionCodeWireType as unknown as Record <
130+ // numerical enums are bidirectional in TypeScript
131+ T ,
132+ T extends FungibleConditionCode ? FungibleComparator : NonFungibleComparator
133+ >
134+ ) [ wireType ] ;
135+ }
136+
73137/**
74138 * Convert a post condition to a hex string
75139 * @param postcondition - The post condition object to convert
@@ -102,3 +166,26 @@ export function postConditionModeFrom(
102166 if ( mode === 'deny' ) return PostConditionMode . Deny ;
103167 throw new Error ( `Invalid post condition mode: ${ mode } ` ) ;
104168}
169+
170+ /** @internal */
171+ function assetWireToString ( asset : AssetWire ) : AssetString {
172+ const address = addressToString ( asset . address ) ;
173+ const contractId = `${ address } .${ asset . contractName . content } ` as const ;
174+ return `${ contractId } ::${ asset . assetName . content } ` ;
175+ }
176+
177+ /** @internal */
178+ function principalWireToString ( principal : PostConditionPrincipalWire ) : string {
179+ switch ( principal . prefix ) {
180+ case PostConditionPrincipalId . Origin :
181+ return 'origin' ;
182+ case PostConditionPrincipalId . Standard :
183+ return addressToString ( principal . address ) ;
184+ case PostConditionPrincipalId . Contract :
185+ const address = addressToString ( principal . address ) ;
186+ return `${ address } .${ principal . contractName . content } ` ;
187+ default :
188+ const _exhaustiveCheck : never = principal ;
189+ throw new Error ( `Invalid principal type: ${ _exhaustiveCheck } ` ) ;
190+ }
191+ }
0 commit comments