@caypo/mpp-canton 0.1.0 → 0.2.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.
- package/.turbo/turbo-build.log +12 -12
- package/.turbo/turbo-test.log +5 -5
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
> @caypo/mpp-canton@0.
|
|
2
|
+
> @caypo/mpp-canton@0.2.0 build /Users/anil/Desktop/caypo/packages/mpp
|
|
3
3
|
> tsup
|
|
4
4
|
|
|
5
5
|
CLI Building entry: src/client.ts, src/index.ts, src/server.ts
|
|
@@ -10,28 +10,28 @@ CLI Target: es2022
|
|
|
10
10
|
CLI Cleaning output folder
|
|
11
11
|
ESM Build start
|
|
12
12
|
CJS Build start
|
|
13
|
-
ESM dist/index.js 497.00 B
|
|
14
|
-
ESM dist/chunk-NTWNP6H5.js 1.14 KB
|
|
15
|
-
ESM dist/server.js 193.00 B
|
|
16
13
|
ESM dist/chunk-757U7PM3.js 4.17 KB
|
|
14
|
+
ESM dist/index.js 497.00 B
|
|
17
15
|
ESM dist/client.js 145.00 B
|
|
18
16
|
ESM dist/chunk-5CWLHTUR.js 3.31 KB
|
|
17
|
+
ESM dist/chunk-NTWNP6H5.js 1.14 KB
|
|
18
|
+
ESM dist/server.js 193.00 B
|
|
19
19
|
ESM dist/index.js.map 893.00 B
|
|
20
|
-
ESM dist/chunk-NTWNP6H5.js.map 2.76 KB
|
|
21
|
-
ESM dist/client.js.map 71.00 B
|
|
22
20
|
ESM dist/chunk-757U7PM3.js.map 8.67 KB
|
|
23
|
-
ESM dist/
|
|
21
|
+
ESM dist/client.js.map 71.00 B
|
|
24
22
|
ESM dist/chunk-5CWLHTUR.js.map 7.01 KB
|
|
23
|
+
ESM dist/chunk-NTWNP6H5.js.map 2.76 KB
|
|
24
|
+
ESM dist/server.js.map 71.00 B
|
|
25
25
|
ESM ⚡️ Build success in 10ms
|
|
26
|
-
CJS dist/server.cjs 5.57 KB
|
|
27
|
-
CJS dist/index.cjs 10.04 KB
|
|
28
26
|
CJS dist/client.cjs 6.38 KB
|
|
27
|
+
CJS dist/index.cjs 10.04 KB
|
|
28
|
+
CJS dist/server.cjs 5.57 KB
|
|
29
|
+
CJS dist/client.cjs.map 11.40 KB
|
|
29
30
|
CJS dist/server.cjs.map 9.75 KB
|
|
30
31
|
CJS dist/index.cjs.map 19.18 KB
|
|
31
|
-
CJS
|
|
32
|
-
CJS ⚡️ Build success in 10ms
|
|
32
|
+
CJS ⚡️ Build success in 11ms
|
|
33
33
|
DTS Build start
|
|
34
|
-
DTS ⚡️ Build success in
|
|
34
|
+
DTS ⚡️ Build success in 748ms
|
|
35
35
|
DTS dist/index.d.ts 2.60 KB
|
|
36
36
|
DTS dist/client.d.ts 839.00 B
|
|
37
37
|
DTS dist/server.d.ts 971.00 B
|
package/.turbo/turbo-test.log
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
|
|
2
|
-
> @caypo/mpp-canton@0.
|
|
2
|
+
> @caypo/mpp-canton@0.2.0 test /Users/anil/Desktop/caypo/packages/mpp
|
|
3
3
|
> vitest run
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
RUN v3.2.4 /Users/anil/Desktop/caypo/packages/mpp
|
|
7
7
|
|
|
8
|
-
✓ src/__tests__/method.test.ts (19 tests)
|
|
8
|
+
✓ src/__tests__/method.test.ts (19 tests) 9ms
|
|
9
9
|
✓ src/__tests__/client.test.ts (6 tests) 18ms
|
|
10
|
-
✓ src/__tests__/server.test.ts (10 tests)
|
|
10
|
+
✓ src/__tests__/server.test.ts (10 tests) 50ms
|
|
11
11
|
|
|
12
12
|
Test Files 3 passed (3)
|
|
13
13
|
Tests 35 passed (35)
|
|
14
|
-
Start at
|
|
15
|
-
Duration
|
|
14
|
+
Start at 12:40:36
|
|
15
|
+
Duration 375ms (transform 120ms, setup 0ms, collect 206ms, tests 77ms, environment 0ms, prepare 206ms)
|
|
16
16
|
|
package/dist/index.cjs
CHANGED
|
@@ -304,7 +304,7 @@ function cantonServer(config) {
|
|
|
304
304
|
}
|
|
305
305
|
|
|
306
306
|
// src/index.ts
|
|
307
|
-
var MPP_CANTON_VERSION = "0.
|
|
307
|
+
var MPP_CANTON_VERSION = "0.2.0";
|
|
308
308
|
// Annotate the CommonJS export names for ESM import in node:
|
|
309
309
|
0 && (module.exports = {
|
|
310
310
|
MPP_CANTON_VERSION,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/method.ts","../src/schemas.ts","../src/client.ts","../src/server.ts"],"sourcesContent":["/**\n * @caypo/mpp-canton — MPP payment method for Canton Network.\n * Uses CIP-56 TransferPreapproval for 1-step transfers.\n */\n\nexport const MPP_CANTON_VERSION = \"0.1.0\";\n\n// Method definition\nexport { cantonMethod } from \"./method.js\";\n\n// Schemas for reuse\nexport {\n credentialPayloadSchema,\n receiptSchema,\n requestSchema,\n} from \"./schemas.js\";\nexport type {\n CantonCredentialPayload,\n CantonReceipt,\n CantonRequest,\n} from \"./schemas.js\";\n\n// Client (agent side)\nexport { cantonClient } from \"./client.js\";\nexport type { CantonMppClientConfig } from \"./client.js\";\n\n// Server (gateway side)\nexport { cantonServer, MppVerificationError } from \"./server.js\";\nexport type { CantonMppServerConfig } from \"./server.js\";\n","/**\n * Canton MPP method definition.\n *\n * Defines the \"canton\" payment method using the mppx Method.from() pattern.\n * The method specifies the request and credential schemas that both\n * client (agent) and server (gateway) use.\n */\n\nimport { Method } from \"mppx\";\nimport { credentialPayloadSchema, requestSchema } from \"./schemas.js\";\n\nexport const cantonMethod = Method.from({\n intent: \"charge\",\n name: \"canton\",\n schema: {\n credential: {\n payload: credentialPayloadSchema,\n },\n request: requestSchema,\n },\n});\n","/**\n * Zod schemas for Canton MPP payment method.\n * Exported separately for reuse in validation, gateway middleware, etc.\n */\n\nimport { z } from \"zod\";\n\nexport const requestSchema = z.object({\n amount: z.string().regex(/^\\d+\\.?\\d{0,10}$/, \"Invalid amount format\"),\n currency: z.enum([\"USDCx\", \"CC\"]),\n recipient: z.string().min(1, \"Recipient party ID required\"),\n network: z.enum([\"mainnet\", \"testnet\", \"devnet\"]),\n description: z.string().optional(),\n expiry: z.number().int().min(1).max(3600).default(300),\n});\n\nexport const credentialPayloadSchema = z.object({\n updateId: z.string().min(1, \"updateId required\"),\n completionOffset: z.number().int(),\n sender: z.string().min(1, \"Sender party ID required\"),\n commandId: z.string().min(1, \"commandId required\"),\n});\n\nexport const receiptSchema = z.object({\n method: z.literal(\"canton\"),\n reference: z.string().min(1),\n status: z.enum([\"success\", \"failed\"]),\n timestamp: z.string(),\n});\n\nexport type CantonRequest = z.infer<typeof requestSchema>;\nexport type CantonCredentialPayload = z.infer<typeof credentialPayloadSchema>;\nexport type CantonReceipt = z.infer<typeof receiptSchema>;\n","/**\n * Canton MPP client — used by agents to pay for services.\n *\n * Flow:\n * 1. Receive 402 challenge with amount, recipient, network\n * 2. Validate network matches agent config\n * 3. Query agent's USDCx holdings via Ledger API\n * 4. Select holdings covering the required amount\n * 5. Exercise TransferFactory_Transfer (1-step, requires recipient TransferPreapproval)\n * 6. Return serialized credential with updateId + completionOffset\n */\n\nimport { Credential, Method, type Challenge } from \"mppx\";\nimport { cantonMethod } from \"./method.js\";\nimport type { CantonRequest } from \"./schemas.js\";\n\nconst USDCX_HOLDING_TEMPLATE_ID = \"Splice.Api.Token.HoldingV1:Holding\";\nconst TRANSFER_FACTORY_TEMPLATE_ID = \"Splice.Api.Token.TransferFactoryV1:TransferFactory\";\nconst USDCX_INSTRUMENT_ID = \"USDCx\";\n\nexport type CantonNetwork = \"mainnet\" | \"testnet\" | \"devnet\";\n\nexport interface CantonMppClientConfig {\n ledgerUrl: string;\n token: string;\n userId: string;\n partyId: string;\n network: CantonNetwork;\n}\n\ninterface HoldingContract {\n contractId: string;\n amount: string;\n}\n\nasync function fetchJson(url: string, token: string, init?: RequestInit): Promise<unknown> {\n const response = await fetch(url, {\n ...init,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n ...(init?.headers as Record<string, string>),\n },\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new Error(`Canton API error: HTTP ${response.status} — ${text}`);\n }\n\n return response.json();\n}\n\nasync function getLedgerEnd(config: CantonMppClientConfig): Promise<number> {\n const data = (await fetchJson(`${config.ledgerUrl}/v2/state/ledger-end`, config.token)) as {\n offset: number;\n };\n return data.offset;\n}\n\nasync function queryHoldings(config: CantonMppClientConfig): Promise<HoldingContract[]> {\n const offset = await getLedgerEnd(config);\n\n const data = (await fetchJson(`${config.ledgerUrl}/v2/state/active-contracts`, config.token, {\n method: \"POST\",\n body: JSON.stringify({\n eventFormat: {\n filtersByParty: {\n [config.partyId]: {\n cumulative: [\n {\n identifierFilter: {\n TemplateFilter: {\n value: { templateId: USDCX_HOLDING_TEMPLATE_ID },\n },\n },\n },\n ],\n },\n },\n verbose: true,\n },\n activeAtOffset: offset,\n }),\n })) as {\n contractEntry?: Array<{\n createdEvent?: { contractId: string; createArgument: { amount: string } };\n }>;\n };\n\n return (data.contractEntry ?? [])\n .filter((e) => e.createdEvent != null)\n .map((e) => ({\n contractId: e.createdEvent!.contractId,\n amount: e.createdEvent!.createArgument.amount,\n }));\n}\n\nfunction selectHoldings(\n holdings: HoldingContract[],\n requiredAmount: string,\n): string[] {\n if (holdings.length === 0) {\n throw new Error(`Insufficient balance: no holdings available`);\n }\n\n // Sort descending\n const sorted = [...holdings].sort(\n (a, b) => parseFloat(b.amount) - parseFloat(a.amount),\n );\n\n // Try single holding\n for (let i = sorted.length - 1; i >= 0; i--) {\n if (parseFloat(sorted[i].amount) >= parseFloat(requiredAmount)) {\n return [sorted[i].contractId];\n }\n }\n\n // Accumulate multiple\n let total = 0;\n const selected: string[] = [];\n for (const h of sorted) {\n selected.push(h.contractId);\n total += parseFloat(h.amount);\n if (total >= parseFloat(requiredAmount)) {\n return selected;\n }\n }\n\n throw new Error(\n `Insufficient balance: have ${total}, need ${requiredAmount}`,\n );\n}\n\nexport function cantonClient(config: CantonMppClientConfig) {\n return Method.toClient(cantonMethod, {\n async createCredential({ challenge }: { challenge: Challenge<CantonRequest> }) {\n // 1. Validate network\n if (challenge.request.network !== config.network) {\n throw new Error(\n `Network mismatch: challenge requires ${challenge.request.network}, agent configured for ${config.network}`,\n );\n }\n\n // 2. Query holdings\n const holdings = await queryHoldings(config);\n\n // 3. Select holdings covering amount\n const selectedCids = selectHoldings(holdings, challenge.request.amount);\n\n // 4. Generate commandId\n const commandId = crypto.randomUUID();\n\n // 5. Exercise TransferFactory_Transfer\n const result = (await fetchJson(\n `${config.ledgerUrl}/v2/commands/submit-and-wait`,\n config.token,\n {\n method: \"POST\",\n body: JSON.stringify({\n commands: [\n {\n ExerciseCommand: {\n templateId: TRANSFER_FACTORY_TEMPLATE_ID,\n contractId: selectedCids[0],\n choice: \"TransferFactory_Transfer\",\n choiceArgument: {\n sender: config.partyId,\n receiver: challenge.request.recipient,\n amount: challenge.request.amount,\n instrumentId: USDCX_INSTRUMENT_ID,\n inputHoldingCids: selectedCids,\n meta: {},\n },\n },\n },\n ],\n userId: config.userId,\n commandId,\n actAs: [config.partyId],\n readAs: [config.partyId],\n }),\n },\n )) as { updateId: string; completionOffset: number };\n\n // 6. Return serialized credential\n return Credential.serialize({\n challenge,\n payload: {\n updateId: result.updateId,\n completionOffset: result.completionOffset,\n sender: config.partyId,\n commandId,\n },\n });\n },\n });\n}\n","/**\n * Canton MPP server — used by gateways to verify payments.\n *\n * Verification flow:\n * 1. Check network matches server config\n * 2. Check recipient matches server's party\n * 3. Fetch transaction from ledger by updateId\n * 4. Find Created Holding event for recipient, verify amount >= required\n * 5. Find Exercised event proving the sender executed the transfer\n * 6. Return receipt\n */\n\nimport { Method, Receipt, type CredentialData } from \"mppx\";\nimport { cantonMethod } from \"./method.js\";\nimport type { CantonCredentialPayload, CantonRequest } from \"./schemas.js\";\n\nexport type CantonNetwork = \"mainnet\" | \"testnet\" | \"devnet\";\n\nexport interface CantonMppServerConfig {\n ledgerUrl: string;\n token: string;\n userId: string;\n recipientPartyId: string;\n network: CantonNetwork;\n}\n\nexport class MppVerificationError extends Error {\n readonly problemCode: string;\n\n constructor(message: string, problemCode: string) {\n super(message);\n this.name = \"MppVerificationError\";\n this.problemCode = problemCode;\n }\n}\n\ninterface TransactionEvent {\n createdEvent?: {\n contractId: string;\n templateId: string;\n createArgument: Record<string, unknown>;\n witnessParties: string[];\n signatories: string[];\n };\n exercisedEvent?: {\n contractId: string;\n choice: string;\n actingParties: string[];\n };\n}\n\ninterface TransactionData {\n updateId: string;\n eventsById?: Record<string, TransactionEvent>;\n rootEventIds?: string[];\n}\n\nfunction findCreatedHolding(\n tx: TransactionData,\n recipientParty: string,\n): { amount: string } | null {\n const events = tx.eventsById ?? {};\n\n for (const evt of Object.values(events)) {\n if (evt.createdEvent) {\n const signatories = evt.createdEvent.signatories ?? [];\n const witnesses = evt.createdEvent.witnessParties ?? [];\n const allParties = [...signatories, ...witnesses];\n\n if (allParties.includes(recipientParty)) {\n const amount = evt.createdEvent.createArgument?.amount;\n if (typeof amount === \"string\") {\n return { amount };\n }\n }\n }\n }\n\n return null;\n}\n\nfunction findExercisedEvent(\n tx: TransactionData,\n senderParty: string,\n): boolean {\n const events = tx.eventsById ?? {};\n\n for (const evt of Object.values(events)) {\n if (evt.exercisedEvent) {\n const acting = evt.exercisedEvent.actingParties ?? [];\n if (acting.includes(senderParty)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function cantonServer(config: CantonMppServerConfig) {\n return Method.toServer(cantonMethod, {\n async verify({\n credential,\n }: {\n credential: CredentialData<CantonCredentialPayload, CantonRequest>;\n }) {\n const { updateId, sender } = credential.payload;\n const { amount, recipient, network } = credential.challenge.request;\n\n // 1. Network check\n if (network !== config.network) {\n throw new MppVerificationError(\n `Network mismatch: credential is for ${network}, server is on ${config.network}`,\n \"verification-failed\",\n );\n }\n\n // 2. Recipient check\n if (recipient !== config.recipientPartyId) {\n throw new MppVerificationError(\n `Recipient mismatch: credential targets ${recipient}, server is ${config.recipientPartyId}`,\n \"verification-failed\",\n );\n }\n\n // 3. Fetch transaction by updateId\n const txResponse = await fetch(\n `${config.ledgerUrl}/v2/updates/transaction-by-id/${encodeURIComponent(updateId)}`,\n {\n headers: {\n Authorization: `Bearer ${config.token}`,\n },\n },\n );\n\n if (!txResponse.ok) {\n throw new MppVerificationError(\n \"Transaction not found on Canton ledger\",\n \"verification-failed\",\n );\n }\n\n const tx = (await txResponse.json()) as TransactionData;\n\n // 4. Find created Holding for recipient and verify amount\n const recipientHolding = findCreatedHolding(tx, config.recipientPartyId);\n if (!recipientHolding) {\n throw new MppVerificationError(\n \"No holding created for recipient in transaction\",\n \"verification-failed\",\n );\n }\n\n if (parseFloat(recipientHolding.amount) < parseFloat(amount)) {\n throw new MppVerificationError(\n `Payment insufficient: received ${recipientHolding.amount}, required ${amount}`,\n \"payment-insufficient\",\n );\n }\n\n // 5. Verify sender\n if (!findExercisedEvent(tx, sender)) {\n throw new MppVerificationError(\n `Sender mismatch: ${sender} did not execute the transfer`,\n \"verification-failed\",\n );\n }\n\n // 6. Return receipt\n return Receipt.from({\n method: \"canton\",\n reference: updateId,\n status: \"success\",\n timestamp: new Date().toISOString(),\n });\n },\n });\n}\n"],"mappings":"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","names":["import_mppx","import_mppx"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/method.ts","../src/schemas.ts","../src/client.ts","../src/server.ts"],"sourcesContent":["/**\n * @caypo/mpp-canton — MPP payment method for Canton Network.\n * Uses CIP-56 TransferPreapproval for 1-step transfers.\n */\n\nexport const MPP_CANTON_VERSION = \"0.2.0\";\n\n// Method definition\nexport { cantonMethod } from \"./method.js\";\n\n// Schemas for reuse\nexport {\n credentialPayloadSchema,\n receiptSchema,\n requestSchema,\n} from \"./schemas.js\";\nexport type {\n CantonCredentialPayload,\n CantonReceipt,\n CantonRequest,\n} from \"./schemas.js\";\n\n// Client (agent side)\nexport { cantonClient } from \"./client.js\";\nexport type { CantonMppClientConfig } from \"./client.js\";\n\n// Server (gateway side)\nexport { cantonServer, MppVerificationError } from \"./server.js\";\nexport type { CantonMppServerConfig } from \"./server.js\";\n","/**\n * Canton MPP method definition.\n *\n * Defines the \"canton\" payment method using the mppx Method.from() pattern.\n * The method specifies the request and credential schemas that both\n * client (agent) and server (gateway) use.\n */\n\nimport { Method } from \"mppx\";\nimport { credentialPayloadSchema, requestSchema } from \"./schemas.js\";\n\nexport const cantonMethod = Method.from({\n intent: \"charge\",\n name: \"canton\",\n schema: {\n credential: {\n payload: credentialPayloadSchema,\n },\n request: requestSchema,\n },\n});\n","/**\n * Zod schemas for Canton MPP payment method.\n * Exported separately for reuse in validation, gateway middleware, etc.\n */\n\nimport { z } from \"zod\";\n\nexport const requestSchema = z.object({\n amount: z.string().regex(/^\\d+\\.?\\d{0,10}$/, \"Invalid amount format\"),\n currency: z.enum([\"USDCx\", \"CC\"]),\n recipient: z.string().min(1, \"Recipient party ID required\"),\n network: z.enum([\"mainnet\", \"testnet\", \"devnet\"]),\n description: z.string().optional(),\n expiry: z.number().int().min(1).max(3600).default(300),\n});\n\nexport const credentialPayloadSchema = z.object({\n updateId: z.string().min(1, \"updateId required\"),\n completionOffset: z.number().int(),\n sender: z.string().min(1, \"Sender party ID required\"),\n commandId: z.string().min(1, \"commandId required\"),\n});\n\nexport const receiptSchema = z.object({\n method: z.literal(\"canton\"),\n reference: z.string().min(1),\n status: z.enum([\"success\", \"failed\"]),\n timestamp: z.string(),\n});\n\nexport type CantonRequest = z.infer<typeof requestSchema>;\nexport type CantonCredentialPayload = z.infer<typeof credentialPayloadSchema>;\nexport type CantonReceipt = z.infer<typeof receiptSchema>;\n","/**\n * Canton MPP client — used by agents to pay for services.\n *\n * Flow:\n * 1. Receive 402 challenge with amount, recipient, network\n * 2. Validate network matches agent config\n * 3. Query agent's USDCx holdings via Ledger API\n * 4. Select holdings covering the required amount\n * 5. Exercise TransferFactory_Transfer (1-step, requires recipient TransferPreapproval)\n * 6. Return serialized credential with updateId + completionOffset\n */\n\nimport { Credential, Method, type Challenge } from \"mppx\";\nimport { cantonMethod } from \"./method.js\";\nimport type { CantonRequest } from \"./schemas.js\";\n\nconst USDCX_HOLDING_TEMPLATE_ID = \"Splice.Api.Token.HoldingV1:Holding\";\nconst TRANSFER_FACTORY_TEMPLATE_ID = \"Splice.Api.Token.TransferFactoryV1:TransferFactory\";\nconst USDCX_INSTRUMENT_ID = \"USDCx\";\n\nexport type CantonNetwork = \"mainnet\" | \"testnet\" | \"devnet\";\n\nexport interface CantonMppClientConfig {\n ledgerUrl: string;\n token: string;\n userId: string;\n partyId: string;\n network: CantonNetwork;\n}\n\ninterface HoldingContract {\n contractId: string;\n amount: string;\n}\n\nasync function fetchJson(url: string, token: string, init?: RequestInit): Promise<unknown> {\n const response = await fetch(url, {\n ...init,\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${token}`,\n ...(init?.headers as Record<string, string>),\n },\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\");\n throw new Error(`Canton API error: HTTP ${response.status} — ${text}`);\n }\n\n return response.json();\n}\n\nasync function getLedgerEnd(config: CantonMppClientConfig): Promise<number> {\n const data = (await fetchJson(`${config.ledgerUrl}/v2/state/ledger-end`, config.token)) as {\n offset: number;\n };\n return data.offset;\n}\n\nasync function queryHoldings(config: CantonMppClientConfig): Promise<HoldingContract[]> {\n const offset = await getLedgerEnd(config);\n\n const data = (await fetchJson(`${config.ledgerUrl}/v2/state/active-contracts`, config.token, {\n method: \"POST\",\n body: JSON.stringify({\n eventFormat: {\n filtersByParty: {\n [config.partyId]: {\n cumulative: [\n {\n identifierFilter: {\n TemplateFilter: {\n value: { templateId: USDCX_HOLDING_TEMPLATE_ID },\n },\n },\n },\n ],\n },\n },\n verbose: true,\n },\n activeAtOffset: offset,\n }),\n })) as {\n contractEntry?: Array<{\n createdEvent?: { contractId: string; createArgument: { amount: string } };\n }>;\n };\n\n return (data.contractEntry ?? [])\n .filter((e) => e.createdEvent != null)\n .map((e) => ({\n contractId: e.createdEvent!.contractId,\n amount: e.createdEvent!.createArgument.amount,\n }));\n}\n\nfunction selectHoldings(\n holdings: HoldingContract[],\n requiredAmount: string,\n): string[] {\n if (holdings.length === 0) {\n throw new Error(`Insufficient balance: no holdings available`);\n }\n\n // Sort descending\n const sorted = [...holdings].sort(\n (a, b) => parseFloat(b.amount) - parseFloat(a.amount),\n );\n\n // Try single holding\n for (let i = sorted.length - 1; i >= 0; i--) {\n if (parseFloat(sorted[i].amount) >= parseFloat(requiredAmount)) {\n return [sorted[i].contractId];\n }\n }\n\n // Accumulate multiple\n let total = 0;\n const selected: string[] = [];\n for (const h of sorted) {\n selected.push(h.contractId);\n total += parseFloat(h.amount);\n if (total >= parseFloat(requiredAmount)) {\n return selected;\n }\n }\n\n throw new Error(\n `Insufficient balance: have ${total}, need ${requiredAmount}`,\n );\n}\n\nexport function cantonClient(config: CantonMppClientConfig) {\n return Method.toClient(cantonMethod, {\n async createCredential({ challenge }: { challenge: Challenge<CantonRequest> }) {\n // 1. Validate network\n if (challenge.request.network !== config.network) {\n throw new Error(\n `Network mismatch: challenge requires ${challenge.request.network}, agent configured for ${config.network}`,\n );\n }\n\n // 2. Query holdings\n const holdings = await queryHoldings(config);\n\n // 3. Select holdings covering amount\n const selectedCids = selectHoldings(holdings, challenge.request.amount);\n\n // 4. Generate commandId\n const commandId = crypto.randomUUID();\n\n // 5. Exercise TransferFactory_Transfer\n const result = (await fetchJson(\n `${config.ledgerUrl}/v2/commands/submit-and-wait`,\n config.token,\n {\n method: \"POST\",\n body: JSON.stringify({\n commands: [\n {\n ExerciseCommand: {\n templateId: TRANSFER_FACTORY_TEMPLATE_ID,\n contractId: selectedCids[0],\n choice: \"TransferFactory_Transfer\",\n choiceArgument: {\n sender: config.partyId,\n receiver: challenge.request.recipient,\n amount: challenge.request.amount,\n instrumentId: USDCX_INSTRUMENT_ID,\n inputHoldingCids: selectedCids,\n meta: {},\n },\n },\n },\n ],\n userId: config.userId,\n commandId,\n actAs: [config.partyId],\n readAs: [config.partyId],\n }),\n },\n )) as { updateId: string; completionOffset: number };\n\n // 6. Return serialized credential\n return Credential.serialize({\n challenge,\n payload: {\n updateId: result.updateId,\n completionOffset: result.completionOffset,\n sender: config.partyId,\n commandId,\n },\n });\n },\n });\n}\n","/**\n * Canton MPP server — used by gateways to verify payments.\n *\n * Verification flow:\n * 1. Check network matches server config\n * 2. Check recipient matches server's party\n * 3. Fetch transaction from ledger by updateId\n * 4. Find Created Holding event for recipient, verify amount >= required\n * 5. Find Exercised event proving the sender executed the transfer\n * 6. Return receipt\n */\n\nimport { Method, Receipt, type CredentialData } from \"mppx\";\nimport { cantonMethod } from \"./method.js\";\nimport type { CantonCredentialPayload, CantonRequest } from \"./schemas.js\";\n\nexport type CantonNetwork = \"mainnet\" | \"testnet\" | \"devnet\";\n\nexport interface CantonMppServerConfig {\n ledgerUrl: string;\n token: string;\n userId: string;\n recipientPartyId: string;\n network: CantonNetwork;\n}\n\nexport class MppVerificationError extends Error {\n readonly problemCode: string;\n\n constructor(message: string, problemCode: string) {\n super(message);\n this.name = \"MppVerificationError\";\n this.problemCode = problemCode;\n }\n}\n\ninterface TransactionEvent {\n createdEvent?: {\n contractId: string;\n templateId: string;\n createArgument: Record<string, unknown>;\n witnessParties: string[];\n signatories: string[];\n };\n exercisedEvent?: {\n contractId: string;\n choice: string;\n actingParties: string[];\n };\n}\n\ninterface TransactionData {\n updateId: string;\n eventsById?: Record<string, TransactionEvent>;\n rootEventIds?: string[];\n}\n\nfunction findCreatedHolding(\n tx: TransactionData,\n recipientParty: string,\n): { amount: string } | null {\n const events = tx.eventsById ?? {};\n\n for (const evt of Object.values(events)) {\n if (evt.createdEvent) {\n const signatories = evt.createdEvent.signatories ?? [];\n const witnesses = evt.createdEvent.witnessParties ?? [];\n const allParties = [...signatories, ...witnesses];\n\n if (allParties.includes(recipientParty)) {\n const amount = evt.createdEvent.createArgument?.amount;\n if (typeof amount === \"string\") {\n return { amount };\n }\n }\n }\n }\n\n return null;\n}\n\nfunction findExercisedEvent(\n tx: TransactionData,\n senderParty: string,\n): boolean {\n const events = tx.eventsById ?? {};\n\n for (const evt of Object.values(events)) {\n if (evt.exercisedEvent) {\n const acting = evt.exercisedEvent.actingParties ?? [];\n if (acting.includes(senderParty)) {\n return true;\n }\n }\n }\n\n return false;\n}\n\nexport function cantonServer(config: CantonMppServerConfig) {\n return Method.toServer(cantonMethod, {\n async verify({\n credential,\n }: {\n credential: CredentialData<CantonCredentialPayload, CantonRequest>;\n }) {\n const { updateId, sender } = credential.payload;\n const { amount, recipient, network } = credential.challenge.request;\n\n // 1. Network check\n if (network !== config.network) {\n throw new MppVerificationError(\n `Network mismatch: credential is for ${network}, server is on ${config.network}`,\n \"verification-failed\",\n );\n }\n\n // 2. Recipient check\n if (recipient !== config.recipientPartyId) {\n throw new MppVerificationError(\n `Recipient mismatch: credential targets ${recipient}, server is ${config.recipientPartyId}`,\n \"verification-failed\",\n );\n }\n\n // 3. Fetch transaction by updateId\n const txResponse = await fetch(\n `${config.ledgerUrl}/v2/updates/transaction-by-id/${encodeURIComponent(updateId)}`,\n {\n headers: {\n Authorization: `Bearer ${config.token}`,\n },\n },\n );\n\n if (!txResponse.ok) {\n throw new MppVerificationError(\n \"Transaction not found on Canton ledger\",\n \"verification-failed\",\n );\n }\n\n const tx = (await txResponse.json()) as TransactionData;\n\n // 4. Find created Holding for recipient and verify amount\n const recipientHolding = findCreatedHolding(tx, config.recipientPartyId);\n if (!recipientHolding) {\n throw new MppVerificationError(\n \"No holding created for recipient in transaction\",\n \"verification-failed\",\n );\n }\n\n if (parseFloat(recipientHolding.amount) < parseFloat(amount)) {\n throw new MppVerificationError(\n `Payment insufficient: received ${recipientHolding.amount}, required ${amount}`,\n \"payment-insufficient\",\n );\n }\n\n // 5. Verify sender\n if (!findExercisedEvent(tx, sender)) {\n throw new MppVerificationError(\n `Sender mismatch: ${sender} did not execute the transfer`,\n \"verification-failed\",\n );\n }\n\n // 6. Return receipt\n return Receipt.from({\n method: \"canton\",\n reference: updateId,\n status: \"success\",\n timestamp: new Date().toISOString(),\n });\n },\n });\n}\n"],"mappings":"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","names":["import_mppx","import_mppx"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -79,6 +79,6 @@ type CantonReceipt = z.infer<typeof receiptSchema>;
|
|
|
79
79
|
* @caypo/mpp-canton — MPP payment method for Canton Network.
|
|
80
80
|
* Uses CIP-56 TransferPreapproval for 1-step transfers.
|
|
81
81
|
*/
|
|
82
|
-
declare const MPP_CANTON_VERSION = "0.
|
|
82
|
+
declare const MPP_CANTON_VERSION = "0.2.0";
|
|
83
83
|
|
|
84
84
|
export { type CantonCredentialPayload, type CantonReceipt, type CantonRequest, MPP_CANTON_VERSION, cantonMethod, credentialPayloadSchema, receiptSchema, requestSchema };
|
package/dist/index.d.ts
CHANGED
|
@@ -79,6 +79,6 @@ type CantonReceipt = z.infer<typeof receiptSchema>;
|
|
|
79
79
|
* @caypo/mpp-canton — MPP payment method for Canton Network.
|
|
80
80
|
* Uses CIP-56 TransferPreapproval for 1-step transfers.
|
|
81
81
|
*/
|
|
82
|
-
declare const MPP_CANTON_VERSION = "0.
|
|
82
|
+
declare const MPP_CANTON_VERSION = "0.2.0";
|
|
83
83
|
|
|
84
84
|
export { type CantonCredentialPayload, type CantonReceipt, type CantonRequest, MPP_CANTON_VERSION, cantonMethod, credentialPayloadSchema, receiptSchema, requestSchema };
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @caypo/mpp-canton — MPP payment method for Canton Network.\n * Uses CIP-56 TransferPreapproval for 1-step transfers.\n */\n\nexport const MPP_CANTON_VERSION = \"0.
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["/**\n * @caypo/mpp-canton — MPP payment method for Canton Network.\n * Uses CIP-56 TransferPreapproval for 1-step transfers.\n */\n\nexport const MPP_CANTON_VERSION = \"0.2.0\";\n\n// Method definition\nexport { cantonMethod } from \"./method.js\";\n\n// Schemas for reuse\nexport {\n credentialPayloadSchema,\n receiptSchema,\n requestSchema,\n} from \"./schemas.js\";\nexport type {\n CantonCredentialPayload,\n CantonReceipt,\n CantonRequest,\n} from \"./schemas.js\";\n\n// Client (agent side)\nexport { cantonClient } from \"./client.js\";\nexport type { CantonMppClientConfig } from \"./client.js\";\n\n// Server (gateway side)\nexport { cantonServer, MppVerificationError } from \"./server.js\";\nexport type { CantonMppServerConfig } from \"./server.js\";\n"],"mappings":";;;;;;;;;;;;;;;AAKO,IAAM,qBAAqB;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caypo/mpp-canton",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Canton Network payment method for the Machine Payments Protocol (MPP) — accept and make USDCx payments in any HTTP API",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"canton",
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"stripe",
|
|
15
15
|
"tempo"
|
|
16
16
|
],
|
|
17
|
-
"author": "Cayvox Labs <
|
|
17
|
+
"author": "Cayvox Labs <dev@caypo.xyz>",
|
|
18
18
|
"homepage": "https://github.com/anilkaracay/Caypo/tree/main/packages/mpp",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|