@hazbase/simplicity 0.2.1 → 0.3.0

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.
@@ -3,6 +3,7 @@ import { ElementsRpcClient } from "../core/rpc";
3
3
  import { BondEvidenceBundle, OutputBindingSupportEvaluation, OutputBindingSupportMatrix, PolicyEvidenceBundle, ReceivableEvidenceBundle, PolicyTemplateManifestValidationResult, DefinitionInput, DefinitionVerificationResult, CompileFromFileInput, CompileFromPresetInput, DefinitionDescriptor, StateDocumentDescriptor, StateDocumentInput, StateVerificationResult, SimplicityArtifact, SimplicityClientConfig } from "../core/types";
4
4
  import { RelayerClient } from "../gasless/RelayerClient";
5
5
  import { GaslessTransferInput, GaslessTransferResult, RelayerClientConfig } from "../gasless/types";
6
+ import * as liquidX402 from "../x402";
6
7
  import { CompiledContract } from "./ContractFactory";
7
8
  import { DeployedContract } from "./DeployedContract";
8
9
  import { prepareRedemption, prepareClosing, exportFinalityPayload, buildSettlement, verifySettlement, define, executeClosing, executeRedemption, exportEvidence, inspectClosing, inspectRedemption, issue, load, verify, verifyIssuanceHistory, verifyClosing, verifyRedemption } from "../domain/bond";
@@ -14,6 +15,16 @@ export declare class SimplicityClient {
14
15
  readonly rpc: ElementsRpcClient;
15
16
  readonly payments: {
16
17
  gaslessTransfer: (input: GaslessTransferInput) => Promise<GaslessTransferResult>;
18
+ x402: {
19
+ assets: typeof liquidX402.listLiquidX402Assets;
20
+ resolveAsset: typeof liquidX402.resolveLiquidX402Asset;
21
+ buildRequirements: typeof liquidX402.buildLiquidX402Requirements;
22
+ encodePayment: typeof liquidX402.encodeLiquidXPayment;
23
+ decodePayment: typeof liquidX402.decodeLiquidXPayment;
24
+ preparePsetPayment: (input: liquidX402.LiquidX402PreparePsetPaymentInput) => Promise<liquidX402.LiquidX402PreparePsetPaymentResult>;
25
+ verify: (input: liquidX402.LiquidX402VerifyPaymentInput) => Promise<liquidX402.LiquidX402VerifyPaymentResult>;
26
+ settle: (input: liquidX402.LiquidX402SettlePaymentInput) => Promise<liquidX402.LiquidX402SettlePaymentResult>;
27
+ };
17
28
  };
18
29
  readonly outputBinding: {
19
30
  describeSupport: () => OutputBindingSupportMatrix;
@@ -1,4 +1,37 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.SimplicityClient = void 0;
4
37
  exports.createSimplicityClient = createSimplicityClient;
@@ -10,6 +43,7 @@ const errors_1 = require("../core/errors");
10
43
  const outputBinding_1 = require("../core/outputBinding");
11
44
  const rpc_1 = require("../core/rpc");
12
45
  const RelayerClient_1 = require("../gasless/RelayerClient");
46
+ const liquidX402 = __importStar(require("../x402"));
13
47
  const ContractFactory_1 = require("./ContractFactory");
14
48
  const DeployedContract_1 = require("./DeployedContract");
15
49
  const bond_1 = require("../domain/bond");
@@ -30,6 +64,16 @@ class SimplicityClient {
30
64
  this.rpc = new rpc_1.ElementsRpcClient(config.rpc);
31
65
  this.payments = {
32
66
  gaslessTransfer: async (input) => this.gaslessTransfer(input),
67
+ x402: {
68
+ assets: liquidX402.listLiquidX402Assets,
69
+ resolveAsset: liquidX402.resolveLiquidX402Asset,
70
+ buildRequirements: liquidX402.buildLiquidX402Requirements,
71
+ encodePayment: liquidX402.encodeLiquidXPayment,
72
+ decodePayment: liquidX402.decodeLiquidXPayment,
73
+ preparePsetPayment: async (input) => liquidX402.prepareLiquidX402PsetPayment(this.rpc, input),
74
+ verify: async (input) => liquidX402.verifyLiquidX402Payment(this.rpc, input),
75
+ settle: async (input) => liquidX402.settleLiquidX402Payment(this.rpc, input),
76
+ },
33
77
  };
34
78
  this.outputBinding = {
35
79
  describeSupport: () => (0, outputBinding_1.describeOutputBindingSupport)(),
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ export { createSimplicityClient, SimplicityClient } from "./client/SimplicityCli
2
2
  export { CompiledContract } from "./client/ContractFactory";
3
3
  export { DeployedContract } from "./client/DeployedContract";
4
4
  export { RelayerClient } from "./gasless/RelayerClient";
5
+ export { ElementsRpcClient } from "./core/rpc";
6
+ export * from "./x402";
5
7
  export * from "./core/types";
6
8
  export * from "./core/errors";
7
9
  export { listPresets, getPresetOrThrow } from "./core/presets";
package/dist/index.js CHANGED
@@ -14,10 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.verifyPositionReceipt = exports.signPositionReceipt = exports.verifyCapitalCall = exports.executeCapitalCallRefund = exports.inspectCapitalCallRefund = exports.executeCapitalCallRollover = exports.inspectCapitalCallRollover = exports.executeCapitalCallClaim = exports.inspectCapitalCallClaim = exports.prepareCapitalCall = exports.loadFund = exports.verifyFund = exports.defineFund = exports.exportFinalityPayload = exports.exportBondEvidence = exports.verifyClosing = exports.executeClosing = exports.inspectClosing = exports.prepareClosing = exports.verifySettlement = exports.buildSettlement = exports.verifyRedemption = exports.executeRedemption = exports.inspectRedemption = exports.prepareRedemption = exports.issueBond = exports.loadBond = exports.verifyIssuanceHistory = exports.verifyBond = exports.defineBond = exports.verifyStateDescriptorAgainstArtifact = exports.verifyStateAgainstArtifact = exports.buildArtifactStateMetadata = exports.loadStateInput = exports.verifyDefinitionDescriptorAgainstArtifact = exports.verifyDefinitionAgainstArtifact = exports.buildArtifactDefinitionMetadata = exports.loadDefinitionInput = exports.evaluateOutputBindingSupport = exports.describeOutputBindingSupport = exports.normalizeArtifact = exports.saveArtifact = exports.loadArtifact = exports.getPresetOrThrow = exports.listPresets = exports.RelayerClient = exports.DeployedContract = exports.CompiledContract = exports.SimplicityClient = exports.createSimplicityClient = void 0;
18
- exports.validateCapitalCallState = exports.validateFundDefinition = exports.summarizeFundFinalityPayload = exports.summarizeFundClosingDescriptor = exports.summarizeDistributionDescriptor = exports.summarizeLPPositionReceipt = exports.summarizeCapitalCallState = exports.summarizeFundDefinition = exports.validateBondSettlementMatchesExpected = exports.validateBondSettlementDescriptor = exports.summarizeBondSettlementDescriptor = exports.verifyBondIssuanceHistory = exports.summarizeBondIssuanceState = exports.buildRedeemedBondIssuanceState = exports.validateBondStateTransition = exports.validateBondCrossChecks = exports.validateBondIssuanceState = exports.validateBondDefinition = exports.exportReceivableFinalityPayload = exports.exportReceivableEvidence = exports.verifyReceivableStateHistory = exports.verifyReceivableClosing = exports.prepareReceivableClosing = exports.verifyReceivableWriteOff = exports.prepareReceivableWriteOff = exports.verifyReceivableRepaymentClaim = exports.executeReceivableRepaymentClaim = exports.inspectReceivableRepaymentClaim = exports.prepareReceivableRepaymentClaim = exports.verifyReceivableRepayment = exports.prepareReceivableRepayment = exports.verifyReceivableFundingClaim = exports.executeReceivableFundingClaim = exports.inspectReceivableFundingClaim = exports.prepareReceivableFundingClaim = exports.verifyReceivableFunding = exports.prepareReceivableFunding = exports.loadReceivable = exports.verifyReceivable = exports.defineReceivable = exports.exportFundFinalityPayload = exports.exportFundEvidence = exports.verifyFundClosing = exports.prepareFundClosing = exports.verifyDistribution = exports.executeDistributionClaim = exports.inspectDistributionClaim = exports.reconcilePosition = exports.prepareDistribution = exports.verifyPositionReceiptChain = void 0;
19
- exports.verifyTransfer = exports.verifyState = exports.inspectTransfer = exports.executeTransfer = exports.prepareTransfer = exports.issue = exports.validatePolicyTemplateParams = exports.describePolicyTemplate = exports.validatePolicyTemplateManifest = exports.loadPolicyTemplateManifest = exports.listPolicyTemplates = exports.buildPolicyOutputDescriptor = exports.compilePolicyStateContract = exports.verifyReceivableStateHistoryValidation = exports.validateReceivableWriteOffTransition = exports.validateReceivableRepaymentTransition = exports.validateReceivableFundingTransition = exports.validateReceivableCrossChecks = exports.validateReceivableState = exports.validateReceivableRepaymentClaimDescriptor = exports.validateReceivableRepaymentClaimAgainstState = exports.validateReceivableFundingClaimDescriptor = exports.validateReceivableFundingClaimAgainstState = exports.validateReceivableDefinition = exports.validateReceivableClosingDescriptor = exports.validateReceivableClosingAgainstState = exports.summarizeReceivableState = exports.summarizeReceivableRepaymentClaimDescriptor = exports.summarizeReceivableFundingClaimDescriptor = exports.summarizeReceivableDefinition = exports.summarizeReceivableClosingDescriptor = exports.buildReceivableRepaymentClaimDescriptor = exports.buildReceivableFundingClaimDescriptor = exports.buildReceivableClosingDescriptor = exports.buildFundedReceivableState = exports.buildDefaultedReceivableState = exports.applyReceivableRepayment = exports.buildFundClosingDescriptor = exports.buildDistributionDescriptor = exports.applyDistributionsToReceipt = exports.applyDistributionToReceipt = exports.buildLPPositionReceipt = exports.buildRefundedCapitalCallState = exports.buildClaimedCapitalCallState = exports.validateClosingAgainstReceipt = exports.validateDistributionAgainstReceipt = exports.validateFundCrossChecks = exports.validateFundClosingDescriptor = exports.validateDistributionDescriptor = exports.validateLPPositionReceipt = void 0;
20
- exports.validatePolicyTransferDescriptor = exports.validatePolicyOutputDescriptor = exports.validatePolicyState = exports.summarizePolicyTransferDescriptor = exports.summarizePolicyOutputDescriptor = exports.summarizePolicyState = exports.exportPolicyEvidence = void 0;
17
+ exports.signPositionReceipt = exports.verifyCapitalCall = exports.executeCapitalCallRefund = exports.inspectCapitalCallRefund = exports.executeCapitalCallRollover = exports.inspectCapitalCallRollover = exports.executeCapitalCallClaim = exports.inspectCapitalCallClaim = exports.prepareCapitalCall = exports.loadFund = exports.verifyFund = exports.defineFund = exports.exportFinalityPayload = exports.exportBondEvidence = exports.verifyClosing = exports.executeClosing = exports.inspectClosing = exports.prepareClosing = exports.verifySettlement = exports.buildSettlement = exports.verifyRedemption = exports.executeRedemption = exports.inspectRedemption = exports.prepareRedemption = exports.issueBond = exports.loadBond = exports.verifyIssuanceHistory = exports.verifyBond = exports.defineBond = exports.verifyStateDescriptorAgainstArtifact = exports.verifyStateAgainstArtifact = exports.buildArtifactStateMetadata = exports.loadStateInput = exports.verifyDefinitionDescriptorAgainstArtifact = exports.verifyDefinitionAgainstArtifact = exports.buildArtifactDefinitionMetadata = exports.loadDefinitionInput = exports.evaluateOutputBindingSupport = exports.describeOutputBindingSupport = exports.normalizeArtifact = exports.saveArtifact = exports.loadArtifact = exports.getPresetOrThrow = exports.listPresets = exports.ElementsRpcClient = exports.RelayerClient = exports.DeployedContract = exports.CompiledContract = exports.SimplicityClient = exports.createSimplicityClient = void 0;
18
+ exports.validateFundDefinition = exports.summarizeFundFinalityPayload = exports.summarizeFundClosingDescriptor = exports.summarizeDistributionDescriptor = exports.summarizeLPPositionReceipt = exports.summarizeCapitalCallState = exports.summarizeFundDefinition = exports.validateBondSettlementMatchesExpected = exports.validateBondSettlementDescriptor = exports.summarizeBondSettlementDescriptor = exports.verifyBondIssuanceHistory = exports.summarizeBondIssuanceState = exports.buildRedeemedBondIssuanceState = exports.validateBondStateTransition = exports.validateBondCrossChecks = exports.validateBondIssuanceState = exports.validateBondDefinition = exports.exportReceivableFinalityPayload = exports.exportReceivableEvidence = exports.verifyReceivableStateHistory = exports.verifyReceivableClosing = exports.prepareReceivableClosing = exports.verifyReceivableWriteOff = exports.prepareReceivableWriteOff = exports.verifyReceivableRepaymentClaim = exports.executeReceivableRepaymentClaim = exports.inspectReceivableRepaymentClaim = exports.prepareReceivableRepaymentClaim = exports.verifyReceivableRepayment = exports.prepareReceivableRepayment = exports.verifyReceivableFundingClaim = exports.executeReceivableFundingClaim = exports.inspectReceivableFundingClaim = exports.prepareReceivableFundingClaim = exports.verifyReceivableFunding = exports.prepareReceivableFunding = exports.loadReceivable = exports.verifyReceivable = exports.defineReceivable = exports.exportFundFinalityPayload = exports.exportFundEvidence = exports.verifyFundClosing = exports.prepareFundClosing = exports.verifyDistribution = exports.executeDistributionClaim = exports.inspectDistributionClaim = exports.reconcilePosition = exports.prepareDistribution = exports.verifyPositionReceiptChain = exports.verifyPositionReceipt = void 0;
19
+ exports.verifyState = exports.inspectTransfer = exports.executeTransfer = exports.prepareTransfer = exports.issue = exports.validatePolicyTemplateParams = exports.describePolicyTemplate = exports.validatePolicyTemplateManifest = exports.loadPolicyTemplateManifest = exports.listPolicyTemplates = exports.buildPolicyOutputDescriptor = exports.compilePolicyStateContract = exports.verifyReceivableStateHistoryValidation = exports.validateReceivableWriteOffTransition = exports.validateReceivableRepaymentTransition = exports.validateReceivableFundingTransition = exports.validateReceivableCrossChecks = exports.validateReceivableState = exports.validateReceivableRepaymentClaimDescriptor = exports.validateReceivableRepaymentClaimAgainstState = exports.validateReceivableFundingClaimDescriptor = exports.validateReceivableFundingClaimAgainstState = exports.validateReceivableDefinition = exports.validateReceivableClosingDescriptor = exports.validateReceivableClosingAgainstState = exports.summarizeReceivableState = exports.summarizeReceivableRepaymentClaimDescriptor = exports.summarizeReceivableFundingClaimDescriptor = exports.summarizeReceivableDefinition = exports.summarizeReceivableClosingDescriptor = exports.buildReceivableRepaymentClaimDescriptor = exports.buildReceivableFundingClaimDescriptor = exports.buildReceivableClosingDescriptor = exports.buildFundedReceivableState = exports.buildDefaultedReceivableState = exports.applyReceivableRepayment = exports.buildFundClosingDescriptor = exports.buildDistributionDescriptor = exports.applyDistributionsToReceipt = exports.applyDistributionToReceipt = exports.buildLPPositionReceipt = exports.buildRefundedCapitalCallState = exports.buildClaimedCapitalCallState = exports.validateClosingAgainstReceipt = exports.validateDistributionAgainstReceipt = exports.validateFundCrossChecks = exports.validateFundClosingDescriptor = exports.validateDistributionDescriptor = exports.validateLPPositionReceipt = exports.validateCapitalCallState = void 0;
20
+ exports.validatePolicyTransferDescriptor = exports.validatePolicyOutputDescriptor = exports.validatePolicyState = exports.summarizePolicyTransferDescriptor = exports.summarizePolicyOutputDescriptor = exports.summarizePolicyState = exports.exportPolicyEvidence = exports.verifyTransfer = void 0;
21
21
  var SimplicityClient_1 = require("./client/SimplicityClient");
22
22
  Object.defineProperty(exports, "createSimplicityClient", { enumerable: true, get: function () { return SimplicityClient_1.createSimplicityClient; } });
23
23
  Object.defineProperty(exports, "SimplicityClient", { enumerable: true, get: function () { return SimplicityClient_1.SimplicityClient; } });
@@ -27,6 +27,9 @@ var DeployedContract_1 = require("./client/DeployedContract");
27
27
  Object.defineProperty(exports, "DeployedContract", { enumerable: true, get: function () { return DeployedContract_1.DeployedContract; } });
28
28
  var RelayerClient_1 = require("./gasless/RelayerClient");
29
29
  Object.defineProperty(exports, "RelayerClient", { enumerable: true, get: function () { return RelayerClient_1.RelayerClient; } });
30
+ var rpc_1 = require("./core/rpc");
31
+ Object.defineProperty(exports, "ElementsRpcClient", { enumerable: true, get: function () { return rpc_1.ElementsRpcClient; } });
32
+ __exportStar(require("./x402"), exports);
30
33
  __exportStar(require("./core/types"), exports);
31
34
  __exportStar(require("./core/errors"), exports);
32
35
  var presets_1 = require("./core/presets");
@@ -0,0 +1,125 @@
1
+ import { ElementsRpcClient } from "../core/rpc";
2
+ export declare const LIQUID_X402_SCHEME: "exact-liquid-pset";
3
+ export declare const LIQUID_X402_VERSION: 1;
4
+ export declare const LIQUID_X402_DEFAULT_NETWORK: "liquidtestnet";
5
+ export declare const LIQUID_X402_DEFAULT_TIMEOUT_SECONDS = 60;
6
+ export type LiquidX402Network = "liquidtestnet" | "liquidv1";
7
+ export type LiquidX402AssetKey = "lbtc" | "usdt";
8
+ export interface LiquidX402Asset {
9
+ key: LiquidX402AssetKey;
10
+ label: string;
11
+ network: LiquidX402Network;
12
+ assetId: string;
13
+ decimals: number;
14
+ isNative: boolean;
15
+ }
16
+ export interface LiquidX402RequirementsInput {
17
+ paymentRequestId: string;
18
+ resource: string;
19
+ payTo: string;
20
+ amountAtomic: string | number | bigint;
21
+ network?: LiquidX402Network;
22
+ asset?: LiquidX402AssetKey | string;
23
+ description?: string;
24
+ mimeType?: string;
25
+ maxTimeoutSeconds?: number;
26
+ expiresAt?: string | Date;
27
+ maxFeeSat?: string | number | bigint;
28
+ metadata?: Record<string, unknown>;
29
+ }
30
+ export interface LiquidX402PaymentRequirements {
31
+ scheme: typeof LIQUID_X402_SCHEME;
32
+ network: LiquidX402Network;
33
+ maxAmountRequired: string;
34
+ resource: string;
35
+ description: string;
36
+ mimeType: string;
37
+ payTo: string;
38
+ maxTimeoutSeconds: number;
39
+ asset: string;
40
+ extra: {
41
+ paymentRequestId: string;
42
+ asset: LiquidX402AssetKey;
43
+ assetId: string;
44
+ decimals: number;
45
+ expiresAt: string;
46
+ feeAsset: "lbtc";
47
+ feeAssetId?: string;
48
+ maxFeeSat?: string;
49
+ metadata?: Record<string, unknown>;
50
+ };
51
+ }
52
+ export interface LiquidX402PaymentPayload {
53
+ scheme: typeof LIQUID_X402_SCHEME;
54
+ network: LiquidX402Network;
55
+ paymentRequestId: string;
56
+ asset: LiquidX402AssetKey;
57
+ assetId: string;
58
+ amountAtomic: string;
59
+ payTo: string;
60
+ psetBase64: string;
61
+ summaryHash: string;
62
+ payer?: string;
63
+ expiresAt: string;
64
+ }
65
+ export interface LiquidX402PreparePsetPaymentInput {
66
+ requirements: LiquidX402PaymentRequirements;
67
+ wallet: string;
68
+ payer?: string;
69
+ locktime?: number;
70
+ sign?: boolean;
71
+ }
72
+ export interface LiquidX402PreparePsetPaymentResult {
73
+ paymentPayload: LiquidX402PaymentPayload;
74
+ xPayment: string;
75
+ psetBase64: string;
76
+ summaryHash: string;
77
+ }
78
+ export interface LiquidX402VerifyPaymentInput {
79
+ requirements: LiquidX402PaymentRequirements | Record<string, unknown>;
80
+ paymentPayload: LiquidX402PaymentPayload | Record<string, unknown>;
81
+ now?: Date;
82
+ }
83
+ export interface LiquidX402VerifyPaymentResult {
84
+ isValid: boolean;
85
+ invalidReason?: string;
86
+ payer?: string | null;
87
+ network?: LiquidX402Network;
88
+ paymentRequestId?: string;
89
+ summaryHash?: string;
90
+ }
91
+ export interface LiquidX402SettlePaymentInput extends LiquidX402VerifyPaymentInput {
92
+ wallet?: string;
93
+ broadcast?: boolean;
94
+ }
95
+ export interface LiquidX402SettlePaymentResult {
96
+ success: boolean;
97
+ errorCode?: string;
98
+ txId?: string;
99
+ transactionHash?: string;
100
+ rawTxHex?: string;
101
+ summaryHash?: string;
102
+ }
103
+ type DecodePsbtResult = {
104
+ fees?: Record<string, number>;
105
+ outputs?: Array<{
106
+ amount?: number;
107
+ asset?: string;
108
+ script?: {
109
+ address?: string;
110
+ hex?: string;
111
+ };
112
+ }>;
113
+ };
114
+ export declare const LIQUID_X402_ASSETS: Record<LiquidX402Network, Record<LiquidX402AssetKey, LiquidX402Asset>>;
115
+ export declare function listLiquidX402Assets(network?: LiquidX402Network): LiquidX402Asset[];
116
+ export declare function resolveLiquidX402Asset(asset: LiquidX402AssetKey | string, network?: LiquidX402Network): LiquidX402Asset;
117
+ export declare function buildLiquidX402Requirements(input: LiquidX402RequirementsInput): LiquidX402PaymentRequirements;
118
+ export declare function encodeLiquidXPayment(payload: LiquidX402PaymentPayload): string;
119
+ export declare function decodeLiquidXPayment(raw: string): LiquidX402PaymentPayload | null;
120
+ export declare function prepareLiquidX402PsetPayment(rpc: ElementsRpcClient, input: LiquidX402PreparePsetPaymentInput): Promise<LiquidX402PreparePsetPaymentResult>;
121
+ export declare function verifyLiquidX402Payment(rpc: ElementsRpcClient | null, input: LiquidX402VerifyPaymentInput): Promise<LiquidX402VerifyPaymentResult>;
122
+ export declare function settleLiquidX402Payment(rpc: ElementsRpcClient, input: LiquidX402SettlePaymentInput): Promise<LiquidX402SettlePaymentResult>;
123
+ export declare function verifyLiquidX402PayloadFields(requirements: LiquidX402PaymentRequirements | Record<string, unknown>, payload: LiquidX402PaymentPayload | Record<string, unknown>, now?: Date): LiquidX402VerifyPaymentResult;
124
+ export declare function buildLiquidPsetSummaryHash(decoded: DecodePsbtResult, requirements: LiquidX402PaymentRequirements | Record<string, unknown>): string;
125
+ export {};
@@ -0,0 +1,396 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LIQUID_X402_ASSETS = exports.LIQUID_X402_DEFAULT_TIMEOUT_SECONDS = exports.LIQUID_X402_DEFAULT_NETWORK = exports.LIQUID_X402_VERSION = exports.LIQUID_X402_SCHEME = void 0;
4
+ exports.listLiquidX402Assets = listLiquidX402Assets;
5
+ exports.resolveLiquidX402Asset = resolveLiquidX402Asset;
6
+ exports.buildLiquidX402Requirements = buildLiquidX402Requirements;
7
+ exports.encodeLiquidXPayment = encodeLiquidXPayment;
8
+ exports.decodeLiquidXPayment = decodeLiquidXPayment;
9
+ exports.prepareLiquidX402PsetPayment = prepareLiquidX402PsetPayment;
10
+ exports.verifyLiquidX402Payment = verifyLiquidX402Payment;
11
+ exports.settleLiquidX402Payment = settleLiquidX402Payment;
12
+ exports.verifyLiquidX402PayloadFields = verifyLiquidX402PayloadFields;
13
+ exports.buildLiquidPsetSummaryHash = buildLiquidPsetSummaryHash;
14
+ const node_crypto_1 = require("node:crypto");
15
+ exports.LIQUID_X402_SCHEME = "exact-liquid-pset";
16
+ exports.LIQUID_X402_VERSION = 1;
17
+ exports.LIQUID_X402_DEFAULT_NETWORK = "liquidtestnet";
18
+ exports.LIQUID_X402_DEFAULT_TIMEOUT_SECONDS = 60;
19
+ const LIQUID_TESTNET_USDT_ASSET_ID = "b612eb46313a2cd6ebabd8b7a8eed5696e29898b87a43bff41c94f51acef9d73";
20
+ const LIQUID_MAINNET_USDT_ASSET_ID = "ce091c998b83c78bb71a632313ba3760f1763d9cfcffae02258ffa9865a37bd2";
21
+ exports.LIQUID_X402_ASSETS = {
22
+ liquidtestnet: {
23
+ lbtc: {
24
+ key: "lbtc",
25
+ label: "Liquid Bitcoin",
26
+ network: "liquidtestnet",
27
+ assetId: "bitcoin",
28
+ decimals: 8,
29
+ isNative: true,
30
+ },
31
+ usdt: {
32
+ key: "usdt",
33
+ label: "Tether USDt",
34
+ network: "liquidtestnet",
35
+ assetId: LIQUID_TESTNET_USDT_ASSET_ID,
36
+ decimals: 8,
37
+ isNative: false,
38
+ },
39
+ },
40
+ liquidv1: {
41
+ lbtc: {
42
+ key: "lbtc",
43
+ label: "Liquid Bitcoin",
44
+ network: "liquidv1",
45
+ assetId: "bitcoin",
46
+ decimals: 8,
47
+ isNative: true,
48
+ },
49
+ usdt: {
50
+ key: "usdt",
51
+ label: "Tether USDt",
52
+ network: "liquidv1",
53
+ assetId: LIQUID_MAINNET_USDT_ASSET_ID,
54
+ decimals: 8,
55
+ isNative: false,
56
+ },
57
+ },
58
+ };
59
+ function listLiquidX402Assets(network) {
60
+ if (network)
61
+ return Object.values(exports.LIQUID_X402_ASSETS[network]);
62
+ return Object.values(exports.LIQUID_X402_ASSETS).flatMap((assets) => Object.values(assets));
63
+ }
64
+ function resolveLiquidX402Asset(asset, network = exports.LIQUID_X402_DEFAULT_NETWORK) {
65
+ const key = normalizeAssetKey(asset);
66
+ const resolved = exports.LIQUID_X402_ASSETS[network]?.[key];
67
+ if (!resolved) {
68
+ throw new Error(`unsupported Liquid x402 asset: ${asset} on ${network}`);
69
+ }
70
+ return resolved;
71
+ }
72
+ function buildLiquidX402Requirements(input) {
73
+ const network = normalizeNetwork(input.network ?? exports.LIQUID_X402_DEFAULT_NETWORK);
74
+ const asset = resolveLiquidX402Asset(input.asset ?? "usdt", network);
75
+ const amountAtomic = normalizeAmountAtomic(input.amountAtomic);
76
+ const expiresAt = normalizeExpiresAt(input.expiresAt, input.maxTimeoutSeconds);
77
+ const description = String(input.description ?? "").trim() || "Unlock resource";
78
+ const mimeType = String(input.mimeType ?? "").trim() || "application/octet-stream";
79
+ const maxTimeoutSeconds = normalizeTimeout(input.maxTimeoutSeconds);
80
+ const paymentRequestId = String(input.paymentRequestId ?? "").trim();
81
+ if (!paymentRequestId)
82
+ throw new Error("paymentRequestId is required");
83
+ const resource = String(input.resource ?? "").trim();
84
+ if (!resource)
85
+ throw new Error("resource is required");
86
+ const payTo = String(input.payTo ?? "").trim();
87
+ if (!payTo)
88
+ throw new Error("payTo is required");
89
+ return {
90
+ scheme: exports.LIQUID_X402_SCHEME,
91
+ network,
92
+ maxAmountRequired: amountAtomic,
93
+ resource,
94
+ description,
95
+ mimeType,
96
+ payTo,
97
+ maxTimeoutSeconds,
98
+ asset: asset.assetId,
99
+ extra: {
100
+ paymentRequestId,
101
+ asset: asset.key,
102
+ assetId: asset.assetId,
103
+ decimals: asset.decimals,
104
+ expiresAt,
105
+ feeAsset: "lbtc",
106
+ feeAssetId: exports.LIQUID_X402_ASSETS[network].lbtc.assetId,
107
+ ...(input.maxFeeSat !== undefined ? { maxFeeSat: normalizeAmountAtomic(input.maxFeeSat) } : {}),
108
+ ...(input.metadata ? { metadata: input.metadata } : {}),
109
+ },
110
+ };
111
+ }
112
+ function encodeLiquidXPayment(payload) {
113
+ return Buffer.from(JSON.stringify(payload)).toString("base64url");
114
+ }
115
+ function decodeLiquidXPayment(raw) {
116
+ const value = String(raw ?? "").trim();
117
+ if (!value)
118
+ return null;
119
+ try {
120
+ const parsed = JSON.parse(Buffer.from(value, "base64url").toString("utf8"));
121
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
122
+ return null;
123
+ if (String(parsed.scheme ?? "") !== exports.LIQUID_X402_SCHEME)
124
+ return null;
125
+ return parsed;
126
+ }
127
+ catch {
128
+ return null;
129
+ }
130
+ }
131
+ async function prepareLiquidX402PsetPayment(rpc, input) {
132
+ const requirements = coerceRequirements(input.requirements);
133
+ const amount = atomicToDecimalNumber(requirements.maxAmountRequired, requirements.extra.decimals);
134
+ const outputs = [
135
+ { [requirements.payTo]: amount, asset: requirements.asset },
136
+ ];
137
+ const pset = await rpc.call("createpsbt", [[], outputs, input.locktime ?? 0, true], input.wallet);
138
+ const updatedPset = await rpc.call("utxoupdatepsbt", [pset], input.wallet);
139
+ const signed = input.sign === false
140
+ ? updatedPset
141
+ : (await rpc.call("walletprocesspsbt", [updatedPset, true, "ALL", true], input.wallet)).psbt ?? updatedPset;
142
+ const decoded = await rpc.call("decodepsbt", [signed], input.wallet);
143
+ const summaryHash = buildLiquidPsetSummaryHash(decoded, requirements);
144
+ const paymentPayload = {
145
+ scheme: exports.LIQUID_X402_SCHEME,
146
+ network: requirements.network,
147
+ paymentRequestId: requirements.extra.paymentRequestId,
148
+ asset: requirements.extra.asset,
149
+ assetId: requirements.asset,
150
+ amountAtomic: requirements.maxAmountRequired,
151
+ payTo: requirements.payTo,
152
+ psetBase64: signed,
153
+ summaryHash,
154
+ ...(input.payer ? { payer: input.payer } : {}),
155
+ expiresAt: requirements.extra.expiresAt,
156
+ };
157
+ return {
158
+ paymentPayload,
159
+ xPayment: encodeLiquidXPayment(paymentPayload),
160
+ psetBase64: signed,
161
+ summaryHash,
162
+ };
163
+ }
164
+ async function verifyLiquidX402Payment(rpc, input) {
165
+ const requirements = coerceRequirements(input.requirements);
166
+ const payload = coercePaymentPayload(input.paymentPayload);
167
+ const basic = verifyLiquidX402PayloadFields(requirements, payload, input.now);
168
+ if (!basic.isValid)
169
+ return basic;
170
+ if (!rpc) {
171
+ return basic;
172
+ }
173
+ try {
174
+ const decoded = await rpc.call("decodepsbt", [payload.psetBase64]);
175
+ const actualSummaryHash = buildLiquidPsetSummaryHash(decoded, requirements);
176
+ if (actualSummaryHash !== payload.summaryHash) {
177
+ return { ...basic, isValid: false, invalidReason: "pset_summary_mismatch" };
178
+ }
179
+ if (!decodedContainsExpectedOutput(decoded, requirements)) {
180
+ return { ...basic, isValid: false, invalidReason: "pset_expected_output_missing" };
181
+ }
182
+ if (!decodedFeeWithinCap(decoded, requirements)) {
183
+ return { ...basic, isValid: false, invalidReason: "fee_too_high" };
184
+ }
185
+ return basic;
186
+ }
187
+ catch {
188
+ return { ...basic, isValid: false, invalidReason: "pset_decode_failed" };
189
+ }
190
+ }
191
+ async function settleLiquidX402Payment(rpc, input) {
192
+ const verification = await verifyLiquidX402Payment(rpc, input);
193
+ if (!verification.isValid) {
194
+ return { success: false, errorCode: verification.invalidReason ?? "payment_verification_failed" };
195
+ }
196
+ const payload = coercePaymentPayload(input.paymentPayload);
197
+ try {
198
+ const finalized = await rpc.call("finalizepsbt", [payload.psetBase64, true], input.wallet);
199
+ if (!finalized.complete || !finalized.hex) {
200
+ return { success: false, errorCode: "pset_not_complete", summaryHash: payload.summaryHash };
201
+ }
202
+ const mempool = await rpc.call("testmempoolaccept", [[finalized.hex]], input.wallet);
203
+ if (mempool[0]?.allowed !== true) {
204
+ return {
205
+ success: false,
206
+ errorCode: mempool[0]?.reject_reason || "mempool_rejected",
207
+ rawTxHex: finalized.hex,
208
+ summaryHash: payload.summaryHash,
209
+ };
210
+ }
211
+ if (input.broadcast === false) {
212
+ return { success: true, rawTxHex: finalized.hex, summaryHash: payload.summaryHash };
213
+ }
214
+ const txId = await rpc.call("sendrawtransaction", [finalized.hex], input.wallet);
215
+ return {
216
+ success: true,
217
+ txId,
218
+ transactionHash: txId,
219
+ rawTxHex: finalized.hex,
220
+ summaryHash: payload.summaryHash,
221
+ };
222
+ }
223
+ catch {
224
+ return { success: false, errorCode: "settlement_rpc_failed", summaryHash: payload.summaryHash };
225
+ }
226
+ }
227
+ function verifyLiquidX402PayloadFields(requirements, payload, now = new Date()) {
228
+ const req = coerceRequirements(requirements);
229
+ const parsed = coercePaymentPayload(payload);
230
+ const base = {
231
+ payer: parsed.payer ?? null,
232
+ network: parsed.network,
233
+ paymentRequestId: parsed.paymentRequestId,
234
+ summaryHash: parsed.summaryHash,
235
+ };
236
+ if (parsed.scheme !== exports.LIQUID_X402_SCHEME)
237
+ return { ...base, isValid: false, invalidReason: "unsupported_scheme" };
238
+ if (parsed.network !== req.network)
239
+ return { ...base, isValid: false, invalidReason: "network_mismatch" };
240
+ if (parsed.paymentRequestId !== req.extra.paymentRequestId) {
241
+ return { ...base, isValid: false, invalidReason: "payment_request_mismatch" };
242
+ }
243
+ if (parsed.asset !== req.extra.asset || parsed.assetId !== req.asset) {
244
+ return { ...base, isValid: false, invalidReason: "asset_mismatch" };
245
+ }
246
+ if (parsed.amountAtomic !== req.maxAmountRequired) {
247
+ return { ...base, isValid: false, invalidReason: "amount_mismatch" };
248
+ }
249
+ if (parsed.payTo !== req.payTo)
250
+ return { ...base, isValid: false, invalidReason: "recipient_mismatch" };
251
+ if (!parsed.psetBase64)
252
+ return { ...base, isValid: false, invalidReason: "pset_missing" };
253
+ if (!parsed.summaryHash)
254
+ return { ...base, isValid: false, invalidReason: "summary_hash_missing" };
255
+ if (new Date(parsed.expiresAt).getTime() <= now.getTime()) {
256
+ return { ...base, isValid: false, invalidReason: "payment_expired" };
257
+ }
258
+ return { ...base, isValid: true };
259
+ }
260
+ function buildLiquidPsetSummaryHash(decoded, requirements) {
261
+ const req = coerceRequirements(requirements);
262
+ return sha256Hex(stableStringify({
263
+ scheme: exports.LIQUID_X402_SCHEME,
264
+ network: req.network,
265
+ paymentRequestId: req.extra.paymentRequestId,
266
+ asset: req.extra.asset,
267
+ assetId: req.asset,
268
+ amountAtomic: req.maxAmountRequired,
269
+ payTo: req.payTo,
270
+ outputs: normalizeDecodedOutputs(decoded),
271
+ fees: decoded.fees ?? {},
272
+ }));
273
+ }
274
+ function decodedContainsExpectedOutput(decoded, requirements) {
275
+ const expectedAmount = atomicToDecimalNumber(requirements.maxAmountRequired, requirements.extra.decimals);
276
+ return (decoded.outputs ?? []).some((output) => (String(output.asset ?? "").toLowerCase() === requirements.asset.toLowerCase() &&
277
+ Math.round(Number(output.amount ?? 0) * 10 ** requirements.extra.decimals) ===
278
+ Math.round(expectedAmount * 10 ** requirements.extra.decimals) &&
279
+ String(output.script?.address ?? "") === requirements.payTo));
280
+ }
281
+ function normalizeDecodedOutputs(decoded) {
282
+ return (decoded.outputs ?? []).map((output) => ({
283
+ amount: output.amount ?? null,
284
+ asset: output.asset ?? null,
285
+ address: output.script?.address ?? null,
286
+ scriptPubKey: output.script?.hex ?? null,
287
+ }));
288
+ }
289
+ function coerceRequirements(value) {
290
+ if (!value || typeof value !== "object" || Array.isArray(value))
291
+ throw new Error("requirements must be an object");
292
+ const raw = value;
293
+ const extra = raw.extra && typeof raw.extra === "object" && !Array.isArray(raw.extra) ? raw.extra : {};
294
+ const network = normalizeNetwork(raw.network);
295
+ const asset = resolveLiquidX402Asset(extra.asset ?? raw.asset, network);
296
+ return {
297
+ scheme: exports.LIQUID_X402_SCHEME,
298
+ network,
299
+ maxAmountRequired: normalizeAmountAtomic(raw.maxAmountRequired),
300
+ resource: String(raw.resource ?? ""),
301
+ description: String(raw.description ?? ""),
302
+ mimeType: String(raw.mimeType ?? ""),
303
+ payTo: String(raw.payTo ?? ""),
304
+ maxTimeoutSeconds: normalizeTimeout(raw.maxTimeoutSeconds),
305
+ asset: String(raw.asset ?? extra.assetId ?? asset.assetId),
306
+ extra: {
307
+ paymentRequestId: String(extra.paymentRequestId ?? raw.paymentRequestId ?? ""),
308
+ asset: asset.key,
309
+ assetId: String(extra.assetId ?? raw.asset ?? asset.assetId),
310
+ decimals: Number(extra.decimals ?? asset.decimals),
311
+ expiresAt: String(extra.expiresAt ?? ""),
312
+ feeAsset: "lbtc",
313
+ feeAssetId: String(extra.feeAssetId ?? exports.LIQUID_X402_ASSETS[network].lbtc.assetId),
314
+ ...(extra.maxFeeSat !== undefined ? { maxFeeSat: normalizeAmountAtomic(extra.maxFeeSat) } : {}),
315
+ ...(extra.metadata ? { metadata: extra.metadata } : {}),
316
+ },
317
+ };
318
+ }
319
+ function decodedFeeWithinCap(decoded, requirements) {
320
+ if (requirements.extra.maxFeeSat === undefined)
321
+ return true;
322
+ const maxFeeSat = BigInt(requirements.extra.maxFeeSat);
323
+ const feeSat = Object.values(decoded.fees ?? {}).reduce((sum, amount) => {
324
+ const sat = Math.round(Number(amount) * 100_000_000);
325
+ return sum + BigInt(Number.isFinite(sat) ? sat : 0);
326
+ }, 0n);
327
+ return feeSat <= maxFeeSat;
328
+ }
329
+ function coercePaymentPayload(value) {
330
+ if (!value || typeof value !== "object" || Array.isArray(value))
331
+ throw new Error("payment payload must be an object");
332
+ const raw = value;
333
+ return {
334
+ scheme: exports.LIQUID_X402_SCHEME,
335
+ network: normalizeNetwork(raw.network),
336
+ paymentRequestId: String(raw.paymentRequestId ?? ""),
337
+ asset: normalizeAssetKey(String(raw.asset ?? "")),
338
+ assetId: String(raw.assetId ?? ""),
339
+ amountAtomic: normalizeAmountAtomic(raw.amountAtomic),
340
+ payTo: String(raw.payTo ?? ""),
341
+ psetBase64: String(raw.psetBase64 ?? ""),
342
+ summaryHash: String(raw.summaryHash ?? ""),
343
+ ...(raw.payer ? { payer: String(raw.payer) } : {}),
344
+ expiresAt: String(raw.expiresAt ?? ""),
345
+ };
346
+ }
347
+ function normalizeNetwork(input) {
348
+ const value = String(input ?? "").trim().toLowerCase();
349
+ if (value === "liquidtestnet" || value === "liquidv1")
350
+ return value;
351
+ throw new Error(`unsupported Liquid x402 network: ${String(input)}`);
352
+ }
353
+ function normalizeAssetKey(input) {
354
+ const value = String(input ?? "").trim().toLowerCase();
355
+ if (value === "lbtc" || value === "bitcoin")
356
+ return "lbtc";
357
+ if (value === "usdt" || value === "usdt-liquid" || value === "tether")
358
+ return "usdt";
359
+ throw new Error(`unsupported Liquid x402 asset: ${String(input)}`);
360
+ }
361
+ function normalizeAmountAtomic(input) {
362
+ const raw = typeof input === "bigint" ? input.toString() : String(input ?? "").trim();
363
+ if (!/^\d+$/u.test(raw))
364
+ throw new Error("amountAtomic must be an integer string");
365
+ return BigInt(raw).toString();
366
+ }
367
+ function normalizeTimeout(input) {
368
+ const parsed = Number(input ?? exports.LIQUID_X402_DEFAULT_TIMEOUT_SECONDS);
369
+ return Number.isFinite(parsed) && parsed > 0 ? Math.trunc(parsed) : exports.LIQUID_X402_DEFAULT_TIMEOUT_SECONDS;
370
+ }
371
+ function normalizeExpiresAt(expiresAt, timeoutSeconds) {
372
+ if (expiresAt instanceof Date)
373
+ return expiresAt.toISOString();
374
+ const raw = String(expiresAt ?? "").trim();
375
+ if (raw)
376
+ return new Date(raw).toISOString();
377
+ return new Date(Date.now() + normalizeTimeout(timeoutSeconds) * 1000).toISOString();
378
+ }
379
+ function atomicToDecimalNumber(amountAtomic, decimals) {
380
+ const amount = BigInt(amountAtomic);
381
+ const scale = 10n ** BigInt(decimals);
382
+ const whole = amount / scale;
383
+ const frac = amount % scale;
384
+ return Number(`${whole}.${frac.toString().padStart(decimals, "0")}`);
385
+ }
386
+ function sha256Hex(value) {
387
+ return (0, node_crypto_1.createHash)("sha256").update(value, "utf8").digest("hex");
388
+ }
389
+ function stableStringify(value) {
390
+ if (value === null || typeof value !== "object")
391
+ return JSON.stringify(value);
392
+ if (Array.isArray(value))
393
+ return `[${value.map((entry) => stableStringify(entry)).join(",")}]`;
394
+ const record = value;
395
+ return `{${Object.keys(record).sort().map((key) => `${JSON.stringify(key)}:${stableStringify(record[key])}`).join(",")}}`;
396
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hazbase/simplicity",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "An SDK for Simplicity on Liquid",
5
5
  "author": "IndieSquare Inc <info@hazbase.com>",
6
6
  "keywords": [