Skip to content

Commit

Permalink
Merge 3eae5ca into 35f2578
Browse files Browse the repository at this point in the history
  • Loading branch information
bucko13 committed Feb 5, 2020
2 parents 35f2578 + 3eae5ca commit 72c273f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 4 deletions.
17 changes: 14 additions & 3 deletions src/configs/time.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { Caveat, expirationSatisfier } from 'lsat-js'
* amount paid
*/
const getTimeCaveat: CaveatGetter = (
_req: Request,
req: Request,
invoice: InvoiceResponse
): string => {
const amount =
Expand All @@ -28,10 +28,21 @@ const getTimeCaveat: CaveatGetter = (
: invoice.amount

// amount is in satoshis which is equal to the amount of seconds paid for
const milli: number = amount * 1000
let time

if (req.boltwallConfig && req.boltwallConfig.rate) {
// rate is expected to be in satoshis per second
const rate = req.boltwallConfig.rate
const seconds = amount / rate
time = Date.now() + seconds * 1000
} else {
const milli: number = amount * 1000
time = Date.now() + milli
}

// add 200 milliseconds of "free time" as a buffer
const time = Date.now() + milli + 200
time += 200

const caveat = new Caveat({ condition: 'expiration', value: time.toString() })
return caveat.encode()
}
Expand Down
2 changes: 1 addition & 1 deletion src/routes/paywall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ export default async function paywall(
// challenge caveats should already have been verified at this point for oauth
// so we can just continue to the paywall as all remaining checks are against our node
if (req?.boltwallConfig?.oauth) {
if (!lsat.isSatisfied()) req.logger.warning(`LSAT submitted to oauth server from ${req.ip} that is not satisfied with preimage`)
if (!lsat.isSatisfied()) req.logger.warning(`LSAT submitted to oauth server from ${req.ip} that is not satisfied with preimage but has valid signature.`)
return next()
}

Expand Down
2 changes: 2 additions & 0 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,14 @@ const {
BOLTWALL_OAUTH,
BOLTWALL_HODL,
BOLTWALL_MIN_AMOUNT,
BOLTWALL_RATE,
} = process.env
let options: BoltwallConfig = {}
if (TIME_CAVEAT) options = TIME_CAVEAT_CONFIGS
if (ORIGIN_CAVEAT) options = ORIGIN_CAVEAT_CONFIGS
if (BOLTWALL_OAUTH) options.oauth = true
if (BOLTWALL_HODL) options.hodl = true
if (BOLTWALL_RATE) options.rate = +BOLTWALL_RATE
if (BOLTWALL_MIN_AMOUNT) options.minAmount = BOLTWALL_MIN_AMOUNT
app.use(boltwall(options))

Expand Down
1 change: 1 addition & 0 deletions src/typings/configs.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,5 @@ export interface BoltwallConfig {
minAmount?: string | number
hodl?: boolean
oauth?: boolean
rate?: number
}
43 changes: 43 additions & 0 deletions tests/configs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ describe('configs', () => {
? config.caveatSatisfiers[0]
: config.caveatSatisfiers
})

it('should create valid caveat that expires after x seconds, where "x" is number satoshis paid', () => {
if (!config.getCaveats)
throw new Error('Expected to have a getCaveats property')
Expand Down Expand Up @@ -47,6 +48,48 @@ describe('configs', () => {
expect(value).to.be.lessThan(now + time + amount)
})

it('should support custom rates for adding expiration caveat', () => {
if (!config.getCaveats)
throw new Error('Expected to have a getCaveats property')
// rate is calculated as number of seconds per satoshi
// testing a value that would give us 1 month for 20k sats
const seconds = 60 * 60 * 24 * 30 // 1 month
const sats = 20000 // 20k sats
const rate = (sats / seconds).toFixed(5)
const req = {
boltwallConfig: {
rate,
},
}
const now = Date.now()

// make typescript happy since this could be an array
const getCaveats = Array.isArray(config.getCaveats)
? config.getCaveats[0]
: config.getCaveats

const result: string = getCaveats(
(req as unknown) as Request,
{
amount: sats,
} as InvoiceResponse
)
const convertCaveat = (): Caveat => Caveat.decode(result)
const caveat = Caveat.decode(result)
const value: number = +caveat.value

// convert difference from ms
const actualSeconds = (value - now) / 1000

expect(convertCaveat).to.not.throw()
expect(value).to.be.greaterThan(now)
expect(actualSeconds).to.be.approximately(
seconds,
2500,
`Expected expiration to be approximately ${seconds}ms from now`
)
})

it('should return the expected invoice description', () => {
const { getInvoiceDescription } = config
if (!getInvoiceDescription)
Expand Down

0 comments on commit 72c273f

Please sign in to comment.