Skip to content

Solana subscription intent specification #270

Open
lgalabru wants to merge 5 commits into
tempoxyz:mainfrom
solana-foundation:feat/solana-subscriptions
Open

Solana subscription intent specification #270
lgalabru wants to merge 5 commits into
tempoxyz:mainfrom
solana-foundation:feat/solana-subscriptions

Conversation

@lgalabru

Copy link
Copy Markdown
Contributor

No description provided.

@brendanjryan brendanjryan left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I reviewed this against the shared subscription intent draft in #230 and left the main consistency comments inline.

Comment thread specs/methods/solana/draft-solana-subscription-00.md
Comment thread specs/methods/solana/draft-solana-subscription-00.md
Comment thread specs/methods/solana/draft-solana-subscription-00.md
| `methodDetails.mint` | string | REQUIRED | Mint address echoed from `currency`. MUST equal the on-chain `plan.mint` |
| `methodDetails.decimals` | number | REQUIRED | Decimal precision of the mint |
| `methodDetails.tokenProgram` | string | REQUIRED | Token program ID. The value MUST be the SPL Token program or the SPL Token-2022 program |
| `methodDetails.puller` | string | REQUIRED | Base58 of the server's puller pubkey. MUST be `plan.owner` or appear in `plan.pullers` |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

puller is a slightly odd name -- is this consistent with how solana represents it in other places?

Comment thread specs/methods/solana/draft-solana-subscription-00.md
Comment thread specs/methods/solana/draft-solana-subscription-00.md

After successful activation, the server MUST return a
`subscriptionId` in the `Payment-Receipt`. On Solana, the
`subscriptionId` is the base58-encoded `SubscriptionDelegation`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This conflicts with the shared subscription intent, which says subscriptionId MUST be a base64url string without padding and unique within the server subscription namespace. This draft currently makes it the base58 SubscriptionDelegation address, and later server-accounting text says base64url, so the profile is inconsistent both externally and internally.

Suggested fix: keep subscriptionId compliant with the shared intent, and add a Solana-specific receipt field for the chain address, e.g. subscriptionDelegation or delegationAddress = base58 SubscriptionDelegation account address. Also update the accounting bullet to use the same identifier format.

`SubscriptionDelegation` account reflects
`amount_pulled_in_period == amount_per_period` for period 0.

Servers MUST NOT treat activation as successful if the activation

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

subscriptionExpires is optional above, but this sentence treats it as always present.

Suggested fix: make this conditional, e.g. Servers MUST NOT treat activation as successful if subscriptionExpires is present and the activation transaction settles at or after that timestamp.

Servers MUST reject request objects where the mapped per-billing-
period interval is zero or exceeds 8760 hours.

The `externalId` value is the base58 address of the on-chain `Plan`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This redefines externalId from the shared subscription intent. The shared intent defines externalId as the merchant’s reference for the subscription; here it becomes the on-chain Plan PDA, while the text above says the shared field meanings are preserved.

Suggested fix: put the Plan PDA in methodDetails.planId (or methodDetails.plan) and leave externalId with the shared merchant-reference meaning. If the intent is to constrain/redefine externalId for Solana, please state that explicitly rather than saying the shared meaning is preserved.

Servers MUST NOT submit more than one successful renewal charge for
the same billing period.

The on-chain `transfer_subscription` advances

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This renewal paragraph appears duplicated/garbled, and it also blurs the shared subscription invariant. The shared intent is fixed amount, once per billing period; this says the on-chain program accepts any transfer up to the remaining per-period cap.

Suggested fix: clean up the duplicate prose and state that conforming Solana subscription renewals collect exactly amount once per billing period. If the on-chain primitive allows partial/multiple pulls up to a cap, describe that as broader program capability outside this HTTP subscription profile.

| `periodCount` | string | Positive integer count of `periodUnit` values per billing period |
| `recipient` | string | Recipient address authorized for subscription charges. The activation transaction MUST bind the destination at sign time |
| `externalId` | string | Base58 address of the on-chain `Plan` |
| `description` | string | Human-readable subscription description |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

description is elevated to REQUIRED here, but the request examples below do not include it.

Suggested fix: either add description to all Solana subscription request examples, or leave description optional as in the shared subscription intent.

| `methodDetails.decimals` | number | REQUIRED | Decimal precision of the mint |
| `methodDetails.tokenProgram` | string | REQUIRED | Token program ID. The value MUST be the SPL Token program or the SPL Token-2022 program |
| `methodDetails.puller` | string | REQUIRED | Base58 of the server's puller pubkey. MUST be `plan.owner` or appear in `plan.pullers` |
| `methodDetails.programId` | string | OPTIONAL | Base58 of the subscriptions program ID. If omitted, the default value is the canonical mainnet deployment |

@brendanjryan brendanjryan Jun 3, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If programId is optional and defaults to a canonical deployment, the draft needs to define that canonical value. Otherwise clients cannot validate the default unambiguously.

Suggested fix: either make methodDetails.programId REQUIRED or add a canonical IDs table.

| `status` | string | `"success"` |
| `subscriptionId` | string | Base58 of the `SubscriptionDelegation` account address |
| `periodIndex` | string | Decimal index of the billing period (`"0"` on activation) |
| `periodStartTs` | string | {{RFC3339}} start of the current period |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is Ts? timestamp? why not just periodStart?

| `reference` | string | Base58 of the settlement transaction signature |
| `status` | string | `"success"` |
| `subscriptionId` | string | Base58 of the `SubscriptionDelegation` account address |
| `periodIndex` | string | Decimal index of the billing period (`"0"` on activation) |

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if this is a decimal why not an int?

@github-actions

github-actions Bot commented Jun 3, 2026

Copy link
Copy Markdown

Spec Preview

Spec Changed Artifacts
draft-card-charge-00 Yes HTML · TXT · XML · PDF
draft-evm-charge-00 Yes HTML · TXT · XML · PDF
draft-hedera-charge-00 Yes HTML · TXT · XML · PDF
draft-httpauth-payment-00 Yes HTML · TXT · XML · PDF
draft-lightning-charge-00 Yes HTML · TXT · XML · PDF
draft-lightning-session-00 Yes HTML · TXT · XML · PDF
draft-payment-discovery-00 Yes HTML · TXT · XML · PDF
draft-payment-intent-charge-00 Yes HTML · TXT · XML · PDF
draft-payment-transport-mcp-00 Yes HTML · TXT · XML · PDF
draft-solana-charge-00 Yes HTML · TXT · XML · PDF
draft-solana-subscription-00 New HTML · TXT · XML · PDF
draft-stellar-charge-00 Yes HTML · TXT · XML · PDF
draft-stripe-charge-00 Yes HTML · TXT · XML · PDF
draft-tempo-charge-00 Yes HTML · TXT · XML · PDF
draft-tempo-session-00 Yes HTML · TXT · XML · PDF

Browse preview release assets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants