前段时间看了下Coinbase的API想着写点东西.
想着多少是涉及钱的东西,所以想着看看能不能不用SDK.
毕竟感觉上,本身就不是个什么特别正规的行业,而且盯着的人也多,供应链上难说没有什么问题.
粗略翻了下文档,倒也不算写得不好.
除去SDK之外,还是有标准的Http JWT形式的提供的.
就是跟国内某些云厂商的文档一样,类别分类只能你懂了之后才懂怎么找.
稍微看了下jwt的签名方式,然后再对了下文档,感觉中间缺了一大段.
估计也没想着有人会直接从头写.
于是估计省事,ChatGTP和Gemini vibe了一下.
让no external dependency地写个client和一些简单策略描述帮助测试,还有就是让预留扩展interface以方便拔插.
gpt绕来绕去还是用上了sdk.
gemini倒是挺直接出了个纯typescript builtin function的版本.
不够提示jwt签名算法不对的时候,又绕回到jose这个jwt库了.
反向情绪价值了几轮,倒是给写了个像模像样的版本.
而且让给写test case mock api看着也挺一回事的.
然后review了下感觉client的部分略复杂.
签名的部分看着也不大对劲.
于是就放弃了.
转回古法编程.
当然,私心也是不够顺手太啰嗦.
顺便还能看看jwt的四种写法.
然后开始翻RFC.
抽象层面倒是挺简单.
然后回去对照了下文档,发觉少了签名的部分.
于是仔细翻了翻.
发觉文档的jwt其实指的是jwk+jws.
即一种json结构描述的key信息,和对应的key的signature的算法.
然后以json/jwt的方式encode一下.
继续翻了翻文档和几个RFC,发觉都是语焉不详的.
文档大部分术语表达其实是按照jose这个high level的jwt库来描述的.
而RFC里有大部分都是optional字段.
一时也没办法知道具体哪些是必要的,哪些是可选的.
现在想想,这个也算暗示了后面Coinbase API一些有趣的地方.
比如像jwt RFC里以及像老一点的oauth等签名方式里,都会要求有一个nouce去防止重放的.
甚至在jwt中,除了这类时间因素外,jwt还有一些从SSL CA方面借鉴过来的东西.
像除了nouce之外,还能assign一个unique id给每个jwt,以及限定token的有效时间区间.
还有就是issuer和subject这类概念.
加上key算法可以是非对称的方式.
所以形式上来说,安全模型算是挺标准完备的.
但关键这些都是optional的.
而且实际上coinbase的实现里,其实也就主要校验了key产生的签名.
像上面说的重放策略什么的,实际是可以重放的.
所以理论上来说,如果它的API Gateway没有做什么特别工程的话,是有可能重复或者意外retry的.
比如多买或者多卖,甚至多转帐理论上应该都是可能发生的.
当然,要说本来就套了一层Https/SSL了,没必要也不是说不过去.
但多多少少算是做的并不太符合预期.
毕竟作为一个怎么说也是金融交易系统的API,校验完全依赖底层通信协议,业务甚至API层面本身没有校验逻辑的话,也多少又些让人意外.
不过,说完全没有校验倒也不至于.
只不过逻辑很奇怪.
因为它会校验请求的url/api路径.
也就是说,在它的jwt的header部分会要求有个uris参数.
这个参数基本就是固定的api path.
如果缺少这个参数加入到签名过程,这个签名是401的.
对于相当一部分API来说,这个基本就是个常量.
所以,对于这部分API来说,这个必要参数显得也不是那么必要.
毕竟对安全性并没有提升.
而且形式上还增加的请求的大小.
也就是无效信息也多了.
想了想有价值的可能是某些url里面带某类动态id的可能会有意义.
比如针对某个transaction的操作之类的,可能会有一个标识嵌入到API路径上.
但这也解决不了产生这些标识的API的安全性问题.
另外就是这种放着标准的防重放机制不用,利用这么一个类似oauth api scope的字段去做随机化的事情,多少有点让人费解.
当然,这些可能知识trade api的问题.
其他类别的可能另一套底层处理机制的话,可能没这些问题.
但是,作为比较核心的交易API的话,多多少少是有些让人不太舒服的.
毕竟这种情况下,一旦遇到中间人,基本上就属于裸奔状态了.
因为即使不知道密钥,但是从请求上是可以看出操作类型的.
比如只是一毛钱的转帐/交易测试,理论上也可以通过重放去扩大的.
联系诸如perceptual这类衍生品的交易概念,交易所形式上来说其实又挺多合理的操作空间的.
比如你的margin可能不是cross的,只是针对某一个产品,也加了止损止盈线.
但是吧,可重放和重试之间模糊的界限,理论上和形式上是可以放大不利场景的.
而且因为虽然API Gateway后面并不校验nouce,但是SDK层面又注入.
所以你要证明是过错方也是有点缺乏依据的.
即使不在交易上出问题,在转账上面也是有可能有一些利润空间的.
像perceptual的funding payment概念.
形式上来说,这个是根据所谓的为了衍生品跟底层标的挂钩平衡加入的激励因素.
比如标的是BTC,然后对应的衍生品BTC perceptual会给予call/sell方以动态的正负利息/税费收入.
根据交易所自己的平衡原则,你call BTC perceptual可能会有一定利息,或者要付一定利息.
sell侧也是.
而且这个东西每小时结算一次.
极端产品的这个小时利息是可能倒万分之一的.
在这种情况下去重放,即使市场本身不波动,交易所那边也还是有可能有超额收益的.
当然,有funding payment这种东西的存在,交易所也犯不着去搞那么复杂的重发了.
毕竟税率既定,而且实际流水的变动相较于市场的波动,可能一般人也不会注意到,或者说在意.
而如果跟进一步考虑的话,这个可能就更有意思了.
因为它的结算单位是USDC.
所以宏观上里说,每小时是有一定市场持仓比例的USDC以这个费率的形式作为交易所收入固化回去的.
而交易苏的所有交易其实都是机遇USDC或者其他所谓稳定币维系的.
因为虽然你可以cash in和cash out各种法币.
但是你其实并不难直接用法币交易非stable coin.
或者说,有路径,但是一般也不会通过非stable coin的方式进行转化.
于是从会计角度来说,形式上,交易所账上的USDC负债会比例性地转换为资产.
再假设,如果交易所有自己的类stable coin的代币.
那么完全可以用这部分转化的资产去对自己的代币进行市值管理.
同时因为市值正向增长,而且属于自我发行的一般代币.
再基于代币进行市场融资进一步放大杠杆,然后回头做市也是有可能的.
所以总的来说,这套东西还是挺野蛮的.