Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
932dcb6
feat(tempo): add funding requirements and policies
jxom Sep 23, 2026
8377cd0
refactor(tempo): remove redundant error constructors
jxom Sep 23, 2026
b391bbf
test(tempo): move behavior cases last
jxom Sep 23, 2026
50411d0
feat(tempo): use to for funding requirement sources
jxom Sep 23, 2026
18ddbff
refactor(tempo): rename dex funding source
jxom Sep 23, 2026
c4fb80b
style(tempo): sort funding source export
jxom Sep 23, 2026
d67d87a
feat: consolidate tempo funding source API
jxom Sep 23, 2026
0b6162e
refactor: split tempo dex funding source
jxom Sep 23, 2026
5e5799f
docs: format dex funding source examples
jxom Sep 23, 2026
4c9c1f5
refactor: name dex funding data encoder
jxom Sep 23, 2026
7ef3523
feat: expose native dex source on FundingSource
jxom Sep 23, 2026
e35669b
fix(tempo): use to for funding policy sources
jxom Sep 24, 2026
99ee991
feat(tempo): distinguish funding payload encoders
jxom Sep 24, 2026
4eb6793
refactor(tempo): restore dex funding source module
jxom Sep 24, 2026
3ae941b
feat: add earn funding source codecs
jxom Sep 24, 2026
f982011
style: order funding source exports
jxom Sep 24, 2026
2e23692
refactor: name funding source data decoders
jxom Sep 24, 2026
9f2209c
feat: add earn funding source constructor
jxom Sep 24, 2026
2e78374
feat(tempo): add unsigned key authorization rpc conversion
jxom Sep 25, 2026
7591c1c
fix(tempo): use to for funding rpc sources
jxom Sep 27, 2026
d02bec3
fix: restore funding rpc target fields
jxom Sep 27, 2026
3b2879b
refactor(tempo): use target for funding sources
jxom Sep 27, 2026
7ac06e9
style(tempo): format funding sources
jxom Sep 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/tempo-funding.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"ox": patch
---

Added Tempo funding codecs, policy rules, source helpers, and access key funding authorization using consistent `target` and `data` source fields.
106 changes: 106 additions & 0 deletions src/tempo/FundingPolicy.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import { describe, expect, test } from 'vitest'
import * as FundingPolicy from './FundingPolicy.js'

const token = '0x0101010101010101010101010101010101010101' as const
const target = '0x0202020202020202020202020202020202020202' as const
const requirement = {
token,
amount: 50n,
sources: [{ target, data: '0xab' as const }],
slippageBps: 100,
}

const rules = {
maxSlippageBps: 100,
sources: { [token]: requirement.sources },
}
describe('encode', () => {
test('ABI encodes, decodes and hashes canonical rules', () => {
expect(FundingPolicy.decode(FundingPolicy.encode(rules))).toEqual(rules)
expect(FundingPolicy.hash(rules)).toMatch(/^0x[0-9a-f]{64}$/)
expect(() =>
FundingPolicy.decode(`${FundingPolicy.encode(rules)}00`),
).toThrow()
})
})

describe('hash', () => {
test('canonical token order preserves significant source order', () => {
const second = '0x0303030303030303030303030303030303030303'
const first = {
...rules,
sources: { [second]: requirement.sources, [token]: requirement.sources },
}
const reordered = {
...rules,
sources: { [token]: requirement.sources, [second]: requirement.sources },
}
expect(FundingPolicy.encode(first)).toBe(FundingPolicy.encode(reordered))
const sources = [...requirement.sources, { target, data: '0xcd' as const }]
expect(
FundingPolicy.hash({ ...rules, sources: { [token]: sources } }),
).not.toBe(
FundingPolicy.hash({
...rules,
sources: { [token]: [...sources].reverse() },
}),
)
})
})

describe('toTuple', () => {
test('rejects invalid policy IDs and admins', () => {
for (const value of [
0n,
2n ** 64n,
{ admins: [], rules },
{ admins: [token, token], rules },
])
expect(() => FundingPolicy.toTuple(value)).toThrow()
})
})

describe('toRoutes', () => {
test('maps source addresses to the contract ABI field', () => {
expect(FundingPolicy.toRoutes(rules)).toEqual([
{ token, sources: [{ target, data: '0xab' }] },
])
})
})

describe('toRpc', () => {
test('keeps the RPC target field', () => {
expect(FundingPolicy.toRpc({ admins: [token], rules })).toEqual({
admins: [token],
rules: {
maxSlippageBps: 100,
sources: { [token]: [{ target, data: '0xab' }] },
},
})
})
})

describe('fromRpc', () => {
test('preserves RPC source targets', () => {
expect(
FundingPolicy.fromRpc({
admins: [token],
rules: {
maxSlippageBps: 100,
sources: { [token]: [{ target, data: '0xab' }] },
},
}),
).toEqual({ admins: [token], rules })
})
})

describe('fromTuple', () => {
test('decodes source targets', () => {
expect(
FundingPolicy.fromTuple([
[token],
['0x64', [[token, [[target, '0xab']]]]],
]),
).toEqual({ admins: [token], rules })
})
})
Loading
Loading