#![cfg(feature = "ext-eip2612")]
#![cfg_attr(docsrs, doc(cfg(feature = "ext-eip2612")))]
use serde_json::{Value, json};
use super::{AdvertiseContext, Extension};
use crate::wire::ExtensionEntry;
pub const EIP2612_GAS_SPONSORING_KEY: &str = "eip2612GasSponsoring";
pub const EIP2612_GAS_SPONSORING_VERSION: &str = "1";
fn client_info_schema() -> Value {
json!({
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"from": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" },
"asset": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" },
"spender": { "type": "string", "pattern": "^0x[a-fA-F0-9]{40}$" },
"amount": { "type": "string", "pattern": "^[0-9]+$" },
"nonce": { "type": "string", "pattern": "^[0-9]+$" },
"deadline": { "type": "string", "pattern": "^[0-9]+$" },
"signature": { "type": "string", "pattern": "^0x[a-fA-F0-9]+$" },
"version": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)*$" }
},
"required": ["from", "asset", "spender", "amount", "nonce", "deadline", "signature", "version"]
})
}
#[derive(Debug, Clone)]
pub struct Eip2612GasSponsoringExtension {
pub description: String,
pub version: String,
}
impl Default for Eip2612GasSponsoringExtension {
fn default() -> Self {
Self::new()
}
}
impl Eip2612GasSponsoringExtension {
#[must_use]
pub fn new() -> Self {
Self {
description:
"The facilitator accepts EIP-2612 gasless Permit to `Permit2` canonical contract."
.into(),
version: EIP2612_GAS_SPONSORING_VERSION.into(),
}
}
}
impl Extension for Eip2612GasSponsoringExtension {
fn id(&self) -> &'static str {
EIP2612_GAS_SPONSORING_KEY
}
fn advertise(&self, _ctx: &AdvertiseContext<'_>) -> Option<ExtensionEntry> {
Some(ExtensionEntry::with_schema(
json!({
"description": self.description,
"version": self.version,
}),
client_info_schema(),
))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn advertise_key_and_version() {
let ext = Eip2612GasSponsoringExtension::new();
assert_eq!(ext.id(), "eip2612GasSponsoring");
let entry = ext
.advertise(&AdvertiseContext { requirement: None })
.unwrap();
let v = entry.to_value();
assert_eq!(v["info"]["version"], "1");
assert!(v.get("schema").is_some());
}
}